bootstack 0.1.0a1__py3-none-any.whl
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/__init__.py +249 -0
- bootstack/__main__.py +5 -0
- bootstack/api/__init__.py +127 -0
- bootstack/api/app.py +30 -0
- bootstack/api/constants.py +3 -0
- bootstack/api/data.py +23 -0
- bootstack/api/dialogs.py +44 -0
- bootstack/api/i18n.py +17 -0
- bootstack/api/localization.py +16 -0
- bootstack/api/menu.py +7 -0
- bootstack/api/style.py +23 -0
- bootstack/api/utils.py +24 -0
- bootstack/api/widgets.py +137 -0
- bootstack/assets/__init__.py +24 -0
- bootstack/assets/bootstack-transparent.png +0 -0
- bootstack/assets/bootstack.ico +0 -0
- bootstack/assets/bootstack.png +0 -0
- bootstack/assets/elements/__init__.py +0 -0
- bootstack/assets/elements/badge-pill.png +0 -0
- bootstack/assets/elements/badge-square.png +0 -0
- bootstack/assets/elements/border.png +0 -0
- bootstack/assets/elements/button-compact.png +0 -0
- bootstack/assets/elements/button-default.png +0 -0
- bootstack/assets/elements/button-group-horizontal-after-compact.png +0 -0
- bootstack/assets/elements/button-group-horizontal-after-default.png +0 -0
- bootstack/assets/elements/button-group-horizontal-before-compact.png +0 -0
- bootstack/assets/elements/button-group-horizontal-before-default.png +0 -0
- bootstack/assets/elements/button-group-horizontal-center-compact.png +0 -0
- bootstack/assets/elements/button-group-horizontal-center-default.png +0 -0
- bootstack/assets/elements/button-group-vertical-after-compact.png +0 -0
- bootstack/assets/elements/button-group-vertical-after-default.png +0 -0
- bootstack/assets/elements/button-group-vertical-before-compact.png +0 -0
- bootstack/assets/elements/button-group-vertical-before-default.png +0 -0
- bootstack/assets/elements/button-group-vertical-center-compact.png +0 -0
- bootstack/assets/elements/button-group-vertical-center-default.png +0 -0
- bootstack/assets/elements/checkbox-checked.png +0 -0
- bootstack/assets/elements/checkbox-indeterminate.png +0 -0
- bootstack/assets/elements/checkbox-unchecked.png +0 -0
- bootstack/assets/elements/field.png +0 -0
- bootstack/assets/elements/input-after-compact.png +0 -0
- bootstack/assets/elements/input-after-default.png +0 -0
- bootstack/assets/elements/input-before-compact.png +0 -0
- bootstack/assets/elements/input-before-default.png +0 -0
- bootstack/assets/elements/input-compact.png +0 -0
- bootstack/assets/elements/input-default.png +0 -0
- bootstack/assets/elements/list-item-separated.png +0 -0
- bootstack/assets/elements/list-item.png +0 -0
- bootstack/assets/elements/manifest.toml +480 -0
- bootstack/assets/elements/menu-item.png +0 -0
- bootstack/assets/elements/nav-button-compact.png +0 -0
- bootstack/assets/elements/nav-button-default.png +0 -0
- bootstack/assets/elements/nav-icon-button-compact.png +0 -0
- bootstack/assets/elements/nav-icon-button-default.png +0 -0
- bootstack/assets/elements/notebook-client-border.png +0 -0
- bootstack/assets/elements/notebook-tab-active.png +0 -0
- bootstack/assets/elements/notebook-tab-bar.png +0 -0
- bootstack/assets/elements/notebook-tab-normal.png +0 -0
- bootstack/assets/elements/notebook-tab-pill.png +0 -0
- bootstack/assets/elements/progress-bar-horizontal-striped.png +0 -0
- bootstack/assets/elements/progress-bar-solid.png +0 -0
- bootstack/assets/elements/progress-bar-thin.png +0 -0
- bootstack/assets/elements/progress-bar-vertical-striped.png +0 -0
- bootstack/assets/elements/radio-selected.png +0 -0
- bootstack/assets/elements/radio-unselected.png +0 -0
- bootstack/assets/elements/scrollbar-horizontal.png +0 -0
- bootstack/assets/elements/scrollbar-vertical.png +0 -0
- bootstack/assets/elements/slider-handle-focus.png +0 -0
- bootstack/assets/elements/slider-handle.png +0 -0
- bootstack/assets/elements/slider-track-horizontal.png +0 -0
- bootstack/assets/elements/slider-track-vertical.png +0 -0
- bootstack/assets/elements/switch-off.png +0 -0
- bootstack/assets/elements/switch-on.png +0 -0
- bootstack/assets/elements/tabs-bar-horizontal.png +0 -0
- bootstack/assets/elements/tabs-bar-vertical.png +0 -0
- bootstack/assets/elements/tabs-pill.png +0 -0
- bootstack/assets/locales/ar/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/ar/LC_MESSAGES/bootstack.po +853 -0
- bootstack/assets/locales/bg/LC_MESSAGES/bootstack.po +875 -0
- bootstack/assets/locales/cs/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/cs/LC_MESSAGES/bootstack.po +853 -0
- bootstack/assets/locales/da/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/da/LC_MESSAGES/bootstack.po +853 -0
- bootstack/assets/locales/de/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/de/LC_MESSAGES/bootstack.po +853 -0
- bootstack/assets/locales/en/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/en/LC_MESSAGES/bootstack.po +875 -0
- bootstack/assets/locales/es/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/es/LC_MESSAGES/bootstack.po +853 -0
- bootstack/assets/locales/fr/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/fr/LC_MESSAGES/bootstack.po +853 -0
- bootstack/assets/locales/he/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/he/LC_MESSAGES/bootstack.po +851 -0
- bootstack/assets/locales/hi/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/hi/LC_MESSAGES/bootstack.po +842 -0
- bootstack/assets/locales/it/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/it/LC_MESSAGES/bootstack.po +841 -0
- bootstack/assets/locales/ja/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/ja/LC_MESSAGES/bootstack.po +914 -0
- bootstack/assets/locales/ko/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/ko/LC_MESSAGES/bootstack.po +842 -0
- bootstack/assets/locales/nb/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/nb/LC_MESSAGES/bootstack.po +841 -0
- bootstack/assets/locales/nl/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/nl/LC_MESSAGES/bootstack.po +841 -0
- bootstack/assets/locales/pl/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/pl/LC_MESSAGES/bootstack.po +842 -0
- bootstack/assets/locales/pt/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/pt/LC_MESSAGES/bootstack.po +842 -0
- bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.po +842 -0
- bootstack/assets/locales/sl/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/sl/LC_MESSAGES/bootstack.po +842 -0
- bootstack/assets/locales/sv/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/sv/LC_MESSAGES/bootstack.po +842 -0
- bootstack/assets/locales/tr/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/tr/LC_MESSAGES/bootstack.po +842 -0
- bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.po +842 -0
- bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.po +842 -0
- bootstack/assets/themes/__init__.py +0 -0
- bootstack/assets/themes/amber-dark.json +32 -0
- bootstack/assets/themes/amber-light.json +32 -0
- bootstack/assets/themes/aurora-dark.json +32 -0
- bootstack/assets/themes/aurora-light.json +32 -0
- bootstack/assets/themes/bootstrap-dark.json +32 -0
- bootstack/assets/themes/bootstrap-light.json +32 -0
- bootstack/assets/themes/classic-dark.json +32 -0
- bootstack/assets/themes/classic-light.json +32 -0
- bootstack/assets/themes/docs-dark.json +32 -0
- bootstack/assets/themes/docs-light.json +32 -0
- bootstack/assets/themes/forest-dark.json +32 -0
- bootstack/assets/themes/forest-light.json +32 -0
- bootstack/assets/themes/ocean-dark.json +32 -0
- bootstack/assets/themes/ocean-light.json +32 -0
- bootstack/assets/themes/rose-dark.json +32 -0
- bootstack/assets/themes/rose-light.json +32 -0
- bootstack/assets/widgets/__init__.py +0 -0
- bootstack/assets/widgets/badge-default.png +0 -0
- bootstack/assets/widgets/badge-pill.png +0 -0
- bootstack/assets/widgets/border.png +0 -0
- bootstack/assets/widgets/button-group-horizontal-after.png +0 -0
- bootstack/assets/widgets/button-group-horizontal-before.png +0 -0
- bootstack/assets/widgets/button-group-horizontal-center.png +0 -0
- bootstack/assets/widgets/button-group-vertical-after.png +0 -0
- bootstack/assets/widgets/button-group-vertical-before.png +0 -0
- bootstack/assets/widgets/button-group-vertical-center.png +0 -0
- bootstack/assets/widgets/button.png +0 -0
- bootstack/assets/widgets/checkbox-checked.png +0 -0
- bootstack/assets/widgets/checkbox-indeterminate.png +0 -0
- bootstack/assets/widgets/checkbox-unchecked.png +0 -0
- bootstack/assets/widgets/field.png +0 -0
- bootstack/assets/widgets/icon-button.png +0 -0
- bootstack/assets/widgets/input-inner.png +0 -0
- bootstack/assets/widgets/input-prefix.png +0 -0
- bootstack/assets/widgets/input-suffix.png +0 -0
- bootstack/assets/widgets/input.png +0 -0
- bootstack/assets/widgets/list-item-focus.png +0 -0
- bootstack/assets/widgets/list-item-separated.png +0 -0
- bootstack/assets/widgets/menu-item-separated.png +0 -0
- bootstack/assets/widgets/notebook-client-border.png +0 -0
- bootstack/assets/widgets/notebook-pill-active.png +0 -0
- bootstack/assets/widgets/notebook-pill-inactive.png +0 -0
- bootstack/assets/widgets/notebook-tab-active.png +0 -0
- bootstack/assets/widgets/notebook-tab-border.png +0 -0
- bootstack/assets/widgets/notebook-tab-normal.png +0 -0
- bootstack/assets/widgets/notebook-underline.png +0 -0
- bootstack/assets/widgets/progress-bar-horizontal-default.png +0 -0
- bootstack/assets/widgets/progress-bar-horizontal-striped.png +0 -0
- bootstack/assets/widgets/progress-bar-vertical-default.png +0 -0
- bootstack/assets/widgets/progress-bar-vertical-striped.png +0 -0
- bootstack/assets/widgets/progress-trough-horizontal.png +0 -0
- bootstack/assets/widgets/progress-trough-vertical.png +0 -0
- bootstack/assets/widgets/radio-selected.png +0 -0
- bootstack/assets/widgets/radio-unselected.png +0 -0
- bootstack/assets/widgets/scrollbar-horizontal-rounded.png +0 -0
- bootstack/assets/widgets/scrollbar-vertical-rounded.png +0 -0
- bootstack/assets/widgets/separator-horizontal.png +0 -0
- bootstack/assets/widgets/separator-vertical.png +0 -0
- bootstack/assets/widgets/slider-handle-focus.png +0 -0
- bootstack/assets/widgets/slider-handle.png +0 -0
- bootstack/assets/widgets/slider-track-horizontal.png +0 -0
- bootstack/assets/widgets/slider-track-vertical.png +0 -0
- bootstack/assets/widgets/switch-off.png +0 -0
- bootstack/assets/widgets/switch-on.png +0 -0
- bootstack/assets/widgets/tabs-bar-horizontal.png +0 -0
- bootstack/assets/widgets/tabs-bar-vertical.png +0 -0
- bootstack/assets/widgets/tabs-pill.png +0 -0
- bootstack/cli/__init__.py +124 -0
- bootstack/cli/__main__.py +6 -0
- bootstack/cli/add.py +439 -0
- bootstack/cli/build.py +115 -0
- bootstack/cli/config.py +287 -0
- bootstack/cli/demo.py +1267 -0
- bootstack/cli/doctor.py +195 -0
- bootstack/cli/list_cmd.py +71 -0
- bootstack/cli/promote.py +120 -0
- bootstack/cli/pyinstaller.py +246 -0
- bootstack/cli/run.py +99 -0
- bootstack/cli/start.py +105 -0
- bootstack/cli/templates/__init__.py +861 -0
- bootstack/constants.py +325 -0
- bootstack/core/__init__.py +34 -0
- bootstack/core/capabilities/__init__.py +45 -0
- bootstack/core/capabilities/after.py +103 -0
- bootstack/core/capabilities/bind.py +154 -0
- bootstack/core/capabilities/bindtags.py +112 -0
- bootstack/core/capabilities/busy.py +61 -0
- bootstack/core/capabilities/clipboard.py +88 -0
- bootstack/core/capabilities/focus.py +118 -0
- bootstack/core/capabilities/grab.py +65 -0
- bootstack/core/capabilities/grid.py +188 -0
- bootstack/core/capabilities/localization.py +231 -0
- bootstack/core/capabilities/pack.py +119 -0
- bootstack/core/capabilities/place.py +92 -0
- bootstack/core/capabilities/selection.py +136 -0
- bootstack/core/capabilities/signals.py +242 -0
- bootstack/core/capabilities/winfo.py +315 -0
- bootstack/core/colorutils.py +234 -0
- bootstack/core/exceptions.py +95 -0
- bootstack/core/images.py +283 -0
- bootstack/core/localization/README.md +90 -0
- bootstack/core/localization/__init__.py +13 -0
- bootstack/core/localization/intl_format.py +580 -0
- bootstack/core/localization/msgcat.py +425 -0
- bootstack/core/localization/specs.py +143 -0
- bootstack/core/mixins/__init__.py +1 -0
- bootstack/core/mixins/ttk_state.py +35 -0
- bootstack/core/mixins/widget.py +132 -0
- bootstack/core/publisher.py +147 -0
- bootstack/core/signals/README.md +112 -0
- bootstack/core/signals/__init__.py +8 -0
- bootstack/core/signals/integration.py +100 -0
- bootstack/core/signals/signal.py +317 -0
- bootstack/core/signals/types.py +4 -0
- bootstack/core/validation/__init__.py +5 -0
- bootstack/core/validation/types.py +13 -0
- bootstack/core/validation/validation_result.py +17 -0
- bootstack/core/validation/validation_rules.py +112 -0
- bootstack/core/variables.py +62 -0
- bootstack/datasource/README.md +607 -0
- bootstack/datasource/__init__.py +51 -0
- bootstack/datasource/base.py +474 -0
- bootstack/datasource/file_source.py +541 -0
- bootstack/datasource/memory_source.py +482 -0
- bootstack/datasource/sqlite_source.py +453 -0
- bootstack/datasource/types.py +259 -0
- bootstack/dialogs/__init__.py +56 -0
- bootstack/dialogs/colorchooser.py +674 -0
- bootstack/dialogs/colordropper.py +257 -0
- bootstack/dialogs/datedialog.py +404 -0
- bootstack/dialogs/dialog.py +514 -0
- bootstack/dialogs/filterdialog.py +358 -0
- bootstack/dialogs/fontdialog.py +339 -0
- bootstack/dialogs/formdialog.py +541 -0
- bootstack/dialogs/message.py +489 -0
- bootstack/dialogs/query.py +561 -0
- bootstack/py.typed +1 -0
- bootstack/runtime/__init__.py +3 -0
- bootstack/runtime/app.py +879 -0
- bootstack/runtime/base_window.py +786 -0
- bootstack/runtime/events.py +399 -0
- bootstack/runtime/menu.py +510 -0
- bootstack/runtime/shortcuts.py +423 -0
- bootstack/runtime/tk_patch.py +31 -0
- bootstack/runtime/toplevel.py +131 -0
- bootstack/runtime/utility.py +371 -0
- bootstack/runtime/visual_focus.py +228 -0
- bootstack/runtime/window_utilities.py +1043 -0
- bootstack/style/__init__.py +5498 -0
- bootstack/style/bootstyle.py +507 -0
- bootstack/style/bootstyle_builder_base.py +752 -0
- bootstack/style/bootstyle_builder_mixed.py +93 -0
- bootstack/style/bootstyle_builder_tk.py +109 -0
- bootstack/style/bootstyle_builder_ttk.py +354 -0
- bootstack/style/builders/__init__.py +51 -0
- bootstack/style/builders/badge.py +44 -0
- bootstack/style/builders/button.py +453 -0
- bootstack/style/builders/buttongroup.py +344 -0
- bootstack/style/builders/calendar.py +271 -0
- bootstack/style/builders/checkbutton.py +95 -0
- bootstack/style/builders/combobox.py +112 -0
- bootstack/style/builders/contextmenu.py +268 -0
- bootstack/style/builders/entry.py +83 -0
- bootstack/style/builders/expander.py +171 -0
- bootstack/style/builders/field.py +312 -0
- bootstack/style/builders/frame.py +27 -0
- bootstack/style/builders/label.py +28 -0
- bootstack/style/builders/labelframe.py +41 -0
- bootstack/style/builders/listview.py +267 -0
- bootstack/style/builders/menubar.py +74 -0
- bootstack/style/builders/menubutton.py +408 -0
- bootstack/style/builders/notebook.py +316 -0
- bootstack/style/builders/panedwindow.py +25 -0
- bootstack/style/builders/progressbar.py +71 -0
- bootstack/style/builders/radiobutton.py +68 -0
- bootstack/style/builders/scale.py +66 -0
- bootstack/style/builders/scrollbar.py +360 -0
- bootstack/style/builders/separator.py +45 -0
- bootstack/style/builders/sidenav.py +313 -0
- bootstack/style/builders/sizegrip.py +15 -0
- bootstack/style/builders/spinbox.py +119 -0
- bootstack/style/builders/switch.py +67 -0
- bootstack/style/builders/tabitem.py +205 -0
- bootstack/style/builders/toolbutton.py +260 -0
- bootstack/style/builders/tooltip.py +26 -0
- bootstack/style/builders/treeview.py +269 -0
- bootstack/style/builders/utils.py +404 -0
- bootstack/style/builders_tk/__init__.py +16 -0
- bootstack/style/builders_tk/defaults.py +229 -0
- bootstack/style/element.py +173 -0
- bootstack/style/style.py +499 -0
- bootstack/style/theme_provider.py +449 -0
- bootstack/style/tk_patch.py +5 -0
- bootstack/style/token_maps.py +42 -0
- bootstack/style/types.py +32 -0
- bootstack/style/typography.py +527 -0
- bootstack/style/utility.py +696 -0
- bootstack/themes/__init__.py +12 -0
- bootstack/themes/standard.py +415 -0
- bootstack/themes/user.py +45 -0
- bootstack/widgets/__init__.py +53 -0
- bootstack/widgets/composites/__init__.py +38 -0
- bootstack/widgets/composites/accordion.py +385 -0
- bootstack/widgets/composites/appshell.py +445 -0
- bootstack/widgets/composites/buttongroup.py +391 -0
- bootstack/widgets/composites/calendar.py +914 -0
- bootstack/widgets/composites/compositeframe.py +282 -0
- bootstack/widgets/composites/contextmenu.py +1754 -0
- bootstack/widgets/composites/dateentry.py +261 -0
- bootstack/widgets/composites/dropdownbutton.py +190 -0
- bootstack/widgets/composites/expander.py +508 -0
- bootstack/widgets/composites/field.py +448 -0
- bootstack/widgets/composites/floodgauge.py +434 -0
- bootstack/widgets/composites/form.py +983 -0
- bootstack/widgets/composites/labeledscale.py +209 -0
- bootstack/widgets/composites/list/__init__.py +15 -0
- bootstack/widgets/composites/list/listitem.py +733 -0
- bootstack/widgets/composites/list/listview.py +1507 -0
- bootstack/widgets/composites/menubar.py +303 -0
- bootstack/widgets/composites/meter.py +882 -0
- bootstack/widgets/composites/numericentry.py +183 -0
- bootstack/widgets/composites/pagestack.py +330 -0
- bootstack/widgets/composites/passwordentry.py +149 -0
- bootstack/widgets/composites/pathentry.py +223 -0
- bootstack/widgets/composites/radiogroup.py +466 -0
- bootstack/widgets/composites/scrolledtext.py +388 -0
- bootstack/widgets/composites/scrolledtext.pyi +186 -0
- bootstack/widgets/composites/scrollview.py +675 -0
- bootstack/widgets/composites/selectbox.py +544 -0
- bootstack/widgets/composites/sidenav/__init__.py +24 -0
- bootstack/widgets/composites/sidenav/group.py +485 -0
- bootstack/widgets/composites/sidenav/header.py +83 -0
- bootstack/widgets/composites/sidenav/item.py +413 -0
- bootstack/widgets/composites/sidenav/separator.py +51 -0
- bootstack/widgets/composites/sidenav/view.py +919 -0
- bootstack/widgets/composites/spinnerentry.py +232 -0
- bootstack/widgets/composites/tableview/__init__.py +5 -0
- bootstack/widgets/composites/tableview/tableview.py +2254 -0
- bootstack/widgets/composites/tableview/types.py +169 -0
- bootstack/widgets/composites/tabs/__init__.py +6 -0
- bootstack/widgets/composites/tabs/tabitem.py +372 -0
- bootstack/widgets/composites/tabs/tabs.py +478 -0
- bootstack/widgets/composites/tabs/tabview.py +352 -0
- bootstack/widgets/composites/textentry.py +90 -0
- bootstack/widgets/composites/timeentry.py +189 -0
- bootstack/widgets/composites/toast.py +364 -0
- bootstack/widgets/composites/togglegroup.py +382 -0
- bootstack/widgets/composites/toolbar.py +393 -0
- bootstack/widgets/composites/tooltip.py +404 -0
- bootstack/widgets/internal/__init__.py +0 -0
- bootstack/widgets/internal/wrapper_base.py +304 -0
- bootstack/widgets/mixins/__init__.py +25 -0
- bootstack/widgets/mixins/configure_mixin.py +186 -0
- bootstack/widgets/mixins/entry_mixin.py +70 -0
- bootstack/widgets/mixins/font_mixin.py +346 -0
- bootstack/widgets/mixins/icon_mixin.py +38 -0
- bootstack/widgets/mixins/localization_mixin.py +255 -0
- bootstack/widgets/mixins/signal_mixin.py +272 -0
- bootstack/widgets/mixins/validation_mixin.py +204 -0
- bootstack/widgets/parts/__init__.py +11 -0
- bootstack/widgets/parts/numberentry_part.py +345 -0
- bootstack/widgets/parts/spinnerentry_part.py +394 -0
- bootstack/widgets/parts/textentry_part.py +344 -0
- bootstack/widgets/primitives/__init__.py +55 -0
- bootstack/widgets/primitives/badge.py +44 -0
- bootstack/widgets/primitives/button.py +89 -0
- bootstack/widgets/primitives/card.py +66 -0
- bootstack/widgets/primitives/checkbutton.py +124 -0
- bootstack/widgets/primitives/checktoggle.py +53 -0
- bootstack/widgets/primitives/combobox.py +165 -0
- bootstack/widgets/primitives/entry.py +98 -0
- bootstack/widgets/primitives/frame.py +206 -0
- bootstack/widgets/primitives/gridframe.py +479 -0
- bootstack/widgets/primitives/label.py +95 -0
- bootstack/widgets/primitives/labelframe.py +63 -0
- bootstack/widgets/primitives/menubutton.py +118 -0
- bootstack/widgets/primitives/notebook.py +551 -0
- bootstack/widgets/primitives/optionmenu.py +248 -0
- bootstack/widgets/primitives/packframe.py +228 -0
- bootstack/widgets/primitives/panedwindow.py +58 -0
- bootstack/widgets/primitives/progressbar.py +95 -0
- bootstack/widgets/primitives/radiobutton.py +115 -0
- bootstack/widgets/primitives/radiotoggle.py +50 -0
- bootstack/widgets/primitives/scale.py +85 -0
- bootstack/widgets/primitives/scrollbar.py +56 -0
- bootstack/widgets/primitives/separator.py +56 -0
- bootstack/widgets/primitives/sizegrip.py +47 -0
- bootstack/widgets/primitives/spinbox.py +91 -0
- bootstack/widgets/primitives/switch.py +41 -0
- bootstack/widgets/primitives/treeview.py +77 -0
- bootstack/widgets/types.py +20 -0
- bootstack-0.1.0a1.dist-info/METADATA +196 -0
- bootstack-0.1.0a1.dist-info/RECORD +419 -0
- bootstack-0.1.0a1.dist-info/WHEEL +5 -0
- bootstack-0.1.0a1.dist-info/entry_points.txt +2 -0
- bootstack-0.1.0a1.dist-info/licenses/LICENSE +22 -0
- bootstack-0.1.0a1.dist-info/licenses/NOTICE +10 -0
- bootstack-0.1.0a1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
"""Query dialogs and querybox facade for data input."""
|
|
2
|
+
|
|
3
|
+
import textwrap
|
|
4
|
+
import tkinter
|
|
5
|
+
from datetime import date
|
|
6
|
+
from types import SimpleNamespace
|
|
7
|
+
from typing import Any, Callable, List, Optional
|
|
8
|
+
|
|
9
|
+
from bootstack.widgets.primitives import Combobox, Frame, Label
|
|
10
|
+
from bootstack.constants import *
|
|
11
|
+
|
|
12
|
+
ttk = SimpleNamespace(
|
|
13
|
+
Combobox=Combobox,
|
|
14
|
+
Frame=Frame,
|
|
15
|
+
Label=Label,
|
|
16
|
+
)
|
|
17
|
+
from bootstack.core.localization import MessageCatalog
|
|
18
|
+
from bootstack.dialogs.datedialog import DateDialog
|
|
19
|
+
from bootstack.dialogs.dialog import Dialog, DialogButton
|
|
20
|
+
from bootstack.dialogs.fontdialog import FontDialog
|
|
21
|
+
from bootstack.dialogs.message import MessageBox
|
|
22
|
+
from bootstack.widgets.composites.textentry import TextEntry
|
|
23
|
+
from bootstack.widgets.composites.numericentry import NumericEntry
|
|
24
|
+
from bootstack.widgets.composites.dateentry import DateEntry
|
|
25
|
+
|
|
26
|
+
EntryWidget = TextEntry | NumericEntry | DateEntry
|
|
27
|
+
|
|
28
|
+
class QueryDialog:
|
|
29
|
+
"""A modal dialog for collecting user input with validation.
|
|
30
|
+
|
|
31
|
+
!!! note "Events"
|
|
32
|
+
|
|
33
|
+
`<<DialogResult>>`: Fired when dialog closes.
|
|
34
|
+
Provides `event.data` with keys: `result` (Any), `confirmed` (bool).
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def __init__(
|
|
38
|
+
self,
|
|
39
|
+
prompt: str,
|
|
40
|
+
title: str = " ",
|
|
41
|
+
value: Any = "",
|
|
42
|
+
minvalue: Optional[Any] = None,
|
|
43
|
+
maxvalue: Optional[Any] = None,
|
|
44
|
+
width: int = 65,
|
|
45
|
+
datatype: Any = str,
|
|
46
|
+
padding: tuple[int, int] | int = (20, 20),
|
|
47
|
+
master: Optional[tkinter.Misc] = None,
|
|
48
|
+
items: Optional[List[str]] = None,
|
|
49
|
+
value_format: Optional[str] = None,
|
|
50
|
+
increment: Optional[int | float] = None,
|
|
51
|
+
) -> None:
|
|
52
|
+
"""Create a query dialog for collecting user input.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
prompt: The prompt text to display above the input field. Supports multiline strings.
|
|
56
|
+
title: The dialog window title.
|
|
57
|
+
value: The initial value to populate in the input field.
|
|
58
|
+
value_format: Optional ICU format pattern for formatting/parsing values.
|
|
59
|
+
For numbers: e.g., '$#,##0.00' for currency, '#,##0.##' for decimals
|
|
60
|
+
For dates: e.g., 'shortDate', 'longDate', 'yyyy-MM-dd'
|
|
61
|
+
When provided, uses specialized Field widgets (TextEntry, NumericEntry, DateEntry).
|
|
62
|
+
minvalue: Minimum allowed value for numeric data types. Ignored for strings.
|
|
63
|
+
maxvalue: Maximum allowed value for numeric data types. Ignored for strings.
|
|
64
|
+
increment: Step size for numeric fields (passed to NumericEntry).
|
|
65
|
+
width: Maximum width in characters for text wrapping of the prompt.
|
|
66
|
+
datatype: Expected data type for validation (str, int, float, date, complex).
|
|
67
|
+
padding: Padding around the dialog content.
|
|
68
|
+
master: Parent widget for the dialog.
|
|
69
|
+
items: Optional list of items for dropdown selection. Shows a Combobox instead of Entry.
|
|
70
|
+
"""
|
|
71
|
+
self._prompt = prompt
|
|
72
|
+
self._value = value
|
|
73
|
+
self._items = items
|
|
74
|
+
self._minvalue = minvalue
|
|
75
|
+
self._maxvalue = maxvalue
|
|
76
|
+
self._width = width
|
|
77
|
+
self._datatype = datatype
|
|
78
|
+
self._padding = padding
|
|
79
|
+
self._value_format = value_format
|
|
80
|
+
self._increment = increment
|
|
81
|
+
self._entry_widget: Optional[EntryWidget] = None
|
|
82
|
+
self._master = master
|
|
83
|
+
|
|
84
|
+
# Create the underlying dialog with inline button specifications
|
|
85
|
+
self._dialog = Dialog(
|
|
86
|
+
master=master,
|
|
87
|
+
title=title,
|
|
88
|
+
content_builder=self._create_content,
|
|
89
|
+
buttons=[
|
|
90
|
+
DialogButton(
|
|
91
|
+
text="button.cancel", # Use semantic key - built-in localization
|
|
92
|
+
role="cancel",
|
|
93
|
+
result=None,
|
|
94
|
+
),
|
|
95
|
+
DialogButton(
|
|
96
|
+
text="button.submit", # Use semantic key - built-in localization
|
|
97
|
+
role="primary",
|
|
98
|
+
default=True,
|
|
99
|
+
command=lambda dlg: self._on_submit(),
|
|
100
|
+
closes=False, # Don't close yet - we need to validate first
|
|
101
|
+
),
|
|
102
|
+
],
|
|
103
|
+
minsize=(350, 120),
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
def _create_content(self, parent: tkinter.Widget) -> None:
|
|
107
|
+
"""Create the dialog body with prompt and input field."""
|
|
108
|
+
frame = ttk.Frame(parent, padding=self._padding)
|
|
109
|
+
|
|
110
|
+
# Create prompt label(s)
|
|
111
|
+
if self._prompt:
|
|
112
|
+
for p in self._prompt.split("\n"):
|
|
113
|
+
prompt = "\n".join(textwrap.wrap(p, width=self._width))
|
|
114
|
+
prompt_label = ttk.Label(frame, text=prompt)
|
|
115
|
+
prompt_label.pack(pady=(0, 5), fill=X, anchor=N)
|
|
116
|
+
|
|
117
|
+
# Create appropriate input field based on datatype and options
|
|
118
|
+
if self._items is not None and len(self._items) > 0:
|
|
119
|
+
# Combobox for item selection
|
|
120
|
+
entry = ttk.Combobox(master=frame, values=self._items)
|
|
121
|
+
entry.bind("<KeyRelease>", self._on_filter_list)
|
|
122
|
+
if self._value:
|
|
123
|
+
entry.set(self._value)
|
|
124
|
+
elif self._datatype == date:
|
|
125
|
+
# DateEntry for date input
|
|
126
|
+
kwargs = {"value": self._value} if self._value else {}
|
|
127
|
+
if self._value_format:
|
|
128
|
+
kwargs["value_format"] = self._value_format
|
|
129
|
+
kwargs.setdefault("initial_focus", True)
|
|
130
|
+
entry = DateEntry(master=frame, label=None, show_message=False, **kwargs)
|
|
131
|
+
elif self._datatype in (int, float):
|
|
132
|
+
# NumericEntry for numeric input with validation
|
|
133
|
+
kwargs = {"value": self._value if self._value else 0}
|
|
134
|
+
if self._minvalue is not None:
|
|
135
|
+
kwargs["minvalue"] = self._minvalue
|
|
136
|
+
if self._maxvalue is not None:
|
|
137
|
+
kwargs["maxvalue"] = self._maxvalue
|
|
138
|
+
if self._value_format:
|
|
139
|
+
kwargs["value_format"] = self._value_format
|
|
140
|
+
if self._increment is not None:
|
|
141
|
+
kwargs["increment"] = self._increment
|
|
142
|
+
kwargs.setdefault("initial_focus", True)
|
|
143
|
+
entry = NumericEntry(master=frame, label=None, show_message=False, **kwargs)
|
|
144
|
+
else:
|
|
145
|
+
# TextEntry for string input
|
|
146
|
+
kwargs = {"value": str(self._value) if self._value else ""}
|
|
147
|
+
if self._value_format:
|
|
148
|
+
kwargs["value_format"] = self._value_format
|
|
149
|
+
kwargs.setdefault("initial_focus", True)
|
|
150
|
+
entry = TextEntry(master=frame, label=None, show_message=False, **kwargs)
|
|
151
|
+
|
|
152
|
+
entry.pack(pady=(0, 5), fill=X)
|
|
153
|
+
entry.bind("<Return>", self._on_submit)
|
|
154
|
+
entry.bind("<KP_Enter>", self._on_submit)
|
|
155
|
+
|
|
156
|
+
# Focus the entry field
|
|
157
|
+
def _focus():
|
|
158
|
+
if hasattr(entry, 'entry_widget'):
|
|
159
|
+
entry.entry_widget.focus_set()
|
|
160
|
+
else:
|
|
161
|
+
entry.focus_set()
|
|
162
|
+
|
|
163
|
+
_focus()
|
|
164
|
+
# Ensure focus after dialog buttons set their own focus
|
|
165
|
+
entry.after_idle(_focus)
|
|
166
|
+
|
|
167
|
+
frame.pack(fill=X, expand=True)
|
|
168
|
+
self._entry_widget = entry
|
|
169
|
+
|
|
170
|
+
def _on_submit(self, *_: Any) -> None:
|
|
171
|
+
"""Handle submit (Enter key or button click)."""
|
|
172
|
+
if not self._entry_widget:
|
|
173
|
+
return
|
|
174
|
+
|
|
175
|
+
# Get value from widget - Field widgets use .value, Entry/Combobox use .get()
|
|
176
|
+
if hasattr(self._entry_widget, 'value'):
|
|
177
|
+
# Field widgets (TextEntry, NumericEntry, DateEntry)
|
|
178
|
+
result = self._entry_widget.value
|
|
179
|
+
# Field widgets handle their own validation, so we can use the value directly
|
|
180
|
+
if result is not None:
|
|
181
|
+
self._dialog.result = result
|
|
182
|
+
if self._dialog.toplevel:
|
|
183
|
+
self._dialog.toplevel.destroy()
|
|
184
|
+
else:
|
|
185
|
+
# Regular Entry/Combobox - use old validation logic
|
|
186
|
+
result = self._entry_widget.get()
|
|
187
|
+
if self._validate(result):
|
|
188
|
+
self._dialog.result = self._datatype(result) if self._datatype != str else result
|
|
189
|
+
if self._dialog.toplevel:
|
|
190
|
+
self._dialog.toplevel.destroy()
|
|
191
|
+
|
|
192
|
+
def _on_filter_list(self, event: tkinter.Event) -> None:
|
|
193
|
+
"""Filter combobox items based on user input."""
|
|
194
|
+
value = event.widget.get().lower()
|
|
195
|
+
if not value:
|
|
196
|
+
event.widget["values"] = self._items
|
|
197
|
+
else:
|
|
198
|
+
data = [k for k in self._items if value in k.lower()]
|
|
199
|
+
event.widget["values"] = data
|
|
200
|
+
|
|
201
|
+
def _validate(self, result: str) -> bool:
|
|
202
|
+
"""Validate the input data."""
|
|
203
|
+
# No validation for string data types unless there's a list of items
|
|
204
|
+
if self._datatype not in [float, int, complex] and (self._items is None or len(self._items) == 0):
|
|
205
|
+
return True
|
|
206
|
+
|
|
207
|
+
# Convert result to appropriate data type
|
|
208
|
+
try:
|
|
209
|
+
converted_result = self._datatype(result)
|
|
210
|
+
except ValueError:
|
|
211
|
+
msg = MessageCatalog.translate("validation.should_be_type")
|
|
212
|
+
MessageBox.ok(
|
|
213
|
+
message=f"{msg} `{self._datatype}`",
|
|
214
|
+
title=MessageCatalog.translate("validation.invalid_type"),
|
|
215
|
+
master=self._dialog.toplevel,
|
|
216
|
+
)
|
|
217
|
+
return False
|
|
218
|
+
|
|
219
|
+
# Check max value range
|
|
220
|
+
if self._maxvalue is not None and converted_result > self._maxvalue:
|
|
221
|
+
msg = MessageCatalog.translate("validation.greater_than")
|
|
222
|
+
MessageBox.ok(
|
|
223
|
+
message=f"{msg} {self._maxvalue}",
|
|
224
|
+
title=MessageCatalog.translate("validation.out_of_range"),
|
|
225
|
+
master=self._dialog.toplevel,
|
|
226
|
+
)
|
|
227
|
+
return False
|
|
228
|
+
|
|
229
|
+
# Check min value range
|
|
230
|
+
if self._minvalue is not None and converted_result < self._minvalue:
|
|
231
|
+
msg = MessageCatalog.translate("validation.less_than")
|
|
232
|
+
MessageBox.ok(
|
|
233
|
+
message=f"{msg} {self._minvalue}",
|
|
234
|
+
title=MessageCatalog.translate("validation.out_of_range"),
|
|
235
|
+
master=self._dialog.toplevel,
|
|
236
|
+
)
|
|
237
|
+
return False
|
|
238
|
+
|
|
239
|
+
# Check if item is in list
|
|
240
|
+
if self._items is not None and len(self._items) > 0 and result not in self._items:
|
|
241
|
+
msg = MessageCatalog.translate("validation.select_item")
|
|
242
|
+
MessageBox.ok(
|
|
243
|
+
message=msg,
|
|
244
|
+
title=MessageCatalog.translate("validation.out_of_range"),
|
|
245
|
+
master=self._dialog.toplevel,
|
|
246
|
+
)
|
|
247
|
+
return False
|
|
248
|
+
|
|
249
|
+
return True
|
|
250
|
+
|
|
251
|
+
def show(self, position: Optional[tuple[int, int]] = None) -> None:
|
|
252
|
+
"""Show the dialog.
|
|
253
|
+
|
|
254
|
+
Args:
|
|
255
|
+
position: x and y coordinates to position the dialog. If None, centers on parent.
|
|
256
|
+
"""
|
|
257
|
+
self._dialog.show(position=position, modal=True)
|
|
258
|
+
target = self._dialog.toplevel or self._master
|
|
259
|
+
if target:
|
|
260
|
+
payload = {"result": self._dialog.result, "confirmed": self._dialog.result is not None}
|
|
261
|
+
try:
|
|
262
|
+
target.event_generate("<<DialogResult>>", data=payload)
|
|
263
|
+
except Exception:
|
|
264
|
+
try:
|
|
265
|
+
target.event_generate("<<DialogResult>>")
|
|
266
|
+
except Exception:
|
|
267
|
+
pass
|
|
268
|
+
|
|
269
|
+
@property
|
|
270
|
+
def result(self) -> Any:
|
|
271
|
+
"""The dialog result value."""
|
|
272
|
+
return self._dialog.result
|
|
273
|
+
|
|
274
|
+
def on_dialog_result(self, callback: Callable[[Any], None]) -> Optional[str]:
|
|
275
|
+
"""Bind a callback fired when the dialog produces a result.
|
|
276
|
+
|
|
277
|
+
The callback receives `event.data["result"]` when available.
|
|
278
|
+
|
|
279
|
+
Args:
|
|
280
|
+
callback: Callable that receives the result payload.
|
|
281
|
+
|
|
282
|
+
Returns:
|
|
283
|
+
Binding identifier for use with `off_dialog_result`.
|
|
284
|
+
"""
|
|
285
|
+
target = self._dialog.toplevel or self._master
|
|
286
|
+
if target is None:
|
|
287
|
+
return None
|
|
288
|
+
|
|
289
|
+
def handler(event):
|
|
290
|
+
callback(getattr(event, "data", None))
|
|
291
|
+
|
|
292
|
+
return target.bind("<<DialogResult>>", handler, add="+")
|
|
293
|
+
|
|
294
|
+
def off_dialog_result(self, funcid: str) -> None:
|
|
295
|
+
"""Unbind a previously bound dialog result callback."""
|
|
296
|
+
target = self._dialog.toplevel or self._master
|
|
297
|
+
if target is None:
|
|
298
|
+
return
|
|
299
|
+
target.unbind("<<DialogResult>>", funcid)
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
class QueryBox:
|
|
303
|
+
"""Static methods for displaying query dialogs."""
|
|
304
|
+
|
|
305
|
+
@staticmethod
|
|
306
|
+
def get_color(
|
|
307
|
+
master: Optional[tkinter.Misc] = None,
|
|
308
|
+
title: str = "Color Chooser",
|
|
309
|
+
value: Optional[str] = None,
|
|
310
|
+
**kwargs: Any,
|
|
311
|
+
) -> Any:
|
|
312
|
+
"""Show a color picker dialog.
|
|
313
|
+
|
|
314
|
+
Args:
|
|
315
|
+
master: Parent widget for the dialog.
|
|
316
|
+
title: The dialog window title.
|
|
317
|
+
value: Initial color to display.
|
|
318
|
+
**kwargs: Additional arguments including 'position'.
|
|
319
|
+
|
|
320
|
+
Returns:
|
|
321
|
+
Selected color or None if canceled.
|
|
322
|
+
"""
|
|
323
|
+
from bootstack.dialogs.colorchooser import ColorChooserDialog
|
|
324
|
+
|
|
325
|
+
position = kwargs.pop("position", None)
|
|
326
|
+
dialog = ColorChooserDialog(master, title, value)
|
|
327
|
+
dialog.show(position)
|
|
328
|
+
return dialog.result
|
|
329
|
+
|
|
330
|
+
@staticmethod
|
|
331
|
+
def get_date(
|
|
332
|
+
master: Optional[tkinter.Misc] = None,
|
|
333
|
+
title: str = " ",
|
|
334
|
+
first_weekday: int = 6,
|
|
335
|
+
value: Optional[date] = None,
|
|
336
|
+
accent: str = None,
|
|
337
|
+
hide_window_chrome: bool = False,
|
|
338
|
+
on_result: Optional[Callable[[Any], None]] = None,
|
|
339
|
+
**kwargs: Any,
|
|
340
|
+
) -> Optional[date]:
|
|
341
|
+
"""Show a date picker dialog.
|
|
342
|
+
|
|
343
|
+
Args:
|
|
344
|
+
master: Parent widget for the dialog.
|
|
345
|
+
title: The dialog window title.
|
|
346
|
+
first_weekday: First day of the week (0=Monday, 6=Sunday).
|
|
347
|
+
value: Initial date to display.
|
|
348
|
+
accent: Accent token for the calendar (e.g., 'primary', 'success').
|
|
349
|
+
hide_window_chrome: If True, shows the dialog with override-redirect
|
|
350
|
+
to hide window decorations.
|
|
351
|
+
on_result: Optional callback receiving the dialog result payload.
|
|
352
|
+
**kwargs: Additional arguments including 'position'.
|
|
353
|
+
|
|
354
|
+
Returns:
|
|
355
|
+
Selected date or None if canceled.
|
|
356
|
+
"""
|
|
357
|
+
position = kwargs.pop("position", None)
|
|
358
|
+
dialog = DateDialog(
|
|
359
|
+
master=master,
|
|
360
|
+
title=title,
|
|
361
|
+
first_weekday=first_weekday,
|
|
362
|
+
initial_date=value,
|
|
363
|
+
accent=accent or "primary",
|
|
364
|
+
hide_window_chrome=hide_window_chrome,
|
|
365
|
+
)
|
|
366
|
+
if on_result:
|
|
367
|
+
dialog.on_result(on_result)
|
|
368
|
+
dialog.show(position)
|
|
369
|
+
return dialog.result
|
|
370
|
+
|
|
371
|
+
@staticmethod
|
|
372
|
+
def get_string(
|
|
373
|
+
prompt: str = "",
|
|
374
|
+
title: str = " ",
|
|
375
|
+
value: Optional[str] = None,
|
|
376
|
+
master: Optional[tkinter.Misc] = None,
|
|
377
|
+
value_format: Optional[str] = None,
|
|
378
|
+
on_result: Optional[Callable[[Any], None]] = None,
|
|
379
|
+
**kwargs: Any,
|
|
380
|
+
) -> Optional[str]:
|
|
381
|
+
"""Show a string input dialog.
|
|
382
|
+
|
|
383
|
+
Args:
|
|
384
|
+
prompt: The prompt text to display.
|
|
385
|
+
title: The dialog window title.
|
|
386
|
+
value: Initial value for the input field.
|
|
387
|
+
master: Parent widget for the dialog.
|
|
388
|
+
value_format: Optional ICU format pattern for parsing/formatting.
|
|
389
|
+
on_result: Optional callback receiving the dialog result payload.
|
|
390
|
+
**kwargs: Additional arguments including 'position'.
|
|
391
|
+
|
|
392
|
+
Returns:
|
|
393
|
+
Input string or None if canceled.
|
|
394
|
+
"""
|
|
395
|
+
value = value or ""
|
|
396
|
+
position = kwargs.pop("position", None)
|
|
397
|
+
dialog = QueryDialog(
|
|
398
|
+
prompt,
|
|
399
|
+
title,
|
|
400
|
+
value,
|
|
401
|
+
master=master,
|
|
402
|
+
value_format=value_format,
|
|
403
|
+
**kwargs,
|
|
404
|
+
)
|
|
405
|
+
if on_result:
|
|
406
|
+
dialog.on_dialog_result(on_result)
|
|
407
|
+
dialog.show(position)
|
|
408
|
+
return dialog.result
|
|
409
|
+
|
|
410
|
+
@staticmethod
|
|
411
|
+
def get_item(
|
|
412
|
+
prompt: str = "",
|
|
413
|
+
title: str = " ",
|
|
414
|
+
value: Optional[str] = None,
|
|
415
|
+
items: Optional[List[str]] = None,
|
|
416
|
+
master: Optional[tkinter.Misc] = None,
|
|
417
|
+
on_result: Optional[Callable[[Any], None]] = None,
|
|
418
|
+
**kwargs: Any,
|
|
419
|
+
) -> Optional[str]:
|
|
420
|
+
"""Show a dropdown selection dialog.
|
|
421
|
+
|
|
422
|
+
Args:
|
|
423
|
+
prompt: The prompt text to display.
|
|
424
|
+
title: The dialog window title.
|
|
425
|
+
value: Initial value for the input field.
|
|
426
|
+
items: List of items to choose from.
|
|
427
|
+
master: Parent widget for the dialog.
|
|
428
|
+
on_result: Optional callback receiving the dialog result payload.
|
|
429
|
+
**kwargs: Additional arguments including 'position'.
|
|
430
|
+
|
|
431
|
+
Returns:
|
|
432
|
+
Selected item or None if canceled.
|
|
433
|
+
"""
|
|
434
|
+
value = value or ""
|
|
435
|
+
position = kwargs.pop("position", None)
|
|
436
|
+
dialog = QueryDialog(
|
|
437
|
+
prompt,
|
|
438
|
+
title,
|
|
439
|
+
value,
|
|
440
|
+
items=items,
|
|
441
|
+
master=master,
|
|
442
|
+
**kwargs,
|
|
443
|
+
)
|
|
444
|
+
if on_result:
|
|
445
|
+
dialog.on_dialog_result(on_result)
|
|
446
|
+
dialog.show(position)
|
|
447
|
+
return dialog.result
|
|
448
|
+
|
|
449
|
+
@staticmethod
|
|
450
|
+
def get_integer(
|
|
451
|
+
prompt: str = "",
|
|
452
|
+
title: str = " ",
|
|
453
|
+
value: Optional[int] = None,
|
|
454
|
+
minvalue: Optional[int] = None,
|
|
455
|
+
maxvalue: Optional[int] = None,
|
|
456
|
+
master: Optional[tkinter.Misc] = None,
|
|
457
|
+
value_format: Optional[str] = None,
|
|
458
|
+
increment: Optional[int] = None,
|
|
459
|
+
on_result: Optional[Callable[[Any], None]] = None,
|
|
460
|
+
**kwargs: Any,
|
|
461
|
+
) -> Optional[int]:
|
|
462
|
+
"""Show an integer input dialog with validation.
|
|
463
|
+
|
|
464
|
+
Args:
|
|
465
|
+
prompt: The prompt text to display.
|
|
466
|
+
title: The dialog window title.
|
|
467
|
+
value: Initial value for the input field.
|
|
468
|
+
minvalue: Minimum allowed value.
|
|
469
|
+
maxvalue: Maximum allowed value.
|
|
470
|
+
increment: Step size for increment/decrement buttons.
|
|
471
|
+
value_format: Optional ICU format pattern for parsing/formatting.
|
|
472
|
+
master: Parent widget for the dialog.
|
|
473
|
+
on_result: Optional callback receiving the dialog result payload.
|
|
474
|
+
**kwargs: Additional arguments including 'position'.
|
|
475
|
+
|
|
476
|
+
Returns:
|
|
477
|
+
Integer value or None if canceled.
|
|
478
|
+
"""
|
|
479
|
+
value = value or ""
|
|
480
|
+
position = kwargs.pop("position", None)
|
|
481
|
+
dialog = QueryDialog(
|
|
482
|
+
prompt,
|
|
483
|
+
title,
|
|
484
|
+
value,
|
|
485
|
+
minvalue,
|
|
486
|
+
maxvalue,
|
|
487
|
+
datatype=int,
|
|
488
|
+
master=master,
|
|
489
|
+
value_format=value_format,
|
|
490
|
+
increment=increment,
|
|
491
|
+
**kwargs,
|
|
492
|
+
)
|
|
493
|
+
if on_result:
|
|
494
|
+
dialog.on_dialog_result(on_result)
|
|
495
|
+
dialog.show(position)
|
|
496
|
+
return dialog.result
|
|
497
|
+
|
|
498
|
+
@staticmethod
|
|
499
|
+
def get_float(
|
|
500
|
+
prompt: str = "",
|
|
501
|
+
title: str = " ",
|
|
502
|
+
value: Optional[float] = None,
|
|
503
|
+
minvalue: Optional[float] = None,
|
|
504
|
+
maxvalue: Optional[float] = None,
|
|
505
|
+
master: Optional[tkinter.Misc] = None,
|
|
506
|
+
value_format: Optional[str] = None,
|
|
507
|
+
increment: Optional[float] = None,
|
|
508
|
+
on_result: Optional[Callable[[Any], None]] = None,
|
|
509
|
+
**kwargs: Any,
|
|
510
|
+
) -> Optional[float]:
|
|
511
|
+
"""Show a float input dialog with validation.
|
|
512
|
+
|
|
513
|
+
Args:
|
|
514
|
+
prompt: The prompt text to display.
|
|
515
|
+
title: The dialog window title.
|
|
516
|
+
value: Initial value for the input field.
|
|
517
|
+
minvalue: Minimum allowed value.
|
|
518
|
+
maxvalue: Maximum allowed value.
|
|
519
|
+
master: Parent widget for the dialog.
|
|
520
|
+
value_format: Optional ICU format pattern for parsing/formatting.
|
|
521
|
+
increment: Step size for increment/decrement buttons.
|
|
522
|
+
on_result: Optional callback receiving the dialog result payload.
|
|
523
|
+
**kwargs: Additional arguments including 'position'.
|
|
524
|
+
|
|
525
|
+
Returns:
|
|
526
|
+
Float value or None if canceled.
|
|
527
|
+
"""
|
|
528
|
+
value = value or ""
|
|
529
|
+
position = kwargs.pop("position", None)
|
|
530
|
+
dialog = QueryDialog(
|
|
531
|
+
prompt,
|
|
532
|
+
title,
|
|
533
|
+
value,
|
|
534
|
+
minvalue,
|
|
535
|
+
maxvalue,
|
|
536
|
+
datatype=float,
|
|
537
|
+
master=master,
|
|
538
|
+
value_format=value_format,
|
|
539
|
+
increment=increment,
|
|
540
|
+
**kwargs,
|
|
541
|
+
)
|
|
542
|
+
if on_result:
|
|
543
|
+
dialog.on_dialog_result(on_result)
|
|
544
|
+
dialog.show(position)
|
|
545
|
+
return dialog.result
|
|
546
|
+
|
|
547
|
+
@staticmethod
|
|
548
|
+
def get_font(master: Optional[tkinter.Misc] = None, **kwargs: Any) -> Any:
|
|
549
|
+
"""Show a font selection dialog.
|
|
550
|
+
|
|
551
|
+
Args:
|
|
552
|
+
master: Parent widget for the dialog.
|
|
553
|
+
**kwargs: Additional arguments including 'position'.
|
|
554
|
+
|
|
555
|
+
Returns:
|
|
556
|
+
Selected font or None if canceled.
|
|
557
|
+
"""
|
|
558
|
+
position = kwargs.pop("position", None)
|
|
559
|
+
dialog = FontDialog(master=master, **kwargs)
|
|
560
|
+
dialog.show(position=position)
|
|
561
|
+
return dialog.result
|
bootstack/py.typed
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|