bootstack 0.4.6__tar.gz → 0.4.8__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.4.6/src/bootstack.egg-info → bootstack-0.4.8}/PKG-INFO +1 -1
- {bootstack-0.4.6 → bootstack-0.4.8}/pyproject.toml +2 -2
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/_core/localization.py +90 -1
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/style_builder_ttk.py +30 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/utility.py +68 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_core/base.py +12 -3
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_core/container.py +34 -8
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/_parts/spinnerentry_part.py +2 -1
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/_parts/textentry_part.py +2 -1
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/contextmenu.py +21 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/selectbox.py +49 -6
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/tableview/tableview.py +2 -1
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/tabs/tabview.py +2 -3
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/textarea/core.py +1 -12
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/tree/treeitem.py +7 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/mixins/localization_mixin.py +2 -2
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/primitives/flexframe.py +47 -5
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/primitives/optionmenu.py +3 -3
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/label.py +9 -13
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/select.py +5 -1
- {bootstack-0.4.6 → bootstack-0.4.8/src/bootstack.egg-info}/PKG-INFO +1 -1
- {bootstack-0.4.6 → bootstack-0.4.8}/LICENSE +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/MANIFEST.in +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/NOTICE +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/README.md +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/setup.cfg +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/__main__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/_core/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/_core/capture.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/_core/exceptions.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/_core/images.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/_core/mixins/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/_core/mixins/ttk_state.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/_core/mixins/widget.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/_core/paths.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/_core/signal_binding.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/_core/variables.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/_runtime/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/_runtime/app.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/_runtime/base_window.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/_runtime/events.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/_runtime/grab.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/_runtime/shortcuts.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/_runtime/tk_patch.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/_runtime/toplevel.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/_runtime/utility.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/_runtime/visual_focus.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/_runtime/wheel.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/_runtime/window_utilities.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/bootstack.ico +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/bootstack.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/badge-pill.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/badge-square.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/button-compact.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/button-default.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/buttongroup-after-h-compact.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/buttongroup-after-h-default.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/buttongroup-after-v-compact.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/buttongroup-after-v-default.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/buttongroup-before-h-compact.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/buttongroup-before-h-default.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/buttongroup-before-v-compact.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/buttongroup-before-v-default.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/buttongroup-center-h-compact.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/buttongroup-center-h-default.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/buttongroup-center-v-compact.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/buttongroup-center-v-default.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/card.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/checkbox-checked.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/checkbox-indeterminate.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/checkbox-unchecked.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/field.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/input-addon-compact.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/input-addon-default.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/input-compact.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/input-default.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/list-item-separated.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/list-item.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/listrow-compact.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/listrow-default.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/manifest.toml +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/menu-item.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/navitem-compact.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/navitem-default.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/progressbar-h-compact.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/progressbar-h-default.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/progressbar-v-compact.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/progressbar-v-default.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/radiobutton.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/scrollbar-horizontal.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/scrollbar-vertical.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/slider-handle.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/slider-track-h.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/slider-track-v.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/switch-off.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/switch-on.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/tab-h.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/elements/tab-v.png +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/icons/bootstrap.ttf +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/icons/glyphmap.json +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/icons/icon_metrics.json +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/ar/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/ar/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/bg/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/bg/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/cs/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/cs/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/da/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/da/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/de/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/de/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/en/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/en/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/es/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/es/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/fr/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/fr/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/he/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/he/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/hi/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/hi/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/it/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/it/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/ja/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/ja/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/ko/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/ko/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/nb/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/nb/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/nl/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/nl/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/pl/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/pl/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/pt/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/pt/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/sl/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/sl/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/sv/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/sv/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/tr/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/tr/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/cli/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/cli/__main__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/cli/add.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/cli/appicon.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/cli/build.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/cli/config.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/cli/demo.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/cli/dev.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/cli/doctor.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/cli/icons.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/cli/promote.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/cli/pyinstaller.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/cli/run.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/cli/start.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/cli/templates/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/clipboard.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/constants.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/data/README.md +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/data/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/data/_observable.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/data/base.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/data/file_source.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/data/memory_source.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/data/query.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/data/readers.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/data/sqlite_source.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/data/types.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/data/writers.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/dev/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/dev/_capture.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/dev/_env.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/dev/_registry.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/dev/_reloader.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/dev/_reset.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/dev/_watcher.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/dialogs/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/dialogs/_impl/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/dialogs/_impl/colorchooser.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/dialogs/_impl/datedialog.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/dialogs/_impl/dialog.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/dialogs/_impl/filterdialog.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/dialogs/_impl/fontdialog.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/dialogs/_impl/formdialog.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/dialogs/_impl/message.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/dialogs/_impl/query.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/errors.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/events/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/events/_event.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/events/_payloads.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/events/_subscription.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/i18n/README.md +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/i18n/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/i18n/catalog.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/i18n/intl_format.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/i18n/msgcat.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/i18n/specs.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/images.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/py.typed +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/scheduling/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/scheduling/_schedule.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/shortcuts.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/signals/README.md +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/signals/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/signals/integration.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/signals/signal.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/signals/types.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/store.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/streams/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/streams/_stream.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/badge.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/button.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/buttongroup.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/calendar.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/checkbutton.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/combobox.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/contextmenu.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/entry.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/expander.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/field.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/frame.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/label.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/labelframe.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/listview.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/menubar.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/menubutton.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/panedwindow.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/progressbar.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/radiobutton.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/scale.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/scrollbar.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/separator.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/sidenav.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/sizegrip.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/spinbox.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/switch.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/tabitem.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/togglegroup.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/toolbutton.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/tooltip.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/treeview.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders/utils.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders_tk/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/builders_tk/defaults.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/element.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/fonts.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/style.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/style_builder_base.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/style_builder_mixed.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/style_builder_tk.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/style_resolver.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/theme.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/theme_provider.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/themes/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/tk_patch.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/token_maps.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/types.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/style/typography.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/types.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/validation/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/validation/types.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/validation/validation_result.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/validation/validation_rules.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_core/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_core/app_config.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_core/choices.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_core/context.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_core/events.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_core/field_mixin.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_core/icon_image_props.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_core/image_binding.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_core/kwargs.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_core/navmodel.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_core/options.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_core/selection_group.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_core/window_controls.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_core/window_menu.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/_internal/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/_internal/wrapper_base.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/_parts/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/_parts/numberentry_part.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/_dateutils.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/_image_fit.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/accordion.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/avatar.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/buttongroup.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/calendar.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/carousel.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/chart.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/compositeframe.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/dateentry.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/dropdownbutton.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/expander.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/field.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/form.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/gallery.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/list/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/list/listitem.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/list/listview.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/menu/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/menu/model.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/menu/render_native.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/menu/render_themed.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/meter.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/numericentry.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/pagestack.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/passwordentry.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/pathentry.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/picture.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/radiogroup.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/scrolledtext.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/scrolledtext.pyi +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/scrollview.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/shell/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/shell/content_host.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/shell/layout.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/shell/nav_panel.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/shell/providers.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/shell/rail.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/shell/shell.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/shell/workspace.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/sidenav/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/sidenav/header.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/sidenav/separator.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/slider/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/slider/_shared.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/slider/rangeslider.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/slider/slider.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/spinnerentry.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/tableview/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/tableview/types.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/tabs/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/tabs/tabitem.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/tabs/tabs.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/textarea/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/textarea/change.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/textarea/codeeditor.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/textarea/decoration.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/textarea/diff.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/textarea/extensions/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/textarea/extensions/bracket_matcher.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/textarea/extensions/indent_guides.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/textarea/extensions/line_numbers.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/textarea/extensions/pygments_highlighter.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/textarea/extensions/smart_indent.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/textarea/filter.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/textarea/redirector.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/textarea/search_overlay.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/textarea/sidebar.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/textarea/style_registry.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/textarea/textarea.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/textarea/undo.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/textentry.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/timeentry.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/toast.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/toast_stack.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/togglegroup.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/toolbar.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/tooltip.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/tree/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/tree/source_binding.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/tree/treenode.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/tree/treeview.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/mixins/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/mixins/configure_mixin.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/mixins/entry_mixin.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/mixins/font_mixin.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/mixins/icon_mixin.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/mixins/signal_mixin.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/mixins/validation_mixin.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/primitives/__init__.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/primitives/_menubutton.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/primitives/badge.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/primitives/button.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/primitives/card.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/primitives/checkbutton.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/primitives/checktoggle.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/primitives/combobox.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/primitives/entry.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/primitives/frame.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/primitives/gridframe.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/primitives/label.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/primitives/labelframe.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/primitives/packframe.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/primitives/panedwindow.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/primitives/progressbar.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/primitives/radiobutton.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/primitives/radiotoggle.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/primitives/scrollbar.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/primitives/separator.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/primitives/sizegrip.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/primitives/spinbox.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/primitives/switch.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/primitives/treeview.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/app.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/appshell.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/avatar.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/boolean_controls.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/button.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/buttongroup.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/calendar.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/card.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/carousel.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/chart.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/codeeditor.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/contextmenu.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/datatable.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/datefield.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/divider.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/expander.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/form.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/gallery.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/gauge.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/grid.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/groupbox.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/listview.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/menubutton.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/numberfield.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/pagestack.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/passwordfield.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/pathfield.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/picture.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/progressbar.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/radio_variants.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/radiogroup.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/scrollbar.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/scrollview.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/selectbutton.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/sidebar_toggle.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/sizegrip.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/slider.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/spinbox.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/spinnerfield.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/splash.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/splitview.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/stacks.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/statusbar.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/tabs.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/textarea.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/textfield.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/theme_toggle.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/timefield.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/toast.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/togglegroup.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/toolbar.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/tooltip.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/tree.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/types.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/window.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack.egg-info/SOURCES.txt +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack.egg-info/dependency_links.txt +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack.egg-info/entry_points.txt +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack.egg-info/requires.txt +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack.egg-info/top_level.txt +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/tests/test_dialog_anchor.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/tests/test_events_doc_coverage.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/tests/test_hot_reload.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/tests/test_images.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/tests/test_images_gui.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/tests/test_intl_format.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/tests/test_navmodel.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/tests/test_on_color_contrast.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/tests/test_public_surface.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/tests/test_store.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/tests/test_theme_from_existing.py +0 -0
- {bootstack-0.4.6 → bootstack-0.4.8}/tests/test_validation_rules.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bootstack
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.8
|
|
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.4.
|
|
7
|
+
version = "0.4.8"
|
|
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.4.
|
|
117
|
+
current_version = "0.4.8"
|
|
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}",
|
|
@@ -10,7 +10,10 @@ a thin glue layer.
|
|
|
10
10
|
|
|
11
11
|
from __future__ import annotations
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
import itertools
|
|
14
|
+
import weakref
|
|
15
|
+
from tkinter import TclError
|
|
16
|
+
from typing import Any, Callable, TYPE_CHECKING
|
|
14
17
|
|
|
15
18
|
from bootstack.i18n.msgcat import MessageCatalog
|
|
16
19
|
from bootstack.i18n.specs import (
|
|
@@ -177,6 +180,91 @@ def get_current_locale() -> str:
|
|
|
177
180
|
return MessageCatalog.locale()
|
|
178
181
|
|
|
179
182
|
|
|
183
|
+
# =============================================================================
|
|
184
|
+
# Locale Change Propagation
|
|
185
|
+
# =============================================================================
|
|
186
|
+
|
|
187
|
+
_LOCALE_EVENT = "<<LocaleChanged>>"
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
# Don't bind a widget's refresh directly on the window: nothing removes it
|
|
191
|
+
# when the widget is destroyed.
|
|
192
|
+
class _LocaleRefreshers:
|
|
193
|
+
"""The refresh methods one toplevel calls on a locale change."""
|
|
194
|
+
|
|
195
|
+
def __init__(self, toplevel: Any) -> None:
|
|
196
|
+
self._toplevel = toplevel
|
|
197
|
+
self._refreshers: dict[int, weakref.WeakMethod] = {}
|
|
198
|
+
self._keys = itertools.count()
|
|
199
|
+
self._funcid: str | None = None
|
|
200
|
+
|
|
201
|
+
def add(self, refresh: Callable[[], Any]) -> None:
|
|
202
|
+
"""Register `refresh`, a bound method of a widget on this toplevel."""
|
|
203
|
+
self._ensure_bound()
|
|
204
|
+
key = next(self._keys)
|
|
205
|
+
refreshers = self._refreshers
|
|
206
|
+
# Drop the entry when the widget is collected, so a window whose
|
|
207
|
+
# locale never changes does not accumulate dead references either.
|
|
208
|
+
refreshers[key] = weakref.WeakMethod(
|
|
209
|
+
refresh, lambda _ref: refreshers.pop(key, None)
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
def _ensure_bound(self) -> None:
|
|
213
|
+
"""Bind the dispatcher, or bind it again if something replaced it.
|
|
214
|
+
|
|
215
|
+
A `bind` of the event without `add` on this toplevel replaces every
|
|
216
|
+
binding for it, the dispatcher included, which would silently stop
|
|
217
|
+
every widget on the window from refreshing.
|
|
218
|
+
"""
|
|
219
|
+
toplevel = self._toplevel
|
|
220
|
+
if self._funcid is not None:
|
|
221
|
+
script = str(toplevel.tk.call("bind", toplevel._w, _LOCALE_EVENT))
|
|
222
|
+
# The line prefix `_patched_bind` emits, as `_patched_unbind` matches it.
|
|
223
|
+
if ('if {"[%s ' % self._funcid) in script:
|
|
224
|
+
return
|
|
225
|
+
self._funcid = toplevel.bind(_LOCALE_EVENT, self._dispatch, add="+")
|
|
226
|
+
|
|
227
|
+
def _dispatch(self, _event: Any = None) -> None:
|
|
228
|
+
"""Call each live widget's refresh, in the order they registered."""
|
|
229
|
+
for key, ref in list(self._refreshers.items()):
|
|
230
|
+
refresh = ref()
|
|
231
|
+
if refresh is None:
|
|
232
|
+
continue
|
|
233
|
+
widget = refresh.__self__
|
|
234
|
+
try:
|
|
235
|
+
alive = widget.winfo_exists()
|
|
236
|
+
except TclError:
|
|
237
|
+
alive = False
|
|
238
|
+
if not alive:
|
|
239
|
+
# Destroyed, but still referenced from somewhere else.
|
|
240
|
+
self._refreshers.pop(key, None)
|
|
241
|
+
continue
|
|
242
|
+
try:
|
|
243
|
+
refresh()
|
|
244
|
+
except Exception:
|
|
245
|
+
# Report and carry on, as a handler bound on its own would:
|
|
246
|
+
# one failing widget must not stop the rest from refreshing.
|
|
247
|
+
widget._report_exception()
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def bind_locale_refresh(refresh: Callable[[], Any]) -> None:
|
|
251
|
+
"""Call `refresh` on every locale change for as long as its widget exists.
|
|
252
|
+
|
|
253
|
+
The locale-change event is generated on the root; `refresh` is called,
|
|
254
|
+
with no arguments, when the event reaches the toplevel of the widget it is
|
|
255
|
+
bound to, after the widgets registered before it. A destroyed widget is
|
|
256
|
+
never called, and registering holds no strong reference to it.
|
|
257
|
+
|
|
258
|
+
Args:
|
|
259
|
+
refresh: A bound method of the widget to refresh.
|
|
260
|
+
"""
|
|
261
|
+
toplevel = refresh.__self__.winfo_toplevel()
|
|
262
|
+
refreshers = toplevel.__dict__.get("_bs_locale_refreshers")
|
|
263
|
+
if refreshers is None:
|
|
264
|
+
refreshers = toplevel._bs_locale_refreshers = _LocaleRefreshers(toplevel)
|
|
265
|
+
refreshers.add(refresh)
|
|
266
|
+
|
|
267
|
+
|
|
180
268
|
# =============================================================================
|
|
181
269
|
# Signal Formatting
|
|
182
270
|
# =============================================================================
|
|
@@ -227,5 +315,6 @@ __all__ = [
|
|
|
227
315
|
"resolve_variable_text",
|
|
228
316
|
"apply_spec",
|
|
229
317
|
"get_current_locale",
|
|
318
|
+
"bind_locale_refresh",
|
|
230
319
|
"create_formatted_signal",
|
|
231
320
|
]
|
|
@@ -9,6 +9,7 @@ from bootstack._core.exceptions import StyleBuilderError
|
|
|
9
9
|
from bootstack.style.style_builder_base import StyleBuilderBase
|
|
10
10
|
from bootstack.style.element import Element, ElementImage
|
|
11
11
|
from bootstack.style.theme_provider import ThemeProvider
|
|
12
|
+
from bootstack.style.utility import pretile_element_image
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
class BuilderCallable(Protocol):
|
|
@@ -344,8 +345,37 @@ class StyleBuilderTtk(StyleBuilderBase):
|
|
|
344
345
|
if name in existing:
|
|
345
346
|
# Element already exists; avoid duplicate creation error on theme rebuilds
|
|
346
347
|
return
|
|
348
|
+
try:
|
|
349
|
+
args, kwargs = self._pretile_element_images(args, kwargs)
|
|
350
|
+
except Exception:
|
|
351
|
+
# Pre-tiling only speeds painting up; the element draws from its own images.
|
|
352
|
+
from bootstack._runtime.utility import debug_log_exception
|
|
353
|
+
debug_log_exception(f"could not pre-tile the images of element {name!r}")
|
|
347
354
|
self.style.element_create(name, "image", *args, **kwargs)
|
|
348
355
|
|
|
356
|
+
def _pretile_element_images(self, args: list, kwargs: dict) -> tuple[list, dict]:
|
|
357
|
+
"""Swap an element's images for copies that paint a wide parcel in few repeats.
|
|
358
|
+
|
|
359
|
+
Only an element that stretches horizontally is pre-tiled; one that does
|
|
360
|
+
not is drawn at its image's own width, so a wider image would draw wider.
|
|
361
|
+
No `sticky` means `nsew`.
|
|
362
|
+
"""
|
|
363
|
+
sticky = kwargs.get("sticky")
|
|
364
|
+
if sticky is not None and not ("e" in sticky and "w" in sticky):
|
|
365
|
+
return args, kwargs
|
|
366
|
+
|
|
367
|
+
master = self.style.master
|
|
368
|
+
border = kwargs.get("border", 0)
|
|
369
|
+
default, *specs = args
|
|
370
|
+
tiled = [pretile_element_image(default, border, master)]
|
|
371
|
+
tiled += [(state, pretile_element_image(image, border, master)) for state, image in specs]
|
|
372
|
+
|
|
373
|
+
if tiled[0] != default and "width" not in kwargs:
|
|
374
|
+
# The element's minimum width defaults to its image's width, so pin
|
|
375
|
+
# it to the original image's.
|
|
376
|
+
kwargs = {**kwargs, "width": int(self.style.tk.call("image", "width", default))}
|
|
377
|
+
return tiled, kwargs
|
|
378
|
+
|
|
349
379
|
def create_style_layout(self, ttk_style: str, element: Element | list[Element]):
|
|
350
380
|
if isinstance(element, list):
|
|
351
381
|
self.style.layout(ttk_style, [e.spec() for e in element])
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import tkinter
|
|
1
2
|
from colorsys import hls_to_rgb, rgb_to_hls
|
|
2
3
|
from dataclasses import dataclass
|
|
3
4
|
from pathlib import Path
|
|
@@ -553,6 +554,73 @@ def recolor_element_image(
|
|
|
553
554
|
return ElementImageResult(image=photo_image, meta=meta)
|
|
554
555
|
|
|
555
556
|
|
|
557
|
+
PRETILE_SPAN = 256
|
|
558
|
+
"""The width, in pixels, an element image's middle column is repeated to."""
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
def pretile_element_image(
|
|
562
|
+
image: str,
|
|
563
|
+
border: int | tuple[int, ...] | list[int],
|
|
564
|
+
master: tkinter.Misc,
|
|
565
|
+
) -> str:
|
|
566
|
+
"""Return a copy of an element image with its middle column repeated.
|
|
567
|
+
|
|
568
|
+
A stretched image element is drawn by repeating its middle column across the
|
|
569
|
+
parcel, one draw per repeat, so an element image only a few pixels wide makes
|
|
570
|
+
a wide widget slow to paint. The copy repeats the column to at least
|
|
571
|
+
`PRETILE_SPAN` pixels, in whole repeats starting at the column's left edge as
|
|
572
|
+
the element's own drawing does, so it draws the same pixels in fewer repeats.
|
|
573
|
+
The left and right columns are copied unchanged.
|
|
574
|
+
|
|
575
|
+
Copies are cached by source image and border, so elements that share an image
|
|
576
|
+
share its copy.
|
|
577
|
+
|
|
578
|
+
Args:
|
|
579
|
+
image: Name of the source photo image.
|
|
580
|
+
border: The element's border: one value, or up to four in the order left,
|
|
581
|
+
top, right, bottom, where right defaults to left.
|
|
582
|
+
master: Widget whose interpreter owns `image`.
|
|
583
|
+
|
|
584
|
+
Returns:
|
|
585
|
+
The name of the copy, or `image` itself when its middle column is already
|
|
586
|
+
at least `PRETILE_SPAN` pixels wide or has no width.
|
|
587
|
+
"""
|
|
588
|
+
values = [border] if isinstance(border, int) else list(border)
|
|
589
|
+
left = int(values[0]) if values else 0
|
|
590
|
+
right = int(values[2]) if len(values) > 2 else left
|
|
591
|
+
|
|
592
|
+
cache_key = ("element-pretile", str(image), left, right)
|
|
593
|
+
cached = ImageService.get_cached(cache_key)
|
|
594
|
+
if cached is not None:
|
|
595
|
+
return str(cached)
|
|
596
|
+
|
|
597
|
+
tk = master.tk
|
|
598
|
+
width = int(tk.call("image", "width", image))
|
|
599
|
+
height = int(tk.call("image", "height", image))
|
|
600
|
+
middle = width - left - right
|
|
601
|
+
if middle <= 0 or middle >= PRETILE_SPAN:
|
|
602
|
+
return str(image)
|
|
603
|
+
|
|
604
|
+
span = middle * -(-PRETILE_SPAN // middle)
|
|
605
|
+
tiled = tkinter.PhotoImage(master=master, width=left + span + right, height=height)
|
|
606
|
+
|
|
607
|
+
def copy(x0: int, x1: int, *to: int) -> None:
|
|
608
|
+
tk.call(
|
|
609
|
+
tiled, "copy", image, "-from", x0, 0, x1, height,
|
|
610
|
+
"-to", *to, "-compositingrule", "set",
|
|
611
|
+
)
|
|
612
|
+
|
|
613
|
+
if left:
|
|
614
|
+
copy(0, left, 0, 0)
|
|
615
|
+
# A -to rectangle larger than the -from region repeats the region across it.
|
|
616
|
+
copy(left, left + middle, left, 0, left + span, height)
|
|
617
|
+
if right:
|
|
618
|
+
copy(width - right, width, left + span, 0)
|
|
619
|
+
|
|
620
|
+
ImageService.set_cached(cache_key, tiled)
|
|
621
|
+
return str(tiled)
|
|
622
|
+
|
|
623
|
+
|
|
556
624
|
def should_darken(bg_hex: str) -> bool:
|
|
557
625
|
"""Determine whether to darken or lighten based on luminance and saturation."""
|
|
558
626
|
r, g, b = [v / 255.0 for v in ImageColor.getrgb(bg_hex)]
|
|
@@ -446,8 +446,14 @@ class PublicWidgetBase:
|
|
|
446
446
|
if placement.method == "flex":
|
|
447
447
|
# The FlexFrame's managed list IS the attached-sibling order, so the
|
|
448
448
|
# current managed index is the slot a plain attach() should restore.
|
|
449
|
+
from bootstack.widgets._core.container import snapshot_flex_slot
|
|
450
|
+
|
|
449
451
|
idx = placement.master.index_of(self._internal)
|
|
450
|
-
|
|
452
|
+
if idx >= 0:
|
|
453
|
+
snapshot_flex_slot(placement, placement.master, idx)
|
|
454
|
+
else:
|
|
455
|
+
placement.index = None
|
|
456
|
+
placement.preceding = ()
|
|
451
457
|
placement.master.remove_child(self._internal)
|
|
452
458
|
elif placement.method == "pack":
|
|
453
459
|
slaves = list(placement.master.pack_slaves())
|
|
@@ -485,7 +491,7 @@ class PublicWidgetBase:
|
|
|
485
491
|
"""
|
|
486
492
|
from bootstack.widgets._core.container import (
|
|
487
493
|
PACK_KEYS, GRID_KEYS, PLACE_KEYS, normalize_fill, _expand_margin, _flex_child_opts,
|
|
488
|
-
_reject_legacy_child_kwargs, resolve_pack_order
|
|
494
|
+
_reject_legacy_child_kwargs, resolve_pack_order, restored_flex_index
|
|
489
495
|
)
|
|
490
496
|
|
|
491
497
|
placement = getattr(self, "_placement", None)
|
|
@@ -503,7 +509,10 @@ class PublicWidgetBase:
|
|
|
503
509
|
options = dict(placement.options)
|
|
504
510
|
|
|
505
511
|
if placement.method == "flex":
|
|
506
|
-
|
|
512
|
+
if "index" in kwargs:
|
|
513
|
+
index = kwargs.pop("index")
|
|
514
|
+
else:
|
|
515
|
+
index = restored_flex_index(placement)
|
|
507
516
|
if kwargs:
|
|
508
517
|
_reject_legacy_child_kwargs(kwargs, type(self).__name__, "flex child")
|
|
509
518
|
_expand_margin(kwargs)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import tkinter
|
|
4
|
+
import weakref
|
|
4
5
|
from typing import Any, Literal
|
|
5
6
|
|
|
6
7
|
PACK_KEYS = frozenset({
|
|
@@ -101,11 +102,12 @@ class Placement:
|
|
|
101
102
|
Recorded on the child at layout time by `guide_layout`; consumed by
|
|
102
103
|
`PublicWidgetBase.detach`/`attach` to remove and re-insert the widget
|
|
103
104
|
without re-running its constructor. `options` holds the resolved Tk
|
|
104
|
-
geometry-manager options (no ordering refs); `index` is the
|
|
105
|
-
|
|
105
|
+
geometry-manager options (no ordering refs); `index` is the position among
|
|
106
|
+
siblings, snapshotted afresh on each `detach`. For a flex child, set it
|
|
107
|
+
with `snapshot_flex_slot`, which keeps `preceding` in step with it.
|
|
106
108
|
"""
|
|
107
109
|
|
|
108
|
-
__slots__ = ("method", "master", "options", "index")
|
|
110
|
+
__slots__ = ("method", "master", "options", "index", "preceding")
|
|
109
111
|
|
|
110
112
|
def __init__(
|
|
111
113
|
self,
|
|
@@ -114,10 +116,31 @@ class Placement:
|
|
|
114
116
|
options: dict,
|
|
115
117
|
index: int | None = None,
|
|
116
118
|
) -> None:
|
|
117
|
-
self.method = method # "pack" | "grid" | "place"
|
|
119
|
+
self.method = method # "pack" | "grid" | "place" | "flex"
|
|
118
120
|
self.master = master # the Tk master the child is placed in
|
|
119
121
|
self.options = options # resolved Tk options (no before/after/index)
|
|
120
122
|
self.index = index # pack order among siblings (snapshot at detach)
|
|
123
|
+
self.preceding: tuple = () # weakrefs to the flex siblings before `index`
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def snapshot_flex_slot(placement: Placement, frame: Any, index: int) -> None:
|
|
127
|
+
"""Record `index` in `frame` as the slot a plain `attach()` restores.
|
|
128
|
+
|
|
129
|
+
The siblings before the slot are kept by weak reference so that one
|
|
130
|
+
destroyed before the attach no longer counts toward the index.
|
|
131
|
+
"""
|
|
132
|
+
placement.index = index
|
|
133
|
+
placement.preceding = tuple(weakref.ref(w) for w, _ in frame._managed[:index])
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def restored_flex_index(placement: Placement) -> int | None:
|
|
137
|
+
"""The snapshotted slot, less the preceding siblings destroyed since."""
|
|
138
|
+
from bootstack.widgets._impl.primitives.flexframe import _alive
|
|
139
|
+
|
|
140
|
+
if placement.index is None:
|
|
141
|
+
return None
|
|
142
|
+
gone = sum(1 for ref in placement.preceding if not ((w := ref()) and _alive(w)))
|
|
143
|
+
return max(placement.index - gone, 0)
|
|
121
144
|
|
|
122
145
|
|
|
123
146
|
def resolve_pack_order(order: dict, master: tkinter.Misc) -> dict:
|
|
@@ -441,8 +464,11 @@ def place_flex_child(
|
|
|
441
464
|
frame.add_child(child._internal, opts, index=index)
|
|
442
465
|
child._placement = Placement("flex", frame, opts)
|
|
443
466
|
else:
|
|
444
|
-
# Record the slot a later attach() restores: an explicit index
|
|
445
|
-
# natural append position (current child count).
|
|
446
|
-
if index is None:
|
|
447
|
-
index = len(frame._managed)
|
|
467
|
+
# Record the slot a later attach() restores: an explicit index as given,
|
|
468
|
+
# else the natural append position (current child count).
|
|
448
469
|
child._placement = Placement("flex", frame, opts, index=index)
|
|
470
|
+
if index is None:
|
|
471
|
+
# Prune first: a dead sibling left in `_managed` would be counted
|
|
472
|
+
# twice, once in the count and again when attach() discounts it.
|
|
473
|
+
frame._prune_destroyed()
|
|
474
|
+
snapshot_flex_slot(child._placement, frame, len(frame._managed))
|
|
@@ -8,6 +8,7 @@ both text and numeric values.
|
|
|
8
8
|
from tkinter import Event, TclError
|
|
9
9
|
from typing import Any, Callable
|
|
10
10
|
|
|
11
|
+
from bootstack._core.localization import bind_locale_refresh
|
|
11
12
|
from bootstack.events import ChangeEvent, InputEvent
|
|
12
13
|
from bootstack.i18n import MessageCatalog, IntlFormatter
|
|
13
14
|
from bootstack.widgets._impl.primitives.spinbox import Spinbox
|
|
@@ -131,7 +132,7 @@ class SpinnerEntryPart(ValidationMixin, Spinbox):
|
|
|
131
132
|
self.bind('<FocusIn>', self._store_prev_value, add=True)
|
|
132
133
|
self.bind('<FocusOut>', self._handle_focus_out, add=True)
|
|
133
134
|
self.bind('<Return>', self._handle_return, add=True)
|
|
134
|
-
|
|
135
|
+
bind_locale_refresh(self._on_locale_changed)
|
|
135
136
|
|
|
136
137
|
# Set initial focus
|
|
137
138
|
if initial_focus:
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from tkinter import Event, TclError
|
|
2
2
|
from typing import Any, Callable
|
|
3
3
|
|
|
4
|
+
from bootstack._core.localization import bind_locale_refresh
|
|
4
5
|
from bootstack.events import ChangeEvent, InputEvent
|
|
5
6
|
from bootstack.i18n import MessageCatalog, IntlFormatter
|
|
6
7
|
from bootstack.widgets._impl.primitives.entry import Entry
|
|
@@ -102,7 +103,7 @@ class TextEntryPart(ValidationMixin, Entry):
|
|
|
102
103
|
self.bind('<FocusIn>', self._store_prev_value, add=True)
|
|
103
104
|
self.bind('<FocusOut>', self._handle_focus_out, add=True)
|
|
104
105
|
self.bind('<Return>', self._handle_return, add=True)
|
|
105
|
-
|
|
106
|
+
bind_locale_refresh(self._on_locale_changed)
|
|
106
107
|
|
|
107
108
|
# set initial focus
|
|
108
109
|
if initial_focus:
|
|
@@ -4,6 +4,7 @@ Provides a customizable context menu with support for commands, checkbuttons,
|
|
|
4
4
|
radiobuttons, and separators.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
+
import weakref
|
|
7
8
|
from tkinter import BooleanVar, IntVar, Misc, StringVar, TclError, Toplevel, Widget
|
|
8
9
|
from typing_extensions import Unpack
|
|
9
10
|
from typing import Any, Callable, Literal
|
|
@@ -42,6 +43,23 @@ On Windows and Linux the result is the created widget. On macOS (native
|
|
|
42
43
|
# explicitly" (no target — no positioning, no auto-trigger).
|
|
43
44
|
_TARGET_DEFAULT: Any = object()
|
|
44
45
|
|
|
46
|
+
# Themed menus currently shown. Weak, so a new menu torn down with its parent
|
|
47
|
+
# is not pinned here (it's destroy()) is never called.
|
|
48
|
+
_OPEN_MENUS: "weakref.WeakSet[_ToplevelContextMenu]" = weakref.WeakSet()
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def hide_open_menus() -> None:
|
|
52
|
+
"""Hide every open themed context menu.
|
|
53
|
+
|
|
54
|
+
Call this from a click handler that returns 'break': the break stops the
|
|
55
|
+
click before the window-level outside-click handler can close the menu.
|
|
56
|
+
"""
|
|
57
|
+
for menu in list(_OPEN_MENUS):
|
|
58
|
+
try:
|
|
59
|
+
menu.hide()
|
|
60
|
+
except TclError:
|
|
61
|
+
_OPEN_MENUS.discard(menu)
|
|
62
|
+
|
|
45
63
|
|
|
46
64
|
class _CommandItemFrame(CompositeFrame):
|
|
47
65
|
"""Container frame for command items that delegates to the inner button.
|
|
@@ -648,6 +666,7 @@ class _ToplevelContextMenu(CustomConfigMixin):
|
|
|
648
666
|
self._toplevel.attributes('-topmost', True)
|
|
649
667
|
self._toplevel.lift()
|
|
650
668
|
self._toplevel.focus_force()
|
|
669
|
+
_OPEN_MENUS.add(self)
|
|
651
670
|
|
|
652
671
|
# Start with no item highlighted (keyboard nav will highlight on first arrow key)
|
|
653
672
|
self._highlighted_index = -1
|
|
@@ -737,6 +756,7 @@ class _ToplevelContextMenu(CustomConfigMixin):
|
|
|
737
756
|
|
|
738
757
|
def hide(self) -> None:
|
|
739
758
|
"""Hide the context menu."""
|
|
759
|
+
_OPEN_MENUS.discard(self)
|
|
740
760
|
# Unbind click handler first
|
|
741
761
|
self._cancel_click_outside_after()
|
|
742
762
|
self._unbind_click_outside_handler()
|
|
@@ -756,6 +776,7 @@ class _ToplevelContextMenu(CustomConfigMixin):
|
|
|
756
776
|
|
|
757
777
|
def destroy(self) -> None:
|
|
758
778
|
"""Destroy the context menu and cleanup resources."""
|
|
779
|
+
_OPEN_MENUS.discard(self)
|
|
759
780
|
# Unbind click handler
|
|
760
781
|
self._cancel_click_outside_after()
|
|
761
782
|
self._unbind_click_outside_handler()
|
|
@@ -4,6 +4,7 @@ from typing_extensions import Unpack
|
|
|
4
4
|
|
|
5
5
|
from typing import Any
|
|
6
6
|
|
|
7
|
+
from bootstack._core.localization import bind_locale_refresh
|
|
7
8
|
from bootstack.events import ChangeEvent
|
|
8
9
|
from bootstack.widgets._core.options import (
|
|
9
10
|
cluster_records,
|
|
@@ -139,7 +140,7 @@ class SelectBox(Field):
|
|
|
139
140
|
self._entry._get_validation_value = self._validation_value
|
|
140
141
|
|
|
141
142
|
# Re-translate the displayed text + option maps on a live locale switch.
|
|
142
|
-
|
|
143
|
+
bind_locale_refresh(self._on_locale_changed_refresh)
|
|
143
144
|
|
|
144
145
|
self._group_by = group_by
|
|
145
146
|
self._max_visible_items = max_visible_items
|
|
@@ -391,7 +392,48 @@ class SelectBox(Field):
|
|
|
391
392
|
text = self.entry_widget.get()
|
|
392
393
|
if text in self._value_by_text and self._value_by_text[text] != text:
|
|
393
394
|
return self._value_by_text[text]
|
|
394
|
-
return self._entry_live_validation_value
|
|
395
|
+
return self._decode_custom_text(text, self._entry_live_validation_value)
|
|
396
|
+
|
|
397
|
+
def _numeric_option_kind(self):
|
|
398
|
+
"""`int` or `float` when every option value shares that type, else None."""
|
|
399
|
+
# type(), not isinstance: bool never reads as int here, so a bool option
|
|
400
|
+
# list falls out as "not numeric" without a special case.
|
|
401
|
+
kinds = {type(rec.value) for rec in self._records}
|
|
402
|
+
if len(kinds) != 1:
|
|
403
|
+
return None
|
|
404
|
+
kind = kinds.pop()
|
|
405
|
+
return kind if kind in (int, float) else None
|
|
406
|
+
|
|
407
|
+
def _decode_custom_text(self, text, fallback):
|
|
408
|
+
"""Decode text that names no option: the options' own type when they share one.
|
|
409
|
+
|
|
410
|
+
A value typed by the user arrives as text with nothing to parse it,
|
|
411
|
+
while one assigned from code arrives already typed. When every option
|
|
412
|
+
value is an `int`, or every one a `float`, numeric text is parsed to
|
|
413
|
+
that type so both routes agree. Anything else — a mixed or empty
|
|
414
|
+
list, `str` or `bool` options, text that is not a number, an entry
|
|
415
|
+
that parses through its own `value_format` — is handed to `fallback`,
|
|
416
|
+
which is what the entry reported before.
|
|
417
|
+
|
|
418
|
+
A whole-number `float` narrows to `int` for `int` options; `'6.5'`
|
|
419
|
+
against `int` options stays `6.5` rather than being truncated.
|
|
420
|
+
"""
|
|
421
|
+
if self.entry_widget._value_format is not None:
|
|
422
|
+
return fallback()
|
|
423
|
+
if getattr(self.entry_widget, "_showing_placeholder", False):
|
|
424
|
+
return fallback()
|
|
425
|
+
kind = self._numeric_option_kind()
|
|
426
|
+
if kind is None:
|
|
427
|
+
return fallback()
|
|
428
|
+
try:
|
|
429
|
+
parsed = self.entry_widget._fmt.parse(text, "decimal")
|
|
430
|
+
except ValueError:
|
|
431
|
+
return fallback()
|
|
432
|
+
if parsed is None:
|
|
433
|
+
return fallback()
|
|
434
|
+
if kind is int and not parsed.is_integer():
|
|
435
|
+
return parsed
|
|
436
|
+
return kind(parsed)
|
|
395
437
|
|
|
396
438
|
def _register_retired_value(self, value: Any) -> None:
|
|
397
439
|
"""Make a value that is not in the option list decodable.
|
|
@@ -1185,16 +1227,17 @@ class SelectBox(Field):
|
|
|
1185
1227
|
"""The selected value, or None when the field is empty.
|
|
1186
1228
|
|
|
1187
1229
|
For a decoupled option (its display text differs from its value) this
|
|
1188
|
-
returns the option's value.
|
|
1189
|
-
|
|
1190
|
-
|
|
1230
|
+
returns the option's value. A custom value typed by the user takes the
|
|
1231
|
+
type the options share when that is `int` or `float`. Otherwise it
|
|
1232
|
+
returns the entry's own raw value, so `value_format` parsing — e.g.
|
|
1233
|
+
TimeField's `datetime.time` — is preserved.
|
|
1191
1234
|
"""
|
|
1192
1235
|
text = self.entry_widget.get()
|
|
1193
1236
|
if text == "":
|
|
1194
1237
|
return None
|
|
1195
1238
|
if text in self._value_by_text and self._value_by_text[text] != text:
|
|
1196
1239
|
return self._value_by_text[text]
|
|
1197
|
-
return Field.value.fget(self)
|
|
1240
|
+
return self._decode_custom_text(text, lambda: Field.value.fget(self))
|
|
1198
1241
|
|
|
1199
1242
|
@value.setter
|
|
1200
1243
|
def value(self, value):
|
{bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/composites/tableview/tableview.py
RENAMED
|
@@ -30,7 +30,7 @@ from bootstack.data.sqlite_source import SqliteDataSource
|
|
|
30
30
|
from bootstack.data.query import col, any_of, all_of
|
|
31
31
|
from bootstack.widgets._impl.primitives.button import Button
|
|
32
32
|
from bootstack._runtime.utility import bind_right_click, debug_log_exception
|
|
33
|
-
from bootstack.widgets._impl.composites.contextmenu import ContextMenu
|
|
33
|
+
from bootstack.widgets._impl.composites.contextmenu import ContextMenu, hide_open_menus
|
|
34
34
|
from bootstack.widgets._impl.composites.tooltip import ToolTip
|
|
35
35
|
from bootstack.widgets._impl.composites.dropdownbutton import DropdownButton
|
|
36
36
|
from bootstack.widgets._impl.primitives.entry import Entry
|
|
@@ -1644,6 +1644,7 @@ class TableView(Frame):
|
|
|
1644
1644
|
# ------------------------------------------------------------------ Row context menu
|
|
1645
1645
|
def _dismiss_context_menus(self) -> None:
|
|
1646
1646
|
"""Hide any open built-in row/header context menu (idempotent)."""
|
|
1647
|
+
hide_open_menus()
|
|
1647
1648
|
for menu in (self._row_menu, self._header_menu):
|
|
1648
1649
|
if menu is not None:
|
|
1649
1650
|
try:
|
|
@@ -17,6 +17,7 @@ from bootstack.events import (
|
|
|
17
17
|
from bootstack.widgets._impl.composites.pagestack import PageStack
|
|
18
18
|
from bootstack.widgets.types import Master
|
|
19
19
|
from bootstack._core import NavigationError
|
|
20
|
+
from bootstack._core.localization import bind_locale_refresh
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
class TabView(Frame):
|
|
@@ -121,9 +122,7 @@ class TabView(Frame):
|
|
|
121
122
|
self._trace_id = self._tab_variable.trace_add('write', self._on_tab_selected)
|
|
122
123
|
|
|
123
124
|
# Locale retranslation
|
|
124
|
-
self.
|
|
125
|
-
"<<LocaleChanged>>", self._on_locale_changed, add='+'
|
|
126
|
-
)
|
|
125
|
+
bind_locale_refresh(self._on_locale_changed)
|
|
127
126
|
|
|
128
127
|
# Clean up trace on destroy
|
|
129
128
|
self.bind('<Destroy>', self._on_destroy, add='+')
|
|
@@ -524,26 +524,15 @@ class _MultilineCore(tk.Frame):
|
|
|
524
524
|
|
|
525
525
|
# ── convenience: forward common Text API to self ──────────────────────
|
|
526
526
|
|
|
527
|
-
def bind(self, sequence=None, func=None, add=None):
|
|
528
|
-
return self.text.bind(sequence, func, add)
|
|
529
|
-
|
|
530
|
-
def unbind(self, sequence, funcid=None):
|
|
531
|
-
return self.text.unbind(sequence, funcid)
|
|
532
|
-
|
|
533
527
|
def focus_set(self):
|
|
534
528
|
self.text.focus_set()
|
|
535
529
|
|
|
536
530
|
# ── cleanup ───────────────────────────────────────────────────────────
|
|
537
531
|
|
|
538
532
|
def _on_destroy(self, event: tk.Event) -> None:
|
|
539
|
-
# Released for any Destroy in this subtree, not just our own: the event
|
|
540
|
-
# this handler receives names the inner Text, never the core, so gating
|
|
541
|
-
# the release on `is self` releases nothing and the subscription outlives
|
|
542
|
-
# the widget. The rest of the block stays behind the guard -- it has
|
|
543
|
-
# never run, and starting it here is not this change's business.
|
|
544
|
-
self._unbind_signal()
|
|
545
533
|
if event.widget is not self:
|
|
546
534
|
return
|
|
535
|
+
self._unbind_signal()
|
|
547
536
|
self._chain.destroy()
|
|
548
537
|
try:
|
|
549
538
|
for seq in wheel.wheel_sequences(self):
|
|
@@ -14,6 +14,7 @@ from tkinter import TclError
|
|
|
14
14
|
from typing import Any, Optional
|
|
15
15
|
|
|
16
16
|
from bootstack.widgets._impl.composites.compositeframe import CompositeFrame
|
|
17
|
+
from bootstack.widgets._impl.composites.contextmenu import hide_open_menus
|
|
17
18
|
from bootstack.widgets._impl.primitives.button import Button
|
|
18
19
|
from bootstack.widgets._impl.primitives.frame import Frame
|
|
19
20
|
from bootstack.widgets._impl.primitives.label import Label
|
|
@@ -193,6 +194,9 @@ class TreeItem(CompositeFrame):
|
|
|
193
194
|
self._emit("<<TreeItemSelect>>", self._node)
|
|
194
195
|
|
|
195
196
|
def _on_ctrl_click(self, event=None) -> str:
|
|
197
|
+
# The 'break' below stops the click before an open menu's outside-click
|
|
198
|
+
# handler sees it, so close the open menus here
|
|
199
|
+
hide_open_menus()
|
|
196
200
|
if self._node is not None:
|
|
197
201
|
if self._focusable:
|
|
198
202
|
self.focus()
|
|
@@ -209,6 +213,9 @@ class TreeItem(CompositeFrame):
|
|
|
209
213
|
return "break"
|
|
210
214
|
|
|
211
215
|
def _on_right_click(self, event) -> str:
|
|
216
|
+
# The 'break' below stops the click before an open menu's outside-click
|
|
217
|
+
# handler sees it, so close open menus before this row opens its own
|
|
218
|
+
hide_open_menus()
|
|
212
219
|
if self._node is not None:
|
|
213
220
|
self._emit(
|
|
214
221
|
"<<TreeItemRightClick>>",
|
{bootstack-0.4.6 → bootstack-0.4.8}/src/bootstack/widgets/_impl/mixins/localization_mixin.py
RENAMED
|
@@ -18,6 +18,7 @@ from bootstack._core.localization import (
|
|
|
18
18
|
resolve_text,
|
|
19
19
|
resolve_variable_text,
|
|
20
20
|
apply_spec,
|
|
21
|
+
bind_locale_refresh,
|
|
21
22
|
create_formatted_signal,
|
|
22
23
|
)
|
|
23
24
|
from bootstack.i18n.specs import (
|
|
@@ -67,8 +68,7 @@ class LocalizationMixin(Misc):
|
|
|
67
68
|
self._localize_mode = localize
|
|
68
69
|
self._default_value_format = value_format
|
|
69
70
|
|
|
70
|
-
|
|
71
|
-
root.bind("<<LocaleChanged>>", self._on_locale_changed, add="+")
|
|
71
|
+
bind_locale_refresh(self._on_locale_changed)
|
|
72
72
|
|
|
73
73
|
# Check if widget has a textsignal or textvariable with value_format
|
|
74
74
|
if value_format and self._has_signal_or_variable():
|