bootstack 0.1.0a13__tar.gz → 0.1.0a15__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.0a13/src/bootstack.egg-info → bootstack-0.1.0a15}/PKG-INFO +1 -1
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/pyproject.toml +2 -2
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/__init__.py +5 -3
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_runtime/app.py +2 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/cli/pyinstaller.py +2 -1
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/events/__init__.py +6 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/events/_payloads.py +32 -0
- bootstack-0.1.0a15/src/bootstack/signals/README.md +98 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/signals/signal.py +110 -102
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/carousel.py +13 -8
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/scrollview.py +30 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/tableview/tableview.py +110 -58
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/textarea/codeeditor.py +145 -2
- bootstack-0.1.0a15/src/bootstack/widgets/_impl/composites/textarea/extensions/smart_indent.py +177 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/textarea/textarea.py +11 -2
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/toolbar.py +17 -14
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/button.py +10 -1
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/codeeditor.py +163 -21
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/datatable.py +14 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/menubutton.py +23 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/scrollview.py +52 -2
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/spinnerfield.py +1 -1
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/splitview.py +61 -3
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/textarea.py +20 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/timefield.py +2 -2
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/toolbar.py +41 -18
- {bootstack-0.1.0a13 → bootstack-0.1.0a15/src/bootstack.egg-info}/PKG-INFO +1 -1
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/tests/test_public_surface.py +16 -0
- bootstack-0.1.0a13/src/bootstack/signals/README.md +0 -112
- bootstack-0.1.0a13/src/bootstack/widgets/_impl/composites/textarea/extensions/smart_indent.py +0 -87
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/LICENSE +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/MANIFEST.in +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/NOTICE +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/README.md +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/setup.cfg +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/__main__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_core/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_core/capabilities/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_core/capabilities/after.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_core/capabilities/bind.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_core/capabilities/bindtags.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_core/capabilities/busy.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_core/capabilities/clipboard.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_core/capabilities/focus.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_core/capabilities/grab.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_core/capabilities/grid.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_core/capabilities/localization.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_core/capabilities/pack.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_core/capabilities/place.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_core/capabilities/selection.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_core/capabilities/signals.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_core/capabilities/winfo.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_core/colorutils.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_core/exceptions.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_core/images.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_core/mixins/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_core/mixins/ttk_state.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_core/mixins/widget.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_core/paths.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_core/publisher.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_core/variables.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_runtime/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_runtime/base_window.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_runtime/events.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_runtime/shortcuts.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_runtime/tk_patch.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_runtime/toplevel.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_runtime/utility.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_runtime/visual_focus.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/_runtime/window_utilities.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/bootstack.ico +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/bootstack.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/badge-pill.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/badge-square.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/button-compact.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/button-default.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/buttongroup-after-h-compact.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/buttongroup-after-h-default.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/buttongroup-after-v-compact.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/buttongroup-after-v-default.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/buttongroup-before-h-compact.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/buttongroup-before-h-default.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/buttongroup-before-v-compact.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/buttongroup-before-v-default.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/buttongroup-center-h-compact.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/buttongroup-center-h-default.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/buttongroup-center-v-compact.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/buttongroup-center-v-default.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/card.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/checkbox-checked.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/checkbox-indeterminate.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/checkbox-unchecked.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/field.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/input-addon-compact.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/input-addon-default.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/input-compact.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/input-default.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/list-item-separated.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/list-item.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/listrow-compact.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/listrow-default.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/manifest.toml +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/menu-item.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/navitem-compact.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/navitem-default.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/progressbar-h-compact.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/progressbar-h-default.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/progressbar-v-compact.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/progressbar-v-default.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/radiobutton.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/scrollbar-horizontal.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/scrollbar-vertical.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/slider-handle.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/slider-track-h.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/slider-track-v.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/switch-off.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/switch-on.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/tab-h.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/elements/tab-v.png +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/icons/bootstrap.ttf +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/icons/glyphmap.json +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/icons/icon_metrics.json +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/ar/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/ar/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/bg/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/bg/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/cs/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/cs/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/da/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/da/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/de/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/de/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/en/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/en/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/es/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/es/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/fr/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/fr/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/he/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/he/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/hi/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/hi/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/it/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/it/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/ja/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/ja/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/ko/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/ko/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/nb/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/nb/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/nl/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/nl/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/pl/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/pl/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/pt/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/pt/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/sl/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/sl/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/sv/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/sv/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/tr/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/tr/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/cli/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/cli/__main__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/cli/add.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/cli/appicon.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/cli/build.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/cli/config.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/cli/demo.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/cli/doctor.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/cli/icons.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/cli/promote.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/cli/run.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/cli/start.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/cli/templates/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/clipboard.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/constants.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/data/README.md +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/data/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/data/_observable.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/data/base.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/data/file_source.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/data/memory_source.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/data/query.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/data/readers.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/data/sqlite_source.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/data/types.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/data/writers.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/dialogs/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/dialogs/_impl/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/dialogs/_impl/colorchooser.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/dialogs/_impl/datedialog.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/dialogs/_impl/dialog.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/dialogs/_impl/filterdialog.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/dialogs/_impl/fontdialog.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/dialogs/_impl/formdialog.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/dialogs/_impl/message.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/dialogs/_impl/query.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/errors.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/events/_event.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/events/_subscription.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/i18n/README.md +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/i18n/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/i18n/catalog.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/i18n/intl_format.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/i18n/msgcat.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/i18n/specs.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/images.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/py.typed +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/scheduling/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/scheduling/_schedule.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/shortcuts.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/signals/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/signals/integration.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/signals/types.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/store.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/streams/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/streams/_stream.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/badge.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/button.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/buttongroup.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/calendar.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/checkbutton.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/combobox.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/contextmenu.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/entry.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/expander.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/field.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/frame.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/label.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/labelframe.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/listview.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/menubar.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/menubutton.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/panedwindow.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/progressbar.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/radiobutton.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/scale.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/scrollbar.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/separator.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/sidenav.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/sizegrip.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/spinbox.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/switch.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/tabitem.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/togglegroup.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/toolbutton.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/tooltip.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/treeview.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders/utils.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders_tk/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/builders_tk/defaults.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/element.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/fonts.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/style.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/style_builder_base.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/style_builder_mixed.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/style_builder_tk.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/style_builder_ttk.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/style_resolver.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/theme.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/theme_provider.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/themes/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/tk_patch.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/token_maps.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/types.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/typography.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/style/utility.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/types.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/validation/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/validation/types.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/validation/validation_result.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/validation/validation_rules.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_core/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_core/app_config.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_core/base.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_core/container.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_core/context.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_core/events.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_core/field_mixin.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_core/icon_image_props.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_core/image_binding.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_core/navmodel.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_core/options.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_core/selection_group.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_core/window_controls.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_core/window_menu.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/_internal/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/_internal/wrapper_base.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/_parts/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/_parts/numberentry_part.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/_parts/spinnerentry_part.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/_parts/textentry_part.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/_dateutils.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/_image_fit.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/accordion.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/avatar.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/buttongroup.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/calendar.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/chart.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/compositeframe.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/contextmenu.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/dateentry.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/dropdownbutton.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/expander.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/field.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/form.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/gallery.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/list/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/list/listitem.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/list/listview.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/menu/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/menu/model.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/menu/render_native.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/menu/render_themed.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/meter.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/numericentry.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/pagestack.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/passwordentry.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/pathentry.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/picture.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/radiogroup.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/scrolledtext.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/scrolledtext.pyi +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/selectbox.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/shell/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/shell/content_host.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/shell/layout.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/shell/nav_panel.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/shell/providers.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/shell/rail.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/shell/shell.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/shell/workspace.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/sidenav/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/sidenav/header.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/sidenav/separator.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/slider/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/slider/_shared.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/slider/rangeslider.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/slider/slider.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/spinnerentry.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/tableview/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/tableview/types.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/tabs/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/tabs/tabitem.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/tabs/tabs.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/tabs/tabview.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/textarea/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/textarea/change.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/textarea/core.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/textarea/decoration.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/textarea/diff.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/textarea/extensions/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/textarea/extensions/bracket_matcher.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/textarea/extensions/indent_guides.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/textarea/extensions/line_numbers.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/textarea/extensions/pygments_highlighter.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/textarea/filter.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/textarea/search_overlay.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/textarea/sidebar.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/textarea/style_registry.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/textarea/undo.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/textentry.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/timeentry.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/toast.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/toast_stack.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/togglegroup.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/tooltip.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/tree/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/tree/source_binding.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/tree/treeitem.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/tree/treenode.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/tree/treeview.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/mixins/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/mixins/configure_mixin.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/mixins/entry_mixin.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/mixins/font_mixin.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/mixins/icon_mixin.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/mixins/localization_mixin.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/mixins/signal_mixin.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/mixins/validation_mixin.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/primitives/__init__.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/primitives/_menubutton.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/primitives/badge.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/primitives/button.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/primitives/card.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/primitives/checkbutton.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/primitives/checktoggle.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/primitives/combobox.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/primitives/entry.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/primitives/flexframe.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/primitives/frame.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/primitives/gridframe.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/primitives/label.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/primitives/labelframe.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/primitives/optionmenu.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/primitives/packframe.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/primitives/panedwindow.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/primitives/progressbar.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/primitives/radiobutton.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/primitives/radiotoggle.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/primitives/scrollbar.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/primitives/separator.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/primitives/sizegrip.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/primitives/spinbox.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/primitives/switch.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/primitives/treeview.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/app.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/appshell.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/avatar.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/boolean_controls.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/buttongroup.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/calendar.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/card.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/carousel.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/chart.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/contextmenu.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/datefield.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/divider.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/expander.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/form.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/gallery.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/gauge.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/grid.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/groupbox.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/label.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/listview.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/numberfield.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/pagestack.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/passwordfield.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/pathfield.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/picture.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/progressbar.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/radio_variants.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/radiogroup.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/scrollbar.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/select.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/selectbutton.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/sidebar_toggle.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/sizegrip.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/slider.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/spinbox.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/stacks.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/statusbar.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/tabs.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/textfield.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/theme_toggle.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/toast.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/togglegroup.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/tooltip.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/tree.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/types.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/window.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack.egg-info/SOURCES.txt +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack.egg-info/dependency_links.txt +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack.egg-info/entry_points.txt +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack.egg-info/requires.txt +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack.egg-info/top_level.txt +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/tests/test_images.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/tests/test_images_gui.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/tests/test_intl_format.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/tests/test_navmodel.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/tests/test_store.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/tests/test_theme_from_existing.py +0 -0
- {bootstack-0.1.0a13 → bootstack-0.1.0a15}/tests/test_validation_rules.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.0a15
|
|
4
4
|
Summary: From idea to a shipped desktop app, fast — a declarative, reactive, batteries-included Python UI framework with 60+ widgets, semantic theming, and built-in packaging.
|
|
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.1.
|
|
7
|
+
version = "0.1.0a15"
|
|
8
8
|
description = "From idea to a shipped desktop app, fast — a declarative, reactive, batteries-included Python UI framework with 60+ widgets, semantic theming, and built-in packaging."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.12"
|
|
@@ -109,7 +109,7 @@ where = ["src"]
|
|
|
109
109
|
]
|
|
110
110
|
|
|
111
111
|
[tool.bumpversion]
|
|
112
|
-
current_version = "0.1.
|
|
112
|
+
current_version = "0.1.0a15"
|
|
113
113
|
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)((?P<pre>a|b|rc)(?P<pre_n>\\d+))?"
|
|
114
114
|
serialize = [
|
|
115
115
|
"{major}.{minor}.{patch}{pre}{pre_n}",
|
|
@@ -27,9 +27,11 @@ submodules — for example::
|
|
|
27
27
|
|
|
28
28
|
See the "API overview" in the documentation for the full map.
|
|
29
29
|
"""
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
__version__ = _pkg_version("bootstack")
|
|
30
|
+
try:
|
|
31
|
+
from importlib.metadata import version as _pkg_version
|
|
32
|
+
__version__ = _pkg_version("bootstack")
|
|
33
|
+
except Exception:
|
|
34
|
+
__version__ = "unknown"
|
|
33
35
|
|
|
34
36
|
# ── Runtime patches — must run before widgets are created ─────────────────────
|
|
35
37
|
from bootstack._runtime.tk_patch import install_tk_autostyle as _install_autostyle
|
|
@@ -694,10 +694,12 @@ class App(BaseWindow, WidgetCapabilitiesMixin, tkinter.Tk):
|
|
|
694
694
|
from bootstack.style.typography import Typography
|
|
695
695
|
from bootstack._core.images import _ImageService
|
|
696
696
|
from bootstack._runtime.visual_focus import reset_visual_focus_root
|
|
697
|
+
from bootstack.signals.signal import reset_realized_signals
|
|
697
698
|
reset_style()
|
|
698
699
|
Typography.reset()
|
|
699
700
|
_ImageService.clear_cache()
|
|
700
701
|
reset_visual_focus_root()
|
|
702
|
+
reset_realized_signals()
|
|
701
703
|
gc.collect()
|
|
702
704
|
except Exception:
|
|
703
705
|
pass
|
|
@@ -128,11 +128,12 @@ if config.build and config.build.datas.include:
|
|
|
128
128
|
# Collect package data (themes, fonts, icon glyphmaps, locales, etc.)
|
|
129
129
|
# =============================================================================
|
|
130
130
|
|
|
131
|
-
from PyInstaller.utils.hooks import collect_data_files
|
|
131
|
+
from PyInstaller.utils.hooks import collect_data_files, copy_metadata
|
|
132
132
|
|
|
133
133
|
for _pkg in ("bootstack",):
|
|
134
134
|
try:
|
|
135
135
|
datas += collect_data_files(_pkg)
|
|
136
|
+
datas += copy_metadata(_pkg)
|
|
136
137
|
except Exception as _e: # pragma: no cover
|
|
137
138
|
print(f"Warning: Could not collect data files from {{_pkg}}: {{_e}}")
|
|
138
139
|
|
|
@@ -32,6 +32,8 @@ from bootstack.events._payloads import (
|
|
|
32
32
|
RangeSliderEvent,
|
|
33
33
|
RowEvent,
|
|
34
34
|
RowsEvent,
|
|
35
|
+
SashMoveEvent,
|
|
36
|
+
ScrollEvent,
|
|
35
37
|
SelectionEvent,
|
|
36
38
|
SliderCommitEvent,
|
|
37
39
|
SliderEvent,
|
|
@@ -97,4 +99,8 @@ __all__ = [
|
|
|
97
99
|
# Payloads — data source
|
|
98
100
|
"DataChangeEvent",
|
|
99
101
|
"ChangeKind",
|
|
102
|
+
# Payloads — split view
|
|
103
|
+
"SashMoveEvent",
|
|
104
|
+
# Payloads — scroll view
|
|
105
|
+
"ScrollEvent",
|
|
100
106
|
]
|
|
@@ -487,3 +487,35 @@ class DataChangeEvent:
|
|
|
487
487
|
record: Mapping[str, Any] | None = None
|
|
488
488
|
"""The affected record (or the applied updates) where cheaply available on
|
|
489
489
|
`insert`/`update`; `None` otherwise."""
|
|
490
|
+
|
|
491
|
+
|
|
492
|
+
# ---------------------------------------------------------------------------
|
|
493
|
+
# SplitView
|
|
494
|
+
# ---------------------------------------------------------------------------
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
@dataclass(frozen=True, slots=True)
|
|
498
|
+
class SashMoveEvent:
|
|
499
|
+
"""Fires when a `SplitView` sash is released after being dragged."""
|
|
500
|
+
|
|
501
|
+
index: int = 0
|
|
502
|
+
"""Zero-based index of the sash that moved."""
|
|
503
|
+
|
|
504
|
+
position: int = 0
|
|
505
|
+
"""New pixel position of the sash in pixels from the leading edge."""
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
# ---------------------------------------------------------------------------
|
|
509
|
+
# ScrollView
|
|
510
|
+
# ---------------------------------------------------------------------------
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
@dataclass(frozen=True, slots=True)
|
|
514
|
+
class ScrollEvent:
|
|
515
|
+
"""Fires when a `ScrollView`'s viewport position changes."""
|
|
516
|
+
|
|
517
|
+
y: float = 0.0
|
|
518
|
+
"""Vertical scroll position — 0.0 (top) to 1.0 (bottom)."""
|
|
519
|
+
|
|
520
|
+
x: float = 0.0
|
|
521
|
+
"""Horizontal scroll position — 0.0 (left) to 1.0 (right)."""
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
Signals for bootstack
|
|
2
|
+
=====================
|
|
3
|
+
|
|
4
|
+
Lightweight reactive state. A ``Signal[T]`` holds a value, notifies subscribers
|
|
5
|
+
when it changes, and can be bound two-way to widgets. It is backed by a Tk
|
|
6
|
+
variable, but that variable is created lazily, so the Tk surface never leaks
|
|
7
|
+
into the public API.
|
|
8
|
+
|
|
9
|
+
> The user-facing guide is ``docs/reference/signals.rst`` (teaching) and the
|
|
10
|
+
> API Reference page for ``bootstack.signals`` (lookup). This README covers the
|
|
11
|
+
> package internals; keep it in sync with ``signal.py``.
|
|
12
|
+
|
|
13
|
+
Architecture
|
|
14
|
+
- ``Signal[T]`` (public): the reactive cell — ``signal()`` to read, ``set()`` to
|
|
15
|
+
write, ``subscribe()`` to observe, ``map()`` to derive.
|
|
16
|
+
- Lazy Tk-var realization: ``Signal(...)`` creates **no** Tk variable at
|
|
17
|
+
construction, so a signal can be created at module level (before any ``App``).
|
|
18
|
+
The backing variable is realized on first bind/escape-hatch access against the
|
|
19
|
+
running interpreter, and re-realized cleanly across ``App`` lifecycles.
|
|
20
|
+
- Object mode: values that are not Tk-native (anything other than
|
|
21
|
+
``bool``/``int``/``float``/``str``/``set`` — e.g. a ``date`` or a dataclass)
|
|
22
|
+
are held as the authoritative Python object; the Tk variable is used only as a
|
|
23
|
+
change-notification bus. Native values are stored in the Tk variable directly.
|
|
24
|
+
- ``_SignalTrace`` (internal): manages the Tcl variable trace
|
|
25
|
+
(``trace_add``/``trace_remove``).
|
|
26
|
+
|
|
27
|
+
Key behaviors
|
|
28
|
+
- Read / write: ``signal()`` returns the current value; ``signal.set(v)`` updates
|
|
29
|
+
it. A ``set()`` to an equal value is a no-op (no notification).
|
|
30
|
+
- Subscriptions: ``subscribe(callback, *, immediate=False)`` returns a
|
|
31
|
+
``streams.Handle``; call ``handle.cancel()`` to unsubscribe. ``immediate=True``
|
|
32
|
+
fires the callback once with the current value at subscribe time.
|
|
33
|
+
- Derived signals: ``map(transform)`` returns a new signal that follows this one.
|
|
34
|
+
A weak reference keeps the parent from holding the derived signal alive.
|
|
35
|
+
- Robustness: the last value is cached and returned even if the backing variable
|
|
36
|
+
has been dropped (e.g. between ``App`` lifecycles).
|
|
37
|
+
- Escape hatch: ``Signal.from_variable(tk_var)`` wraps an existing Tk variable,
|
|
38
|
+
and ``signal.var`` exposes the backing variable. These are the only Tk-aware
|
|
39
|
+
paths; everything else stays Tk-free.
|
|
40
|
+
|
|
41
|
+
Usage
|
|
42
|
+
1) Quick start (works at module level — no ``App`` required)
|
|
43
|
+
```python
|
|
44
|
+
from bootstack.signals import Signal
|
|
45
|
+
|
|
46
|
+
count = Signal(0)
|
|
47
|
+
print(count()) # -> 0
|
|
48
|
+
count.set(1)
|
|
49
|
+
print(count()) # -> 1
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
2) Two-way binding to a widget
|
|
53
|
+
```python
|
|
54
|
+
import bootstack as bs
|
|
55
|
+
|
|
56
|
+
with bs.App() as app:
|
|
57
|
+
name = bs.Signal("")
|
|
58
|
+
bs.TextField(textsignal=name) # edits flow into the signal
|
|
59
|
+
bs.Label(textsignal=name.map(lambda v: f"Hello, {v}!")) # derived display
|
|
60
|
+
app.run()
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
3) Subscribing and unsubscribing
|
|
64
|
+
```python
|
|
65
|
+
import bootstack as bs
|
|
66
|
+
|
|
67
|
+
with bs.App() as app:
|
|
68
|
+
flag = bs.Signal(False)
|
|
69
|
+
|
|
70
|
+
def on_flag(value):
|
|
71
|
+
print("flag:", value)
|
|
72
|
+
|
|
73
|
+
handle = flag.subscribe(on_flag, immediate=True) # prints: flag: False
|
|
74
|
+
flag.set(True) # prints: flag: True
|
|
75
|
+
handle.cancel() # stop observing
|
|
76
|
+
app.run()
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
4) Typed (object-mode) values
|
|
80
|
+
```python
|
|
81
|
+
from datetime import date
|
|
82
|
+
import bootstack as bs
|
|
83
|
+
|
|
84
|
+
with bs.App():
|
|
85
|
+
due = bs.Signal(date.today())
|
|
86
|
+
bs.DateField(signal=due) # binds the typed value
|
|
87
|
+
print(type(due())) # -> <class 'datetime.date'> (not str)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Import path
|
|
91
|
+
- ``import bootstack as bs; bs.Signal``
|
|
92
|
+
- ``from bootstack.signals import Signal``
|
|
93
|
+
|
|
94
|
+
Notes
|
|
95
|
+
- The UI toolkit is not thread-safe. Marshal cross-thread updates onto the UI
|
|
96
|
+
via the framework's scheduling, not by touching the signal from a worker
|
|
97
|
+
thread.
|
|
98
|
+
- Keep subscriber callbacks fast; offload long-running work.
|
|
@@ -10,43 +10,43 @@ from bootstack.streams import Handle
|
|
|
10
10
|
T = TypeVar("T")
|
|
11
11
|
U = TypeVar("U")
|
|
12
12
|
|
|
13
|
+
# Weak registry of all realized signals. Cleared on App.destroy() (when no
|
|
14
|
+
# other App is live) so module-level signals can be re-realized against the
|
|
15
|
+
# next App's interpreter without dangling against a dead one.
|
|
16
|
+
_realized: "weakref.WeakSet[Signal]" = weakref.WeakSet()
|
|
13
17
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
# Global subscriber ID counter — unique across all Signal instances so that
|
|
19
|
+
# Handle cancellation never accidentally removes the wrong entry.
|
|
20
|
+
_sub_counter = count(1)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def reset_realized_signals() -> None:
|
|
24
|
+
"""Drop the Tk var from every realized signal.
|
|
25
|
+
|
|
26
|
+
Called on App.destroy() when no other App is live. Module-level signals
|
|
27
|
+
return to pending (unrealized) state and re-realize transparently the next
|
|
28
|
+
time a widget inside a new App binds them via .var / .name / .tk.
|
|
18
29
|
"""
|
|
30
|
+
for sig in list(_realized):
|
|
31
|
+
try:
|
|
32
|
+
sig._drop_var()
|
|
33
|
+
except Exception:
|
|
34
|
+
pass
|
|
19
35
|
|
|
20
|
-
def __init__(self, tk_var: tk.Variable):
|
|
21
|
-
"""
|
|
22
|
-
Initialize a trace manager for a tkinter variable.
|
|
23
36
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
37
|
+
class _SignalTrace:
|
|
38
|
+
"""Manages the single bridge Tk trace on a realized Signal."""
|
|
39
|
+
|
|
40
|
+
def __init__(self, tk_var: tk.Variable):
|
|
27
41
|
self._var = tk_var
|
|
28
|
-
# Map trace id -> (operation, callback)
|
|
29
42
|
self._traces: dict[str, tuple[TraceOperation, Callable[..., Any]]] = {}
|
|
30
43
|
|
|
31
|
-
def callbacks(self) -> tuple[str, ...]:
|
|
32
|
-
"""
|
|
33
|
-
Return all currently active trace IDs.
|
|
34
|
-
|
|
35
|
-
Returns:
|
|
36
|
-
A tuple of trace ID strings.
|
|
37
|
-
"""
|
|
38
|
-
return tuple(self._traces.keys())
|
|
39
|
-
|
|
40
44
|
def add(
|
|
41
45
|
self,
|
|
42
46
|
operation: TraceOperation,
|
|
43
47
|
callback: Callable[[T], Any],
|
|
44
48
|
get_value: Callable[[], T],
|
|
45
49
|
) -> str:
|
|
46
|
-
"""
|
|
47
|
-
Add a new trace that calls a callback when the variable is written.
|
|
48
|
-
"""
|
|
49
|
-
|
|
50
50
|
def traced_callback(name: str, index: str, mode: str) -> None:
|
|
51
51
|
callback(get_value())
|
|
52
52
|
|
|
@@ -58,9 +58,6 @@ class _SignalTrace:
|
|
|
58
58
|
return fid
|
|
59
59
|
|
|
60
60
|
def remove(self, fid: str) -> None:
|
|
61
|
-
"""
|
|
62
|
-
Remove a trace by ID. Safe if already removed or variable destroyed.
|
|
63
|
-
"""
|
|
64
61
|
op_cb = self._traces.pop(fid, None)
|
|
65
62
|
if op_cb is None:
|
|
66
63
|
return
|
|
@@ -68,7 +65,6 @@ class _SignalTrace:
|
|
|
68
65
|
try:
|
|
69
66
|
self._var.trace_remove(operation, fid)
|
|
70
67
|
except tk.TclError:
|
|
71
|
-
# Variable may be unset/destroyed; ignore
|
|
72
68
|
pass
|
|
73
69
|
|
|
74
70
|
|
|
@@ -82,6 +78,11 @@ class Signal(Generic[T]):
|
|
|
82
78
|
|
|
83
79
|
Bind a signal to a widget by passing it as `textsignal=` for text-bearing
|
|
84
80
|
widgets, or `signal=` for boolean and numeric widgets.
|
|
81
|
+
|
|
82
|
+
Signals may be constructed at module level (before `bs.App()` exists). The
|
|
83
|
+
backing Tk variable is created lazily on the first widget binding and torn
|
|
84
|
+
down when the App is destroyed, so the same signal can be reused across
|
|
85
|
+
successive App lifecycles.
|
|
85
86
|
"""
|
|
86
87
|
|
|
87
88
|
_cnt = count(1)
|
|
@@ -90,29 +91,22 @@ class Signal(Generic[T]):
|
|
|
90
91
|
self._name = name or f"SIG{next(self._cnt)}"
|
|
91
92
|
self._type: Type[T] = type(value)
|
|
92
93
|
self._master: tk.Misc | None = master
|
|
93
|
-
# An object-typed signal (e.g. a date/time, or any custom object) has no
|
|
94
|
-
# native Tk variable that round-trips it — a StringVar would hand back the
|
|
95
|
-
# string form. In that case the cached Python value is the source of truth
|
|
96
|
-
# and the backing variable serves only as the write-trace notification bus.
|
|
97
94
|
self._object_mode = not self._is_tk_native(value)
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
# Map fid -> callback to allow multiple subscriptions of same function
|
|
101
|
-
self._subscribers: dict[str, Callable[[T], Any]] = {}
|
|
102
|
-
# Reverse index: callback -> set of fids
|
|
103
|
-
self._callback_index: dict[Callable[[T], Any], set[str]] = {}
|
|
104
|
-
# Cache last known value for robustness when Tcl variable is torn down
|
|
95
|
+
# _last is always the authoritative Python value — before realization it
|
|
96
|
+
# is the only store; after realization it stays in sync via the bridge.
|
|
105
97
|
self._last: T = value
|
|
98
|
+
# Tk var and bridge trace — None until the first widget binding.
|
|
99
|
+
self._var: tk.Variable | None = None
|
|
100
|
+
self._trace: _SignalTrace | None = None
|
|
101
|
+
self._bridge_fid: str | None = None
|
|
102
|
+
# Python-owned subscriber list (int id → callback). The bridge trace fans
|
|
103
|
+
# these out when a widget writes the Tk var; set() notifies them directly
|
|
104
|
+
# while unrealized. Replaces the old one-Tk-trace-per-subscriber model.
|
|
105
|
+
self._subscribers: dict[int, Callable[[T], Any]] = {}
|
|
106
106
|
|
|
107
107
|
@staticmethod
|
|
108
108
|
def _is_tk_native(value: Any) -> bool:
|
|
109
|
-
"""Whether a value maps to a Tk variable that round-trips it losslessly.
|
|
110
|
-
|
|
111
|
-
Booleans, ints, floats, strings, and sets each have a backing Tk
|
|
112
|
-
variable that returns the same Python type on read. Any other value
|
|
113
|
-
(a `date`, `time`, or arbitrary object) does not, so it is held as a
|
|
114
|
-
Python object instead.
|
|
115
|
-
"""
|
|
109
|
+
"""Whether a value maps to a Tk variable that round-trips it losslessly."""
|
|
116
110
|
return isinstance(value, (bool, int, float, str, set))
|
|
117
111
|
|
|
118
112
|
def _create_variable(self, value: T) -> tk.Variable:
|
|
@@ -127,23 +121,44 @@ class Signal(Generic[T]):
|
|
|
127
121
|
else:
|
|
128
122
|
return tk.StringVar(master=self._master, name=self._name, value=value)
|
|
129
123
|
|
|
130
|
-
def
|
|
131
|
-
"""
|
|
132
|
-
Get the current value of the signal.
|
|
124
|
+
def _realize(self) -> None:
|
|
125
|
+
"""Create the backing Tk variable and wire the single bridge trace.
|
|
133
126
|
|
|
134
|
-
|
|
135
|
-
|
|
127
|
+
Idempotent — safe to call multiple times. Only runs inside an App
|
|
128
|
+
context (widget bindings are always inside one), so a live interpreter
|
|
129
|
+
is guaranteed.
|
|
136
130
|
"""
|
|
137
|
-
if self.
|
|
138
|
-
|
|
139
|
-
|
|
131
|
+
if self._var is not None:
|
|
132
|
+
return
|
|
133
|
+
self._var = self._create_variable(self._last)
|
|
134
|
+
self._trace = _SignalTrace(self._var)
|
|
135
|
+
|
|
136
|
+
def _bridge(value: T) -> None:
|
|
137
|
+
if not self._object_mode:
|
|
138
|
+
self._last = value
|
|
139
|
+
for cb in list(self._subscribers.values()):
|
|
140
|
+
cb(self._last)
|
|
141
|
+
|
|
142
|
+
self._bridge_fid = self._trace.add("write", _bridge, self)
|
|
143
|
+
_realized.add(self)
|
|
144
|
+
|
|
145
|
+
def _drop_var(self) -> None:
|
|
146
|
+
"""Release the Tk var and bridge trace (called by reset_realized_signals)."""
|
|
147
|
+
if self._trace is not None and self._bridge_fid is not None:
|
|
148
|
+
self._trace.remove(self._bridge_fid)
|
|
149
|
+
self._var = None
|
|
150
|
+
self._trace = None
|
|
151
|
+
self._bridge_fid = None
|
|
152
|
+
|
|
153
|
+
def __call__(self) -> T:
|
|
154
|
+
"""Get the current value of the signal."""
|
|
155
|
+
if self._var is None or self._object_mode:
|
|
140
156
|
return self._last
|
|
141
157
|
try:
|
|
142
158
|
value = self._var.get()
|
|
143
|
-
self._last = value
|
|
159
|
+
self._last = value
|
|
144
160
|
return value
|
|
145
161
|
except tk.TclError:
|
|
146
|
-
# Return last known value when underlying var is destroyed/unset
|
|
147
162
|
return self._last
|
|
148
163
|
|
|
149
164
|
@classmethod
|
|
@@ -166,7 +181,6 @@ class Signal(Generic[T]):
|
|
|
166
181
|
Returns:
|
|
167
182
|
A Signal bound to the provided tk_var.
|
|
168
183
|
"""
|
|
169
|
-
# Infer Python type from the tk variable if not explicitly provided
|
|
170
184
|
if coerce is None:
|
|
171
185
|
if isinstance(tk_var, tk.BooleanVar):
|
|
172
186
|
py_type: Type[Any] = bool
|
|
@@ -181,23 +195,15 @@ class Signal(Generic[T]):
|
|
|
181
195
|
else:
|
|
182
196
|
py_type = coerce
|
|
183
197
|
|
|
184
|
-
|
|
185
|
-
self = cls.__new__(cls) # bypass __init__
|
|
198
|
+
self = cls.__new__(cls)
|
|
186
199
|
self._name = name or getattr(tk_var, "_name", str(tk_var))
|
|
187
200
|
self._type = py_type # type: ignore[assignment]
|
|
188
|
-
# Wrapping an existing Tk variable: it always round-trips its own native
|
|
189
|
-
# type, so object mode never applies here.
|
|
190
201
|
self._object_mode = False
|
|
191
|
-
self._var = tk_var
|
|
192
|
-
self._trace = _SignalTrace(self._var)
|
|
193
|
-
self._subscribers = {}
|
|
194
|
-
self._callback_index = {}
|
|
195
|
-
# Best-effort capture of master/interpreter for reference
|
|
196
202
|
self._master = getattr(tk_var, "_master", None)
|
|
203
|
+
self._subscribers = {}
|
|
197
204
|
try:
|
|
198
205
|
current = tk_var.get() # type: ignore[assignment]
|
|
199
206
|
except tk.TclError:
|
|
200
|
-
# Fallback default per inferred type
|
|
201
207
|
if py_type is float: # type: ignore[comparison-overlap]
|
|
202
208
|
current = 0.0
|
|
203
209
|
elif py_type is int: # type: ignore[comparison-overlap]
|
|
@@ -209,6 +215,18 @@ class Signal(Generic[T]):
|
|
|
209
215
|
else:
|
|
210
216
|
current = ""
|
|
211
217
|
self._last = current # type: ignore[assignment]
|
|
218
|
+
|
|
219
|
+
# from_variable is immediately realized — the var already exists.
|
|
220
|
+
self._var = tk_var
|
|
221
|
+
self._trace = _SignalTrace(self._var)
|
|
222
|
+
|
|
223
|
+
def _bridge(value: T) -> None:
|
|
224
|
+
self._last = value
|
|
225
|
+
for cb in list(self._subscribers.values()):
|
|
226
|
+
cb(self._last)
|
|
227
|
+
|
|
228
|
+
self._bridge_fid = self._trace.add("write", _bridge, self)
|
|
229
|
+
_realized.add(self)
|
|
212
230
|
return self
|
|
213
231
|
|
|
214
232
|
def set(self, value: T) -> None:
|
|
@@ -223,9 +241,6 @@ class Signal(Generic[T]):
|
|
|
223
241
|
TypeError: If the value type does not match the signal's type (and is
|
|
224
242
|
not an `int` widened to a `float`).
|
|
225
243
|
"""
|
|
226
|
-
# Enforce the type to avoid surprises (e.g. a bool accepted for an int),
|
|
227
|
-
# but widen an int into a float-typed signal — a Slider seeded at 0 and
|
|
228
|
-
# later set to 0.5 is the common case. `type(value) is int` excludes bool.
|
|
229
244
|
if type(value) is not self._type:
|
|
230
245
|
if self._type is float and type(value) is int:
|
|
231
246
|
value = float(value) # type: ignore[assignment]
|
|
@@ -233,10 +248,17 @@ class Signal(Generic[T]):
|
|
|
233
248
|
raise TypeError(
|
|
234
249
|
f"Expected {self._type.__name__}, got {type(value).__name__}"
|
|
235
250
|
)
|
|
251
|
+
|
|
252
|
+
if self._var is None:
|
|
253
|
+
# Unrealized — notify Python subscribers directly.
|
|
254
|
+
if self._last == value:
|
|
255
|
+
return
|
|
256
|
+
self._last = value
|
|
257
|
+
for cb in list(self._subscribers.values()):
|
|
258
|
+
cb(self._last)
|
|
259
|
+
return
|
|
260
|
+
|
|
236
261
|
if self._object_mode:
|
|
237
|
-
# Reduce redundant updates by comparing the Python objects, not the
|
|
238
|
-
# var's string form. Writing the string form fires write traces, so
|
|
239
|
-
# subscribers are notified with the real object via `__call__`.
|
|
240
262
|
if self._last == value:
|
|
241
263
|
return
|
|
242
264
|
self._last = value
|
|
@@ -244,14 +266,14 @@ class Signal(Generic[T]):
|
|
|
244
266
|
self._var.set(str(value))
|
|
245
267
|
except tk.TclError:
|
|
246
268
|
pass
|
|
269
|
+
# Bridge trace fires from var.set() → notifies subscribers.
|
|
247
270
|
return
|
|
248
|
-
|
|
271
|
+
|
|
272
|
+
# Native-type, realized — let the Tk var fire the bridge trace.
|
|
249
273
|
try:
|
|
250
|
-
|
|
251
|
-
if current == value:
|
|
274
|
+
if self._var.get() == value:
|
|
252
275
|
return
|
|
253
276
|
except tk.TclError:
|
|
254
|
-
# If var is gone, proceed to set and let Tcl recreate path if possible
|
|
255
277
|
pass
|
|
256
278
|
self._var.set(value)
|
|
257
279
|
self._last = value
|
|
@@ -271,14 +293,11 @@ class Signal(Generic[T]):
|
|
|
271
293
|
A new read-only signal that stays updated with the transformed value.
|
|
272
294
|
"""
|
|
273
295
|
derived = Signal(transform(self()))
|
|
274
|
-
|
|
275
|
-
# Use weakref to avoid keeping derived alive solely via subscription
|
|
276
296
|
weak_derived = weakref.ref(derived)
|
|
277
297
|
|
|
278
298
|
def update(value: T) -> None:
|
|
279
299
|
d = weak_derived()
|
|
280
300
|
if d is None:
|
|
281
|
-
# Auto-detach if derived is GC'd
|
|
282
301
|
return
|
|
283
302
|
d.set(transform(value))
|
|
284
303
|
|
|
@@ -298,48 +317,37 @@ class Signal(Generic[T]):
|
|
|
298
317
|
A cancellable `Handle` — call `.cancel()` to stop listening, or use
|
|
299
318
|
it as a context manager to unsubscribe on exit.
|
|
300
319
|
"""
|
|
301
|
-
fid =
|
|
320
|
+
fid = next(_sub_counter)
|
|
302
321
|
self._subscribers[fid] = callback
|
|
303
|
-
self._callback_index.setdefault(callback, set()).add(fid)
|
|
304
322
|
if immediate:
|
|
305
|
-
# Call synchronously at subscription time; let any error surface to
|
|
306
|
-
# the caller rather than swallowing a real bug in the callback.
|
|
307
323
|
callback(self())
|
|
308
|
-
return Handle(lambda: self.
|
|
309
|
-
|
|
310
|
-
def _unsubscribe(self, funcid: str) -> None:
|
|
311
|
-
"""Remove a previously registered subscriber by its trace id."""
|
|
312
|
-
self._subscribers.pop(funcid, None)
|
|
313
|
-
self._trace.remove(funcid)
|
|
324
|
+
return Handle(lambda: self._subscribers.pop(fid, None))
|
|
314
325
|
|
|
315
326
|
@property
|
|
316
327
|
def name(self) -> str:
|
|
317
|
-
"""
|
|
318
|
-
|
|
319
|
-
"""
|
|
328
|
+
"""The internal Tcl variable name. Accessing this realizes the signal."""
|
|
329
|
+
self._realize()
|
|
320
330
|
return self._name
|
|
321
331
|
|
|
322
332
|
@property
|
|
323
333
|
def type(self) -> Type[T]:
|
|
324
|
-
"""
|
|
325
|
-
The original type of the signal value.
|
|
326
|
-
|
|
327
|
-
Returns:
|
|
328
|
-
A Python type (e.g., int, str).
|
|
329
|
-
"""
|
|
334
|
+
"""The original type of the signal value."""
|
|
330
335
|
return self._type
|
|
331
336
|
|
|
332
337
|
@property
|
|
333
338
|
def var(self) -> tk.Variable:
|
|
334
|
-
|
|
339
|
+
"""The backing `tk.Variable`. Accessing this realizes the signal."""
|
|
340
|
+
self._realize()
|
|
341
|
+
return self._var # type: ignore[return-value]
|
|
335
342
|
|
|
336
343
|
@property
|
|
337
344
|
def tk(self) -> tk.Variable:
|
|
338
345
|
"""Underlying `tk.Variable`. UNSUPPORTED — escape-hatch use only."""
|
|
339
|
-
|
|
346
|
+
self._realize()
|
|
347
|
+
return self._var # type: ignore[return-value]
|
|
340
348
|
|
|
341
349
|
def __str__(self) -> str:
|
|
342
350
|
return self._name
|
|
343
351
|
|
|
344
352
|
def __repr__(self) -> str:
|
|
345
|
-
return self._name
|
|
353
|
+
return self._name
|
{bootstack-0.1.0a13 → bootstack-0.1.0a15}/src/bootstack/widgets/_impl/composites/carousel.py
RENAMED
|
@@ -351,8 +351,10 @@ class Carousel(Frame):
|
|
|
351
351
|
self._stage.tag_lower(next_id)
|
|
352
352
|
if cur_id is not None:
|
|
353
353
|
self._stage.tag_lower(cur_id)
|
|
354
|
-
steps =
|
|
355
|
-
|
|
354
|
+
steps = 8
|
|
355
|
+
|
|
356
|
+
def _ease(t: float) -> float:
|
|
357
|
+
return 2 * t * t if t < 0.5 else 1 - (-2 * t + 2) ** 2 / 2
|
|
356
358
|
|
|
357
359
|
def step(i: int) -> None:
|
|
358
360
|
if i >= steps:
|
|
@@ -366,9 +368,10 @@ class Carousel(Frame):
|
|
|
366
368
|
self._transitioning = False
|
|
367
369
|
self._after_change()
|
|
368
370
|
return
|
|
369
|
-
|
|
371
|
+
t = _ease(i / steps)
|
|
372
|
+
self._stage.coords(next_id, round(d * w * (1 - t)), 0)
|
|
370
373
|
if cur_id is not None:
|
|
371
|
-
self._stage.
|
|
374
|
+
self._stage.coords(cur_id, round(-d * w * t), 0)
|
|
372
375
|
self._schedule.delay(_FRAME_MS, lambda: step(i + 1))
|
|
373
376
|
|
|
374
377
|
step(1)
|
|
@@ -381,19 +384,21 @@ class Carousel(Frame):
|
|
|
381
384
|
return
|
|
382
385
|
self._transitioning = True
|
|
383
386
|
steps = 10
|
|
387
|
+
# Pre-compute all frames up front so PhotoImage allocation doesn't happen
|
|
388
|
+
# inside the after() loop where it blocks the canvas refresh.
|
|
389
|
+
frames = [PhotoImage(PILImage.blend(cur, next_pil, i / steps)) for i in range(1, steps + 1)]
|
|
384
390
|
|
|
385
391
|
def step(i: int) -> None:
|
|
386
|
-
if i
|
|
392
|
+
if i >= len(frames):
|
|
387
393
|
self._set_current(next_pil)
|
|
388
394
|
self._transitioning = False
|
|
389
395
|
self._after_change()
|
|
390
396
|
return
|
|
391
|
-
|
|
392
|
-
self._fade_photo = PhotoImage(blended)
|
|
397
|
+
self._fade_photo = frames[i]
|
|
393
398
|
self._stage.itemconfigure(self._img_id, image=self._fade_photo)
|
|
394
399
|
self._schedule.delay(_FRAME_MS + 6, lambda: step(i + 1))
|
|
395
400
|
|
|
396
|
-
step(
|
|
401
|
+
step(0)
|
|
397
402
|
|
|
398
403
|
def _after_change(self) -> None:
|
|
399
404
|
bw, bh = self._box
|