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,282 @@
|
|
|
1
|
+
import tkinter as tk
|
|
2
|
+
from tkinter import ttk
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from bootstack.widgets.primitives.frame import Frame
|
|
6
|
+
from bootstack.widgets.types import Master
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Composite:
|
|
10
|
+
"""State coordinator for composite widgets.
|
|
11
|
+
|
|
12
|
+
Composite is a pure state management class that synchronizes interaction
|
|
13
|
+
states (hover, pressed, focus, selected, disabled) across multiple widgets.
|
|
14
|
+
It does not inherit from any visual widget, making it suitable as a
|
|
15
|
+
coordination hub for widgets anywhere in the widget tree.
|
|
16
|
+
|
|
17
|
+
Attributes:
|
|
18
|
+
HOVER (str): State name constant for hover state ('hover').
|
|
19
|
+
ACTIVE (str): State name constant for active state ('active').
|
|
20
|
+
PRESSED (str): State name constant for pressed state ('pressed').
|
|
21
|
+
SELECTED (str): State name constant for selected state ('selected').
|
|
22
|
+
FOCUS (str): State name constant for focus state ('focus').
|
|
23
|
+
DISABLED (str): State name constant for disabled state ('disabled').
|
|
24
|
+
selected (bool): Read-only property for current selection state.
|
|
25
|
+
disabled (bool): Read-only property for current disabled state.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
# state names
|
|
29
|
+
HOVER = 'hover'
|
|
30
|
+
ACTIVE = 'active'
|
|
31
|
+
PRESSED = 'pressed'
|
|
32
|
+
SELECTED = 'selected'
|
|
33
|
+
FOCUS = 'focus'
|
|
34
|
+
DISABLED = 'disabled'
|
|
35
|
+
|
|
36
|
+
def __init__(self, event_target, select_on_click=False):
|
|
37
|
+
"""Initialize the Composite coordinator.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
event_target: The widget that determines bounds for hover detection
|
|
41
|
+
and where <<CompositeInvoke>> events are generated. This should
|
|
42
|
+
typically be the container widget that visually represents the
|
|
43
|
+
composite group.
|
|
44
|
+
select_on_click: If True, automatically toggles the selected state
|
|
45
|
+
when clicking on non-button registered widgets. Defaults to False.
|
|
46
|
+
"""
|
|
47
|
+
self._hovered = False
|
|
48
|
+
self._pressed = False
|
|
49
|
+
self._focused = False
|
|
50
|
+
|
|
51
|
+
# semantic
|
|
52
|
+
self._selected = False
|
|
53
|
+
self._disabled = False
|
|
54
|
+
|
|
55
|
+
# event target determines bounds and where events are generated
|
|
56
|
+
self._event_target = event_target
|
|
57
|
+
|
|
58
|
+
# composites registry
|
|
59
|
+
self._composites = set()
|
|
60
|
+
|
|
61
|
+
# auto-toggle selection on click if enabled
|
|
62
|
+
if select_on_click:
|
|
63
|
+
self.on_invoked(lambda e: self.set_selected(not self._selected))
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def selected(self) -> bool:
|
|
67
|
+
"""Whether this composite is currently in the selected state."""
|
|
68
|
+
return self._selected
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def disabled(self) -> bool:
|
|
72
|
+
"""Whether this composite is currently in the disabled state."""
|
|
73
|
+
return self._disabled
|
|
74
|
+
|
|
75
|
+
def register_composite(self, widget: ttk.Widget):
|
|
76
|
+
"""Register a widget to participate in state synchronization.
|
|
77
|
+
|
|
78
|
+
The widget will be bound to event handlers and will receive state
|
|
79
|
+
updates whenever any registered widget's state changes. Registered
|
|
80
|
+
widgets can be anywhere in the widget tree; they don't need to be
|
|
81
|
+
children of the event_target.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
widget: The ttk widget to register for state synchronization.
|
|
85
|
+
Event bindings are added to this widget using add='+' to
|
|
86
|
+
preserve existing bindings.
|
|
87
|
+
|
|
88
|
+
Note:
|
|
89
|
+
Buttons are treated specially - they invoke their command on
|
|
90
|
+
click instead of generating <<CompositeInvoke>> events.
|
|
91
|
+
"""
|
|
92
|
+
self._composites.add(widget)
|
|
93
|
+
|
|
94
|
+
widget.bind('<Enter>', self._on_enter, add='+')
|
|
95
|
+
widget.bind('<Leave>', self._on_leave, add='+')
|
|
96
|
+
widget.bind('<ButtonPress-1>', self._on_press, add='+')
|
|
97
|
+
widget.bind('<ButtonRelease-1>', self._on_release, add='+')
|
|
98
|
+
widget.bind('<FocusIn>', self._on_focus_in, add='+')
|
|
99
|
+
widget.bind('<FocusOut>', self._on_focus_out, add='+')
|
|
100
|
+
|
|
101
|
+
def set_selected(self, selected: bool):
|
|
102
|
+
"""Set the selected state and propagate to all registered widgets.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
selected: True to mark as selected, False to deselect.
|
|
106
|
+
"""
|
|
107
|
+
self._selected = selected
|
|
108
|
+
self._update_states()
|
|
109
|
+
|
|
110
|
+
def set_disabled(self, disabled: bool):
|
|
111
|
+
"""Set the disabled state and propagate to all registered widgets.
|
|
112
|
+
|
|
113
|
+
When disabled, hover, pressed, and focus states are automatically
|
|
114
|
+
cleared and will not update until re-enabled.
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
disabled: True to mark as disabled, False to enable.
|
|
118
|
+
"""
|
|
119
|
+
self._disabled = disabled
|
|
120
|
+
self._update_states()
|
|
121
|
+
|
|
122
|
+
def _pointer_inside_bounds(self):
|
|
123
|
+
rx, ry = self._event_target.winfo_rootx(), self._event_target.winfo_rooty()
|
|
124
|
+
rw, rh = self._event_target.winfo_width(), self._event_target.winfo_height()
|
|
125
|
+
px, py = self._event_target.winfo_pointerxy()
|
|
126
|
+
|
|
127
|
+
if px < rx or py < ry:
|
|
128
|
+
return False
|
|
129
|
+
|
|
130
|
+
return (px - rx - rw) < 0 and (py - ry - rh) < 0
|
|
131
|
+
|
|
132
|
+
def _update_states(self):
|
|
133
|
+
states_on = set()
|
|
134
|
+
states_off = set()
|
|
135
|
+
|
|
136
|
+
if self._disabled:
|
|
137
|
+
states_on.add(self.DISABLED)
|
|
138
|
+
states_off |= {self.HOVER, self.PRESSED, self.FOCUS}
|
|
139
|
+
else:
|
|
140
|
+
states_off.add(self.DISABLED)
|
|
141
|
+
(states_on if self._hovered else states_off).add(self.HOVER)
|
|
142
|
+
(states_on if self._pressed else states_off).add(self.PRESSED)
|
|
143
|
+
(states_on if self._focused else states_off).add(self.FOCUS)
|
|
144
|
+
|
|
145
|
+
(states_on if self._selected else states_off).add(self.SELECTED)
|
|
146
|
+
|
|
147
|
+
on = [s for s in states_on]
|
|
148
|
+
off = [f'!{s}' for s in states_off]
|
|
149
|
+
state_map = tuple(on + off)
|
|
150
|
+
|
|
151
|
+
for c in self._composites:
|
|
152
|
+
c.state(state_map)
|
|
153
|
+
|
|
154
|
+
def _on_enter(self, e):
|
|
155
|
+
self._hovered = True
|
|
156
|
+
self._pressed = False
|
|
157
|
+
self._update_states()
|
|
158
|
+
|
|
159
|
+
def _on_leave(self, e):
|
|
160
|
+
in_bounds = self._pointer_inside_bounds()
|
|
161
|
+
if in_bounds:
|
|
162
|
+
self._hovered = True
|
|
163
|
+
else:
|
|
164
|
+
self._hovered = False
|
|
165
|
+
self._pressed = False
|
|
166
|
+
self._update_states()
|
|
167
|
+
|
|
168
|
+
def _on_press(self, e):
|
|
169
|
+
self._pressed = True
|
|
170
|
+
self._update_states()
|
|
171
|
+
|
|
172
|
+
def _on_release(self, e):
|
|
173
|
+
self._pressed = False
|
|
174
|
+
self._update_states()
|
|
175
|
+
# For buttons, invoke their command; for others, generate event
|
|
176
|
+
if isinstance(e.widget, ttk.Button):
|
|
177
|
+
# Manually invoke the button's command since our binding blocks it
|
|
178
|
+
cmd = e.widget.cget('command')
|
|
179
|
+
if cmd:
|
|
180
|
+
e.widget.tk.call(cmd)
|
|
181
|
+
else:
|
|
182
|
+
# Only non-button widgets trigger selection
|
|
183
|
+
self._event_target.event_generate('<<CompositeInvoke>>', when='tail')
|
|
184
|
+
|
|
185
|
+
def _on_focus_in(self, e):
|
|
186
|
+
self._focused = True
|
|
187
|
+
self._update_states()
|
|
188
|
+
|
|
189
|
+
def _on_focus_out(self, e):
|
|
190
|
+
self._focused = False
|
|
191
|
+
self._hovered = False
|
|
192
|
+
self._pressed = False
|
|
193
|
+
self._update_states()
|
|
194
|
+
|
|
195
|
+
def on_invoked(self, callback) -> str:
|
|
196
|
+
"""Bind to `<<CompositeInvoke>>`. Callback receives `event.data = None`. Fired when clicking on non-button registered widgets."""
|
|
197
|
+
return self._event_target.bind('<<CompositeInvoke>>', callback, add='+')
|
|
198
|
+
|
|
199
|
+
def off_invoked(self, bind_id: str | None = None) -> None:
|
|
200
|
+
"""Unbind from `<<CompositeInvoke>>`."""
|
|
201
|
+
return self._event_target.unbind('<<CompositeInvoke>>', bind_id)
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
class CompositeFrame(Frame):
|
|
205
|
+
"""A bootstack Frame that uses Composite for state coordination.
|
|
206
|
+
|
|
207
|
+
CompositeFrame is a convenience wrapper that combines ttk.Frame with the
|
|
208
|
+
Composite state coordinator. It provides a simple way to create containers
|
|
209
|
+
with synchronized state management across child widgets.
|
|
210
|
+
|
|
211
|
+
Attributes:
|
|
212
|
+
selected (bool): Read-only property for current selection state.
|
|
213
|
+
disabled (bool): Read-only property for current disabled state.
|
|
214
|
+
"""
|
|
215
|
+
|
|
216
|
+
def __init__(self, master: Master = None, select_on_click: bool = False, **kwargs: Any):
|
|
217
|
+
"""Initialize the CompositeFrame.
|
|
218
|
+
|
|
219
|
+
Args:
|
|
220
|
+
master: The parent widget.
|
|
221
|
+
select_on_click: If True, automatically toggles selection when
|
|
222
|
+
clicking on non-button registered widgets. Defaults to False.
|
|
223
|
+
**kwargs: Additional arguments passed to ttk.Frame constructor.
|
|
224
|
+
"""
|
|
225
|
+
super().__init__(master, **kwargs)
|
|
226
|
+
|
|
227
|
+
# Create composite coordinator with self as event target
|
|
228
|
+
self._composite = Composite(event_target=self, select_on_click=select_on_click)
|
|
229
|
+
|
|
230
|
+
# Register self to receive state updates
|
|
231
|
+
self._composite.register_composite(self)
|
|
232
|
+
|
|
233
|
+
def register_composite(self, widget):
|
|
234
|
+
"""Register a widget to participate in state synchronization.
|
|
235
|
+
|
|
236
|
+
Args:
|
|
237
|
+
widget: The ttk widget to register.
|
|
238
|
+
|
|
239
|
+
See Also:
|
|
240
|
+
Composite.register_composite for more details.
|
|
241
|
+
"""
|
|
242
|
+
return self._composite.register_composite(widget)
|
|
243
|
+
|
|
244
|
+
def set_selected(self, selected: bool):
|
|
245
|
+
"""Set the selected state.
|
|
246
|
+
|
|
247
|
+
Args:
|
|
248
|
+
selected: True to mark as selected, False to deselect.
|
|
249
|
+
|
|
250
|
+
See Also:
|
|
251
|
+
Composite.set_selected for more details.
|
|
252
|
+
"""
|
|
253
|
+
return self._composite.set_selected(selected)
|
|
254
|
+
|
|
255
|
+
def set_disabled(self, disabled: bool):
|
|
256
|
+
"""Set the disabled state.
|
|
257
|
+
|
|
258
|
+
Args:
|
|
259
|
+
disabled: True to mark as disabled, False to enable.
|
|
260
|
+
|
|
261
|
+
See Also:
|
|
262
|
+
Composite.set_disabled for more details.
|
|
263
|
+
"""
|
|
264
|
+
return self._composite.set_disabled(disabled)
|
|
265
|
+
|
|
266
|
+
@property
|
|
267
|
+
def selected(self):
|
|
268
|
+
"""bool: Current selection state (read-only)."""
|
|
269
|
+
return self._composite.selected
|
|
270
|
+
|
|
271
|
+
@property
|
|
272
|
+
def disabled(self):
|
|
273
|
+
"""bool: Current disabled state (read-only)."""
|
|
274
|
+
return self._composite.disabled
|
|
275
|
+
|
|
276
|
+
def on_invoked(self, callback) -> str:
|
|
277
|
+
"""Bind to `<<CompositeInvoke>>`. Callback receives `event.data = None`. Fired when clicking on non-button registered widgets."""
|
|
278
|
+
return self._composite.on_invoked(callback)
|
|
279
|
+
|
|
280
|
+
def off_invoked(self, bind_id: str | None = None) -> None:
|
|
281
|
+
"""Unbind from `<<CompositeInvoke>>`."""
|
|
282
|
+
return self._composite.off_invoked(bind_id)
|