bootstack 0.1.0a1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bootstack/__init__.py +249 -0
- bootstack/__main__.py +5 -0
- bootstack/api/__init__.py +127 -0
- bootstack/api/app.py +30 -0
- bootstack/api/constants.py +3 -0
- bootstack/api/data.py +23 -0
- bootstack/api/dialogs.py +44 -0
- bootstack/api/i18n.py +17 -0
- bootstack/api/localization.py +16 -0
- bootstack/api/menu.py +7 -0
- bootstack/api/style.py +23 -0
- bootstack/api/utils.py +24 -0
- bootstack/api/widgets.py +137 -0
- bootstack/assets/__init__.py +24 -0
- bootstack/assets/bootstack-transparent.png +0 -0
- bootstack/assets/bootstack.ico +0 -0
- bootstack/assets/bootstack.png +0 -0
- bootstack/assets/elements/__init__.py +0 -0
- bootstack/assets/elements/badge-pill.png +0 -0
- bootstack/assets/elements/badge-square.png +0 -0
- bootstack/assets/elements/border.png +0 -0
- bootstack/assets/elements/button-compact.png +0 -0
- bootstack/assets/elements/button-default.png +0 -0
- bootstack/assets/elements/button-group-horizontal-after-compact.png +0 -0
- bootstack/assets/elements/button-group-horizontal-after-default.png +0 -0
- bootstack/assets/elements/button-group-horizontal-before-compact.png +0 -0
- bootstack/assets/elements/button-group-horizontal-before-default.png +0 -0
- bootstack/assets/elements/button-group-horizontal-center-compact.png +0 -0
- bootstack/assets/elements/button-group-horizontal-center-default.png +0 -0
- bootstack/assets/elements/button-group-vertical-after-compact.png +0 -0
- bootstack/assets/elements/button-group-vertical-after-default.png +0 -0
- bootstack/assets/elements/button-group-vertical-before-compact.png +0 -0
- bootstack/assets/elements/button-group-vertical-before-default.png +0 -0
- bootstack/assets/elements/button-group-vertical-center-compact.png +0 -0
- bootstack/assets/elements/button-group-vertical-center-default.png +0 -0
- bootstack/assets/elements/checkbox-checked.png +0 -0
- bootstack/assets/elements/checkbox-indeterminate.png +0 -0
- bootstack/assets/elements/checkbox-unchecked.png +0 -0
- bootstack/assets/elements/field.png +0 -0
- bootstack/assets/elements/input-after-compact.png +0 -0
- bootstack/assets/elements/input-after-default.png +0 -0
- bootstack/assets/elements/input-before-compact.png +0 -0
- bootstack/assets/elements/input-before-default.png +0 -0
- bootstack/assets/elements/input-compact.png +0 -0
- bootstack/assets/elements/input-default.png +0 -0
- bootstack/assets/elements/list-item-separated.png +0 -0
- bootstack/assets/elements/list-item.png +0 -0
- bootstack/assets/elements/manifest.toml +480 -0
- bootstack/assets/elements/menu-item.png +0 -0
- bootstack/assets/elements/nav-button-compact.png +0 -0
- bootstack/assets/elements/nav-button-default.png +0 -0
- bootstack/assets/elements/nav-icon-button-compact.png +0 -0
- bootstack/assets/elements/nav-icon-button-default.png +0 -0
- bootstack/assets/elements/notebook-client-border.png +0 -0
- bootstack/assets/elements/notebook-tab-active.png +0 -0
- bootstack/assets/elements/notebook-tab-bar.png +0 -0
- bootstack/assets/elements/notebook-tab-normal.png +0 -0
- bootstack/assets/elements/notebook-tab-pill.png +0 -0
- bootstack/assets/elements/progress-bar-horizontal-striped.png +0 -0
- bootstack/assets/elements/progress-bar-solid.png +0 -0
- bootstack/assets/elements/progress-bar-thin.png +0 -0
- bootstack/assets/elements/progress-bar-vertical-striped.png +0 -0
- bootstack/assets/elements/radio-selected.png +0 -0
- bootstack/assets/elements/radio-unselected.png +0 -0
- bootstack/assets/elements/scrollbar-horizontal.png +0 -0
- bootstack/assets/elements/scrollbar-vertical.png +0 -0
- bootstack/assets/elements/slider-handle-focus.png +0 -0
- bootstack/assets/elements/slider-handle.png +0 -0
- bootstack/assets/elements/slider-track-horizontal.png +0 -0
- bootstack/assets/elements/slider-track-vertical.png +0 -0
- bootstack/assets/elements/switch-off.png +0 -0
- bootstack/assets/elements/switch-on.png +0 -0
- bootstack/assets/elements/tabs-bar-horizontal.png +0 -0
- bootstack/assets/elements/tabs-bar-vertical.png +0 -0
- bootstack/assets/elements/tabs-pill.png +0 -0
- bootstack/assets/locales/ar/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/ar/LC_MESSAGES/bootstack.po +853 -0
- bootstack/assets/locales/bg/LC_MESSAGES/bootstack.po +875 -0
- bootstack/assets/locales/cs/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/cs/LC_MESSAGES/bootstack.po +853 -0
- bootstack/assets/locales/da/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/da/LC_MESSAGES/bootstack.po +853 -0
- bootstack/assets/locales/de/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/de/LC_MESSAGES/bootstack.po +853 -0
- bootstack/assets/locales/en/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/en/LC_MESSAGES/bootstack.po +875 -0
- bootstack/assets/locales/es/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/es/LC_MESSAGES/bootstack.po +853 -0
- bootstack/assets/locales/fr/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/fr/LC_MESSAGES/bootstack.po +853 -0
- bootstack/assets/locales/he/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/he/LC_MESSAGES/bootstack.po +851 -0
- bootstack/assets/locales/hi/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/hi/LC_MESSAGES/bootstack.po +842 -0
- bootstack/assets/locales/it/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/it/LC_MESSAGES/bootstack.po +841 -0
- bootstack/assets/locales/ja/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/ja/LC_MESSAGES/bootstack.po +914 -0
- bootstack/assets/locales/ko/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/ko/LC_MESSAGES/bootstack.po +842 -0
- bootstack/assets/locales/nb/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/nb/LC_MESSAGES/bootstack.po +841 -0
- bootstack/assets/locales/nl/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/nl/LC_MESSAGES/bootstack.po +841 -0
- bootstack/assets/locales/pl/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/pl/LC_MESSAGES/bootstack.po +842 -0
- bootstack/assets/locales/pt/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/pt/LC_MESSAGES/bootstack.po +842 -0
- bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.po +842 -0
- bootstack/assets/locales/sl/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/sl/LC_MESSAGES/bootstack.po +842 -0
- bootstack/assets/locales/sv/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/sv/LC_MESSAGES/bootstack.po +842 -0
- bootstack/assets/locales/tr/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/tr/LC_MESSAGES/bootstack.po +842 -0
- bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.po +842 -0
- bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.po +842 -0
- bootstack/assets/themes/__init__.py +0 -0
- bootstack/assets/themes/amber-dark.json +32 -0
- bootstack/assets/themes/amber-light.json +32 -0
- bootstack/assets/themes/aurora-dark.json +32 -0
- bootstack/assets/themes/aurora-light.json +32 -0
- bootstack/assets/themes/bootstrap-dark.json +32 -0
- bootstack/assets/themes/bootstrap-light.json +32 -0
- bootstack/assets/themes/classic-dark.json +32 -0
- bootstack/assets/themes/classic-light.json +32 -0
- bootstack/assets/themes/docs-dark.json +32 -0
- bootstack/assets/themes/docs-light.json +32 -0
- bootstack/assets/themes/forest-dark.json +32 -0
- bootstack/assets/themes/forest-light.json +32 -0
- bootstack/assets/themes/ocean-dark.json +32 -0
- bootstack/assets/themes/ocean-light.json +32 -0
- bootstack/assets/themes/rose-dark.json +32 -0
- bootstack/assets/themes/rose-light.json +32 -0
- bootstack/assets/widgets/__init__.py +0 -0
- bootstack/assets/widgets/badge-default.png +0 -0
- bootstack/assets/widgets/badge-pill.png +0 -0
- bootstack/assets/widgets/border.png +0 -0
- bootstack/assets/widgets/button-group-horizontal-after.png +0 -0
- bootstack/assets/widgets/button-group-horizontal-before.png +0 -0
- bootstack/assets/widgets/button-group-horizontal-center.png +0 -0
- bootstack/assets/widgets/button-group-vertical-after.png +0 -0
- bootstack/assets/widgets/button-group-vertical-before.png +0 -0
- bootstack/assets/widgets/button-group-vertical-center.png +0 -0
- bootstack/assets/widgets/button.png +0 -0
- bootstack/assets/widgets/checkbox-checked.png +0 -0
- bootstack/assets/widgets/checkbox-indeterminate.png +0 -0
- bootstack/assets/widgets/checkbox-unchecked.png +0 -0
- bootstack/assets/widgets/field.png +0 -0
- bootstack/assets/widgets/icon-button.png +0 -0
- bootstack/assets/widgets/input-inner.png +0 -0
- bootstack/assets/widgets/input-prefix.png +0 -0
- bootstack/assets/widgets/input-suffix.png +0 -0
- bootstack/assets/widgets/input.png +0 -0
- bootstack/assets/widgets/list-item-focus.png +0 -0
- bootstack/assets/widgets/list-item-separated.png +0 -0
- bootstack/assets/widgets/menu-item-separated.png +0 -0
- bootstack/assets/widgets/notebook-client-border.png +0 -0
- bootstack/assets/widgets/notebook-pill-active.png +0 -0
- bootstack/assets/widgets/notebook-pill-inactive.png +0 -0
- bootstack/assets/widgets/notebook-tab-active.png +0 -0
- bootstack/assets/widgets/notebook-tab-border.png +0 -0
- bootstack/assets/widgets/notebook-tab-normal.png +0 -0
- bootstack/assets/widgets/notebook-underline.png +0 -0
- bootstack/assets/widgets/progress-bar-horizontal-default.png +0 -0
- bootstack/assets/widgets/progress-bar-horizontal-striped.png +0 -0
- bootstack/assets/widgets/progress-bar-vertical-default.png +0 -0
- bootstack/assets/widgets/progress-bar-vertical-striped.png +0 -0
- bootstack/assets/widgets/progress-trough-horizontal.png +0 -0
- bootstack/assets/widgets/progress-trough-vertical.png +0 -0
- bootstack/assets/widgets/radio-selected.png +0 -0
- bootstack/assets/widgets/radio-unselected.png +0 -0
- bootstack/assets/widgets/scrollbar-horizontal-rounded.png +0 -0
- bootstack/assets/widgets/scrollbar-vertical-rounded.png +0 -0
- bootstack/assets/widgets/separator-horizontal.png +0 -0
- bootstack/assets/widgets/separator-vertical.png +0 -0
- bootstack/assets/widgets/slider-handle-focus.png +0 -0
- bootstack/assets/widgets/slider-handle.png +0 -0
- bootstack/assets/widgets/slider-track-horizontal.png +0 -0
- bootstack/assets/widgets/slider-track-vertical.png +0 -0
- bootstack/assets/widgets/switch-off.png +0 -0
- bootstack/assets/widgets/switch-on.png +0 -0
- bootstack/assets/widgets/tabs-bar-horizontal.png +0 -0
- bootstack/assets/widgets/tabs-bar-vertical.png +0 -0
- bootstack/assets/widgets/tabs-pill.png +0 -0
- bootstack/cli/__init__.py +124 -0
- bootstack/cli/__main__.py +6 -0
- bootstack/cli/add.py +439 -0
- bootstack/cli/build.py +115 -0
- bootstack/cli/config.py +287 -0
- bootstack/cli/demo.py +1267 -0
- bootstack/cli/doctor.py +195 -0
- bootstack/cli/list_cmd.py +71 -0
- bootstack/cli/promote.py +120 -0
- bootstack/cli/pyinstaller.py +246 -0
- bootstack/cli/run.py +99 -0
- bootstack/cli/start.py +105 -0
- bootstack/cli/templates/__init__.py +861 -0
- bootstack/constants.py +325 -0
- bootstack/core/__init__.py +34 -0
- bootstack/core/capabilities/__init__.py +45 -0
- bootstack/core/capabilities/after.py +103 -0
- bootstack/core/capabilities/bind.py +154 -0
- bootstack/core/capabilities/bindtags.py +112 -0
- bootstack/core/capabilities/busy.py +61 -0
- bootstack/core/capabilities/clipboard.py +88 -0
- bootstack/core/capabilities/focus.py +118 -0
- bootstack/core/capabilities/grab.py +65 -0
- bootstack/core/capabilities/grid.py +188 -0
- bootstack/core/capabilities/localization.py +231 -0
- bootstack/core/capabilities/pack.py +119 -0
- bootstack/core/capabilities/place.py +92 -0
- bootstack/core/capabilities/selection.py +136 -0
- bootstack/core/capabilities/signals.py +242 -0
- bootstack/core/capabilities/winfo.py +315 -0
- bootstack/core/colorutils.py +234 -0
- bootstack/core/exceptions.py +95 -0
- bootstack/core/images.py +283 -0
- bootstack/core/localization/README.md +90 -0
- bootstack/core/localization/__init__.py +13 -0
- bootstack/core/localization/intl_format.py +580 -0
- bootstack/core/localization/msgcat.py +425 -0
- bootstack/core/localization/specs.py +143 -0
- bootstack/core/mixins/__init__.py +1 -0
- bootstack/core/mixins/ttk_state.py +35 -0
- bootstack/core/mixins/widget.py +132 -0
- bootstack/core/publisher.py +147 -0
- bootstack/core/signals/README.md +112 -0
- bootstack/core/signals/__init__.py +8 -0
- bootstack/core/signals/integration.py +100 -0
- bootstack/core/signals/signal.py +317 -0
- bootstack/core/signals/types.py +4 -0
- bootstack/core/validation/__init__.py +5 -0
- bootstack/core/validation/types.py +13 -0
- bootstack/core/validation/validation_result.py +17 -0
- bootstack/core/validation/validation_rules.py +112 -0
- bootstack/core/variables.py +62 -0
- bootstack/datasource/README.md +607 -0
- bootstack/datasource/__init__.py +51 -0
- bootstack/datasource/base.py +474 -0
- bootstack/datasource/file_source.py +541 -0
- bootstack/datasource/memory_source.py +482 -0
- bootstack/datasource/sqlite_source.py +453 -0
- bootstack/datasource/types.py +259 -0
- bootstack/dialogs/__init__.py +56 -0
- bootstack/dialogs/colorchooser.py +674 -0
- bootstack/dialogs/colordropper.py +257 -0
- bootstack/dialogs/datedialog.py +404 -0
- bootstack/dialogs/dialog.py +514 -0
- bootstack/dialogs/filterdialog.py +358 -0
- bootstack/dialogs/fontdialog.py +339 -0
- bootstack/dialogs/formdialog.py +541 -0
- bootstack/dialogs/message.py +489 -0
- bootstack/dialogs/query.py +561 -0
- bootstack/py.typed +1 -0
- bootstack/runtime/__init__.py +3 -0
- bootstack/runtime/app.py +879 -0
- bootstack/runtime/base_window.py +786 -0
- bootstack/runtime/events.py +399 -0
- bootstack/runtime/menu.py +510 -0
- bootstack/runtime/shortcuts.py +423 -0
- bootstack/runtime/tk_patch.py +31 -0
- bootstack/runtime/toplevel.py +131 -0
- bootstack/runtime/utility.py +371 -0
- bootstack/runtime/visual_focus.py +228 -0
- bootstack/runtime/window_utilities.py +1043 -0
- bootstack/style/__init__.py +5498 -0
- bootstack/style/bootstyle.py +507 -0
- bootstack/style/bootstyle_builder_base.py +752 -0
- bootstack/style/bootstyle_builder_mixed.py +93 -0
- bootstack/style/bootstyle_builder_tk.py +109 -0
- bootstack/style/bootstyle_builder_ttk.py +354 -0
- bootstack/style/builders/__init__.py +51 -0
- bootstack/style/builders/badge.py +44 -0
- bootstack/style/builders/button.py +453 -0
- bootstack/style/builders/buttongroup.py +344 -0
- bootstack/style/builders/calendar.py +271 -0
- bootstack/style/builders/checkbutton.py +95 -0
- bootstack/style/builders/combobox.py +112 -0
- bootstack/style/builders/contextmenu.py +268 -0
- bootstack/style/builders/entry.py +83 -0
- bootstack/style/builders/expander.py +171 -0
- bootstack/style/builders/field.py +312 -0
- bootstack/style/builders/frame.py +27 -0
- bootstack/style/builders/label.py +28 -0
- bootstack/style/builders/labelframe.py +41 -0
- bootstack/style/builders/listview.py +267 -0
- bootstack/style/builders/menubar.py +74 -0
- bootstack/style/builders/menubutton.py +408 -0
- bootstack/style/builders/notebook.py +316 -0
- bootstack/style/builders/panedwindow.py +25 -0
- bootstack/style/builders/progressbar.py +71 -0
- bootstack/style/builders/radiobutton.py +68 -0
- bootstack/style/builders/scale.py +66 -0
- bootstack/style/builders/scrollbar.py +360 -0
- bootstack/style/builders/separator.py +45 -0
- bootstack/style/builders/sidenav.py +313 -0
- bootstack/style/builders/sizegrip.py +15 -0
- bootstack/style/builders/spinbox.py +119 -0
- bootstack/style/builders/switch.py +67 -0
- bootstack/style/builders/tabitem.py +205 -0
- bootstack/style/builders/toolbutton.py +260 -0
- bootstack/style/builders/tooltip.py +26 -0
- bootstack/style/builders/treeview.py +269 -0
- bootstack/style/builders/utils.py +404 -0
- bootstack/style/builders_tk/__init__.py +16 -0
- bootstack/style/builders_tk/defaults.py +229 -0
- bootstack/style/element.py +173 -0
- bootstack/style/style.py +499 -0
- bootstack/style/theme_provider.py +449 -0
- bootstack/style/tk_patch.py +5 -0
- bootstack/style/token_maps.py +42 -0
- bootstack/style/types.py +32 -0
- bootstack/style/typography.py +527 -0
- bootstack/style/utility.py +696 -0
- bootstack/themes/__init__.py +12 -0
- bootstack/themes/standard.py +415 -0
- bootstack/themes/user.py +45 -0
- bootstack/widgets/__init__.py +53 -0
- bootstack/widgets/composites/__init__.py +38 -0
- bootstack/widgets/composites/accordion.py +385 -0
- bootstack/widgets/composites/appshell.py +445 -0
- bootstack/widgets/composites/buttongroup.py +391 -0
- bootstack/widgets/composites/calendar.py +914 -0
- bootstack/widgets/composites/compositeframe.py +282 -0
- bootstack/widgets/composites/contextmenu.py +1754 -0
- bootstack/widgets/composites/dateentry.py +261 -0
- bootstack/widgets/composites/dropdownbutton.py +190 -0
- bootstack/widgets/composites/expander.py +508 -0
- bootstack/widgets/composites/field.py +448 -0
- bootstack/widgets/composites/floodgauge.py +434 -0
- bootstack/widgets/composites/form.py +983 -0
- bootstack/widgets/composites/labeledscale.py +209 -0
- bootstack/widgets/composites/list/__init__.py +15 -0
- bootstack/widgets/composites/list/listitem.py +733 -0
- bootstack/widgets/composites/list/listview.py +1507 -0
- bootstack/widgets/composites/menubar.py +303 -0
- bootstack/widgets/composites/meter.py +882 -0
- bootstack/widgets/composites/numericentry.py +183 -0
- bootstack/widgets/composites/pagestack.py +330 -0
- bootstack/widgets/composites/passwordentry.py +149 -0
- bootstack/widgets/composites/pathentry.py +223 -0
- bootstack/widgets/composites/radiogroup.py +466 -0
- bootstack/widgets/composites/scrolledtext.py +388 -0
- bootstack/widgets/composites/scrolledtext.pyi +186 -0
- bootstack/widgets/composites/scrollview.py +675 -0
- bootstack/widgets/composites/selectbox.py +544 -0
- bootstack/widgets/composites/sidenav/__init__.py +24 -0
- bootstack/widgets/composites/sidenav/group.py +485 -0
- bootstack/widgets/composites/sidenav/header.py +83 -0
- bootstack/widgets/composites/sidenav/item.py +413 -0
- bootstack/widgets/composites/sidenav/separator.py +51 -0
- bootstack/widgets/composites/sidenav/view.py +919 -0
- bootstack/widgets/composites/spinnerentry.py +232 -0
- bootstack/widgets/composites/tableview/__init__.py +5 -0
- bootstack/widgets/composites/tableview/tableview.py +2254 -0
- bootstack/widgets/composites/tableview/types.py +169 -0
- bootstack/widgets/composites/tabs/__init__.py +6 -0
- bootstack/widgets/composites/tabs/tabitem.py +372 -0
- bootstack/widgets/composites/tabs/tabs.py +478 -0
- bootstack/widgets/composites/tabs/tabview.py +352 -0
- bootstack/widgets/composites/textentry.py +90 -0
- bootstack/widgets/composites/timeentry.py +189 -0
- bootstack/widgets/composites/toast.py +364 -0
- bootstack/widgets/composites/togglegroup.py +382 -0
- bootstack/widgets/composites/toolbar.py +393 -0
- bootstack/widgets/composites/tooltip.py +404 -0
- bootstack/widgets/internal/__init__.py +0 -0
- bootstack/widgets/internal/wrapper_base.py +304 -0
- bootstack/widgets/mixins/__init__.py +25 -0
- bootstack/widgets/mixins/configure_mixin.py +186 -0
- bootstack/widgets/mixins/entry_mixin.py +70 -0
- bootstack/widgets/mixins/font_mixin.py +346 -0
- bootstack/widgets/mixins/icon_mixin.py +38 -0
- bootstack/widgets/mixins/localization_mixin.py +255 -0
- bootstack/widgets/mixins/signal_mixin.py +272 -0
- bootstack/widgets/mixins/validation_mixin.py +204 -0
- bootstack/widgets/parts/__init__.py +11 -0
- bootstack/widgets/parts/numberentry_part.py +345 -0
- bootstack/widgets/parts/spinnerentry_part.py +394 -0
- bootstack/widgets/parts/textentry_part.py +344 -0
- bootstack/widgets/primitives/__init__.py +55 -0
- bootstack/widgets/primitives/badge.py +44 -0
- bootstack/widgets/primitives/button.py +89 -0
- bootstack/widgets/primitives/card.py +66 -0
- bootstack/widgets/primitives/checkbutton.py +124 -0
- bootstack/widgets/primitives/checktoggle.py +53 -0
- bootstack/widgets/primitives/combobox.py +165 -0
- bootstack/widgets/primitives/entry.py +98 -0
- bootstack/widgets/primitives/frame.py +206 -0
- bootstack/widgets/primitives/gridframe.py +479 -0
- bootstack/widgets/primitives/label.py +95 -0
- bootstack/widgets/primitives/labelframe.py +63 -0
- bootstack/widgets/primitives/menubutton.py +118 -0
- bootstack/widgets/primitives/notebook.py +551 -0
- bootstack/widgets/primitives/optionmenu.py +248 -0
- bootstack/widgets/primitives/packframe.py +228 -0
- bootstack/widgets/primitives/panedwindow.py +58 -0
- bootstack/widgets/primitives/progressbar.py +95 -0
- bootstack/widgets/primitives/radiobutton.py +115 -0
- bootstack/widgets/primitives/radiotoggle.py +50 -0
- bootstack/widgets/primitives/scale.py +85 -0
- bootstack/widgets/primitives/scrollbar.py +56 -0
- bootstack/widgets/primitives/separator.py +56 -0
- bootstack/widgets/primitives/sizegrip.py +47 -0
- bootstack/widgets/primitives/spinbox.py +91 -0
- bootstack/widgets/primitives/switch.py +41 -0
- bootstack/widgets/primitives/treeview.py +77 -0
- bootstack/widgets/types.py +20 -0
- bootstack-0.1.0a1.dist-info/METADATA +196 -0
- bootstack-0.1.0a1.dist-info/RECORD +419 -0
- bootstack-0.1.0a1.dist-info/WHEEL +5 -0
- bootstack-0.1.0a1.dist-info/entry_points.txt +2 -0
- bootstack-0.1.0a1.dist-info/licenses/LICENSE +22 -0
- bootstack-0.1.0a1.dist-info/licenses/NOTICE +10 -0
- bootstack-0.1.0a1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any, Callable, Literal, TypedDict, TYPE_CHECKING
|
|
4
|
+
from typing_extensions import Unpack
|
|
5
|
+
|
|
6
|
+
from bootstack.widgets.primitives.button import Button
|
|
7
|
+
from bootstack.widgets.mixins.configure_mixin import configure_delegate
|
|
8
|
+
from bootstack.widgets.primitives import Frame
|
|
9
|
+
from bootstack.widgets.primitives.checkbutton import CheckButton
|
|
10
|
+
from bootstack.widgets.primitives.checktoggle import CheckToggle
|
|
11
|
+
from bootstack.widgets.primitives.radiobutton import RadioButton
|
|
12
|
+
from bootstack.widgets.primitives.radiotoggle import RadioToggle
|
|
13
|
+
from bootstack.widgets.types import Master
|
|
14
|
+
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
import tkinter as tk
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ButtonGroupKwargs(TypedDict, total=False):
|
|
20
|
+
orient: Literal['horizontal', 'vertical']
|
|
21
|
+
accent: str
|
|
22
|
+
variant: str
|
|
23
|
+
state: Literal['normal', 'disabled']
|
|
24
|
+
surface: str
|
|
25
|
+
density: Literal['default', 'compact']
|
|
26
|
+
style_options: dict[str, Any]
|
|
27
|
+
# Frame options
|
|
28
|
+
padding: Any
|
|
29
|
+
width: int
|
|
30
|
+
height: int
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class ButtonGroup(Frame):
|
|
34
|
+
"""A group of buttons with automatic positioning and styling.
|
|
35
|
+
|
|
36
|
+
ButtonGroup provides visual grouping of buttons (or other widgets) without
|
|
37
|
+
state tracking. Perfect for toolbars, action button groups, or any scenario
|
|
38
|
+
where you want buttons visually connected but don't need to track which is
|
|
39
|
+
selected.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
def __init__(
|
|
43
|
+
self,
|
|
44
|
+
master: Master = None,
|
|
45
|
+
*,
|
|
46
|
+
orient: Literal['horizontal', 'vertical'] = 'horizontal',
|
|
47
|
+
accent: str = None,
|
|
48
|
+
variant: str = 'solid',
|
|
49
|
+
density: Literal['default', 'compact'] = 'default',
|
|
50
|
+
state: Literal['normal', 'disabled'] = 'normal',
|
|
51
|
+
**kwargs: Unpack[ButtonGroupKwargs]
|
|
52
|
+
):
|
|
53
|
+
"""Initialize the ButtonGroup.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
master: Parent widget. If None, uses the default root window.
|
|
57
|
+
|
|
58
|
+
Other Parameters:
|
|
59
|
+
orient (str): Layout orientation - 'horizontal' (default) or 'vertical'.
|
|
60
|
+
accent (str): The accent token (e.g., 'primary', 'success', 'danger').
|
|
61
|
+
variant (str): The style variant (e.g., 'solid', 'outline', 'ghost'). Defaults to 'solid',
|
|
62
|
+
state (str): Initial state for all buttons - 'normal' (default) or 'disabled'.
|
|
63
|
+
surface (str): Optional surface token; otherwise inherited.
|
|
64
|
+
density (str): The vertical and horizontal compactness of widget content, e.g. 'default', 'compact'.
|
|
65
|
+
padding (int | tuple): Frame padding. Defaults to 1.
|
|
66
|
+
width (int): Requested width in pixels.
|
|
67
|
+
height (int): Requested height in pixels.
|
|
68
|
+
style_options (dict): Additional style options passed to child widgets.
|
|
69
|
+
"""
|
|
70
|
+
# Store ButtonGroup-specific options from explicit parameters
|
|
71
|
+
# NOTE: _color and _variant are set AFTER super().__init__() because
|
|
72
|
+
# the bootstyle wrapper in TTKWrapperBase sets them to None/extracted values
|
|
73
|
+
self._orientation = orient
|
|
74
|
+
self._state = state
|
|
75
|
+
|
|
76
|
+
style_options = kwargs.pop('style_options', {})
|
|
77
|
+
kwargs.pop('show_border', None) # not allowed
|
|
78
|
+
|
|
79
|
+
# Initialize internal state
|
|
80
|
+
self._widgets: dict[str, tk.Widget] = {}
|
|
81
|
+
self._counter = 0 # For auto-generating keys
|
|
82
|
+
|
|
83
|
+
# Handle padding default
|
|
84
|
+
if 'padding' not in kwargs:
|
|
85
|
+
kwargs['padding'] = 1
|
|
86
|
+
|
|
87
|
+
super().__init__(master, style_options=style_options, **kwargs)
|
|
88
|
+
|
|
89
|
+
# Set accent/variant AFTER super().__init__() to override wrapper's values
|
|
90
|
+
self._accent = accent
|
|
91
|
+
self._variant = variant
|
|
92
|
+
self._density = density
|
|
93
|
+
|
|
94
|
+
def add(
|
|
95
|
+
self,
|
|
96
|
+
text: str = None,
|
|
97
|
+
*,
|
|
98
|
+
key: str = None,
|
|
99
|
+
widget_type: type = None,
|
|
100
|
+
command: Callable[[], Any] = None,
|
|
101
|
+
**kwargs: Any
|
|
102
|
+
) -> 'tk.Widget':
|
|
103
|
+
"""Add a widget to the group.
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
text: Text to display on the widget.
|
|
107
|
+
key: Unique identifier. Auto-generated if not provided.
|
|
108
|
+
widget_type: Widget class to instantiate (defaults to Button).
|
|
109
|
+
command: Callback for button press.
|
|
110
|
+
**kwargs: Additional arguments passed to the widget constructor.
|
|
111
|
+
|
|
112
|
+
Returns:
|
|
113
|
+
The created widget instance.
|
|
114
|
+
|
|
115
|
+
Raises:
|
|
116
|
+
ValueError: If a widget with the same key already exists.
|
|
117
|
+
"""
|
|
118
|
+
# Auto-generate key if not provided
|
|
119
|
+
if key is None:
|
|
120
|
+
key = f"widget_{self._counter}"
|
|
121
|
+
self._counter += 1
|
|
122
|
+
|
|
123
|
+
if key in self._widgets:
|
|
124
|
+
raise ValueError(f"A widget with the key '{key}' already exists.")
|
|
125
|
+
|
|
126
|
+
# Default to Button if no widget type specified
|
|
127
|
+
if widget_type is None:
|
|
128
|
+
widget_type = Button
|
|
129
|
+
elif not callable(widget_type):
|
|
130
|
+
raise TypeError(f"widget_type must be a class or callable, got {type(widget_type).__name__}")
|
|
131
|
+
|
|
132
|
+
widget_kwargs = kwargs.copy()
|
|
133
|
+
|
|
134
|
+
# Apply buttongroup styling using ttk_class='ButtonGroup'
|
|
135
|
+
widget_kwargs.setdefault('ttk_class', 'ButtonGroup')
|
|
136
|
+
|
|
137
|
+
# Apply accent/variant for styling
|
|
138
|
+
if self._accent or self._variant:
|
|
139
|
+
# New API: use accent and variant directly
|
|
140
|
+
if 'accent' not in widget_kwargs:
|
|
141
|
+
widget_kwargs['accent'] = self._accent
|
|
142
|
+
if 'variant' not in widget_kwargs:
|
|
143
|
+
widget_kwargs['variant'] = self._variant
|
|
144
|
+
|
|
145
|
+
# force uniform density
|
|
146
|
+
widget_kwargs['density'] = self._density
|
|
147
|
+
|
|
148
|
+
# Apply positioning via style_options
|
|
149
|
+
existing_style_opts = widget_kwargs.get('style_options', {}).copy()
|
|
150
|
+
existing_style_opts['orient'] = self._orientation
|
|
151
|
+
existing_style_opts['density'] = self._density
|
|
152
|
+
existing_style_opts.setdefault('position', 'before')
|
|
153
|
+
|
|
154
|
+
# Set active_state for non-radio/check button types
|
|
155
|
+
_radio_check_types = (CheckButton, CheckToggle, RadioButton, RadioToggle)
|
|
156
|
+
if not (isinstance(widget_type, type) and issubclass(widget_type, _radio_check_types)):
|
|
157
|
+
existing_style_opts.setdefault('active_state', True)
|
|
158
|
+
|
|
159
|
+
widget_kwargs['style_options'] = existing_style_opts
|
|
160
|
+
|
|
161
|
+
# Apply state if not explicitly provided
|
|
162
|
+
if 'state' not in widget_kwargs:
|
|
163
|
+
widget_kwargs['state'] = self._state
|
|
164
|
+
|
|
165
|
+
# Build constructor arguments
|
|
166
|
+
ctor_args = {'text': text} if text is not None else {}
|
|
167
|
+
if command is not None:
|
|
168
|
+
ctor_args['command'] = command
|
|
169
|
+
ctor_args.update(widget_kwargs)
|
|
170
|
+
|
|
171
|
+
# Create the widget
|
|
172
|
+
widget = widget_type(self, **ctor_args)
|
|
173
|
+
|
|
174
|
+
# Pack based on orientation
|
|
175
|
+
if self._orientation == 'horizontal':
|
|
176
|
+
widget.pack(side='left')
|
|
177
|
+
else: # vertical
|
|
178
|
+
widget.pack(side='top', fill='x')
|
|
179
|
+
|
|
180
|
+
self._widgets[key] = widget
|
|
181
|
+
self._update_widget_positions()
|
|
182
|
+
return widget
|
|
183
|
+
|
|
184
|
+
def _update_widget_positions(self):
|
|
185
|
+
"""Update widget styles based on their position in the group.
|
|
186
|
+
|
|
187
|
+
Note: Relies on dictionary insertion order (Python 3.7+) to maintain
|
|
188
|
+
widget order based on when they were added.
|
|
189
|
+
"""
|
|
190
|
+
widget_list = list(self._widgets.values())
|
|
191
|
+
num_widgets = len(widget_list)
|
|
192
|
+
|
|
193
|
+
if num_widgets == 0:
|
|
194
|
+
return
|
|
195
|
+
|
|
196
|
+
for idx, widget in enumerate(widget_list):
|
|
197
|
+
if num_widgets == 1:
|
|
198
|
+
position = 'before'
|
|
199
|
+
elif idx == 0:
|
|
200
|
+
position = 'before'
|
|
201
|
+
elif idx == num_widgets - 1:
|
|
202
|
+
position = 'after'
|
|
203
|
+
else:
|
|
204
|
+
position = 'center'
|
|
205
|
+
|
|
206
|
+
# Update position if widget supports configure_style_options
|
|
207
|
+
if hasattr(widget, 'configure_style_options'):
|
|
208
|
+
current_position = widget.configure_style_options('position')
|
|
209
|
+
if current_position != position:
|
|
210
|
+
widget.configure_style_options(position=position)
|
|
211
|
+
# Rebuild style with new position
|
|
212
|
+
if hasattr(widget, 'rebuild_style'):
|
|
213
|
+
widget.rebuild_style()
|
|
214
|
+
|
|
215
|
+
def remove(self, key: str):
|
|
216
|
+
"""Remove a widget by its key.
|
|
217
|
+
|
|
218
|
+
Args:
|
|
219
|
+
key: The key of the widget to remove.
|
|
220
|
+
|
|
221
|
+
Raises:
|
|
222
|
+
KeyError: If no widget with the given key exists.
|
|
223
|
+
"""
|
|
224
|
+
if key not in self._widgets:
|
|
225
|
+
raise KeyError(f"No widget with key '{key}'")
|
|
226
|
+
widget = self._widgets.pop(key)
|
|
227
|
+
widget.destroy()
|
|
228
|
+
self._update_widget_positions()
|
|
229
|
+
|
|
230
|
+
def item(self, key: str) -> 'tk.Widget':
|
|
231
|
+
"""Get a widget by its key.
|
|
232
|
+
|
|
233
|
+
Args:
|
|
234
|
+
key: The key of the widget to retrieve.
|
|
235
|
+
|
|
236
|
+
Returns:
|
|
237
|
+
The widget instance.
|
|
238
|
+
|
|
239
|
+
Raises:
|
|
240
|
+
KeyError: If no widget with the given key exists.
|
|
241
|
+
"""
|
|
242
|
+
if key not in self._widgets:
|
|
243
|
+
raise KeyError(f"No widget with key '{key}'")
|
|
244
|
+
return self._widgets[key]
|
|
245
|
+
|
|
246
|
+
def configure_item(self, key: str, option: str = None, **kwargs: Any):
|
|
247
|
+
"""Configure a specific widget by its key.
|
|
248
|
+
|
|
249
|
+
Args:
|
|
250
|
+
key: The key of the widget to configure.
|
|
251
|
+
option: If provided, return the value of this option.
|
|
252
|
+
**kwargs: Configuration options to apply to the widget.
|
|
253
|
+
|
|
254
|
+
Returns:
|
|
255
|
+
If option is provided, returns the value of that option.
|
|
256
|
+
|
|
257
|
+
Examples:
|
|
258
|
+
group.configure_item("save_btn", state='disabled')
|
|
259
|
+
current_state = group.configure_item("save_btn", 'state')
|
|
260
|
+
"""
|
|
261
|
+
widget = self.item(key)
|
|
262
|
+
if option is not None:
|
|
263
|
+
return widget.cget(option)
|
|
264
|
+
widget.configure(**kwargs)
|
|
265
|
+
|
|
266
|
+
def items(self) -> tuple['tk.Widget', ...]:
|
|
267
|
+
"""Get all widgets in the group.
|
|
268
|
+
|
|
269
|
+
Returns:
|
|
270
|
+
A tuple of all widget instances in the group.
|
|
271
|
+
"""
|
|
272
|
+
return tuple(self._widgets.values())
|
|
273
|
+
|
|
274
|
+
def keys(self) -> tuple[str, ...]:
|
|
275
|
+
"""Get all widget keys.
|
|
276
|
+
|
|
277
|
+
Returns:
|
|
278
|
+
A tuple of all widget keys in the group.
|
|
279
|
+
"""
|
|
280
|
+
return tuple(self._widgets.keys())
|
|
281
|
+
|
|
282
|
+
def __len__(self) -> int:
|
|
283
|
+
"""Return the number of widgets in the group.
|
|
284
|
+
|
|
285
|
+
Examples:
|
|
286
|
+
>>> count = len(button_group)
|
|
287
|
+
"""
|
|
288
|
+
return len(self._widgets)
|
|
289
|
+
|
|
290
|
+
def __contains__(self, key: str) -> bool:
|
|
291
|
+
"""Check if a widget with the given key exists in the group.
|
|
292
|
+
|
|
293
|
+
Examples:
|
|
294
|
+
>>> if 'save' in button_group:
|
|
295
|
+
... print('Save button exists')
|
|
296
|
+
"""
|
|
297
|
+
return key in self._widgets
|
|
298
|
+
|
|
299
|
+
def __iter__(self):
|
|
300
|
+
"""Iterate over the widgets in the group.
|
|
301
|
+
|
|
302
|
+
Examples:
|
|
303
|
+
>>> for widget in button_group:
|
|
304
|
+
... widget.configure(state='disabled')
|
|
305
|
+
"""
|
|
306
|
+
return iter(self._widgets.values())
|
|
307
|
+
|
|
308
|
+
@configure_delegate('accent')
|
|
309
|
+
def _delegate_accent(self, value=None):
|
|
310
|
+
"""Get or set the accent. Updates all widgets when changed."""
|
|
311
|
+
if value is None:
|
|
312
|
+
return self._accent
|
|
313
|
+
|
|
314
|
+
self._accent = value
|
|
315
|
+
self._reconfigure_all_widgets()
|
|
316
|
+
|
|
317
|
+
@configure_delegate('density')
|
|
318
|
+
def _delegate_density(self, value=None):
|
|
319
|
+
"""Get or set the density. Updates all widgets when changed."""
|
|
320
|
+
if value is None:
|
|
321
|
+
return self._density
|
|
322
|
+
|
|
323
|
+
self._density = value
|
|
324
|
+
self._reconfigure_all_widgets()
|
|
325
|
+
|
|
326
|
+
@configure_delegate('variant')
|
|
327
|
+
def _delegate_variant(self, value=None):
|
|
328
|
+
"""Get or set the variant. Updates all widgets when changed."""
|
|
329
|
+
if value is None:
|
|
330
|
+
return self._variant
|
|
331
|
+
|
|
332
|
+
self._variant = value
|
|
333
|
+
self._reconfigure_all_widgets()
|
|
334
|
+
|
|
335
|
+
def _reconfigure_all_widgets(self):
|
|
336
|
+
"""Reconfigure all widgets with current accent/variant/density"""
|
|
337
|
+
for widget in self._widgets.values():
|
|
338
|
+
# Update density in style_options
|
|
339
|
+
if hasattr(widget, 'configure_style_options'):
|
|
340
|
+
widget.configure_style_options(density=self._density)
|
|
341
|
+
if hasattr(widget, 'configure'):
|
|
342
|
+
if self._accent or self._variant:
|
|
343
|
+
widget.configure(accent=self._accent, variant=self._variant)
|
|
344
|
+
if hasattr(widget, 'rebuild_style'):
|
|
345
|
+
widget.rebuild_style()
|
|
346
|
+
self._update_widget_positions()
|
|
347
|
+
|
|
348
|
+
@configure_delegate('orient')
|
|
349
|
+
def _delegate_orient(self, value=None):
|
|
350
|
+
"""Get or set orientation ('horizontal' or 'vertical'). Repacks widgets when changed."""
|
|
351
|
+
if value is None:
|
|
352
|
+
return self._orientation
|
|
353
|
+
|
|
354
|
+
if value not in ('horizontal', 'vertical'):
|
|
355
|
+
raise ValueError("orient must be 'horizontal' or 'vertical'")
|
|
356
|
+
|
|
357
|
+
self._orientation = value
|
|
358
|
+
|
|
359
|
+
# Repack all widgets
|
|
360
|
+
for widget in self._widgets.values():
|
|
361
|
+
widget.pack_forget()
|
|
362
|
+
if hasattr(widget, 'configure_style_options'):
|
|
363
|
+
widget.configure_style_options(orient=value)
|
|
364
|
+
# Rebuild style with new orientation
|
|
365
|
+
if hasattr(widget, 'rebuild_style'):
|
|
366
|
+
widget.rebuild_style()
|
|
367
|
+
|
|
368
|
+
if self._orientation == 'horizontal':
|
|
369
|
+
widget.pack(side='left')
|
|
370
|
+
else:
|
|
371
|
+
widget.pack(side='top', fill='x')
|
|
372
|
+
|
|
373
|
+
self._update_widget_positions()
|
|
374
|
+
|
|
375
|
+
@configure_delegate('state')
|
|
376
|
+
def _delegate_state(self, value=None):
|
|
377
|
+
"""Get or set state for all widgets ('normal' or 'disabled')."""
|
|
378
|
+
if value is None:
|
|
379
|
+
return self._state
|
|
380
|
+
|
|
381
|
+
if value not in ('normal', 'disabled'):
|
|
382
|
+
raise ValueError("state must be 'normal' or 'disabled'")
|
|
383
|
+
|
|
384
|
+
self._state = value
|
|
385
|
+
# Update all widgets with new state
|
|
386
|
+
for widget in self._widgets.values():
|
|
387
|
+
try:
|
|
388
|
+
widget.configure(state=value)
|
|
389
|
+
except (AttributeError, TypeError):
|
|
390
|
+
# Widget doesn't support state configuration
|
|
391
|
+
pass
|