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,413 @@
|
|
|
1
|
+
"""SideNavItem widget for selectable navigation items."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from tkinter import Variable
|
|
6
|
+
from typing import Any, Callable, TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
from typing_extensions import TypedDict, Unpack
|
|
9
|
+
|
|
10
|
+
from bootstack.widgets.primitives.frame import Frame
|
|
11
|
+
from bootstack.widgets.primitives.label import Label
|
|
12
|
+
from bootstack.widgets.composites.compositeframe import CompositeFrame
|
|
13
|
+
from bootstack.widgets.mixins import configure_delegate
|
|
14
|
+
from bootstack.widgets.types import Master
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from bootstack.core.signals import Signal
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class SideNavItemKwargs(TypedDict, total=False):
|
|
21
|
+
key: str
|
|
22
|
+
text: str
|
|
23
|
+
icon: Any
|
|
24
|
+
signal: Any
|
|
25
|
+
variable: Variable
|
|
26
|
+
is_enabled: bool
|
|
27
|
+
indent_level: int
|
|
28
|
+
command: Callable
|
|
29
|
+
padding_x: int
|
|
30
|
+
padding_y: int
|
|
31
|
+
icon_gap: int
|
|
32
|
+
accent: str
|
|
33
|
+
variant: str
|
|
34
|
+
# Frame options
|
|
35
|
+
padding: Any
|
|
36
|
+
width: int
|
|
37
|
+
height: int
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class SideNavItem(Frame):
|
|
41
|
+
"""A selectable navigation item with icon and text.
|
|
42
|
+
|
|
43
|
+
SideNavItem uses a CompositeFrame container with separate icon and
|
|
44
|
+
text label children. This provides synchronized hover/pressed/selected
|
|
45
|
+
states across all elements and precise control over layout.
|
|
46
|
+
|
|
47
|
+
The widget supports expanded and compact modes. In compact mode, only the
|
|
48
|
+
icon is displayed and it remains perfectly centered due to symmetrical
|
|
49
|
+
padding. In expanded mode, both icon and text are visible.
|
|
50
|
+
|
|
51
|
+
Uses NavigationButton.TFrame for the container (with selection indicator)
|
|
52
|
+
and NavigationButton.TLabel for the icon and text labels.
|
|
53
|
+
|
|
54
|
+
!!! note "Events"
|
|
55
|
+
- `<<ItemInvoked>>`: Fired when the item is clicked.
|
|
56
|
+
`event.data = {'key': str}`
|
|
57
|
+
|
|
58
|
+
Example:
|
|
59
|
+
```python
|
|
60
|
+
# Items are typically created via SideNav.add_item()
|
|
61
|
+
nav.add_item('home', text='Home', icon='house')
|
|
62
|
+
nav.add_item('local', text='Local', icon='hdd', group='files')
|
|
63
|
+
```
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
# Default indent width in pixels per indent level
|
|
67
|
+
INDENT_WIDTH = 24
|
|
68
|
+
|
|
69
|
+
# Default padding values
|
|
70
|
+
DEFAULT_PADDING_X = 12 # Horizontal padding on left/right edges
|
|
71
|
+
DEFAULT_PADDING_Y = 6 # Vertical padding
|
|
72
|
+
DEFAULT_ICON_GAP = 10 # Gap between icon and text in expanded mode
|
|
73
|
+
COMPACT_PADDING_X = 6 # Reduced horizontal padding in compact mode
|
|
74
|
+
COMPACT_PADDING_Y = 6 # Reduced vertical padding in compact mode
|
|
75
|
+
|
|
76
|
+
def __init__(
|
|
77
|
+
self,
|
|
78
|
+
master: Master = None,
|
|
79
|
+
key: str = '',
|
|
80
|
+
text: str = '',
|
|
81
|
+
icon: str | dict = None,
|
|
82
|
+
signal: 'Signal[Any]' = None,
|
|
83
|
+
variable: Variable = None,
|
|
84
|
+
is_enabled: bool = True,
|
|
85
|
+
indent_level: int = 0,
|
|
86
|
+
command: Callable = None,
|
|
87
|
+
padding_x: int = None,
|
|
88
|
+
padding_y: int = None,
|
|
89
|
+
icon_gap: int = None,
|
|
90
|
+
**kwargs: Unpack[SideNavItemKwargs]
|
|
91
|
+
):
|
|
92
|
+
"""Initialize a SideNavItem.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
master (Master | None): Parent widget.
|
|
96
|
+
key (str): Unique identifier for this item (used as selection value).
|
|
97
|
+
text (str): Display text for the item.
|
|
98
|
+
icon (str | dict | None): Icon name or configuration dict.
|
|
99
|
+
signal (Signal | None): Reactive signal for selection state (preferred).
|
|
100
|
+
variable (Variable | None): Shared variable for radio group selection.
|
|
101
|
+
is_enabled (bool): Whether the item is interactive. Default True.
|
|
102
|
+
indent_level (int): Nesting level for indentation (0 = root, 1 = child). Default 0.
|
|
103
|
+
command (Callable | None): Callback invoked when item is clicked.
|
|
104
|
+
padding_x (int | None): Horizontal padding on edges. Default is 12.
|
|
105
|
+
padding_y (int | None): Vertical padding. Default is 8.
|
|
106
|
+
icon_gap (int | None): Gap between icon and text. Default is 8.
|
|
107
|
+
**kwargs: Additional arguments passed to Frame.
|
|
108
|
+
"""
|
|
109
|
+
if not key:
|
|
110
|
+
raise ValueError("SideNavItem requires a non-empty 'key'")
|
|
111
|
+
|
|
112
|
+
# Extract styling kwargs before super().__init__
|
|
113
|
+
# Must set these AFTER super().__init__ because TTKWrapperBase also sets _accent/_variant
|
|
114
|
+
saved_accent = kwargs.pop('accent', 'primary')
|
|
115
|
+
saved_variant = kwargs.pop('variant', None)
|
|
116
|
+
|
|
117
|
+
super().__init__(master, **kwargs)
|
|
118
|
+
|
|
119
|
+
# Set after super() to avoid being overwritten by TTKWrapperBase
|
|
120
|
+
self._accent = saved_accent
|
|
121
|
+
self._variant = saved_variant
|
|
122
|
+
|
|
123
|
+
self._key = key
|
|
124
|
+
self._text = text
|
|
125
|
+
self._icon = icon
|
|
126
|
+
self._signal = signal
|
|
127
|
+
self._variable = variable
|
|
128
|
+
self._is_enabled = is_enabled
|
|
129
|
+
self._indent_level = indent_level
|
|
130
|
+
self._command = command
|
|
131
|
+
self._padding_x = padding_x if padding_x is not None else self.DEFAULT_PADDING_X
|
|
132
|
+
self._padding_y = padding_y if padding_y is not None else self.DEFAULT_PADDING_Y
|
|
133
|
+
self._icon_gap = icon_gap if icon_gap is not None else self.DEFAULT_ICON_GAP
|
|
134
|
+
|
|
135
|
+
# Compact mode state
|
|
136
|
+
self._compact = False
|
|
137
|
+
|
|
138
|
+
# Widget references
|
|
139
|
+
self._container: CompositeFrame | None = None
|
|
140
|
+
self._icon_label: Label | None = None
|
|
141
|
+
self._text_label: Label | None = None
|
|
142
|
+
|
|
143
|
+
# Variable trace
|
|
144
|
+
self._trace_id: str | None = None
|
|
145
|
+
|
|
146
|
+
# Build internal structure
|
|
147
|
+
self._build_widget()
|
|
148
|
+
|
|
149
|
+
# Set up variable trace for selection state
|
|
150
|
+
self._setup_variable_trace()
|
|
151
|
+
|
|
152
|
+
# Apply initial enabled state
|
|
153
|
+
if not is_enabled:
|
|
154
|
+
self._container.set_disabled(True)
|
|
155
|
+
|
|
156
|
+
def _build_widget(self):
|
|
157
|
+
"""Build the internal widget structure."""
|
|
158
|
+
# Calculate indentation padding for expanded mode
|
|
159
|
+
indent_padding = self._indent_level * self.INDENT_WIDTH
|
|
160
|
+
left_padding = self._padding_x + indent_padding
|
|
161
|
+
|
|
162
|
+
# CompositeFrame container with selection indicator
|
|
163
|
+
# Uses NavigationButton.TFrame style which has the nav-button assets
|
|
164
|
+
self._container = CompositeFrame(
|
|
165
|
+
self,
|
|
166
|
+
ttk_class='NavigationButton.TFrame',
|
|
167
|
+
accent=self._accent,
|
|
168
|
+
padding=(left_padding, self._padding_y, self._padding_x, self._padding_y),
|
|
169
|
+
takefocus=True,
|
|
170
|
+
)
|
|
171
|
+
self._container.pack(fill='x')
|
|
172
|
+
|
|
173
|
+
# Icon label (optional)
|
|
174
|
+
if self._icon:
|
|
175
|
+
self._icon_label = Label(
|
|
176
|
+
self._container,
|
|
177
|
+
icon=self._icon,
|
|
178
|
+
icon_only=True,
|
|
179
|
+
ttk_class='NavigationButton.TLabel',
|
|
180
|
+
accent=self._accent,
|
|
181
|
+
takefocus=False,
|
|
182
|
+
)
|
|
183
|
+
self._container.register_composite(self._icon_label)
|
|
184
|
+
|
|
185
|
+
# Text label
|
|
186
|
+
self._text_label = Label(
|
|
187
|
+
self._container,
|
|
188
|
+
text=self._text,
|
|
189
|
+
anchor='w',
|
|
190
|
+
ttk_class='NavigationButton.TLabel',
|
|
191
|
+
accent=self._accent,
|
|
192
|
+
takefocus=False,
|
|
193
|
+
)
|
|
194
|
+
self._container.register_composite(self._text_label)
|
|
195
|
+
|
|
196
|
+
# Apply initial layout
|
|
197
|
+
self._apply_layout()
|
|
198
|
+
|
|
199
|
+
# Bind click events - only to container, events bubble up from children
|
|
200
|
+
self._bind_events()
|
|
201
|
+
|
|
202
|
+
def _apply_layout(self):
|
|
203
|
+
"""Apply the current layout based on compact mode."""
|
|
204
|
+
# Clear current layout
|
|
205
|
+
if self._icon_label:
|
|
206
|
+
self._icon_label.pack_forget()
|
|
207
|
+
self._text_label.pack_forget()
|
|
208
|
+
|
|
209
|
+
if self._compact:
|
|
210
|
+
# Compact mode: tighter symmetrical padding, icon centered
|
|
211
|
+
px = self.COMPACT_PADDING_X
|
|
212
|
+
py = self.COMPACT_PADDING_Y
|
|
213
|
+
self._container.configure(padding=(px, py, px, py))
|
|
214
|
+
if self._icon_label:
|
|
215
|
+
self._icon_label.pack(expand=True)
|
|
216
|
+
else:
|
|
217
|
+
# Expanded mode: icon + text, with indent
|
|
218
|
+
indent_padding = self._indent_level * self.INDENT_WIDTH
|
|
219
|
+
left_padding = self._padding_x + indent_padding
|
|
220
|
+
self._container.configure(
|
|
221
|
+
padding=(left_padding, self._padding_y, self._padding_x, self._padding_y)
|
|
222
|
+
)
|
|
223
|
+
if self._icon_label:
|
|
224
|
+
self._icon_label.pack(side='left', padx=(0, self._icon_gap))
|
|
225
|
+
self._text_label.pack(side='left', fill='x', expand=True)
|
|
226
|
+
|
|
227
|
+
def _bind_events(self):
|
|
228
|
+
"""Bind click and keyboard events.
|
|
229
|
+
|
|
230
|
+
Binds click to container and all child widgets since Tkinter
|
|
231
|
+
doesn't bubble events from children to parents.
|
|
232
|
+
"""
|
|
233
|
+
self._container.bind('<Button-1>', self._on_click, add='+')
|
|
234
|
+
if self._icon_label:
|
|
235
|
+
self._icon_label.bind('<Button-1>', self._on_click, add='+')
|
|
236
|
+
self._text_label.bind('<Button-1>', self._on_click, add='+')
|
|
237
|
+
|
|
238
|
+
# Keyboard support on focusable container
|
|
239
|
+
self._container.bind('<Return>', self._on_click, add='+')
|
|
240
|
+
self._container.bind('<space>', self._on_click, add='+')
|
|
241
|
+
|
|
242
|
+
def _setup_variable_trace(self):
|
|
243
|
+
"""Set up variable trace for selection state updates.
|
|
244
|
+
|
|
245
|
+
Note: For performance, the SideNav now manages selection updates
|
|
246
|
+
centrally rather than each item tracing the variable. This method is
|
|
247
|
+
kept for backwards compatibility but does nothing when used with
|
|
248
|
+
SideNav.
|
|
249
|
+
"""
|
|
250
|
+
# Selection state is now managed by SideNav._on_selection_changed()
|
|
251
|
+
# which only updates the affected items rather than all items.
|
|
252
|
+
# Initial state update
|
|
253
|
+
self._update_selection_state()
|
|
254
|
+
|
|
255
|
+
def _update_selection_state(self):
|
|
256
|
+
"""Update visual state based on selection."""
|
|
257
|
+
if self._variable is not None and self._key:
|
|
258
|
+
selected = self._variable.get() == self._key
|
|
259
|
+
self._container.set_selected(selected)
|
|
260
|
+
|
|
261
|
+
def set_selected(self, selected: bool) -> None:
|
|
262
|
+
"""Directly set the selection visual state.
|
|
263
|
+
|
|
264
|
+
This is called by SideNav for efficient selection updates,
|
|
265
|
+
avoiding the need to query the variable.
|
|
266
|
+
|
|
267
|
+
Args:
|
|
268
|
+
selected: True to show as selected, False otherwise.
|
|
269
|
+
"""
|
|
270
|
+
self._container.set_selected(selected)
|
|
271
|
+
|
|
272
|
+
def _on_click(self, event=None):
|
|
273
|
+
"""Handle item click."""
|
|
274
|
+
if not self._is_enabled:
|
|
275
|
+
return
|
|
276
|
+
|
|
277
|
+
# Request focus
|
|
278
|
+
self._container.focus_set()
|
|
279
|
+
|
|
280
|
+
# Set selection if variable is configured
|
|
281
|
+
if self._variable is not None and self._key:
|
|
282
|
+
self._variable.set(self._key)
|
|
283
|
+
|
|
284
|
+
# Fire invoked event
|
|
285
|
+
self.event_generate('<<ItemInvoked>>', data={'key': self._key})
|
|
286
|
+
|
|
287
|
+
# Call command if set
|
|
288
|
+
if self._command:
|
|
289
|
+
self._command()
|
|
290
|
+
|
|
291
|
+
# --- Public API ---
|
|
292
|
+
|
|
293
|
+
def select(self) -> None:
|
|
294
|
+
"""Select this item (set the variable to this item's key)."""
|
|
295
|
+
if self._variable is not None:
|
|
296
|
+
self._variable.set(self._key)
|
|
297
|
+
|
|
298
|
+
def set_enabled(self, enabled: bool) -> None:
|
|
299
|
+
"""Set the enabled state.
|
|
300
|
+
|
|
301
|
+
Args:
|
|
302
|
+
enabled (bool): True to enable, False to disable.
|
|
303
|
+
"""
|
|
304
|
+
self._is_enabled = enabled
|
|
305
|
+
self._container.set_disabled(not enabled)
|
|
306
|
+
|
|
307
|
+
def set_compact(self, compact: bool) -> None:
|
|
308
|
+
"""Set compact mode (icon only, no text).
|
|
309
|
+
|
|
310
|
+
Args:
|
|
311
|
+
compact (bool): True for compact mode, False for full display.
|
|
312
|
+
"""
|
|
313
|
+
if self._compact == compact:
|
|
314
|
+
return
|
|
315
|
+
|
|
316
|
+
self._compact = compact
|
|
317
|
+
self._apply_layout()
|
|
318
|
+
self._update_selection_state()
|
|
319
|
+
|
|
320
|
+
# --- Properties ---
|
|
321
|
+
|
|
322
|
+
@property
|
|
323
|
+
def key(self) -> str:
|
|
324
|
+
"""Get the item's unique key."""
|
|
325
|
+
return self._key
|
|
326
|
+
|
|
327
|
+
@property
|
|
328
|
+
def is_selected(self) -> bool:
|
|
329
|
+
"""Check if this item is currently selected."""
|
|
330
|
+
if self._variable is not None:
|
|
331
|
+
return self._variable.get() == self._key
|
|
332
|
+
return False
|
|
333
|
+
|
|
334
|
+
@property
|
|
335
|
+
def is_enabled(self) -> bool:
|
|
336
|
+
"""Check if this item is enabled."""
|
|
337
|
+
return self._is_enabled
|
|
338
|
+
|
|
339
|
+
@property
|
|
340
|
+
def signal(self) -> 'Signal[Any] | None':
|
|
341
|
+
"""Get the signal for selection state."""
|
|
342
|
+
return self._signal
|
|
343
|
+
|
|
344
|
+
@property
|
|
345
|
+
def variable(self) -> Variable | None:
|
|
346
|
+
"""Get the variable for selection state."""
|
|
347
|
+
return self._variable
|
|
348
|
+
|
|
349
|
+
# --- Configuration Delegates ---
|
|
350
|
+
|
|
351
|
+
@configure_delegate('text')
|
|
352
|
+
def _delegate_text(self, value: str = None):
|
|
353
|
+
"""Configure the item text."""
|
|
354
|
+
if value is None:
|
|
355
|
+
return self._text
|
|
356
|
+
self._text = value
|
|
357
|
+
if self._text_label:
|
|
358
|
+
self._text_label.configure(text=value)
|
|
359
|
+
return None
|
|
360
|
+
|
|
361
|
+
@configure_delegate('icon')
|
|
362
|
+
def _delegate_icon(self, value: str | dict = None):
|
|
363
|
+
"""Configure the item icon."""
|
|
364
|
+
if value is None:
|
|
365
|
+
return self._icon
|
|
366
|
+
self._icon = value
|
|
367
|
+
|
|
368
|
+
if self._icon_label is not None:
|
|
369
|
+
self._icon_label.configure(icon=value)
|
|
370
|
+
elif value is not None:
|
|
371
|
+
# Create icon label if it doesn't exist
|
|
372
|
+
self._icon_label = Label(
|
|
373
|
+
self._container,
|
|
374
|
+
icon=value,
|
|
375
|
+
icon_only=True,
|
|
376
|
+
ttk_class='NavigationButton.TLabel',
|
|
377
|
+
accent=self._accent,
|
|
378
|
+
takefocus=False,
|
|
379
|
+
)
|
|
380
|
+
self._container.register_composite(self._icon_label)
|
|
381
|
+
self._icon_label.bind('<Button-1>', self._on_click, add='+')
|
|
382
|
+
# Re-apply layout
|
|
383
|
+
self._apply_layout()
|
|
384
|
+
return None
|
|
385
|
+
|
|
386
|
+
@configure_delegate('command')
|
|
387
|
+
def _delegate_command(self, value: Callable = None):
|
|
388
|
+
"""Configure the command callback."""
|
|
389
|
+
if value is None:
|
|
390
|
+
return self._command
|
|
391
|
+
self._command = value
|
|
392
|
+
return None
|
|
393
|
+
|
|
394
|
+
# --- Event Binding Helpers ---
|
|
395
|
+
|
|
396
|
+
def on_invoked(self, callback) -> str:
|
|
397
|
+
"""Bind to `<<ItemInvoked>>`.
|
|
398
|
+
|
|
399
|
+
Args:
|
|
400
|
+
callback: Function to call when item is invoked.
|
|
401
|
+
|
|
402
|
+
Returns:
|
|
403
|
+
str: Binding identifier for use with off_invoked().
|
|
404
|
+
"""
|
|
405
|
+
return self.bind('<<ItemInvoked>>', callback, add='+')
|
|
406
|
+
|
|
407
|
+
def off_invoked(self, bind_id: str = None) -> None:
|
|
408
|
+
"""Unbind from `<<ItemInvoked>>`.
|
|
409
|
+
|
|
410
|
+
Args:
|
|
411
|
+
bind_id (str | None): Binding identifier from on_invoked().
|
|
412
|
+
"""
|
|
413
|
+
self.unbind('<<ItemInvoked>>', bind_id)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""SideNavSeparator widget for visual grouping in navigation menus."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from typing_extensions import TypedDict, Unpack
|
|
6
|
+
|
|
7
|
+
from bootstack.widgets.primitives.frame import Frame
|
|
8
|
+
from bootstack.widgets.primitives.separator import Separator
|
|
9
|
+
from bootstack.widgets.types import Master
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class SideNavSeparatorKwargs(TypedDict, total=False):
|
|
13
|
+
# Frame options
|
|
14
|
+
padding: Any
|
|
15
|
+
width: int
|
|
16
|
+
height: int
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class SideNavSeparator(Frame):
|
|
20
|
+
"""A visual separator for grouping items in a SideNav.
|
|
21
|
+
|
|
22
|
+
SideNavSeparator provides a horizontal line to visually separate
|
|
23
|
+
groups of navigation items. It is a thin wrapper around the Separator
|
|
24
|
+
primitive with appropriate padding for navigation contexts.
|
|
25
|
+
|
|
26
|
+
Example:
|
|
27
|
+
```python
|
|
28
|
+
nav.add_item('home', text='Home', icon='house')
|
|
29
|
+
nav.add_item('documents', text='Documents', icon='folder')
|
|
30
|
+
nav.add_separator() # Creates SideNavSeparator
|
|
31
|
+
nav.add_item('settings', text='Settings', icon='gear')
|
|
32
|
+
```
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
DEFAULT_PADDING = (0, 4, 0, 4)
|
|
36
|
+
|
|
37
|
+
def __init__(self, master: Master = None, **kwargs: Unpack[SideNavSeparatorKwargs]):
|
|
38
|
+
"""Initialize a SideNavSeparator.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
master (Master | None): Parent widget.
|
|
42
|
+
**kwargs: Additional arguments passed to Frame.
|
|
43
|
+
"""
|
|
44
|
+
# Default padding for visual separation
|
|
45
|
+
kwargs.setdefault('padding', self.DEFAULT_PADDING)
|
|
46
|
+
|
|
47
|
+
super().__init__(master, **kwargs)
|
|
48
|
+
|
|
49
|
+
# Create horizontal separator
|
|
50
|
+
self._separator = Separator(self, orient='horizontal')
|
|
51
|
+
self._separator.pack(fill='x')
|