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,45 @@
|
|
|
1
|
+
from typing_extensions import Unpack
|
|
2
|
+
from bootstack.widgets._impl.primitives.label import Label, LabelKwargs
|
|
3
|
+
from bootstack.widgets.types import Master
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Badge(Label):
|
|
7
|
+
"""bootstack wrapper for `ttk.Label` that renders with a badge style."""
|
|
8
|
+
|
|
9
|
+
def __init__(self, master: Master = None, **kwargs: Unpack[LabelKwargs]):
|
|
10
|
+
"""Create a themed bootstack Badge.
|
|
11
|
+
|
|
12
|
+
Args:
|
|
13
|
+
master: Parent widget. If None, uses the default root window.
|
|
14
|
+
|
|
15
|
+
Note:
|
|
16
|
+
Badge is text-only by design. The TBadge ttk style layout omits the
|
|
17
|
+
image element, so `image=`, `icon=`, `icon_only=`, and `compound=`
|
|
18
|
+
are silently dropped at render time even though Label accepts them.
|
|
19
|
+
|
|
20
|
+
Other Parameters:
|
|
21
|
+
text: Text to display on the badge.
|
|
22
|
+
anchor: Alignment of the badge content within its area.
|
|
23
|
+
justify: How to justify multiple lines of text.
|
|
24
|
+
localize: Determines the widget's localization mode.
|
|
25
|
+
value_format: Format specification for the badge value.
|
|
26
|
+
padding: Extra space around the badge content.
|
|
27
|
+
width: Width of the badge in characters.
|
|
28
|
+
wraplength: Maximum width before wrapping text.
|
|
29
|
+
font: Font for the badge text.
|
|
30
|
+
foreground: Text color.
|
|
31
|
+
background: Background color.
|
|
32
|
+
relief: Border style.
|
|
33
|
+
state: Widget state.
|
|
34
|
+
takefocus: Whether the widget participates in focus traversal.
|
|
35
|
+
style: Explicit ttk style name (overrides accent/variant).
|
|
36
|
+
accent: Accent token for styling, e.g. 'primary', 'success', 'danger'.
|
|
37
|
+
variant: Shape of badge. 'pill' or 'square' (default).
|
|
38
|
+
surface: Optional surface token; otherwise inherited.
|
|
39
|
+
style_options: Optional dict forwarded to the style builder.
|
|
40
|
+
"""
|
|
41
|
+
kwargs.setdefault('ttk_class', 'TBadge')
|
|
42
|
+
kwargs.setdefault('anchor', 'center')
|
|
43
|
+
kwargs.setdefault('font', '-size 8')
|
|
44
|
+
kwargs.setdefault('variant', 'square')
|
|
45
|
+
super().__init__(master=master, **kwargs)
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from tkinter import ttk
|
|
4
|
+
from typing import Any, Callable, Literal, TYPE_CHECKING
|
|
5
|
+
from typing_extensions import Unpack
|
|
6
|
+
|
|
7
|
+
from bootstack._core.mixins.ttk_state import TtkStateMixin
|
|
8
|
+
from bootstack._core.mixins.widget import WidgetCapabilitiesMixin
|
|
9
|
+
from bootstack.widgets._impl._internal.wrapper_base import TTKWrapperBase
|
|
10
|
+
from bootstack.widgets._impl.mixins import IconMixin, TextSignalMixin, LocalizationMixin
|
|
11
|
+
from bootstack.widgets.types import Master, StyledKwargs, Anchor, CompoundMode, WidgetState, WidgetDensity
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from bootstack.signals import Signal
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class ButtonKwargs(StyledKwargs, total=False):
|
|
18
|
+
# Standard ttk.Button options
|
|
19
|
+
text: Any
|
|
20
|
+
command: Callable[[], Any] | None
|
|
21
|
+
image: Any
|
|
22
|
+
icon: Any
|
|
23
|
+
icon_only: bool
|
|
24
|
+
anchor: Anchor
|
|
25
|
+
compound: CompoundMode
|
|
26
|
+
padding: Any
|
|
27
|
+
width: int
|
|
28
|
+
underline: int
|
|
29
|
+
state: WidgetState
|
|
30
|
+
localize: bool | Literal['auto']
|
|
31
|
+
default: Any
|
|
32
|
+
textvariable: Any
|
|
33
|
+
textsignal: Signal[str]
|
|
34
|
+
|
|
35
|
+
# bootstack-specific extensions
|
|
36
|
+
density: WidgetDensity
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class Button(LocalizationMixin, TextSignalMixin, IconMixin, TTKWrapperBase, WidgetCapabilitiesMixin, TtkStateMixin, ttk.Button):
|
|
40
|
+
"""bootstack wrapper for `ttk.Button` with themed styling and icon support.
|
|
41
|
+
"""
|
|
42
|
+
_ttk_base = ttk.Button
|
|
43
|
+
|
|
44
|
+
def __init__(self, master: Master = None, **kwargs: Unpack[ButtonKwargs]) -> None:
|
|
45
|
+
"""Create a themed bootstack Button.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
master: Parent widget. If None, uses the default root window.
|
|
49
|
+
|
|
50
|
+
Other Parameters:
|
|
51
|
+
text: Text to display on the button.
|
|
52
|
+
textvariable: Tk variable linked to the button text.
|
|
53
|
+
See [tkinter Variables](https://docs.python.org/3/library/tkinter.html#tkinter-variables).
|
|
54
|
+
textsignal: Reactive Signal linked to the button text (auto-synced with textvariable).
|
|
55
|
+
command: Callable invoked when the button is pressed.
|
|
56
|
+
image: Image to display on the button.
|
|
57
|
+
icon: Optional icon spec integrated via the style system.
|
|
58
|
+
icon_only: If true, removes the extra padding reserved for the text labels.
|
|
59
|
+
compound: Placement of the image relative to text (e.g., 'left').
|
|
60
|
+
padding: Extra space around the button content.
|
|
61
|
+
anchor: Determines how the content is aligned in the container. Combination of 'n', 's', 'e', 'w', or 'center' (default).
|
|
62
|
+
localize: Determines the widgets localization mode.
|
|
63
|
+
width: Width of the button in characters.
|
|
64
|
+
underline: Index of the character to underline in `text`.
|
|
65
|
+
state: Widget state — 'normal', 'active', 'disabled', or 'readonly'.
|
|
66
|
+
takefocus: Whether the widget accepts focus during traversal.
|
|
67
|
+
style: Explicit ttk style name to apply (overrides accent/variant).
|
|
68
|
+
accent: Accent token for styling, e.g. 'primary', 'danger', 'success'.
|
|
69
|
+
variant: Style variant, e.g. 'solid', 'outline', 'link', 'text'. Defaults to 'solid'.
|
|
70
|
+
density: Widget density — 'default' or 'compact'.
|
|
71
|
+
surface: Optional surface token to use for this button; if not provided, surface color is inherited from the parent.
|
|
72
|
+
style_options: Optional dict forwarded to the style builder.
|
|
73
|
+
"""
|
|
74
|
+
kwargs.setdefault('variant', 'solid')
|
|
75
|
+
kwargs.update(style_options=self._capture_style_options(['icon_only', 'icon', 'anchor', 'density'], kwargs))
|
|
76
|
+
super().__init__(master, **kwargs)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from typing_extensions import Unpack
|
|
6
|
+
|
|
7
|
+
from bootstack.widgets._impl.primitives.frame import Frame
|
|
8
|
+
from bootstack.widgets.types import Master, StyledKwargs
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class CardKwargs(StyledKwargs, total=False):
|
|
12
|
+
# Standard ttk.Frame options
|
|
13
|
+
padding: Any
|
|
14
|
+
width: int
|
|
15
|
+
height: int
|
|
16
|
+
|
|
17
|
+
# bootstack-specific extensions
|
|
18
|
+
show_border: bool
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Card(Frame):
|
|
22
|
+
"""A frame with card styling"""
|
|
23
|
+
|
|
24
|
+
def __init__(self, master: Master = None, **kwargs: Unpack[CardKwargs]) -> None:
|
|
25
|
+
"""Create a themed Card container.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
master: Parent widget. If None, uses the default root window.
|
|
29
|
+
|
|
30
|
+
Other Parameters:
|
|
31
|
+
padding: Extra padding inside the card. Default 16.
|
|
32
|
+
width: Requested width in pixels.
|
|
33
|
+
height: Requested height in pixels.
|
|
34
|
+
takefocus: Widget accepts focus during keyboard traversal.
|
|
35
|
+
style: Explicit ttk style name (overrides accent/variant).
|
|
36
|
+
accent: Accent/color token for the card. Default 'card'.
|
|
37
|
+
surface: Surface token for the parent background.
|
|
38
|
+
show_border: Draw a border around the card. Default True.
|
|
39
|
+
style_options: Optional dict forwarded to the style builder.
|
|
40
|
+
"""
|
|
41
|
+
kwargs.setdefault('accent', 'card')
|
|
42
|
+
kwargs.setdefault('show_border', True)
|
|
43
|
+
kwargs.setdefault('padding', 16)
|
|
44
|
+
kwargs.setdefault('variant', 'card')
|
|
45
|
+
super().__init__(master, **kwargs)
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from tkinter import ttk
|
|
4
|
+
from typing import Any, Callable, Literal, TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
from typing_extensions import Unpack
|
|
7
|
+
|
|
8
|
+
from bootstack._core.mixins.ttk_state import TtkStateMixin
|
|
9
|
+
from bootstack._core.mixins.widget import WidgetCapabilitiesMixin
|
|
10
|
+
from bootstack.widgets._impl._internal.wrapper_base import TTKWrapperBase
|
|
11
|
+
from bootstack.widgets._impl.mixins import IconMixin, LocalizationMixin, SignalMixin, TextSignalMixin
|
|
12
|
+
from bootstack.widgets._impl.mixins.configure_mixin import configure_delegate
|
|
13
|
+
from bootstack.widgets.types import Master, StyledKwargs, Anchor, CompoundMode, WidgetState
|
|
14
|
+
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from bootstack.signals import Signal
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class CheckButtonKwargs(StyledKwargs, total=False):
|
|
20
|
+
# Standard ttk.Checkbutton options
|
|
21
|
+
text: Any
|
|
22
|
+
command: Callable[[], Any] | None
|
|
23
|
+
image: Any
|
|
24
|
+
icon: Any
|
|
25
|
+
on_icon: Any
|
|
26
|
+
off_icon: Any
|
|
27
|
+
icon_only: bool
|
|
28
|
+
show_indicator: bool
|
|
29
|
+
compound: CompoundMode
|
|
30
|
+
variable: Any
|
|
31
|
+
signal: Signal[Any]
|
|
32
|
+
value: Any
|
|
33
|
+
onvalue: Any
|
|
34
|
+
offvalue: Any
|
|
35
|
+
padding: Any
|
|
36
|
+
anchor: Anchor
|
|
37
|
+
width: int
|
|
38
|
+
underline: int
|
|
39
|
+
state: WidgetState
|
|
40
|
+
textvariable: Any
|
|
41
|
+
textsignal: Signal[str]
|
|
42
|
+
|
|
43
|
+
# bootstack-specific extensions
|
|
44
|
+
localize: bool | Literal['auto']
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class CheckButton(LocalizationMixin, SignalMixin, TextSignalMixin, IconMixin, TTKWrapperBase, WidgetCapabilitiesMixin, TtkStateMixin, ttk.Checkbutton):
|
|
48
|
+
"""bootstack wrapper for `ttk.Checkbutton` with themed styling and icon support."""
|
|
49
|
+
|
|
50
|
+
_ttk_base = ttk.Checkbutton
|
|
51
|
+
|
|
52
|
+
def __init__(self, master: Master = None, **kwargs: Unpack[CheckButtonKwargs]) -> None:
|
|
53
|
+
"""Create a themed bootstack Checkbutton.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
master: Parent widget. If None, uses the default root window.
|
|
57
|
+
|
|
58
|
+
Other Parameters:
|
|
59
|
+
text: Text to display.
|
|
60
|
+
textvariable: Tk variable linked to the text.
|
|
61
|
+
See [tkinter Variables](https://docs.python.org/3/library/tkinter.html#tkinter-variables).
|
|
62
|
+
textsignal: Reactive Signal linked to the text (auto-synced with textvariable).
|
|
63
|
+
command: Callable invoked when the value toggles.
|
|
64
|
+
image: Image to display.
|
|
65
|
+
icon: Icon shown in the label area for all states. Color shifts
|
|
66
|
+
from foreground (unselected) to accent (selected) automatically.
|
|
67
|
+
on_icon: Icon shown in the label area when the button is selected.
|
|
68
|
+
Shortcut for `state=[("selected", name)]` inside a full icon spec.
|
|
69
|
+
off_icon: Icon shown in the label area when the button is unselected.
|
|
70
|
+
Used as the base icon when `on_icon` is also provided.
|
|
71
|
+
icon_only: If True, removes the additional padding reserved for text.
|
|
72
|
+
show_indicator: Whether to show the standard checkbox indicator. Defaults
|
|
73
|
+
to True. Set to False to hide the indicator (e.g. when using icons alone).
|
|
74
|
+
compound: Placement of the image relative to text.
|
|
75
|
+
variable: Linked variable controlling the on/off state.
|
|
76
|
+
See [tkinter Variables](https://docs.python.org/3/library/tkinter.html#tkinter-variables).
|
|
77
|
+
localize: Determines the widget's localization mode.
|
|
78
|
+
signal: Reactive Signal controlling the on/off state (auto-synced with variable).
|
|
79
|
+
value: Initial state for the widget's associated variable (defaults to None when unset).
|
|
80
|
+
onvalue: Value set in `variable` when selected.
|
|
81
|
+
offvalue: Value set in `variable` when deselected.
|
|
82
|
+
padding: Extra space around the content.
|
|
83
|
+
anchor: Determines how the content is aligned in the container. Combination of 'n', 's', 'e', 'w', or 'center' (default).
|
|
84
|
+
width: Width of the control in characters.
|
|
85
|
+
underline: Index of character to underline in `text`.
|
|
86
|
+
state: Widget state.
|
|
87
|
+
takefocus: Whether the widget participates in focus traversal.
|
|
88
|
+
style: Explicit ttk style name (overrides accent/variant).
|
|
89
|
+
accent: Accent token for styling, e.g. 'primary', 'success', 'danger'.
|
|
90
|
+
variant: Style variant, e.g. 'default', 'round', 'square'.
|
|
91
|
+
surface: Optional surface token; otherwise inherited.
|
|
92
|
+
style_options: Optional dict forwarded to the style builder.
|
|
93
|
+
"""
|
|
94
|
+
signal_provided = 'signal' in kwargs
|
|
95
|
+
variable_provided = 'variable' in kwargs
|
|
96
|
+
initial_value = kwargs.pop('value', None)
|
|
97
|
+
kwargs.update(style_options=self._capture_style_options(['icon_only', 'icon', 'on_icon', 'off_icon', 'show_indicator', 'anchor'], kwargs))
|
|
98
|
+
super().__init__(master, **kwargs)
|
|
99
|
+
if initial_value is not None and not signal_provided and not variable_provided:
|
|
100
|
+
self.variable.set(initial_value)
|
|
101
|
+
|
|
102
|
+
def get(self) -> Any:
|
|
103
|
+
"""Return the current value of the checkbutton."""
|
|
104
|
+
return self.variable.get()
|
|
105
|
+
|
|
106
|
+
def set(self, value: Any) -> None:
|
|
107
|
+
"""Set the value of the checkbutton."""
|
|
108
|
+
self.variable.set(value)
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def value(self) -> Any:
|
|
112
|
+
"""Get or set the checkbutton's value."""
|
|
113
|
+
return self.get()
|
|
114
|
+
|
|
115
|
+
@value.setter
|
|
116
|
+
def value(self, value: Any) -> None:
|
|
117
|
+
self.set(value)
|
|
118
|
+
|
|
119
|
+
@configure_delegate('value')
|
|
120
|
+
def _delegate_value(self, value=None):
|
|
121
|
+
"""Get or set the value via configure."""
|
|
122
|
+
if value is None:
|
|
123
|
+
return self.get()
|
|
124
|
+
self.set(value)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from typing import Literal
|
|
2
|
+
|
|
3
|
+
from typing_extensions import Unpack
|
|
4
|
+
|
|
5
|
+
from bootstack.widgets._impl.primitives.checkbutton import CheckButton, CheckButtonKwargs
|
|
6
|
+
from bootstack.widgets.types import Master
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class CheckToggle(CheckButton):
|
|
10
|
+
"""bootstack wrapper for `ttk.Checkbutton` that renders with a ToolButton style"""
|
|
11
|
+
|
|
12
|
+
def __init__(self, master: Master = None, **kwargs: Unpack[CheckButtonKwargs]) -> None:
|
|
13
|
+
"""Create a themed bootstack CheckToggle.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
master: Parent widget. If None, uses the default root window.
|
|
17
|
+
|
|
18
|
+
Other Parameters:
|
|
19
|
+
text: Text to display on the toggle.
|
|
20
|
+
textvariable: Tk variable linked to the text.
|
|
21
|
+
See [tkinter Variables](https://docs.python.org/3/library/tkinter.html#tkinter-variables).
|
|
22
|
+
textsignal: Reactive Signal linked to the text (auto-synced with textvariable).
|
|
23
|
+
command: Callable invoked when the toggle changes state.
|
|
24
|
+
image: Image to display.
|
|
25
|
+
icon: Icon shown in the label area for all states. Color shifts
|
|
26
|
+
with the button's pressed/selected state automatically.
|
|
27
|
+
on_icon: Icon shown when the toggle is selected (on). Shortcut
|
|
28
|
+
for `state=[("selected", name)]` inside a full icon spec.
|
|
29
|
+
off_icon: Icon shown when the toggle is unselected (off). Used
|
|
30
|
+
as the base icon when `on_icon` is also provided.
|
|
31
|
+
icon_only: If True, removes the additional padding reserved for text.
|
|
32
|
+
compound: Placement of the image relative to text.
|
|
33
|
+
variable: Linked variable controlling the on/off state.
|
|
34
|
+
See [tkinter Variables](https://docs.python.org/3/library/tkinter.html#tkinter-variables).
|
|
35
|
+
signal: Reactive Signal controlling the on/off state (auto-synced with variable).
|
|
36
|
+
value: Initial state for the widget's associated variable (defaults to None when unset).
|
|
37
|
+
onvalue: Value set in `variable` when selected.
|
|
38
|
+
offvalue: Value set in `variable` when deselected.
|
|
39
|
+
padding: Extra space around the content.
|
|
40
|
+
anchor: Determines how the content is aligned in the container. Combination of 'n', 's', 'e', 'w', or 'center' (default).
|
|
41
|
+
density: The vertical and horizontal compactness of widget content, e.g. 'default', 'compact'.
|
|
42
|
+
width: Width of the control in characters.
|
|
43
|
+
underline: Index of character to underline in `text`.
|
|
44
|
+
state: Widget state ('normal', 'active', 'disabled', 'readonly').
|
|
45
|
+
takefocus: Whether the widget participates in focus traversal.
|
|
46
|
+
accent: Accent token for styling, e.g. 'primary', 'success', 'danger'.
|
|
47
|
+
variant: Style variant (coerced to 'toolbutton').
|
|
48
|
+
surface: Optional surface token; otherwise inherited.
|
|
49
|
+
style_options: Optional dict forwarded to the style builder.
|
|
50
|
+
localize: Determines the widget's localization mode.
|
|
51
|
+
"""
|
|
52
|
+
self._capture_density_option(kwargs)
|
|
53
|
+
kwargs.setdefault('class_', 'Toolbutton')
|
|
54
|
+
super().__init__(master, **kwargs)
|
|
55
|
+
|
|
56
|
+
@staticmethod
|
|
57
|
+
def _capture_density_option(kwargs: dict) -> None:
|
|
58
|
+
"""Capture density from kwargs into style_options."""
|
|
59
|
+
density: Literal['default', 'compact'] | None = kwargs.pop('density', None)
|
|
60
|
+
if density is not None:
|
|
61
|
+
style_options = kwargs.setdefault('style_options', {})
|
|
62
|
+
style_options['density'] = density
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from tkinter import ttk
|
|
4
|
+
from typing import Any, TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
from typing_extensions import Unpack
|
|
7
|
+
|
|
8
|
+
from bootstack._core.mixins.ttk_state import TtkStateMixin
|
|
9
|
+
from bootstack._core.mixins.widget import WidgetCapabilitiesMixin
|
|
10
|
+
from bootstack.widgets._impl._internal.wrapper_base import TTKWrapperBase
|
|
11
|
+
from bootstack.widgets.types import Master, StyledKwargs, Justify, WidgetState, WidgetDensity
|
|
12
|
+
from ..mixins import TextSignalMixin, configure_delegate
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from bootstack.signals import Signal
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ComboboxKwargs(StyledKwargs, total=False):
|
|
19
|
+
# Standard ttk.Combobox options
|
|
20
|
+
values: Any
|
|
21
|
+
textvariable: Any
|
|
22
|
+
textsignal: Signal[Any]
|
|
23
|
+
state: WidgetState
|
|
24
|
+
width: int
|
|
25
|
+
height: int
|
|
26
|
+
postcommand: Any
|
|
27
|
+
justify: Justify
|
|
28
|
+
exportselection: bool
|
|
29
|
+
xscrollcommand: Any
|
|
30
|
+
font: Any
|
|
31
|
+
foreground: str
|
|
32
|
+
background: str
|
|
33
|
+
|
|
34
|
+
# bootstack-specific extensions
|
|
35
|
+
density: WidgetDensity
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class Combobox(TextSignalMixin, TTKWrapperBase, WidgetCapabilitiesMixin, TtkStateMixin, ttk.Combobox):
|
|
39
|
+
"""bootstack wrapper for `ttk.Combobox` with themed styling support."""
|
|
40
|
+
|
|
41
|
+
_ttk_base = ttk.Combobox
|
|
42
|
+
|
|
43
|
+
def __init__(self, master: Master = None, **kwargs: Unpack[ComboboxKwargs]) -> None:
|
|
44
|
+
"""Create a themed bootstack Combobox.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
master: Parent widget. If None, uses the default root window.
|
|
48
|
+
|
|
49
|
+
Other Parameters:
|
|
50
|
+
values: Sequence of values to display.
|
|
51
|
+
textvariable: Tk variable linked to the selected value.
|
|
52
|
+
See [tkinter Variables](https://docs.python.org/3/library/tkinter.html#tkinter-variables).
|
|
53
|
+
textsignal: Reactive Signal linked to the text (auto-synced with textvariable).
|
|
54
|
+
state: Widget state; 'readonly' restricts to list items.
|
|
55
|
+
width: Width in characters.
|
|
56
|
+
height: Maximum rows shown in the drop-down list.
|
|
57
|
+
postcommand: Callback executed before showing the drop-down.
|
|
58
|
+
justify: Text justification within the entry field.
|
|
59
|
+
exportselection: Whether selection is exported to X clipboard.
|
|
60
|
+
xscrollcommand: Scroll callback for horizontal scrolling.
|
|
61
|
+
font: Font for the entry field.
|
|
62
|
+
foreground: Text color.
|
|
63
|
+
background: Background color for the entry field.
|
|
64
|
+
style: Explicit ttk style name (overrides accent/variant).
|
|
65
|
+
accent: Accent token for styling, e.g. 'primary', 'danger', 'success'.
|
|
66
|
+
density: Vertical and horizontal compactness, e.g. 'default', 'compact'.
|
|
67
|
+
surface: Optional surface token; otherwise inherited.
|
|
68
|
+
style_options: Optional dict forwarded to the style builder.
|
|
69
|
+
"""
|
|
70
|
+
# Store density for popdown positioning
|
|
71
|
+
if kwargs.get('density') == 'compact':
|
|
72
|
+
kwargs['font'] = 'caption'
|
|
73
|
+
kwargs.update(style_options=self._capture_style_options(['density'], kwargs))
|
|
74
|
+
super().__init__(master, **kwargs)
|
|
75
|
+
|
|
76
|
+
# Store original postcommand if provided
|
|
77
|
+
self._original_postcommand = kwargs.get('postcommand')
|
|
78
|
+
|
|
79
|
+
# Set up popdown styling. A theme change re-styles an already-open
|
|
80
|
+
# popdown through the unified theme walk (`_bs_apply_theme`).
|
|
81
|
+
self._setup_postcommand()
|
|
82
|
+
|
|
83
|
+
@configure_delegate('density')
|
|
84
|
+
def _delegate_density(self, value=None):
|
|
85
|
+
if value is None:
|
|
86
|
+
return self.configure_style_options(value)
|
|
87
|
+
else:
|
|
88
|
+
if value == 'compact':
|
|
89
|
+
self.configure(font='caption')
|
|
90
|
+
else:
|
|
91
|
+
self.configure(font='body')
|
|
92
|
+
return self.configure_style_options(density=value)
|
|
93
|
+
|
|
94
|
+
def _setup_postcommand(self) -> None:
|
|
95
|
+
"""Re-style the popdown each time it opens.
|
|
96
|
+
|
|
97
|
+
The popdown is created lazily on first open and reused. Re-styling on
|
|
98
|
+
every open ensures it picks up the current theme's colors, since the
|
|
99
|
+
embedded Tk listbox/scrollbar aren't rebuilt by the ttk style engine.
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
def on_popdown():
|
|
103
|
+
self._apply_popdown_style(create_if_missing=True)
|
|
104
|
+
|
|
105
|
+
if self._original_postcommand:
|
|
106
|
+
if callable(self._original_postcommand):
|
|
107
|
+
self._original_postcommand()
|
|
108
|
+
else:
|
|
109
|
+
self.tk.eval(str(self._original_postcommand))
|
|
110
|
+
|
|
111
|
+
self.configure(postcommand=on_popdown)
|
|
112
|
+
|
|
113
|
+
def _apply_popdown_style(self, create_if_missing: bool = False, **kwargs) -> None:
|
|
114
|
+
"""Apply theme colors and density font to the embedded popdown.
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
create_if_missing: If True, force-create the popdown so we can
|
|
118
|
+
style it before it's mapped (used from the postcommand). If
|
|
119
|
+
False, no-op when the popdown doesn't exist yet (used from
|
|
120
|
+
the theme-change subscriber).
|
|
121
|
+
"""
|
|
122
|
+
popdown_path = f"{self}.popdown"
|
|
123
|
+
try:
|
|
124
|
+
popdown_exists = bool(int(self.tk.eval(f"winfo exists {popdown_path}")))
|
|
125
|
+
except Exception:
|
|
126
|
+
return
|
|
127
|
+
|
|
128
|
+
if not popdown_exists:
|
|
129
|
+
if not create_if_missing:
|
|
130
|
+
return
|
|
131
|
+
try:
|
|
132
|
+
self.tk.eval(f"ttk::combobox::PopdownWindow {self}")
|
|
133
|
+
except Exception:
|
|
134
|
+
return
|
|
135
|
+
|
|
136
|
+
try:
|
|
137
|
+
from bootstack.style.style_builder_mixed import StyleBuilderMixed
|
|
138
|
+
StyleBuilderMixed().update_combobox_popdown_style(self)
|
|
139
|
+
except Exception:
|
|
140
|
+
pass
|
|
141
|
+
|
|
142
|
+
try:
|
|
143
|
+
density = self.configure_style_options('density') or 'default'
|
|
144
|
+
from bootstack.style.typography import get_font
|
|
145
|
+
font_token = 'caption' if density == 'compact' else 'body'
|
|
146
|
+
self.tk.call(f"{popdown_path}.f.l", "configure", "-font", str(get_font(font_token)))
|
|
147
|
+
except Exception:
|
|
148
|
+
pass
|
|
149
|
+
|
|
150
|
+
def _bs_apply_theme(self) -> None:
|
|
151
|
+
"""Unified theme-walk hook — re-style an already-open popdown.
|
|
152
|
+
|
|
153
|
+
The ttk style engine handles the entry itself; this re-colors the
|
|
154
|
+
embedded Tk listbox/scrollbar of the popdown if one has been created.
|
|
155
|
+
"""
|
|
156
|
+
self._apply_popdown_style()
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from tkinter import ttk
|
|
4
|
+
from typing import Any, TYPE_CHECKING
|
|
5
|
+
from typing_extensions import Unpack
|
|
6
|
+
|
|
7
|
+
from bootstack._core.mixins.ttk_state import TtkStateMixin
|
|
8
|
+
from bootstack._core.mixins.widget import WidgetCapabilitiesMixin
|
|
9
|
+
from bootstack.widgets._impl._internal.wrapper_base import TTKWrapperBase
|
|
10
|
+
from bootstack.widgets.types import Master, StyledKwargs, Justify, WidgetState, WidgetDensity
|
|
11
|
+
from ..mixins import TextSignalMixin, configure_delegate
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from bootstack.signals import Signal
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class EntryKwargs(StyledKwargs, total=False):
|
|
18
|
+
# Standard ttk.Entry options
|
|
19
|
+
textvariable: Any
|
|
20
|
+
textsignal: Signal[str]
|
|
21
|
+
show: Any
|
|
22
|
+
width: int
|
|
23
|
+
exportselection: bool
|
|
24
|
+
justify: Justify
|
|
25
|
+
validate: Any
|
|
26
|
+
validatecommand: Any
|
|
27
|
+
invalidcommand: Any
|
|
28
|
+
xscrollcommand: Any
|
|
29
|
+
font: Any
|
|
30
|
+
foreground: str
|
|
31
|
+
background: str
|
|
32
|
+
state: WidgetState
|
|
33
|
+
|
|
34
|
+
# bootstack-specific extensions
|
|
35
|
+
density: WidgetDensity
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class Entry(TextSignalMixin, TTKWrapperBase, WidgetCapabilitiesMixin, TtkStateMixin, ttk.Entry):
|
|
39
|
+
"""bootstack wrapper for `ttk.Entry` with themed styling support."""
|
|
40
|
+
|
|
41
|
+
_ttk_base = ttk.Entry
|
|
42
|
+
|
|
43
|
+
def __init__(self, master: Master = None, **kwargs: Unpack[EntryKwargs]) -> None:
|
|
44
|
+
"""Create a themed bootstack Entry.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
master: Parent widget. If None, uses the default root window.
|
|
48
|
+
|
|
49
|
+
Other Parameters:
|
|
50
|
+
textvariable: Tk variable linked to the entry text.
|
|
51
|
+
See [tkinter Variables](https://docs.python.org/3/library/tkinter.html#tkinter-variables).
|
|
52
|
+
textsignal: Reactive Signal linked to the entry text (auto-synced with textvariable).
|
|
53
|
+
show: Substitute character for masked input.
|
|
54
|
+
width: Width in characters.
|
|
55
|
+
exportselection: Whether selection is exported to X clipboard.
|
|
56
|
+
justify: Text alignment inside the entry.
|
|
57
|
+
validate: Validation mode.
|
|
58
|
+
validatecommand: Validation callback.
|
|
59
|
+
invalidcommand: Callback executed on validation failure.
|
|
60
|
+
xscrollcommand: Horizontal scroll callback.
|
|
61
|
+
font: Font for the entry text.
|
|
62
|
+
foreground: Text color.
|
|
63
|
+
background: Background color.
|
|
64
|
+
state: Widget state.
|
|
65
|
+
takefocus: Whether the widget participates in focus traversal.
|
|
66
|
+
style: Explicit ttk style name (overrides accent/variant).
|
|
67
|
+
accent: Accent token for styling, e.g. 'primary', 'danger', 'success'.
|
|
68
|
+
variant: Style variant, e.g. 'default'.
|
|
69
|
+
density: Vertical and horizontal compactness, e.g. 'default', 'compact'.
|
|
70
|
+
surface: Optional surface token; otherwise inherited.
|
|
71
|
+
style_options: Optional dict forwarded to the style builder.
|
|
72
|
+
"""
|
|
73
|
+
if kwargs.get('density') == 'compact':
|
|
74
|
+
kwargs['font'] = 'caption'
|
|
75
|
+
kwargs.update(style_options=self._capture_style_options(['density'], kwargs))
|
|
76
|
+
super().__init__(master, **kwargs)
|
|
77
|
+
|
|
78
|
+
@configure_delegate('density')
|
|
79
|
+
def _delegate_density(self, value=None):
|
|
80
|
+
if value is None:
|
|
81
|
+
return self.configure_style_options(value)
|
|
82
|
+
else:
|
|
83
|
+
if value == 'compact':
|
|
84
|
+
self.configure(font='caption')
|
|
85
|
+
else:
|
|
86
|
+
self.configure(font='body')
|
|
87
|
+
return self.configure_style_options(density=value)
|