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,507 @@
|
|
|
1
|
+
"""Bootstyle parsing and widget integration for bootstack.
|
|
2
|
+
|
|
3
|
+
Handles parsing of bootstyle strings and provides integration layer between
|
|
4
|
+
user-friendly bootstyle syntax and TTK style names.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import Optional
|
|
10
|
+
|
|
11
|
+
from bootstack.runtime.app import get_app_settings
|
|
12
|
+
from bootstack.core.exceptions import BootstyleParsingError
|
|
13
|
+
from bootstack.style.token_maps import (COLOR_TOKENS, CONTAINER_CLASSES, ORIENT_CLASSES, WIDGET_CLASS_MAP)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def parse_bootstyle_v2(bootstyle: str, widget_class: str) -> dict:
|
|
18
|
+
"""Parse bootstyle string using V2 syntax (dash-separated).
|
|
19
|
+
|
|
20
|
+
Syntax: `accent-variant-widget` where all parts are optional.
|
|
21
|
+
Checks actual theme colors and registered variants. Unknown parts are
|
|
22
|
+
treated as custom colors.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
bootstyle: Bootstyle string (e.g., "success-outline", "primary")
|
|
26
|
+
widget_class: TTK widget class name (e.g., "TButton")
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
Dict with: accent, variant, widget_class, cross_widget
|
|
30
|
+
"""
|
|
31
|
+
if not bootstyle:
|
|
32
|
+
return {
|
|
33
|
+
'accent': None,
|
|
34
|
+
'variant': "default",
|
|
35
|
+
'widget_class': widget_class,
|
|
36
|
+
'cross_widget': False,
|
|
37
|
+
'orient': None,
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
from bootstack.style.bootstyle_builder_ttk import BootstyleBuilderTTk
|
|
41
|
+
from bootstack.style.theme_provider import use_theme
|
|
42
|
+
|
|
43
|
+
theme_colors = use_theme().colors
|
|
44
|
+
if not isinstance(bootstyle, str):
|
|
45
|
+
raise BootstyleParsingError(f'bootstyle must be a string. Received the value: {bootstyle}')
|
|
46
|
+
parts = bootstyle.lower().split('-')
|
|
47
|
+
|
|
48
|
+
accent = None
|
|
49
|
+
variant = None
|
|
50
|
+
resolved_widget = widget_class
|
|
51
|
+
cross_widget = False
|
|
52
|
+
orient = None
|
|
53
|
+
|
|
54
|
+
# First pass: resolve widget target (so variant tokens can be validated)
|
|
55
|
+
for part in parts:
|
|
56
|
+
if part in WIDGET_CLASS_MAP:
|
|
57
|
+
resolved_widget = WIDGET_CLASS_MAP[part]
|
|
58
|
+
if resolved_widget != widget_class:
|
|
59
|
+
cross_widget = True
|
|
60
|
+
|
|
61
|
+
# Second pass: resolve accent/variant/orientation
|
|
62
|
+
for part in parts:
|
|
63
|
+
if part in WIDGET_CLASS_MAP:
|
|
64
|
+
# already handled in first pass
|
|
65
|
+
continue
|
|
66
|
+
if part in theme_colors or part in COLOR_TOKENS or '[' in part:
|
|
67
|
+
accent = part
|
|
68
|
+
continue
|
|
69
|
+
if part in ("horizontal", "vertical"):
|
|
70
|
+
orient = part
|
|
71
|
+
continue
|
|
72
|
+
if BootstyleBuilderTTk.has_builder(resolved_widget, part):
|
|
73
|
+
variant = part
|
|
74
|
+
continue
|
|
75
|
+
# If we reach here, it's unrecognized
|
|
76
|
+
message = f"Unrecognized variant or accent token: '{part}'"
|
|
77
|
+
raise BootstyleParsingError(message)
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
'accent': accent,
|
|
81
|
+
'variant': variant,
|
|
82
|
+
'widget_class': resolved_widget,
|
|
83
|
+
'cross_widget': cross_widget,
|
|
84
|
+
'orient': orient
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def to_pascal_case(s: str) -> str:
|
|
89
|
+
"""Convert dash-separated string to PascalCase.
|
|
90
|
+
|
|
91
|
+
Examples:
|
|
92
|
+
'context-check' -> 'ContextCheck'
|
|
93
|
+
'outline' -> 'Outline'
|
|
94
|
+
'solid' -> 'Solid'
|
|
95
|
+
"""
|
|
96
|
+
return ''.join(part.capitalize() for part in s.split('-'))
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def from_pascal_case(s: str) -> str:
|
|
100
|
+
"""Convert PascalCase string to dash-separated lowercase.
|
|
101
|
+
|
|
102
|
+
Examples:
|
|
103
|
+
'ContextCheck' -> 'context-check'
|
|
104
|
+
'Outline' -> 'outline'
|
|
105
|
+
'Solid' -> 'solid'
|
|
106
|
+
"""
|
|
107
|
+
import re
|
|
108
|
+
# Insert dash before uppercase letters (except at start), then lowercase
|
|
109
|
+
return re.sub(r'(?<!^)(?=[A-Z])', '-', s).lower()
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def generate_ttk_style_name(
|
|
113
|
+
accent: Optional[str],
|
|
114
|
+
variant: Optional[str],
|
|
115
|
+
widget_class: str,
|
|
116
|
+
custom_prefix: Optional[str] = None,
|
|
117
|
+
orient: Optional[str] = None,
|
|
118
|
+
) -> str:
|
|
119
|
+
"""Generate TTK style name from parsed components.
|
|
120
|
+
|
|
121
|
+
Returns style name in format: [custom_prefix].[accent].[Variant].[Orient].[Widget]
|
|
122
|
+
"""
|
|
123
|
+
parts = []
|
|
124
|
+
|
|
125
|
+
if custom_prefix:
|
|
126
|
+
parts.append(custom_prefix)
|
|
127
|
+
if accent:
|
|
128
|
+
parts.append(accent)
|
|
129
|
+
if variant:
|
|
130
|
+
parts.append(to_pascal_case(variant))
|
|
131
|
+
if orient:
|
|
132
|
+
parts.append(normalize_orientation(orient))
|
|
133
|
+
parts.append(widget_class)
|
|
134
|
+
return '.'.join(parts)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def normalize_orientation(orient: str):
|
|
138
|
+
"""Normalize TTK style orientation."""
|
|
139
|
+
if orient.lower().startswith('v'):
|
|
140
|
+
return 'Vertical'
|
|
141
|
+
else:
|
|
142
|
+
return 'Horizontal'
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def parse_bootstyle(bootstyle: str, widget_class: str) -> dict:
|
|
147
|
+
"""Parse bootstyle string using configured parsing method.
|
|
148
|
+
|
|
149
|
+
Main entry point for bootstyle parsing.
|
|
150
|
+
"""
|
|
151
|
+
return parse_bootstyle_v2(bootstyle, widget_class)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def extract_orient_from_style(ttk_style: str):
|
|
155
|
+
"""Extract orientation from TTK style name."""
|
|
156
|
+
if 'horizontal' in ttk_style.lower():
|
|
157
|
+
return 'Horizontal'
|
|
158
|
+
elif 'vertical' in ttk_style.lower():
|
|
159
|
+
return 'Vertical'
|
|
160
|
+
else:
|
|
161
|
+
return None
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def extract_accent_from_style(ttk_style: str, default: str = 'primary') -> str:
|
|
165
|
+
"""Extract accent token from TTK style name, including modifiers like [subtle]."""
|
|
166
|
+
parts = ttk_style.split('.')
|
|
167
|
+
|
|
168
|
+
# Skip custom prefix if present (e.g., bs[hash] or custom_xyz)
|
|
169
|
+
if parts and (parts[0].startswith('bs[') or parts[0].startswith('custom_')):
|
|
170
|
+
parts = parts[1:]
|
|
171
|
+
|
|
172
|
+
for part in parts:
|
|
173
|
+
part_lower = part.lower()
|
|
174
|
+
# Check exact match first
|
|
175
|
+
if part_lower in COLOR_TOKENS:
|
|
176
|
+
return part_lower
|
|
177
|
+
# Check if base accent (before modifier) is an accent token
|
|
178
|
+
# e.g., 'primary[subtle]' -> 'primary'
|
|
179
|
+
if '[' in part_lower:
|
|
180
|
+
base_accent = part_lower.split('[')[0]
|
|
181
|
+
if base_accent in COLOR_TOKENS:
|
|
182
|
+
return part_lower # Return full token with modifier
|
|
183
|
+
|
|
184
|
+
return default
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def extract_variant_from_style(ttk_style: str, widget_class: str = None) -> Optional[str]:
|
|
188
|
+
"""Extract variant name from TTK style name.
|
|
189
|
+
|
|
190
|
+
Args:
|
|
191
|
+
ttk_style: The TTK style name to parse.
|
|
192
|
+
widget_class: Optional widget class from winfo_class() to exclude from parsing.
|
|
193
|
+
|
|
194
|
+
Returns:
|
|
195
|
+
Variant name in dash-separated lowercase format (e.g., 'context-check')
|
|
196
|
+
"""
|
|
197
|
+
parts = ttk_style.split('.')
|
|
198
|
+
|
|
199
|
+
# Skip custom prefix if present (e.g., bs[hash] or custom_xyz)
|
|
200
|
+
if parts and (parts[0].startswith('bs[') or parts[0].startswith('custom_')):
|
|
201
|
+
parts = parts[1:]
|
|
202
|
+
|
|
203
|
+
# Build set of class-related parts to skip (e.g., 'Expander', 'TLabel')
|
|
204
|
+
class_parts = set()
|
|
205
|
+
if widget_class:
|
|
206
|
+
class_parts.update(widget_class.split('.'))
|
|
207
|
+
|
|
208
|
+
for part in parts:
|
|
209
|
+
part_lower = part.lower()
|
|
210
|
+
# Skip color tokens (including those with modifiers like 'primary[subtle]')
|
|
211
|
+
if part_lower in COLOR_TOKENS:
|
|
212
|
+
continue
|
|
213
|
+
if '[' in part_lower:
|
|
214
|
+
base_color = part_lower.split('[')[0]
|
|
215
|
+
if base_color in COLOR_TOKENS:
|
|
216
|
+
continue
|
|
217
|
+
# Skip known class parts from widget_class
|
|
218
|
+
if part in class_parts:
|
|
219
|
+
continue
|
|
220
|
+
# Skip standard ttk class names (TLabel, TButton, etc.)
|
|
221
|
+
if part.startswith('T'):
|
|
222
|
+
continue
|
|
223
|
+
# Skip orientation parts
|
|
224
|
+
if part in ('Horizontal', 'Vertical'):
|
|
225
|
+
continue
|
|
226
|
+
# Found a variant - convert from PascalCase to dash-separated
|
|
227
|
+
return from_pascal_case(part)
|
|
228
|
+
|
|
229
|
+
return None
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def extract_widget_class_from_style(ttk_style: str) -> Optional[str]:
|
|
233
|
+
"""Extract widget class from TTK style name."""
|
|
234
|
+
parts = ttk_style.split('.')
|
|
235
|
+
|
|
236
|
+
for part in parts:
|
|
237
|
+
if part.startswith('T'):
|
|
238
|
+
return part
|
|
239
|
+
|
|
240
|
+
return None
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
class Bootstyle:
|
|
244
|
+
"""Widget integration layer for bootstyle functionality.
|
|
245
|
+
|
|
246
|
+
Wires bootstack into tkinter/ttk by overriding widget constructors and
|
|
247
|
+
configure methods to accept `bootstyle` parameter.
|
|
248
|
+
"""
|
|
249
|
+
|
|
250
|
+
@staticmethod
|
|
251
|
+
def create_ttk_style(
|
|
252
|
+
widget_class: str,
|
|
253
|
+
style_options: Optional[dict] = None,
|
|
254
|
+
*,
|
|
255
|
+
accent: Optional[str] = None,
|
|
256
|
+
variant: Optional[str] = None,
|
|
257
|
+
) -> str:
|
|
258
|
+
"""Create or get TTK style name for a widget.
|
|
259
|
+
|
|
260
|
+
Args:
|
|
261
|
+
widget_class: TTK widget class (e.g., "TButton")
|
|
262
|
+
style_options: Custom style options dict
|
|
263
|
+
accent: Accent token (e.g., "success", "primary[subtle]")
|
|
264
|
+
variant: Variant name (e.g., "outline", "solid")
|
|
265
|
+
|
|
266
|
+
Returns:
|
|
267
|
+
Generated TTK style name
|
|
268
|
+
"""
|
|
269
|
+
from bootstack.style.bootstyle_builder_ttk import BootstyleBuilderTTk
|
|
270
|
+
|
|
271
|
+
# If no accent and no variant, return base widget class
|
|
272
|
+
if not accent and not variant:
|
|
273
|
+
return widget_class
|
|
274
|
+
|
|
275
|
+
# Initialize style_options to empty dict if None
|
|
276
|
+
if style_options is None:
|
|
277
|
+
style_options = {}
|
|
278
|
+
|
|
279
|
+
surface = style_options.get("surface")
|
|
280
|
+
|
|
281
|
+
builder_variant = variant if variant is not None else \
|
|
282
|
+
BootstyleBuilderTTk.get_default_variant(widget_class)
|
|
283
|
+
|
|
284
|
+
custom_prefix = None
|
|
285
|
+
|
|
286
|
+
if style_options.keys() or surface != 'background':
|
|
287
|
+
import hashlib
|
|
288
|
+
import json
|
|
289
|
+
options_str = json.dumps(style_options, sort_keys=True)
|
|
290
|
+
options_hash = hashlib.md5(options_str.encode()).hexdigest()[:8]
|
|
291
|
+
custom_prefix = f"bs[{options_hash}]"
|
|
292
|
+
|
|
293
|
+
ttk_style = generate_ttk_style_name(
|
|
294
|
+
accent=accent,
|
|
295
|
+
variant=variant,
|
|
296
|
+
widget_class=widget_class,
|
|
297
|
+
custom_prefix=custom_prefix,
|
|
298
|
+
orient=style_options.get('orient'),
|
|
299
|
+
)
|
|
300
|
+
|
|
301
|
+
from bootstack.style.style import get_style
|
|
302
|
+
style = get_style()
|
|
303
|
+
|
|
304
|
+
style.create_style(
|
|
305
|
+
widget_class=widget_class,
|
|
306
|
+
variant=builder_variant,
|
|
307
|
+
ttk_style=ttk_style,
|
|
308
|
+
accent=accent,
|
|
309
|
+
options=style_options
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
return ttk_style
|
|
313
|
+
|
|
314
|
+
@staticmethod
|
|
315
|
+
def override_ttk_widget_constructor(func):
|
|
316
|
+
"""Override ttk widget __init__ to accept bootstyle, accent, and variant parameters."""
|
|
317
|
+
|
|
318
|
+
def __init__wrapper(self, *args, **kwargs):
|
|
319
|
+
|
|
320
|
+
# Extract accent/variant parameters
|
|
321
|
+
accent = kwargs.pop("accent", None)
|
|
322
|
+
variant = kwargs.pop("variant", None)
|
|
323
|
+
kwargs.pop("bootstyle", None) # removed param — discard silently
|
|
324
|
+
|
|
325
|
+
had_style_kwarg = 'style' in kwargs
|
|
326
|
+
|
|
327
|
+
style_options = kwargs.pop("style_options", {})
|
|
328
|
+
inherit_surface = kwargs.pop('inherit_surface', None)
|
|
329
|
+
surface_token = kwargs.pop('surface', None)
|
|
330
|
+
input_bg_token = kwargs.pop('input_background', None)
|
|
331
|
+
|
|
332
|
+
# Extract ttk_class for style lookup (doesn't affect widget's actual class_)
|
|
333
|
+
# This allows custom style builders without affecting bindtags
|
|
334
|
+
ttk_class = kwargs.pop('ttk_class', None)
|
|
335
|
+
|
|
336
|
+
func(self, *args, **kwargs) # the actual widget constructor
|
|
337
|
+
|
|
338
|
+
# Use ttk_class for style lookup if provided, otherwise use widget's actual class
|
|
339
|
+
widget_class = self.winfo_class()
|
|
340
|
+
style_class = ttk_class or widget_class
|
|
341
|
+
|
|
342
|
+
# ===== Surface color inheritance =====
|
|
343
|
+
|
|
344
|
+
if inherit_surface is None:
|
|
345
|
+
inherit_surface = get_app_settings().inherit_surface_color
|
|
346
|
+
|
|
347
|
+
if hasattr(self, 'master') and self.master is not None:
|
|
348
|
+
parent_surface_token = getattr(self.master, '_surface', 'content')
|
|
349
|
+
else:
|
|
350
|
+
parent_surface_token = 'content'
|
|
351
|
+
|
|
352
|
+
if surface_token:
|
|
353
|
+
effective_surface_token = surface_token
|
|
354
|
+
elif inherit_surface:
|
|
355
|
+
effective_surface_token = parent_surface_token
|
|
356
|
+
else:
|
|
357
|
+
effective_surface_token = 'content'
|
|
358
|
+
|
|
359
|
+
# container widgets can take their surface color from the accent param
|
|
360
|
+
# Use style_class so custom ttk_class like 'Field' can opt out of this behavior
|
|
361
|
+
if accent and style_class in CONTAINER_CLASSES and surface_token is None:
|
|
362
|
+
effective_surface_token = accent
|
|
363
|
+
|
|
364
|
+
# cache the surface color for child components
|
|
365
|
+
setattr(self, '_surface', effective_surface_token)
|
|
366
|
+
if effective_surface_token != 'content' and effective_surface_token is not None:
|
|
367
|
+
style_options.setdefault('surface', effective_surface_token)
|
|
368
|
+
|
|
369
|
+
# ===== Input background inheritance =====
|
|
370
|
+
|
|
371
|
+
if hasattr(self, 'master') and self.master is not None:
|
|
372
|
+
parent_input_bg = getattr(self.master, '_input_background', None)
|
|
373
|
+
else:
|
|
374
|
+
parent_input_bg = None
|
|
375
|
+
|
|
376
|
+
if input_bg_token:
|
|
377
|
+
effective_input_bg = input_bg_token
|
|
378
|
+
elif inherit_surface and parent_input_bg:
|
|
379
|
+
effective_input_bg = parent_input_bg
|
|
380
|
+
else:
|
|
381
|
+
effective_input_bg = None
|
|
382
|
+
|
|
383
|
+
setattr(self, '_input_background', effective_input_bg)
|
|
384
|
+
if effective_input_bg:
|
|
385
|
+
style_options.setdefault('input_background', effective_input_bg)
|
|
386
|
+
|
|
387
|
+
# ==== Orientation =====
|
|
388
|
+
|
|
389
|
+
# handle widgets with orientation
|
|
390
|
+
if widget_class in ORIENT_CLASSES:
|
|
391
|
+
orient = str(self.cget('orient'))
|
|
392
|
+
style_options.setdefault('orient', orient)
|
|
393
|
+
|
|
394
|
+
# ==== Create actual ttk style & assign to widget =====
|
|
395
|
+
|
|
396
|
+
if (accent or variant) and style_class:
|
|
397
|
+
|
|
398
|
+
ttk_style = Bootstyle.create_ttk_style(
|
|
399
|
+
widget_class=style_class,
|
|
400
|
+
style_options=style_options,
|
|
401
|
+
accent=accent,
|
|
402
|
+
variant=variant,
|
|
403
|
+
)
|
|
404
|
+
self.configure(style=ttk_style)
|
|
405
|
+
|
|
406
|
+
elif style_class and not had_style_kwarg:
|
|
407
|
+
from bootstack.style.bootstyle_builder_ttk import BootstyleBuilderTTk
|
|
408
|
+
from bootstack.style.style import get_style
|
|
409
|
+
|
|
410
|
+
default_variant = BootstyleBuilderTTk.get_default_variant(style_class)
|
|
411
|
+
|
|
412
|
+
if BootstyleBuilderTTk.has_builder(style_class, default_variant):
|
|
413
|
+
|
|
414
|
+
# Build options first so we can decide if a custom bs[...] prefix is needed
|
|
415
|
+
custom_prefix = None
|
|
416
|
+
if style_options.keys():
|
|
417
|
+
import hashlib
|
|
418
|
+
import json
|
|
419
|
+
options_str = json.dumps(style_options, sort_keys=True)
|
|
420
|
+
options_hash = hashlib.md5(options_str.encode()).hexdigest()[:8]
|
|
421
|
+
custom_prefix = f"bs[{options_hash}]"
|
|
422
|
+
|
|
423
|
+
ttk_style = generate_ttk_style_name(
|
|
424
|
+
accent=None,
|
|
425
|
+
variant=default_variant,
|
|
426
|
+
widget_class=style_class,
|
|
427
|
+
custom_prefix=custom_prefix,
|
|
428
|
+
)
|
|
429
|
+
|
|
430
|
+
style_instance = get_style()
|
|
431
|
+
if style_instance is not None:
|
|
432
|
+
style_instance.create_style(
|
|
433
|
+
widget_class=style_class,
|
|
434
|
+
variant=default_variant,
|
|
435
|
+
ttk_style=ttk_style,
|
|
436
|
+
options=style_options,
|
|
437
|
+
)
|
|
438
|
+
self.configure(style=ttk_style)
|
|
439
|
+
else:
|
|
440
|
+
self.configure(style=style_class)
|
|
441
|
+
|
|
442
|
+
# Store accent, variant, ttk_class, and style_options for later retrieval
|
|
443
|
+
setattr(self, '_accent', accent)
|
|
444
|
+
setattr(self, '_variant', variant)
|
|
445
|
+
setattr(self, '_ttk_class', ttk_class)
|
|
446
|
+
setattr(self, '_style_options', style_options)
|
|
447
|
+
|
|
448
|
+
return __init__wrapper
|
|
449
|
+
|
|
450
|
+
@staticmethod
|
|
451
|
+
def override_tk_widget_constructor(func):
|
|
452
|
+
"""Override Tk widget __init__ to apply theme background when autostyle=True."""
|
|
453
|
+
|
|
454
|
+
def __init__wrapper(self, *args, **kwargs):
|
|
455
|
+
|
|
456
|
+
# capture bootstrap arguments
|
|
457
|
+
auto_style = kwargs.pop("autostyle", True)
|
|
458
|
+
inherit_surface = kwargs.pop('inherit_surface', None)
|
|
459
|
+
if inherit_surface is None:
|
|
460
|
+
inherit_surface = get_app_settings().inherit_surface_color
|
|
461
|
+
surface_token = kwargs.pop('surface', None)
|
|
462
|
+
|
|
463
|
+
func(self, *args, **kwargs) # the actual constructor
|
|
464
|
+
|
|
465
|
+
# ===== Surface color inheritance =====
|
|
466
|
+
|
|
467
|
+
if hasattr(self, 'master') and self.master is not None:
|
|
468
|
+
parent_surface_token = getattr(self.master, '_surface', 'content')
|
|
469
|
+
else:
|
|
470
|
+
parent_surface_token = 'content'
|
|
471
|
+
|
|
472
|
+
if inherit_surface:
|
|
473
|
+
surface_token = parent_surface_token
|
|
474
|
+
else:
|
|
475
|
+
surface_token = surface_token or 'content'
|
|
476
|
+
|
|
477
|
+
setattr(self, '_surface', surface_token)
|
|
478
|
+
|
|
479
|
+
if not auto_style:
|
|
480
|
+
return
|
|
481
|
+
|
|
482
|
+
# ==== Update widget style & register for theme changes =====
|
|
483
|
+
|
|
484
|
+
from bootstack.style.style import get_style
|
|
485
|
+
from bootstack.style.bootstyle_builder_tk import BootstyleBuilderBuilderTk
|
|
486
|
+
style = get_style()
|
|
487
|
+
builder_tk = BootstyleBuilderBuilderTk(
|
|
488
|
+
theme_provider=style.theme_provider if style else None,
|
|
489
|
+
style_instance=style
|
|
490
|
+
)
|
|
491
|
+
surface = getattr(self, '_surface', 'content')
|
|
492
|
+
builder_tk.call_builder(self, surface=surface)
|
|
493
|
+
|
|
494
|
+
style.register_tk_widget(self)
|
|
495
|
+
|
|
496
|
+
return __init__wrapper
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
__all__ = [
|
|
500
|
+
'parse_bootstyle',
|
|
501
|
+
'parse_bootstyle_v2',
|
|
502
|
+
'generate_ttk_style_name',
|
|
503
|
+
'extract_accent_from_style',
|
|
504
|
+
'extract_variant_from_style',
|
|
505
|
+
'extract_widget_class_from_style',
|
|
506
|
+
'Bootstyle',
|
|
507
|
+
]
|