bootstack 0.1.4__tar.gz → 0.1.6__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.1.4/src/bootstack.egg-info → bootstack-0.1.6}/PKG-INFO +4 -5
- {bootstack-0.1.4 → bootstack-0.1.6}/README.md +3 -4
- {bootstack-0.1.4 → bootstack-0.1.6}/pyproject.toml +2 -2
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/i18n/intl_format.py +7 -3
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/validation/validation_rules.py +20 -2
- bootstack-0.1.6/src/bootstack/widgets/_core/kwargs.py +85 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_core/selection_group.py +7 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/_parts/numberentry_part.py +3 -2
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/_parts/textentry_part.py +8 -2
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/dropdownbutton.py +15 -2
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/field.py +7 -2
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/form.py +71 -29
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/selectbox.py +89 -12
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/primitives/checkbutton.py +14 -2
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/boolean_controls.py +52 -25
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/buttongroup.py +23 -9
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/menubutton.py +4 -1
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/passwordfield.py +3 -1
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/pathfield.py +3 -1
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/radiogroup.py +9 -2
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/select.py +14 -3
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/statusbar.py +5 -1
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/textfield.py +3 -1
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/togglegroup.py +9 -2
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/toolbar.py +8 -3
- {bootstack-0.1.4 → bootstack-0.1.6/src/bootstack.egg-info}/PKG-INFO +4 -5
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack.egg-info/SOURCES.txt +1 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/tests/test_intl_format.py +25 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/tests/test_validation_rules.py +61 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/LICENSE +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/MANIFEST.in +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/NOTICE +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/setup.cfg +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/__main__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_core/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_core/capabilities/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_core/capabilities/after.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_core/capabilities/bind.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_core/capabilities/bindtags.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_core/capabilities/busy.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_core/capabilities/clipboard.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_core/capabilities/focus.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_core/capabilities/grab.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_core/capabilities/grid.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_core/capabilities/localization.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_core/capabilities/pack.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_core/capabilities/place.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_core/capabilities/selection.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_core/capabilities/signals.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_core/capabilities/winfo.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_core/colorutils.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_core/exceptions.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_core/images.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_core/mixins/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_core/mixins/ttk_state.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_core/mixins/widget.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_core/paths.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_core/publisher.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_core/variables.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_runtime/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_runtime/app.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_runtime/base_window.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_runtime/events.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_runtime/shortcuts.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_runtime/tk_patch.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_runtime/toplevel.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_runtime/utility.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_runtime/visual_focus.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/_runtime/window_utilities.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/bootstack.ico +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/bootstack.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/badge-pill.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/badge-square.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/button-compact.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/button-default.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/buttongroup-after-h-compact.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/buttongroup-after-h-default.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/buttongroup-after-v-compact.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/buttongroup-after-v-default.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/buttongroup-before-h-compact.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/buttongroup-before-h-default.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/buttongroup-before-v-compact.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/buttongroup-before-v-default.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/buttongroup-center-h-compact.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/buttongroup-center-h-default.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/buttongroup-center-v-compact.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/buttongroup-center-v-default.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/card.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/checkbox-checked.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/checkbox-indeterminate.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/checkbox-unchecked.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/field.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/input-addon-compact.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/input-addon-default.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/input-compact.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/input-default.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/list-item-separated.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/list-item.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/listrow-compact.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/listrow-default.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/manifest.toml +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/menu-item.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/navitem-compact.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/navitem-default.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/progressbar-h-compact.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/progressbar-h-default.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/progressbar-v-compact.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/progressbar-v-default.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/radiobutton.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/scrollbar-horizontal.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/scrollbar-vertical.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/slider-handle.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/slider-track-h.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/slider-track-v.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/switch-off.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/switch-on.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/tab-h.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/elements/tab-v.png +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/icons/bootstrap.ttf +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/icons/glyphmap.json +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/icons/icon_metrics.json +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/ar/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/ar/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/bg/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/bg/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/cs/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/cs/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/da/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/da/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/de/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/de/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/en/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/en/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/es/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/es/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/fr/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/fr/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/he/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/he/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/hi/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/hi/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/it/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/it/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/ja/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/ja/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/ko/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/ko/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/nb/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/nb/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/nl/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/nl/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/pl/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/pl/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/pt/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/pt/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/sl/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/sl/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/sv/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/sv/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/tr/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/tr/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/cli/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/cli/__main__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/cli/add.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/cli/appicon.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/cli/build.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/cli/config.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/cli/demo.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/cli/dev.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/cli/doctor.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/cli/icons.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/cli/promote.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/cli/pyinstaller.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/cli/run.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/cli/start.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/cli/templates/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/clipboard.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/constants.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/data/README.md +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/data/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/data/_observable.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/data/base.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/data/file_source.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/data/memory_source.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/data/query.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/data/readers.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/data/sqlite_source.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/data/types.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/data/writers.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/dev/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/dev/_capture.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/dev/_env.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/dev/_registry.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/dev/_reloader.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/dev/_reset.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/dev/_watcher.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/dialogs/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/dialogs/_impl/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/dialogs/_impl/colorchooser.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/dialogs/_impl/datedialog.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/dialogs/_impl/dialog.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/dialogs/_impl/filterdialog.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/dialogs/_impl/fontdialog.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/dialogs/_impl/formdialog.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/dialogs/_impl/message.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/dialogs/_impl/query.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/errors.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/events/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/events/_event.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/events/_payloads.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/events/_subscription.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/i18n/README.md +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/i18n/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/i18n/catalog.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/i18n/msgcat.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/i18n/specs.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/images.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/py.typed +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/scheduling/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/scheduling/_schedule.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/shortcuts.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/signals/README.md +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/signals/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/signals/integration.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/signals/signal.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/signals/types.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/store.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/streams/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/streams/_stream.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/badge.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/button.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/buttongroup.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/calendar.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/checkbutton.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/combobox.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/contextmenu.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/entry.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/expander.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/field.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/frame.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/label.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/labelframe.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/listview.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/menubar.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/menubutton.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/panedwindow.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/progressbar.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/radiobutton.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/scale.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/scrollbar.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/separator.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/sidenav.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/sizegrip.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/spinbox.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/switch.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/tabitem.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/togglegroup.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/toolbutton.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/tooltip.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/treeview.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders/utils.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders_tk/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/builders_tk/defaults.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/element.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/fonts.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/style.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/style_builder_base.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/style_builder_mixed.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/style_builder_tk.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/style_builder_ttk.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/style_resolver.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/theme.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/theme_provider.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/themes/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/tk_patch.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/token_maps.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/types.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/typography.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/style/utility.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/types.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/validation/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/validation/types.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/validation/validation_result.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_core/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_core/app_config.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_core/base.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_core/container.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_core/context.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_core/events.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_core/field_mixin.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_core/icon_image_props.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_core/image_binding.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_core/navmodel.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_core/options.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_core/window_controls.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_core/window_menu.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/_internal/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/_internal/wrapper_base.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/_parts/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/_parts/spinnerentry_part.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/_dateutils.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/_image_fit.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/accordion.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/avatar.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/buttongroup.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/calendar.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/carousel.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/chart.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/compositeframe.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/contextmenu.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/dateentry.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/expander.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/gallery.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/list/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/list/listitem.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/list/listview.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/menu/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/menu/model.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/menu/render_native.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/menu/render_themed.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/meter.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/numericentry.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/pagestack.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/passwordentry.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/pathentry.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/picture.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/radiogroup.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/scrolledtext.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/scrolledtext.pyi +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/scrollview.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/shell/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/shell/content_host.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/shell/layout.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/shell/nav_panel.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/shell/providers.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/shell/rail.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/shell/shell.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/shell/workspace.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/sidenav/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/sidenav/header.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/sidenav/separator.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/slider/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/slider/_shared.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/slider/rangeslider.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/slider/slider.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/spinnerentry.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/tableview/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/tableview/tableview.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/tableview/types.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/tabs/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/tabs/tabitem.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/tabs/tabs.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/tabs/tabview.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/textarea/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/textarea/change.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/textarea/codeeditor.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/textarea/core.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/textarea/decoration.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/textarea/diff.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/textarea/extensions/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/textarea/extensions/bracket_matcher.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/textarea/extensions/indent_guides.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/textarea/extensions/line_numbers.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/textarea/extensions/pygments_highlighter.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/textarea/extensions/smart_indent.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/textarea/filter.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/textarea/search_overlay.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/textarea/sidebar.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/textarea/style_registry.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/textarea/textarea.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/textarea/undo.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/textentry.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/timeentry.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/toast.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/toast_stack.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/togglegroup.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/toolbar.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/tooltip.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/tree/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/tree/source_binding.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/tree/treeitem.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/tree/treenode.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/tree/treeview.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/mixins/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/mixins/configure_mixin.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/mixins/entry_mixin.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/mixins/font_mixin.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/mixins/icon_mixin.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/mixins/localization_mixin.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/mixins/signal_mixin.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/mixins/validation_mixin.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/primitives/__init__.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/primitives/_menubutton.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/primitives/badge.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/primitives/button.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/primitives/card.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/primitives/checktoggle.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/primitives/combobox.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/primitives/entry.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/primitives/flexframe.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/primitives/frame.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/primitives/gridframe.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/primitives/label.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/primitives/labelframe.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/primitives/optionmenu.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/primitives/packframe.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/primitives/panedwindow.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/primitives/progressbar.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/primitives/radiobutton.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/primitives/radiotoggle.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/primitives/scrollbar.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/primitives/separator.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/primitives/sizegrip.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/primitives/spinbox.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/primitives/switch.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/primitives/treeview.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/app.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/appshell.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/avatar.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/button.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/calendar.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/card.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/carousel.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/chart.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/codeeditor.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/contextmenu.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/datatable.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/datefield.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/divider.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/expander.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/form.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/gallery.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/gauge.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/grid.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/groupbox.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/label.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/listview.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/numberfield.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/pagestack.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/picture.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/progressbar.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/radio_variants.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/scrollbar.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/scrollview.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/selectbutton.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/sidebar_toggle.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/sizegrip.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/slider.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/spinbox.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/spinnerfield.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/splash.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/splitview.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/stacks.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/tabs.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/textarea.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/theme_toggle.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/timefield.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/toast.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/tooltip.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/tree.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/types.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/window.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack.egg-info/dependency_links.txt +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack.egg-info/entry_points.txt +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack.egg-info/requires.txt +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack.egg-info/top_level.txt +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/tests/test_dialog_anchor.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/tests/test_events_doc_coverage.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/tests/test_hot_reload.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/tests/test_images.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/tests/test_images_gui.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/tests/test_navmodel.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/tests/test_on_color_contrast.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/tests/test_public_surface.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/tests/test_store.py +0 -0
- {bootstack-0.1.4 → bootstack-0.1.6}/tests/test_theme_from_existing.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bootstack
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.6
|
|
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
|
|
@@ -66,10 +66,9 @@ Dynamic: license-file
|
|
|
66
66
|
|
|
67
67
|
### Desktop apps in pure Python — Tk underneath, none of the boilerplate.
|
|
68
68
|
|
|
69
|
-
bootstack is built on Tk, so the install is light
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
and a CLI that scaffolds and packages the whole thing.
|
|
69
|
+
bootstack is built on Tk, so the install is light and your app ships as a small standalone executable. But you'll never
|
|
70
|
+
write a `StringVar` or call `.pack()` — the API is its own. 60+ widgets, reactive state, and a CLI that scaffolds and
|
|
71
|
+
packages the whole thing.
|
|
73
72
|
|
|
74
73
|
<p align="center">
|
|
75
74
|
<picture>
|
|
@@ -13,10 +13,9 @@
|
|
|
13
13
|
|
|
14
14
|
### Desktop apps in pure Python — Tk underneath, none of the boilerplate.
|
|
15
15
|
|
|
16
|
-
bootstack is built on Tk, so the install is light
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
and a CLI that scaffolds and packages the whole thing.
|
|
16
|
+
bootstack is built on Tk, so the install is light and your app ships as a small standalone executable. But you'll never
|
|
17
|
+
write a `StringVar` or call `.pack()` — the API is its own. 60+ widgets, reactive state, and a CLI that scaffolds and
|
|
18
|
+
packages the whole thing.
|
|
20
19
|
|
|
21
20
|
<p align="center">
|
|
22
21
|
<picture>
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "bootstack"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.6"
|
|
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.1.
|
|
117
|
+
current_version = "0.1.6"
|
|
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}",
|
|
@@ -12,6 +12,7 @@ import locale
|
|
|
12
12
|
import re
|
|
13
13
|
import warnings
|
|
14
14
|
from dataclasses import dataclass
|
|
15
|
+
from decimal import Decimal
|
|
15
16
|
from datetime import date, datetime, time
|
|
16
17
|
from typing import Any, Literal, Mapping, Optional, TypedDict, Union, cast
|
|
17
18
|
|
|
@@ -148,7 +149,10 @@ SUFFIXES_EN = (
|
|
|
148
149
|
Suffix(1_000, "K"),
|
|
149
150
|
)
|
|
150
151
|
_SUFFIX_TO_FACTOR = {"K": 1_000, "M": 1_000_000, "B": 1_000_000_000, "T": 1_000_000_000_000}
|
|
151
|
-
|
|
152
|
+
# Values formatted as numbers. `Decimal` is passed to Babel as-is rather than
|
|
153
|
+
# coerced: Babel formats it natively, and going through `float` would round
|
|
154
|
+
# away the precision a caller chose `Decimal` to keep.
|
|
155
|
+
_NUMBERISH = (int, float, Decimal)
|
|
152
156
|
|
|
153
157
|
|
|
154
158
|
def _locale_to_languages(loc: str) -> list[str]:
|
|
@@ -208,7 +212,7 @@ class IntlFormatter:
|
|
|
208
212
|
if value is None:
|
|
209
213
|
return ""
|
|
210
214
|
if isinstance(value, _NUMBERISH):
|
|
211
|
-
return self._format_number(float(value), spec)
|
|
215
|
+
return self._format_number(value if isinstance(value, Decimal) else float(value), spec)
|
|
212
216
|
if isinstance(value, datetime):
|
|
213
217
|
return self._format_datetime(value, spec)
|
|
214
218
|
if isinstance(value, date):
|
|
@@ -238,7 +242,7 @@ class IntlFormatter:
|
|
|
238
242
|
return self._parse_temporal(s, spec)
|
|
239
243
|
|
|
240
244
|
# ---------- Numbers ----------
|
|
241
|
-
def _format_number(self, x: float, spec: LooseSpec) -> str:
|
|
245
|
+
def _format_number(self, x: float | Decimal, spec: LooseSpec) -> str:
|
|
242
246
|
opt = self._normalize_number_spec(spec)
|
|
243
247
|
|
|
244
248
|
if opt["type"] == "custom":
|
|
@@ -33,6 +33,16 @@ def rule_applies_to_kind(rule_type: str, kind: str) -> bool:
|
|
|
33
33
|
return True
|
|
34
34
|
|
|
35
35
|
|
|
36
|
+
def _is_empty(value: object) -> bool:
|
|
37
|
+
"""Whether a field holds nothing, for rules that only shape a value.
|
|
38
|
+
|
|
39
|
+
Matches the emptiness test `range` uses: `None` or the empty string. A
|
|
40
|
+
whitespace-only entry is real input — `stringLength` should still measure
|
|
41
|
+
it — so only `required` treats blank text as absent.
|
|
42
|
+
"""
|
|
43
|
+
return value is None or value == ""
|
|
44
|
+
|
|
45
|
+
|
|
36
46
|
def _as_text(value: object) -> str:
|
|
37
47
|
"""Coerce a value to text for the string rules.
|
|
38
48
|
|
|
@@ -104,7 +114,15 @@ class ValidationRule:
|
|
|
104
114
|
# Everything else is valid (non-empty string, number, date, etc.)
|
|
105
115
|
return ValidationResult(True, "")
|
|
106
116
|
|
|
107
|
-
|
|
117
|
+
# A rule other than `required` describes what a value must look like,
|
|
118
|
+
# not that one must be present. An untouched optional field has nothing
|
|
119
|
+
# to check, so it passes — otherwise leaving it blank would block a
|
|
120
|
+
# submit with no way forward. Use `required` for presence, the same
|
|
121
|
+
# contract `range` states below.
|
|
122
|
+
if self.type in TEXT_RULES and _is_empty(value):
|
|
123
|
+
return ValidationResult(True, "")
|
|
124
|
+
|
|
125
|
+
if self.type == "email":
|
|
108
126
|
if not re.match(r"[^@]+@[^@]+\.[^@]+", _as_text(value)):
|
|
109
127
|
return ValidationResult(False, msg)
|
|
110
128
|
elif self.type == "stringLength":
|
|
@@ -119,7 +137,7 @@ class ValidationRule:
|
|
|
119
137
|
elif self.type == "range":
|
|
120
138
|
# Bounds on an ordered value (number/date/time). An empty field is
|
|
121
139
|
# not out of range — use 'required' for presence.
|
|
122
|
-
if value
|
|
140
|
+
if _is_empty(value):
|
|
123
141
|
return ValidationResult(True)
|
|
124
142
|
lo = self.params.get("min")
|
|
125
143
|
hi = self.params.get("max")
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"""Merging a caller's options dict over framework-built keyword arguments.
|
|
2
|
+
|
|
3
|
+
Several widgets accept a bag of options aimed at a widget they build for you —
|
|
4
|
+
`Form`'s `editor_options`, `MenuButton`'s `menu_options`, the keyword
|
|
5
|
+
passthrough on `ButtonGroup.add` / `RadioGroup.add` / `Toolbar.add_widget`.
|
|
6
|
+
Those bags name the built widget's own public keyword arguments, so a caller
|
|
7
|
+
may name a parameter the framework also fills.
|
|
8
|
+
|
|
9
|
+
Splatting both into one call raises `TypeError: got multiple values for
|
|
10
|
+
keyword argument`, which names an internal class the caller never wrote.
|
|
11
|
+
`merge_kwargs` gives that meeting point one rule instead:
|
|
12
|
+
|
|
13
|
+
- The caller's options WIN over the framework's defaults. Naming a parameter
|
|
14
|
+
the framework also fills is how you override it.
|
|
15
|
+
- A short list of keys is structural — the widget cannot do its job if they
|
|
16
|
+
are replaced (it would be parented elsewhere, or lose the command that emits
|
|
17
|
+
its events). Supplying one raises `BootstackError` naming the API you called
|
|
18
|
+
and what to use instead.
|
|
19
|
+
"""
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
from typing import Any, Mapping
|
|
23
|
+
|
|
24
|
+
from bootstack.errors import BootstackError
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def reject_reserved(
|
|
28
|
+
user: Mapping[str, Any] | None,
|
|
29
|
+
reserved: Mapping[str, str] | None,
|
|
30
|
+
context: str,
|
|
31
|
+
) -> None:
|
|
32
|
+
"""Raise if the caller set a key the framework owns.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
user: The caller's options. `None` is treated as empty.
|
|
36
|
+
reserved: Structural keys the caller may not set, mapped to the
|
|
37
|
+
guidance shown when they try.
|
|
38
|
+
context: The API the caller invoked, e.g. `'ButtonGroup.add()'`.
|
|
39
|
+
|
|
40
|
+
Raises:
|
|
41
|
+
BootstackError: If `user` contains a key listed in `reserved`.
|
|
42
|
+
"""
|
|
43
|
+
if not user or not reserved:
|
|
44
|
+
return
|
|
45
|
+
for key in user:
|
|
46
|
+
if key in reserved:
|
|
47
|
+
raise BootstackError(f"{context} does not accept {key}= — {reserved[key]}")
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def merge_kwargs(
|
|
51
|
+
defaults: Mapping[str, Any],
|
|
52
|
+
user: Mapping[str, Any] | None,
|
|
53
|
+
*,
|
|
54
|
+
reserved: Mapping[str, str] | None = None,
|
|
55
|
+
context: str = "this call",
|
|
56
|
+
) -> dict[str, Any]:
|
|
57
|
+
"""Merge a caller's options over framework-built keyword arguments.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
defaults: Keyword arguments the framework derived for the call. Any
|
|
61
|
+
key also present in `user` is overridden.
|
|
62
|
+
reserved: Structural keys the caller may not set, mapped to the
|
|
63
|
+
guidance shown when they try.
|
|
64
|
+
context: The API the caller invoked, used in the error message.
|
|
65
|
+
user: The caller's options. `None` is treated as empty.
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
The merged keyword arguments.
|
|
69
|
+
|
|
70
|
+
Raises:
|
|
71
|
+
BootstackError: If `user` contains a key listed in `reserved`.
|
|
72
|
+
"""
|
|
73
|
+
merged = dict(defaults)
|
|
74
|
+
if not user:
|
|
75
|
+
return merged
|
|
76
|
+
reject_reserved(user, reserved, context)
|
|
77
|
+
merged.update(user)
|
|
78
|
+
return merged
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
# Structural keys a bar's widget-options passthrough may not set — a toolbar or
|
|
82
|
+
# status bar places every widget it builds.
|
|
83
|
+
RESERVED_BAR_KWARGS = {
|
|
84
|
+
'parent': 'the bar places the widgets it builds.',
|
|
85
|
+
}
|
|
@@ -4,6 +4,13 @@ from typing import Any
|
|
|
4
4
|
|
|
5
5
|
from bootstack.widgets._core.options import OptionRecord, record_to_dict, option_localize
|
|
6
6
|
|
|
7
|
+
# Structural keys a per-option kwargs passthrough may not set — the group owns
|
|
8
|
+
# each option's identity and tracks its own selection.
|
|
9
|
+
RESERVED_OPTION_KWARGS = {
|
|
10
|
+
'text': 'set the caption with the label argument.',
|
|
11
|
+
'variable': 'the group tracks its own selection.',
|
|
12
|
+
}
|
|
13
|
+
|
|
7
14
|
|
|
8
15
|
class SelectionGroupMixin:
|
|
9
16
|
"""Shared item-management surface for the option-group widgets.
|
|
@@ -272,9 +272,10 @@ class NumberEntryPart(TextEntryPart):
|
|
|
272
272
|
A plain numeric field parses to a string when no display format is set,
|
|
273
273
|
so coerce it the same way the public value does — validation rules and a
|
|
274
274
|
`custom` func receive a real `int`/`float` (or `None` for empty/invalid
|
|
275
|
-
input), never the display string.
|
|
275
|
+
input), never the display string. A visible placeholder is not input,
|
|
276
|
+
so it reads as empty here — same rule as the text field this overrides.
|
|
276
277
|
"""
|
|
277
|
-
text = self.get()
|
|
278
|
+
text = '' if self._showing_placeholder else self.get()
|
|
278
279
|
try:
|
|
279
280
|
raw = self._parse_or_none(text)
|
|
280
281
|
except Exception:
|
|
@@ -288,11 +288,17 @@ class TextEntryPart(ValidationMixin, Entry):
|
|
|
288
288
|
last-committed value. This keeps a manual `validate()`, the automatic
|
|
289
289
|
blur/key validation, and a form-level validate in agreement on the same
|
|
290
290
|
live, typed input.
|
|
291
|
+
|
|
292
|
+
A visible placeholder is not input. It is inserted into the entry to
|
|
293
|
+
render it, so reading the raw text would hand the placeholder string to
|
|
294
|
+
the rules and `required` would pass on an untouched field — the field
|
|
295
|
+
reads as empty here, exactly as it does through `value`.
|
|
291
296
|
"""
|
|
297
|
+
text = "" if self._showing_placeholder else self.get()
|
|
292
298
|
try:
|
|
293
|
-
return self._parse_or_none(
|
|
299
|
+
return self._parse_or_none(text)
|
|
294
300
|
except Exception:
|
|
295
|
-
return
|
|
301
|
+
return text
|
|
296
302
|
|
|
297
303
|
def text(self, value=None):
|
|
298
304
|
"""Get or set the raw display text without committing.
|
{bootstack-0.1.4 → bootstack-0.1.6}/src/bootstack/widgets/_impl/composites/dropdownbutton.py
RENAMED
|
@@ -7,8 +7,18 @@ from typing_extensions import Unpack
|
|
|
7
7
|
from bootstack.widgets._impl.composites.contextmenu import ContextMenu, ContextMenuItem, ContextMenuItemResult
|
|
8
8
|
from bootstack.widgets._impl.primitives._menubutton import MenuButton
|
|
9
9
|
from bootstack.widgets._impl.mixins import configure_delegate
|
|
10
|
+
from bootstack.widgets._core.kwargs import merge_kwargs
|
|
10
11
|
from bootstack.widgets.types import Master, StyledKwargs, CompoundMode, WidgetState, WidgetDensity
|
|
11
12
|
|
|
13
|
+
# Structural keys a menu_options bag may not set — the button owns the menu's
|
|
14
|
+
# contents and the callback that emits its selection events.
|
|
15
|
+
_RESERVED_MENU_OPTIONS = {
|
|
16
|
+
'items': 'pass the menu items to the button itself.',
|
|
17
|
+
'command': "use the button's on_select event.",
|
|
18
|
+
'trigger': 'the button opens its own menu when clicked.',
|
|
19
|
+
'target': 'the menu belongs to the button that opens it.',
|
|
20
|
+
}
|
|
21
|
+
|
|
12
22
|
if TYPE_CHECKING:
|
|
13
23
|
from bootstack.signals import Signal
|
|
14
24
|
|
|
@@ -122,10 +132,13 @@ class DropdownButton(MenuButton):
|
|
|
122
132
|
"offset": (offset_x, 0),
|
|
123
133
|
"density": density,
|
|
124
134
|
}
|
|
125
|
-
options.update(self._popdown_options)
|
|
126
135
|
# DropdownButton manages its own activation (left-click, Return/
|
|
127
136
|
# KP_Enter via show_menu), so opt out of ContextMenu's auto-trigger.
|
|
128
|
-
|
|
137
|
+
options["trigger"] = None
|
|
138
|
+
options = merge_kwargs(options, self._popdown_options,
|
|
139
|
+
reserved=_RESERVED_MENU_OPTIONS,
|
|
140
|
+
context='MenuButton menu_options')
|
|
141
|
+
cm = ContextMenu(self, target=self, items=self._items, command=self._command, **options)
|
|
129
142
|
return cm
|
|
130
143
|
|
|
131
144
|
@property
|
|
@@ -273,8 +273,13 @@ class Field(EntryMixin, Frame):
|
|
|
273
273
|
self._entry.value(value)
|
|
274
274
|
|
|
275
275
|
def get(self) -> str:
|
|
276
|
-
"""Return the
|
|
277
|
-
|
|
276
|
+
"""Return the display text from the underlying entry widget.
|
|
277
|
+
|
|
278
|
+
Reads the entry's own text rather than its raw contents, so a field
|
|
279
|
+
showing only its placeholder reports an empty string — `text` and
|
|
280
|
+
`value` are a pair and must agree on whether the field is empty.
|
|
281
|
+
"""
|
|
282
|
+
return self._entry.text()
|
|
278
283
|
|
|
279
284
|
@property
|
|
280
285
|
def entry_widget(self) -> EntryWidget:
|
|
@@ -15,8 +15,15 @@ from bootstack.widgets._impl.primitives.label import Label
|
|
|
15
15
|
from bootstack.widgets._impl.primitives.labelframe import LabelFrame
|
|
16
16
|
from bootstack.widgets._impl.mixins import configure_delegate
|
|
17
17
|
from bootstack.widgets._impl.composites.tabs.tabview import TabView
|
|
18
|
+
from bootstack.widgets._core.kwargs import merge_kwargs
|
|
18
19
|
from bootstack.widgets.types import EditorType, Master
|
|
19
20
|
|
|
21
|
+
# Structural keys an editor_options bag may not set — the form's field
|
|
22
|
+
# container owns where the editor is placed.
|
|
23
|
+
_RESERVED_EDITOR_OPTIONS = {
|
|
24
|
+
'parent': 'the form places each editor in its own field container',
|
|
25
|
+
}
|
|
26
|
+
|
|
20
27
|
if TYPE_CHECKING:
|
|
21
28
|
from bootstack.dialogs._impl.dialog import DialogButton
|
|
22
29
|
ButtonInput = str | Mapping[str, Any] | DialogButton
|
|
@@ -603,10 +610,10 @@ class Form(Frame):
|
|
|
603
610
|
auto_col = 0
|
|
604
611
|
auto_row += 1
|
|
605
612
|
|
|
606
|
-
# Editors that
|
|
607
|
-
#
|
|
608
|
-
|
|
609
|
-
|
|
613
|
+
# Editors that render something other than a validating field, so `required`
|
|
614
|
+
# and friends are dropped for them. Anything NOT named here — including a
|
|
615
|
+
# misspelled editor name — falls back to a text field, which does validate.
|
|
616
|
+
_NON_VALIDATING_EDITORS = frozenset({'checkbox', 'switch', 'slider'})
|
|
610
617
|
|
|
611
618
|
def _build_field(self, parent: Frame, item: FieldItem):
|
|
612
619
|
if not item.visible:
|
|
@@ -614,7 +621,11 @@ class Form(Frame):
|
|
|
614
621
|
|
|
615
622
|
editor = item.editor or self._default_editor_for_dtype(item.dtype, self._data.get(item.key))
|
|
616
623
|
options = dict(item.editor_options or {})
|
|
617
|
-
|
|
624
|
+
# Gate on what does NOT validate, not on what does: an unrecognized
|
|
625
|
+
# editor name falls back to a text field, so testing membership of the
|
|
626
|
+
# validating set silently dropped `required` on a typo and let the form
|
|
627
|
+
# submit empty.
|
|
628
|
+
if item.required and editor not in self._NON_VALIDATING_EDITORS:
|
|
618
629
|
options["required"] = True
|
|
619
630
|
initial_value = self._data.get(item.key)
|
|
620
631
|
label_text = item.label if item.label is not None else item.key.replace("_", " ").title()
|
|
@@ -680,45 +691,76 @@ class Form(Frame):
|
|
|
680
691
|
for internal_only in ("show_message", "validator"):
|
|
681
692
|
opts.pop(internal_only, None)
|
|
682
693
|
|
|
694
|
+
# `value` in editor_options seeds the editor when the form data carries
|
|
695
|
+
# nothing for the key; the data wins when it does. Every editor below
|
|
696
|
+
# passes `value=` positionally-by-keyword, so leaving it in `opts` would
|
|
697
|
+
# raise "got multiple values for keyword argument 'value'".
|
|
698
|
+
seed_value = opts.pop('value', None)
|
|
699
|
+
if initial is None:
|
|
700
|
+
initial = seed_value
|
|
701
|
+
|
|
702
|
+
def build(cls, *args, **defaults):
|
|
703
|
+
"""Construct `cls`, letting `editor_options` override the defaults."""
|
|
704
|
+
merged = merge_kwargs(defaults, opts, reserved=_RESERVED_EDITOR_OPTIONS,
|
|
705
|
+
context='Form editor_options')
|
|
706
|
+
merged['parent'] = container
|
|
707
|
+
return cls(*args, **merged)
|
|
708
|
+
|
|
709
|
+
def choice_list():
|
|
710
|
+
"""Pop the documented `items`/`values` aliases for the option list."""
|
|
711
|
+
choices = opts.pop('items', None)
|
|
712
|
+
if choices is None:
|
|
713
|
+
choices = opts.pop('values', None)
|
|
714
|
+
return choices
|
|
715
|
+
|
|
716
|
+
# Test against None, not truthiness: a falsy-but-real datum (0, False)
|
|
717
|
+
# is a value, not an absent one, and blanking it here would write the
|
|
718
|
+
# blank straight back into the form data. Pass the datum through as it
|
|
719
|
+
# came, too — `data` is the caller's record, and stringifying it here
|
|
720
|
+
# would flip a Decimal or a date to `str` in `form.data` before the
|
|
721
|
+
# user has edited anything.
|
|
722
|
+
text_value = initial if initial is not None else ""
|
|
723
|
+
|
|
683
724
|
if editor == 'textfield':
|
|
684
|
-
return TextField
|
|
725
|
+
return build(TextField, value=text_value, label=label_text)
|
|
685
726
|
if editor == 'numberfield':
|
|
686
|
-
|
|
687
|
-
|
|
727
|
+
return build(NumberField, value=initial if initial is not None else 0,
|
|
728
|
+
label=label_text)
|
|
688
729
|
if editor == 'passwordfield':
|
|
689
|
-
return PasswordField
|
|
730
|
+
return build(PasswordField, value=text_value, label=label_text)
|
|
690
731
|
if editor == 'datefield':
|
|
691
|
-
return DateField
|
|
732
|
+
return build(DateField, value=initial, label=label_text)
|
|
692
733
|
if editor == 'textarea':
|
|
693
|
-
|
|
694
|
-
return TextArea(value=text, label=label_text, parent=container, **opts)
|
|
734
|
+
return build(TextArea, value=text_value, label=label_text)
|
|
695
735
|
if editor == 'select':
|
|
696
|
-
choices =
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
label=label_text, parent=container, **opts)
|
|
736
|
+
choices = [str(i) for i in (choice_list() or [])]
|
|
737
|
+
return build(Select, options=choices, label=label_text,
|
|
738
|
+
value=initial if initial is not None else "")
|
|
700
739
|
if editor == 'spinnerfield':
|
|
701
|
-
choices =
|
|
740
|
+
choices = choice_list()
|
|
702
741
|
if choices is not None:
|
|
703
742
|
opts['options'] = [str(i) for i in choices]
|
|
704
|
-
return SpinnerField
|
|
705
|
-
|
|
706
|
-
if editor
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
743
|
+
return build(SpinnerField, value=initial if initial is not None else "",
|
|
744
|
+
label=label_text)
|
|
745
|
+
if editor in ('checkbox', 'switch'):
|
|
746
|
+
# The boolean controls call their caption `label`, so pass it by
|
|
747
|
+
# keyword — passing it positionally would collide with a `label`
|
|
748
|
+
# option instead of letting it override, and `text` is the alias a
|
|
749
|
+
# caller reaches for first.
|
|
750
|
+
caption = opts.pop('text', None) or label_text
|
|
751
|
+
# `None` stays `None` so a tristate checkbox starts indeterminate;
|
|
752
|
+
# the widget maps `None` to unchecked when tristate is off.
|
|
753
|
+
cls = Checkbox if editor == 'checkbox' else Switch
|
|
754
|
+
return build(cls, label=caption,
|
|
755
|
+
value=bool(initial) if initial is not None else None)
|
|
714
756
|
if editor == 'slider':
|
|
715
757
|
# Slider has no label parameter, so render a stacked caption above it
|
|
716
758
|
# (the field wrappers render their own label internally).
|
|
717
759
|
if label_text:
|
|
718
760
|
Label(container, text=label_text).pack(anchor='w', pady=(0, 2))
|
|
719
|
-
return Slider
|
|
761
|
+
return build(Slider, value=initial if initial is not None else 0)
|
|
720
762
|
# Fallback: treat any unknown editor as a text field.
|
|
721
|
-
return TextField
|
|
763
|
+
return build(TextField, value=text_value, label=label_text)
|
|
722
764
|
|
|
723
765
|
def _build_buttons(self, parent: Frame, buttons: Sequence[ButtonInput]) -> None:
|
|
724
766
|
parsed = self._normalize_buttons(buttons)
|