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,249 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from bootstack.widgets._impl.primitives.frame import Frame
|
|
6
|
+
from bootstack.widgets._impl.primitives.flexframe import FlexFrame
|
|
7
|
+
from bootstack.widgets._core.base import PublicWidgetBase
|
|
8
|
+
from bootstack.widgets._core.container import FlexContainer
|
|
9
|
+
from bootstack.widgets.types import (
|
|
10
|
+
AccentToken, SurfaceToken, HAlign, VAlign, HArrange, VArrange, Padding,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class _FlexBase(FlexContainer):
|
|
15
|
+
_direction: str # set by subclass
|
|
16
|
+
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
*,
|
|
20
|
+
parent: Any = None,
|
|
21
|
+
horizontal_items: str = "left",
|
|
22
|
+
vertical_items: str = "top",
|
|
23
|
+
grow_items: bool = False,
|
|
24
|
+
weights: list[int] | None = None,
|
|
25
|
+
gap: int = 0,
|
|
26
|
+
padding: Padding | None = None,
|
|
27
|
+
surface: SurfaceToken | AccentToken | str | None = None,
|
|
28
|
+
show_border: bool = False,
|
|
29
|
+
width: int | None = None,
|
|
30
|
+
height: int | None = None,
|
|
31
|
+
**kwargs: Any,
|
|
32
|
+
) -> None:
|
|
33
|
+
# Shared implementation for Row/Column. Each subclass declares its own
|
|
34
|
+
# __init__ so Sphinx renders the (axis-specific) params and value types
|
|
35
|
+
# per class.
|
|
36
|
+
self._parent = self._resolve_parent(parent)
|
|
37
|
+
layout_kw = self._split_layout_kwargs(kwargs)
|
|
38
|
+
|
|
39
|
+
frame_kwargs: dict[str, Any] = {
|
|
40
|
+
"direction": self._direction,
|
|
41
|
+
"horizontal_items": horizontal_items,
|
|
42
|
+
"vertical_items": vertical_items,
|
|
43
|
+
"grow_items": grow_items,
|
|
44
|
+
"weights": weights,
|
|
45
|
+
"gap": gap,
|
|
46
|
+
}
|
|
47
|
+
if padding is not None:
|
|
48
|
+
frame_kwargs["padding"] = padding
|
|
49
|
+
if surface is not None:
|
|
50
|
+
frame_kwargs["surface"] = surface
|
|
51
|
+
if show_border:
|
|
52
|
+
frame_kwargs["show_border"] = show_border
|
|
53
|
+
if width is not None:
|
|
54
|
+
frame_kwargs["width"] = width
|
|
55
|
+
if height is not None:
|
|
56
|
+
frame_kwargs["height"] = height
|
|
57
|
+
if width is not None or height is not None:
|
|
58
|
+
frame_kwargs["propagate"] = False
|
|
59
|
+
|
|
60
|
+
tk_master = self._parent._child_master() if self._parent else None
|
|
61
|
+
self._internal = FlexFrame(tk_master, **frame_kwargs)
|
|
62
|
+
self._attach_to_parent(layout_kw)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class Row(_FlexBase):
|
|
66
|
+
"""Lays out children left to right along the horizontal axis.
|
|
67
|
+
|
|
68
|
+
Children flow in order. Position them on each screen axis: `horizontal_items`
|
|
69
|
+
*arranges the group* along the row (`'left'`/`'center'`/`'right'` or a
|
|
70
|
+
`'space-*'` mode), `vertical_items` *aligns* them up and down
|
|
71
|
+
(`'top'`/`'center'`/`'bottom'`/`'stretch'`), and `grow` / `weights` let
|
|
72
|
+
children share the available width. Drop a `Spacer` between children to push a
|
|
73
|
+
group aside without nesting.
|
|
74
|
+
|
|
75
|
+
Example::
|
|
76
|
+
|
|
77
|
+
with bs.Row(gap=8, vertical_items="center"):
|
|
78
|
+
bs.Label("Name:")
|
|
79
|
+
bs.TextField(grow=1)
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
horizontal_items: How the whole group of children is arranged along the
|
|
83
|
+
row — `'left'`, `'center'`, `'right'`, or the `'space-*'` modes. Has
|
|
84
|
+
no effect once any child grows. Defaults to `'left'`.
|
|
85
|
+
vertical_items: Vertical alignment of children — `'top'`, `'center'`,
|
|
86
|
+
`'bottom'`, or `'stretch'` (fill the row's height). Override per child
|
|
87
|
+
with `vertical`. Defaults to `'center'`.
|
|
88
|
+
grow_items: When `True`, every child grows equally to fill the row.
|
|
89
|
+
Defaults to `False`.
|
|
90
|
+
weights: Explicit per-child width weights (e.g. `[1, 2, 1]`) — shorthand
|
|
91
|
+
for setting `grow` on each child positionally. Overrides `grow_items`
|
|
92
|
+
and per-child `grow`. Defaults to `None`.
|
|
93
|
+
gap: Spacing in pixels between adjacent children. Defaults to `0`.
|
|
94
|
+
padding: Space in pixels between the row border and its content. Defaults
|
|
95
|
+
to `None` (no padding).
|
|
96
|
+
surface: Background token. Accepts a surface token, an accent token, or
|
|
97
|
+
any token with modifiers (e.g. `'primary[subtle]'`). Defaults to
|
|
98
|
+
`None` (inherits from parent surface).
|
|
99
|
+
show_border: When `True`, draws a 1 px border around the row frame.
|
|
100
|
+
Defaults to `False`.
|
|
101
|
+
width: Fixed width in pixels. Disables frame propagation so children
|
|
102
|
+
cannot resize the container. Defaults to `None` (size from children).
|
|
103
|
+
height: Fixed height in pixels. Disables frame propagation so children
|
|
104
|
+
cannot resize the container. Defaults to `None` (size from children).
|
|
105
|
+
parent: Override the context-stack parent widget.
|
|
106
|
+
**kwargs: Per-child placement options — `grow` (`bool | int`: `grow=True`
|
|
107
|
+
fills the leftover width with weight 1, `grow=N` takes N shares),
|
|
108
|
+
`vertical` (this child's vertical alignment: `'top'`/`'center'`/
|
|
109
|
+
`'bottom'`/`'stretch'`), `margin`, `index`. See :doc:`/tasks/layout`.
|
|
110
|
+
"""
|
|
111
|
+
_direction = "horizontal"
|
|
112
|
+
|
|
113
|
+
def __init__(
|
|
114
|
+
self,
|
|
115
|
+
*,
|
|
116
|
+
parent: Any = None,
|
|
117
|
+
horizontal_items: HArrange = "left",
|
|
118
|
+
vertical_items: VAlign = "center",
|
|
119
|
+
grow_items: bool = False,
|
|
120
|
+
weights: list[int] | None = None,
|
|
121
|
+
gap: int = 0,
|
|
122
|
+
padding: Padding | None = None,
|
|
123
|
+
surface: SurfaceToken | AccentToken | str | None = None,
|
|
124
|
+
show_border: bool = False,
|
|
125
|
+
width: int | None = None,
|
|
126
|
+
height: int | None = None,
|
|
127
|
+
**kwargs: Any,
|
|
128
|
+
) -> None:
|
|
129
|
+
super().__init__(
|
|
130
|
+
parent=parent, horizontal_items=horizontal_items,
|
|
131
|
+
vertical_items=vertical_items, grow_items=grow_items, weights=weights,
|
|
132
|
+
gap=gap, padding=padding, surface=surface, show_border=show_border,
|
|
133
|
+
width=width, height=height, **kwargs,
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class Column(_FlexBase):
|
|
138
|
+
"""Lays out children top to bottom along the vertical axis.
|
|
139
|
+
|
|
140
|
+
Children flow in order. Position them on each screen axis: `vertical_items`
|
|
141
|
+
*arranges the group* down the column (`'top'`/`'center'`/`'bottom'` or a
|
|
142
|
+
`'space-*'` mode), `horizontal_items` *aligns* them left and right
|
|
143
|
+
(`'left'`/`'center'`/`'right'`/`'stretch'`), and `grow` / `weights` let
|
|
144
|
+
children share the available height. Use `horizontal_items='stretch'` for a
|
|
145
|
+
full-width form column.
|
|
146
|
+
|
|
147
|
+
Example::
|
|
148
|
+
|
|
149
|
+
with bs.Column(gap=12, horizontal_items="stretch", padding=16):
|
|
150
|
+
bs.Label("Title", font="heading-md")
|
|
151
|
+
bs.TextField()
|
|
152
|
+
bs.Button("Submit", accent="primary")
|
|
153
|
+
|
|
154
|
+
Args:
|
|
155
|
+
horizontal_items: Horizontal alignment of children — `'left'`,
|
|
156
|
+
`'center'`, `'right'`, or `'stretch'` (fill the column's width).
|
|
157
|
+
Override per child with `horizontal`. Defaults to `'center'`.
|
|
158
|
+
vertical_items: How the whole group of children is arranged down the
|
|
159
|
+
column — `'top'`, `'center'`, `'bottom'`, or the `'space-*'` modes.
|
|
160
|
+
Has no effect once any child grows. Defaults to `'top'`.
|
|
161
|
+
grow_items: When `True`, every child grows equally to fill the column.
|
|
162
|
+
Defaults to `False`.
|
|
163
|
+
weights: Explicit per-child height weights (e.g. `[1, 2, 1]`) — shorthand
|
|
164
|
+
for setting `grow` on each child positionally. Overrides `grow_items`
|
|
165
|
+
and per-child `grow`. Defaults to `None`.
|
|
166
|
+
gap: Spacing in pixels between adjacent children. Defaults to `0`.
|
|
167
|
+
padding: Space in pixels between the column border and its content.
|
|
168
|
+
Defaults to `None` (no padding).
|
|
169
|
+
surface: Background token. Accepts a surface token, an accent token, or
|
|
170
|
+
any token with modifiers (e.g. `'primary[subtle]'`). Defaults to
|
|
171
|
+
`None` (inherits from parent surface).
|
|
172
|
+
show_border: When `True`, draws a 1 px border around the column frame.
|
|
173
|
+
Defaults to `False`.
|
|
174
|
+
width: Fixed width in pixels. Disables frame propagation so children
|
|
175
|
+
cannot resize the container. Defaults to `None` (size from children).
|
|
176
|
+
height: Fixed height in pixels. Disables frame propagation so children
|
|
177
|
+
cannot resize the container. Defaults to `None` (size from children).
|
|
178
|
+
parent: Override the context-stack parent widget.
|
|
179
|
+
**kwargs: Per-child placement options — `grow` (`bool | int`: `grow=True`
|
|
180
|
+
fills the leftover height with weight 1, `grow=N` takes N shares),
|
|
181
|
+
`horizontal` (this child's horizontal alignment: `'left'`/`'center'`/
|
|
182
|
+
`'right'`/`'stretch'`), `margin`, `index`. See :doc:`/tasks/layout`.
|
|
183
|
+
"""
|
|
184
|
+
_direction = "vertical"
|
|
185
|
+
|
|
186
|
+
def __init__(
|
|
187
|
+
self,
|
|
188
|
+
*,
|
|
189
|
+
parent: Any = None,
|
|
190
|
+
horizontal_items: HAlign = "center",
|
|
191
|
+
vertical_items: VArrange = "top",
|
|
192
|
+
grow_items: bool = False,
|
|
193
|
+
weights: list[int] | None = None,
|
|
194
|
+
gap: int = 0,
|
|
195
|
+
padding: Padding | None = None,
|
|
196
|
+
surface: SurfaceToken | AccentToken | str | None = None,
|
|
197
|
+
show_border: bool = False,
|
|
198
|
+
width: int | None = None,
|
|
199
|
+
height: int | None = None,
|
|
200
|
+
**kwargs: Any,
|
|
201
|
+
) -> None:
|
|
202
|
+
super().__init__(
|
|
203
|
+
parent=parent, horizontal_items=horizontal_items,
|
|
204
|
+
vertical_items=vertical_items, grow_items=grow_items, weights=weights,
|
|
205
|
+
gap=gap, padding=padding, surface=surface, show_border=show_border,
|
|
206
|
+
width=width, height=height, **kwargs,
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
class Spacer(PublicWidgetBase):
|
|
211
|
+
"""A composable break that pushes neighbors apart in a Row or Column.
|
|
212
|
+
|
|
213
|
+
Flexible by default — it absorbs the available stacking-axis space, so items
|
|
214
|
+
before it cluster at the start and items after it at the end. `Spacer(size=N)`
|
|
215
|
+
is instead a fixed N-pixel gap, and `Spacer(weight=N)` shares slack with
|
|
216
|
+
other spacers in proportion to their weights.
|
|
217
|
+
|
|
218
|
+
Unlike `horizontal_items`/`vertical_items` (which arrange the *whole* group),
|
|
219
|
+
a `Spacer` is a local break at one point — use it for clustered toolbars and
|
|
220
|
+
footers without nesting::
|
|
221
|
+
|
|
222
|
+
with bs.Row(gap=4):
|
|
223
|
+
bs.Button("New"); bs.Button("Open")
|
|
224
|
+
bs.Spacer()
|
|
225
|
+
bs.Button("Settings")
|
|
226
|
+
|
|
227
|
+
Args:
|
|
228
|
+
size: Fixed size in pixels. When set, the spacer is a rigid gap rather
|
|
229
|
+
than flexible slack. Defaults to `None` (flexible).
|
|
230
|
+
weight: Relative share of the leftover space when flexible. Ignored when
|
|
231
|
+
`size` is set. Defaults to `1`.
|
|
232
|
+
parent: Override the context-stack parent widget.
|
|
233
|
+
"""
|
|
234
|
+
|
|
235
|
+
_is_spacer = True
|
|
236
|
+
|
|
237
|
+
def __init__(
|
|
238
|
+
self,
|
|
239
|
+
*,
|
|
240
|
+
size: int | None = None,
|
|
241
|
+
weight: int = 1,
|
|
242
|
+
parent: Any = None,
|
|
243
|
+
) -> None:
|
|
244
|
+
self._parent = self._resolve_parent(parent)
|
|
245
|
+
self._spacer_size = size
|
|
246
|
+
self._spacer_weight = 0 if size is not None else weight
|
|
247
|
+
tk_master = self._parent._child_master() if self._parent else None
|
|
248
|
+
self._internal = Frame(tk_master, width=1, height=1)
|
|
249
|
+
self._attach_to_parent({})
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Literal
|
|
4
|
+
|
|
5
|
+
from bootstack.widgets._impl.composites.toolbar import Toolbar as _InternalToolbar
|
|
6
|
+
from bootstack.widgets._core.base import PublicWidgetBase
|
|
7
|
+
from bootstack.widgets.types import SurfaceToken, WidgetDensity
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from bootstack.signals import Signal
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class StatusBar(PublicWidgetBase):
|
|
14
|
+
"""A horizontal status band of passive segments — counts, sync state, a ready
|
|
15
|
+
message.
|
|
16
|
+
|
|
17
|
+
Intended for *passive* status (whether static or bound to a `Signal` for live
|
|
18
|
+
updates). Interactive controls (buttons, a search box) belong on a
|
|
19
|
+
:class:`Toolbar <bootstack.Toolbar>` by convention; nothing enforces it,
|
|
20
|
+
but the status bar reads best as a quiet display strip. Segments add
|
|
21
|
+
left-to-right; an `add_spacer()` (or `side='right'`) pushes the following
|
|
22
|
+
segments to the right cluster.
|
|
23
|
+
|
|
24
|
+
Use it standalone — `bs.StatusBar(horizontal="stretch")` spans the bottom of
|
|
25
|
+
any `App`/`Window` (place it last and let the content above `grow`) — or read
|
|
26
|
+
`shell.statusbar` for the one built
|
|
27
|
+
into an :class:`AppShell <bootstack.AppShell>`. Add widgets by class with
|
|
28
|
+
`add_widget()`, or create custom widgets with `parent=statusbar` (they add to
|
|
29
|
+
the left cluster automatically).
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
surface: Background surface token. Defaults to the theme's `'chrome'`
|
|
33
|
+
surface (a quiet band, distinct from the content area).
|
|
34
|
+
density: Size of the band's segments. Default `'compact'`.
|
|
35
|
+
padding: Inner padding in pixels — an int or a `(horizontal, vertical)`
|
|
36
|
+
tuple. Defaults to a thin compact padding.
|
|
37
|
+
parent: Override the context-stack parent.
|
|
38
|
+
**kwargs: Layout placement options applied by the parent container —
|
|
39
|
+
`fill`, `side`, `expand`, `anchor`, `margin`. See :doc:`/tasks/layout`.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
_auto_place = True
|
|
43
|
+
|
|
44
|
+
def __init__(
|
|
45
|
+
self,
|
|
46
|
+
*,
|
|
47
|
+
surface: SurfaceToken | str | None = "chrome",
|
|
48
|
+
density: WidgetDensity = "compact",
|
|
49
|
+
padding: int | tuple[int, int] | None = None,
|
|
50
|
+
parent: Any = None,
|
|
51
|
+
_toolbar: Any = None,
|
|
52
|
+
_show: Any = None,
|
|
53
|
+
**kwargs: Any,
|
|
54
|
+
) -> None:
|
|
55
|
+
self._has_right_spacer = False
|
|
56
|
+
if _toolbar is not None:
|
|
57
|
+
# Shell adoption: wrap the AppShell's pre-built status band. `_show`
|
|
58
|
+
# reveals the (content-driven) band on the first segment added.
|
|
59
|
+
self._internal = _toolbar
|
|
60
|
+
self._parent = None
|
|
61
|
+
self._show = _show or (lambda: None)
|
|
62
|
+
return
|
|
63
|
+
|
|
64
|
+
# Standalone: build our own bar (the Toolbar pattern).
|
|
65
|
+
self._parent = self._resolve_parent(parent)
|
|
66
|
+
layout_kw = self._split_layout_kwargs(kwargs)
|
|
67
|
+
tk_master = self._parent._child_master() if self._parent else None
|
|
68
|
+
internal_kwargs: dict[str, Any] = {"density": density, "draggable": False}
|
|
69
|
+
if surface is not None:
|
|
70
|
+
internal_kwargs["surface"] = surface
|
|
71
|
+
if padding is not None:
|
|
72
|
+
internal_kwargs["padding"] = padding
|
|
73
|
+
internal_kwargs.update(kwargs)
|
|
74
|
+
self._internal = _InternalToolbar(tk_master, **internal_kwargs)
|
|
75
|
+
self._attach_to_parent(layout_kw)
|
|
76
|
+
# Standalone bars are placed/shown by the caller — nothing to reveal.
|
|
77
|
+
self._show = lambda: None
|
|
78
|
+
|
|
79
|
+
# ----- Container protocol (so `parent=statusbar` works) -----
|
|
80
|
+
|
|
81
|
+
def _child_master(self) -> Any:
|
|
82
|
+
return self._internal.content
|
|
83
|
+
|
|
84
|
+
def guide_layout(self, child: Any, **layout_kw: Any) -> None:
|
|
85
|
+
# A widget created with `parent=statusbar` adds to the left cluster.
|
|
86
|
+
self._internal.add_widget(child._internal)
|
|
87
|
+
self._show()
|
|
88
|
+
|
|
89
|
+
@property
|
|
90
|
+
def content(self) -> Any:
|
|
91
|
+
"""The band's content frame — parent custom widgets here."""
|
|
92
|
+
return self._internal.content
|
|
93
|
+
|
|
94
|
+
# ----- Segments -----
|
|
95
|
+
|
|
96
|
+
def _ensure_right(self) -> None:
|
|
97
|
+
if not self._has_right_spacer:
|
|
98
|
+
self._internal.add_spacer()
|
|
99
|
+
self._has_right_spacer = True
|
|
100
|
+
|
|
101
|
+
def add_widget(
|
|
102
|
+
self, widget_cls: Any, *, side: Literal["left", "right"] = "left", **kwargs: Any
|
|
103
|
+
) -> Any:
|
|
104
|
+
"""Build a widget on the left or right cluster from its class.
|
|
105
|
+
|
|
106
|
+
Pass a widget **class** — the bar builds it, applying its own `density`
|
|
107
|
+
and `surface` (for any the class accepts) so the widget matches the band,
|
|
108
|
+
and forwarding `kwargs` to the constructor:
|
|
109
|
+
|
|
110
|
+
status.add_widget(bs.ThemeToggle, side="right")
|
|
111
|
+
status.add_widget(bs.ProgressBar, value=65)
|
|
112
|
+
|
|
113
|
+
To add a widget you have already built yourself, parent it onto the bar
|
|
114
|
+
directly (it lands in the left cluster):
|
|
115
|
+
|
|
116
|
+
bs.MyCustomWidget(parent=status)
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
widget_cls: The widget class to build on the band.
|
|
120
|
+
side: `'left'` (default) or `'right'` (after the spacer).
|
|
121
|
+
**kwargs: Constructor arguments for the widget.
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
The new widget instance.
|
|
125
|
+
"""
|
|
126
|
+
if side == "right":
|
|
127
|
+
self._ensure_right()
|
|
128
|
+
self._apply_bar_defaults(widget_cls, kwargs)
|
|
129
|
+
return widget_cls(parent=self, **kwargs)
|
|
130
|
+
|
|
131
|
+
def _apply_bar_defaults(self, widget_cls: type, kwargs: dict[str, Any]) -> None:
|
|
132
|
+
"""Default `density`/`surface` from the band onto a class being built, but
|
|
133
|
+
only for parameters the widget actually accepts (and not if the caller
|
|
134
|
+
already passed them)."""
|
|
135
|
+
import inspect
|
|
136
|
+
|
|
137
|
+
try:
|
|
138
|
+
params = inspect.signature(widget_cls).parameters
|
|
139
|
+
except (TypeError, ValueError):
|
|
140
|
+
return
|
|
141
|
+
if "density" in params:
|
|
142
|
+
kwargs.setdefault("density", self._internal.density)
|
|
143
|
+
if "surface" in params:
|
|
144
|
+
kwargs.setdefault("surface", self._internal._surface)
|
|
145
|
+
|
|
146
|
+
def add_text(
|
|
147
|
+
self,
|
|
148
|
+
text: str = "",
|
|
149
|
+
*,
|
|
150
|
+
textsignal: "Signal | None" = None,
|
|
151
|
+
side: Literal["left", "right"] = "left",
|
|
152
|
+
icon: str | None = None,
|
|
153
|
+
font: str | None = None,
|
|
154
|
+
) -> None:
|
|
155
|
+
"""Add a text (and optional icon) segment to a cluster.
|
|
156
|
+
|
|
157
|
+
Pass `textsignal` to make the segment **reactive** — a `Signal` whose
|
|
158
|
+
value drives the text and updates it live as the signal changes (e.g. a
|
|
159
|
+
running count or sync state). `text` seeds a static segment instead.
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
text: The static label text (ignored when `textsignal` is given).
|
|
163
|
+
textsignal: A reactive `Signal[str]` bound to the segment's text.
|
|
164
|
+
side: `'left'` (default) or `'right'` (after the spacer).
|
|
165
|
+
icon: Optional icon name displayed beside the text.
|
|
166
|
+
font: Optional font token, e.g. `'caption'`.
|
|
167
|
+
"""
|
|
168
|
+
if side == "right":
|
|
169
|
+
self._ensure_right()
|
|
170
|
+
kwargs: dict[str, Any] = {"icon": icon, "font": font}
|
|
171
|
+
if textsignal is not None:
|
|
172
|
+
kwargs["textsignal"] = textsignal
|
|
173
|
+
self._internal.add_label(text, **kwargs)
|
|
174
|
+
self._show()
|
|
175
|
+
|
|
176
|
+
def add_spacer(self) -> None:
|
|
177
|
+
"""Add a flexible spacer that pushes following items to the right."""
|
|
178
|
+
self._internal.add_spacer()
|
|
179
|
+
self._has_right_spacer = True
|
|
180
|
+
self._show()
|
|
181
|
+
|
|
182
|
+
def clear(self) -> None:
|
|
183
|
+
"""Remove all status segments."""
|
|
184
|
+
for child in list(self._internal.content.winfo_children()):
|
|
185
|
+
try:
|
|
186
|
+
child.destroy()
|
|
187
|
+
except Exception:
|
|
188
|
+
pass
|
|
189
|
+
self._has_right_spacer = False
|