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,425 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import tkinter
|
|
4
|
+
from typing import overload, Any, Callable, Literal
|
|
5
|
+
|
|
6
|
+
from bootstack.widgets._impl.composites.tabs.tabview import TabView as _InternalTabView
|
|
7
|
+
from bootstack.events import TabChangeEvent, TabCloseEvent, TabRef
|
|
8
|
+
from bootstack.widgets._impl.primitives.flexframe import FlexFrame
|
|
9
|
+
from bootstack.widgets._impl.primitives.gridframe import GridFrame
|
|
10
|
+
from bootstack.widgets._core.base import PublicWidgetBase, adapt_handler
|
|
11
|
+
from bootstack.widgets._core.container import (
|
|
12
|
+
GRID_KEYS, grid_sticky, place_flex_child, _reject_legacy_child_kwargs,
|
|
13
|
+
_expand_margin,
|
|
14
|
+
)
|
|
15
|
+
from bootstack.widgets._core.context import push_container, pop_container
|
|
16
|
+
from bootstack.widgets._core.events import register_widget_events, resolve_event
|
|
17
|
+
from bootstack.events import Subscription
|
|
18
|
+
from bootstack._core import NavigationError
|
|
19
|
+
from bootstack.streams import Stream
|
|
20
|
+
from bootstack.widgets.types import (
|
|
21
|
+
Event, AccentToken, Padding, LayoutKind, AutoFlow, Orient,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
_TABS_EVENTS: dict[str, str] = {
|
|
25
|
+
"change": "<<TabChanged>>",
|
|
26
|
+
"tab_close": "<<TabClose>>",
|
|
27
|
+
"tab_add": "<<TabAdd>>",
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class TabPage:
|
|
32
|
+
"""A handle for one tab — both a layout context and a live controller.
|
|
33
|
+
|
|
34
|
+
Returned by `Tabs.add()` and by `Tabs.item()` / `items()`. Use it as a `with`
|
|
35
|
+
block to place child widgets, and read `key` / read or set `label`, or call
|
|
36
|
+
`select()` / `hide()` / `show()` / `remove()` to drive the tab afterward.
|
|
37
|
+
|
|
38
|
+
As a context manager it accepts the same layout kwargs as the standalone
|
|
39
|
+
layout containers — `layout=`, `gap=`, `horizontal_items=`, `vertical_items=`,
|
|
40
|
+
`grow_items=`, `columns=`, `rows=`, `auto_flow=`.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
def __init__(
|
|
44
|
+
self,
|
|
45
|
+
page_widget: tkinter.Widget,
|
|
46
|
+
*,
|
|
47
|
+
key: str,
|
|
48
|
+
owner: "Tabs",
|
|
49
|
+
layout: LayoutKind = "column",
|
|
50
|
+
padding: Padding | None = None,
|
|
51
|
+
gap: int = 0,
|
|
52
|
+
horizontal_items: str | None = None,
|
|
53
|
+
vertical_items: str | None = None,
|
|
54
|
+
grow_items: bool = False,
|
|
55
|
+
columns: int | list[int | str] | None = None,
|
|
56
|
+
rows: int | list[int | str] | None = None,
|
|
57
|
+
auto_flow: AutoFlow = "row",
|
|
58
|
+
) -> None:
|
|
59
|
+
self._page = page_widget
|
|
60
|
+
self._key = key
|
|
61
|
+
self._owner = owner
|
|
62
|
+
self._layout = layout
|
|
63
|
+
|
|
64
|
+
if horizontal_items is None:
|
|
65
|
+
horizontal_items = (
|
|
66
|
+
"stretch" if layout == "grid"
|
|
67
|
+
else "center" if layout == "column" else "left"
|
|
68
|
+
)
|
|
69
|
+
if vertical_items is None:
|
|
70
|
+
vertical_items = (
|
|
71
|
+
"stretch" if layout == "grid"
|
|
72
|
+
else "center" if layout == "row" else "top"
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
if layout in ("column", "row"):
|
|
76
|
+
self._layout_frame = FlexFrame(
|
|
77
|
+
page_widget,
|
|
78
|
+
direction="vertical" if layout == "column" else "horizontal",
|
|
79
|
+
padding=padding,
|
|
80
|
+
gap=gap,
|
|
81
|
+
horizontal_items=horizontal_items,
|
|
82
|
+
vertical_items=vertical_items,
|
|
83
|
+
grow_items=grow_items,
|
|
84
|
+
)
|
|
85
|
+
elif layout == "grid":
|
|
86
|
+
self._layout_frame = GridFrame(
|
|
87
|
+
page_widget,
|
|
88
|
+
columns=columns,
|
|
89
|
+
rows=rows,
|
|
90
|
+
padding=padding,
|
|
91
|
+
gap=gap,
|
|
92
|
+
auto_flow=auto_flow,
|
|
93
|
+
)
|
|
94
|
+
else:
|
|
95
|
+
raise ValueError(
|
|
96
|
+
f"TabPage layout must be 'column', 'row', or 'grid', got {layout!r}"
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
self._horizontal_items = horizontal_items
|
|
100
|
+
self._vertical_items = vertical_items
|
|
101
|
+
self._layout_frame.pack(fill="both", expand=True)
|
|
102
|
+
|
|
103
|
+
def _child_master(self) -> tkinter.Widget:
|
|
104
|
+
return self._layout_frame
|
|
105
|
+
|
|
106
|
+
def guide_layout(self, child: PublicWidgetBase, **layout_kw: Any) -> None:
|
|
107
|
+
if self._layout == "grid":
|
|
108
|
+
_reject_legacy_child_kwargs(layout_kw, "TabPage")
|
|
109
|
+
_expand_margin(layout_kw)
|
|
110
|
+
options = {k: v for k, v in layout_kw.items() if k in GRID_KEYS}
|
|
111
|
+
h = layout_kw.get("horizontal") or self._horizontal_items
|
|
112
|
+
v = layout_kw.get("vertical") or self._vertical_items
|
|
113
|
+
options["sticky"] = grid_sticky(h, v)
|
|
114
|
+
child._internal.grid(in_=self._child_master(), **options)
|
|
115
|
+
return
|
|
116
|
+
place_flex_child(self._layout_frame, child, layout_kw, "TabPage")
|
|
117
|
+
|
|
118
|
+
# ----- Tab identity, label, and control -----
|
|
119
|
+
|
|
120
|
+
@property
|
|
121
|
+
def key(self) -> str:
|
|
122
|
+
"""The tab's unique key, used with `Tabs.item()` / `select()`."""
|
|
123
|
+
return self._key
|
|
124
|
+
|
|
125
|
+
@property
|
|
126
|
+
def label(self) -> str:
|
|
127
|
+
"""The text shown on the tab. Assigning a new value relabels the tab."""
|
|
128
|
+
return self._owner._internal.configure_tab(self._key, "text")
|
|
129
|
+
|
|
130
|
+
@label.setter
|
|
131
|
+
def label(self, value: str) -> None:
|
|
132
|
+
self._owner._internal.configure_tab(self._key, text=value)
|
|
133
|
+
|
|
134
|
+
def select(self) -> None:
|
|
135
|
+
"""Select (focus) this tab."""
|
|
136
|
+
self._owner.select(self._key)
|
|
137
|
+
|
|
138
|
+
def hide(self) -> None:
|
|
139
|
+
"""Hide this tab without removing it. Restore with `show()`."""
|
|
140
|
+
self._owner.hide_tab(self._key)
|
|
141
|
+
|
|
142
|
+
def show(self) -> None:
|
|
143
|
+
"""Restore this tab after it was hidden."""
|
|
144
|
+
self._owner.show_tab(self._key)
|
|
145
|
+
|
|
146
|
+
def remove(self) -> None:
|
|
147
|
+
"""Remove this tab and its page entirely."""
|
|
148
|
+
self._owner.forget_tab(self._key)
|
|
149
|
+
|
|
150
|
+
def __enter__(self) -> "TabPage":
|
|
151
|
+
push_container(self)
|
|
152
|
+
return self
|
|
153
|
+
|
|
154
|
+
def __exit__(self, exc_type, exc, tb) -> None:
|
|
155
|
+
pop_container(self)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
class Tabs(PublicWidgetBase):
|
|
159
|
+
"""A tabbed container. Add pages with `.add()` and place children inside them.
|
|
160
|
+
|
|
161
|
+
Usage::
|
|
162
|
+
|
|
163
|
+
tabs = bs.Tabs()
|
|
164
|
+
with tabs.add("home", label="Home"):
|
|
165
|
+
bs.Label("Welcome")
|
|
166
|
+
with tabs.add("settings", label="Settings"):
|
|
167
|
+
bs.Label("Settings here")
|
|
168
|
+
|
|
169
|
+
Args:
|
|
170
|
+
orient: `'horizontal'` (default, tabs above content) or `'vertical'` (tabs left).
|
|
171
|
+
show_divider: Show a divider line between the tab bar and the page area.
|
|
172
|
+
tab_width: Fixed tab width in pixels, `'stretch'` to fill available space, or
|
|
173
|
+
`None` (default, size to content). When tabs exceed the strip they
|
|
174
|
+
scroll — no scrollbar, the wheel scrolls along the strip, and a
|
|
175
|
+
trailing chevron lists the off-screen tabs and scrolls the chosen one
|
|
176
|
+
into view (both orientations). `'stretch'` tabs always fit.
|
|
177
|
+
allow_close: Show close buttons on tabs. `True` = always, `False` = never,
|
|
178
|
+
`'hover'` = on hover. Defaults to `False`.
|
|
179
|
+
allow_add: Show an add-tab button that fires the `tab_add` event.
|
|
180
|
+
max_tabs: Maximum number of tabs. When reached, the add button is
|
|
181
|
+
disabled (and re-enabled when a tab is removed). `None` (default)
|
|
182
|
+
means no limit. Pairs with `allow_add`.
|
|
183
|
+
accent: Accent token for the tab bar. Defaults to the theme accent.
|
|
184
|
+
parent: Override the context-stack parent.
|
|
185
|
+
**kwargs: Layout placement options applied by the parent container —
|
|
186
|
+
`fill`, `expand`, `anchor`, `margin`, `row`, `column`, `sticky`.
|
|
187
|
+
See :doc:`/tasks/layout`.
|
|
188
|
+
"""
|
|
189
|
+
|
|
190
|
+
def __init__(
|
|
191
|
+
self,
|
|
192
|
+
*,
|
|
193
|
+
orient: Orient = "horizontal",
|
|
194
|
+
show_divider: bool | None = None,
|
|
195
|
+
tab_width: int | Literal["stretch"] | None = None,
|
|
196
|
+
allow_close: bool | Literal["hover"] = False,
|
|
197
|
+
allow_add: bool = False,
|
|
198
|
+
max_tabs: int | None = None,
|
|
199
|
+
accent: AccentToken | str | None = None,
|
|
200
|
+
parent: Any = None,
|
|
201
|
+
**kwargs: Any,
|
|
202
|
+
) -> None:
|
|
203
|
+
self._parent = self._resolve_parent(parent)
|
|
204
|
+
layout_kw = self._split_layout_kwargs(kwargs)
|
|
205
|
+
|
|
206
|
+
tk_master = self._parent._child_master() if self._parent else None
|
|
207
|
+
|
|
208
|
+
internal_kwargs: dict[str, Any] = {
|
|
209
|
+
"orient": orient,
|
|
210
|
+
"enable_closing": allow_close,
|
|
211
|
+
"enable_adding": allow_add,
|
|
212
|
+
"max_tabs": max_tabs,
|
|
213
|
+
}
|
|
214
|
+
if show_divider is not None:
|
|
215
|
+
internal_kwargs["show_divider"] = show_divider
|
|
216
|
+
if tab_width is not None:
|
|
217
|
+
internal_kwargs["tab_width"] = tab_width
|
|
218
|
+
if accent is not None:
|
|
219
|
+
internal_kwargs["accent"] = accent
|
|
220
|
+
|
|
221
|
+
self._pages: dict[str, TabPage] = {}
|
|
222
|
+
self._internal = _InternalTabView(tk_master, **internal_kwargs)
|
|
223
|
+
self._attach_to_parent(layout_kw)
|
|
224
|
+
|
|
225
|
+
# ----- Event routing -----
|
|
226
|
+
|
|
227
|
+
@overload
|
|
228
|
+
def on(self, event: str) -> Stream: ...
|
|
229
|
+
@overload
|
|
230
|
+
def on(self, event: str, handler: Callable[[Event], Any]) -> Subscription: ...
|
|
231
|
+
def on(self, event: str, handler: Callable[[Event], Any] | None = None) -> Stream | Subscription:
|
|
232
|
+
"""Bind `handler` to `event` and return a `Subscription`."""
|
|
233
|
+
sequence = resolve_event(self, str(event))
|
|
234
|
+
|
|
235
|
+
if handler is None:
|
|
236
|
+
def _source(h):
|
|
237
|
+
bid = self._internal.bind(sequence, adapt_handler(h), add="+")
|
|
238
|
+
return Subscription(self._internal, sequence, bid)
|
|
239
|
+
return Stream(self._internal, _source=_source)
|
|
240
|
+
|
|
241
|
+
bind_id = self._internal.bind(sequence, adapt_handler(handler), add="+")
|
|
242
|
+
return Subscription(self._internal, sequence, bind_id)
|
|
243
|
+
|
|
244
|
+
# ----- Tab management -----
|
|
245
|
+
|
|
246
|
+
def add(
|
|
247
|
+
self,
|
|
248
|
+
key: str,
|
|
249
|
+
*,
|
|
250
|
+
label: str = "",
|
|
251
|
+
icon: str | None = None,
|
|
252
|
+
closable: bool | Literal["hover"] | None = None,
|
|
253
|
+
close_command: Callable[[], Any] | None = None,
|
|
254
|
+
layout: LayoutKind = "column",
|
|
255
|
+
padding: Padding | None = None,
|
|
256
|
+
gap: int = 0,
|
|
257
|
+
horizontal_items: str | None = None,
|
|
258
|
+
vertical_items: str | None = None,
|
|
259
|
+
grow_items: bool = False,
|
|
260
|
+
columns: int | list[int | str] | None = None,
|
|
261
|
+
rows: int | list[int | str] | None = None,
|
|
262
|
+
auto_flow: AutoFlow = "row",
|
|
263
|
+
) -> TabPage:
|
|
264
|
+
"""Add a tab and return a handle for placing its children and controlling it.
|
|
265
|
+
|
|
266
|
+
Args:
|
|
267
|
+
key: Unique identifier for the tab/page.
|
|
268
|
+
label: Label displayed on the tab.
|
|
269
|
+
icon: Icon name displayed on the tab.
|
|
270
|
+
closable: Close-button visibility for this tab. Overrides `allow_close`.
|
|
271
|
+
close_command: Called when the close button is clicked.
|
|
272
|
+
layout: Internal layout. Defaults to `'column'`.
|
|
273
|
+
padding: Space inside the page frame. Defaults to `None`.
|
|
274
|
+
gap: Space between children in pixels. Defaults to `0`.
|
|
275
|
+
horizontal_items: How children sit on the horizontal axis — edge
|
|
276
|
+
values `'left'`/`'center'`/`'right'`/`'stretch'`, plus `'space-*'`
|
|
277
|
+
when horizontal is the stacking axis. Defaults to `'stretch'` in grid mode,
|
|
278
|
+
`'center'` in a column and `'left'` in a row.
|
|
279
|
+
vertical_items: How children sit on the vertical axis — edge values
|
|
280
|
+
`'top'`/`'center'`/`'bottom'`/`'stretch'`, plus `'space-*'` when
|
|
281
|
+
vertical is the stacking axis. Defaults to `'stretch'` in grid mode,
|
|
282
|
+
`'center'` in a row and `'top'` in a column.
|
|
283
|
+
grow_items: For `'column'`/`'row'`, when `True` every child grows
|
|
284
|
+
equally to share the main axis. Defaults to `False`.
|
|
285
|
+
columns: Column definitions for `'grid'` layout. An integer sets
|
|
286
|
+
the number of equal-weight columns; a list sets per-column
|
|
287
|
+
weights or sizes (e.g. `[1, 2, 'auto', '120px']`).
|
|
288
|
+
rows: Row definitions for `'grid'` layout, same format as `columns`.
|
|
289
|
+
auto_flow: Grid auto-flow direction. Defaults to `'row'`.
|
|
290
|
+
|
|
291
|
+
Returns:
|
|
292
|
+
`TabPage` — use as a context manager to place children, and as a
|
|
293
|
+
handle to `select()`/`hide()`/`show()`/`remove()` the tab.
|
|
294
|
+
"""
|
|
295
|
+
add_kwargs: dict[str, Any] = {}
|
|
296
|
+
if icon is not None:
|
|
297
|
+
add_kwargs["icon"] = icon
|
|
298
|
+
if closable is not None:
|
|
299
|
+
add_kwargs["closable"] = closable
|
|
300
|
+
if close_command is not None:
|
|
301
|
+
add_kwargs["close_command"] = close_command
|
|
302
|
+
|
|
303
|
+
page_widget = self._internal.add(key, text=label, **add_kwargs)
|
|
304
|
+
page = TabPage(
|
|
305
|
+
page_widget,
|
|
306
|
+
key=key, owner=self,
|
|
307
|
+
layout=layout, padding=padding, gap=gap,
|
|
308
|
+
horizontal_items=horizontal_items, vertical_items=vertical_items,
|
|
309
|
+
grow_items=grow_items,
|
|
310
|
+
columns=columns, rows=rows, auto_flow=auto_flow,
|
|
311
|
+
)
|
|
312
|
+
self._pages[key] = page
|
|
313
|
+
return page
|
|
314
|
+
|
|
315
|
+
def select(self, key: str) -> None:
|
|
316
|
+
"""Select the tab identified by `key`.
|
|
317
|
+
|
|
318
|
+
Raises:
|
|
319
|
+
NavigationError: If no tab with the given key exists.
|
|
320
|
+
"""
|
|
321
|
+
self._internal.select(key)
|
|
322
|
+
|
|
323
|
+
def hide_tab(self, key: str) -> None:
|
|
324
|
+
"""Hide a tab without removing it. Restore with `show_tab()`.
|
|
325
|
+
|
|
326
|
+
Raises:
|
|
327
|
+
NavigationError: If no tab with the given key exists.
|
|
328
|
+
"""
|
|
329
|
+
self._internal.hide_tab(key)
|
|
330
|
+
|
|
331
|
+
def show_tab(self, key: str) -> None:
|
|
332
|
+
"""Restore a previously hidden tab.
|
|
333
|
+
|
|
334
|
+
Raises:
|
|
335
|
+
NavigationError: If no tab with the given key exists.
|
|
336
|
+
"""
|
|
337
|
+
self._internal.show_tab(key)
|
|
338
|
+
|
|
339
|
+
def forget_tab(self, key: str) -> None:
|
|
340
|
+
"""Remove a tab and its page entirely.
|
|
341
|
+
|
|
342
|
+
Raises:
|
|
343
|
+
NavigationError: If no tab with the given key exists.
|
|
344
|
+
"""
|
|
345
|
+
self._internal.forget_tab(key)
|
|
346
|
+
self._pages.pop(key, None)
|
|
347
|
+
|
|
348
|
+
# ----- Properties / introspection -----
|
|
349
|
+
|
|
350
|
+
@property
|
|
351
|
+
def current(self) -> str | None:
|
|
352
|
+
"""Key of the currently selected tab, or `None` if no tab is selected."""
|
|
353
|
+
return self._internal.current
|
|
354
|
+
|
|
355
|
+
def tab_keys(self) -> tuple[str, ...]:
|
|
356
|
+
"""All tab keys in insertion order."""
|
|
357
|
+
return self._internal.tab_keys()
|
|
358
|
+
|
|
359
|
+
def page_keys(self) -> tuple[str, ...]:
|
|
360
|
+
"""All page keys in insertion order."""
|
|
361
|
+
return self._internal.page_keys()
|
|
362
|
+
|
|
363
|
+
def item(self, key: str) -> TabPage:
|
|
364
|
+
"""Return the tab handle for `key`.
|
|
365
|
+
|
|
366
|
+
Args:
|
|
367
|
+
key: Tab key assigned in `add()`.
|
|
368
|
+
|
|
369
|
+
Returns:
|
|
370
|
+
The `TabPage` for that key — read/set its `label` or call
|
|
371
|
+
`select()`/`hide()`/`show()`/`remove()`.
|
|
372
|
+
|
|
373
|
+
Raises:
|
|
374
|
+
NavigationError: If no tab with the given key exists.
|
|
375
|
+
"""
|
|
376
|
+
if key not in self._pages:
|
|
377
|
+
raise NavigationError(f"No tab with key '{key}'")
|
|
378
|
+
return self._pages[key]
|
|
379
|
+
|
|
380
|
+
def items(self) -> tuple[TabPage, ...]:
|
|
381
|
+
"""Return all tab handles in insertion order."""
|
|
382
|
+
return tuple(self._pages[k] for k in self._internal.tab_keys())
|
|
383
|
+
|
|
384
|
+
# ----- Event shorthands -----
|
|
385
|
+
|
|
386
|
+
@overload
|
|
387
|
+
def on_change(self) -> Stream: ...
|
|
388
|
+
@overload
|
|
389
|
+
def on_change(self, handler: Callable[[TabChangeEvent], Any]) -> Subscription: ...
|
|
390
|
+
def on_change(self, handler: Callable[[TabChangeEvent], Any] | None = None) -> Stream | Subscription:
|
|
391
|
+
"""Register a callback fired when the selected tab changes.
|
|
392
|
+
|
|
393
|
+
Returns:
|
|
394
|
+
`Subscription` (with handler) or `Stream` (without handler).
|
|
395
|
+
"""
|
|
396
|
+
return self.on("change", handler)
|
|
397
|
+
|
|
398
|
+
@overload
|
|
399
|
+
def on_tab_close(self) -> Stream: ...
|
|
400
|
+
@overload
|
|
401
|
+
def on_tab_close(self, handler: Callable[[TabCloseEvent], Any]) -> Subscription: ...
|
|
402
|
+
def on_tab_close(self, handler: Callable[[TabCloseEvent], Any] | None = None) -> Stream | Subscription:
|
|
403
|
+
"""Register a callback fired when a tab's close button is clicked.
|
|
404
|
+
|
|
405
|
+
Returns:
|
|
406
|
+
`Subscription` (with handler) or `Stream` (without handler).
|
|
407
|
+
"""
|
|
408
|
+
return self.on("tab_close", handler)
|
|
409
|
+
|
|
410
|
+
@overload
|
|
411
|
+
def on_tab_add(self) -> Stream: ...
|
|
412
|
+
@overload
|
|
413
|
+
def on_tab_add(self, handler: Callable[[Event], Any]) -> Subscription: ...
|
|
414
|
+
def on_tab_add(self, handler: Callable[[Event], Any] | None = None) -> Stream | Subscription:
|
|
415
|
+
"""Register a callback fired when the add-tab button is clicked.
|
|
416
|
+
|
|
417
|
+
Returns:
|
|
418
|
+
`Subscription` (with handler) or `Stream` (without handler).
|
|
419
|
+
"""
|
|
420
|
+
return self.on("tab_add", handler)
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
register_widget_events(Tabs, _TABS_EVENTS)
|
|
424
|
+
|
|
425
|
+
__all__ = ["Tabs", "TabPage", "TabChangeEvent", "TabRef"]
|