bootstack 0.1.0__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 +157 -0
- bootstack/__main__.py +5 -0
- bootstack/_core/__init__.py +21 -0
- bootstack/_core/capabilities/__init__.py +45 -0
- bootstack/_core/capabilities/after.py +103 -0
- bootstack/_core/capabilities/bind.py +192 -0
- bootstack/_core/capabilities/bindtags.py +112 -0
- bootstack/_core/capabilities/busy.py +72 -0
- bootstack/_core/capabilities/clipboard.py +89 -0
- bootstack/_core/capabilities/focus.py +118 -0
- bootstack/_core/capabilities/grab.py +65 -0
- bootstack/_core/capabilities/grid.py +211 -0
- bootstack/_core/capabilities/localization.py +231 -0
- bootstack/_core/capabilities/pack.py +140 -0
- bootstack/_core/capabilities/place.py +113 -0
- bootstack/_core/capabilities/selection.py +136 -0
- bootstack/_core/capabilities/signals.py +244 -0
- bootstack/_core/capabilities/winfo.py +315 -0
- bootstack/_core/colorutils.py +234 -0
- bootstack/_core/exceptions.py +25 -0
- bootstack/_core/images.py +463 -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/paths.py +49 -0
- bootstack/_core/publisher.py +149 -0
- bootstack/_core/variables.py +62 -0
- bootstack/_runtime/__init__.py +3 -0
- bootstack/_runtime/app.py +930 -0
- bootstack/_runtime/base_window.py +945 -0
- bootstack/_runtime/events.py +399 -0
- bootstack/_runtime/shortcuts.py +496 -0
- bootstack/_runtime/tk_patch.py +43 -0
- bootstack/_runtime/toplevel.py +276 -0
- bootstack/_runtime/utility.py +457 -0
- bootstack/_runtime/visual_focus.py +240 -0
- bootstack/_runtime/window_utilities.py +1123 -0
- bootstack/assets/__init__.py +21 -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/button-compact.png +0 -0
- bootstack/assets/elements/button-default.png +0 -0
- bootstack/assets/elements/buttongroup-after-h-compact.png +0 -0
- bootstack/assets/elements/buttongroup-after-h-default.png +0 -0
- bootstack/assets/elements/buttongroup-after-v-compact.png +0 -0
- bootstack/assets/elements/buttongroup-after-v-default.png +0 -0
- bootstack/assets/elements/buttongroup-before-h-compact.png +0 -0
- bootstack/assets/elements/buttongroup-before-h-default.png +0 -0
- bootstack/assets/elements/buttongroup-before-v-compact.png +0 -0
- bootstack/assets/elements/buttongroup-before-v-default.png +0 -0
- bootstack/assets/elements/buttongroup-center-h-compact.png +0 -0
- bootstack/assets/elements/buttongroup-center-h-default.png +0 -0
- bootstack/assets/elements/buttongroup-center-v-compact.png +0 -0
- bootstack/assets/elements/buttongroup-center-v-default.png +0 -0
- bootstack/assets/elements/card.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-addon-compact.png +0 -0
- bootstack/assets/elements/input-addon-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/listrow-compact.png +0 -0
- bootstack/assets/elements/listrow-default.png +0 -0
- bootstack/assets/elements/manifest.toml +361 -0
- bootstack/assets/elements/menu-item.png +0 -0
- bootstack/assets/elements/navitem-compact.png +0 -0
- bootstack/assets/elements/navitem-default.png +0 -0
- bootstack/assets/elements/progressbar-h-compact.png +0 -0
- bootstack/assets/elements/progressbar-h-default.png +0 -0
- bootstack/assets/elements/progressbar-v-compact.png +0 -0
- bootstack/assets/elements/progressbar-v-default.png +0 -0
- bootstack/assets/elements/radiobutton.png +0 -0
- bootstack/assets/elements/scrollbar-horizontal.png +0 -0
- bootstack/assets/elements/scrollbar-vertical.png +0 -0
- bootstack/assets/elements/slider-handle.png +0 -0
- bootstack/assets/elements/slider-track-h.png +0 -0
- bootstack/assets/elements/slider-track-v.png +0 -0
- bootstack/assets/elements/switch-off.png +0 -0
- bootstack/assets/elements/switch-on.png +0 -0
- bootstack/assets/elements/tab-h.png +0 -0
- bootstack/assets/elements/tab-v.png +0 -0
- bootstack/assets/icons/bootstrap.ttf +0 -0
- bootstack/assets/icons/glyphmap.json +2080 -0
- bootstack/assets/icons/icon_metrics.json +12470 -0
- bootstack/assets/locales/ar/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/ar/LC_MESSAGES/bootstack.po +856 -0
- bootstack/assets/locales/bg/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/bg/LC_MESSAGES/bootstack.po +878 -0
- bootstack/assets/locales/cs/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/cs/LC_MESSAGES/bootstack.po +856 -0
- bootstack/assets/locales/da/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/da/LC_MESSAGES/bootstack.po +856 -0
- bootstack/assets/locales/de/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/de/LC_MESSAGES/bootstack.po +856 -0
- bootstack/assets/locales/en/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/en/LC_MESSAGES/bootstack.po +878 -0
- bootstack/assets/locales/es/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/es/LC_MESSAGES/bootstack.po +856 -0
- bootstack/assets/locales/fr/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/fr/LC_MESSAGES/bootstack.po +856 -0
- bootstack/assets/locales/he/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/he/LC_MESSAGES/bootstack.po +854 -0
- bootstack/assets/locales/hi/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/hi/LC_MESSAGES/bootstack.po +845 -0
- bootstack/assets/locales/it/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/it/LC_MESSAGES/bootstack.po +844 -0
- bootstack/assets/locales/ja/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/ja/LC_MESSAGES/bootstack.po +917 -0
- bootstack/assets/locales/ko/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/ko/LC_MESSAGES/bootstack.po +845 -0
- bootstack/assets/locales/nb/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/nb/LC_MESSAGES/bootstack.po +844 -0
- bootstack/assets/locales/nl/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/nl/LC_MESSAGES/bootstack.po +844 -0
- bootstack/assets/locales/pl/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/pl/LC_MESSAGES/bootstack.po +845 -0
- bootstack/assets/locales/pt/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/pt/LC_MESSAGES/bootstack.po +845 -0
- bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.po +845 -0
- bootstack/assets/locales/sl/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/sl/LC_MESSAGES/bootstack.po +845 -0
- bootstack/assets/locales/sv/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/sv/LC_MESSAGES/bootstack.po +845 -0
- bootstack/assets/locales/tr/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/tr/LC_MESSAGES/bootstack.po +845 -0
- bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.po +845 -0
- bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.po +845 -0
- bootstack/cli/__init__.py +133 -0
- bootstack/cli/__main__.py +6 -0
- bootstack/cli/add.py +395 -0
- bootstack/cli/appicon.py +285 -0
- bootstack/cli/build.py +115 -0
- bootstack/cli/config.py +313 -0
- bootstack/cli/demo.py +564 -0
- bootstack/cli/dev.py +153 -0
- bootstack/cli/doctor.py +195 -0
- bootstack/cli/icons.py +98 -0
- bootstack/cli/promote.py +120 -0
- bootstack/cli/pyinstaller.py +268 -0
- bootstack/cli/run.py +95 -0
- bootstack/cli/start.py +117 -0
- bootstack/cli/templates/__init__.py +931 -0
- bootstack/clipboard.py +48 -0
- bootstack/constants.py +318 -0
- bootstack/data/README.md +615 -0
- bootstack/data/__init__.py +78 -0
- bootstack/data/_observable.py +276 -0
- bootstack/data/base.py +780 -0
- bootstack/data/file_source.py +367 -0
- bootstack/data/memory_source.py +450 -0
- bootstack/data/query.py +367 -0
- bootstack/data/readers.py +289 -0
- bootstack/data/sqlite_source.py +869 -0
- bootstack/data/types.py +354 -0
- bootstack/data/writers.py +232 -0
- bootstack/dev/__init__.py +36 -0
- bootstack/dev/_capture.py +141 -0
- bootstack/dev/_env.py +43 -0
- bootstack/dev/_registry.py +140 -0
- bootstack/dev/_reloader.py +351 -0
- bootstack/dev/_reset.py +50 -0
- bootstack/dev/_watcher.py +91 -0
- bootstack/dialogs/__init__.py +948 -0
- bootstack/dialogs/_impl/__init__.py +47 -0
- bootstack/dialogs/_impl/colorchooser.py +588 -0
- bootstack/dialogs/_impl/datedialog.py +450 -0
- bootstack/dialogs/_impl/dialog.py +594 -0
- bootstack/dialogs/_impl/filterdialog.py +358 -0
- bootstack/dialogs/_impl/fontdialog.py +364 -0
- bootstack/dialogs/_impl/formdialog.py +564 -0
- bootstack/dialogs/_impl/message.py +486 -0
- bootstack/dialogs/_impl/query.py +570 -0
- bootstack/errors.py +67 -0
- bootstack/events/__init__.py +111 -0
- bootstack/events/_event.py +135 -0
- bootstack/events/_payloads.py +539 -0
- bootstack/events/_subscription.py +38 -0
- bootstack/i18n/README.md +77 -0
- bootstack/i18n/__init__.py +23 -0
- bootstack/i18n/catalog.py +121 -0
- bootstack/i18n/intl_format.py +584 -0
- bootstack/i18n/msgcat.py +425 -0
- bootstack/i18n/specs.py +156 -0
- bootstack/images.py +563 -0
- bootstack/py.typed +1 -0
- bootstack/scheduling/__init__.py +11 -0
- bootstack/scheduling/_schedule.py +218 -0
- bootstack/shortcuts.py +21 -0
- bootstack/signals/README.md +98 -0
- bootstack/signals/__init__.py +10 -0
- bootstack/signals/integration.py +100 -0
- bootstack/signals/signal.py +353 -0
- bootstack/signals/types.py +6 -0
- bootstack/store.py +286 -0
- bootstack/streams/__init__.py +12 -0
- bootstack/streams/_stream.py +321 -0
- bootstack/style/__init__.py +38 -0
- bootstack/style/builders/__init__.py +51 -0
- bootstack/style/builders/badge.py +46 -0
- bootstack/style/builders/button.py +339 -0
- bootstack/style/builders/buttongroup.py +311 -0
- bootstack/style/builders/calendar.py +271 -0
- bootstack/style/builders/checkbutton.py +110 -0
- bootstack/style/builders/combobox.py +113 -0
- bootstack/style/builders/contextmenu.py +268 -0
- bootstack/style/builders/entry.py +82 -0
- bootstack/style/builders/expander.py +148 -0
- bootstack/style/builders/field.py +335 -0
- bootstack/style/builders/frame.py +50 -0
- bootstack/style/builders/label.py +28 -0
- bootstack/style/builders/labelframe.py +34 -0
- bootstack/style/builders/listview.py +369 -0
- bootstack/style/builders/menubar.py +91 -0
- bootstack/style/builders/menubutton.py +359 -0
- bootstack/style/builders/panedwindow.py +25 -0
- bootstack/style/builders/progressbar.py +67 -0
- bootstack/style/builders/radiobutton.py +99 -0
- bootstack/style/builders/scale.py +64 -0
- bootstack/style/builders/scrollbar.py +225 -0
- bootstack/style/builders/separator.py +49 -0
- bootstack/style/builders/sidenav.py +643 -0
- bootstack/style/builders/sizegrip.py +15 -0
- bootstack/style/builders/spinbox.py +119 -0
- bootstack/style/builders/switch.py +70 -0
- bootstack/style/builders/tabitem.py +204 -0
- bootstack/style/builders/togglegroup.py +294 -0
- bootstack/style/builders/toolbutton.py +275 -0
- bootstack/style/builders/tooltip.py +26 -0
- bootstack/style/builders/treeview.py +193 -0
- bootstack/style/builders/utils.py +455 -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/fonts.py +123 -0
- bootstack/style/style.py +609 -0
- bootstack/style/style_builder_base.py +716 -0
- bootstack/style/style_builder_mixed.py +93 -0
- bootstack/style/style_builder_tk.py +109 -0
- bootstack/style/style_builder_ttk.py +353 -0
- bootstack/style/style_resolver.py +447 -0
- bootstack/style/theme.py +245 -0
- bootstack/style/theme_provider.py +471 -0
- bootstack/style/themes/__init__.py +128 -0
- bootstack/style/tk_patch.py +5 -0
- bootstack/style/token_maps.py +41 -0
- bootstack/style/types.py +32 -0
- bootstack/style/typography.py +523 -0
- bootstack/style/utility.py +746 -0
- bootstack/types.py +39 -0
- bootstack/validation/__init__.py +6 -0
- bootstack/validation/types.py +15 -0
- bootstack/validation/validation_result.py +17 -0
- bootstack/validation/validation_rules.py +205 -0
- bootstack/widgets/__init__.py +74 -0
- bootstack/widgets/_core/__init__.py +31 -0
- bootstack/widgets/_core/app_config.py +266 -0
- bootstack/widgets/_core/base.py +461 -0
- bootstack/widgets/_core/container.py +334 -0
- bootstack/widgets/_core/context.py +35 -0
- bootstack/widgets/_core/events.py +130 -0
- bootstack/widgets/_core/field_mixin.py +353 -0
- bootstack/widgets/_core/icon_image_props.py +72 -0
- bootstack/widgets/_core/image_binding.py +93 -0
- bootstack/widgets/_core/navmodel.py +345 -0
- bootstack/widgets/_core/options.py +210 -0
- bootstack/widgets/_core/selection_group.py +130 -0
- bootstack/widgets/_core/window_controls.py +96 -0
- bootstack/widgets/_core/window_menu.py +246 -0
- bootstack/widgets/_impl/__init__.py +1 -0
- bootstack/widgets/_impl/_internal/__init__.py +0 -0
- bootstack/widgets/_impl/_internal/wrapper_base.py +307 -0
- bootstack/widgets/_impl/_parts/__init__.py +11 -0
- bootstack/widgets/_impl/_parts/numberentry_part.py +385 -0
- bootstack/widgets/_impl/_parts/spinnerentry_part.py +434 -0
- bootstack/widgets/_impl/_parts/textentry_part.py +406 -0
- bootstack/widgets/_impl/composites/__init__.py +33 -0
- bootstack/widgets/_impl/composites/_dateutils.py +33 -0
- bootstack/widgets/_impl/composites/_image_fit.py +105 -0
- bootstack/widgets/_impl/composites/accordion.py +381 -0
- bootstack/widgets/_impl/composites/avatar.py +191 -0
- bootstack/widgets/_impl/composites/buttongroup.py +371 -0
- bootstack/widgets/_impl/composites/calendar.py +972 -0
- bootstack/widgets/_impl/composites/carousel.py +567 -0
- bootstack/widgets/_impl/composites/chart.py +882 -0
- bootstack/widgets/_impl/composites/compositeframe.py +298 -0
- bootstack/widgets/_impl/composites/contextmenu.py +1951 -0
- bootstack/widgets/_impl/composites/dateentry.py +404 -0
- bootstack/widgets/_impl/composites/dropdownbutton.py +325 -0
- bootstack/widgets/_impl/composites/expander.py +515 -0
- bootstack/widgets/_impl/composites/field.py +670 -0
- bootstack/widgets/_impl/composites/form.py +1066 -0
- bootstack/widgets/_impl/composites/gallery.py +551 -0
- bootstack/widgets/_impl/composites/list/__init__.py +15 -0
- bootstack/widgets/_impl/composites/list/listitem.py +802 -0
- bootstack/widgets/_impl/composites/list/listview.py +1433 -0
- bootstack/widgets/_impl/composites/menu/__init__.py +18 -0
- bootstack/widgets/_impl/composites/menu/model.py +358 -0
- bootstack/widgets/_impl/composites/menu/render_native.py +134 -0
- bootstack/widgets/_impl/composites/menu/render_themed.py +134 -0
- bootstack/widgets/_impl/composites/meter.py +860 -0
- bootstack/widgets/_impl/composites/numericentry.py +201 -0
- bootstack/widgets/_impl/composites/pagestack.py +395 -0
- bootstack/widgets/_impl/composites/passwordentry.py +142 -0
- bootstack/widgets/_impl/composites/pathentry.py +168 -0
- bootstack/widgets/_impl/composites/picture.py +289 -0
- bootstack/widgets/_impl/composites/radiogroup.py +511 -0
- bootstack/widgets/_impl/composites/scrolledtext.py +375 -0
- bootstack/widgets/_impl/composites/scrolledtext.pyi +186 -0
- bootstack/widgets/_impl/composites/scrollview.py +764 -0
- bootstack/widgets/_impl/composites/selectbox.py +1026 -0
- bootstack/widgets/_impl/composites/shell/__init__.py +40 -0
- bootstack/widgets/_impl/composites/shell/content_host.py +52 -0
- bootstack/widgets/_impl/composites/shell/layout.py +335 -0
- bootstack/widgets/_impl/composites/shell/nav_panel.py +345 -0
- bootstack/widgets/_impl/composites/shell/providers.py +558 -0
- bootstack/widgets/_impl/composites/shell/rail.py +117 -0
- bootstack/widgets/_impl/composites/shell/shell.py +581 -0
- bootstack/widgets/_impl/composites/shell/workspace.py +273 -0
- bootstack/widgets/_impl/composites/sidenav/__init__.py +16 -0
- bootstack/widgets/_impl/composites/sidenav/header.py +81 -0
- bootstack/widgets/_impl/composites/sidenav/separator.py +44 -0
- bootstack/widgets/_impl/composites/slider/__init__.py +7 -0
- bootstack/widgets/_impl/composites/slider/_shared.py +195 -0
- bootstack/widgets/_impl/composites/slider/rangeslider.py +982 -0
- bootstack/widgets/_impl/composites/slider/slider.py +851 -0
- bootstack/widgets/_impl/composites/spinnerentry.py +185 -0
- bootstack/widgets/_impl/composites/tableview/__init__.py +5 -0
- bootstack/widgets/_impl/composites/tableview/tableview.py +3388 -0
- bootstack/widgets/_impl/composites/tableview/types.py +169 -0
- bootstack/widgets/_impl/composites/tabs/__init__.py +23 -0
- bootstack/widgets/_impl/composites/tabs/tabitem.py +389 -0
- bootstack/widgets/_impl/composites/tabs/tabs.py +974 -0
- bootstack/widgets/_impl/composites/tabs/tabview.py +650 -0
- bootstack/widgets/_impl/composites/textarea/__init__.py +26 -0
- bootstack/widgets/_impl/composites/textarea/change.py +46 -0
- bootstack/widgets/_impl/composites/textarea/codeeditor.py +526 -0
- bootstack/widgets/_impl/composites/textarea/core.py +495 -0
- bootstack/widgets/_impl/composites/textarea/decoration.py +42 -0
- bootstack/widgets/_impl/composites/textarea/diff.py +127 -0
- bootstack/widgets/_impl/composites/textarea/extensions/__init__.py +1 -0
- bootstack/widgets/_impl/composites/textarea/extensions/bracket_matcher.py +138 -0
- bootstack/widgets/_impl/composites/textarea/extensions/indent_guides.py +158 -0
- bootstack/widgets/_impl/composites/textarea/extensions/line_numbers.py +138 -0
- bootstack/widgets/_impl/composites/textarea/extensions/pygments_highlighter.py +312 -0
- bootstack/widgets/_impl/composites/textarea/extensions/smart_indent.py +177 -0
- bootstack/widgets/_impl/composites/textarea/filter.py +171 -0
- bootstack/widgets/_impl/composites/textarea/search_overlay.py +459 -0
- bootstack/widgets/_impl/composites/textarea/sidebar.py +88 -0
- bootstack/widgets/_impl/composites/textarea/style_registry.py +178 -0
- bootstack/widgets/_impl/composites/textarea/textarea.py +606 -0
- bootstack/widgets/_impl/composites/textarea/undo.py +217 -0
- bootstack/widgets/_impl/composites/textentry.py +57 -0
- bootstack/widgets/_impl/composites/timeentry.py +176 -0
- bootstack/widgets/_impl/composites/toast.py +390 -0
- bootstack/widgets/_impl/composites/toast_stack.py +156 -0
- bootstack/widgets/_impl/composites/togglegroup.py +418 -0
- bootstack/widgets/_impl/composites/toolbar.py +608 -0
- bootstack/widgets/_impl/composites/tooltip.py +491 -0
- bootstack/widgets/_impl/composites/tree/__init__.py +7 -0
- bootstack/widgets/_impl/composites/tree/source_binding.py +136 -0
- bootstack/widgets/_impl/composites/tree/treeitem.py +393 -0
- bootstack/widgets/_impl/composites/tree/treenode.py +174 -0
- bootstack/widgets/_impl/composites/tree/treeview.py +841 -0
- bootstack/widgets/_impl/mixins/__init__.py +24 -0
- bootstack/widgets/_impl/mixins/configure_mixin.py +216 -0
- bootstack/widgets/_impl/mixins/entry_mixin.py +134 -0
- bootstack/widgets/_impl/mixins/font_mixin.py +368 -0
- bootstack/widgets/_impl/mixins/icon_mixin.py +61 -0
- bootstack/widgets/_impl/mixins/localization_mixin.py +253 -0
- bootstack/widgets/_impl/mixins/signal_mixin.py +268 -0
- bootstack/widgets/_impl/mixins/validation_mixin.py +226 -0
- bootstack/widgets/_impl/primitives/__init__.py +49 -0
- bootstack/widgets/_impl/primitives/_menubutton.py +107 -0
- bootstack/widgets/_impl/primitives/badge.py +45 -0
- bootstack/widgets/_impl/primitives/button.py +76 -0
- bootstack/widgets/_impl/primitives/card.py +45 -0
- bootstack/widgets/_impl/primitives/checkbutton.py +124 -0
- bootstack/widgets/_impl/primitives/checktoggle.py +62 -0
- bootstack/widgets/_impl/primitives/combobox.py +156 -0
- bootstack/widgets/_impl/primitives/entry.py +87 -0
- bootstack/widgets/_impl/primitives/flexframe.py +448 -0
- bootstack/widgets/_impl/primitives/frame.py +185 -0
- bootstack/widgets/_impl/primitives/gridframe.py +546 -0
- bootstack/widgets/_impl/primitives/label.py +84 -0
- bootstack/widgets/_impl/primitives/labelframe.py +54 -0
- bootstack/widgets/_impl/primitives/optionmenu.py +387 -0
- bootstack/widgets/_impl/primitives/packframe.py +227 -0
- bootstack/widgets/_impl/primitives/panedwindow.py +45 -0
- bootstack/widgets/_impl/primitives/progressbar.py +83 -0
- bootstack/widgets/_impl/primitives/radiobutton.py +115 -0
- bootstack/widgets/_impl/primitives/radiotoggle.py +54 -0
- bootstack/widgets/_impl/primitives/scrollbar.py +42 -0
- bootstack/widgets/_impl/primitives/separator.py +43 -0
- bootstack/widgets/_impl/primitives/sizegrip.py +33 -0
- bootstack/widgets/_impl/primitives/spinbox.py +95 -0
- bootstack/widgets/_impl/primitives/switch.py +44 -0
- bootstack/widgets/_impl/primitives/treeview.py +69 -0
- bootstack/widgets/app.py +371 -0
- bootstack/widgets/appshell.py +1179 -0
- bootstack/widgets/avatar.py +140 -0
- bootstack/widgets/boolean_controls.py +455 -0
- bootstack/widgets/button.py +224 -0
- bootstack/widgets/buttongroup.py +239 -0
- bootstack/widgets/calendar.py +195 -0
- bootstack/widgets/card.py +159 -0
- bootstack/widgets/carousel.py +241 -0
- bootstack/widgets/chart.py +302 -0
- bootstack/widgets/codeeditor.py +675 -0
- bootstack/widgets/contextmenu.py +371 -0
- bootstack/widgets/datatable.py +688 -0
- bootstack/widgets/datefield.py +395 -0
- bootstack/widgets/divider.py +60 -0
- bootstack/widgets/expander.py +579 -0
- bootstack/widgets/form.py +200 -0
- bootstack/widgets/gallery.py +250 -0
- bootstack/widgets/gauge.py +168 -0
- bootstack/widgets/grid.py +121 -0
- bootstack/widgets/groupbox.py +162 -0
- bootstack/widgets/label.py +229 -0
- bootstack/widgets/listview.py +354 -0
- bootstack/widgets/menubutton.py +419 -0
- bootstack/widgets/numberfield.py +431 -0
- bootstack/widgets/pagestack.py +345 -0
- bootstack/widgets/passwordfield.py +383 -0
- bootstack/widgets/pathfield.py +454 -0
- bootstack/widgets/picture.py +251 -0
- bootstack/widgets/progressbar.py +106 -0
- bootstack/widgets/radio_variants.py +271 -0
- bootstack/widgets/radiogroup.py +228 -0
- bootstack/widgets/scrollbar.py +64 -0
- bootstack/widgets/scrollview.py +186 -0
- bootstack/widgets/select.py +302 -0
- bootstack/widgets/selectbutton.py +182 -0
- bootstack/widgets/sidebar_toggle.py +130 -0
- bootstack/widgets/sizegrip.py +42 -0
- bootstack/widgets/slider.py +408 -0
- bootstack/widgets/spinbox.py +147 -0
- bootstack/widgets/spinnerfield.py +413 -0
- bootstack/widgets/splash.py +367 -0
- bootstack/widgets/splitview.py +482 -0
- bootstack/widgets/stacks.py +249 -0
- bootstack/widgets/statusbar.py +189 -0
- bootstack/widgets/tabs.py +425 -0
- bootstack/widgets/textarea.py +459 -0
- bootstack/widgets/textfield.py +410 -0
- bootstack/widgets/theme_toggle.py +92 -0
- bootstack/widgets/timefield.py +340 -0
- bootstack/widgets/toast.py +314 -0
- bootstack/widgets/togglegroup.py +231 -0
- bootstack/widgets/toolbar.py +347 -0
- bootstack/widgets/tooltip.py +94 -0
- bootstack/widgets/tree.py +648 -0
- bootstack/widgets/types.py +305 -0
- bootstack/widgets/window.py +307 -0
- bootstack-0.1.0.dist-info/METADATA +301 -0
- bootstack-0.1.0.dist-info/RECORD +471 -0
- bootstack-0.1.0.dist-info/WHEEL +5 -0
- bootstack-0.1.0.dist-info/entry_points.txt +2 -0
- bootstack-0.1.0.dist-info/licenses/LICENSE +21 -0
- bootstack-0.1.0.dist-info/licenses/NOTICE +10 -0
- bootstack-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import tkinter as tk
|
|
4
|
+
from typing import Any, Callable, Generic, Optional, TypeVar
|
|
5
|
+
|
|
6
|
+
from bootstack.events import Subscription
|
|
7
|
+
|
|
8
|
+
T = TypeVar("T")
|
|
9
|
+
U = TypeVar("U")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Handle:
|
|
13
|
+
"""Cancellable handle returned by stream terminal operators.
|
|
14
|
+
|
|
15
|
+
Duck-type compatible with `Subscription` — supports `.cancel()`,
|
|
16
|
+
context manager protocol, and `.cancelled` property.
|
|
17
|
+
|
|
18
|
+
Returned by `Stream.listen()` and time-based stream operators
|
|
19
|
+
(`debounce`, `throttle`, `delay`).
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
__slots__ = ("_fn", "_cancelled")
|
|
23
|
+
|
|
24
|
+
def __init__(self, cancel_fn: Callable[[], None]) -> None:
|
|
25
|
+
self._fn = cancel_fn
|
|
26
|
+
self._cancelled = False
|
|
27
|
+
|
|
28
|
+
def cancel(self) -> None:
|
|
29
|
+
"""Detach the handler and clean up all resources in the chain."""
|
|
30
|
+
if self._cancelled:
|
|
31
|
+
return
|
|
32
|
+
self._cancelled = True
|
|
33
|
+
try:
|
|
34
|
+
self._fn()
|
|
35
|
+
except Exception:
|
|
36
|
+
pass
|
|
37
|
+
|
|
38
|
+
def __enter__(self) -> "Handle":
|
|
39
|
+
return self
|
|
40
|
+
|
|
41
|
+
def __exit__(self, *_: Any) -> None:
|
|
42
|
+
self.cancel()
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def cancelled(self) -> bool:
|
|
46
|
+
"""True once `.cancel()` has been called."""
|
|
47
|
+
return self._cancelled
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class _Scheduler:
|
|
51
|
+
"""Timer adapter for stream operators.
|
|
52
|
+
|
|
53
|
+
Tracks all pending tokens and cancels them when the owner widget is
|
|
54
|
+
destroyed, preventing callbacks from firing on dead widgets.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
__slots__ = ("_w", "_tokens")
|
|
58
|
+
|
|
59
|
+
def __init__(self, widget: tk.Misc) -> None:
|
|
60
|
+
self._w = widget
|
|
61
|
+
self._tokens: set = set()
|
|
62
|
+
try:
|
|
63
|
+
widget.bind("<Destroy>", self._on_destroy, add=True)
|
|
64
|
+
except Exception:
|
|
65
|
+
pass
|
|
66
|
+
|
|
67
|
+
def call_later(self, ms: int, fn: Callable[[], None]) -> Any:
|
|
68
|
+
tok = self._w.after(max(0, int(ms)), fn)
|
|
69
|
+
self._tokens.add(tok)
|
|
70
|
+
return tok
|
|
71
|
+
|
|
72
|
+
def cancel(self, token: Any) -> None:
|
|
73
|
+
self._tokens.discard(token)
|
|
74
|
+
try:
|
|
75
|
+
self._w.after_cancel(token)
|
|
76
|
+
except Exception:
|
|
77
|
+
pass
|
|
78
|
+
|
|
79
|
+
def _on_destroy(self, *_: Any) -> None:
|
|
80
|
+
for tok in list(self._tokens):
|
|
81
|
+
try:
|
|
82
|
+
self._w.after_cancel(tok)
|
|
83
|
+
except Exception:
|
|
84
|
+
pass
|
|
85
|
+
self._tokens.clear()
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
# Union of the two subscription-compatible types.
|
|
89
|
+
AnySubscription = Subscription | Handle
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class Stream(Generic[T]):
|
|
93
|
+
"""A composable push-stream for widget events.
|
|
94
|
+
|
|
95
|
+
Created by `widget.on(event)` (no handler). Chain operators to transform
|
|
96
|
+
or filter events, then call `.listen(handler)` to attach a handler and
|
|
97
|
+
activate the upstream event binding.
|
|
98
|
+
|
|
99
|
+
Usage::
|
|
100
|
+
|
|
101
|
+
# Simple — bind immediately, return Subscription
|
|
102
|
+
sub = widget.on("change", handler)
|
|
103
|
+
|
|
104
|
+
# Composed — lazy bind, activated by .listen()
|
|
105
|
+
sub = (
|
|
106
|
+
widget.on("change")
|
|
107
|
+
.debounce(300)
|
|
108
|
+
.filter(lambda e: len(e.value or "") > 1)
|
|
109
|
+
.listen(on_search)
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
sub.cancel() # detach handler and remove the event binding
|
|
113
|
+
|
|
114
|
+
All operator methods return a new `Stream` — they do not consume the
|
|
115
|
+
original. `.listen()` is the only terminal; it activates the binding and
|
|
116
|
+
returns a cancellable handle.
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
owner: Widget used for timer scheduling (debounce/throttle delays).
|
|
120
|
+
_source: Internal — callable that, given a downstream handler,
|
|
121
|
+
installs the upstream binding and returns a handle.
|
|
122
|
+
"""
|
|
123
|
+
|
|
124
|
+
def __init__(
|
|
125
|
+
self,
|
|
126
|
+
owner: tk.Misc,
|
|
127
|
+
*,
|
|
128
|
+
_source: Optional[Callable[[Callable[[T], Any]], AnySubscription]] = None,
|
|
129
|
+
_scheduler: Optional[_Scheduler] = None,
|
|
130
|
+
) -> None:
|
|
131
|
+
self._owner = owner
|
|
132
|
+
self._source = _source
|
|
133
|
+
self._sched = _scheduler or _Scheduler(owner)
|
|
134
|
+
|
|
135
|
+
# ----- operators ---------------------------------------------------------
|
|
136
|
+
|
|
137
|
+
def map(self, fn: Callable[[T], U]) -> "Stream[U]":
|
|
138
|
+
"""Transform each event value through `fn`.
|
|
139
|
+
|
|
140
|
+
Args:
|
|
141
|
+
fn: Mapping function applied to each value.
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
New stream emitting transformed values.
|
|
145
|
+
"""
|
|
146
|
+
parent = self
|
|
147
|
+
|
|
148
|
+
def _source(handler: Callable[[U], Any]) -> AnySubscription:
|
|
149
|
+
return parent.listen(lambda v: handler(fn(v)))
|
|
150
|
+
|
|
151
|
+
return Stream(self._owner, _source=_source, _scheduler=self._sched)
|
|
152
|
+
|
|
153
|
+
def filter(self, pred: Callable[[T], bool]) -> "Stream[T]":
|
|
154
|
+
"""Emit only values for which `pred(value)` is `True`.
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
pred: Predicate — values returning `False` are dropped.
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
New stream emitting only matching values.
|
|
161
|
+
"""
|
|
162
|
+
parent = self
|
|
163
|
+
|
|
164
|
+
def _source(handler: Callable[[T], Any]) -> AnySubscription:
|
|
165
|
+
return parent.listen(lambda v: handler(v) if pred(v) else None)
|
|
166
|
+
|
|
167
|
+
return Stream(self._owner, _source=_source, _scheduler=self._sched)
|
|
168
|
+
|
|
169
|
+
def tap(self, fn: Callable[[T], Any]) -> "Stream[T]":
|
|
170
|
+
"""Call `fn` for side-effects on each value; forward value unchanged.
|
|
171
|
+
|
|
172
|
+
Args:
|
|
173
|
+
fn: Side-effect function (result is ignored).
|
|
174
|
+
|
|
175
|
+
Returns:
|
|
176
|
+
New stream emitting the original values.
|
|
177
|
+
"""
|
|
178
|
+
parent = self
|
|
179
|
+
|
|
180
|
+
def _source(handler: Callable[[T], Any]) -> AnySubscription:
|
|
181
|
+
def _tap(v: T) -> None:
|
|
182
|
+
fn(v)
|
|
183
|
+
handler(v)
|
|
184
|
+
return parent.listen(_tap)
|
|
185
|
+
|
|
186
|
+
return Stream(self._owner, _source=_source, _scheduler=self._sched)
|
|
187
|
+
|
|
188
|
+
def debounce(self, ms: int) -> "Stream[T]":
|
|
189
|
+
"""Emit after `ms` milliseconds of silence — resets on each new value.
|
|
190
|
+
|
|
191
|
+
Useful for search-as-you-type: only fires after the user stops typing.
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
ms: Quiet period in milliseconds before emission.
|
|
195
|
+
|
|
196
|
+
Returns:
|
|
197
|
+
New stream emitting debounced values.
|
|
198
|
+
"""
|
|
199
|
+
parent = self
|
|
200
|
+
sched = self._sched
|
|
201
|
+
|
|
202
|
+
def _source(handler: Callable[[T], Any]) -> AnySubscription:
|
|
203
|
+
state: dict[str, Any] = {"token": None, "last": None}
|
|
204
|
+
|
|
205
|
+
def _fire() -> None:
|
|
206
|
+
state["token"] = None
|
|
207
|
+
handler(state["last"])
|
|
208
|
+
|
|
209
|
+
def _on_value(v: T) -> None:
|
|
210
|
+
state["last"] = v
|
|
211
|
+
if state["token"] is not None:
|
|
212
|
+
sched.cancel(state["token"])
|
|
213
|
+
state["token"] = sched.call_later(ms, _fire)
|
|
214
|
+
|
|
215
|
+
upstream = parent.listen(_on_value)
|
|
216
|
+
|
|
217
|
+
def _cancel() -> None:
|
|
218
|
+
if state["token"] is not None:
|
|
219
|
+
sched.cancel(state["token"])
|
|
220
|
+
state["token"] = None
|
|
221
|
+
upstream.cancel()
|
|
222
|
+
|
|
223
|
+
return Handle(_cancel)
|
|
224
|
+
|
|
225
|
+
return Stream(self._owner, _source=_source, _scheduler=self._sched)
|
|
226
|
+
|
|
227
|
+
def throttle(self, ms: int) -> "Stream[T]":
|
|
228
|
+
"""Emit at most once per `ms` milliseconds (leading edge).
|
|
229
|
+
|
|
230
|
+
Args:
|
|
231
|
+
ms: Minimum interval between emissions in milliseconds.
|
|
232
|
+
|
|
233
|
+
Returns:
|
|
234
|
+
New stream emitting throttled values.
|
|
235
|
+
"""
|
|
236
|
+
parent = self
|
|
237
|
+
sched = self._sched
|
|
238
|
+
|
|
239
|
+
def _source(handler: Callable[[T], Any]) -> AnySubscription:
|
|
240
|
+
state: dict[str, Any] = {"open": True, "token": None}
|
|
241
|
+
|
|
242
|
+
def _reopen() -> None:
|
|
243
|
+
state["open"] = True
|
|
244
|
+
state["token"] = None
|
|
245
|
+
|
|
246
|
+
def _on_value(v: T) -> None:
|
|
247
|
+
if state["open"]:
|
|
248
|
+
state["open"] = False
|
|
249
|
+
handler(v)
|
|
250
|
+
state["token"] = sched.call_later(ms, _reopen)
|
|
251
|
+
|
|
252
|
+
upstream = parent.listen(_on_value)
|
|
253
|
+
|
|
254
|
+
def _cancel() -> None:
|
|
255
|
+
if state["token"] is not None:
|
|
256
|
+
sched.cancel(state["token"])
|
|
257
|
+
state["token"] = None
|
|
258
|
+
upstream.cancel()
|
|
259
|
+
|
|
260
|
+
return Handle(_cancel)
|
|
261
|
+
|
|
262
|
+
return Stream(self._owner, _source=_source, _scheduler=self._sched)
|
|
263
|
+
|
|
264
|
+
def delay(self, ms: int) -> "Stream[T]":
|
|
265
|
+
"""Re-emit each value after a fixed `ms` millisecond delay.
|
|
266
|
+
|
|
267
|
+
Args:
|
|
268
|
+
ms: Delay in milliseconds applied to each value.
|
|
269
|
+
|
|
270
|
+
Returns:
|
|
271
|
+
New stream emitting delayed values.
|
|
272
|
+
"""
|
|
273
|
+
parent = self
|
|
274
|
+
sched = self._sched
|
|
275
|
+
|
|
276
|
+
def _source(handler: Callable[[T], Any]) -> AnySubscription:
|
|
277
|
+
tokens: set[Any] = set()
|
|
278
|
+
|
|
279
|
+
def _on_value(v: T) -> None:
|
|
280
|
+
tok_holder: list[Any] = [None]
|
|
281
|
+
|
|
282
|
+
def _fire() -> None:
|
|
283
|
+
tokens.discard(tok_holder[0])
|
|
284
|
+
handler(v)
|
|
285
|
+
|
|
286
|
+
tok = sched.call_later(ms, _fire)
|
|
287
|
+
tok_holder[0] = tok
|
|
288
|
+
tokens.add(tok)
|
|
289
|
+
|
|
290
|
+
upstream = parent.listen(_on_value)
|
|
291
|
+
|
|
292
|
+
def _cancel() -> None:
|
|
293
|
+
for tok in list(tokens):
|
|
294
|
+
sched.cancel(tok)
|
|
295
|
+
tokens.clear()
|
|
296
|
+
upstream.cancel()
|
|
297
|
+
|
|
298
|
+
return Handle(_cancel)
|
|
299
|
+
|
|
300
|
+
return Stream(self._owner, _source=_source, _scheduler=self._sched)
|
|
301
|
+
|
|
302
|
+
# ----- terminal ----------------------------------------------------------
|
|
303
|
+
|
|
304
|
+
def listen(self, handler: Callable[[T], Any]) -> AnySubscription:
|
|
305
|
+
"""Attach `handler` and activate the upstream event binding.
|
|
306
|
+
|
|
307
|
+
This is the only terminal operator. Returns a cancellable handle —
|
|
308
|
+
call `.cancel()` to detach the handler and clean up all resources
|
|
309
|
+
(event binding, pending timers) in the operator chain.
|
|
310
|
+
|
|
311
|
+
Args:
|
|
312
|
+
handler: Callable invoked for each event value.
|
|
313
|
+
|
|
314
|
+
Returns:
|
|
315
|
+
Cancellable handle.
|
|
316
|
+
"""
|
|
317
|
+
if self._source is None:
|
|
318
|
+
raise RuntimeError(
|
|
319
|
+
"Stream has no source. Use widget.on(event) to create a stream."
|
|
320
|
+
)
|
|
321
|
+
return self._source(handler)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""Style engine, theming, and typography for bootstack.
|
|
2
|
+
|
|
3
|
+
`Style`, `Typography`, and `Font` are internal engine classes — import them from
|
|
4
|
+
their modules (`bootstack.style.style`, `bootstack.style.typography`) if you need
|
|
5
|
+
them. They are deliberately not part of the public API: `Style` subclasses
|
|
6
|
+
`ttk.Style` (a Tkinter leak), and `Typography`/`Font` are internal registries
|
|
7
|
+
slated to be replaced by a public font-token API.
|
|
8
|
+
|
|
9
|
+
The low-level engine accessors `get_style`, `get_style_builder`, and
|
|
10
|
+
`get_theme_provider` return those internal objects and are likewise not public —
|
|
11
|
+
import them from `bootstack.style.style` if you need them internally.
|
|
12
|
+
"""
|
|
13
|
+
from bootstack.style.style import (
|
|
14
|
+
get_theme,
|
|
15
|
+
get_theme_color,
|
|
16
|
+
get_themes,
|
|
17
|
+
set_theme,
|
|
18
|
+
toggle_theme,
|
|
19
|
+
)
|
|
20
|
+
from bootstack.style.theme import Theme, ThemeMode
|
|
21
|
+
from bootstack.style.fonts import (
|
|
22
|
+
get_font_families,
|
|
23
|
+
set_font_family,
|
|
24
|
+
update_font_token,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
__all__ = [
|
|
28
|
+
"Theme",
|
|
29
|
+
"ThemeMode",
|
|
30
|
+
"get_theme",
|
|
31
|
+
"get_theme_color",
|
|
32
|
+
"get_themes",
|
|
33
|
+
"set_theme",
|
|
34
|
+
"toggle_theme",
|
|
35
|
+
"get_font_families",
|
|
36
|
+
"set_font_family",
|
|
37
|
+
"update_font_token",
|
|
38
|
+
]
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""Style builder functions for bootstack widgets.
|
|
2
|
+
|
|
3
|
+
This package contains individual builder functions organized by widget type.
|
|
4
|
+
Each builder is registered with the StyleBuilder registry using decorators.
|
|
5
|
+
|
|
6
|
+
Builder modules are automatically imported to trigger registration.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from . import (
|
|
12
|
+
badge, button, checkbutton, combobox, entry, expander, frame, label, labelframe, menubutton, sidenav,
|
|
13
|
+
panedwindow, progressbar, radiobutton, scale, scrollbar, separator, sizegrip, spinbox, switch,
|
|
14
|
+
treeview, toolbutton, tooltip, field, buttongroup, togglegroup, listview, calendar, contextmenu, tabitem, menubar
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
# Import all builder modules to trigger registration
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
'badge',
|
|
21
|
+
'button',
|
|
22
|
+
'expander',
|
|
23
|
+
'frame',
|
|
24
|
+
'label',
|
|
25
|
+
'sidenav',
|
|
26
|
+
'radiobutton',
|
|
27
|
+
'checkbutton',
|
|
28
|
+
'switch',
|
|
29
|
+
'progressbar',
|
|
30
|
+
'scale',
|
|
31
|
+
'scrollbar',
|
|
32
|
+
'menubutton',
|
|
33
|
+
'entry',
|
|
34
|
+
'field',
|
|
35
|
+
'separator',
|
|
36
|
+
'combobox',
|
|
37
|
+
'labelframe',
|
|
38
|
+
'panedwindow',
|
|
39
|
+
'sizegrip',
|
|
40
|
+
'spinbox',
|
|
41
|
+
'treeview',
|
|
42
|
+
'toolbutton',
|
|
43
|
+
'tooltip',
|
|
44
|
+
'buttongroup',
|
|
45
|
+
'togglegroup',
|
|
46
|
+
'listview',
|
|
47
|
+
'calendar',
|
|
48
|
+
'contextmenu',
|
|
49
|
+
'menubar',
|
|
50
|
+
'tabitem'
|
|
51
|
+
]
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""Badge style builders.
|
|
2
|
+
|
|
3
|
+
This module contains style builders for ttk.Label widget badge variants.
|
|
4
|
+
"""
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
from bootstack.style.style_builder_ttk import StyleBuilderTtk
|
|
8
|
+
from bootstack.style.element import Element, ElementImage
|
|
9
|
+
from bootstack.style.utility import recolor_element_image
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@StyleBuilderTtk.register_builder('square', 'TBadge')
|
|
13
|
+
def build_default_badge_style(b: StyleBuilderTtk, ttk_style: str, accent: Optional[str] = None, **options):
|
|
14
|
+
build_badge(b, ttk_style, accent, 'square', **options)
|
|
15
|
+
|
|
16
|
+
@StyleBuilderTtk.register_builder('pill', 'TBadge')
|
|
17
|
+
def build_pill_badge_style(b: StyleBuilderTtk, ttk_style: str, accent: Optional[str] = None, **options):
|
|
18
|
+
build_badge(b, ttk_style, accent, 'pill', **options)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def build_badge(b: StyleBuilderTtk, ttk_style: str, accent: Optional[str] = None, variant: str = 'square', **options):
|
|
22
|
+
"""Create a badge style for the variant specified"""
|
|
23
|
+
|
|
24
|
+
surface_token = options.get('surface', 'content')
|
|
25
|
+
surface = b.color(surface_token)
|
|
26
|
+
normal = b.color(accent or 'primary')
|
|
27
|
+
foreground = b.on_color(normal)
|
|
28
|
+
|
|
29
|
+
badge_img = recolor_element_image(f'badge_{variant}', normal, normal, surface, surface)
|
|
30
|
+
|
|
31
|
+
b.create_style_element_image(ElementImage(f'{ttk_style}.border', badge_img.image,
|
|
32
|
+
border=badge_img.meta.border,
|
|
33
|
+
padding=badge_img.meta.padding,
|
|
34
|
+
height=badge_img.meta.height,
|
|
35
|
+
sticky='nsew'))
|
|
36
|
+
|
|
37
|
+
b.create_style_layout(
|
|
38
|
+
ttk_style, Element(f"{ttk_style}.border", sticky="nsew").children(
|
|
39
|
+
[
|
|
40
|
+
Element("Label.padding", sticky="nsew").children(
|
|
41
|
+
[
|
|
42
|
+
Element("Label.label", sticky="ew")
|
|
43
|
+
])
|
|
44
|
+
]))
|
|
45
|
+
|
|
46
|
+
b.configure_style(ttk_style, background=surface, foreground=foreground, padding=(6, 0))
|