bootstack 0.1.0a5__tar.gz → 0.1.0a7__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.0a5/src/bootstack.egg-info → bootstack-0.1.0a7}/PKG-INFO +2 -2
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/README.md +1 -1
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/pyproject.toml +2 -2
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/__init__.py +9 -4
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/api/__init__.py +2 -1
- bootstack-0.1.0a7/src/bootstack/api/menu.py +7 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/api/style.py +4 -1
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/api/widgets.py +3 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/cli/__init__.py +4 -1
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/cli/add.py +2 -2
- bootstack-0.1.0a7/src/bootstack/cli/icons.py +28 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/localization/intl_format.py +4 -4
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/datasource/sqlite_source.py +60 -53
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/dialogs/datedialog.py +38 -12
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/dialogs/dialog.py +9 -9
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/dialogs/filterdialog.py +12 -12
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/runtime/menu.py +89 -136
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/field.py +14 -8
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/typography.py +6 -6
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/appshell.py +47 -16
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/calendar.py +1 -1
- bootstack-0.1.0a7/src/bootstack/widgets/composites/dateentry.py +434 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/dropdownbutton.py +1 -3
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/field.py +43 -17
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/form.py +1 -2
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/scrollview.py +19 -10
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/selectbox.py +11 -4
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/sidenav/view.py +6 -15
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/tableview/tableview.py +21 -21
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/textentry.py +5 -8
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/timeentry.py +8 -1
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/toolbar.py +1 -1
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/parts/textentry_part.py +2 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7/src/bootstack.egg-info}/PKG-INFO +2 -2
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack.egg-info/SOURCES.txt +1 -0
- bootstack-0.1.0a5/src/bootstack/api/menu.py +0 -7
- bootstack-0.1.0a5/src/bootstack/widgets/composites/dateentry.py +0 -261
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/LICENSE +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/MANIFEST.in +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/NOTICE +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/setup.cfg +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/__main__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/api/app.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/api/constants.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/api/data.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/api/dialogs.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/api/i18n.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/api/localization.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/api/utils.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/bootstack-dark.ico +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/bootstack-light.ico +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/bootstack-transparent.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/bootstack.ico +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/bootstack.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/badge-pill.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/badge-square.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/border.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-compact.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-default.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-group-horizontal-after-compact.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-group-horizontal-after-default.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-group-horizontal-before-compact.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-group-horizontal-before-default.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-group-horizontal-center-compact.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-group-horizontal-center-default.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-group-vertical-after-compact.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-group-vertical-after-default.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-group-vertical-before-compact.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-group-vertical-before-default.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-group-vertical-center-compact.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/button-group-vertical-center-default.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/checkbox-checked.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/checkbox-indeterminate.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/checkbox-unchecked.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/field.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/input-after-compact.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/input-after-default.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/input-before-compact.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/input-before-default.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/input-compact.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/input-default.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/list-item-separated.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/list-item.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/manifest.toml +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/menu-item.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/nav-button-compact.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/nav-button-default.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/nav-icon-button-compact.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/nav-icon-button-default.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/notebook-client-border.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/notebook-tab-active.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/notebook-tab-bar.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/notebook-tab-normal.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/notebook-tab-pill.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/progress-bar-horizontal-striped.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/progress-bar-solid.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/progress-bar-thin.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/progress-bar-vertical-striped.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/radio-selected.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/radio-unselected.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/scrollbar-horizontal.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/scrollbar-vertical.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/slider-handle-focus.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/slider-handle.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/slider-track-horizontal.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/slider-track-vertical.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/switch-off.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/switch-on.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/tabs-bar-horizontal.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/tabs-bar-vertical.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/elements/tabs-pill.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/ar/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/ar/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/bg/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/cs/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/cs/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/da/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/da/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/de/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/de/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/en/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/en/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/es/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/es/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/fr/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/fr/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/he/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/he/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/hi/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/hi/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/it/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/it/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/ja/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/ja/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/ko/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/ko/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/nb/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/nb/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/nl/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/nl/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/pl/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/pl/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/pt/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/pt/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/sl/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/sl/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/sv/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/sv/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/tr/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/tr/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.mo +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.po +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/themes/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/themes/amber-dark.json +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/themes/amber-light.json +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/themes/aurora-dark.json +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/themes/aurora-light.json +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/themes/bootstrap-dark.json +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/themes/bootstrap-light.json +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/themes/classic-dark.json +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/themes/classic-light.json +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/themes/docs-dark.json +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/themes/docs-light.json +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/themes/forest-dark.json +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/themes/forest-light.json +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/themes/ocean-dark.json +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/themes/ocean-light.json +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/themes/rose-dark.json +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/themes/rose-light.json +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/badge-default.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/badge-pill.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/border.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/button-group-horizontal-after.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/button-group-horizontal-before.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/button-group-horizontal-center.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/button-group-vertical-after.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/button-group-vertical-before.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/button-group-vertical-center.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/button.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/checkbox-checked.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/checkbox-indeterminate.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/checkbox-unchecked.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/field.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/icon-button.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/input-inner.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/input-prefix.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/input-suffix.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/input.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/list-item-focus.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/list-item-separated.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/menu-item-separated.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/notebook-client-border.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/notebook-pill-active.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/notebook-pill-inactive.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/notebook-tab-active.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/notebook-tab-border.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/notebook-tab-normal.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/notebook-underline.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/progress-bar-horizontal-default.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/progress-bar-horizontal-striped.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/progress-bar-vertical-default.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/progress-bar-vertical-striped.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/progress-trough-horizontal.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/progress-trough-vertical.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/radio-selected.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/radio-unselected.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/scrollbar-horizontal-rounded.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/scrollbar-vertical-rounded.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/separator-horizontal.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/separator-vertical.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/slider-handle-focus.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/slider-handle.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/slider-track-horizontal.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/slider-track-vertical.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/switch-off.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/switch-on.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/tabs-bar-horizontal.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/tabs-bar-vertical.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/assets/widgets/tabs-pill.png +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/cli/__main__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/cli/build.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/cli/config.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/cli/demo.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/cli/doctor.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/cli/list_cmd.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/cli/promote.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/cli/pyinstaller.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/cli/run.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/cli/start.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/cli/templates/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/constants.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/after.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/bind.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/bindtags.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/busy.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/clipboard.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/focus.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/grab.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/grid.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/localization.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/pack.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/place.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/selection.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/signals.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/capabilities/winfo.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/colorutils.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/exceptions.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/images.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/localization/README.md +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/localization/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/localization/msgcat.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/localization/specs.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/mixins/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/mixins/ttk_state.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/mixins/widget.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/publisher.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/signals/README.md +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/signals/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/signals/integration.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/signals/signal.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/signals/types.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/validation/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/validation/types.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/validation/validation_result.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/validation/validation_rules.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/core/variables.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/datasource/README.md +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/datasource/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/datasource/base.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/datasource/file_source.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/datasource/memory_source.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/datasource/types.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/dialogs/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/dialogs/colorchooser.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/dialogs/colordropper.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/dialogs/fontdialog.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/dialogs/formdialog.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/dialogs/message.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/dialogs/query.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/py.typed +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/runtime/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/runtime/app.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/runtime/base_window.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/runtime/events.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/runtime/shortcuts.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/runtime/tk_patch.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/runtime/toplevel.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/runtime/utility.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/runtime/visual_focus.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/runtime/window_utilities.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/bootstyle.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/bootstyle_builder_base.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/bootstyle_builder_mixed.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/bootstyle_builder_tk.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/bootstyle_builder_ttk.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/badge.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/button.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/buttongroup.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/calendar.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/checkbutton.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/combobox.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/contextmenu.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/entry.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/expander.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/frame.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/label.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/labelframe.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/listview.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/menubar.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/menubutton.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/notebook.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/panedwindow.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/progressbar.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/radiobutton.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/scale.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/scrollbar.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/separator.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/sidenav.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/sizegrip.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/spinbox.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/switch.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/tabitem.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/toolbutton.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/tooltip.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/treeview.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders/utils.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders_tk/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/builders_tk/defaults.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/element.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/style.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/theme_provider.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/tk_patch.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/token_maps.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/types.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/style/utility.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/themes/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/themes/standard.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/themes/user.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/accordion.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/buttongroup.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/compositeframe.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/contextmenu.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/expander.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/floodgauge.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/labeledscale.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/list/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/list/listitem.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/list/listview.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/menubar.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/meter.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/numericentry.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/pagestack.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/passwordentry.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/pathentry.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/radiogroup.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/scrolledtext.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/scrolledtext.pyi +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/sidenav/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/sidenav/group.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/sidenav/header.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/sidenav/item.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/sidenav/separator.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/spinnerentry.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/tableview/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/tableview/types.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/tabs/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/tabs/tabitem.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/tabs/tabs.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/tabs/tabview.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/toast.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/togglegroup.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/composites/tooltip.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/internal/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/internal/wrapper_base.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/mixins/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/mixins/configure_mixin.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/mixins/entry_mixin.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/mixins/font_mixin.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/mixins/icon_mixin.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/mixins/localization_mixin.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/mixins/signal_mixin.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/mixins/validation_mixin.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/parts/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/parts/numberentry_part.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/parts/spinnerentry_part.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/__init__.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/badge.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/button.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/card.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/checkbutton.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/checktoggle.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/combobox.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/entry.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/frame.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/gridframe.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/label.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/labelframe.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/menubutton.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/notebook.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/optionmenu.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/packframe.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/panedwindow.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/progressbar.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/radiobutton.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/radiotoggle.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/scale.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/scrollbar.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/separator.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/sizegrip.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/spinbox.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/switch.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/primitives/treeview.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack/widgets/types.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack.egg-info/dependency_links.txt +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack.egg-info/entry_points.txt +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack.egg-info/requires.txt +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/src/bootstack.egg-info/top_level.txt +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/tests/test_togglegroup.py +0 -0
- {bootstack-0.1.0a5 → bootstack-0.1.0a7}/tests/test_variables.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.0a7
|
|
4
4
|
Summary: A full UI framework for Python desktop apps built on tkinter — rich widgets, theming, and application structure out of the box.
|
|
5
5
|
Author-email: Israel Dryer <israel.dryer@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -150,7 +150,7 @@ bs.Button(app, text="+1", command=lambda: counter.set(counter.get() + 1))
|
|
|
150
150
|
|
|
151
151
|
## Features
|
|
152
152
|
|
|
153
|
-
- **Application scaffolding** — `App` for blank windows, `AppShell` for toolbar + sidebar + page-stack apps,
|
|
153
|
+
- **Application scaffolding** — `App` for blank windows, `AppShell` for toolbar + sidebar + page-stack apps, undecorated windows with custom chrome
|
|
154
154
|
- **60+ themed widgets** — ttk-derived primitives plus higher-level composites (TableView, Calendar, DateEntry, Form, FloodGauge, Meter, ToggleGroup, PageStack, Toast, Tooltip, and more)
|
|
155
155
|
- **9 dialogs** — Message, Query, ColorChooser, ColorDropper, DateDialog, FontDialog, FilterDialog, FormDialog, plus a `Dialog` base
|
|
156
156
|
- **Layout containers** — `PackFrame` and `GridFrame` for declarative layouts; `ScrollView`, `PanedWindow`, `Accordion`, `Card`, `Expander`
|
|
@@ -116,7 +116,7 @@ bs.Button(app, text="+1", command=lambda: counter.set(counter.get() + 1))
|
|
|
116
116
|
|
|
117
117
|
## Features
|
|
118
118
|
|
|
119
|
-
- **Application scaffolding** — `App` for blank windows, `AppShell` for toolbar + sidebar + page-stack apps,
|
|
119
|
+
- **Application scaffolding** — `App` for blank windows, `AppShell` for toolbar + sidebar + page-stack apps, undecorated windows with custom chrome
|
|
120
120
|
- **60+ themed widgets** — ttk-derived primitives plus higher-level composites (TableView, Calendar, DateEntry, Form, FloodGauge, Meter, ToggleGroup, PageStack, Toast, Tooltip, and more)
|
|
121
121
|
- **9 dialogs** — Message, Query, ColorChooser, ColorDropper, DateDialog, FontDialog, FilterDialog, FormDialog, plus a `Dialog` base
|
|
122
122
|
- **Layout containers** — `PackFrame` and `GridFrame` for declarative layouts; `ScrollView`, `PanedWindow`, `Accordion`, `Card`, `Expander`
|
|
@@ -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.0a7"
|
|
8
8
|
description = "A full UI framework for Python desktop apps built on tkinter — rich widgets, theming, and application structure out of the box."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.12"
|
|
@@ -82,7 +82,7 @@ where = ["src"]
|
|
|
82
82
|
]
|
|
83
83
|
|
|
84
84
|
[tool.bumpversion]
|
|
85
|
-
current_version = "0.1.
|
|
85
|
+
current_version = "0.1.0a7"
|
|
86
86
|
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)((?P<pre>a|b|rc)(?P<pre_n>\\d+))?"
|
|
87
87
|
serialize = [
|
|
88
88
|
"{major}.{minor}.{patch}{pre}{pre_n}",
|
|
@@ -45,11 +45,12 @@ from ttkbootstrap_icons_bs import BootstrapIcon # noqa: E402
|
|
|
45
45
|
# (see constants.py which re-exports from core.constants)
|
|
46
46
|
|
|
47
47
|
if TYPE_CHECKING:
|
|
48
|
-
from bootstack.api.menu import MenuManager, create_menu
|
|
48
|
+
from bootstack.api.menu import MenuManager, create_menu, create_menu_items
|
|
49
49
|
from bootstack.api.app import App, AppShell, App as Window, Toplevel, AppSettings, get_app_settings, get_current_app, Shortcuts, Shortcut, get_shortcuts
|
|
50
50
|
from bootstack.api.style import (
|
|
51
51
|
Font,
|
|
52
52
|
Style,
|
|
53
|
+
Typography,
|
|
53
54
|
get_style,
|
|
54
55
|
get_style_builder,
|
|
55
56
|
get_theme,
|
|
@@ -58,6 +59,7 @@ if TYPE_CHECKING:
|
|
|
58
59
|
toggle_theme,
|
|
59
60
|
get_theme_color,
|
|
60
61
|
get_themes,
|
|
62
|
+
register_user_theme,
|
|
61
63
|
)
|
|
62
64
|
from bootstack.api.widgets import (
|
|
63
65
|
Button,
|
|
@@ -80,6 +82,8 @@ if TYPE_CHECKING:
|
|
|
80
82
|
Label,
|
|
81
83
|
LabelFrame,
|
|
82
84
|
LabeledScale,
|
|
85
|
+
ListItem,
|
|
86
|
+
ListView,
|
|
83
87
|
MenuBar,
|
|
84
88
|
MenuButton,
|
|
85
89
|
Meter,
|
|
@@ -153,15 +157,16 @@ _MODULE_EXPORTS = {
|
|
|
153
157
|
# Application & Windows (includes menu and shortcuts)
|
|
154
158
|
"bootstack.api.app": [
|
|
155
159
|
"App", "AppShell", "Toplevel", "Window", "AppSettings", "get_app_settings", "get_current_app",
|
|
156
|
-
"MenuManager", "create_menu",
|
|
160
|
+
"MenuManager", "create_menu", "create_menu_items",
|
|
157
161
|
"Shortcuts", "Shortcut", "get_shortcuts",
|
|
158
162
|
],
|
|
159
163
|
# Style & Theming
|
|
160
164
|
"bootstack.api.style": [
|
|
161
|
-
"BootstrapIcon", "Font", "Style",
|
|
165
|
+
"BootstrapIcon", "Font", "Style", "Typography",
|
|
162
166
|
"get_style", "get_style_builder", "get_theme",
|
|
163
167
|
"get_theme_provider", "set_theme", "get_theme_color",
|
|
164
168
|
"toggle_theme", "get_themes",
|
|
169
|
+
"register_user_theme",
|
|
165
170
|
],
|
|
166
171
|
# Widgets
|
|
167
172
|
"bootstack.api.widgets": [
|
|
@@ -173,7 +178,7 @@ _MODULE_EXPORTS = {
|
|
|
173
178
|
"RadioToggle",
|
|
174
179
|
"Calendar", "ContextMenu", "ContextMenuItem", "DateEntry",
|
|
175
180
|
"Accordion", "DropdownButton", "Expander", "Field", "FieldOptions", "FloodGauge", "Form",
|
|
176
|
-
"GridFrame", "LabeledScale", "MenuBar", "Meter",
|
|
181
|
+
"GridFrame", "LabeledScale", "ListItem", "ListView", "MenuBar", "Meter",
|
|
177
182
|
"SideNav", "SideNavItem", "SideNavGroup",
|
|
178
183
|
"SideNavHeader", "SideNavSeparator",
|
|
179
184
|
"NumericEntry", "PackFrame", "PageStack",
|
|
@@ -64,7 +64,7 @@ from bootstack.api.widgets import (
|
|
|
64
64
|
)
|
|
65
65
|
from bootstack.runtime.app import App, App as Window
|
|
66
66
|
from bootstack.runtime.toplevel import Toplevel
|
|
67
|
-
from bootstack.runtime.menu import MenuManager, create_menu
|
|
67
|
+
from bootstack.runtime.menu import MenuManager, create_menu, create_menu_items
|
|
68
68
|
|
|
69
69
|
__all__ = [
|
|
70
70
|
"BootstrapIcon",
|
|
@@ -122,6 +122,7 @@ __all__ = [
|
|
|
122
122
|
"get_theme_provider",
|
|
123
123
|
"get_theme_color",
|
|
124
124
|
"create_menu",
|
|
125
|
+
"create_menu_items",
|
|
125
126
|
"TK_WIDGETS",
|
|
126
127
|
"TTK_WIDGETS",
|
|
127
128
|
]
|
|
@@ -6,12 +6,14 @@ from ttkbootstrap_icons_bs import BootstrapIcon
|
|
|
6
6
|
|
|
7
7
|
from bootstack.style.style import (Style, get_style, get_style_builder, get_theme, get_theme_color,
|
|
8
8
|
get_theme_provider, set_theme, toggle_theme, get_themes)
|
|
9
|
-
from bootstack.style.
|
|
9
|
+
from bootstack.style.theme_provider import register_user_theme
|
|
10
|
+
from bootstack.style.typography import Font, Typography
|
|
10
11
|
|
|
11
12
|
__all__ = [
|
|
12
13
|
"BootstrapIcon",
|
|
13
14
|
"Font",
|
|
14
15
|
"Style",
|
|
16
|
+
"Typography",
|
|
15
17
|
"get_style",
|
|
16
18
|
"get_style_builder",
|
|
17
19
|
"get_theme",
|
|
@@ -20,4 +22,5 @@ __all__ = [
|
|
|
20
22
|
"get_theme_provider",
|
|
21
23
|
"get_theme_color",
|
|
22
24
|
"get_themes",
|
|
25
|
+
"register_user_theme",
|
|
23
26
|
]
|
|
@@ -35,6 +35,7 @@ from bootstack.widgets.primitives.gridframe import GridFrame
|
|
|
35
35
|
from bootstack.widgets.primitives.label import Label
|
|
36
36
|
from bootstack.widgets.primitives.labelframe import LabelFrame
|
|
37
37
|
from bootstack.widgets.composites.labeledscale import LabeledScale
|
|
38
|
+
from bootstack.widgets.composites.list import ListItem, ListView
|
|
38
39
|
from bootstack.widgets.composites.menubar import MenuBar
|
|
39
40
|
from bootstack.widgets.primitives.menubutton import MenuButton
|
|
40
41
|
from bootstack.widgets.composites.meter import Meter
|
|
@@ -93,6 +94,8 @@ __all__ = [
|
|
|
93
94
|
"Label",
|
|
94
95
|
"LabelFrame",
|
|
95
96
|
"LabeledScale",
|
|
97
|
+
"ListItem",
|
|
98
|
+
"ListView",
|
|
96
99
|
"MenuBar",
|
|
97
100
|
"SideNav",
|
|
98
101
|
"SideNavItem",
|
|
@@ -20,6 +20,7 @@ Usage:
|
|
|
20
20
|
bootstack list themes List available themes
|
|
21
21
|
bootstack doctor Diagnose project and environment health
|
|
22
22
|
bootstack gallery Launch the widget gallery
|
|
23
|
+
bootstack icons Browse Bootstrap Icons
|
|
23
24
|
"""
|
|
24
25
|
|
|
25
26
|
from __future__ import annotations
|
|
@@ -28,7 +29,7 @@ import argparse
|
|
|
28
29
|
import sys
|
|
29
30
|
from typing import Sequence
|
|
30
31
|
|
|
31
|
-
from bootstack.cli import add, build, doctor, list_cmd, promote, run, start
|
|
32
|
+
from bootstack.cli import add, build, doctor, icons, list_cmd, promote, run, start
|
|
32
33
|
from bootstack.cli.demo import run_demo
|
|
33
34
|
|
|
34
35
|
|
|
@@ -50,6 +51,7 @@ Examples:
|
|
|
50
51
|
bootstack list themes List available themes
|
|
51
52
|
bootstack doctor Diagnose project and environment health
|
|
52
53
|
bootstack gallery Launch the widget gallery
|
|
54
|
+
bootstack icons Browse Bootstrap Icons
|
|
53
55
|
|
|
54
56
|
For more information on a command:
|
|
55
57
|
bootstack <command> --help
|
|
@@ -82,6 +84,7 @@ For more information on a command:
|
|
|
82
84
|
add.add_parser(subparsers)
|
|
83
85
|
list_cmd.add_parser(subparsers)
|
|
84
86
|
doctor.add_parser(subparsers)
|
|
87
|
+
icons.add_parser(subparsers)
|
|
85
88
|
|
|
86
89
|
# Gallery command
|
|
87
90
|
gallery_parser = subparsers.add_parser(
|
|
@@ -305,7 +305,7 @@ def run_add_theme(args: argparse.Namespace) -> None:
|
|
|
305
305
|
print()
|
|
306
306
|
print(" from bootstack.style.theme_provider import register_user_theme")
|
|
307
307
|
print(f' register_user_theme("{theme_name}", "themes/{theme_name}.json")')
|
|
308
|
-
print(f' app =
|
|
308
|
+
print(f' app = bs.App(theme="{theme_name}")')
|
|
309
309
|
|
|
310
310
|
|
|
311
311
|
def run_add_i18n(args: argparse.Namespace) -> None:
|
|
@@ -340,7 +340,7 @@ def run_add_i18n(args: argparse.Namespace) -> None:
|
|
|
340
340
|
print("Next steps:")
|
|
341
341
|
print(" 1. Add translatable strings to your .po files")
|
|
342
342
|
print(" 2. Compile with: msgfmt locales/<lang>/LC_MESSAGES/messages.po -o locales/<lang>/LC_MESSAGES/messages.mo")
|
|
343
|
-
print(" 3. Use translations in code:
|
|
343
|
+
print(" 3. Use translations in code: bs.L('Hello')")
|
|
344
344
|
|
|
345
345
|
|
|
346
346
|
_BASE_SHADES = {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""Icons command — delegates to the ttkbootstrap-icons browser."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
import subprocess
|
|
6
|
+
import sys
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def add_parser(subparsers: argparse._SubParsersAction) -> None:
|
|
11
|
+
parser = subparsers.add_parser(
|
|
12
|
+
"icons",
|
|
13
|
+
help="Browse Bootstrap Icons available in bootstack",
|
|
14
|
+
description=(
|
|
15
|
+
"Launch the Bootstrap Icons browser.\n\n"
|
|
16
|
+
"Delegates to the ttkbootstrap-icons tool bundled with the "
|
|
17
|
+
"ttkbootstrap_icons_bs package. Any icon name shown there can "
|
|
18
|
+
"be used as the icon= parameter on any bootstack widget."
|
|
19
|
+
),
|
|
20
|
+
)
|
|
21
|
+
parser.set_defaults(func=lambda args: run_icons())
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def run_icons() -> None:
|
|
25
|
+
scripts = Path(sys.executable).parent
|
|
26
|
+
name = "ttkbootstrap-icons.exe" if sys.platform == "win32" else "ttkbootstrap-icons"
|
|
27
|
+
result = subprocess.run([str(scripts / name)])
|
|
28
|
+
sys.exit(result.returncode)
|
|
@@ -429,8 +429,8 @@ class IntlFormatter:
|
|
|
429
429
|
opt = self._normalize_date_spec(spec)
|
|
430
430
|
typ = opt["type"]
|
|
431
431
|
if typ == "custom": return format_time(t, format=opt["pattern"], locale=self.locale)
|
|
432
|
-
if typ == "longTime": return format_time(t, "long", self.locale)
|
|
433
|
-
if typ == "shortTime": return format_time(t, "short", self.locale)
|
|
432
|
+
if typ == "longTime": return format_time(t, "long", locale=self.locale)
|
|
433
|
+
if typ == "shortTime": return format_time(t, "short", locale=self.locale)
|
|
434
434
|
if typ == "hour": return format_time(t, "H", self.locale)
|
|
435
435
|
if typ == "minute": return format_time(t, "m", self.locale)
|
|
436
436
|
if typ == "second": return format_time(t, "s", self.locale)
|
|
@@ -451,8 +451,8 @@ class IntlFormatter:
|
|
|
451
451
|
if typ == "shortDateShortTime": return format_datetime(dt, "short", self.locale)
|
|
452
452
|
if typ == "longDate": return format_date(dt.date(), "long", self.locale)
|
|
453
453
|
if typ == "shortDate": return format_date(dt.date(), "short", self.locale)
|
|
454
|
-
if typ == "longTime": return format_time(dt.time(), "long", self.locale)
|
|
455
|
-
if typ == "shortTime": return format_time(dt.time(), "short", self.locale)
|
|
454
|
+
if typ == "longTime": return format_time(dt.time(), "long", locale=self.locale)
|
|
455
|
+
if typ == "shortTime": return format_time(dt.time(), "short", locale=self.locale)
|
|
456
456
|
if typ == "monthAndDay": return format_date(dt.date(), "MMMM d", self.locale)
|
|
457
457
|
if typ == "monthAndYear": return format_date(dt.date(), "MMMM y", self.locale)
|
|
458
458
|
if typ == "quarterAndYear": return format_date(dt.date(), "QQQ y", self.locale)
|
|
@@ -34,6 +34,10 @@ from typing import Any, Dict, List, Optional, Union, Sequence
|
|
|
34
34
|
from bootstack.datasource.base import BaseDataSource
|
|
35
35
|
from bootstack.datasource.types import Primitive, Record
|
|
36
36
|
|
|
37
|
+
# Internal column names — reserved by SqliteDataSource, never exposed to user data.
|
|
38
|
+
_ROW_ID = "_bs_row_id"
|
|
39
|
+
_ROW_SEL = "_bs_selected"
|
|
40
|
+
|
|
37
41
|
|
|
38
42
|
class SqliteDataSource(BaseDataSource):
|
|
39
43
|
"""SQLite-backed data manager with pagination, filtering, sorting, and CRUD operations.
|
|
@@ -61,8 +65,9 @@ class SqliteDataSource(BaseDataSource):
|
|
|
61
65
|
- The database connection persists for the lifetime of the object
|
|
62
66
|
- Close the connection explicitly with conn.close() if needed
|
|
63
67
|
- Schema is inferred from first record's data types
|
|
64
|
-
-
|
|
65
|
-
-
|
|
68
|
+
- An internal row-identity column (_bs_row_id) is added automatically as PRIMARY KEY
|
|
69
|
+
- An internal selection column (_bs_selected) is added automatically for selection tracking
|
|
70
|
+
- These internal columns are filtered out of the display column list automatically
|
|
66
71
|
"""
|
|
67
72
|
|
|
68
73
|
def __init__(self, name: str = ":memory:", page_size: int = 10):
|
|
@@ -121,12 +126,12 @@ class SqliteDataSource(BaseDataSource):
|
|
|
121
126
|
using_dicts = True
|
|
122
127
|
|
|
123
128
|
if using_dicts:
|
|
124
|
-
# Ensure helper columns
|
|
129
|
+
# Ensure internal helper columns
|
|
125
130
|
for i, record in enumerate(records):
|
|
126
|
-
if
|
|
127
|
-
record[
|
|
128
|
-
if
|
|
129
|
-
record[
|
|
131
|
+
if _ROW_ID not in record:
|
|
132
|
+
record[_ROW_ID] = i
|
|
133
|
+
if _ROW_SEL not in record:
|
|
134
|
+
record[_ROW_SEL] = 0
|
|
130
135
|
|
|
131
136
|
self._columns = list(records[0].keys())
|
|
132
137
|
col_types = {col: self._infer_type(records[0][col]) for col in self._columns}
|
|
@@ -136,25 +141,25 @@ class SqliteDataSource(BaseDataSource):
|
|
|
136
141
|
keys = list(column_keys or [])
|
|
137
142
|
if not keys:
|
|
138
143
|
keys = [str(i) for i in range(len(first))]
|
|
139
|
-
need_id =
|
|
140
|
-
|
|
144
|
+
need_id = _ROW_ID not in keys
|
|
145
|
+
need_sel = _ROW_SEL not in keys
|
|
141
146
|
if need_id:
|
|
142
|
-
keys.append(
|
|
143
|
-
if
|
|
144
|
-
keys.append(
|
|
147
|
+
keys.append(_ROW_ID)
|
|
148
|
+
if need_sel:
|
|
149
|
+
keys.append(_ROW_SEL)
|
|
145
150
|
self._columns = keys
|
|
146
151
|
|
|
147
152
|
# Infer types from first row (pad to keys length)
|
|
148
153
|
padded_first = list(first) + [None] * (len(keys) - len(first))
|
|
149
|
-
if need_id and
|
|
150
|
-
padded_first[keys.index(
|
|
151
|
-
if
|
|
152
|
-
padded_first[keys.index(
|
|
154
|
+
if need_id and _ROW_ID in keys:
|
|
155
|
+
padded_first[keys.index(_ROW_ID)] = 0
|
|
156
|
+
if need_sel and _ROW_SEL in keys:
|
|
157
|
+
padded_first[keys.index(_ROW_SEL)] = 0
|
|
153
158
|
col_types = {col: self._infer_type(padded_first[idx]) for idx, col in enumerate(keys)}
|
|
154
159
|
|
|
155
160
|
rows_to_insert = []
|
|
156
|
-
id_idx = keys.index(
|
|
157
|
-
sel_idx = keys.index(
|
|
161
|
+
id_idx = keys.index(_ROW_ID) if _ROW_ID in keys else None
|
|
162
|
+
sel_idx = keys.index(_ROW_SEL) if _ROW_SEL in keys else None
|
|
158
163
|
value_len = len(keys)
|
|
159
164
|
for i, row in enumerate(records):
|
|
160
165
|
base_values = list(row[: value_len]) + [""] * (value_len - len(row))
|
|
@@ -165,7 +170,7 @@ class SqliteDataSource(BaseDataSource):
|
|
|
165
170
|
rows_to_insert.append(tuple(base_values))
|
|
166
171
|
|
|
167
172
|
col_definitions = ", ".join(
|
|
168
|
-
f"{self._quote_identifier(col)} {col_types[col]}" + (" PRIMARY KEY" if col ==
|
|
173
|
+
f"{self._quote_identifier(col)} {col_types[col]}" + (" PRIMARY KEY" if col == _ROW_ID else "")
|
|
169
174
|
for col in self._columns
|
|
170
175
|
)
|
|
171
176
|
placeholders = ", ".join("?" for _ in self._columns)
|
|
@@ -241,11 +246,11 @@ class SqliteDataSource(BaseDataSource):
|
|
|
241
246
|
|
|
242
247
|
def create_record(self, record: Dict[str, Any]) -> int:
|
|
243
248
|
"""Create new record and return its ID."""
|
|
244
|
-
if
|
|
245
|
-
record[
|
|
249
|
+
if _ROW_ID not in record:
|
|
250
|
+
record[_ROW_ID] = self._generate_new_id()
|
|
246
251
|
|
|
247
|
-
if
|
|
248
|
-
record[
|
|
252
|
+
if _ROW_SEL not in record:
|
|
253
|
+
record[_ROW_SEL] = 0
|
|
249
254
|
|
|
250
255
|
# Ensure table exists (handles empty datasources)
|
|
251
256
|
self._ensure_table_for_record(record)
|
|
@@ -257,11 +262,11 @@ class SqliteDataSource(BaseDataSource):
|
|
|
257
262
|
|
|
258
263
|
with self.conn:
|
|
259
264
|
self.conn.execute(f"INSERT INTO {self._table} ({cols}) VALUES ({placeholders})", values)
|
|
260
|
-
return record[
|
|
265
|
+
return record[_ROW_ID]
|
|
261
266
|
|
|
262
267
|
def read_record(self, record_id: Any) -> Optional[Dict[str, Any]]:
|
|
263
268
|
"""Retrieve single record by ID."""
|
|
264
|
-
cursor = self.conn.execute(f"SELECT * FROM {self._table} WHERE
|
|
269
|
+
cursor = self.conn.execute(f"SELECT * FROM {self._table} WHERE {_ROW_ID} = ?", (record_id,))
|
|
265
270
|
row = cursor.fetchone()
|
|
266
271
|
return dict(row) if row else None
|
|
267
272
|
|
|
@@ -272,19 +277,19 @@ class SqliteDataSource(BaseDataSource):
|
|
|
272
277
|
set_clause = ", ".join(f"{self._quote_identifier(k)} = ?" for k in updates)
|
|
273
278
|
values = tuple(updates.values()) + (record_id,)
|
|
274
279
|
with self.conn:
|
|
275
|
-
cur = self.conn.execute(f"UPDATE {self._table} SET {set_clause} WHERE
|
|
280
|
+
cur = self.conn.execute(f"UPDATE {self._table} SET {set_clause} WHERE {_ROW_ID} = ?", values)
|
|
276
281
|
return cur.rowcount > 0
|
|
277
282
|
|
|
278
283
|
def delete_record(self, record_id: Any) -> bool:
|
|
279
284
|
"""Delete record by ID."""
|
|
280
285
|
with self.conn:
|
|
281
|
-
cur = self.conn.execute(f"DELETE FROM {self._table} WHERE
|
|
286
|
+
cur = self.conn.execute(f"DELETE FROM {self._table} WHERE {_ROW_ID} = ?", (record_id,))
|
|
282
287
|
return cur.rowcount > 0
|
|
283
288
|
|
|
284
289
|
def _generate_new_id(self) -> int:
|
|
285
290
|
"""Generate next available integer ID."""
|
|
286
291
|
try:
|
|
287
|
-
cursor = self.conn.execute(f"SELECT MAX(
|
|
292
|
+
cursor = self.conn.execute(f"SELECT MAX({_ROW_ID}) FROM {self._table}")
|
|
288
293
|
max_id = cursor.fetchone()[0]
|
|
289
294
|
except Exception:
|
|
290
295
|
max_id = 0
|
|
@@ -301,23 +306,23 @@ class SqliteDataSource(BaseDataSource):
|
|
|
301
306
|
pass
|
|
302
307
|
|
|
303
308
|
cols = list(self._columns) if self._columns else list(record.keys())
|
|
304
|
-
if
|
|
305
|
-
cols.append(
|
|
306
|
-
if
|
|
307
|
-
cols.append(
|
|
309
|
+
if _ROW_ID not in cols:
|
|
310
|
+
cols.append(_ROW_ID)
|
|
311
|
+
if _ROW_SEL not in cols:
|
|
312
|
+
cols.append(_ROW_SEL)
|
|
308
313
|
self._columns = cols
|
|
309
314
|
|
|
310
315
|
col_types = {}
|
|
311
316
|
for c in cols:
|
|
312
|
-
if c ==
|
|
317
|
+
if c == _ROW_ID:
|
|
313
318
|
col_types[c] = "INTEGER"
|
|
314
|
-
elif c ==
|
|
319
|
+
elif c == _ROW_SEL:
|
|
315
320
|
col_types[c] = "INTEGER"
|
|
316
321
|
else:
|
|
317
322
|
col_types[c] = self._infer_type(record.get(c))
|
|
318
323
|
|
|
319
324
|
col_definitions = ", ".join(
|
|
320
|
-
f"{self._quote_identifier(col)} {col_types[col]}" + (" PRIMARY KEY" if col ==
|
|
325
|
+
f"{self._quote_identifier(col)} {col_types[col]}" + (" PRIMARY KEY" if col == _ROW_ID else "")
|
|
321
326
|
for col in cols
|
|
322
327
|
)
|
|
323
328
|
with self.conn:
|
|
@@ -337,40 +342,40 @@ class SqliteDataSource(BaseDataSource):
|
|
|
337
342
|
"""Select all records (optionally only current page)."""
|
|
338
343
|
self._ensure_selected_column()
|
|
339
344
|
if current_page_only:
|
|
340
|
-
ids = [row[
|
|
345
|
+
ids = [row[_ROW_ID] for row in self.get_page()]
|
|
341
346
|
if not ids:
|
|
342
347
|
return 0
|
|
343
348
|
placeholders = ", ".join("?" for _ in ids)
|
|
344
|
-
query = f"UPDATE {self._table} SET
|
|
349
|
+
query = f"UPDATE {self._table} SET {_ROW_SEL} = 1 WHERE {_ROW_ID} IN ({placeholders})"
|
|
345
350
|
with self.conn:
|
|
346
351
|
cur = self.conn.execute(query, ids)
|
|
347
352
|
return cur.rowcount
|
|
348
353
|
else:
|
|
349
354
|
with self.conn:
|
|
350
|
-
cur = self.conn.execute(f"UPDATE {self._table} SET
|
|
355
|
+
cur = self.conn.execute(f"UPDATE {self._table} SET {_ROW_SEL} = 1")
|
|
351
356
|
return cur.rowcount
|
|
352
357
|
|
|
353
358
|
def unselect_all(self, current_page_only: bool = False) -> int:
|
|
354
359
|
"""Unselect all records (optionally only current page)."""
|
|
355
360
|
self._ensure_selected_column()
|
|
356
361
|
if current_page_only:
|
|
357
|
-
ids = [row[
|
|
362
|
+
ids = [row[_ROW_ID] for row in self.get_page()]
|
|
358
363
|
if not ids:
|
|
359
364
|
return 0
|
|
360
365
|
placeholders = ", ".join("?" for _ in ids)
|
|
361
|
-
query = f"UPDATE {self._table} SET
|
|
366
|
+
query = f"UPDATE {self._table} SET {_ROW_SEL} = 0 WHERE {_ROW_ID} IN ({placeholders})"
|
|
362
367
|
with self.conn:
|
|
363
368
|
cur = self.conn.execute(query, ids)
|
|
364
369
|
return cur.rowcount
|
|
365
370
|
else:
|
|
366
371
|
with self.conn:
|
|
367
|
-
cur = self.conn.execute(f"UPDATE {self._table} SET
|
|
372
|
+
cur = self.conn.execute(f"UPDATE {self._table} SET {_ROW_SEL} = 0")
|
|
368
373
|
return cur.rowcount
|
|
369
374
|
|
|
370
375
|
def get_selected(self, page: Optional[int] = None) -> List[Dict[str, Any]]:
|
|
371
376
|
"""Get selected records, optionally paginated."""
|
|
372
377
|
self._ensure_selected_column()
|
|
373
|
-
query = f"SELECT * FROM {self._table} WHERE
|
|
378
|
+
query = f"SELECT * FROM {self._table} WHERE {_ROW_SEL} = 1"
|
|
374
379
|
|
|
375
380
|
if page is not None:
|
|
376
381
|
offset = page * self.page_size
|
|
@@ -380,28 +385,30 @@ class SqliteDataSource(BaseDataSource):
|
|
|
380
385
|
return [dict(row) for row in cursor.fetchall()]
|
|
381
386
|
|
|
382
387
|
def _ensure_selected_column(self):
|
|
383
|
-
"""Add
|
|
384
|
-
if
|
|
388
|
+
"""Add selection column to table if it doesn't exist."""
|
|
389
|
+
if _ROW_SEL not in self._columns:
|
|
385
390
|
with self.conn:
|
|
386
|
-
self.conn.execute(f"ALTER TABLE {self._table} ADD COLUMN
|
|
387
|
-
self._columns.append(
|
|
391
|
+
self.conn.execute(f"ALTER TABLE {self._table} ADD COLUMN {_ROW_SEL} INTEGER DEFAULT 0")
|
|
392
|
+
self._columns.append(_ROW_SEL)
|
|
388
393
|
|
|
389
394
|
def selected_count(self) -> int:
|
|
390
395
|
"""Get total number of selected records."""
|
|
391
396
|
self._ensure_selected_column()
|
|
392
|
-
query = f"SELECT COUNT(*) FROM {self._table} WHERE
|
|
397
|
+
query = f"SELECT COUNT(*) FROM {self._table} WHERE {_ROW_SEL} = 1"
|
|
393
398
|
return self.conn.execute(query).fetchone()[0]
|
|
394
399
|
|
|
395
400
|
def _set_selected_flag(self, record_id: Any, flag: int) -> bool:
|
|
396
401
|
"""Set selection flag for record by ID."""
|
|
397
|
-
if
|
|
398
|
-
# Add selected column if it doesn't exist
|
|
402
|
+
if _ROW_SEL not in self._columns:
|
|
399
403
|
with self.conn:
|
|
400
|
-
self.conn.execute(f"ALTER TABLE {self._table} ADD COLUMN
|
|
401
|
-
self._columns.append(
|
|
404
|
+
self.conn.execute(f"ALTER TABLE {self._table} ADD COLUMN {_ROW_SEL} INTEGER DEFAULT 0")
|
|
405
|
+
self._columns.append(_ROW_SEL)
|
|
402
406
|
|
|
403
407
|
with self.conn:
|
|
404
|
-
cur = self.conn.execute(
|
|
408
|
+
cur = self.conn.execute(
|
|
409
|
+
f"UPDATE {self._table} SET {_ROW_SEL} = ? WHERE {_ROW_ID} = ?",
|
|
410
|
+
(flag, record_id),
|
|
411
|
+
)
|
|
405
412
|
return cur.rowcount > 0
|
|
406
413
|
|
|
407
414
|
# === DATA EXPORT ===
|
|
@@ -411,7 +418,7 @@ class SqliteDataSource(BaseDataSource):
|
|
|
411
418
|
self._ensure_selected_column()
|
|
412
419
|
query = f"SELECT * FROM {self._table}"
|
|
413
420
|
if not include_all:
|
|
414
|
-
query += " WHERE
|
|
421
|
+
query += f" WHERE {_ROW_SEL} = 1"
|
|
415
422
|
|
|
416
423
|
cursor = self.conn.execute(query)
|
|
417
424
|
rows = cursor.fetchall()
|
|
@@ -202,13 +202,16 @@ class DateDialog:
|
|
|
202
202
|
show_week_numbers: bool = False,
|
|
203
203
|
hide_window_chrome: bool = False,
|
|
204
204
|
close_on_click_outside: bool = False,
|
|
205
|
+
selection_mode: Literal["single", "range"] = "single",
|
|
206
|
+
start_date: Optional[date | datetime | str] = None,
|
|
207
|
+
end_date: Optional[date | datetime | str] = None,
|
|
205
208
|
) -> None:
|
|
206
209
|
"""Create a date selection dialog.
|
|
207
210
|
|
|
208
211
|
Args:
|
|
209
212
|
master: Parent widget; positions dialog relative to it when set.
|
|
210
213
|
title: Dialog window title text.
|
|
211
|
-
initial_date: Initial date shown; defaults to `date.today()`.
|
|
214
|
+
initial_date: Initial date shown in single mode; defaults to `date.today()`.
|
|
212
215
|
first_weekday: First weekday index (0=Monday, 6=Sunday).
|
|
213
216
|
accent: Calendar accent token (e.g., `primary`, `secondary`).
|
|
214
217
|
disabled_dates: Iterable of dates to disable selection.
|
|
@@ -221,6 +224,11 @@ class DateDialog:
|
|
|
221
224
|
decorations using override-redirect.
|
|
222
225
|
close_on_click_outside: When True, closes the dialog when focus
|
|
223
226
|
moves outside (popover mode).
|
|
227
|
+
selection_mode: `'single'` for a single date (default) or `'range'`
|
|
228
|
+
for a start/end date range. In range mode `result` is a
|
|
229
|
+
`tuple[date, date]` rather than a `date`.
|
|
230
|
+
start_date: Initial range start date (range mode only).
|
|
231
|
+
end_date: Initial range end date (range mode only).
|
|
224
232
|
"""
|
|
225
233
|
self._master = master
|
|
226
234
|
self._first_weekday = first_weekday
|
|
@@ -233,6 +241,9 @@ class DateDialog:
|
|
|
233
241
|
self._show_week_numbers = show_week_numbers
|
|
234
242
|
self._hide_window_chrome = hide_window_chrome
|
|
235
243
|
self._close_on_click_outside = close_on_click_outside
|
|
244
|
+
self._selection_mode = selection_mode
|
|
245
|
+
self._start_date = start_date
|
|
246
|
+
self._end_date = end_date
|
|
236
247
|
|
|
237
248
|
self._picker: Optional[_DialogCalendar] = None
|
|
238
249
|
|
|
@@ -253,7 +264,9 @@ class DateDialog:
|
|
|
253
264
|
|
|
254
265
|
self._picker = _DialogCalendar(
|
|
255
266
|
master=container,
|
|
256
|
-
|
|
267
|
+
selection_mode=self._selection_mode,
|
|
268
|
+
start_date=self._start_date if self._selection_mode == "range" else self._initial_date,
|
|
269
|
+
end_date=self._end_date if self._selection_mode == "range" else None,
|
|
257
270
|
first_weekday=self._first_weekday,
|
|
258
271
|
accent=self._accent,
|
|
259
272
|
disabled_dates=self._disabled_dates,
|
|
@@ -275,16 +288,29 @@ class DateDialog:
|
|
|
275
288
|
return
|
|
276
289
|
|
|
277
290
|
payload = getattr(event, "data", None)
|
|
278
|
-
selected = None
|
|
279
|
-
if isinstance(payload, dict):
|
|
280
|
-
selected = payload.get("date") or payload.get("result")
|
|
281
291
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
292
|
+
if self._selection_mode == "range":
|
|
293
|
+
range_data = None
|
|
294
|
+
if isinstance(payload, dict):
|
|
295
|
+
range_data = payload.get("range")
|
|
296
|
+
if range_data is None:
|
|
297
|
+
range_data = self._picker.get_range()
|
|
298
|
+
start, end = range_data if range_data else (None, None)
|
|
299
|
+
# Wait for both dates before confirming
|
|
300
|
+
if start is None or end is None:
|
|
301
|
+
return
|
|
302
|
+
result: date | Tuple[date, date] = (start, end)
|
|
303
|
+
else:
|
|
304
|
+
selected = None
|
|
305
|
+
if isinstance(payload, dict):
|
|
306
|
+
selected = payload.get("date") or payload.get("result")
|
|
307
|
+
selected = selected or self._picker.get()
|
|
308
|
+
if selected is None:
|
|
309
|
+
return
|
|
310
|
+
result = selected
|
|
285
311
|
|
|
286
|
-
self._dialog.result =
|
|
287
|
-
self._emit_result(
|
|
312
|
+
self._dialog.result = result
|
|
313
|
+
self._emit_result(result, confirmed=True)
|
|
288
314
|
if self._dialog.toplevel:
|
|
289
315
|
top = self._dialog.toplevel
|
|
290
316
|
try:
|
|
@@ -354,8 +380,8 @@ class DateDialog:
|
|
|
354
380
|
)
|
|
355
381
|
|
|
356
382
|
@property
|
|
357
|
-
def result(self) -> Optional[date]:
|
|
358
|
-
"""The selected date, or None if cancelled."""
|
|
383
|
+
def result(self) -> Optional[Union[date, Tuple[date, date]]]:
|
|
384
|
+
"""The selected date (single mode) or ``(start, end)`` tuple (range mode), or None if cancelled."""
|
|
359
385
|
return self._dialog.result
|
|
360
386
|
|
|
361
387
|
def on_result(self, callback: Callable[[date], None]) -> Optional[str]:
|