bootstack 0.1.0__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 +157 -0
- bootstack/__main__.py +5 -0
- bootstack/_core/__init__.py +21 -0
- bootstack/_core/capabilities/__init__.py +45 -0
- bootstack/_core/capabilities/after.py +103 -0
- bootstack/_core/capabilities/bind.py +192 -0
- bootstack/_core/capabilities/bindtags.py +112 -0
- bootstack/_core/capabilities/busy.py +72 -0
- bootstack/_core/capabilities/clipboard.py +89 -0
- bootstack/_core/capabilities/focus.py +118 -0
- bootstack/_core/capabilities/grab.py +65 -0
- bootstack/_core/capabilities/grid.py +211 -0
- bootstack/_core/capabilities/localization.py +231 -0
- bootstack/_core/capabilities/pack.py +140 -0
- bootstack/_core/capabilities/place.py +113 -0
- bootstack/_core/capabilities/selection.py +136 -0
- bootstack/_core/capabilities/signals.py +244 -0
- bootstack/_core/capabilities/winfo.py +315 -0
- bootstack/_core/colorutils.py +234 -0
- bootstack/_core/exceptions.py +25 -0
- bootstack/_core/images.py +463 -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/paths.py +49 -0
- bootstack/_core/publisher.py +149 -0
- bootstack/_core/variables.py +62 -0
- bootstack/_runtime/__init__.py +3 -0
- bootstack/_runtime/app.py +930 -0
- bootstack/_runtime/base_window.py +945 -0
- bootstack/_runtime/events.py +399 -0
- bootstack/_runtime/shortcuts.py +496 -0
- bootstack/_runtime/tk_patch.py +43 -0
- bootstack/_runtime/toplevel.py +276 -0
- bootstack/_runtime/utility.py +457 -0
- bootstack/_runtime/visual_focus.py +240 -0
- bootstack/_runtime/window_utilities.py +1123 -0
- bootstack/assets/__init__.py +21 -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/button-compact.png +0 -0
- bootstack/assets/elements/button-default.png +0 -0
- bootstack/assets/elements/buttongroup-after-h-compact.png +0 -0
- bootstack/assets/elements/buttongroup-after-h-default.png +0 -0
- bootstack/assets/elements/buttongroup-after-v-compact.png +0 -0
- bootstack/assets/elements/buttongroup-after-v-default.png +0 -0
- bootstack/assets/elements/buttongroup-before-h-compact.png +0 -0
- bootstack/assets/elements/buttongroup-before-h-default.png +0 -0
- bootstack/assets/elements/buttongroup-before-v-compact.png +0 -0
- bootstack/assets/elements/buttongroup-before-v-default.png +0 -0
- bootstack/assets/elements/buttongroup-center-h-compact.png +0 -0
- bootstack/assets/elements/buttongroup-center-h-default.png +0 -0
- bootstack/assets/elements/buttongroup-center-v-compact.png +0 -0
- bootstack/assets/elements/buttongroup-center-v-default.png +0 -0
- bootstack/assets/elements/card.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-addon-compact.png +0 -0
- bootstack/assets/elements/input-addon-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/listrow-compact.png +0 -0
- bootstack/assets/elements/listrow-default.png +0 -0
- bootstack/assets/elements/manifest.toml +361 -0
- bootstack/assets/elements/menu-item.png +0 -0
- bootstack/assets/elements/navitem-compact.png +0 -0
- bootstack/assets/elements/navitem-default.png +0 -0
- bootstack/assets/elements/progressbar-h-compact.png +0 -0
- bootstack/assets/elements/progressbar-h-default.png +0 -0
- bootstack/assets/elements/progressbar-v-compact.png +0 -0
- bootstack/assets/elements/progressbar-v-default.png +0 -0
- bootstack/assets/elements/radiobutton.png +0 -0
- bootstack/assets/elements/scrollbar-horizontal.png +0 -0
- bootstack/assets/elements/scrollbar-vertical.png +0 -0
- bootstack/assets/elements/slider-handle.png +0 -0
- bootstack/assets/elements/slider-track-h.png +0 -0
- bootstack/assets/elements/slider-track-v.png +0 -0
- bootstack/assets/elements/switch-off.png +0 -0
- bootstack/assets/elements/switch-on.png +0 -0
- bootstack/assets/elements/tab-h.png +0 -0
- bootstack/assets/elements/tab-v.png +0 -0
- bootstack/assets/icons/bootstrap.ttf +0 -0
- bootstack/assets/icons/glyphmap.json +2080 -0
- bootstack/assets/icons/icon_metrics.json +12470 -0
- bootstack/assets/locales/ar/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/ar/LC_MESSAGES/bootstack.po +856 -0
- bootstack/assets/locales/bg/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/bg/LC_MESSAGES/bootstack.po +878 -0
- bootstack/assets/locales/cs/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/cs/LC_MESSAGES/bootstack.po +856 -0
- bootstack/assets/locales/da/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/da/LC_MESSAGES/bootstack.po +856 -0
- bootstack/assets/locales/de/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/de/LC_MESSAGES/bootstack.po +856 -0
- bootstack/assets/locales/en/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/en/LC_MESSAGES/bootstack.po +878 -0
- bootstack/assets/locales/es/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/es/LC_MESSAGES/bootstack.po +856 -0
- bootstack/assets/locales/fr/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/fr/LC_MESSAGES/bootstack.po +856 -0
- bootstack/assets/locales/he/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/he/LC_MESSAGES/bootstack.po +854 -0
- bootstack/assets/locales/hi/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/hi/LC_MESSAGES/bootstack.po +845 -0
- bootstack/assets/locales/it/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/it/LC_MESSAGES/bootstack.po +844 -0
- bootstack/assets/locales/ja/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/ja/LC_MESSAGES/bootstack.po +917 -0
- bootstack/assets/locales/ko/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/ko/LC_MESSAGES/bootstack.po +845 -0
- bootstack/assets/locales/nb/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/nb/LC_MESSAGES/bootstack.po +844 -0
- bootstack/assets/locales/nl/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/nl/LC_MESSAGES/bootstack.po +844 -0
- bootstack/assets/locales/pl/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/pl/LC_MESSAGES/bootstack.po +845 -0
- bootstack/assets/locales/pt/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/pt/LC_MESSAGES/bootstack.po +845 -0
- bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.po +845 -0
- bootstack/assets/locales/sl/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/sl/LC_MESSAGES/bootstack.po +845 -0
- bootstack/assets/locales/sv/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/sv/LC_MESSAGES/bootstack.po +845 -0
- bootstack/assets/locales/tr/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/tr/LC_MESSAGES/bootstack.po +845 -0
- bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.po +845 -0
- bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.mo +0 -0
- bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.po +845 -0
- bootstack/cli/__init__.py +133 -0
- bootstack/cli/__main__.py +6 -0
- bootstack/cli/add.py +395 -0
- bootstack/cli/appicon.py +285 -0
- bootstack/cli/build.py +115 -0
- bootstack/cli/config.py +313 -0
- bootstack/cli/demo.py +564 -0
- bootstack/cli/dev.py +153 -0
- bootstack/cli/doctor.py +195 -0
- bootstack/cli/icons.py +98 -0
- bootstack/cli/promote.py +120 -0
- bootstack/cli/pyinstaller.py +268 -0
- bootstack/cli/run.py +95 -0
- bootstack/cli/start.py +117 -0
- bootstack/cli/templates/__init__.py +931 -0
- bootstack/clipboard.py +48 -0
- bootstack/constants.py +318 -0
- bootstack/data/README.md +615 -0
- bootstack/data/__init__.py +78 -0
- bootstack/data/_observable.py +276 -0
- bootstack/data/base.py +780 -0
- bootstack/data/file_source.py +367 -0
- bootstack/data/memory_source.py +450 -0
- bootstack/data/query.py +367 -0
- bootstack/data/readers.py +289 -0
- bootstack/data/sqlite_source.py +869 -0
- bootstack/data/types.py +354 -0
- bootstack/data/writers.py +232 -0
- bootstack/dev/__init__.py +36 -0
- bootstack/dev/_capture.py +141 -0
- bootstack/dev/_env.py +43 -0
- bootstack/dev/_registry.py +140 -0
- bootstack/dev/_reloader.py +351 -0
- bootstack/dev/_reset.py +50 -0
- bootstack/dev/_watcher.py +91 -0
- bootstack/dialogs/__init__.py +948 -0
- bootstack/dialogs/_impl/__init__.py +47 -0
- bootstack/dialogs/_impl/colorchooser.py +588 -0
- bootstack/dialogs/_impl/datedialog.py +450 -0
- bootstack/dialogs/_impl/dialog.py +594 -0
- bootstack/dialogs/_impl/filterdialog.py +358 -0
- bootstack/dialogs/_impl/fontdialog.py +364 -0
- bootstack/dialogs/_impl/formdialog.py +564 -0
- bootstack/dialogs/_impl/message.py +486 -0
- bootstack/dialogs/_impl/query.py +570 -0
- bootstack/errors.py +67 -0
- bootstack/events/__init__.py +111 -0
- bootstack/events/_event.py +135 -0
- bootstack/events/_payloads.py +539 -0
- bootstack/events/_subscription.py +38 -0
- bootstack/i18n/README.md +77 -0
- bootstack/i18n/__init__.py +23 -0
- bootstack/i18n/catalog.py +121 -0
- bootstack/i18n/intl_format.py +584 -0
- bootstack/i18n/msgcat.py +425 -0
- bootstack/i18n/specs.py +156 -0
- bootstack/images.py +563 -0
- bootstack/py.typed +1 -0
- bootstack/scheduling/__init__.py +11 -0
- bootstack/scheduling/_schedule.py +218 -0
- bootstack/shortcuts.py +21 -0
- bootstack/signals/README.md +98 -0
- bootstack/signals/__init__.py +10 -0
- bootstack/signals/integration.py +100 -0
- bootstack/signals/signal.py +353 -0
- bootstack/signals/types.py +6 -0
- bootstack/store.py +286 -0
- bootstack/streams/__init__.py +12 -0
- bootstack/streams/_stream.py +321 -0
- bootstack/style/__init__.py +38 -0
- bootstack/style/builders/__init__.py +51 -0
- bootstack/style/builders/badge.py +46 -0
- bootstack/style/builders/button.py +339 -0
- bootstack/style/builders/buttongroup.py +311 -0
- bootstack/style/builders/calendar.py +271 -0
- bootstack/style/builders/checkbutton.py +110 -0
- bootstack/style/builders/combobox.py +113 -0
- bootstack/style/builders/contextmenu.py +268 -0
- bootstack/style/builders/entry.py +82 -0
- bootstack/style/builders/expander.py +148 -0
- bootstack/style/builders/field.py +335 -0
- bootstack/style/builders/frame.py +50 -0
- bootstack/style/builders/label.py +28 -0
- bootstack/style/builders/labelframe.py +34 -0
- bootstack/style/builders/listview.py +369 -0
- bootstack/style/builders/menubar.py +91 -0
- bootstack/style/builders/menubutton.py +359 -0
- bootstack/style/builders/panedwindow.py +25 -0
- bootstack/style/builders/progressbar.py +67 -0
- bootstack/style/builders/radiobutton.py +99 -0
- bootstack/style/builders/scale.py +64 -0
- bootstack/style/builders/scrollbar.py +225 -0
- bootstack/style/builders/separator.py +49 -0
- bootstack/style/builders/sidenav.py +643 -0
- bootstack/style/builders/sizegrip.py +15 -0
- bootstack/style/builders/spinbox.py +119 -0
- bootstack/style/builders/switch.py +70 -0
- bootstack/style/builders/tabitem.py +204 -0
- bootstack/style/builders/togglegroup.py +294 -0
- bootstack/style/builders/toolbutton.py +275 -0
- bootstack/style/builders/tooltip.py +26 -0
- bootstack/style/builders/treeview.py +193 -0
- bootstack/style/builders/utils.py +455 -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/fonts.py +123 -0
- bootstack/style/style.py +609 -0
- bootstack/style/style_builder_base.py +716 -0
- bootstack/style/style_builder_mixed.py +93 -0
- bootstack/style/style_builder_tk.py +109 -0
- bootstack/style/style_builder_ttk.py +353 -0
- bootstack/style/style_resolver.py +447 -0
- bootstack/style/theme.py +245 -0
- bootstack/style/theme_provider.py +471 -0
- bootstack/style/themes/__init__.py +128 -0
- bootstack/style/tk_patch.py +5 -0
- bootstack/style/token_maps.py +41 -0
- bootstack/style/types.py +32 -0
- bootstack/style/typography.py +523 -0
- bootstack/style/utility.py +746 -0
- bootstack/types.py +39 -0
- bootstack/validation/__init__.py +6 -0
- bootstack/validation/types.py +15 -0
- bootstack/validation/validation_result.py +17 -0
- bootstack/validation/validation_rules.py +205 -0
- bootstack/widgets/__init__.py +74 -0
- bootstack/widgets/_core/__init__.py +31 -0
- bootstack/widgets/_core/app_config.py +266 -0
- bootstack/widgets/_core/base.py +461 -0
- bootstack/widgets/_core/container.py +334 -0
- bootstack/widgets/_core/context.py +35 -0
- bootstack/widgets/_core/events.py +130 -0
- bootstack/widgets/_core/field_mixin.py +353 -0
- bootstack/widgets/_core/icon_image_props.py +72 -0
- bootstack/widgets/_core/image_binding.py +93 -0
- bootstack/widgets/_core/navmodel.py +345 -0
- bootstack/widgets/_core/options.py +210 -0
- bootstack/widgets/_core/selection_group.py +130 -0
- bootstack/widgets/_core/window_controls.py +96 -0
- bootstack/widgets/_core/window_menu.py +246 -0
- bootstack/widgets/_impl/__init__.py +1 -0
- bootstack/widgets/_impl/_internal/__init__.py +0 -0
- bootstack/widgets/_impl/_internal/wrapper_base.py +307 -0
- bootstack/widgets/_impl/_parts/__init__.py +11 -0
- bootstack/widgets/_impl/_parts/numberentry_part.py +385 -0
- bootstack/widgets/_impl/_parts/spinnerentry_part.py +434 -0
- bootstack/widgets/_impl/_parts/textentry_part.py +406 -0
- bootstack/widgets/_impl/composites/__init__.py +33 -0
- bootstack/widgets/_impl/composites/_dateutils.py +33 -0
- bootstack/widgets/_impl/composites/_image_fit.py +105 -0
- bootstack/widgets/_impl/composites/accordion.py +381 -0
- bootstack/widgets/_impl/composites/avatar.py +191 -0
- bootstack/widgets/_impl/composites/buttongroup.py +371 -0
- bootstack/widgets/_impl/composites/calendar.py +972 -0
- bootstack/widgets/_impl/composites/carousel.py +567 -0
- bootstack/widgets/_impl/composites/chart.py +882 -0
- bootstack/widgets/_impl/composites/compositeframe.py +298 -0
- bootstack/widgets/_impl/composites/contextmenu.py +1951 -0
- bootstack/widgets/_impl/composites/dateentry.py +404 -0
- bootstack/widgets/_impl/composites/dropdownbutton.py +325 -0
- bootstack/widgets/_impl/composites/expander.py +515 -0
- bootstack/widgets/_impl/composites/field.py +670 -0
- bootstack/widgets/_impl/composites/form.py +1066 -0
- bootstack/widgets/_impl/composites/gallery.py +551 -0
- bootstack/widgets/_impl/composites/list/__init__.py +15 -0
- bootstack/widgets/_impl/composites/list/listitem.py +802 -0
- bootstack/widgets/_impl/composites/list/listview.py +1433 -0
- bootstack/widgets/_impl/composites/menu/__init__.py +18 -0
- bootstack/widgets/_impl/composites/menu/model.py +358 -0
- bootstack/widgets/_impl/composites/menu/render_native.py +134 -0
- bootstack/widgets/_impl/composites/menu/render_themed.py +134 -0
- bootstack/widgets/_impl/composites/meter.py +860 -0
- bootstack/widgets/_impl/composites/numericentry.py +201 -0
- bootstack/widgets/_impl/composites/pagestack.py +395 -0
- bootstack/widgets/_impl/composites/passwordentry.py +142 -0
- bootstack/widgets/_impl/composites/pathentry.py +168 -0
- bootstack/widgets/_impl/composites/picture.py +289 -0
- bootstack/widgets/_impl/composites/radiogroup.py +511 -0
- bootstack/widgets/_impl/composites/scrolledtext.py +375 -0
- bootstack/widgets/_impl/composites/scrolledtext.pyi +186 -0
- bootstack/widgets/_impl/composites/scrollview.py +764 -0
- bootstack/widgets/_impl/composites/selectbox.py +1026 -0
- bootstack/widgets/_impl/composites/shell/__init__.py +40 -0
- bootstack/widgets/_impl/composites/shell/content_host.py +52 -0
- bootstack/widgets/_impl/composites/shell/layout.py +335 -0
- bootstack/widgets/_impl/composites/shell/nav_panel.py +345 -0
- bootstack/widgets/_impl/composites/shell/providers.py +558 -0
- bootstack/widgets/_impl/composites/shell/rail.py +117 -0
- bootstack/widgets/_impl/composites/shell/shell.py +581 -0
- bootstack/widgets/_impl/composites/shell/workspace.py +273 -0
- bootstack/widgets/_impl/composites/sidenav/__init__.py +16 -0
- bootstack/widgets/_impl/composites/sidenav/header.py +81 -0
- bootstack/widgets/_impl/composites/sidenav/separator.py +44 -0
- bootstack/widgets/_impl/composites/slider/__init__.py +7 -0
- bootstack/widgets/_impl/composites/slider/_shared.py +195 -0
- bootstack/widgets/_impl/composites/slider/rangeslider.py +982 -0
- bootstack/widgets/_impl/composites/slider/slider.py +851 -0
- bootstack/widgets/_impl/composites/spinnerentry.py +185 -0
- bootstack/widgets/_impl/composites/tableview/__init__.py +5 -0
- bootstack/widgets/_impl/composites/tableview/tableview.py +3388 -0
- bootstack/widgets/_impl/composites/tableview/types.py +169 -0
- bootstack/widgets/_impl/composites/tabs/__init__.py +23 -0
- bootstack/widgets/_impl/composites/tabs/tabitem.py +389 -0
- bootstack/widgets/_impl/composites/tabs/tabs.py +974 -0
- bootstack/widgets/_impl/composites/tabs/tabview.py +650 -0
- bootstack/widgets/_impl/composites/textarea/__init__.py +26 -0
- bootstack/widgets/_impl/composites/textarea/change.py +46 -0
- bootstack/widgets/_impl/composites/textarea/codeeditor.py +526 -0
- bootstack/widgets/_impl/composites/textarea/core.py +495 -0
- bootstack/widgets/_impl/composites/textarea/decoration.py +42 -0
- bootstack/widgets/_impl/composites/textarea/diff.py +127 -0
- bootstack/widgets/_impl/composites/textarea/extensions/__init__.py +1 -0
- bootstack/widgets/_impl/composites/textarea/extensions/bracket_matcher.py +138 -0
- bootstack/widgets/_impl/composites/textarea/extensions/indent_guides.py +158 -0
- bootstack/widgets/_impl/composites/textarea/extensions/line_numbers.py +138 -0
- bootstack/widgets/_impl/composites/textarea/extensions/pygments_highlighter.py +312 -0
- bootstack/widgets/_impl/composites/textarea/extensions/smart_indent.py +177 -0
- bootstack/widgets/_impl/composites/textarea/filter.py +171 -0
- bootstack/widgets/_impl/composites/textarea/search_overlay.py +459 -0
- bootstack/widgets/_impl/composites/textarea/sidebar.py +88 -0
- bootstack/widgets/_impl/composites/textarea/style_registry.py +178 -0
- bootstack/widgets/_impl/composites/textarea/textarea.py +606 -0
- bootstack/widgets/_impl/composites/textarea/undo.py +217 -0
- bootstack/widgets/_impl/composites/textentry.py +57 -0
- bootstack/widgets/_impl/composites/timeentry.py +176 -0
- bootstack/widgets/_impl/composites/toast.py +390 -0
- bootstack/widgets/_impl/composites/toast_stack.py +156 -0
- bootstack/widgets/_impl/composites/togglegroup.py +418 -0
- bootstack/widgets/_impl/composites/toolbar.py +608 -0
- bootstack/widgets/_impl/composites/tooltip.py +491 -0
- bootstack/widgets/_impl/composites/tree/__init__.py +7 -0
- bootstack/widgets/_impl/composites/tree/source_binding.py +136 -0
- bootstack/widgets/_impl/composites/tree/treeitem.py +393 -0
- bootstack/widgets/_impl/composites/tree/treenode.py +174 -0
- bootstack/widgets/_impl/composites/tree/treeview.py +841 -0
- bootstack/widgets/_impl/mixins/__init__.py +24 -0
- bootstack/widgets/_impl/mixins/configure_mixin.py +216 -0
- bootstack/widgets/_impl/mixins/entry_mixin.py +134 -0
- bootstack/widgets/_impl/mixins/font_mixin.py +368 -0
- bootstack/widgets/_impl/mixins/icon_mixin.py +61 -0
- bootstack/widgets/_impl/mixins/localization_mixin.py +253 -0
- bootstack/widgets/_impl/mixins/signal_mixin.py +268 -0
- bootstack/widgets/_impl/mixins/validation_mixin.py +226 -0
- bootstack/widgets/_impl/primitives/__init__.py +49 -0
- bootstack/widgets/_impl/primitives/_menubutton.py +107 -0
- bootstack/widgets/_impl/primitives/badge.py +45 -0
- bootstack/widgets/_impl/primitives/button.py +76 -0
- bootstack/widgets/_impl/primitives/card.py +45 -0
- bootstack/widgets/_impl/primitives/checkbutton.py +124 -0
- bootstack/widgets/_impl/primitives/checktoggle.py +62 -0
- bootstack/widgets/_impl/primitives/combobox.py +156 -0
- bootstack/widgets/_impl/primitives/entry.py +87 -0
- bootstack/widgets/_impl/primitives/flexframe.py +448 -0
- bootstack/widgets/_impl/primitives/frame.py +185 -0
- bootstack/widgets/_impl/primitives/gridframe.py +546 -0
- bootstack/widgets/_impl/primitives/label.py +84 -0
- bootstack/widgets/_impl/primitives/labelframe.py +54 -0
- bootstack/widgets/_impl/primitives/optionmenu.py +387 -0
- bootstack/widgets/_impl/primitives/packframe.py +227 -0
- bootstack/widgets/_impl/primitives/panedwindow.py +45 -0
- bootstack/widgets/_impl/primitives/progressbar.py +83 -0
- bootstack/widgets/_impl/primitives/radiobutton.py +115 -0
- bootstack/widgets/_impl/primitives/radiotoggle.py +54 -0
- bootstack/widgets/_impl/primitives/scrollbar.py +42 -0
- bootstack/widgets/_impl/primitives/separator.py +43 -0
- bootstack/widgets/_impl/primitives/sizegrip.py +33 -0
- bootstack/widgets/_impl/primitives/spinbox.py +95 -0
- bootstack/widgets/_impl/primitives/switch.py +44 -0
- bootstack/widgets/_impl/primitives/treeview.py +69 -0
- bootstack/widgets/app.py +371 -0
- bootstack/widgets/appshell.py +1179 -0
- bootstack/widgets/avatar.py +140 -0
- bootstack/widgets/boolean_controls.py +455 -0
- bootstack/widgets/button.py +224 -0
- bootstack/widgets/buttongroup.py +239 -0
- bootstack/widgets/calendar.py +195 -0
- bootstack/widgets/card.py +159 -0
- bootstack/widgets/carousel.py +241 -0
- bootstack/widgets/chart.py +302 -0
- bootstack/widgets/codeeditor.py +675 -0
- bootstack/widgets/contextmenu.py +371 -0
- bootstack/widgets/datatable.py +688 -0
- bootstack/widgets/datefield.py +395 -0
- bootstack/widgets/divider.py +60 -0
- bootstack/widgets/expander.py +579 -0
- bootstack/widgets/form.py +200 -0
- bootstack/widgets/gallery.py +250 -0
- bootstack/widgets/gauge.py +168 -0
- bootstack/widgets/grid.py +121 -0
- bootstack/widgets/groupbox.py +162 -0
- bootstack/widgets/label.py +229 -0
- bootstack/widgets/listview.py +354 -0
- bootstack/widgets/menubutton.py +419 -0
- bootstack/widgets/numberfield.py +431 -0
- bootstack/widgets/pagestack.py +345 -0
- bootstack/widgets/passwordfield.py +383 -0
- bootstack/widgets/pathfield.py +454 -0
- bootstack/widgets/picture.py +251 -0
- bootstack/widgets/progressbar.py +106 -0
- bootstack/widgets/radio_variants.py +271 -0
- bootstack/widgets/radiogroup.py +228 -0
- bootstack/widgets/scrollbar.py +64 -0
- bootstack/widgets/scrollview.py +186 -0
- bootstack/widgets/select.py +302 -0
- bootstack/widgets/selectbutton.py +182 -0
- bootstack/widgets/sidebar_toggle.py +130 -0
- bootstack/widgets/sizegrip.py +42 -0
- bootstack/widgets/slider.py +408 -0
- bootstack/widgets/spinbox.py +147 -0
- bootstack/widgets/spinnerfield.py +413 -0
- bootstack/widgets/splash.py +367 -0
- bootstack/widgets/splitview.py +482 -0
- bootstack/widgets/stacks.py +249 -0
- bootstack/widgets/statusbar.py +189 -0
- bootstack/widgets/tabs.py +425 -0
- bootstack/widgets/textarea.py +459 -0
- bootstack/widgets/textfield.py +410 -0
- bootstack/widgets/theme_toggle.py +92 -0
- bootstack/widgets/timefield.py +340 -0
- bootstack/widgets/toast.py +314 -0
- bootstack/widgets/togglegroup.py +231 -0
- bootstack/widgets/toolbar.py +347 -0
- bootstack/widgets/tooltip.py +94 -0
- bootstack/widgets/tree.py +648 -0
- bootstack/widgets/types.py +305 -0
- bootstack/widgets/window.py +307 -0
- bootstack-0.1.0.dist-info/METADATA +301 -0
- bootstack-0.1.0.dist-info/RECORD +471 -0
- bootstack-0.1.0.dist-info/WHEEL +5 -0
- bootstack-0.1.0.dist-info/entry_points.txt +2 -0
- bootstack-0.1.0.dist-info/licenses/LICENSE +21 -0
- bootstack-0.1.0.dist-info/licenses/NOTICE +10 -0
- bootstack-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
"""Numeric entry widget with manual stepping and validation.
|
|
2
|
+
|
|
3
|
+
This module provides a number entry widget that extends TextEntryPart with
|
|
4
|
+
numeric-specific features like min/max bounds, stepping, and keyboard/mouse
|
|
5
|
+
wheel support.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
from bootstack.events import ChangeEvent
|
|
10
|
+
from bootstack.widgets._impl.mixins.configure_mixin import configure_delegate
|
|
11
|
+
from bootstack.widgets._impl._parts.textentry_part import TextEntryPart
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class NumberEntryPart(TextEntryPart):
|
|
15
|
+
"""Numeric entry widget with stepping and bounds validation.
|
|
16
|
+
|
|
17
|
+
Extends TextEntryPart to provide numeric input with constraints and
|
|
18
|
+
stepping functionality. Supports min/max bounds, increment/decrement
|
|
19
|
+
via keyboard and mouse wheel, and optional wrapping.
|
|
20
|
+
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(
|
|
24
|
+
self,
|
|
25
|
+
master=None,
|
|
26
|
+
*,
|
|
27
|
+
value: int | float | str = 0,
|
|
28
|
+
value_format: str = None,
|
|
29
|
+
minvalue: int | float | None = None,
|
|
30
|
+
maxvalue: int | float | None = None,
|
|
31
|
+
increment: int | float = 1,
|
|
32
|
+
wrap: bool = False,
|
|
33
|
+
initial_focus: bool = False,
|
|
34
|
+
allow_blank: bool = True,
|
|
35
|
+
**kwargs
|
|
36
|
+
):
|
|
37
|
+
"""Initialize a NumberEntryPart widget.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
master: Parent widget
|
|
41
|
+
value: Initial numeric value (int, float, string, or None)
|
|
42
|
+
value_format: Number format specification for IntlFormatter.
|
|
43
|
+
Examples: 'decimal', 'percent', 'currency', '#,##0.00', etc.
|
|
44
|
+
minvalue: Minimum allowed value (inclusive), or None for no lower bound
|
|
45
|
+
maxvalue: Maximum allowed value (inclusive), or None for no upper bound
|
|
46
|
+
increment: Step size for increment/decrement operations
|
|
47
|
+
wrap: If True, values wrap around at min/max boundaries.
|
|
48
|
+
If False, values are clamped at boundaries.
|
|
49
|
+
initial_focus: If True, widget receives focus on creation
|
|
50
|
+
allow_blank: If True, empty input is allowed (sets value to None)
|
|
51
|
+
locale: Locale identifier for number formatting (e.g., 'en_US')
|
|
52
|
+
**kwargs: Additional keyword arguments passed to TextEntryPart
|
|
53
|
+
"""
|
|
54
|
+
# Store numeric configuration
|
|
55
|
+
self._minvalue = minvalue
|
|
56
|
+
self._maxvalue = maxvalue
|
|
57
|
+
self._increment = increment
|
|
58
|
+
self._wrap = wrap
|
|
59
|
+
|
|
60
|
+
# Determine numeric type (float if any parameter is float)
|
|
61
|
+
def _has_fractional(x: int | float | None) -> bool:
|
|
62
|
+
if x is None:
|
|
63
|
+
return False
|
|
64
|
+
if isinstance(x, float):
|
|
65
|
+
return True
|
|
66
|
+
if isinstance(x, (int, float)) and float(x) != int(x):
|
|
67
|
+
return True
|
|
68
|
+
return False
|
|
69
|
+
|
|
70
|
+
self._num_type = float if any(
|
|
71
|
+
_has_fractional(x) for x in (
|
|
72
|
+
minvalue, maxvalue, increment,
|
|
73
|
+
value if not isinstance(value, str) else 0
|
|
74
|
+
)
|
|
75
|
+
) else int
|
|
76
|
+
|
|
77
|
+
# Initialize base TextEntryPart
|
|
78
|
+
# Convert initial value to appropriate type
|
|
79
|
+
if isinstance(value, str):
|
|
80
|
+
initial_value = value
|
|
81
|
+
else:
|
|
82
|
+
initial_value = None if value is None else self._num_type(value)
|
|
83
|
+
|
|
84
|
+
super().__init__(
|
|
85
|
+
master=master,
|
|
86
|
+
value=initial_value,
|
|
87
|
+
value_format=value_format,
|
|
88
|
+
initial_focus=initial_focus,
|
|
89
|
+
allow_blank=allow_blank,
|
|
90
|
+
**kwargs
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
# Apply bounds to the initial value. An empty/blank field has no numeric
|
|
94
|
+
# value — it arrives here as '' (a number field with no format stores its
|
|
95
|
+
# text verbatim) — so normalize it to None and skip bounds, mirroring how
|
|
96
|
+
# clear()/commit represent an empty field. (Without this, float('') raises
|
|
97
|
+
# at construction for NumberField(value=None) or value="".)
|
|
98
|
+
if self._value is None or self._value == "":
|
|
99
|
+
self._value = None
|
|
100
|
+
self._prev_changed_value = None
|
|
101
|
+
else:
|
|
102
|
+
self._value = self._apply_bounds(float(self._value))
|
|
103
|
+
if self._num_type is int:
|
|
104
|
+
self._value = int(round(self._value))
|
|
105
|
+
# Update display with bounded value
|
|
106
|
+
formatted_text = self._format_value(self._value)
|
|
107
|
+
self.textsignal.set(formatted_text)
|
|
108
|
+
self._prev_changed_value = self._value
|
|
109
|
+
|
|
110
|
+
# Bind keyboard stepping (Up/Down arrows)
|
|
111
|
+
self.bind('<Up>', self._handle_up_key, add=True)
|
|
112
|
+
self.bind('<Down>', self._handle_down_key, add=True)
|
|
113
|
+
|
|
114
|
+
# Bind mouse wheel (Windows/macOS)
|
|
115
|
+
self.bind('<MouseWheel>', self._handle_mouse_wheel, add=True)
|
|
116
|
+
|
|
117
|
+
# Bind mouse wheel (Linux/X11)
|
|
118
|
+
self.bind('<Button-4>', self._handle_wheel_up, add=True)
|
|
119
|
+
self.bind('<Button-5>', self._handle_wheel_down, add=True)
|
|
120
|
+
|
|
121
|
+
# Listen for increment/decrement events to invoke step
|
|
122
|
+
self.bind('<<Increment>>', self._handle_increment_event, add=True)
|
|
123
|
+
self.bind('<<Decrement>>', self._handle_decrement_event, add=True)
|
|
124
|
+
|
|
125
|
+
def _handle_up_key(self, event):
|
|
126
|
+
"""Handle Up arrow key press - emit increment event."""
|
|
127
|
+
if not self._is_interactive():
|
|
128
|
+
return 'break'
|
|
129
|
+
self.event_generate('<<Increment>>', data={'value': self._value})
|
|
130
|
+
return 'break' # Prevent default behavior
|
|
131
|
+
|
|
132
|
+
def _handle_down_key(self, event):
|
|
133
|
+
"""Handle Down arrow key press - emit decrement event."""
|
|
134
|
+
if not self._is_interactive():
|
|
135
|
+
return 'break'
|
|
136
|
+
self.event_generate('<<Decrement>>', data={'value': self._value})
|
|
137
|
+
return 'break' # Prevent default behavior
|
|
138
|
+
|
|
139
|
+
def _handle_mouse_wheel(self, event):
|
|
140
|
+
"""Handle mouse wheel on Windows/macOS."""
|
|
141
|
+
if not self._is_interactive():
|
|
142
|
+
return 'break'
|
|
143
|
+
try:
|
|
144
|
+
delta = int(event.delta)
|
|
145
|
+
except (AttributeError, ValueError):
|
|
146
|
+
delta = 0
|
|
147
|
+
|
|
148
|
+
if delta != 0:
|
|
149
|
+
if delta > 0:
|
|
150
|
+
self.event_generate('<<Increment>>', data={'value': self._value})
|
|
151
|
+
else:
|
|
152
|
+
self.event_generate('<<Decrement>>', data={'value': self._value})
|
|
153
|
+
return 'break'
|
|
154
|
+
|
|
155
|
+
def _handle_wheel_up(self, event):
|
|
156
|
+
"""Handle mouse wheel up on Linux/X11."""
|
|
157
|
+
if not self._is_interactive():
|
|
158
|
+
return 'break'
|
|
159
|
+
self.event_generate('<<Increment>>', data={'value': self._value})
|
|
160
|
+
return 'break'
|
|
161
|
+
|
|
162
|
+
def _handle_wheel_down(self, event):
|
|
163
|
+
"""Handle mouse wheel down on Linux/X11."""
|
|
164
|
+
if not self._is_interactive():
|
|
165
|
+
return 'break'
|
|
166
|
+
self.event_generate('<<Decrement>>', data={'value': self._value})
|
|
167
|
+
return 'break'
|
|
168
|
+
|
|
169
|
+
def _handle_increment_event(self, event):
|
|
170
|
+
"""Handle <<Increment>> event by stepping up."""
|
|
171
|
+
if not self._is_interactive():
|
|
172
|
+
return 'break'
|
|
173
|
+
self.step(+1)
|
|
174
|
+
|
|
175
|
+
def _handle_decrement_event(self, event):
|
|
176
|
+
"""Handle <<Decrement>> event by stepping down."""
|
|
177
|
+
if not self._is_interactive():
|
|
178
|
+
return 'break'
|
|
179
|
+
self.step(-1)
|
|
180
|
+
|
|
181
|
+
def _increment_decimals(self) -> int:
|
|
182
|
+
"""Number of decimal places implied by the increment.
|
|
183
|
+
|
|
184
|
+
Used to quantize stepped values to the step grid so floating-point
|
|
185
|
+
error does not accumulate across repeated steps.
|
|
186
|
+
"""
|
|
187
|
+
from decimal import Decimal
|
|
188
|
+
|
|
189
|
+
try:
|
|
190
|
+
exponent = Decimal(str(self._increment)).as_tuple().exponent
|
|
191
|
+
except Exception:
|
|
192
|
+
return 0
|
|
193
|
+
return max(0, -exponent) if isinstance(exponent, int) else 0
|
|
194
|
+
|
|
195
|
+
def _apply_bounds(self, x: float) -> float:
|
|
196
|
+
"""Apply min/max bounds with optional wrapping."""
|
|
197
|
+
lo = float(self._minvalue) if self._minvalue is not None else None
|
|
198
|
+
hi = float(self._maxvalue) if self._maxvalue is not None else None
|
|
199
|
+
|
|
200
|
+
if self._wrap and lo is not None and hi is not None:
|
|
201
|
+
if hi <= lo:
|
|
202
|
+
return lo
|
|
203
|
+
|
|
204
|
+
span = hi - lo
|
|
205
|
+
while x < lo:
|
|
206
|
+
x += span
|
|
207
|
+
while x > hi:
|
|
208
|
+
x -= span
|
|
209
|
+
return x
|
|
210
|
+
|
|
211
|
+
if lo is not None and x < lo:
|
|
212
|
+
x = lo
|
|
213
|
+
if hi is not None and x > hi:
|
|
214
|
+
x = hi
|
|
215
|
+
|
|
216
|
+
return x
|
|
217
|
+
|
|
218
|
+
def _is_interactive(self) -> bool:
|
|
219
|
+
"""Return True if the widget is not readonly or disabled."""
|
|
220
|
+
current_states = self.state()
|
|
221
|
+
return 'disabled' not in current_states and 'readonly' not in current_states
|
|
222
|
+
|
|
223
|
+
def step(self, n: int = 1):
|
|
224
|
+
"""Increment or decrement value by n steps."""
|
|
225
|
+
if not self._is_interactive():
|
|
226
|
+
return self
|
|
227
|
+
# Get current value (default to min if None)
|
|
228
|
+
current = self._value
|
|
229
|
+
if current is None:
|
|
230
|
+
base = float(self._minvalue) if self._minvalue is not None else 0.0
|
|
231
|
+
else:
|
|
232
|
+
base = float(current)
|
|
233
|
+
|
|
234
|
+
# Calculate new value
|
|
235
|
+
new_value = base + float(self._increment) * float(n)
|
|
236
|
+
|
|
237
|
+
# Apply bounds/wrapping
|
|
238
|
+
new_value = self._apply_bounds(new_value)
|
|
239
|
+
|
|
240
|
+
# Coerce to desired type. Snap floats to the increment's decimal
|
|
241
|
+
# precision so repeated stepping doesn't accumulate float error (e.g.
|
|
242
|
+
# 0.05 + 0.05 + 0.05 → 0.15000000000000002).
|
|
243
|
+
if self._num_type is float:
|
|
244
|
+
coerced = round(new_value, self._increment_decimals())
|
|
245
|
+
else:
|
|
246
|
+
coerced = int(round(new_value))
|
|
247
|
+
|
|
248
|
+
# Store previous value for change detection
|
|
249
|
+
prev_value = self._value
|
|
250
|
+
|
|
251
|
+
# Update internal value
|
|
252
|
+
self._value = coerced
|
|
253
|
+
|
|
254
|
+
# Update display
|
|
255
|
+
self._normalize_display_from_value()
|
|
256
|
+
|
|
257
|
+
# Emit changed event if value actually changed
|
|
258
|
+
if self._value != prev_value:
|
|
259
|
+
self._prev_changed_value = self._value
|
|
260
|
+
self.event_generate(
|
|
261
|
+
'<<Change>>', data=ChangeEvent(
|
|
262
|
+
value=self._value,
|
|
263
|
+
prev_value=prev_value,
|
|
264
|
+
text=self.textsignal(),
|
|
265
|
+
))
|
|
266
|
+
|
|
267
|
+
return self
|
|
268
|
+
|
|
269
|
+
def _get_validation_value(self):
|
|
270
|
+
"""Return the current input coerced to its numeric type, for validation.
|
|
271
|
+
|
|
272
|
+
A plain numeric field parses to a string when no display format is set,
|
|
273
|
+
so coerce it the same way the public value does — validation rules and a
|
|
274
|
+
`custom` func receive a real `int`/`float` (or `None` for empty/invalid
|
|
275
|
+
input), never the display string.
|
|
276
|
+
"""
|
|
277
|
+
text = self.get()
|
|
278
|
+
try:
|
|
279
|
+
raw = self._parse_or_none(text)
|
|
280
|
+
except Exception:
|
|
281
|
+
raw = text
|
|
282
|
+
if raw is None or raw == "":
|
|
283
|
+
return None
|
|
284
|
+
try:
|
|
285
|
+
number = float(raw)
|
|
286
|
+
except (TypeError, ValueError):
|
|
287
|
+
return None
|
|
288
|
+
return int(round(number)) if self._num_type is int else number
|
|
289
|
+
|
|
290
|
+
def _normalize_display_from_value(self):
|
|
291
|
+
"""Update display text from internal value without triggering input events."""
|
|
292
|
+
# Format the value
|
|
293
|
+
new_text = self._format_value(self._value)
|
|
294
|
+
|
|
295
|
+
# Only update if text changed
|
|
296
|
+
if new_text != self.textsignal():
|
|
297
|
+
# Temporarily unsubscribe from input signal to avoid spurious events
|
|
298
|
+
fid = getattr(self, '_on_input_fid', None)
|
|
299
|
+
if fid:
|
|
300
|
+
try:
|
|
301
|
+
fid.cancel()
|
|
302
|
+
except Exception:
|
|
303
|
+
pass
|
|
304
|
+
|
|
305
|
+
# Update display
|
|
306
|
+
self.textsignal.set(new_text)
|
|
307
|
+
|
|
308
|
+
# Re-subscribe to input signal
|
|
309
|
+
if fid:
|
|
310
|
+
self._on_input_fid = self.textsignal.subscribe(self._handle_change)
|
|
311
|
+
|
|
312
|
+
def commit(self):
|
|
313
|
+
"""Override commit to apply bounds validation after parsing.
|
|
314
|
+
|
|
315
|
+
This ensures user-entered values are constrained to valid range.
|
|
316
|
+
"""
|
|
317
|
+
# Call parent commit to parse and format
|
|
318
|
+
super().commit()
|
|
319
|
+
|
|
320
|
+
# Apply bounds to the parsed value
|
|
321
|
+
if self._value is not None:
|
|
322
|
+
bounded_value = self._apply_bounds(float(self._value))
|
|
323
|
+
|
|
324
|
+
# Coerce to appropriate type
|
|
325
|
+
if self._num_type is float:
|
|
326
|
+
self._value = float(bounded_value)
|
|
327
|
+
else:
|
|
328
|
+
self._value = int(round(bounded_value))
|
|
329
|
+
|
|
330
|
+
# Update display if value changed due to bounds
|
|
331
|
+
self._normalize_display_from_value()
|
|
332
|
+
|
|
333
|
+
def on_increment(self, callback) -> str:
|
|
334
|
+
"""Bind to `<<Increment>>`. Callback receives `event.data = {'value': current_value}`."""
|
|
335
|
+
return self.bind('<<Increment>>', callback, add=True)
|
|
336
|
+
|
|
337
|
+
def off_increment(self, bind_id: str | None = None) -> None:
|
|
338
|
+
"""Unbind from `<<Increment>>`."""
|
|
339
|
+
self.unbind('<<Increment>>', bind_id)
|
|
340
|
+
|
|
341
|
+
def on_decrement(self, callback) -> str:
|
|
342
|
+
"""Bind to `<<Decrement>>`. Callback receives `event.data = {'value': current_value}`."""
|
|
343
|
+
return self.bind('<<Decrement>>', callback, add=True)
|
|
344
|
+
|
|
345
|
+
def off_decrement(self, bind_id: str | None = None) -> None:
|
|
346
|
+
"""Unbind from `<<Decrement>>`."""
|
|
347
|
+
self.unbind('<<Decrement>>', bind_id)
|
|
348
|
+
|
|
349
|
+
@configure_delegate('minvalue')
|
|
350
|
+
def _delegate_minvalue(self, value: int | float):
|
|
351
|
+
"""Get or set the minimum allowed value and re-validate current value."""
|
|
352
|
+
if value is None:
|
|
353
|
+
return self._minvalue
|
|
354
|
+
|
|
355
|
+
self._minvalue = value
|
|
356
|
+
if self._value is not None:
|
|
357
|
+
self._value = self._apply_bounds(float(self._value))
|
|
358
|
+
self._normalize_display_from_value()
|
|
359
|
+
|
|
360
|
+
@configure_delegate('maxvalue')
|
|
361
|
+
def _delegate_maxvalue(self, value: int | float):
|
|
362
|
+
"""Get or set the maximum allowed value and re-validate current value."""
|
|
363
|
+
if value is None:
|
|
364
|
+
return self._maxvalue
|
|
365
|
+
|
|
366
|
+
self._maxvalue = value
|
|
367
|
+
if self._value is not None:
|
|
368
|
+
self._value = self._apply_bounds(float(self._value))
|
|
369
|
+
self._normalize_display_from_value()
|
|
370
|
+
|
|
371
|
+
@configure_delegate('increment')
|
|
372
|
+
def _delegate_increment(self, value: int | float):
|
|
373
|
+
"""Get or set the step increment value."""
|
|
374
|
+
if value is None:
|
|
375
|
+
return self._increment
|
|
376
|
+
|
|
377
|
+
self._increment = value
|
|
378
|
+
|
|
379
|
+
@configure_delegate('wrap')
|
|
380
|
+
def _delegate_wrap(self, value: bool):
|
|
381
|
+
"""Get or set the wrap setting."""
|
|
382
|
+
if value is None:
|
|
383
|
+
return self._wrap
|
|
384
|
+
|
|
385
|
+
self._wrap = bool(value)
|