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,434 @@
|
|
|
1
|
+
from tkinter import Canvas, Event, IntVar, StringVar
|
|
2
|
+
from typing import Any, Optional, Union
|
|
3
|
+
|
|
4
|
+
from bootstack.widgets.mixins.configure_mixin import ConfigureDelegationMixin, configure_delegate
|
|
5
|
+
from bootstack.widgets.types import Master
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class FloodGauge(ConfigureDelegationMixin, Canvas):
|
|
9
|
+
"""A canvas-based progress widget with determinate and indeterminate modes.
|
|
10
|
+
|
|
11
|
+
Provides an enhanced alternative to ttk.Progressbar with full styling control,
|
|
12
|
+
horizontal/vertical orientations, customizable text overlays with format masks,
|
|
13
|
+
and bounce-style animation for indeterminate mode.
|
|
14
|
+
|
|
15
|
+
Attributes:
|
|
16
|
+
variable (IntVar): Tkinter IntVar for value binding.
|
|
17
|
+
textvariable (StringVar): Tkinter StringVar for text binding.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
master: Master = None,
|
|
23
|
+
value: int = 0,
|
|
24
|
+
maximum: int = 100,
|
|
25
|
+
mode: str = "determinate",
|
|
26
|
+
mask: Optional[str] = None,
|
|
27
|
+
text: str = "",
|
|
28
|
+
font: Union[tuple[str, int], str] = ("Helvetica", 12),
|
|
29
|
+
accent: str = None,
|
|
30
|
+
orient: str = "horizontal",
|
|
31
|
+
length: int = 200,
|
|
32
|
+
thickness: int = 50,
|
|
33
|
+
increment: int = 1,
|
|
34
|
+
**kwargs: Any
|
|
35
|
+
) -> None:
|
|
36
|
+
"""Initialize a FloodGauge widget.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
master: Parent widget. If None, uses the default root window.
|
|
40
|
+
value (int): Initial progress value (0-maximum).
|
|
41
|
+
maximum (int): Maximum value for determinate range.
|
|
42
|
+
mode (str): Progress mode - `'determinate'` for known progress or
|
|
43
|
+
`'indeterminate'` for unknown duration.
|
|
44
|
+
mask (str): Format string for text overlay with `'{}'` placeholder for
|
|
45
|
+
the value. Examples: `'{}% Complete'` or `'Progress: {}/100'`.
|
|
46
|
+
If None, no automatic text formatting is applied.
|
|
47
|
+
text (str): Static text label shown when no mask is specified.
|
|
48
|
+
font (tuple | str): Font specification as tuple `(family, size)` or
|
|
49
|
+
string like `'Arial 12 bold'`.
|
|
50
|
+
accent (str): Accent token from bootstack (e.g., `'primary'`,
|
|
51
|
+
`'success'`, `'info'`, `'warning'`, `'danger'`).
|
|
52
|
+
orient (str): Widget orientation - `'horizontal'` or `'vertical'`.
|
|
53
|
+
length (int): Size in pixels along the main axis (width if horizontal,
|
|
54
|
+
height if vertical).
|
|
55
|
+
thickness (int): Size in pixels along the minor axis (height if horizontal,
|
|
56
|
+
width if vertical).
|
|
57
|
+
increment (int): Step size for value changes when using `step()` method
|
|
58
|
+
or during animations.
|
|
59
|
+
|
|
60
|
+
Other Parameters:
|
|
61
|
+
variable (IntVar): Tkinter IntVar for value binding.
|
|
62
|
+
textvariable (StringVar): Tkinter StringVar for text binding.
|
|
63
|
+
|
|
64
|
+
Note:
|
|
65
|
+
The widget automatically updates colors when the theme changes via the
|
|
66
|
+
`<<ThemeChanged>>` event. When using variable or textvariable bindings,
|
|
67
|
+
the widget redraws automatically when the variables change.
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
# Handle deprecated bootstyle parameter
|
|
71
|
+
bootstyle = kwargs.pop("bootstyle", None)
|
|
72
|
+
|
|
73
|
+
self._variable = kwargs.pop("variable", IntVar(value=value))
|
|
74
|
+
self._value = self._variable.get()
|
|
75
|
+
|
|
76
|
+
self._textvariable = kwargs.pop("textvariable", StringVar(value=text))
|
|
77
|
+
self._text = self._textvariable.get()
|
|
78
|
+
|
|
79
|
+
self._mode = mode
|
|
80
|
+
self._mask = mask
|
|
81
|
+
self._font = font
|
|
82
|
+
self._accent = accent or bootstyle or "primary"
|
|
83
|
+
self._orient = orient
|
|
84
|
+
self._length = length
|
|
85
|
+
self._thickness = thickness
|
|
86
|
+
self._maximum = maximum
|
|
87
|
+
self._increment = increment
|
|
88
|
+
|
|
89
|
+
self._running = False
|
|
90
|
+
self._after_id = None
|
|
91
|
+
self._pulse_pos = 0
|
|
92
|
+
self._pulse_direction = 1
|
|
93
|
+
|
|
94
|
+
canvas_kwargs = dict(highlightthickness=0, **kwargs)
|
|
95
|
+
if self._orient == "horizontal":
|
|
96
|
+
canvas_kwargs.update(width=self._length, height=self._thickness)
|
|
97
|
+
else:
|
|
98
|
+
canvas_kwargs.update(width=self._thickness, height=self._length)
|
|
99
|
+
|
|
100
|
+
super().__init__(master, **canvas_kwargs)
|
|
101
|
+
|
|
102
|
+
self._variable_trace_id = self._variable.trace_add("write", lambda n, i, m: self._on_var_change())
|
|
103
|
+
self._textvariable_trace_id = self._textvariable.trace_add("write", lambda n, i, m: self._on_text_change())
|
|
104
|
+
|
|
105
|
+
self._update_theme_colors()
|
|
106
|
+
|
|
107
|
+
self.bind("<Configure>", self._on_resize)
|
|
108
|
+
|
|
109
|
+
# Bind to root to receive theme change events
|
|
110
|
+
root = self.nametowidget('.')
|
|
111
|
+
root.bind('<<ThemeChanged>>', lambda e: self._update_theme_colors(), add='+')
|
|
112
|
+
|
|
113
|
+
self._draw()
|
|
114
|
+
|
|
115
|
+
def destroy(self) -> None:
|
|
116
|
+
"""Clean up resources before destroying the widget."""
|
|
117
|
+
self.stop()
|
|
118
|
+
|
|
119
|
+
# Remove traces to prevent memory leaks
|
|
120
|
+
if hasattr(self, '_variable') and hasattr(self, '_variable_trace_id'):
|
|
121
|
+
try:
|
|
122
|
+
self._variable.trace_remove('write', self._variable_trace_id)
|
|
123
|
+
except Exception:
|
|
124
|
+
pass
|
|
125
|
+
|
|
126
|
+
if hasattr(self, '_textvariable') and hasattr(self, '_textvariable_trace_id'):
|
|
127
|
+
try:
|
|
128
|
+
self._textvariable.trace_remove('write', self._textvariable_trace_id)
|
|
129
|
+
except Exception:
|
|
130
|
+
pass
|
|
131
|
+
|
|
132
|
+
super().destroy()
|
|
133
|
+
|
|
134
|
+
# ----- Configuration Delegates ------
|
|
135
|
+
|
|
136
|
+
@configure_delegate('mode')
|
|
137
|
+
def _delegate_mode(self, value=None):
|
|
138
|
+
if value is None:
|
|
139
|
+
return self._mode
|
|
140
|
+
self._mode = value
|
|
141
|
+
self._draw()
|
|
142
|
+
|
|
143
|
+
@configure_delegate('mask')
|
|
144
|
+
def _delegate_mask(self, value=None):
|
|
145
|
+
if value is None:
|
|
146
|
+
return self._mask
|
|
147
|
+
self._mask = value
|
|
148
|
+
self._draw()
|
|
149
|
+
|
|
150
|
+
@configure_delegate('font')
|
|
151
|
+
def _delegate_font(self, value=None):
|
|
152
|
+
if value is None:
|
|
153
|
+
return self._font
|
|
154
|
+
self._font = value
|
|
155
|
+
self._draw()
|
|
156
|
+
|
|
157
|
+
@configure_delegate('bootstyle')
|
|
158
|
+
def _delegate_bootstyle(self, value=None):
|
|
159
|
+
if value is None:
|
|
160
|
+
return self._accent
|
|
161
|
+
self._accent = value
|
|
162
|
+
self._update_theme_colors() # calls _draw()
|
|
163
|
+
|
|
164
|
+
@configure_delegate('accent')
|
|
165
|
+
def _delegate_accent(self, value=None):
|
|
166
|
+
if value is None:
|
|
167
|
+
return self._accent
|
|
168
|
+
self._accent = value
|
|
169
|
+
self._update_theme_colors() # calls _draw()
|
|
170
|
+
|
|
171
|
+
@configure_delegate('orient')
|
|
172
|
+
def _delegate_orient(self, value=None):
|
|
173
|
+
if value is None:
|
|
174
|
+
return self._orient
|
|
175
|
+
self._orient = value
|
|
176
|
+
self._draw()
|
|
177
|
+
|
|
178
|
+
@configure_delegate('length')
|
|
179
|
+
def _delegate_length(self, value=None):
|
|
180
|
+
if value is None:
|
|
181
|
+
return self._length
|
|
182
|
+
self._length = value
|
|
183
|
+
if self._orient == "horizontal":
|
|
184
|
+
self.configure(width=self._length)
|
|
185
|
+
else:
|
|
186
|
+
self.configure(height=self._length)
|
|
187
|
+
self._draw()
|
|
188
|
+
|
|
189
|
+
@configure_delegate('thickness')
|
|
190
|
+
def _delegate_thickness(self, value=None):
|
|
191
|
+
if value is None:
|
|
192
|
+
return self._thickness
|
|
193
|
+
self._thickness = value
|
|
194
|
+
if self._orient == "horizontal":
|
|
195
|
+
self.configure(height=self._thickness)
|
|
196
|
+
else:
|
|
197
|
+
self.configure(width=self._thickness)
|
|
198
|
+
self._draw()
|
|
199
|
+
|
|
200
|
+
@configure_delegate('maximum')
|
|
201
|
+
def _delegate_maximum(self, value=None):
|
|
202
|
+
if value is None:
|
|
203
|
+
return self._maximum
|
|
204
|
+
self._maximum = value
|
|
205
|
+
self._draw()
|
|
206
|
+
|
|
207
|
+
@configure_delegate('increment')
|
|
208
|
+
def _delegate_increment(self, value=None):
|
|
209
|
+
if value is None:
|
|
210
|
+
return self._increment
|
|
211
|
+
self._increment = value
|
|
212
|
+
self._draw()
|
|
213
|
+
|
|
214
|
+
@configure_delegate('value')
|
|
215
|
+
def _delegate_value(self, value=None):
|
|
216
|
+
if value is None:
|
|
217
|
+
return self._value
|
|
218
|
+
# Variable trace triggers redraw
|
|
219
|
+
self._variable.set(value)
|
|
220
|
+
|
|
221
|
+
def get(self) -> int:
|
|
222
|
+
"""Return the current progress value."""
|
|
223
|
+
return self._value
|
|
224
|
+
|
|
225
|
+
def set(self, value: int) -> None:
|
|
226
|
+
"""Set the progress value.
|
|
227
|
+
|
|
228
|
+
Args:
|
|
229
|
+
value: The new progress value.
|
|
230
|
+
"""
|
|
231
|
+
self._variable.set(value)
|
|
232
|
+
|
|
233
|
+
@property
|
|
234
|
+
def value(self) -> int:
|
|
235
|
+
"""Get or set the progress value."""
|
|
236
|
+
return self.get()
|
|
237
|
+
|
|
238
|
+
@value.setter
|
|
239
|
+
def value(self, value: int) -> None:
|
|
240
|
+
self.set(value)
|
|
241
|
+
|
|
242
|
+
@configure_delegate('text')
|
|
243
|
+
def _delegate_text(self, value=None):
|
|
244
|
+
if value is None:
|
|
245
|
+
return self._text
|
|
246
|
+
# Textvariable trace triggers redraw
|
|
247
|
+
self._textvariable.set(value)
|
|
248
|
+
|
|
249
|
+
@configure_delegate('variable')
|
|
250
|
+
def _delegate_variable(self, value=None):
|
|
251
|
+
if value is None:
|
|
252
|
+
return self._variable
|
|
253
|
+
self._variable.trace_remove('write', self._variable_trace_id)
|
|
254
|
+
self._variable = value
|
|
255
|
+
self._variable_trace_id = self._variable.trace_add("write", lambda n, i, m: self._on_var_change())
|
|
256
|
+
self._value = self._variable.get()
|
|
257
|
+
self._draw()
|
|
258
|
+
|
|
259
|
+
@configure_delegate('textvariable')
|
|
260
|
+
def _delegate_textvariable(self, value=None):
|
|
261
|
+
if value is None:
|
|
262
|
+
return self._textvariable
|
|
263
|
+
self._textvariable.trace_remove('write', self._textvariable_trace_id)
|
|
264
|
+
self._textvariable = value
|
|
265
|
+
self._textvariable_trace_id = self._textvariable.trace_add("write", lambda n, i, m: self._on_text_change())
|
|
266
|
+
self._text = self._textvariable.get()
|
|
267
|
+
self._draw()
|
|
268
|
+
|
|
269
|
+
def _update_theme_colors(self) -> None:
|
|
270
|
+
"""Update widget colors based on current theme and bootstyle."""
|
|
271
|
+
from bootstack.style.style import get_style
|
|
272
|
+
style = get_style()
|
|
273
|
+
b = style.style_builder
|
|
274
|
+
surface = b.color('background')
|
|
275
|
+
self._bar_color = b.color(self._accent)
|
|
276
|
+
self._trough_color = b.border(b.subtle(self._accent, surface))
|
|
277
|
+
self._text_color = b.on_color(self._bar_color)
|
|
278
|
+
self._draw()
|
|
279
|
+
|
|
280
|
+
def _on_resize(self, event: Event) -> None:
|
|
281
|
+
"""Handle widget resize events and update dimensions."""
|
|
282
|
+
if self._orient == "horizontal":
|
|
283
|
+
self._length = event.width
|
|
284
|
+
self._thickness = event.height
|
|
285
|
+
else:
|
|
286
|
+
self._length = event.height
|
|
287
|
+
self._thickness = event.width
|
|
288
|
+
self._draw()
|
|
289
|
+
|
|
290
|
+
def _draw(self) -> None:
|
|
291
|
+
"""Render the progress bar and text overlay on the canvas."""
|
|
292
|
+
self.delete("all")
|
|
293
|
+
# Fallback to configured dimensions if widget not yet mapped
|
|
294
|
+
w = self.winfo_width() or (self._length if self._orient == "horizontal" else self._thickness)
|
|
295
|
+
h = self.winfo_height() or (self._thickness if self._orient == "horizontal" else self._length)
|
|
296
|
+
|
|
297
|
+
self.create_rectangle(0, 0, w, h, fill=self._trough_color, width=0)
|
|
298
|
+
|
|
299
|
+
if self._mode == "determinate":
|
|
300
|
+
ratio = max(0.0, min(1.0, self._value / self._maximum)) if self._maximum > 0 else 0.0
|
|
301
|
+
if self._orient == "horizontal":
|
|
302
|
+
fill = int(ratio * w)
|
|
303
|
+
self.create_rectangle(0, 0, fill, h, fill=self._bar_color, width=0)
|
|
304
|
+
else:
|
|
305
|
+
fill = int(ratio * h)
|
|
306
|
+
self.create_rectangle(0, h - fill, w, h, fill=self._bar_color, width=0)
|
|
307
|
+
else:
|
|
308
|
+
if self._orient == "horizontal":
|
|
309
|
+
pulse_width = max(10, int(w * 0.2))
|
|
310
|
+
x = self._pulse_pos
|
|
311
|
+
self.create_rectangle(x, 0, x + pulse_width, h, fill=self._bar_color, width=0)
|
|
312
|
+
else:
|
|
313
|
+
pulse_height = max(10, int(h * 0.2))
|
|
314
|
+
y = self._pulse_pos
|
|
315
|
+
self.create_rectangle(0, y - pulse_height, w, y, fill=self._bar_color, width=0)
|
|
316
|
+
|
|
317
|
+
if self._mask:
|
|
318
|
+
try:
|
|
319
|
+
label = self._mask.format(int(self._value))
|
|
320
|
+
except (ValueError, KeyError, IndexError):
|
|
321
|
+
label = str(int(self._value))
|
|
322
|
+
# Remove trace to avoid recursive redraw
|
|
323
|
+
self._textvariable.trace_remove('write', self._textvariable_trace_id)
|
|
324
|
+
self._textvariable.set(label)
|
|
325
|
+
self._textvariable_trace_id = self._textvariable.trace_add("write", lambda n, i, m: self._on_text_change())
|
|
326
|
+
elif self._textvariable:
|
|
327
|
+
label = self._textvariable.get()
|
|
328
|
+
else:
|
|
329
|
+
label = self._text
|
|
330
|
+
|
|
331
|
+
if label:
|
|
332
|
+
self.create_text(
|
|
333
|
+
w // 2,
|
|
334
|
+
h // 2,
|
|
335
|
+
text=label,
|
|
336
|
+
font=self._font,
|
|
337
|
+
fill=self._text_color,
|
|
338
|
+
anchor="center"
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
def _on_var_change(self) -> None:
|
|
342
|
+
"""Handle changes to the value variable."""
|
|
343
|
+
self._value = self._variable.get()
|
|
344
|
+
self._draw()
|
|
345
|
+
|
|
346
|
+
def _on_text_change(self) -> None:
|
|
347
|
+
"""Handle changes to the text variable."""
|
|
348
|
+
self._text = self._textvariable.get()
|
|
349
|
+
self._draw()
|
|
350
|
+
|
|
351
|
+
def step(self, amount: int = 1) -> None:
|
|
352
|
+
"""Increment the progress value by the specified amount.
|
|
353
|
+
|
|
354
|
+
Args:
|
|
355
|
+
amount (int): Amount to increment. Value wraps around after reaching
|
|
356
|
+
maximum.
|
|
357
|
+
"""
|
|
358
|
+
self._value = (self._value + amount) % (self._maximum + 1)
|
|
359
|
+
self._variable.set(self._value)
|
|
360
|
+
self._draw()
|
|
361
|
+
|
|
362
|
+
def start(self, step_size: Optional[int] = None, interval: Optional[int] = None) -> None:
|
|
363
|
+
"""Start the progress animation.
|
|
364
|
+
|
|
365
|
+
For indeterminate mode, starts bouncing animation. For determinate mode,
|
|
366
|
+
auto-increments the value at regular intervals.
|
|
367
|
+
|
|
368
|
+
Args:
|
|
369
|
+
step_size (int): Amount to increment per animation step. Defaults to 8
|
|
370
|
+
for indeterminate mode, 1 for determinate mode.
|
|
371
|
+
interval (int): Time in milliseconds between animation steps. Defaults
|
|
372
|
+
to 20ms for indeterminate mode, 50ms for determinate mode.
|
|
373
|
+
"""
|
|
374
|
+
if self._mode == "indeterminate":
|
|
375
|
+
self._increment = step_size if step_size is not None else 8
|
|
376
|
+
interval = interval if interval is not None else 20
|
|
377
|
+
else:
|
|
378
|
+
self._increment = step_size if step_size is not None else 1
|
|
379
|
+
interval = interval if interval is not None else 50
|
|
380
|
+
|
|
381
|
+
self._running = True
|
|
382
|
+
self._pulse_pos = 0 # Reset position
|
|
383
|
+
self._pulse_direction = 1
|
|
384
|
+
self._run_animation(interval)
|
|
385
|
+
|
|
386
|
+
def stop(self) -> None:
|
|
387
|
+
"""Stop the progress animation and cancel any scheduled updates."""
|
|
388
|
+
self._running = False
|
|
389
|
+
if self._after_id:
|
|
390
|
+
self.after_cancel(self._after_id)
|
|
391
|
+
self._after_id = None
|
|
392
|
+
|
|
393
|
+
def _run_animation(self, interval: int) -> None:
|
|
394
|
+
"""Execute one animation frame and schedule the next."""
|
|
395
|
+
if not self._running:
|
|
396
|
+
return
|
|
397
|
+
|
|
398
|
+
if self._mode == "indeterminate":
|
|
399
|
+
self._animate_indeterminate(interval)
|
|
400
|
+
else:
|
|
401
|
+
self.step(self._increment)
|
|
402
|
+
self._after_id = self.after(interval, lambda: self._run_animation(interval))
|
|
403
|
+
|
|
404
|
+
def _animate_indeterminate(self, interval: int) -> None:
|
|
405
|
+
"""Animate the bouncing pulse for indeterminate mode."""
|
|
406
|
+
if not self._running:
|
|
407
|
+
return
|
|
408
|
+
|
|
409
|
+
if self._orient == "horizontal":
|
|
410
|
+
w = self.winfo_width()
|
|
411
|
+
pulse_width = max(10, int(w * 0.2))
|
|
412
|
+
max_pos = w - pulse_width
|
|
413
|
+
self._pulse_pos += self._increment * self._pulse_direction
|
|
414
|
+
if self._pulse_pos >= max_pos:
|
|
415
|
+
self._pulse_pos = max_pos
|
|
416
|
+
self._pulse_direction = -1
|
|
417
|
+
elif self._pulse_pos <= 0:
|
|
418
|
+
self._pulse_pos = 0
|
|
419
|
+
self._pulse_direction = 1
|
|
420
|
+
else:
|
|
421
|
+
h = self.winfo_height()
|
|
422
|
+
pulse_height = max(10, int(h * 0.2))
|
|
423
|
+
max_pos = h
|
|
424
|
+
self._pulse_pos += self._increment * self._pulse_direction
|
|
425
|
+
if self._pulse_pos >= max_pos:
|
|
426
|
+
self._pulse_pos = max_pos
|
|
427
|
+
self._pulse_direction = -1
|
|
428
|
+
elif self._pulse_pos <= pulse_height:
|
|
429
|
+
self._pulse_pos = pulse_height
|
|
430
|
+
self._pulse_direction = 1
|
|
431
|
+
|
|
432
|
+
self._draw()
|
|
433
|
+
self._after_id = self.after(interval, lambda: self._animate_indeterminate(interval))
|
|
434
|
+
|