bootstack 0.3.0__tar.gz → 0.3.1__tar.gz
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-0.3.0/src/bootstack.egg-info → bootstack-0.3.1}/PKG-INFO +1 -1
- {bootstack-0.3.0 → bootstack-0.3.1}/pyproject.toml +2 -2
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/dialogs/_impl/datedialog.py +27 -2
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/dialogs/_impl/dialog.py +293 -7
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/dialogs/_impl/query.py +12 -10
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_core/base.py +1 -1
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_core/container.py +63 -6
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/appshell.py +1 -1
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/card.py +1 -1
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/expander.py +2 -2
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/grid.py +1 -1
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/groupbox.py +1 -1
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/pagestack.py +1 -1
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/splitview.py +1 -1
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/tabs.py +1 -1
- {bootstack-0.3.0 → bootstack-0.3.1/src/bootstack.egg-info}/PKG-INFO +1 -1
- {bootstack-0.3.0 → bootstack-0.3.1}/LICENSE +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/MANIFEST.in +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/NOTICE +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/README.md +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/setup.cfg +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/__main__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_core/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_core/capabilities/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_core/capabilities/after.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_core/capabilities/bind.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_core/capabilities/bindtags.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_core/capabilities/busy.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_core/capabilities/clipboard.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_core/capabilities/focus.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_core/capabilities/grab.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_core/capabilities/grid.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_core/capabilities/localization.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_core/capabilities/pack.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_core/capabilities/place.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_core/capabilities/selection.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_core/capabilities/signals.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_core/capabilities/winfo.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_core/capture.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_core/colorutils.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_core/exceptions.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_core/images.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_core/mixins/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_core/mixins/ttk_state.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_core/mixins/widget.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_core/paths.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_core/publisher.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_core/variables.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_runtime/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_runtime/app.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_runtime/base_window.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_runtime/events.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_runtime/shortcuts.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_runtime/tk_patch.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_runtime/toplevel.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_runtime/utility.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_runtime/visual_focus.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_runtime/wheel.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/_runtime/window_utilities.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/bootstack.ico +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/bootstack.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/badge-pill.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/badge-square.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/button-compact.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/button-default.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/buttongroup-after-h-compact.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/buttongroup-after-h-default.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/buttongroup-after-v-compact.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/buttongroup-after-v-default.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/buttongroup-before-h-compact.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/buttongroup-before-h-default.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/buttongroup-before-v-compact.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/buttongroup-before-v-default.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/buttongroup-center-h-compact.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/buttongroup-center-h-default.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/buttongroup-center-v-compact.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/buttongroup-center-v-default.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/card.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/checkbox-checked.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/checkbox-indeterminate.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/checkbox-unchecked.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/field.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/input-addon-compact.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/input-addon-default.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/input-compact.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/input-default.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/list-item-separated.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/list-item.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/listrow-compact.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/listrow-default.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/manifest.toml +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/menu-item.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/navitem-compact.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/navitem-default.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/progressbar-h-compact.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/progressbar-h-default.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/progressbar-v-compact.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/progressbar-v-default.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/radiobutton.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/scrollbar-horizontal.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/scrollbar-vertical.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/slider-handle.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/slider-track-h.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/slider-track-v.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/switch-off.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/switch-on.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/tab-h.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/elements/tab-v.png +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/icons/bootstrap.ttf +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/icons/glyphmap.json +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/icons/icon_metrics.json +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/ar/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/ar/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/bg/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/bg/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/cs/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/cs/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/da/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/da/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/de/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/de/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/en/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/en/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/es/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/es/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/fr/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/fr/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/he/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/he/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/hi/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/hi/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/it/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/it/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/ja/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/ja/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/ko/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/ko/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/nb/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/nb/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/nl/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/nl/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/pl/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/pl/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/pt/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/pt/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/sl/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/sl/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/sv/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/sv/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/tr/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/tr/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/cli/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/cli/__main__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/cli/add.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/cli/appicon.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/cli/build.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/cli/config.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/cli/demo.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/cli/dev.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/cli/doctor.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/cli/icons.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/cli/promote.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/cli/pyinstaller.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/cli/run.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/cli/start.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/cli/templates/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/clipboard.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/constants.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/data/README.md +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/data/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/data/_observable.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/data/base.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/data/file_source.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/data/memory_source.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/data/query.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/data/readers.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/data/sqlite_source.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/data/types.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/data/writers.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/dev/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/dev/_capture.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/dev/_env.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/dev/_registry.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/dev/_reloader.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/dev/_reset.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/dev/_watcher.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/dialogs/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/dialogs/_impl/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/dialogs/_impl/colorchooser.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/dialogs/_impl/filterdialog.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/dialogs/_impl/fontdialog.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/dialogs/_impl/formdialog.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/dialogs/_impl/message.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/errors.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/events/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/events/_event.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/events/_payloads.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/events/_subscription.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/i18n/README.md +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/i18n/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/i18n/catalog.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/i18n/intl_format.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/i18n/msgcat.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/i18n/specs.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/images.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/py.typed +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/scheduling/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/scheduling/_schedule.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/shortcuts.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/signals/README.md +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/signals/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/signals/integration.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/signals/signal.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/signals/types.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/store.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/streams/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/streams/_stream.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/badge.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/button.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/buttongroup.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/calendar.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/checkbutton.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/combobox.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/contextmenu.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/entry.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/expander.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/field.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/frame.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/label.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/labelframe.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/listview.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/menubar.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/menubutton.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/panedwindow.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/progressbar.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/radiobutton.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/scale.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/scrollbar.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/separator.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/sidenav.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/sizegrip.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/spinbox.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/switch.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/tabitem.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/togglegroup.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/toolbutton.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/tooltip.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/treeview.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders/utils.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders_tk/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/builders_tk/defaults.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/element.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/fonts.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/style.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/style_builder_base.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/style_builder_mixed.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/style_builder_tk.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/style_builder_ttk.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/style_resolver.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/theme.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/theme_provider.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/themes/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/tk_patch.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/token_maps.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/types.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/typography.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/style/utility.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/types.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/validation/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/validation/types.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/validation/validation_result.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/validation/validation_rules.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_core/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_core/app_config.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_core/choices.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_core/context.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_core/events.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_core/field_mixin.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_core/icon_image_props.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_core/image_binding.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_core/kwargs.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_core/navmodel.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_core/options.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_core/selection_group.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_core/window_controls.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_core/window_menu.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/_internal/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/_internal/wrapper_base.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/_parts/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/_parts/numberentry_part.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/_parts/spinnerentry_part.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/_parts/textentry_part.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/_dateutils.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/_image_fit.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/accordion.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/avatar.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/buttongroup.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/calendar.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/carousel.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/chart.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/compositeframe.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/contextmenu.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/dateentry.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/dropdownbutton.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/expander.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/field.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/form.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/gallery.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/list/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/list/listitem.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/list/listview.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/menu/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/menu/model.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/menu/render_native.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/menu/render_themed.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/meter.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/numericentry.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/pagestack.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/passwordentry.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/pathentry.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/picture.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/radiogroup.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/scrolledtext.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/scrolledtext.pyi +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/scrollview.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/selectbox.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/shell/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/shell/content_host.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/shell/layout.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/shell/nav_panel.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/shell/providers.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/shell/rail.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/shell/shell.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/shell/workspace.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/sidenav/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/sidenav/header.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/sidenav/separator.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/slider/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/slider/_shared.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/slider/rangeslider.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/slider/slider.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/spinnerentry.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/tableview/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/tableview/tableview.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/tableview/types.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/tabs/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/tabs/tabitem.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/tabs/tabs.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/tabs/tabview.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/textarea/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/textarea/change.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/textarea/codeeditor.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/textarea/core.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/textarea/decoration.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/textarea/diff.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/textarea/extensions/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/textarea/extensions/bracket_matcher.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/textarea/extensions/indent_guides.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/textarea/extensions/line_numbers.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/textarea/extensions/pygments_highlighter.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/textarea/extensions/smart_indent.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/textarea/filter.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/textarea/redirector.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/textarea/search_overlay.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/textarea/sidebar.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/textarea/style_registry.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/textarea/textarea.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/textarea/undo.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/textentry.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/timeentry.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/toast.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/toast_stack.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/togglegroup.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/toolbar.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/tooltip.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/tree/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/tree/source_binding.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/tree/treeitem.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/tree/treenode.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/composites/tree/treeview.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/mixins/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/mixins/configure_mixin.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/mixins/entry_mixin.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/mixins/font_mixin.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/mixins/icon_mixin.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/mixins/localization_mixin.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/mixins/signal_mixin.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/mixins/validation_mixin.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/primitives/__init__.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/primitives/_menubutton.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/primitives/badge.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/primitives/button.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/primitives/card.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/primitives/checkbutton.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/primitives/checktoggle.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/primitives/combobox.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/primitives/entry.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/primitives/flexframe.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/primitives/frame.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/primitives/gridframe.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/primitives/label.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/primitives/labelframe.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/primitives/optionmenu.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/primitives/packframe.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/primitives/panedwindow.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/primitives/progressbar.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/primitives/radiobutton.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/primitives/radiotoggle.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/primitives/scrollbar.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/primitives/separator.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/primitives/sizegrip.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/primitives/spinbox.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/primitives/switch.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/_impl/primitives/treeview.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/app.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/avatar.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/boolean_controls.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/button.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/buttongroup.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/calendar.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/carousel.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/chart.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/codeeditor.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/contextmenu.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/datatable.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/datefield.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/divider.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/form.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/gallery.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/gauge.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/label.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/listview.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/menubutton.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/numberfield.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/passwordfield.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/pathfield.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/picture.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/progressbar.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/radio_variants.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/radiogroup.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/scrollbar.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/scrollview.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/select.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/selectbutton.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/sidebar_toggle.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/sizegrip.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/slider.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/spinbox.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/spinnerfield.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/splash.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/stacks.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/statusbar.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/textarea.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/textfield.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/theme_toggle.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/timefield.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/toast.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/togglegroup.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/toolbar.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/tooltip.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/tree.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/types.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack/widgets/window.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack.egg-info/SOURCES.txt +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack.egg-info/dependency_links.txt +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack.egg-info/entry_points.txt +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack.egg-info/requires.txt +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/src/bootstack.egg-info/top_level.txt +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/tests/test_dialog_anchor.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/tests/test_events_doc_coverage.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/tests/test_hot_reload.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/tests/test_images.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/tests/test_images_gui.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/tests/test_intl_format.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/tests/test_navmodel.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/tests/test_on_color_contrast.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/tests/test_public_surface.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/tests/test_store.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/tests/test_theme_from_existing.py +0 -0
- {bootstack-0.3.0 → bootstack-0.3.1}/tests/test_validation_rules.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bootstack
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: Build desktop GUI apps in pure Python and ship them as a standalone executable — built on Tk, no Tkinter boilerplate.
|
|
5
5
|
Author-email: Israel Dryer <israel.dryer@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "bootstack"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.1"
|
|
8
8
|
description = "Build desktop GUI apps in pure Python and ship them as a standalone executable — built on Tk, no Tkinter boilerplate."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.12"
|
|
@@ -114,7 +114,7 @@ where = ["src"]
|
|
|
114
114
|
]
|
|
115
115
|
|
|
116
116
|
[tool.bumpversion]
|
|
117
|
-
current_version = "0.3.
|
|
117
|
+
current_version = "0.3.1"
|
|
118
118
|
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)((?P<pre>a|b|rc)(?P<pre_n>\\d+))?"
|
|
119
119
|
serialize = [
|
|
120
120
|
"{major}.{minor}.{patch}{pre}{pre_n}",
|
|
@@ -16,7 +16,8 @@ from bootstack.widgets._impl.primitives import Frame
|
|
|
16
16
|
from bootstack.constants import BOTH, YES
|
|
17
17
|
from bootstack.events import Subscription
|
|
18
18
|
from bootstack.dialogs._impl.dialog import (
|
|
19
|
-
DIALOG_RESULT, Dialog, DialogButton, emit_dialog_result,
|
|
19
|
+
DIALOG_RESULT, Dialog, DialogButton, capture_grab, emit_dialog_result, restore_grab,
|
|
20
|
+
result_target,
|
|
20
21
|
)
|
|
21
22
|
from bootstack._runtime.window_utilities import AnchorPoint
|
|
22
23
|
from bootstack.widgets._impl.composites.calendar import Calendar
|
|
@@ -78,6 +79,22 @@ class _ChromeDialog(Dialog):
|
|
|
78
79
|
self._build_content()
|
|
79
80
|
self._build_footer()
|
|
80
81
|
|
|
82
|
+
# This override duplicates `Dialog.show()` rather than extending it, so
|
|
83
|
+
# the initial-focus resolution has to be repeated here — see
|
|
84
|
+
# `Dialog._focus_when_mapped` (issue #439).
|
|
85
|
+
#
|
|
86
|
+
# This reaches only RANGE mode. Single-date mode commits the moment a
|
|
87
|
+
# date is clicked and so builds no footer buttons (see `__init__`),
|
|
88
|
+
# leaving `_default_button` None; nothing sets `_focus_target` for the
|
|
89
|
+
# raw calendar content either. So `ask_date()` still opens with focus on
|
|
90
|
+
# the toplevel itself, exactly as before — measured, not assumed. Giving
|
|
91
|
+
# the single-date calendar a real focus target is a separate change,
|
|
92
|
+
# since it would put a focus ring on a day cell and make the arrow keys
|
|
93
|
+
# move the selection.
|
|
94
|
+
focus_target = self._focus_target or self._default_button
|
|
95
|
+
if focus_target is not None:
|
|
96
|
+
self._focus_when_mapped(focus_target)
|
|
97
|
+
|
|
81
98
|
self._position_dialog(
|
|
82
99
|
position=position,
|
|
83
100
|
anchor_to=anchor_to,
|
|
@@ -110,9 +127,17 @@ class _ChromeDialog(Dialog):
|
|
|
110
127
|
if modal:
|
|
111
128
|
# transient() is already called in Dialog._create_toplevel()
|
|
112
129
|
# Don't call it again here as it breaks mica effect on Windows
|
|
130
|
+
previous_grab = None
|
|
113
131
|
if self._mode == "modal":
|
|
132
|
+
# Remember who held the grab, and how, so it can be handed back
|
|
133
|
+
# — a nested modal must not leave its opener non-modal (#440),
|
|
134
|
+
# nor narrow an app-modal window to a local grab.
|
|
135
|
+
previous_grab = capture_grab(self._toplevel)
|
|
114
136
|
self._toplevel.grab_set()
|
|
115
|
-
|
|
137
|
+
try:
|
|
138
|
+
self._master.wait_window(self._toplevel)
|
|
139
|
+
finally:
|
|
140
|
+
restore_grab(previous_grab)
|
|
116
141
|
|
|
117
142
|
def _on_focus_out(self, event: tkinter.Event):
|
|
118
143
|
if self._suppress_focus_out:
|
|
@@ -182,6 +182,187 @@ def emit_dialog_result(target: Optional[tkinter.Misc], payload: dict) -> None:
|
|
|
182
182
|
|
|
183
183
|
# --- Dialog ----------------------------------------------------------------
|
|
184
184
|
|
|
185
|
+
def capture_grab(widget: Any) -> tuple[Any, str | None] | None:
|
|
186
|
+
"""Record who holds the modal grab and HOW, for `restore_grab` to hand back.
|
|
187
|
+
|
|
188
|
+
Returns `None` when nothing holds the grab — the outermost case, which needs
|
|
189
|
+
no restore. Otherwise returns the holder paired with its grab KIND.
|
|
190
|
+
|
|
191
|
+
⚠ Call this BEFORE taking the grab. Once another window grabs, the previous
|
|
192
|
+
holder's `grab_status()` reads `None`, so a kind read afterwards is always
|
|
193
|
+
wrong — measured, and the reason this pairing exists as one function rather
|
|
194
|
+
than two steps a caller has to sequence correctly.
|
|
195
|
+
|
|
196
|
+
The kind matters because Tk has two: `bs.Window(modal="app")` takes a GLOBAL
|
|
197
|
+
grab, and restoring that as a local one silently narrows the window's
|
|
198
|
+
modality (it would block only this application). Reading the kind back from
|
|
199
|
+
Tk rather than assuming it keeps this correct on every window system without
|
|
200
|
+
a platform branch — whatever Tk reported, we hand back.
|
|
201
|
+
"""
|
|
202
|
+
holder = widget.grab_current()
|
|
203
|
+
if holder is None:
|
|
204
|
+
return None
|
|
205
|
+
try:
|
|
206
|
+
kind = holder.grab_status()
|
|
207
|
+
except (AttributeError, tkinter.TclError):
|
|
208
|
+
# Fall back to the narrower grab rather than guessing global.
|
|
209
|
+
kind = "local"
|
|
210
|
+
return (holder, kind)
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def restore_grab(previous: tuple[Any, str | None] | None) -> None:
|
|
214
|
+
"""Hand the modal grab back to whatever held it before this dialog took it.
|
|
215
|
+
|
|
216
|
+
Tk releases a grab when the window holding it is destroyed, but it does NOT
|
|
217
|
+
restore the grab that window displaced. So a modal opened from inside
|
|
218
|
+
another modal — `bs.alert()` from a dialog button command, or
|
|
219
|
+
`QueryDialog._on_submit` — took the grab over and then dropped it on the
|
|
220
|
+
floor when it closed. The OUTER dialog was left on screen and still
|
|
221
|
+
blocking its caller inside `show()`, yet holding no grab at all: the user
|
|
222
|
+
could click straight back into the main window and drive the app
|
|
223
|
+
underneath it, against a dialog that was modal in appearance only
|
|
224
|
+
(issue #440).
|
|
225
|
+
|
|
226
|
+
Pass the token `capture_grab()` returned. `None` means nothing held the
|
|
227
|
+
grab, which is the outermost case and needs no restore.
|
|
228
|
+
|
|
229
|
+
A failure here is deliberately swallowed. This runs on a teardown path,
|
|
230
|
+
where the previous holder may itself have been destroyed while the inner
|
|
231
|
+
dialog was up, or the whole interpreter may be going down — and a dialog
|
|
232
|
+
that has already closed must not raise on its way out. It is LOGGED rather
|
|
233
|
+
than passed over in silence, because a failed restore is the very defect
|
|
234
|
+
this function exists to prevent (#440): the outer dialog stays on screen
|
|
235
|
+
holding nothing.
|
|
236
|
+
|
|
237
|
+
⚠ A global restore can fail where a local one cannot — `grab set -global`
|
|
238
|
+
is the call Tk's viewability rule guards, and on X11 it can also lose to
|
|
239
|
+
another client. That is the one way this is riskier than always restoring
|
|
240
|
+
a local grab, so a failed global restore DEGRADES TO LOCAL rather than to
|
|
241
|
+
nothing: modal within the application is imperfect, but it is not the #440
|
|
242
|
+
symptom.
|
|
243
|
+
"""
|
|
244
|
+
if previous is None:
|
|
245
|
+
return
|
|
246
|
+
holder, kind = previous
|
|
247
|
+
try:
|
|
248
|
+
if not holder.winfo_exists():
|
|
249
|
+
return
|
|
250
|
+
if kind == "global":
|
|
251
|
+
try:
|
|
252
|
+
holder.grab_set_global()
|
|
253
|
+
except tkinter.TclError:
|
|
254
|
+
_log_grab_failure("could not restore a global grab; falling back to local")
|
|
255
|
+
holder.grab_set()
|
|
256
|
+
else:
|
|
257
|
+
holder.grab_set()
|
|
258
|
+
except (AttributeError, tkinter.TclError):
|
|
259
|
+
_log_grab_failure("could not restore the previous dialog's grab")
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
def _log_grab_failure(message: str) -> None:
|
|
263
|
+
"""Report a grab failure without ever raising from a teardown path."""
|
|
264
|
+
from bootstack._runtime.utility import debug_log_exception
|
|
265
|
+
|
|
266
|
+
debug_log_exception(message)
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
# Bindtags whose widgets treat Enter as CONTENT rather than as a command.
|
|
270
|
+
# `Text` is Tk's multi-line text class, which `TextArea` and `CodeEditor` are
|
|
271
|
+
# both built on — naming the class covers them, and anything else Text-backed,
|
|
272
|
+
# without listing widgets.
|
|
273
|
+
_ENTER_IS_CONTENT = frozenset({"Text"})
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
def _key_was_consumed(widget: Any, keysym: str) -> bool:
|
|
277
|
+
"""Did `widget` already answer this Enter key by the time it reached us?
|
|
278
|
+
|
|
279
|
+
A dialog binds Return on its TOPLEVEL so the default button can be pressed
|
|
280
|
+
from an input field. The toplevel is last in the bindtag walk, so by the
|
|
281
|
+
time that binding runs a widget-level or class-level handler has already
|
|
282
|
+
had the key — and firing the default button on top of it either invokes the
|
|
283
|
+
same button twice or runs the default button's command over the one the
|
|
284
|
+
user actually pressed.
|
|
285
|
+
|
|
286
|
+
Two kinds of widget answer Enter, and the rule names the intent rather than
|
|
287
|
+
inferring it:
|
|
288
|
+
|
|
289
|
+
* a **button** invokes. bootstack installs `TButton <Key-Return>` ->
|
|
290
|
+
`button_default_binding` at app construction (`_runtime/app.py:151`).
|
|
291
|
+
* a **multi-line text widget** inserts a newline. That is issue #441: the
|
|
292
|
+
newline went in and the dialog then closed on top of it, because the
|
|
293
|
+
guard recognized only buttons.
|
|
294
|
+
|
|
295
|
+
In both cases a DISABLED widget is the exception: its class binding runs
|
|
296
|
+
but does nothing — `invoke` is a no-op on a disabled button, and
|
|
297
|
+
`tk::TextInsert` returns early on a disabled text (both measured,
|
|
298
|
+
`development/probe_441_key_already_handled.py`). Nothing answered the key,
|
|
299
|
+
so the default button should still get it. Standing down there would leave
|
|
300
|
+
the keyboard dead for the whole dialog.
|
|
301
|
+
|
|
302
|
+
⚠ THE KEY MATTERS, NOT ONLY THE WIDGET — which is why `keysym` is required
|
|
303
|
+
rather than defaulted. The two Enter keys are equivalent to a button and are
|
|
304
|
+
NOT equivalent to a text widget. Measured against the live binding table:
|
|
305
|
+
|
|
306
|
+
TButton <Key-Return> -> button_default_binding
|
|
307
|
+
TButton <Key-KP_Enter> -> button_default_binding (both, app.py:150)
|
|
308
|
+
Text <Key-Return> -> tk::TextInsert
|
|
309
|
+
Text <Key-KP_Enter> -> '# nothing'
|
|
310
|
+
|
|
311
|
+
Tk binds `Text <KP_Enter>` to the literal script `# nothing`
|
|
312
|
+
(`tk8.6/text.tcl:308`, unconditional — it is in the block that stops the
|
|
313
|
+
generic `<Key>` binding inserting `%A`, which for that key is `\r` rather
|
|
314
|
+
than `\n`). So wherever the keypad key arrives as its own keysym a text
|
|
315
|
+
widget inserts NOTHING, and reporting it consumed would leave that key dead
|
|
316
|
+
for the whole dialog. Windows never reaches this: it FOLDS the keypad key
|
|
317
|
+
into `Return` (see the binding site below), so `keysym` is `Return` there
|
|
318
|
+
and the text branch behaves as it always has. X11 reports `KP_Enter`
|
|
319
|
+
separately and is the case this scoping exists for. Aqua is unmeasured and
|
|
320
|
+
needs no measurement — both of its possible answers are handled.
|
|
321
|
+
|
|
322
|
+
⚠ The text branch tests `keysym != "KP_Enter"` rather than
|
|
323
|
+
`keysym == "Return"`, deliberately. An unrecognized keysym then reads as
|
|
324
|
+
CONSUMED, which is the conservative answer for a text widget: standing down
|
|
325
|
+
wrongly costs a dead key, while firing wrongly costs #441 itself — the
|
|
326
|
+
dialog closing on top of a newline the user just typed. The button branch
|
|
327
|
+
has no such asymmetry, both keys invoking there.
|
|
328
|
+
|
|
329
|
+
⚠ INTERROGATING THE BINDINGS INSTEAD WAS TRIED AND IS WRONG — do not
|
|
330
|
+
re-propose it as the "general" rule. Asking whether any bindtag carries a
|
|
331
|
+
real binding for the key looks principled and misclassifies the control:
|
|
332
|
+
bootstack's own `TextField` binds `<Return>` as an instance binding to emit
|
|
333
|
+
its `submit` event, so a plain entry reads as "already handled" and
|
|
334
|
+
`ask_string()` stops submitting. Tk also binds `TEntry <Return>` to the
|
|
335
|
+
literal script `# nothing`, so a non-empty script does not mean the key was
|
|
336
|
+
handled either. Binding inspection cannot separate binds-to-notify from
|
|
337
|
+
binds-to-consume; the class name is where that intent is recorded.
|
|
338
|
+
"""
|
|
339
|
+
try:
|
|
340
|
+
tags = {str(tag) for tag in widget.bindtags()}
|
|
341
|
+
except (AttributeError, tkinter.TclError):
|
|
342
|
+
# Nothing identifiable answered the key, so let the default button run
|
|
343
|
+
# rather than silently swallowing Enter for the whole dialog.
|
|
344
|
+
return False
|
|
345
|
+
|
|
346
|
+
if "TButton" in tags:
|
|
347
|
+
try:
|
|
348
|
+
return not widget.instate(["disabled"])
|
|
349
|
+
except (AttributeError, tkinter.TclError):
|
|
350
|
+
return True
|
|
351
|
+
|
|
352
|
+
if tags & _ENTER_IS_CONTENT:
|
|
353
|
+
if keysym == "KP_Enter":
|
|
354
|
+
# `Text <KP_Enter>` is the literal script `# nothing`, so nothing
|
|
355
|
+
# was inserted whatever the widget's state — the default button
|
|
356
|
+
# should still get the key rather than it dying here.
|
|
357
|
+
return False
|
|
358
|
+
try:
|
|
359
|
+
return str(widget.cget("state")) == "normal"
|
|
360
|
+
except (AttributeError, tkinter.TclError):
|
|
361
|
+
return True
|
|
362
|
+
|
|
363
|
+
return False
|
|
364
|
+
|
|
365
|
+
|
|
185
366
|
class Dialog:
|
|
186
367
|
"""A flexible dialog window using the builder pattern.
|
|
187
368
|
|
|
@@ -283,6 +464,13 @@ class Dialog:
|
|
|
283
464
|
self._footer: _Frame | None = None
|
|
284
465
|
self._border_frame: _Frame | None = None
|
|
285
466
|
|
|
467
|
+
# Who gets focus when the window comes up. `_focus_target` is the
|
|
468
|
+
# override a content builder can claim (QueryDialog's entry); the
|
|
469
|
+
# default button is the fallback. Resolved once in `show()`, after
|
|
470
|
+
# content is built, so the two cannot race — see `_focus_when_mapped`.
|
|
471
|
+
self._default_button: _Button | None = None
|
|
472
|
+
self._focus_target: Widget | None = None
|
|
473
|
+
|
|
286
474
|
self.result: Any = None
|
|
287
475
|
|
|
288
476
|
# --------------------------------------------------------------- API
|
|
@@ -333,6 +521,16 @@ class Dialog:
|
|
|
333
521
|
self._create_toplevel(modal=modal)
|
|
334
522
|
self._build_footer()
|
|
335
523
|
self._build_content()
|
|
524
|
+
|
|
525
|
+
# Resolve initial focus once, now that both halves exist. A content
|
|
526
|
+
# widget that claimed `_focus_target` wins; otherwise the default
|
|
527
|
+
# button takes it, which is what `DialogButton.default` promises.
|
|
528
|
+
# Deferred to <Map> because the window is still withdrawn here and
|
|
529
|
+
# `focus_set()` is a silent no-op until it is not (issue #439).
|
|
530
|
+
focus_target = self._focus_target or self._default_button
|
|
531
|
+
if focus_target is not None:
|
|
532
|
+
self._focus_when_mapped(focus_target)
|
|
533
|
+
|
|
336
534
|
self._position_dialog(
|
|
337
535
|
position=position,
|
|
338
536
|
anchor_to=_resolve_anchor_target(anchor_to),
|
|
@@ -353,9 +551,18 @@ class Dialog:
|
|
|
353
551
|
# sheet window class; calling grab_set on top of that is fine
|
|
354
552
|
# but unnecessary. Plain modal mode still uses grab to block
|
|
355
553
|
# interaction with the parent on platforms without a sheet.
|
|
554
|
+
previous_grab = None
|
|
356
555
|
if self._mode in ("modal", "sheet"):
|
|
556
|
+
# Remember who held the grab, and how, so it can be handed back
|
|
557
|
+
# — a nested modal must not leave its opener non-modal (#440),
|
|
558
|
+
# nor narrow an app-modal window to a local grab. Captured
|
|
559
|
+
# before grab_set(), which is the only order that works.
|
|
560
|
+
previous_grab = capture_grab(self._toplevel)
|
|
357
561
|
self._toplevel.grab_set()
|
|
358
|
-
|
|
562
|
+
try:
|
|
563
|
+
self._master.wait_window(self._toplevel)
|
|
564
|
+
finally:
|
|
565
|
+
restore_grab(previous_grab)
|
|
359
566
|
|
|
360
567
|
@property
|
|
361
568
|
def toplevel(self) -> Toplevel | None:
|
|
@@ -541,7 +748,10 @@ class Dialog:
|
|
|
541
748
|
return
|
|
542
749
|
|
|
543
750
|
if default_button is not None:
|
|
544
|
-
|
|
751
|
+
# Recorded, not focused here: `show()` resolves focus after the
|
|
752
|
+
# content is built, so a content widget asking for initial focus
|
|
753
|
+
# is not overruled by build order (issue #439).
|
|
754
|
+
self._default_button = default_button
|
|
545
755
|
top = self._toplevel
|
|
546
756
|
|
|
547
757
|
def press_default(event: Any, b: Any = default_button) -> None:
|
|
@@ -563,18 +773,46 @@ class Dialog:
|
|
|
563
773
|
leave the keyboard dead for the whole dialog — which is what a
|
|
564
774
|
content button that greys itself out on click would cause.
|
|
565
775
|
|
|
776
|
+
A multi-line text widget answers Enter too, by inserting a
|
|
777
|
+
newline, and standing down for it is issue #441 — the newline
|
|
778
|
+
went in and the dialog closed on top of it. `_key_was_consumed`
|
|
779
|
+
owns that decision for both kinds of widget.
|
|
780
|
+
|
|
781
|
+
It is handed the KEYSYM as well as the widget because a text
|
|
782
|
+
widget answers only the main Enter key: Tk binds its keypad
|
|
783
|
+
twin to a no-op script, so standing down for that one would
|
|
784
|
+
leave it dead. A button answers both.
|
|
785
|
+
|
|
566
786
|
The remaining case is the one this binding exists for — focus
|
|
567
787
|
in an entry, as in `QueryDialog`, where nothing else would
|
|
568
788
|
answer the key.
|
|
569
789
|
"""
|
|
570
|
-
|
|
571
|
-
if "TButton" in pressed.bindtags() and not pressed.instate(["disabled"]):
|
|
790
|
+
if _key_was_consumed(event.widget, event.keysym):
|
|
572
791
|
return
|
|
573
792
|
b.invoke()
|
|
574
793
|
|
|
575
|
-
# The keypad Enter key
|
|
576
|
-
#
|
|
577
|
-
#
|
|
794
|
+
# The keypad Enter key needs its own binding to reach the default
|
|
795
|
+
# button from an input field -- but only where the window system
|
|
796
|
+
# reports it separately, which is NOT everywhere. Measured with a
|
|
797
|
+
# real keypress, alternating against the main Enter key as a
|
|
798
|
+
# control (`development/probe_441_kp_enter_platform.py`):
|
|
799
|
+
#
|
|
800
|
+
# * Windows FOLDS it into `Return` -- keysym `Return`, keycode 13,
|
|
801
|
+
# char `\r`, byte-identical to the main Enter key -- so this
|
|
802
|
+
# binding never fires there. Synthesis is no help either: win32
|
|
803
|
+
# cannot map the keysym back to a keycode and `event_generate`
|
|
804
|
+
# delivers keysym `??` with keycode 0, matching no binding at
|
|
805
|
+
# all. Both routes to this path are closed on Windows, so no
|
|
806
|
+
# test there can cover it.
|
|
807
|
+
# * X11 reports `KP_Enter` as a distinct keysym. That is the case
|
|
808
|
+
# this binding exists for.
|
|
809
|
+
# * Aqua is unmeasured.
|
|
810
|
+
#
|
|
811
|
+
# Binding both is harmless where the two coincide. Where they do
|
|
812
|
+
# NOT, the keysym is threaded into `_key_was_consumed` so a text
|
|
813
|
+
# widget stands down only for the key it actually inserts for --
|
|
814
|
+
# Tk's `Text <KP_Enter>` is a no-op script, so treating the two
|
|
815
|
+
# alike would kill the keypad key inside a dialog TextArea.
|
|
578
816
|
for key in ("<Return>", "<KP_Enter>"):
|
|
579
817
|
self._toplevel.bind(key, press_default)
|
|
580
818
|
|
|
@@ -583,6 +821,54 @@ class Dialog:
|
|
|
583
821
|
else:
|
|
584
822
|
self._toplevel.bind("<Escape>", lambda e: self._toplevel.destroy())
|
|
585
823
|
|
|
824
|
+
@staticmethod
|
|
825
|
+
def _focus_when_mapped(widget: Widget) -> None:
|
|
826
|
+
"""Focus `widget` once it is actually mapped.
|
|
827
|
+
|
|
828
|
+
`focus_set()` is a SILENT no-op while the widget's toplevel is
|
|
829
|
+
withdrawn: `TkSetFocusWin` walks the ancestry and returns without
|
|
830
|
+
setting anything, reporting nothing. Footer buttons are built from
|
|
831
|
+
`_build_footer`, which runs while `_create_toplevel` still has the
|
|
832
|
+
window withdrawn, so focusing the default button there never took —
|
|
833
|
+
`focus_lastfor()` kept naming the toplevel, leaving keyboard users
|
|
834
|
+
with no focus ring and a Tab order starting from nowhere, in a dialog
|
|
835
|
+
documented as focusing its default button (issue #439).
|
|
836
|
+
|
|
837
|
+
Waiting for the widget's own `<Map>` states that precondition instead
|
|
838
|
+
of guessing a delay. Measured on Windows
|
|
839
|
+
(`development/probe_439_focus_timing.py`): the button is still
|
|
840
|
+
unmapped once `deiconify()` AND `update_idletasks()` have both
|
|
841
|
+
returned, so neither is a usable barrier. Asking after the toplevel is
|
|
842
|
+
deiconified happens to work — Tk defers a request made against a
|
|
843
|
+
mapped toplevel — but that deferral is a Tk implementation detail and
|
|
844
|
+
window managers map asynchronously, so the explicit wait is what
|
|
845
|
+
travels off this box.
|
|
846
|
+
|
|
847
|
+
Binding on the widget rather than scheduling on the root is
|
|
848
|
+
deliberate: a `<Map>` binding is torn down with the widget it is on,
|
|
849
|
+
so a dialog closed before it ever maps leaves nothing pending. An
|
|
850
|
+
`after` timer would outlive the widget and fire as an orphan.
|
|
851
|
+
"""
|
|
852
|
+
if widget.winfo_ismapped():
|
|
853
|
+
widget.focus_set()
|
|
854
|
+
return
|
|
855
|
+
|
|
856
|
+
def on_map(_event: Any = None) -> None:
|
|
857
|
+
# One-shot: the default button should not reclaim focus every time
|
|
858
|
+
# the dialog is unmapped and remapped (minimize/restore), which
|
|
859
|
+
# would yank focus off whatever the user had tabbed to.
|
|
860
|
+
try:
|
|
861
|
+
widget.unbind("<Map>", bind_id)
|
|
862
|
+
except tkinter.TclError:
|
|
863
|
+
pass
|
|
864
|
+
try:
|
|
865
|
+
if widget.winfo_exists():
|
|
866
|
+
widget.focus_set()
|
|
867
|
+
except tkinter.TclError:
|
|
868
|
+
pass
|
|
869
|
+
|
|
870
|
+
bind_id = widget.bind("<Map>", on_map, add="+")
|
|
871
|
+
|
|
586
872
|
def _position_dialog(
|
|
587
873
|
self,
|
|
588
874
|
position: Optional[Tuple[int, int]] = None,
|
|
@@ -161,16 +161,18 @@ class QueryDialog:
|
|
|
161
161
|
# anyway: focus goes to `entry.entry_widget`, and the composite frame is
|
|
162
162
|
# not in that widget's bindtags, so Tk would never reach it.
|
|
163
163
|
|
|
164
|
-
#
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
#
|
|
173
|
-
|
|
164
|
+
# Claim initial focus for the entry, so the user can type straight
|
|
165
|
+
# away. `Dialog` applies this once the window is mapped, in preference
|
|
166
|
+
# to the default button.
|
|
167
|
+
#
|
|
168
|
+
# This used to be a bare `focus_set()` plus an `after_idle` repeat to
|
|
169
|
+
# "ensure focus after dialog buttons set their own focus". Both ran
|
|
170
|
+
# while the toplevel was still withdrawn, where `focus_set()` is a
|
|
171
|
+
# silent no-op, so neither ever took and the entry was never actually
|
|
172
|
+
# focused — measured in `development/probe_439_default_button_focus.py`
|
|
173
|
+
# against pre-fix code, where focus sat on the toplevel. Handing the
|
|
174
|
+
# target to `Dialog` replaces the race with an ordering (issue #439).
|
|
175
|
+
self._dialog._focus_target = getattr(entry, "entry_widget", entry)
|
|
174
176
|
|
|
175
177
|
frame.pack(fill=X, expand=True)
|
|
176
178
|
self._entry_widget = entry
|
|
@@ -492,7 +492,7 @@ class PublicWidgetBase:
|
|
|
492
492
|
if placement.method == "flex":
|
|
493
493
|
index = kwargs.pop("index", placement.index)
|
|
494
494
|
if kwargs:
|
|
495
|
-
_reject_legacy_child_kwargs(kwargs, type(self).__name__)
|
|
495
|
+
_reject_legacy_child_kwargs(kwargs, type(self).__name__, "flex child")
|
|
496
496
|
_expand_margin(kwargs)
|
|
497
497
|
options.update(_flex_child_opts(self, kwargs))
|
|
498
498
|
master.add_child(self._internal, options, index=index)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import tkinter
|
|
4
|
-
from typing import Any
|
|
4
|
+
from typing import Any, Literal
|
|
5
5
|
|
|
6
6
|
PACK_KEYS = frozenset({
|
|
7
7
|
"side", "fill", "expand", "anchor",
|
|
@@ -218,16 +218,73 @@ class PublicContainer(PublicWidgetBase):
|
|
|
218
218
|
# --- Flex engine (Row / Column) --------------------------------------------
|
|
219
219
|
|
|
220
220
|
|
|
221
|
-
|
|
222
|
-
|
|
221
|
+
# Per-child keys a GRID CELL honors. `grow=` is deliberately ABSENT: Grid and
|
|
222
|
+
# the page/pane containers filter their child options to GRID_KEYS, so a `grow=`
|
|
223
|
+
# written on one of their children is silently dropped. `sticky`/`in_` are not
|
|
224
|
+
# user-facing — `sticky` is a legacy key the guard below rejects, and the cell
|
|
225
|
+
# derives it from `horizontal`/`vertical` instead.
|
|
226
|
+
GRID_CHILD_KEYS = (GRID_KEYS | {"horizontal", "vertical"}) - {"sticky", "in_"}
|
|
227
|
+
|
|
228
|
+
_ALIGN_ADVICE = (
|
|
229
|
+
"horizontal= takes left/center/right/stretch and vertical= takes "
|
|
230
|
+
"top/center/bottom/stretch (for example horizontal=\"stretch\")"
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
# The remedy depends on HOW the container places its children, and naming the
|
|
234
|
+
# wrong one is the defect this message exists to fix (issue #426). A flex
|
|
235
|
+
# container honors `grow=` on the child; a grid cell drops it, so recommending
|
|
236
|
+
# it there would send the user to a kwarg that does nothing — the same silent
|
|
237
|
+
# no-op #426 was filed about, just one step further along.
|
|
238
|
+
FLEX_CHILD_ADVICE = (
|
|
239
|
+
"Use grow= to claim leftover space along the stacking axis, or "
|
|
240
|
+
"horizontal=/vertical= to align or stretch across it — " + _ALIGN_ADVICE
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
# Container-level options are named WITHOUT a trailing `=` on purpose: the `X=`
|
|
244
|
+
# spelling is reserved for per-child remedies, which is what the regression test
|
|
245
|
+
# checks must be real keys.
|
|
246
|
+
GRID_CHILD_ADVICE = (
|
|
247
|
+
"Use horizontal=/vertical= to align or stretch the child inside its cell — "
|
|
248
|
+
+ _ALIGN_ADVICE
|
|
249
|
+
+ ". Leftover space is claimed by weighting the row or column on the "
|
|
250
|
+
"container (its columns/rows arguments), not by a kwarg on the child"
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
# The kind names the child's PLACEMENT, not its parent class: the dual-mode
|
|
254
|
+
# containers (Card/GroupBox/Expander/AccordionSection) are one or the other
|
|
255
|
+
# depending on their `layout=`, and the page/pane containers are grid cells
|
|
256
|
+
# without a `Grid` anywhere in sight.
|
|
257
|
+
ChildKind = Literal["flex child", "grid cell"]
|
|
258
|
+
|
|
259
|
+
_CHILD_ADVICE: dict[str, str] = {
|
|
260
|
+
"flex child": FLEX_CHILD_ADVICE,
|
|
261
|
+
"grid cell": GRID_CHILD_ADVICE,
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def _reject_legacy_child_kwargs(layout_kw: dict, where: str, kind: ChildKind) -> None:
|
|
266
|
+
"""Raise on legacy pack/grid placement kwargs passed to a laid-out child.
|
|
267
|
+
|
|
268
|
+
Args:
|
|
269
|
+
layout_kw: the split-out layout kwargs to inspect.
|
|
270
|
+
where: the call site named in the message.
|
|
271
|
+
kind: how this container places the child — `'flex child'` or
|
|
272
|
+
`'grid cell'`. It selects the remedy, and the two differ: a grid
|
|
273
|
+
cell drops `grow=`, so recommending it there is the silent no-op
|
|
274
|
+
issue #426 exists to remove. Required rather than defaulted,
|
|
275
|
+
because a default hands the wrong advice to any caller who forgets
|
|
276
|
+
— which is how four call sites kept the defect through its own fix.
|
|
277
|
+
"""
|
|
223
278
|
bad = _LEGACY_CHILD_KEYS & layout_kw.keys()
|
|
224
279
|
if bad:
|
|
225
280
|
from bootstack.errors import BootstackError
|
|
226
281
|
|
|
282
|
+
# KeyError on an unknown kind is deliberate: a mistyped kind must fail
|
|
283
|
+
# loudly here rather than quietly pick a remedy for the other engine.
|
|
284
|
+
advice = _CHILD_ADVICE[kind]
|
|
227
285
|
raise BootstackError(
|
|
228
286
|
f"{where}: {', '.join(sorted(bad))} is not a valid layout option for "
|
|
229
|
-
f"a
|
|
230
|
-
f"in a Grid) instead — see the layout guide."
|
|
287
|
+
f"a {kind}. {advice} — see the layout guide."
|
|
231
288
|
)
|
|
232
289
|
|
|
233
290
|
|
|
@@ -376,7 +433,7 @@ def place_flex_child(
|
|
|
376
433
|
child._placement = Placement("place", frame, options)
|
|
377
434
|
return
|
|
378
435
|
|
|
379
|
-
_reject_legacy_child_kwargs(layout_kw, where)
|
|
436
|
+
_reject_legacy_child_kwargs(layout_kw, where, "flex child")
|
|
380
437
|
_expand_margin(layout_kw)
|
|
381
438
|
index = layout_kw.get("index")
|
|
382
439
|
opts = _flex_child_opts(child, layout_kw)
|
|
@@ -106,7 +106,7 @@ class Page:
|
|
|
106
106
|
|
|
107
107
|
def guide_layout(self, child: Any, **layout_kw: Any) -> None:
|
|
108
108
|
if self._layout == "grid":
|
|
109
|
-
_reject_legacy_child_kwargs(layout_kw, "AppShell page")
|
|
109
|
+
_reject_legacy_child_kwargs(layout_kw, "AppShell page", "grid cell")
|
|
110
110
|
_expand_margin(layout_kw)
|
|
111
111
|
options = {k: v for k, v in layout_kw.items() if k in GRID_KEYS}
|
|
112
112
|
h = layout_kw.get("horizontal") or self._horizontal_items
|
|
@@ -144,7 +144,7 @@ class Card(PublicContainer):
|
|
|
144
144
|
|
|
145
145
|
def _merge_layout_options(self, child: Any, layout_kw: dict) -> tuple[str, dict]:
|
|
146
146
|
# Only reached for grid layout (column/row use the flex path above).
|
|
147
|
-
_reject_legacy_child_kwargs(layout_kw, "Card")
|
|
147
|
+
_reject_legacy_child_kwargs(layout_kw, "Card", "grid cell")
|
|
148
148
|
options = {k: v for k, v in layout_kw.items() if k in GRID_KEYS}
|
|
149
149
|
h = layout_kw.get("horizontal") or self._horizontal_items
|
|
150
150
|
v = layout_kw.get("vertical") or self._vertical_items
|
|
@@ -166,7 +166,7 @@ class Expander(PublicContainer):
|
|
|
166
166
|
|
|
167
167
|
def guide_layout(self, child: PublicWidgetBase, **layout_kw: Any) -> None:
|
|
168
168
|
if self._layout == "grid":
|
|
169
|
-
_reject_legacy_child_kwargs(layout_kw, "Expander")
|
|
169
|
+
_reject_legacy_child_kwargs(layout_kw, "Expander", "grid cell")
|
|
170
170
|
_expand_margin(layout_kw)
|
|
171
171
|
options = {k: v for k, v in layout_kw.items() if k in GRID_KEYS}
|
|
172
172
|
h = layout_kw.get("horizontal") or self._horizontal_items
|
|
@@ -284,7 +284,7 @@ class AccordionSection:
|
|
|
284
284
|
|
|
285
285
|
def guide_layout(self, child: PublicWidgetBase, **layout_kw: Any) -> None:
|
|
286
286
|
if self._layout == "grid":
|
|
287
|
-
_reject_legacy_child_kwargs(layout_kw, "AccordionSection")
|
|
287
|
+
_reject_legacy_child_kwargs(layout_kw, "AccordionSection", "grid cell")
|
|
288
288
|
_expand_margin(layout_kw)
|
|
289
289
|
options = {k: v for k, v in layout_kw.items() if k in GRID_KEYS}
|
|
290
290
|
h = layout_kw.get("horizontal") or self._horizontal_items
|
|
@@ -111,7 +111,7 @@ class Grid(PublicContainer):
|
|
|
111
111
|
return "grid"
|
|
112
112
|
|
|
113
113
|
def _merge_layout_options(self, child: Any, layout_kw: dict) -> tuple[str, dict]:
|
|
114
|
-
_reject_legacy_child_kwargs(layout_kw, "Grid")
|
|
114
|
+
_reject_legacy_child_kwargs(layout_kw, "Grid", "grid cell")
|
|
115
115
|
options = {k: v for k, v in layout_kw.items() if k in GRID_KEYS}
|
|
116
116
|
# Derive the cell sticky from per-child horizontal/vertical, each falling
|
|
117
117
|
# back to the container default for its axis.
|
|
@@ -136,7 +136,7 @@ class GroupBox(PublicContainer):
|
|
|
136
136
|
|
|
137
137
|
def _merge_layout_options(self, child: Any, layout_kw: dict) -> tuple[str, dict]:
|
|
138
138
|
# Only reached for grid layout (column/row use the flex path above).
|
|
139
|
-
_reject_legacy_child_kwargs(layout_kw, "GroupBox")
|
|
139
|
+
_reject_legacy_child_kwargs(layout_kw, "GroupBox", "grid cell")
|
|
140
140
|
options = {k: v for k, v in layout_kw.items() if k in GRID_KEYS}
|
|
141
141
|
h = layout_kw.get("horizontal") or self._horizontal_items
|
|
142
142
|
v = layout_kw.get("vertical") or self._vertical_items
|
|
@@ -96,7 +96,7 @@ class StackPage:
|
|
|
96
96
|
|
|
97
97
|
def guide_layout(self, child: PublicWidgetBase, **layout_kw: Any) -> None:
|
|
98
98
|
if self._layout == "grid":
|
|
99
|
-
_reject_legacy_child_kwargs(layout_kw, "StackPage")
|
|
99
|
+
_reject_legacy_child_kwargs(layout_kw, "StackPage", "grid cell")
|
|
100
100
|
_expand_margin(layout_kw)
|
|
101
101
|
options = {k: v for k, v in layout_kw.items() if k in GRID_KEYS}
|
|
102
102
|
h = layout_kw.get("horizontal") or self._horizontal_items
|
|
@@ -92,7 +92,7 @@ class SplitPane:
|
|
|
92
92
|
|
|
93
93
|
def guide_layout(self, child: PublicWidgetBase, **layout_kw: Any) -> None:
|
|
94
94
|
if self._layout == "grid":
|
|
95
|
-
_reject_legacy_child_kwargs(layout_kw, "SplitPane")
|
|
95
|
+
_reject_legacy_child_kwargs(layout_kw, "SplitPane", "grid cell")
|
|
96
96
|
_expand_margin(layout_kw)
|
|
97
97
|
options = {k: v for k, v in layout_kw.items() if k in GRID_KEYS}
|
|
98
98
|
h = layout_kw.get("horizontal") or self._horizontal_items
|