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,364 @@
|
|
|
1
|
+
from tkinter import Widget, Misc
|
|
2
|
+
|
|
3
|
+
from bootstack.runtime.toplevel import Toplevel
|
|
4
|
+
from typing import Any, Callable, Literal, Optional, Sequence, Tuple, Union
|
|
5
|
+
|
|
6
|
+
from typing_extensions import TypedDict, Unpack
|
|
7
|
+
|
|
8
|
+
from bootstack.runtime.window_utilities import WindowPositioning, AnchorPoint
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class IconSpec(TypedDict, total=False):
|
|
12
|
+
"""Icon configuration for toast."""
|
|
13
|
+
name: str
|
|
14
|
+
size: Optional[int]
|
|
15
|
+
color: Optional[str]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ToastConfig(TypedDict, total=False):
|
|
19
|
+
"""Configuration options for Toast widget."""
|
|
20
|
+
title: Optional[str]
|
|
21
|
+
icon: Union[str, IconSpec, None]
|
|
22
|
+
message: Optional[str]
|
|
23
|
+
memo: Optional[str]
|
|
24
|
+
duration: Optional[int]
|
|
25
|
+
buttons: Optional[Sequence[dict[str, Any]]]
|
|
26
|
+
show_close_button: bool
|
|
27
|
+
accent: Optional[str]
|
|
28
|
+
bootstyle: Optional[str] # DEPRECATED: Use accent instead
|
|
29
|
+
position: Optional[str]
|
|
30
|
+
alert: bool
|
|
31
|
+
on_dismissed: Optional[Callable[[Any], Any]]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class Toast:
|
|
35
|
+
"""A notification toast widget that displays temporary messages.
|
|
36
|
+
|
|
37
|
+
Toast notifications appear in a small window, typically in the corner of the screen,
|
|
38
|
+
and can display a title, message, icon, buttons, and optional metadata. They can be
|
|
39
|
+
configured to auto-dismiss after a duration or remain visible until manually closed.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
def __init__(
|
|
43
|
+
self,
|
|
44
|
+
*,
|
|
45
|
+
title: Optional[str] = None,
|
|
46
|
+
icon: Union[str, IconSpec, None] = None,
|
|
47
|
+
message: Optional[str] = None,
|
|
48
|
+
memo: Optional[str] = None,
|
|
49
|
+
duration: Optional[int] = None,
|
|
50
|
+
buttons: Optional[Sequence[dict[str, Any]]] = None,
|
|
51
|
+
show_close_button: bool = True,
|
|
52
|
+
accent: Optional[str] = None,
|
|
53
|
+
bootstyle: Optional[str] = None,
|
|
54
|
+
position: Optional[str] = None,
|
|
55
|
+
alert: bool = False,
|
|
56
|
+
on_dismissed: Optional[Callable[[Any], Any]] = None,
|
|
57
|
+
) -> None:
|
|
58
|
+
"""Initialize a Toast notification.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
title (str): The toast title text. If provided without a message, it will be displayed
|
|
62
|
+
with a larger "label" font. If both title and message are provided, the title
|
|
63
|
+
appears in the header and the message appears in a separate section below.
|
|
64
|
+
icon (str | dict): Icon to display in the header. Can be a string icon name (e.g., "bootstrap-fill")
|
|
65
|
+
or an IconSpec dict with name, size, and color properties.
|
|
66
|
+
message (str): The main message text. If no title is provided, this message is displayed
|
|
67
|
+
in the header with a "body" font. If a title is provided, this appears in a
|
|
68
|
+
separate section below the header.
|
|
69
|
+
memo (str): Small metadata text displayed in the header (e.g., "5 mins ago"). Appears
|
|
70
|
+
with muted styling.
|
|
71
|
+
duration (int): Auto-dismiss duration in milliseconds. If None, the toast remains visible
|
|
72
|
+
until manually closed.
|
|
73
|
+
buttons (list): Sequence of button configurations. Each dict can contain any bootstack
|
|
74
|
+
button options (text, bootstyle, command, etc.). Button commands will trigger
|
|
75
|
+
the on_dismissed callback before closing the toast.
|
|
76
|
+
show_close_button (bool): Whether to show the close button in the header. Default is True.
|
|
77
|
+
accent (str): Accent token for the toast container (e.g., "primary", "success",
|
|
78
|
+
"danger"). If None, uses the default background color.
|
|
79
|
+
bootstyle (str): DEPRECATED - Use `accent` instead.
|
|
80
|
+
position (str): Tkinter geometry string for toast position (e.g., "-25-75" for bottom-right).
|
|
81
|
+
If None, uses platform-specific defaults.
|
|
82
|
+
alert (bool): If True, plays a system bell sound when the toast is shown.
|
|
83
|
+
on_dismissed (Callable): Callback function invoked when the toast is dismissed. Receives the
|
|
84
|
+
button options dict if dismissed via a button, or None if dismissed via close
|
|
85
|
+
button or auto-dismiss.
|
|
86
|
+
"""
|
|
87
|
+
self._config_keys = {'title', 'icon', 'message', 'memo', 'duration', 'buttons', 'show_close_button',
|
|
88
|
+
'accent', 'bootstyle', 'position', 'alert', 'on_dismissed'}
|
|
89
|
+
|
|
90
|
+
# initialized configuration
|
|
91
|
+
self._title = title
|
|
92
|
+
self._icon = icon
|
|
93
|
+
self._message = message
|
|
94
|
+
self._memo = memo
|
|
95
|
+
self._duration = duration
|
|
96
|
+
self._buttons = buttons
|
|
97
|
+
self._show_close_button = show_close_button
|
|
98
|
+
self._accent = accent or bootstyle # Support legacy bootstyle parameter
|
|
99
|
+
self._bootstyle = bootstyle # Keep for backwards compatibility
|
|
100
|
+
self._position = position
|
|
101
|
+
self._alert = alert
|
|
102
|
+
self._on_dismissed = on_dismissed
|
|
103
|
+
|
|
104
|
+
# top level widget
|
|
105
|
+
self._toplevel: Optional[Toplevel] = None
|
|
106
|
+
|
|
107
|
+
def __setitem__(self, key: str, value: Any) -> None:
|
|
108
|
+
"""Set a configuration option using dictionary syntax."""
|
|
109
|
+
self.configure(**{key: value})
|
|
110
|
+
|
|
111
|
+
def __getitem__(self, key: str) -> Any:
|
|
112
|
+
"""Get a configuration option using dictionary syntax."""
|
|
113
|
+
return self.cget(key)
|
|
114
|
+
|
|
115
|
+
def _handle_on_dismissed(self, data: Any = None) -> None:
|
|
116
|
+
"""Invoke the on_dismissed callback if configured."""
|
|
117
|
+
if self._on_dismissed:
|
|
118
|
+
self._on_dismissed(data)
|
|
119
|
+
|
|
120
|
+
def configure(
|
|
121
|
+
self,
|
|
122
|
+
option: Optional[str] = None,
|
|
123
|
+
**kwargs: Unpack[ToastConfig]
|
|
124
|
+
) -> Optional[tuple[str, str, str, None, Any]]:
|
|
125
|
+
"""Configure toast options.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
option: If provided, returns the configuration for this option.
|
|
129
|
+
**kwargs: Configuration options to set.
|
|
130
|
+
|
|
131
|
+
Returns:
|
|
132
|
+
Configuration tuple if option provided, otherwise None.
|
|
133
|
+
"""
|
|
134
|
+
if option is not None:
|
|
135
|
+
if option in self._config_keys:
|
|
136
|
+
attr = f"_{option}"
|
|
137
|
+
value = getattr(self, attr)
|
|
138
|
+
# returns in the expected tkinter.configure format
|
|
139
|
+
return option, option, option.capitalize(), None, value
|
|
140
|
+
else:
|
|
141
|
+
raise AttributeError(f"'{option}' is not a valid option")
|
|
142
|
+
|
|
143
|
+
if kwargs:
|
|
144
|
+
for key, value in kwargs.items():
|
|
145
|
+
if key in self._config_keys:
|
|
146
|
+
attr = f"_{key}"
|
|
147
|
+
setattr(self, attr, value)
|
|
148
|
+
else:
|
|
149
|
+
raise AttributeError(f"'{key}' is not a valid option")
|
|
150
|
+
return None
|
|
151
|
+
|
|
152
|
+
def cget(self, option: str) -> Any:
|
|
153
|
+
"""Get the value of a configuration option.
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
option: The configuration option name.
|
|
157
|
+
|
|
158
|
+
Returns:
|
|
159
|
+
The value of the configuration option.
|
|
160
|
+
"""
|
|
161
|
+
if option in self._config_keys:
|
|
162
|
+
attr = f"_{option}"
|
|
163
|
+
return getattr(self, attr)
|
|
164
|
+
else:
|
|
165
|
+
raise AttributeError(f"'{option}' is not a valid option")
|
|
166
|
+
|
|
167
|
+
def show(self, merge: bool = True, **options: Unpack[ToastConfig]) -> None:
|
|
168
|
+
"""Display the toast.
|
|
169
|
+
|
|
170
|
+
If options are provided, they are merged with the existing toast configuration. If you do not want this
|
|
171
|
+
behavior, set the merge flag to False, or create a new toast instance.
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
merge: If True, merge options with existing configuration. If False, clear existing options first.
|
|
175
|
+
**options: Configuration options to set before showing.
|
|
176
|
+
"""
|
|
177
|
+
if not merge:
|
|
178
|
+
self._clear_options()
|
|
179
|
+
|
|
180
|
+
self.configure(**options)
|
|
181
|
+
self._build_toast()
|
|
182
|
+
if self._toplevel:
|
|
183
|
+
self._toplevel.deiconify()
|
|
184
|
+
|
|
185
|
+
def _clear_options(self) -> None:
|
|
186
|
+
"""Clear all configuration options to their default values."""
|
|
187
|
+
self._title = None
|
|
188
|
+
self._icon = None
|
|
189
|
+
self._message = None
|
|
190
|
+
self._memo = None
|
|
191
|
+
self._duration = None
|
|
192
|
+
self._buttons = None
|
|
193
|
+
self._show_close_button = True
|
|
194
|
+
self._accent = None
|
|
195
|
+
self._bootstyle = None
|
|
196
|
+
self._position = None
|
|
197
|
+
self._alert = False
|
|
198
|
+
self._on_dismissed = None
|
|
199
|
+
|
|
200
|
+
def hide(self) -> None:
|
|
201
|
+
"""Hide the toast and trigger the on_dismissed callback."""
|
|
202
|
+
if self._toplevel:
|
|
203
|
+
self._toplevel.destroy()
|
|
204
|
+
self._handle_on_dismissed(None)
|
|
205
|
+
|
|
206
|
+
def destroy(self) -> None:
|
|
207
|
+
"""Destroy the toast widget and cleanup resources."""
|
|
208
|
+
if hasattr(self, '_toplevel') and self._toplevel:
|
|
209
|
+
self._toplevel.destroy()
|
|
210
|
+
self._toplevel = None
|
|
211
|
+
|
|
212
|
+
def _build_toast(self) -> None:
|
|
213
|
+
import bootstack as bs
|
|
214
|
+
# ----- Configuration Options -------
|
|
215
|
+
|
|
216
|
+
has_title = self._title is not None
|
|
217
|
+
has_title_and_message = has_title and self._message is not None
|
|
218
|
+
resolved_title_font = "label" if has_title else "body"
|
|
219
|
+
muted_foreground = "background[muted]" if self._accent is None else f"{self._accent}[muted]"
|
|
220
|
+
|
|
221
|
+
# ------ Toplevel setup ------
|
|
222
|
+
|
|
223
|
+
# bootstack.Toplevel applies MacWindowStyle 'help none' on Aqua
|
|
224
|
+
# via windowtype='tooltip', so toasts render chromeless on Mac
|
|
225
|
+
# (overrideredirect alone is silently skipped on Aqua per the
|
|
226
|
+
# project's BaseWindow guard). Win/Linux keep the overrideredirect
|
|
227
|
+
# path. Topmost + alpha are passed as kwargs so the Toplevel sets
|
|
228
|
+
# them at the right moment in its setup pipeline.
|
|
229
|
+
top = Toplevel(
|
|
230
|
+
overrideredirect=True,
|
|
231
|
+
topmost=True,
|
|
232
|
+
alpha=0.97,
|
|
233
|
+
windowtype='tooltip',
|
|
234
|
+
)
|
|
235
|
+
top.minsize(400, 30)
|
|
236
|
+
|
|
237
|
+
# ------ Toast Layout ------
|
|
238
|
+
|
|
239
|
+
container = bs.Frame(top, padding=4, accent=self._accent)
|
|
240
|
+
container.pack(fill='both', expand=True)
|
|
241
|
+
|
|
242
|
+
header = bs.Frame(container, padding=(8, 0, 0, 0))
|
|
243
|
+
header.pack(side='top', fill='x')
|
|
244
|
+
|
|
245
|
+
# icon
|
|
246
|
+
if self._icon:
|
|
247
|
+
bs.Label(header, icon=self._icon).pack(side='left', padx=(0, 8))
|
|
248
|
+
|
|
249
|
+
# title
|
|
250
|
+
bs.Label(
|
|
251
|
+
header,
|
|
252
|
+
text=self._title if has_title else self._message,
|
|
253
|
+
font=resolved_title_font,
|
|
254
|
+
wraplength=380,
|
|
255
|
+
justify='left',
|
|
256
|
+
).pack(side='left', fill='x')
|
|
257
|
+
|
|
258
|
+
# close
|
|
259
|
+
if self._show_close_button:
|
|
260
|
+
bs.Button(
|
|
261
|
+
header,
|
|
262
|
+
icon="x-lg",
|
|
263
|
+
accent=muted_foreground,
|
|
264
|
+
variant="text",
|
|
265
|
+
style_options={"icon_only": True},
|
|
266
|
+
command=self.hide
|
|
267
|
+
).pack(side='right')
|
|
268
|
+
|
|
269
|
+
# memo
|
|
270
|
+
if self._memo:
|
|
271
|
+
bs.Label(
|
|
272
|
+
header,
|
|
273
|
+
text=self._memo,
|
|
274
|
+
font="caption",
|
|
275
|
+
accent=muted_foreground,
|
|
276
|
+
).pack(side='right', pady=8, padx=(0, 0 if self._show_close_button else 12))
|
|
277
|
+
|
|
278
|
+
# message
|
|
279
|
+
if has_title_and_message:
|
|
280
|
+
bs.Separator(container).pack(side='top', fill='x')
|
|
281
|
+
bs.Label(
|
|
282
|
+
container,
|
|
283
|
+
text=self._message,
|
|
284
|
+
wraplength=400,
|
|
285
|
+
justify='left'
|
|
286
|
+
).pack(side='top', fill='x', pady=8, padx=8)
|
|
287
|
+
|
|
288
|
+
# buttons
|
|
289
|
+
if self._buttons:
|
|
290
|
+
def execute_command(options: dict[str, Any], fn: Optional[Callable[[], None]] = None) -> Callable[[], None]:
|
|
291
|
+
def inner() -> None:
|
|
292
|
+
if fn:
|
|
293
|
+
fn()
|
|
294
|
+
self._handle_on_dismissed(options)
|
|
295
|
+
top.destroy()
|
|
296
|
+
|
|
297
|
+
return inner
|
|
298
|
+
|
|
299
|
+
bs.Separator(container).pack(side='top', fill='x', pady=4)
|
|
300
|
+
button_frame = bs.Frame(container)
|
|
301
|
+
button_frame.pack(side='top', fill='x')
|
|
302
|
+
|
|
303
|
+
for i, button_options in enumerate(self._buttons):
|
|
304
|
+
func = button_options.get('command', None)
|
|
305
|
+
button_opts = {k: v for k, v in button_options.items() if k != 'command'}
|
|
306
|
+
bs.Button(
|
|
307
|
+
button_frame,
|
|
308
|
+
**button_opts,
|
|
309
|
+
command=execute_command(button_options, func)
|
|
310
|
+
).grid(column=i, row=0, sticky="ew")
|
|
311
|
+
|
|
312
|
+
# ------ Positioning -------
|
|
313
|
+
|
|
314
|
+
# Update layout to get final window size
|
|
315
|
+
top.update_idletasks()
|
|
316
|
+
|
|
317
|
+
# Apply positioning using WindowPositioning utilities
|
|
318
|
+
if self._position:
|
|
319
|
+
# Support legacy geometry strings (e.g., "-25-75")
|
|
320
|
+
if self._position.startswith(('+', '-')):
|
|
321
|
+
# Legacy geometry string - use directly
|
|
322
|
+
top.geometry(self._position)
|
|
323
|
+
else:
|
|
324
|
+
# New positioning - assume it's a corner specification
|
|
325
|
+
# (future enhancement: could support more complex positioning)
|
|
326
|
+
top.geometry(self._position)
|
|
327
|
+
else:
|
|
328
|
+
# Default positioning based on platform
|
|
329
|
+
winsys = top.tk.call('tk', 'windowingsystem')
|
|
330
|
+
if winsys in ['win32', 'aqua']:
|
|
331
|
+
# Bottom-right corner
|
|
332
|
+
WindowPositioning.position_anchored(
|
|
333
|
+
window=top,
|
|
334
|
+
anchor_to="screen",
|
|
335
|
+
parent=None,
|
|
336
|
+
anchor_point="se",
|
|
337
|
+
window_point="se",
|
|
338
|
+
offset=(-25, -75),
|
|
339
|
+
auto_flip=False,
|
|
340
|
+
ensure_visible=True
|
|
341
|
+
)
|
|
342
|
+
else:
|
|
343
|
+
# Top-right corner for X11
|
|
344
|
+
WindowPositioning.position_anchored(
|
|
345
|
+
window=top,
|
|
346
|
+
anchor_to="screen",
|
|
347
|
+
parent=None,
|
|
348
|
+
anchor_point="ne",
|
|
349
|
+
window_point="ne",
|
|
350
|
+
offset=(-25, 25),
|
|
351
|
+
auto_flip=False,
|
|
352
|
+
ensure_visible=True
|
|
353
|
+
)
|
|
354
|
+
|
|
355
|
+
# ------ Other setup -------
|
|
356
|
+
|
|
357
|
+
if self._duration:
|
|
358
|
+
top.after(self._duration, self.hide)
|
|
359
|
+
|
|
360
|
+
if self._alert:
|
|
361
|
+
top.bell()
|
|
362
|
+
|
|
363
|
+
self._toplevel = top
|
|
364
|
+
|