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,121 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from bootstack.widgets._impl.primitives.gridframe import GridFrame
|
|
6
|
+
from bootstack.widgets._core.container import (
|
|
7
|
+
PublicContainer, GRID_KEYS, grid_sticky, _reject_legacy_child_kwargs,
|
|
8
|
+
)
|
|
9
|
+
from bootstack.widgets.types import (
|
|
10
|
+
AccentToken, SurfaceToken, HAlign, VAlign, Padding, AutoFlow,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Grid(PublicContainer):
|
|
15
|
+
"""A container that arranges children in rows and columns.
|
|
16
|
+
|
|
17
|
+
Children are auto-placed left-to-right, top-to-bottom by default. Column and
|
|
18
|
+
row sizes are set with weighted `columns=` / `rows=`; in-cell alignment is
|
|
19
|
+
controlled with `horizontal_items` and `vertical_items`, overridable per
|
|
20
|
+
child with `horizontal` / `vertical`.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
columns: Column definitions. An integer creates that many
|
|
24
|
+
equal-weight columns. A list sets per-column weights or
|
|
25
|
+
sizes — integers are relative weights, `'auto'` sizes to
|
|
26
|
+
content, `'Npx'` sets a fixed pixel width (e.g. `'120px'`).
|
|
27
|
+
Defaults to `None` (single column, sized to content).
|
|
28
|
+
rows: Row definitions, same format as `columns`. Defaults to
|
|
29
|
+
`None` (rows added automatically as children are placed).
|
|
30
|
+
gap: Space in pixels between cells. An integer applies to both
|
|
31
|
+
axes; a 2-tuple `(col_gap, row_gap)` sets them
|
|
32
|
+
independently. Defaults to `0`.
|
|
33
|
+
horizontal_items: Horizontal in-cell alignment of every child —
|
|
34
|
+
`'stretch'` (fill the cell width), `'left'`, `'center'`, or
|
|
35
|
+
`'right'`. Override per child with `horizontal`. Defaults to
|
|
36
|
+
`'stretch'`.
|
|
37
|
+
vertical_items: Vertical in-cell alignment of every child —
|
|
38
|
+
`'stretch'` (fill the cell height), `'top'`, `'center'`, or
|
|
39
|
+
`'bottom'`. Override per child with `vertical`. Defaults to
|
|
40
|
+
`'stretch'`.
|
|
41
|
+
auto_flow: Auto-placement direction. Defaults to `'row'`.
|
|
42
|
+
padding: Space in pixels between the grid border and its
|
|
43
|
+
content. Defaults to `None` (no padding).
|
|
44
|
+
surface: Background token. Accepts a surface token, an accent
|
|
45
|
+
token, or any token with modifiers (e.g. `'primary[subtle]'`).
|
|
46
|
+
Defaults to `None` (inherits from parent surface).
|
|
47
|
+
show_border: When `True`, draws a 1 px border around the
|
|
48
|
+
grid. Use at least `padding=1` to give the border visual
|
|
49
|
+
clearance. Defaults to `False`.
|
|
50
|
+
width: Fixed width in pixels. Disables frame propagation —
|
|
51
|
+
see the note in :class:`Row` for sizing behavior.
|
|
52
|
+
Defaults to `None`.
|
|
53
|
+
height: Fixed height in pixels. Disables frame propagation —
|
|
54
|
+
see the note in :class:`Column` for sizing behavior.
|
|
55
|
+
Defaults to `None`.
|
|
56
|
+
parent: Override the context-stack parent widget.
|
|
57
|
+
**kwargs: Per-child placement options — `row`, `column`,
|
|
58
|
+
`rowspan`, `columnspan`, `horizontal`, `vertical`,
|
|
59
|
+
`margin`. See :doc:`/tasks/layout`.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
def __init__(
|
|
63
|
+
self,
|
|
64
|
+
*,
|
|
65
|
+
parent: Any = None,
|
|
66
|
+
columns: int | list[int | str] | None = None,
|
|
67
|
+
rows: int | list[int | str] | None = None,
|
|
68
|
+
gap: int | tuple[int, int] = 0,
|
|
69
|
+
horizontal_items: HAlign = "stretch",
|
|
70
|
+
vertical_items: VAlign = "stretch",
|
|
71
|
+
auto_flow: AutoFlow = "row",
|
|
72
|
+
padding: Padding | None = None,
|
|
73
|
+
surface: SurfaceToken | AccentToken | str | None = None,
|
|
74
|
+
show_border: bool = False,
|
|
75
|
+
width: int | None = None,
|
|
76
|
+
height: int | None = None,
|
|
77
|
+
**kwargs: Any,
|
|
78
|
+
) -> None:
|
|
79
|
+
self._parent = self._resolve_parent(parent)
|
|
80
|
+
layout_kw = self._split_layout_kwargs(kwargs)
|
|
81
|
+
|
|
82
|
+
frame_kwargs: dict[str, Any] = {
|
|
83
|
+
"rows": rows,
|
|
84
|
+
"columns": columns,
|
|
85
|
+
"gap": gap,
|
|
86
|
+
"auto_flow": auto_flow,
|
|
87
|
+
}
|
|
88
|
+
for k, v in {
|
|
89
|
+
"padding": padding,
|
|
90
|
+
"surface": surface,
|
|
91
|
+
}.items():
|
|
92
|
+
if v is not None:
|
|
93
|
+
frame_kwargs[k] = v
|
|
94
|
+
if show_border:
|
|
95
|
+
frame_kwargs["show_border"] = True
|
|
96
|
+
if width is not None:
|
|
97
|
+
frame_kwargs["width"] = width
|
|
98
|
+
if height is not None:
|
|
99
|
+
frame_kwargs["height"] = height
|
|
100
|
+
if width is not None or height is not None:
|
|
101
|
+
frame_kwargs["propagate"] = False
|
|
102
|
+
|
|
103
|
+
self._horizontal_items = horizontal_items
|
|
104
|
+
self._vertical_items = vertical_items
|
|
105
|
+
|
|
106
|
+
tk_master = self._parent._child_master() if self._parent else None
|
|
107
|
+
self._internal = GridFrame(tk_master, **frame_kwargs)
|
|
108
|
+
self._attach_to_parent(layout_kw)
|
|
109
|
+
|
|
110
|
+
def _default_layout_method(self) -> str:
|
|
111
|
+
return "grid"
|
|
112
|
+
|
|
113
|
+
def _merge_layout_options(self, child: Any, layout_kw: dict) -> tuple[str, dict]:
|
|
114
|
+
_reject_legacy_child_kwargs(layout_kw, "Grid")
|
|
115
|
+
options = {k: v for k, v in layout_kw.items() if k in GRID_KEYS}
|
|
116
|
+
# Derive the cell sticky from per-child horizontal/vertical, each falling
|
|
117
|
+
# back to the container default for its axis.
|
|
118
|
+
h = layout_kw.get("horizontal") or self._horizontal_items
|
|
119
|
+
v = layout_kw.get("vertical") or self._vertical_items
|
|
120
|
+
options["sticky"] = grid_sticky(h, v)
|
|
121
|
+
return ("grid", options)
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import tkinter
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from bootstack.widgets._impl.primitives.labelframe import LabelFrame as _LabelFrame
|
|
7
|
+
from bootstack.widgets._impl.primitives.flexframe import FlexFrame
|
|
8
|
+
from bootstack.widgets._impl.primitives.gridframe import GridFrame
|
|
9
|
+
from bootstack.widgets._core.container import (
|
|
10
|
+
PublicContainer, GRID_KEYS, place_flex_child, grid_sticky,
|
|
11
|
+
_reject_legacy_child_kwargs,
|
|
12
|
+
)
|
|
13
|
+
from bootstack.widgets.types import (
|
|
14
|
+
AccentToken, Padding, LayoutKind, AutoFlow, LocalizeMode,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class GroupBox(PublicContainer):
|
|
19
|
+
"""A labeled container that groups related content inside a bordered frame.
|
|
20
|
+
|
|
21
|
+
The title is embedded in the top border line, giving the classic fieldset
|
|
22
|
+
look. Children are laid out according to `layout`.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
title: Text label embedded in the top border line. Defaults to an
|
|
26
|
+
empty string (border only, no label).
|
|
27
|
+
layout: Internal layout manager. Defaults to `'column'`.
|
|
28
|
+
padding: Space in pixels between the border and the content. A single
|
|
29
|
+
value applies to all sides; `(x, y)` sets the horizontal and
|
|
30
|
+
vertical amounts. Defaults to `16`.
|
|
31
|
+
accent: Color intent token applied to the border and title label.
|
|
32
|
+
When omitted, the border uses the theme's default foreground color.
|
|
33
|
+
gap: Space in pixels between child widgets. Defaults to `0`.
|
|
34
|
+
horizontal_items: How children sit on the horizontal axis — edge values
|
|
35
|
+
`'left'`/`'center'`/`'right'`/`'stretch'`, plus the `'space-*'` modes
|
|
36
|
+
when horizontal is the stacking axis (`'row'`). Override per child
|
|
37
|
+
with `horizontal`. Defaults to `'stretch'` in grid mode, `'center'` in a column
|
|
38
|
+
and `'left'` in a row.
|
|
39
|
+
vertical_items: How children sit on the vertical axis — edge values
|
|
40
|
+
`'top'`/`'center'`/`'bottom'`/`'stretch'`, plus the `'space-*'` modes
|
|
41
|
+
when vertical is the stacking axis (`'column'`). Override per child
|
|
42
|
+
with `vertical`. Defaults to `'stretch'` in grid mode, `'center'` in a row and `'top'` in a column.
|
|
43
|
+
grow_items: For `'column'`/`'row'` layout, when `True` every child
|
|
44
|
+
grows equally to share the main axis. Defaults to `False`.
|
|
45
|
+
columns: Column definitions for `'grid'` layout. An integer sets
|
|
46
|
+
the number of equal-weight columns; a list sets per-column
|
|
47
|
+
weights or sizes — integers are relative weights, `'auto'`
|
|
48
|
+
sizes to content, `'Npx'` sets a fixed pixel width (e.g.
|
|
49
|
+
`[1, 2, 'auto', '120px']`).
|
|
50
|
+
rows: Row definitions for `'grid'` layout, same format as `columns`.
|
|
51
|
+
auto_flow: Grid auto-placement direction. Defaults to `'row'`.
|
|
52
|
+
localize: Whether the title is translated through the catalog — `True`,
|
|
53
|
+
`False`, or `'auto'`. Defaults to the app's `localize_mode`.
|
|
54
|
+
parent: Override the context-stack parent widget.
|
|
55
|
+
**kwargs: Layout placement options applied by the parent container —
|
|
56
|
+
`fill`, `expand`, `anchor`, `margin`, `row`, `column`, `sticky`.
|
|
57
|
+
See :doc:`/tasks/layout`.
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
def __init__(
|
|
61
|
+
self,
|
|
62
|
+
title: str = "",
|
|
63
|
+
*,
|
|
64
|
+
layout: LayoutKind = "column",
|
|
65
|
+
padding: Padding | None = 16,
|
|
66
|
+
accent: AccentToken | str | None = None,
|
|
67
|
+
gap: int = 0,
|
|
68
|
+
horizontal_items: str | None = None,
|
|
69
|
+
vertical_items: str | None = None,
|
|
70
|
+
grow_items: bool = False,
|
|
71
|
+
columns: int | list[int | str] | None = None,
|
|
72
|
+
rows: int | list[int | str] | None = None,
|
|
73
|
+
auto_flow: AutoFlow = "row",
|
|
74
|
+
localize: LocalizeMode | None = None,
|
|
75
|
+
parent: Any = None,
|
|
76
|
+
**kwargs: Any,
|
|
77
|
+
) -> None:
|
|
78
|
+
self._parent = self._resolve_parent(parent)
|
|
79
|
+
self._layout = layout
|
|
80
|
+
layout_kw = self._split_layout_kwargs(kwargs)
|
|
81
|
+
|
|
82
|
+
# One horizontal_items/vertical_items pair serves both modes; the sensible
|
|
83
|
+
# default differs — grid cells fill (stretch), stacked children sit at the
|
|
84
|
+
# leading edge (left/top).
|
|
85
|
+
if horizontal_items is None:
|
|
86
|
+
horizontal_items = (
|
|
87
|
+
"stretch" if layout == "grid"
|
|
88
|
+
else "center" if layout == "column" else "left"
|
|
89
|
+
)
|
|
90
|
+
if vertical_items is None:
|
|
91
|
+
vertical_items = (
|
|
92
|
+
"stretch" if layout == "grid"
|
|
93
|
+
else "center" if layout == "row" else "top"
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
tk_master = self._parent._child_master() if self._parent else None
|
|
97
|
+
|
|
98
|
+
lf_kwargs: dict[str, Any] = {"text": title, "padding": padding}
|
|
99
|
+
if accent is not None:
|
|
100
|
+
lf_kwargs["accent"] = accent
|
|
101
|
+
if localize is not None:
|
|
102
|
+
lf_kwargs["localize"] = localize
|
|
103
|
+
|
|
104
|
+
self._internal = _LabelFrame(tk_master, **lf_kwargs)
|
|
105
|
+
|
|
106
|
+
if layout in ("column", "row"):
|
|
107
|
+
self._layout_frame = FlexFrame(
|
|
108
|
+
self._internal,
|
|
109
|
+
direction="vertical" if layout == "column" else "horizontal",
|
|
110
|
+
gap=gap,
|
|
111
|
+
horizontal_items=horizontal_items,
|
|
112
|
+
vertical_items=vertical_items,
|
|
113
|
+
grow_items=grow_items,
|
|
114
|
+
)
|
|
115
|
+
elif layout == "grid":
|
|
116
|
+
self._layout_frame = GridFrame(
|
|
117
|
+
self._internal,
|
|
118
|
+
columns=columns,
|
|
119
|
+
rows=rows,
|
|
120
|
+
gap=gap,
|
|
121
|
+
auto_flow=auto_flow,
|
|
122
|
+
)
|
|
123
|
+
else:
|
|
124
|
+
raise ValueError(
|
|
125
|
+
f"GroupBox layout must be 'column', 'row', or 'grid', got {layout!r}"
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
self._horizontal_items = horizontal_items
|
|
129
|
+
self._vertical_items = vertical_items
|
|
130
|
+
self._layout_frame.pack(fill="both", expand=True)
|
|
131
|
+
self._attach_to_parent(layout_kw)
|
|
132
|
+
|
|
133
|
+
def _child_master(self) -> tkinter.Misc:
|
|
134
|
+
return self._layout_frame
|
|
135
|
+
|
|
136
|
+
def _default_layout_method(self) -> str:
|
|
137
|
+
return "grid" if self._layout == "grid" else "flex"
|
|
138
|
+
|
|
139
|
+
def guide_layout(self, child: Any, **layout_kw: Any) -> None:
|
|
140
|
+
if self._layout == "grid":
|
|
141
|
+
return super().guide_layout(child, **layout_kw)
|
|
142
|
+
place_flex_child(self._layout_frame, child, layout_kw, "GroupBox")
|
|
143
|
+
|
|
144
|
+
def _merge_layout_options(self, child: Any, layout_kw: dict) -> tuple[str, dict]:
|
|
145
|
+
# Only reached for grid layout (column/row use the flex path above).
|
|
146
|
+
_reject_legacy_child_kwargs(layout_kw, "GroupBox")
|
|
147
|
+
options = {k: v for k, v in layout_kw.items() if k in GRID_KEYS}
|
|
148
|
+
h = layout_kw.get("horizontal") or self._horizontal_items
|
|
149
|
+
v = layout_kw.get("vertical") or self._vertical_items
|
|
150
|
+
options["sticky"] = grid_sticky(h, v)
|
|
151
|
+
return ("grid", options)
|
|
152
|
+
|
|
153
|
+
# ----- Properties -----
|
|
154
|
+
|
|
155
|
+
@property
|
|
156
|
+
def title(self) -> str:
|
|
157
|
+
"""The text embedded in the border."""
|
|
158
|
+
return self._internal.cget("text")
|
|
159
|
+
|
|
160
|
+
@title.setter
|
|
161
|
+
def title(self, value: str) -> None:
|
|
162
|
+
self._internal.configure(text=value)
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import overload, Any, Callable, Literal, TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from bootstack.widgets._impl.primitives.label import Label as _InternalLabel
|
|
6
|
+
from bootstack.widgets._impl.primitives.badge import Badge as _InternalBadge
|
|
7
|
+
from bootstack.widgets._core.base import PublicWidgetBase
|
|
8
|
+
from bootstack.widgets._core.events import register_widget_events
|
|
9
|
+
from bootstack.widgets._core.icon_image_props import IconProperty, ImageProperty
|
|
10
|
+
from bootstack.events import Event, Subscription
|
|
11
|
+
from bootstack.streams import Stream
|
|
12
|
+
from bootstack.widgets.types import (
|
|
13
|
+
AccentToken, SurfaceToken,
|
|
14
|
+
Anchor, Justify, Relief, CompoundMode, Padding, IconPosition, IconSpec,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from bootstack.signals import Signal
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Label(IconProperty, ImageProperty, PublicWidgetBase):
|
|
22
|
+
"""Static text display with optional icon, semantic styling, and font tokens.
|
|
23
|
+
|
|
24
|
+
The display text is the first positional argument. All options are
|
|
25
|
+
keyword-only.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
text: Text to display.
|
|
29
|
+
textsignal: Reactive `Signal` bound to the display text. Updates
|
|
30
|
+
automatically when the signal changes. Combine with
|
|
31
|
+
`value_format=` to format numeric or date values.
|
|
32
|
+
value_format: Format applied to the `textsignal` value before display —
|
|
33
|
+
a named preset (e.g. `'decimal'`, `'currency'`, `'shortDate'`) or a
|
|
34
|
+
custom pattern (e.g. `'#,##0'`). Requires `textsignal=` and
|
|
35
|
+
localization enabled. See :ref:`format specs <value-formats>`.
|
|
36
|
+
image: An `Image` handle (from `bootstack.images`) to display, for custom
|
|
37
|
+
artwork rather than a Bootstrap Icon name. Also accepts a `get_icon`
|
|
38
|
+
result. Use `icon_position=` to control placement relative to text.
|
|
39
|
+
icon: Bootstrap Icons name (e.g. `'house'`, `'gear'`) — see the full
|
|
40
|
+
catalog at https://icons.getbootstrap.com — or an `IconSpec` mapping
|
|
41
|
+
(`{'name', 'size', 'color'}`) for control over size and color.
|
|
42
|
+
icon_only: If `True`, show only the icon. Auto-detected when
|
|
43
|
+
`text` is empty and `icon` is provided.
|
|
44
|
+
icon_position: Position of the icon or image relative to the text.
|
|
45
|
+
Only relevant when an icon or image is shown alongside text.
|
|
46
|
+
Default `'left'`.
|
|
47
|
+
anchor: Content alignment within the label area. Default `'center'`.
|
|
48
|
+
justify: Multi-line text alignment.
|
|
49
|
+
padding: Inner spacing around the text content.
|
|
50
|
+
width: Width in character units.
|
|
51
|
+
wrap_width: Maximum pixel width before text wraps. Set to enable
|
|
52
|
+
multi-line wrapping.
|
|
53
|
+
font: Semantic font token. Examples: `'body'`, `'heading-lg'`,
|
|
54
|
+
`'heading-md[bold]'`, `'caption'`, `'code'`, `'body+2[italic]'`.
|
|
55
|
+
accent: Semantic color applied to the text.
|
|
56
|
+
surface: Background surface context.
|
|
57
|
+
localize: Whether the text is translated through the catalog — `True`,
|
|
58
|
+
`False`, or `'auto'` (translate when a translation is registered,
|
|
59
|
+
otherwise show the literal). Defaults to the app's `localize_mode`.
|
|
60
|
+
Set `False` to keep a proper noun or identifier untranslated.
|
|
61
|
+
parent: Explicit parent widget. If omitted, the current context-stack
|
|
62
|
+
container is used.
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
_internal_class = _InternalLabel
|
|
66
|
+
|
|
67
|
+
def __init__(
|
|
68
|
+
self,
|
|
69
|
+
text: str = "",
|
|
70
|
+
*,
|
|
71
|
+
textsignal: "Signal | None" = None,
|
|
72
|
+
value_format: str | None = None,
|
|
73
|
+
image: Any = None,
|
|
74
|
+
icon: str | IconSpec | None = None,
|
|
75
|
+
icon_only: bool = False,
|
|
76
|
+
icon_position: IconPosition = "left",
|
|
77
|
+
anchor: Anchor | None = None,
|
|
78
|
+
justify: Justify | None = None,
|
|
79
|
+
padding: Padding | None = None,
|
|
80
|
+
width: int | None = None,
|
|
81
|
+
wrap_width: int | None = None,
|
|
82
|
+
font: str | None = None,
|
|
83
|
+
accent: AccentToken | Literal['muted'] | str | None = None,
|
|
84
|
+
surface: SurfaceToken | str | None = None,
|
|
85
|
+
localize: bool | Literal['auto'] | None = None,
|
|
86
|
+
parent: Any = None,
|
|
87
|
+
**kwargs: Any,
|
|
88
|
+
) -> None:
|
|
89
|
+
# `variant` is not a public Label option (Label has only the implicit
|
|
90
|
+
# 'default'); it rides in via kwargs as the conduit for the Badge
|
|
91
|
+
# subclass, which sets its own 'square'/'pill' on a Badge ttk class.
|
|
92
|
+
variant = kwargs.pop("variant", None)
|
|
93
|
+
self._reject_signal_text(text)
|
|
94
|
+
self._parent = self._resolve_parent(parent)
|
|
95
|
+
layout_kw = self._split_layout_kwargs(kwargs)
|
|
96
|
+
tk_master = self._parent._child_master() if self._parent else None
|
|
97
|
+
|
|
98
|
+
internal_kwargs: dict[str, Any] = {}
|
|
99
|
+
if text:
|
|
100
|
+
internal_kwargs["text"] = text
|
|
101
|
+
if textsignal is not None:
|
|
102
|
+
internal_kwargs["textsignal"] = textsignal
|
|
103
|
+
if value_format is not None:
|
|
104
|
+
internal_kwargs["value_format"] = value_format
|
|
105
|
+
deferred_image = None
|
|
106
|
+
if image is not None:
|
|
107
|
+
from bootstack.images import Image as _ImageHandle
|
|
108
|
+
|
|
109
|
+
if isinstance(image, _ImageHandle):
|
|
110
|
+
deferred_image = image
|
|
111
|
+
has_text = bool(text) or textsignal is not None
|
|
112
|
+
if not has_text or icon_only:
|
|
113
|
+
internal_kwargs["icon_only"] = True
|
|
114
|
+
internal_kwargs["compound"] = "image"
|
|
115
|
+
else:
|
|
116
|
+
internal_kwargs["compound"] = icon_position
|
|
117
|
+
else:
|
|
118
|
+
internal_kwargs["image"] = image
|
|
119
|
+
if icon is not None:
|
|
120
|
+
internal_kwargs["icon"] = icon
|
|
121
|
+
has_text = bool(text) or textsignal is not None
|
|
122
|
+
if not has_text or icon_only:
|
|
123
|
+
internal_kwargs["icon_only"] = True
|
|
124
|
+
internal_kwargs["compound"] = "image"
|
|
125
|
+
else:
|
|
126
|
+
internal_kwargs["compound"] = icon_position
|
|
127
|
+
elif icon_only:
|
|
128
|
+
internal_kwargs["icon_only"] = True
|
|
129
|
+
if anchor is not None:
|
|
130
|
+
internal_kwargs["anchor"] = anchor
|
|
131
|
+
if justify is not None:
|
|
132
|
+
internal_kwargs["justify"] = justify
|
|
133
|
+
if padding is not None:
|
|
134
|
+
internal_kwargs["padding"] = padding
|
|
135
|
+
if width is not None:
|
|
136
|
+
internal_kwargs["width"] = width
|
|
137
|
+
if wrap_width is not None:
|
|
138
|
+
internal_kwargs["wraplength"] = wrap_width
|
|
139
|
+
if font is not None:
|
|
140
|
+
internal_kwargs["font"] = font
|
|
141
|
+
if accent is not None:
|
|
142
|
+
internal_kwargs["accent"] = accent
|
|
143
|
+
if variant is not None:
|
|
144
|
+
internal_kwargs["variant"] = variant
|
|
145
|
+
if surface is not None:
|
|
146
|
+
internal_kwargs["surface"] = surface
|
|
147
|
+
if localize is not None:
|
|
148
|
+
internal_kwargs["localize"] = localize
|
|
149
|
+
|
|
150
|
+
self._internal = self._internal_class(tk_master, **internal_kwargs)
|
|
151
|
+
if deferred_image is not None:
|
|
152
|
+
from bootstack.widgets._core.image_binding import bind_image
|
|
153
|
+
|
|
154
|
+
bind_image(self, self._internal, deferred_image)
|
|
155
|
+
self._attach_to_parent(layout_kw)
|
|
156
|
+
|
|
157
|
+
# ----- Properties -----
|
|
158
|
+
|
|
159
|
+
@property
|
|
160
|
+
def text(self) -> str:
|
|
161
|
+
"""The displayed text."""
|
|
162
|
+
return str(self._internal.cget("text"))
|
|
163
|
+
|
|
164
|
+
@text.setter
|
|
165
|
+
def text(self, value: str) -> None:
|
|
166
|
+
# When a textsignal/textvariable owns the text, ttk ignores the `text`
|
|
167
|
+
# option — write through the variable instead (which also keeps the
|
|
168
|
+
# bound signal in sync). Falls back to the option when unbound.
|
|
169
|
+
textvar = getattr(self._internal, "_textvariable", None)
|
|
170
|
+
if textvar is not None:
|
|
171
|
+
textvar.set(value)
|
|
172
|
+
else:
|
|
173
|
+
self._internal.configure(text=value)
|
|
174
|
+
|
|
175
|
+
# ----- Events -----
|
|
176
|
+
|
|
177
|
+
@overload
|
|
178
|
+
def on_click(self) -> Stream: ...
|
|
179
|
+
@overload
|
|
180
|
+
def on_click(self, handler: Callable[[Event], Any]) -> Subscription: ...
|
|
181
|
+
def on_click(self, handler: Callable[[Event], Any] | None = None) -> Stream | Subscription:
|
|
182
|
+
"""Register a callback for click events on this label.
|
|
183
|
+
|
|
184
|
+
Called with no handler, returns a composable `Stream`. Called with
|
|
185
|
+
a handler, binds it immediately and returns a `Subscription`. The
|
|
186
|
+
handler receives the curated `Event` (pointer position, modifier keys).
|
|
187
|
+
|
|
188
|
+
Args:
|
|
189
|
+
handler: Called with the click `Event` when the label is clicked.
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
`Subscription` (with handler) or `Stream` (without handler).
|
|
193
|
+
"""
|
|
194
|
+
return self.on("click", handler)
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
register_widget_events(Label, {})
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
class Badge(Label):
|
|
201
|
+
"""Compact styled chip for status indicators, counts, and tags.
|
|
202
|
+
|
|
203
|
+
A `Badge` is a styled `Label` with a fixed visual shape. It accepts the
|
|
204
|
+
same kwargs as `Label`, but the icon and image elements are not rendered.
|
|
205
|
+
|
|
206
|
+
Args:
|
|
207
|
+
text: Text to display inside the badge.
|
|
208
|
+
accent: Color intent token for the badge. Defaults to `'primary'`.
|
|
209
|
+
variant: Shape variant — `'square'` is a rounded rectangle, `'pill'` is
|
|
210
|
+
fully rounded. Default `'square'`.
|
|
211
|
+
**kwargs: Other `Label` options (e.g. `font`, `padding`, `width`) plus
|
|
212
|
+
layout placement options applied by the parent container. See
|
|
213
|
+
:doc:`/tasks/layout`.
|
|
214
|
+
"""
|
|
215
|
+
|
|
216
|
+
_internal_class = _InternalBadge
|
|
217
|
+
|
|
218
|
+
def __init__(
|
|
219
|
+
self,
|
|
220
|
+
text: str = "",
|
|
221
|
+
*,
|
|
222
|
+
accent: AccentToken | str = "primary",
|
|
223
|
+
variant: Literal["square", "pill"] = "square",
|
|
224
|
+
**kwargs: Any,
|
|
225
|
+
) -> None:
|
|
226
|
+
super().__init__(text, accent=accent, variant=variant, **kwargs)
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
register_widget_events(Badge, {})
|