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,261 @@
|
|
|
1
|
+
"""Date entry field widget with calendar picker button.
|
|
2
|
+
|
|
3
|
+
Provides a specialized entry field for date input with locale-aware formatting
|
|
4
|
+
and an optional calendar picker button.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from datetime import date, datetime
|
|
8
|
+
from typing import TYPE_CHECKING
|
|
9
|
+
|
|
10
|
+
from typing_extensions import Unpack
|
|
11
|
+
|
|
12
|
+
from bootstack.widgets.primitives.button import Button
|
|
13
|
+
from bootstack.widgets.composites.field import Field, FieldOptions
|
|
14
|
+
from bootstack.widgets.mixins import configure_delegate
|
|
15
|
+
from bootstack.widgets.types import Master
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from bootstack.dialogs.datedialog import DateDialog
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class DateEntry(Field):
|
|
22
|
+
"""A date entry field widget with calendar picker button.
|
|
23
|
+
|
|
24
|
+
DateEntry extends the Field widget to provide specialized date input with
|
|
25
|
+
locale-aware formatting and an optional calendar picker button. The widget
|
|
26
|
+
supports various date format presets and custom ICU date format patterns,
|
|
27
|
+
and can accept input as strings, date objects, or datetime objects.
|
|
28
|
+
|
|
29
|
+
The available date format presets are: `longDate` (January 15, 2025),
|
|
30
|
+
`shortDate` (1/15/25), `monthAndDate` (January 15), `monthAndYear`
|
|
31
|
+
(January 2025), `quarterAndYear` (Q1 2025), `day` (15), `dayOfWeek`
|
|
32
|
+
(Wednesday), `month` (January), `quarter` (Q1), `year` (2025),
|
|
33
|
+
`longTime` (3:30:45 PM PST), `shortTime` (3:30 PM), `longDateLongTime`,
|
|
34
|
+
`shortDateShortTime`, or any custom ICU date format pattern (e.g., "yyyy-MM-dd").
|
|
35
|
+
|
|
36
|
+
!!! note "Events"
|
|
37
|
+
|
|
38
|
+
- `<<Change>>`: Fired when date value changes after commit.
|
|
39
|
+
- `<<Input>>`: Fired on each keystroke.
|
|
40
|
+
- `<<Valid>>`: Fired when validation passes.
|
|
41
|
+
- `<<Invalid>>`: Fired when validation fails.
|
|
42
|
+
|
|
43
|
+
The calendar picker button uses a DateDialog. The button can be hidden
|
|
44
|
+
using `show_picker_button=False`.
|
|
45
|
+
|
|
46
|
+
Attributes:
|
|
47
|
+
entry_widget (TextEntryPart): Access to the underlying TextEntryPart widget.
|
|
48
|
+
label_widget (Label): Access to the label widget.
|
|
49
|
+
message_widget (Label): Access to the message label widget.
|
|
50
|
+
addons (dict): Dictionary of inserted addon widgets.
|
|
51
|
+
variable (Variable): Tkinter Variable linked to entry text.
|
|
52
|
+
signal (Signal): Signal object for reactive updates.
|
|
53
|
+
date_picker_button (Button): The calendar picker button widget.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
def __init__(
|
|
57
|
+
self,
|
|
58
|
+
master: Master = None,
|
|
59
|
+
value: str | date | datetime = None,
|
|
60
|
+
value_format: str = "longDate",
|
|
61
|
+
label: str = None,
|
|
62
|
+
message: str = None,
|
|
63
|
+
show_picker_button=True,
|
|
64
|
+
picker_title: str = "Select new date",
|
|
65
|
+
picker_first_weekday: int = 6,
|
|
66
|
+
**kwargs: Unpack[FieldOptions]
|
|
67
|
+
):
|
|
68
|
+
"""Initialize a DateEntry widget.
|
|
69
|
+
|
|
70
|
+
Creates a date entry field with locale-aware formatting and an optional
|
|
71
|
+
calendar picker button. The widget accepts date input as strings, date
|
|
72
|
+
objects, or datetime objects, and formats them according to the specified
|
|
73
|
+
value_format pattern.
|
|
74
|
+
|
|
75
|
+
Args:
|
|
76
|
+
master: Parent widget. If None, uses the default root window.
|
|
77
|
+
value (str | date | datetime): Initial date value to display. Can be a
|
|
78
|
+
date object, datetime object, or string representation.
|
|
79
|
+
value_format (str): Date format pattern to use for parsing and displaying
|
|
80
|
+
dates. See class docstring for complete list of presets.
|
|
81
|
+
label (str): Optional label text to display above the entry field.
|
|
82
|
+
If required=True, an asterisk (*) is automatically appended.
|
|
83
|
+
message (str): Optional message text to display below the entry field.
|
|
84
|
+
Used for hints or help text. Replaced by validation errors when
|
|
85
|
+
validation fails.
|
|
86
|
+
show_picker_button (bool): If True, displays the calendar picker button
|
|
87
|
+
to the right of the entry. If False, hides the button.
|
|
88
|
+
picker_title (str): Title text for the calendar picker dialog.
|
|
89
|
+
picker_first_weekday (int): First day of the week to display in the
|
|
90
|
+
calendar picker. 0=Monday, 6=Sunday.
|
|
91
|
+
|
|
92
|
+
Other Parameters:
|
|
93
|
+
locale (str): Locale identifier for date formatting (e.g., 'en_US').
|
|
94
|
+
required (bool): If True, field cannot be empty.
|
|
95
|
+
bootstyle (str): The accent color of the focus ring and active border.
|
|
96
|
+
allow_blank (bool): Allow empty input.
|
|
97
|
+
cursor (str): Cursor style when hovering.
|
|
98
|
+
exportselection (bool): Export selection to clipboard.
|
|
99
|
+
font (str): Font for text display.
|
|
100
|
+
foreground (str): Text color.
|
|
101
|
+
initial_focus (bool): If True, widget receives focus on creation.
|
|
102
|
+
justify (str): Text alignment ('left', 'center', 'right').
|
|
103
|
+
show_message (bool): If True, displays message area.
|
|
104
|
+
padding (int | tuple): Padding around entry widget.
|
|
105
|
+
takefocus (bool): If True, widget accepts Tab focus.
|
|
106
|
+
textvariable (Variable): Tkinter Variable to link with text.
|
|
107
|
+
textsignal (Signal): Signal object for reactive updates.
|
|
108
|
+
width (int): Width in characters.
|
|
109
|
+
xscrollcommand (Callable): Callback for horizontal scrolling.
|
|
110
|
+
|
|
111
|
+
Note:
|
|
112
|
+
The widget uses the IntlFormatter for locale-aware date formatting.
|
|
113
|
+
The value is parsed and formatted automatically when the user commits
|
|
114
|
+
input (on FocusOut or Return key). Invalid date strings that cannot
|
|
115
|
+
be parsed will revert to the previous valid value.
|
|
116
|
+
"""
|
|
117
|
+
kwargs.setdefault('bootstyle', 'primary')
|
|
118
|
+
super().__init__(master=master, value=value, value_format=value_format, label=label, message=message, **kwargs)
|
|
119
|
+
|
|
120
|
+
# configuration
|
|
121
|
+
self._show_picker_button = show_picker_button
|
|
122
|
+
self._picker_title = picker_title
|
|
123
|
+
self._picker_first_weekday = picker_first_weekday
|
|
124
|
+
|
|
125
|
+
self._button_pack = {}
|
|
126
|
+
|
|
127
|
+
self.insert_addon(
|
|
128
|
+
Button,
|
|
129
|
+
position="after",
|
|
130
|
+
name="date-picker",
|
|
131
|
+
icon="calendar-week",
|
|
132
|
+
icon_only=True,
|
|
133
|
+
command=self._show_date_picker
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
self._delegate_show_picker_button(self._show_picker_button)
|
|
137
|
+
|
|
138
|
+
@property
|
|
139
|
+
def date_picker_button(self):
|
|
140
|
+
"""Get the calendar picker button widget."""
|
|
141
|
+
return self.addons.get('date-picker')
|
|
142
|
+
|
|
143
|
+
@configure_delegate('show_picker_button')
|
|
144
|
+
def _delegate_show_picker_button(self, value: bool = None):
|
|
145
|
+
"""Get or set the visibility of the calendar picker button."""
|
|
146
|
+
if value is None:
|
|
147
|
+
return self._show_picker_button
|
|
148
|
+
else:
|
|
149
|
+
if value:
|
|
150
|
+
if not self.date_picker_button.winfo_ismapped():
|
|
151
|
+
self.date_picker_button.pack(**self._button_pack)
|
|
152
|
+
else:
|
|
153
|
+
self._button_pack = self.date_picker_button.pack_info()
|
|
154
|
+
self.date_picker_button.pack_forget()
|
|
155
|
+
return None
|
|
156
|
+
|
|
157
|
+
def _show_date_picker(self):
|
|
158
|
+
"""Open the calendar picker dialog.
|
|
159
|
+
|
|
160
|
+
Opens a DateDialog seeded with the current value (if valid), updates
|
|
161
|
+
the entry when a date is picked, and leaves the field unchanged on
|
|
162
|
+
cancel.
|
|
163
|
+
"""
|
|
164
|
+
from bootstack.dialogs.datedialog import DateDialog
|
|
165
|
+
|
|
166
|
+
# Prevent multiple dialogs: reuse existing if still open
|
|
167
|
+
existing = getattr(self, "_active_date_dialog", None)
|
|
168
|
+
top = getattr(getattr(existing, "_dialog", None), "toplevel", None) if existing else None
|
|
169
|
+
try:
|
|
170
|
+
exists = bool(top and top.winfo_exists())
|
|
171
|
+
except Exception:
|
|
172
|
+
exists = False
|
|
173
|
+
|
|
174
|
+
if exists:
|
|
175
|
+
try:
|
|
176
|
+
top.lift()
|
|
177
|
+
top.focus_force()
|
|
178
|
+
except Exception:
|
|
179
|
+
pass
|
|
180
|
+
return
|
|
181
|
+
self._active_date_dialog = None
|
|
182
|
+
|
|
183
|
+
current_value = self.value
|
|
184
|
+
if isinstance(current_value, datetime):
|
|
185
|
+
current_value = current_value.date()
|
|
186
|
+
if not isinstance(current_value, date):
|
|
187
|
+
current_value = date.today()
|
|
188
|
+
|
|
189
|
+
position = self._picker_position()
|
|
190
|
+
|
|
191
|
+
dialog = DateDialog(
|
|
192
|
+
master=self.winfo_toplevel(),
|
|
193
|
+
title=self._picker_title,
|
|
194
|
+
first_weekday=self._picker_first_weekday,
|
|
195
|
+
initial_date=current_value,
|
|
196
|
+
accent=self._accent,
|
|
197
|
+
hide_window_chrome=True,
|
|
198
|
+
close_on_click_outside=False, # Disabled to avoid interference with button clicks
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
self._active_date_dialog = dialog
|
|
202
|
+
|
|
203
|
+
def _on_result(payload):
|
|
204
|
+
if isinstance(payload, dict):
|
|
205
|
+
result = payload.get('result')
|
|
206
|
+
self.value = result
|
|
207
|
+
else:
|
|
208
|
+
self.value = payload
|
|
209
|
+
|
|
210
|
+
dialog.on_result(lambda x: _on_result(x))
|
|
211
|
+
dialog.show(position=position)
|
|
212
|
+
|
|
213
|
+
top = getattr(getattr(dialog, "_dialog", None), "toplevel", None)
|
|
214
|
+
cleared = False
|
|
215
|
+
try:
|
|
216
|
+
if top and top.winfo_exists():
|
|
217
|
+
def _clear(_=None):
|
|
218
|
+
self._active_date_dialog = None
|
|
219
|
+
top.bind("<Destroy>", _clear, add="+")
|
|
220
|
+
cleared = True
|
|
221
|
+
except Exception:
|
|
222
|
+
cleared = False
|
|
223
|
+
if not cleared:
|
|
224
|
+
self._active_date_dialog = None
|
|
225
|
+
|
|
226
|
+
# Fallback: ensure value is applied after modal dialog closes.
|
|
227
|
+
selected = dialog.result
|
|
228
|
+
if isinstance(selected, datetime):
|
|
229
|
+
selected = selected.date()
|
|
230
|
+
if isinstance(selected, date):
|
|
231
|
+
self.value = selected
|
|
232
|
+
|
|
233
|
+
# Return focus to the entry after dialog closes
|
|
234
|
+
# Note: focus_force() is needed on Windows after override-redirect dialogs
|
|
235
|
+
try:
|
|
236
|
+
self._entry.focus_force()
|
|
237
|
+
except Exception:
|
|
238
|
+
pass
|
|
239
|
+
|
|
240
|
+
def _picker_position(self):
|
|
241
|
+
"""Choose a dialog position beneath the entry mirroring SelectBox spacing."""
|
|
242
|
+
try:
|
|
243
|
+
# Position relative to the inner field widget, not the whole container
|
|
244
|
+
# This ensures proper positioning even when message label is visible
|
|
245
|
+
field_widget = self._field
|
|
246
|
+
field_widget.update_idletasks()
|
|
247
|
+
x = field_widget.winfo_rootx() + 4
|
|
248
|
+
y = field_widget.winfo_rooty() + field_widget.winfo_height() + 2
|
|
249
|
+
return x, y
|
|
250
|
+
except Exception:
|
|
251
|
+
pass
|
|
252
|
+
|
|
253
|
+
try:
|
|
254
|
+
top = self.winfo_toplevel()
|
|
255
|
+
top.update_idletasks()
|
|
256
|
+
x = top.winfo_rootx() + top.winfo_width() // 2
|
|
257
|
+
y = top.winfo_rooty() + top.winfo_height() // 2
|
|
258
|
+
return x, y
|
|
259
|
+
except Exception:
|
|
260
|
+
return None
|
|
261
|
+
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any, Callable, Literal, Optional, TYPE_CHECKING, TypedDict
|
|
4
|
+
|
|
5
|
+
from typing_extensions import Unpack
|
|
6
|
+
|
|
7
|
+
from bootstack.widgets.composites.contextmenu import ContextMenu, ContextMenuItem
|
|
8
|
+
from bootstack.widgets.primitives.menubutton import MenuButton
|
|
9
|
+
from bootstack.widgets.mixins import configure_delegate
|
|
10
|
+
from bootstack.widgets.types import Master
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from bootstack.core.signals import Signal
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class DropdownButtonKwargs(TypedDict, total=False):
|
|
17
|
+
command: Optional[Callable[[], Any]]
|
|
18
|
+
image: Any
|
|
19
|
+
icon: Any
|
|
20
|
+
icon_only: bool
|
|
21
|
+
compound: Literal['text', 'image', 'top', 'bottom', 'left', 'right', 'center', 'none'] | str
|
|
22
|
+
padding: Any
|
|
23
|
+
width: int
|
|
24
|
+
underline: int
|
|
25
|
+
state: Literal['normal', 'active', 'disabled', 'readonly'] | str
|
|
26
|
+
takefocus: Any
|
|
27
|
+
style: str
|
|
28
|
+
class_: str
|
|
29
|
+
cursor: str
|
|
30
|
+
default: Any
|
|
31
|
+
name: str
|
|
32
|
+
textvariable: Any
|
|
33
|
+
textsignal: Signal[str]
|
|
34
|
+
bootstyle: str # DEPRECATED: Use accent and variant instead
|
|
35
|
+
accent: str
|
|
36
|
+
density: Literal['default', 'compact']
|
|
37
|
+
variant: str
|
|
38
|
+
surface: str
|
|
39
|
+
style_options: dict[str, Any]
|
|
40
|
+
popdown_options: dict[str, Any]
|
|
41
|
+
show_dropdown_button: bool
|
|
42
|
+
dropdown_button_icon: str | dict
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class DropdownButton(MenuButton):
|
|
46
|
+
|
|
47
|
+
def __init__(
|
|
48
|
+
self,
|
|
49
|
+
master: Master = None,
|
|
50
|
+
text: Any = None,
|
|
51
|
+
items: list[ContextMenuItem] = None,
|
|
52
|
+
**kwargs: Unpack[DropdownButtonKwargs],
|
|
53
|
+
):
|
|
54
|
+
"""Create a dropdown button backed by a ContextMenu.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
master: Parent widget. If None, uses the default root window.
|
|
58
|
+
text (str): Label text for the button.
|
|
59
|
+
items (list): Initial list of ContextMenuItem entries.
|
|
60
|
+
|
|
61
|
+
Other Parameters:
|
|
62
|
+
command (Callable): Callback when the button is activated.
|
|
63
|
+
image (PhotoImage): Tk image to display.
|
|
64
|
+
icon (str | dict): Bootstyle icon spec for the button content.
|
|
65
|
+
icon_only (bool): Whether to reserve label padding when showing only an icon.
|
|
66
|
+
compound (str): Placement of image relative to text.
|
|
67
|
+
padding (int | tuple): Extra padding around the button content.
|
|
68
|
+
density (str): The vertical and horizontal compactness of widget content, e.g. 'default', 'compact'.
|
|
69
|
+
width (int): Width of the button.
|
|
70
|
+
underline (int): Index of underlined character in text.
|
|
71
|
+
state (str): Widget state ('normal', 'active', 'disabled', 'readonly').
|
|
72
|
+
takefocus (bool): Participation in focus traversal.
|
|
73
|
+
style (str): Explicit ttk style name.
|
|
74
|
+
textvariable (Variable): Existing Tk variable for the label text.
|
|
75
|
+
textsignal (Signal[str]): Signal bound to the textvariable.
|
|
76
|
+
accent (str): Accent token for styling (e.g., 'primary', 'danger').
|
|
77
|
+
variant (str): Style variant (e.g., 'outline', 'ghost').
|
|
78
|
+
bootstyle (str): DEPRECATED - Use `accent` and `variant` instead.
|
|
79
|
+
surface (str): Surface token for style.
|
|
80
|
+
style_options (dict): Dict forwarded to the menubutton style builder.
|
|
81
|
+
popdown_options (dict): Dict forwarded to ContextMenu (e.g., anchor, attach, offset).
|
|
82
|
+
show_dropdown_button (bool): Show/hide the chevron.
|
|
83
|
+
dropdown_button_icon (str | dict): Icon name for the chevron.
|
|
84
|
+
"""
|
|
85
|
+
style_options = kwargs.pop('style_options', {})
|
|
86
|
+
style_options.update(
|
|
87
|
+
self._capture_style_options(
|
|
88
|
+
options=['icon', 'icon_only', 'density', 'show_dropdown_button', 'dropdown_button_icon'],
|
|
89
|
+
source=kwargs
|
|
90
|
+
)
|
|
91
|
+
)
|
|
92
|
+
kwargs['style_options'] = style_options
|
|
93
|
+
self._item_click_callback = None
|
|
94
|
+
self._items = items if items else []
|
|
95
|
+
self._popdown_options = kwargs.pop('popdown_options', {})
|
|
96
|
+
|
|
97
|
+
# Store the textvariable if provided, or create a new one
|
|
98
|
+
super().__init__(master, text=text, **kwargs)
|
|
99
|
+
|
|
100
|
+
# Create menu items that update the shared variable
|
|
101
|
+
self._context_menu = self._build_context_menu()
|
|
102
|
+
|
|
103
|
+
# Bind menu display to button events
|
|
104
|
+
self.bind('<Button-1>', lambda _: self.show_menu(), add="+")
|
|
105
|
+
self.bind('<Return>', lambda _: self.show_menu(), add="+")
|
|
106
|
+
self.bind('<KP_Enter>', lambda _: self.show_menu(), add="+")
|
|
107
|
+
|
|
108
|
+
# passthrough methods
|
|
109
|
+
self.on_item_click = self._context_menu.on_item_click
|
|
110
|
+
self.add_radiobutton = self._context_menu.add_radiobutton
|
|
111
|
+
self.add_command = self._context_menu.add_command
|
|
112
|
+
self.add_checkbutton = self._context_menu.add_checkbutton
|
|
113
|
+
self.add_separator = self._context_menu.add_separator
|
|
114
|
+
self.add_item = self._context_menu.add_item
|
|
115
|
+
self.add_items = self._context_menu.add_items
|
|
116
|
+
self.insert_item = self._context_menu.insert_item
|
|
117
|
+
self.remove_item = self._context_menu.remove_item
|
|
118
|
+
self.move_item = self._context_menu.move_item
|
|
119
|
+
self.configure_item = self._context_menu.configure_item
|
|
120
|
+
self.items = self._context_menu.items
|
|
121
|
+
|
|
122
|
+
def on_item_click(self, callback: Callable) -> None:
|
|
123
|
+
"""Set item click callback. Callback receives `item_info = {'type': str, 'text': str, 'value': Any}`."""
|
|
124
|
+
self._item_click_callback = callback
|
|
125
|
+
self._context_menu.on_item_click(callback)
|
|
126
|
+
|
|
127
|
+
def off_item_click(self) -> None:
|
|
128
|
+
"""Remove the item click callback."""
|
|
129
|
+
self._item_click_callback = None
|
|
130
|
+
self._context_menu.on_item_click(None)
|
|
131
|
+
|
|
132
|
+
def _build_context_menu(self):
|
|
133
|
+
"""Construct the ContextMenu with current items and options."""
|
|
134
|
+
# Offset compensates for the focus-ring affordance baked into the
|
|
135
|
+
# button image so the dropdown's left edge aligns with the visible
|
|
136
|
+
# button border. Same treatment as OptionMenu.
|
|
137
|
+
from bootstack.style.bootstyle_builder_base import BootstyleBuilderBase
|
|
138
|
+
offset_x = BootstyleBuilderBase.scale_from_source(10)
|
|
139
|
+
density = self.configure_style_options('density') or 'default'
|
|
140
|
+
options = {
|
|
141
|
+
"anchor": "nw",
|
|
142
|
+
"attach": "sw",
|
|
143
|
+
"offset": (offset_x, 0),
|
|
144
|
+
"density": density,
|
|
145
|
+
}
|
|
146
|
+
options.update(self._popdown_options)
|
|
147
|
+
# DropdownButton manages its own activation (left-click, Return/
|
|
148
|
+
# KP_Enter via show_menu), so opt out of ContextMenu's auto-trigger.
|
|
149
|
+
cm = ContextMenu(self, target=self, items=self._items, trigger=None, **options)
|
|
150
|
+
if self._item_click_callback:
|
|
151
|
+
self.on_item_click(self._item_click_callback)
|
|
152
|
+
return cm
|
|
153
|
+
|
|
154
|
+
@property
|
|
155
|
+
def context_menu(self):
|
|
156
|
+
"""Returns the context menu widget"""
|
|
157
|
+
return self._context_menu
|
|
158
|
+
|
|
159
|
+
def show_menu(self):
|
|
160
|
+
"""Show the dropdown menu unless disabled or readonly."""
|
|
161
|
+
if not self.instate(("!disabled", "!readonly")):
|
|
162
|
+
return
|
|
163
|
+
self._context_menu.show()
|
|
164
|
+
|
|
165
|
+
@configure_delegate('popdown_options')
|
|
166
|
+
def _delegate_popdown_options(self, value=None):
|
|
167
|
+
if value is None:
|
|
168
|
+
return self._popdown_options
|
|
169
|
+
else:
|
|
170
|
+
self._popdown_options = value
|
|
171
|
+
return self.context_menu.configure(**value)
|
|
172
|
+
|
|
173
|
+
@configure_delegate('show_dropdown_button')
|
|
174
|
+
def _delegate_show_dropdown_button(self, value=None):
|
|
175
|
+
"""Get or set visibility of the dropdown chevron."""
|
|
176
|
+
if value is None:
|
|
177
|
+
return self.configure_style_options('show_dropdown_button')
|
|
178
|
+
else:
|
|
179
|
+
self.configure_style_options(show_dropdown_button=value)
|
|
180
|
+
return self.rebuild_style()
|
|
181
|
+
|
|
182
|
+
@configure_delegate('dropdown_button_icon')
|
|
183
|
+
def _delegate_dropdown_button_icon(self, value=None):
|
|
184
|
+
"""Get or set the dropdown chevron icon name."""
|
|
185
|
+
if value is None:
|
|
186
|
+
return self.configure_style_options('dropdown_button_icon')
|
|
187
|
+
else:
|
|
188
|
+
self.configure_style_options(dropdown_button_icon=value)
|
|
189
|
+
return self.rebuild_style()
|
|
190
|
+
|