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
bootstack/style/style.py
ADDED
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
"""Enhanced TTK Style class with builder registry and theme management."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import weakref
|
|
6
|
+
from tkinter.ttk import Style as ttkStyle
|
|
7
|
+
from typing import Dict, Optional, Set
|
|
8
|
+
|
|
9
|
+
from bootstack.runtime.app import get_app_settings
|
|
10
|
+
from bootstack.style.bootstyle_builder_ttk import BootstyleBuilderTTk
|
|
11
|
+
from bootstack.style.theme_provider import ThemeProvider, use_theme
|
|
12
|
+
from bootstack.widgets.types import Master
|
|
13
|
+
|
|
14
|
+
_style_instance: Style | None = None
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Style(ttkStyle):
|
|
18
|
+
"""Enhanced TTK Style with builder registry and theme management.
|
|
19
|
+
|
|
20
|
+
This class extends ttk.Style to provide:
|
|
21
|
+
|
|
22
|
+
- Singleton pattern (one instance per Tkinter master)
|
|
23
|
+
- Integration with BootstyleBuilder registry
|
|
24
|
+
- Theme management via ThemeProvider
|
|
25
|
+
- Automatic style rebuilding on theme changes
|
|
26
|
+
- Custom style options support
|
|
27
|
+
|
|
28
|
+
The Style class maintains registries to track:
|
|
29
|
+
|
|
30
|
+
- All created styles (for theme change rebuilds)
|
|
31
|
+
- Which styles exist in each theme (for caching)
|
|
32
|
+
- Custom options per style (for recreating with same options)
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
def __new__(cls, *args, **kwargs):
|
|
36
|
+
"""Ensure Style() always returns the global singleton instance.
|
|
37
|
+
|
|
38
|
+
If an instance already exists, return it. Otherwise, create it.
|
|
39
|
+
"""
|
|
40
|
+
global _style_instance
|
|
41
|
+
if _style_instance is None:
|
|
42
|
+
_style_instance = super().__new__(cls)
|
|
43
|
+
return _style_instance
|
|
44
|
+
|
|
45
|
+
def __init__(self, master: Master = None, theme: str = "light"):
|
|
46
|
+
"""Initialize the Style instance.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
master: Tkinter master widget (None for default)
|
|
50
|
+
theme: Initial theme name (default: "light")
|
|
51
|
+
"""
|
|
52
|
+
# Prevent reinitialization on subsequent Style() calls
|
|
53
|
+
if getattr(self, "_initialized", False):
|
|
54
|
+
# Optionally honor a theme argument after initialization
|
|
55
|
+
try:
|
|
56
|
+
if theme and theme != self._current_theme:
|
|
57
|
+
self.theme_use(theme)
|
|
58
|
+
except Exception:
|
|
59
|
+
pass
|
|
60
|
+
return
|
|
61
|
+
|
|
62
|
+
super().__init__(master)
|
|
63
|
+
|
|
64
|
+
self._theme_provider = use_theme(theme)
|
|
65
|
+
self._style_builder = BootstyleBuilderTTk(theme_provider=self._theme_provider, style_instance=None)
|
|
66
|
+
self._style_builder.set_style_instance(self)
|
|
67
|
+
|
|
68
|
+
# Style registries
|
|
69
|
+
self._style_registry: Set[str] = set()
|
|
70
|
+
self._style_accents: Dict[str, Optional[str]] = {}
|
|
71
|
+
self._style_variants: Dict[str, str] = {}
|
|
72
|
+
self._style_options: Dict[str, dict] = {}
|
|
73
|
+
self._style_widget_classes: Dict[str, str] = {}
|
|
74
|
+
|
|
75
|
+
# Current theme tracking
|
|
76
|
+
self._current_theme: Optional[str] = theme
|
|
77
|
+
|
|
78
|
+
# Track legacy Tk widgets for theme-change restyling
|
|
79
|
+
self._tk_widgets = weakref.WeakSet()
|
|
80
|
+
|
|
81
|
+
self.theme_use(theme)
|
|
82
|
+
self._initialized = True
|
|
83
|
+
|
|
84
|
+
@property
|
|
85
|
+
def style_builder(self) -> BootstyleBuilderTTk:
|
|
86
|
+
"""Get the builder manager instance.
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
BootstyleBuilder instance
|
|
90
|
+
"""
|
|
91
|
+
return self._style_builder
|
|
92
|
+
|
|
93
|
+
@property
|
|
94
|
+
def theme_provider(self) -> ThemeProvider:
|
|
95
|
+
"""Get the theme provider instance.
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
ThemeProvider instance
|
|
99
|
+
"""
|
|
100
|
+
return self._theme_provider
|
|
101
|
+
|
|
102
|
+
# ----- Theme metadata helpers -------------------------------------------------
|
|
103
|
+
|
|
104
|
+
def list_themes(self) -> list[dict[str, str]]:
|
|
105
|
+
"""Return available themes as [{'name', 'display_name'}, ...].
|
|
106
|
+
|
|
107
|
+
This delegates to the underlying ThemeProvider. Themes are always
|
|
108
|
+
loaded from both the v2 and legacy theme packages.
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
List of theme dictionaries with 'name' and 'display_name' keys.
|
|
112
|
+
"""
|
|
113
|
+
return self._theme_provider.list_themes()
|
|
114
|
+
|
|
115
|
+
@property
|
|
116
|
+
def current_theme(self) -> Optional[str]:
|
|
117
|
+
"""Get the current theme name.
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
Current theme name or None
|
|
121
|
+
"""
|
|
122
|
+
return self._current_theme
|
|
123
|
+
|
|
124
|
+
@property
|
|
125
|
+
def colors(self) -> dict[str, str]:
|
|
126
|
+
"""Get colors for the current theme.
|
|
127
|
+
|
|
128
|
+
Returns:
|
|
129
|
+
Colors dictionary from ThemeProvider
|
|
130
|
+
"""
|
|
131
|
+
return self._theme_provider.colors
|
|
132
|
+
|
|
133
|
+
def style_exists(self, style: str) -> bool:
|
|
134
|
+
"""Check if a style exists (basic check).
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
style: TTK style name
|
|
138
|
+
|
|
139
|
+
Returns:
|
|
140
|
+
True if style has any configuration
|
|
141
|
+
"""
|
|
142
|
+
return bool(self.configure(style))
|
|
143
|
+
|
|
144
|
+
def register_style(self, ttk_style: str, options: Optional[dict] = None):
|
|
145
|
+
"""Register a style in the current theme.
|
|
146
|
+
|
|
147
|
+
This adds the style to registries so it can be:
|
|
148
|
+
|
|
149
|
+
- Cached (not recreated if already exists)
|
|
150
|
+
- Rebuilt when theme changes
|
|
151
|
+
- Recreated with same options
|
|
152
|
+
|
|
153
|
+
Args:
|
|
154
|
+
ttk_style: Full TTK style name
|
|
155
|
+
options: Optional custom style options
|
|
156
|
+
"""
|
|
157
|
+
# Add to global registry
|
|
158
|
+
self._style_registry.add(ttk_style)
|
|
159
|
+
|
|
160
|
+
# Store a copy of custom options if provided (to prevent mutation issues)
|
|
161
|
+
if options:
|
|
162
|
+
self._style_options[ttk_style] = options.copy()
|
|
163
|
+
|
|
164
|
+
def create_style(
|
|
165
|
+
self,
|
|
166
|
+
widget_class: str,
|
|
167
|
+
variant: str,
|
|
168
|
+
ttk_style: str,
|
|
169
|
+
accent: Optional[str] = None,
|
|
170
|
+
options: Optional[dict] = None) -> None:
|
|
171
|
+
"""Create a new style if it doesn't exist in current theme.
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
widget_class: TTK widget class (e.g., "TButton")
|
|
175
|
+
variant: Variant name (e.g., "outline")
|
|
176
|
+
ttk_style: Full TTK style name (e.g., "success.Outline.TButton")
|
|
177
|
+
accent: Optional accent token (e.g., "success", "blue[100]")
|
|
178
|
+
options: Optional custom style options
|
|
179
|
+
"""
|
|
180
|
+
# Check if already exists in this theme
|
|
181
|
+
if self.style_exists(ttk_style):
|
|
182
|
+
return # Already created for this theme
|
|
183
|
+
|
|
184
|
+
# Call builder with widget class, variant, and parsed accent
|
|
185
|
+
self._style_builder.call_builder(
|
|
186
|
+
widget_class=widget_class,
|
|
187
|
+
variant=variant,
|
|
188
|
+
ttk_style=ttk_style,
|
|
189
|
+
accent=accent,
|
|
190
|
+
**(options or {})
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
# Store the accent, variant, and widget_class so we can rebuild with the same values
|
|
194
|
+
self._style_accents[ttk_style] = accent
|
|
195
|
+
self._style_variants[ttk_style] = variant
|
|
196
|
+
self._style_widget_classes[ttk_style] = widget_class
|
|
197
|
+
|
|
198
|
+
# Register it
|
|
199
|
+
self.register_style(ttk_style, options)
|
|
200
|
+
|
|
201
|
+
def theme_use(self, name: str = None) -> str | None:
|
|
202
|
+
"""Switch to a different theme and rebuild all styles.
|
|
203
|
+
|
|
204
|
+
Applies theme change to the global Style instance, rebuilds all
|
|
205
|
+
TTK styles and registered Tk widgets, and publishes a legacy
|
|
206
|
+
theme-change event for subscribers.
|
|
207
|
+
|
|
208
|
+
Args:
|
|
209
|
+
name: Theme name to switch to. If None, returns the current theme.
|
|
210
|
+
|
|
211
|
+
Returns:
|
|
212
|
+
The current theme name, or None if no theme is set.
|
|
213
|
+
"""
|
|
214
|
+
if name is None:
|
|
215
|
+
return super().theme_use()
|
|
216
|
+
|
|
217
|
+
# Only call use() if theme is changing to avoid redundant build_theme_colors()
|
|
218
|
+
if name != self._theme_provider.name:
|
|
219
|
+
self._theme_provider.use(name)
|
|
220
|
+
self._current_theme = name
|
|
221
|
+
|
|
222
|
+
if name not in self.theme_names():
|
|
223
|
+
self.theme_create(name, 'clam', {})
|
|
224
|
+
|
|
225
|
+
super().theme_use(name)
|
|
226
|
+
|
|
227
|
+
# Initialize all default widget styles before rebuilding custom styles
|
|
228
|
+
# self._style_builder.initialize_all_default_styles()
|
|
229
|
+
|
|
230
|
+
self._rebuild_all_styles()
|
|
231
|
+
|
|
232
|
+
# Re-apply Tk widget styling (legacy widgets)
|
|
233
|
+
self._rebuild_all_tk_widgets()
|
|
234
|
+
|
|
235
|
+
# Publish theme-change event for legacy subscribers
|
|
236
|
+
from bootstack.core.publisher import Channel, Publisher # lazy import
|
|
237
|
+
Publisher.publish_message(Channel.STD)
|
|
238
|
+
|
|
239
|
+
return self._current_theme
|
|
240
|
+
|
|
241
|
+
def _rebuild_all_styles(self):
|
|
242
|
+
"""Recreate all registered styles when theme changes.
|
|
243
|
+
|
|
244
|
+
This iterates through all styles that have been created and
|
|
245
|
+
rebuilds them using the new theme's colors, preserving any
|
|
246
|
+
custom options.
|
|
247
|
+
"""
|
|
248
|
+
for style in self._style_registry:
|
|
249
|
+
# Get stored options, accent, and variant
|
|
250
|
+
options = self._style_options.get(style, {})
|
|
251
|
+
accent = self._style_accents.get(style)
|
|
252
|
+
variant = self._style_variants.get(style)
|
|
253
|
+
|
|
254
|
+
# Use stored widget_class if available (preserves composite classes like 'Menubar.TField')
|
|
255
|
+
# Fall back to parsing from style name for backwards compatibility
|
|
256
|
+
widget_class = self._style_widget_classes.get(style)
|
|
257
|
+
if not widget_class:
|
|
258
|
+
parsed = self._parse_style_name(style)
|
|
259
|
+
if not parsed:
|
|
260
|
+
continue
|
|
261
|
+
widget_class = parsed['widget_class']
|
|
262
|
+
# Only use parsed variant if we don't have a stored one
|
|
263
|
+
if variant is None:
|
|
264
|
+
variant = parsed['variant']
|
|
265
|
+
|
|
266
|
+
if variant is None:
|
|
267
|
+
from bootstack.style.bootstyle_builder_ttk import BootstyleBuilderTTk
|
|
268
|
+
variant = BootstyleBuilderTTk.get_default_variant(widget_class)
|
|
269
|
+
|
|
270
|
+
self._style_builder.call_builder(
|
|
271
|
+
widget_class=widget_class,
|
|
272
|
+
variant=variant,
|
|
273
|
+
ttk_style=style,
|
|
274
|
+
accent=accent,
|
|
275
|
+
**options
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
def register_tk_widget(self, widget) -> None:
|
|
279
|
+
"""Register a Tk widget to be restyled on theme changes."""
|
|
280
|
+
self._tk_widgets.add(widget)
|
|
281
|
+
|
|
282
|
+
def _rebuild_all_tk_widgets(self) -> None:
|
|
283
|
+
"""Restyle all registered Tk widgets on theme change."""
|
|
284
|
+
from bootstack.style.bootstyle_builder_tk import BootstyleBuilderBuilderTk
|
|
285
|
+
builder_tk = BootstyleBuilderBuilderTk(theme_provider=self._theme_provider, style_instance=self)
|
|
286
|
+
|
|
287
|
+
for widget in list(self._tk_widgets):
|
|
288
|
+
try:
|
|
289
|
+
surface = getattr(widget, '_surface', 'background')
|
|
290
|
+
builder_tk.call_builder(widget, surface=surface)
|
|
291
|
+
except Exception:
|
|
292
|
+
# ignore incompatible or unmapped widgets
|
|
293
|
+
pass
|
|
294
|
+
|
|
295
|
+
@staticmethod
|
|
296
|
+
def _parse_style_name(ttk_style: str) -> Optional[dict]:
|
|
297
|
+
"""Parse TTK style name to extract widget class and variant.
|
|
298
|
+
|
|
299
|
+
Args:
|
|
300
|
+
ttk_style: Full TTK style name
|
|
301
|
+
|
|
302
|
+
Returns:
|
|
303
|
+
Dict with 'widget_class' and 'variant', or None
|
|
304
|
+
|
|
305
|
+
Examples:
|
|
306
|
+
>>> Style._parse_style_name("success.TButton")
|
|
307
|
+
{'widget_class': 'TButton', 'variant': 'solid'}
|
|
308
|
+
>>> Style._parse_style_name("info.Striped.TProgressbar")
|
|
309
|
+
{'widget_class': 'TProgressbar', 'variant': 'striped'}
|
|
310
|
+
"""
|
|
311
|
+
# Split into parts
|
|
312
|
+
parts = ttk_style.split('.')
|
|
313
|
+
|
|
314
|
+
if not parts:
|
|
315
|
+
return None
|
|
316
|
+
|
|
317
|
+
# Extract widget class (e.g., "TButton")
|
|
318
|
+
# Widget class is always the LAST part starting with 'T'
|
|
319
|
+
widget_class = None
|
|
320
|
+
for part in parts:
|
|
321
|
+
if part.startswith('T'):
|
|
322
|
+
widget_class = part
|
|
323
|
+
|
|
324
|
+
if not widget_class:
|
|
325
|
+
return None
|
|
326
|
+
|
|
327
|
+
# Determine variant using registered builders for this widget
|
|
328
|
+
from bootstack.style.bootstyle_builder_ttk import BootstyleBuilderTTk
|
|
329
|
+
builder_variants = set(v.lower() for v in BootstyleBuilderTTk.get_registered_builders(widget_class))
|
|
330
|
+
|
|
331
|
+
variant = None
|
|
332
|
+
accent = None
|
|
333
|
+
for part in parts:
|
|
334
|
+
# Skip the widget class itself (e.g., 'TCheckbutton')
|
|
335
|
+
if part == widget_class:
|
|
336
|
+
continue
|
|
337
|
+
token = part.lower()
|
|
338
|
+
# Identify variant by registry match
|
|
339
|
+
if token in builder_variants and variant is None:
|
|
340
|
+
variant = token
|
|
341
|
+
continue
|
|
342
|
+
# First non-variant token becomes accent
|
|
343
|
+
if accent is None:
|
|
344
|
+
accent = part
|
|
345
|
+
|
|
346
|
+
if variant is None:
|
|
347
|
+
variant = BootstyleBuilderTTk.get_default_variant(widget_class)
|
|
348
|
+
|
|
349
|
+
return {
|
|
350
|
+
'widget_class': widget_class,
|
|
351
|
+
'variant': variant
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
def get_style_builder(self) -> BootstyleBuilderTTk:
|
|
355
|
+
"""Get the style builder instance.
|
|
356
|
+
|
|
357
|
+
Returns:
|
|
358
|
+
BootstyleBuilder instance
|
|
359
|
+
"""
|
|
360
|
+
return self._style_builder
|
|
361
|
+
|
|
362
|
+
def __repr__(self) -> str:
|
|
363
|
+
"""String representation of Style instance."""
|
|
364
|
+
return f"<Style theme={self._current_theme} styles={len(self._style_registry)}>"
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
def get_style(master: Master = None) -> Style:
|
|
368
|
+
"""Return the global Style singleton instance.
|
|
369
|
+
|
|
370
|
+
Convenience helper function that ensures a single Style instance
|
|
371
|
+
is used across the application.
|
|
372
|
+
|
|
373
|
+
Args:
|
|
374
|
+
master: Optional master for initial construction; ignored thereafter.
|
|
375
|
+
|
|
376
|
+
Returns:
|
|
377
|
+
Global Style instance.
|
|
378
|
+
|
|
379
|
+
Examples:
|
|
380
|
+
>>> style = get_style()
|
|
381
|
+
>>> style.theme_use("ocean-dark")
|
|
382
|
+
"""
|
|
383
|
+
if _style_instance:
|
|
384
|
+
return _style_instance
|
|
385
|
+
else:
|
|
386
|
+
return Style(master)
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
def get_style_builder() -> BootstyleBuilderTTk:
|
|
390
|
+
"""Return the style builder for the currently active theme.
|
|
391
|
+
|
|
392
|
+
Returns:
|
|
393
|
+
The BootstyleBuilderTTk instance for the active theme.
|
|
394
|
+
|
|
395
|
+
Examples:
|
|
396
|
+
>>> builder = get_style_builder()
|
|
397
|
+
>>> primary_color = builder.color("primary")
|
|
398
|
+
"""
|
|
399
|
+
style = get_style()
|
|
400
|
+
return style.style_builder
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
# --- Global Utilities ---
|
|
404
|
+
|
|
405
|
+
def set_theme(name: str) -> None:
|
|
406
|
+
"""Set the active application theme.
|
|
407
|
+
|
|
408
|
+
Args:
|
|
409
|
+
name: Theme name to activate (e.g., "ocean-dark", "bootstrap-light", "aurora-dark").
|
|
410
|
+
|
|
411
|
+
Examples:
|
|
412
|
+
>>> set_theme("ocean-dark")
|
|
413
|
+
"""
|
|
414
|
+
style = get_style()
|
|
415
|
+
style.theme_use(name)
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
def toggle_theme() -> None:
|
|
419
|
+
"""Toggle the active application theme between light and dark mode.
|
|
420
|
+
|
|
421
|
+
Uses the light and dark themes specified in app settings, or defaults
|
|
422
|
+
to bootstrap-light and bootstrap-dark.
|
|
423
|
+
|
|
424
|
+
Examples:
|
|
425
|
+
>>> toggle_theme()
|
|
426
|
+
"""
|
|
427
|
+
settings = get_app_settings()
|
|
428
|
+
light = settings.light_theme
|
|
429
|
+
dark = settings.dark_theme
|
|
430
|
+
theme = get_theme()
|
|
431
|
+
if theme == light or theme == "light":
|
|
432
|
+
set_theme(dark)
|
|
433
|
+
else:
|
|
434
|
+
set_theme(light)
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
def get_theme() -> str:
|
|
438
|
+
"""Return the name of the currently active theme.
|
|
439
|
+
|
|
440
|
+
Returns:
|
|
441
|
+
Name of the active theme.
|
|
442
|
+
|
|
443
|
+
Examples:
|
|
444
|
+
>>> theme = get_theme()
|
|
445
|
+
>>> print(theme) # "darkly"
|
|
446
|
+
"""
|
|
447
|
+
style = get_style()
|
|
448
|
+
return style.theme_use()
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
def get_themes() -> list[dict[str, str]]:
|
|
452
|
+
"""Return the list of all registered themes.
|
|
453
|
+
|
|
454
|
+
Returns:
|
|
455
|
+
List of dictionaries containing `name` and `display_name` for each theme.
|
|
456
|
+
|
|
457
|
+
Examples:
|
|
458
|
+
>>> themes = get_themes()
|
|
459
|
+
>>> print([theme["name"] for theme in themes])
|
|
460
|
+
"""
|
|
461
|
+
style = get_style()
|
|
462
|
+
return style.list_themes()
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
def get_theme_provider() -> ThemeProvider:
|
|
466
|
+
"""Get the theme provider instance for the active theme.
|
|
467
|
+
|
|
468
|
+
Returns:
|
|
469
|
+
ThemeProvider instance.
|
|
470
|
+
|
|
471
|
+
Examples:
|
|
472
|
+
>>> provider = get_theme_provider()
|
|
473
|
+
>>> colors = provider.get_colors()
|
|
474
|
+
"""
|
|
475
|
+
style = get_style()
|
|
476
|
+
return style.theme_provider
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
def get_theme_color(token: str) -> str:
|
|
480
|
+
"""Get a hex color value from a color token based on the active theme.
|
|
481
|
+
|
|
482
|
+
Args:
|
|
483
|
+
token: Color token name (e.g., "primary", "background").
|
|
484
|
+
|
|
485
|
+
Returns:
|
|
486
|
+
Hex color string (e.g., "#007bff").
|
|
487
|
+
|
|
488
|
+
Raises:
|
|
489
|
+
ValueError: If the color token is invalid.
|
|
490
|
+
|
|
491
|
+
Examples:
|
|
492
|
+
>>> primary = get_theme_color("primary")
|
|
493
|
+
>>> print(primary) # "#007bff"
|
|
494
|
+
"""
|
|
495
|
+
builder = get_style_builder()
|
|
496
|
+
try:
|
|
497
|
+
return builder.color(token)
|
|
498
|
+
except Exception:
|
|
499
|
+
raise ValueError(f"Invalid color token: {token}")
|