bootstack 0.3.2__tar.gz → 0.4.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (496) hide show
  1. {bootstack-0.3.2/src/bootstack.egg-info → bootstack-0.4.1}/PKG-INFO +1 -1
  2. {bootstack-0.3.2 → bootstack-0.4.1}/pyproject.toml +2 -2
  3. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/_core/__init__.py +0 -4
  4. bootstack-0.4.1/src/bootstack/_core/mixins/widget.py +387 -0
  5. bootstack-0.3.2/src/bootstack/_core/capabilities/signals.py → bootstack-0.4.1/src/bootstack/_core/signal_binding.py +2 -1
  6. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/_runtime/app.py +0 -6
  7. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/_runtime/base_window.py +0 -3
  8. bootstack-0.4.1/src/bootstack/_runtime/grab.py +109 -0
  9. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/_runtime/toplevel.py +50 -4
  10. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/dialogs/_impl/colorchooser.py +10 -6
  11. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/dialogs/_impl/dialog.py +1 -84
  12. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/signals/signal.py +182 -23
  13. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/validation/validation_rules.py +74 -2
  14. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_core/base.py +19 -6
  15. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_core/field_mixin.py +29 -9
  16. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/_parts/spinnerentry_part.py +24 -11
  17. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/_parts/textentry_part.py +29 -14
  18. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/expander.py +1 -1
  19. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/form.py +5 -4
  20. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/list/listview.py +1 -2
  21. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/tableview/tableview.py +15 -10
  22. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/tabs/tabitem.py +1 -1
  23. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/textarea/core.py +65 -5
  24. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/textarea/textarea.py +13 -0
  25. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/mixins/localization_mixin.py +1 -1
  26. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/mixins/signal_mixin.py +1 -1
  27. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/primitives/gridframe.py +0 -4
  28. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/primitives/optionmenu.py +6 -2
  29. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/primitives/packframe.py +0 -4
  30. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/boolean_controls.py +3 -3
  31. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/chart.py +3 -0
  32. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/codeeditor.py +2 -2
  33. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/datatable.py +15 -0
  34. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/datefield.py +2 -1
  35. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/menubutton.py +3 -0
  36. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/numberfield.py +2 -1
  37. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/passwordfield.py +3 -3
  38. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/pathfield.py +3 -3
  39. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/picture.py +3 -0
  40. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/select.py +100 -40
  41. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/selectbutton.py +15 -11
  42. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/spinnerfield.py +3 -3
  43. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/splitview.py +1 -3
  44. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/statusbar.py +3 -0
  45. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/textarea.py +6 -2
  46. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/textfield.py +3 -3
  47. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/timefield.py +11 -2
  48. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/toolbar.py +3 -0
  49. {bootstack-0.3.2 → bootstack-0.4.1/src/bootstack.egg-info}/PKG-INFO +1 -1
  50. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack.egg-info/SOURCES.txt +3 -17
  51. bootstack-0.3.2/src/bootstack/_core/capabilities/__init__.py +0 -45
  52. bootstack-0.3.2/src/bootstack/_core/capabilities/after.py +0 -103
  53. bootstack-0.3.2/src/bootstack/_core/capabilities/bind.py +0 -192
  54. bootstack-0.3.2/src/bootstack/_core/capabilities/bindtags.py +0 -112
  55. bootstack-0.3.2/src/bootstack/_core/capabilities/busy.py +0 -72
  56. bootstack-0.3.2/src/bootstack/_core/capabilities/clipboard.py +0 -89
  57. bootstack-0.3.2/src/bootstack/_core/capabilities/focus.py +0 -118
  58. bootstack-0.3.2/src/bootstack/_core/capabilities/grab.py +0 -65
  59. bootstack-0.3.2/src/bootstack/_core/capabilities/grid.py +0 -211
  60. bootstack-0.3.2/src/bootstack/_core/capabilities/pack.py +0 -140
  61. bootstack-0.3.2/src/bootstack/_core/capabilities/place.py +0 -113
  62. bootstack-0.3.2/src/bootstack/_core/capabilities/selection.py +0 -136
  63. bootstack-0.3.2/src/bootstack/_core/capabilities/winfo.py +0 -315
  64. bootstack-0.3.2/src/bootstack/_core/colorutils.py +0 -234
  65. bootstack-0.3.2/src/bootstack/_core/mixins/widget.py +0 -132
  66. bootstack-0.3.2/src/bootstack/_core/publisher.py +0 -149
  67. {bootstack-0.3.2 → bootstack-0.4.1}/LICENSE +0 -0
  68. {bootstack-0.3.2 → bootstack-0.4.1}/MANIFEST.in +0 -0
  69. {bootstack-0.3.2 → bootstack-0.4.1}/NOTICE +0 -0
  70. {bootstack-0.3.2 → bootstack-0.4.1}/README.md +0 -0
  71. {bootstack-0.3.2 → bootstack-0.4.1}/setup.cfg +0 -0
  72. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/__init__.py +0 -0
  73. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/__main__.py +0 -0
  74. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/_core/capture.py +0 -0
  75. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/_core/exceptions.py +0 -0
  76. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/_core/images.py +0 -0
  77. {bootstack-0.3.2/src/bootstack/_core/capabilities → bootstack-0.4.1/src/bootstack/_core}/localization.py +0 -0
  78. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/_core/mixins/__init__.py +0 -0
  79. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/_core/mixins/ttk_state.py +0 -0
  80. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/_core/paths.py +0 -0
  81. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/_core/variables.py +0 -0
  82. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/_runtime/__init__.py +0 -0
  83. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/_runtime/events.py +0 -0
  84. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/_runtime/shortcuts.py +0 -0
  85. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/_runtime/tk_patch.py +0 -0
  86. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/_runtime/utility.py +0 -0
  87. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/_runtime/visual_focus.py +0 -0
  88. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/_runtime/wheel.py +0 -0
  89. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/_runtime/window_utilities.py +0 -0
  90. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/__init__.py +0 -0
  91. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/bootstack.ico +0 -0
  92. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/bootstack.png +0 -0
  93. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/__init__.py +0 -0
  94. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/badge-pill.png +0 -0
  95. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/badge-square.png +0 -0
  96. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/button-compact.png +0 -0
  97. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/button-default.png +0 -0
  98. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/buttongroup-after-h-compact.png +0 -0
  99. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/buttongroup-after-h-default.png +0 -0
  100. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/buttongroup-after-v-compact.png +0 -0
  101. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/buttongroup-after-v-default.png +0 -0
  102. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/buttongroup-before-h-compact.png +0 -0
  103. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/buttongroup-before-h-default.png +0 -0
  104. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/buttongroup-before-v-compact.png +0 -0
  105. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/buttongroup-before-v-default.png +0 -0
  106. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/buttongroup-center-h-compact.png +0 -0
  107. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/buttongroup-center-h-default.png +0 -0
  108. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/buttongroup-center-v-compact.png +0 -0
  109. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/buttongroup-center-v-default.png +0 -0
  110. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/card.png +0 -0
  111. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/checkbox-checked.png +0 -0
  112. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/checkbox-indeterminate.png +0 -0
  113. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/checkbox-unchecked.png +0 -0
  114. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/field.png +0 -0
  115. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/input-addon-compact.png +0 -0
  116. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/input-addon-default.png +0 -0
  117. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/input-compact.png +0 -0
  118. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/input-default.png +0 -0
  119. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/list-item-separated.png +0 -0
  120. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/list-item.png +0 -0
  121. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/listrow-compact.png +0 -0
  122. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/listrow-default.png +0 -0
  123. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/manifest.toml +0 -0
  124. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/menu-item.png +0 -0
  125. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/navitem-compact.png +0 -0
  126. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/navitem-default.png +0 -0
  127. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/progressbar-h-compact.png +0 -0
  128. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/progressbar-h-default.png +0 -0
  129. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/progressbar-v-compact.png +0 -0
  130. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/progressbar-v-default.png +0 -0
  131. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/radiobutton.png +0 -0
  132. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/scrollbar-horizontal.png +0 -0
  133. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/scrollbar-vertical.png +0 -0
  134. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/slider-handle.png +0 -0
  135. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/slider-track-h.png +0 -0
  136. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/slider-track-v.png +0 -0
  137. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/switch-off.png +0 -0
  138. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/switch-on.png +0 -0
  139. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/tab-h.png +0 -0
  140. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/elements/tab-v.png +0 -0
  141. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/icons/bootstrap.ttf +0 -0
  142. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/icons/glyphmap.json +0 -0
  143. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/icons/icon_metrics.json +0 -0
  144. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/ar/LC_MESSAGES/bootstack.mo +0 -0
  145. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/ar/LC_MESSAGES/bootstack.po +0 -0
  146. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/bg/LC_MESSAGES/bootstack.mo +0 -0
  147. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/bg/LC_MESSAGES/bootstack.po +0 -0
  148. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/cs/LC_MESSAGES/bootstack.mo +0 -0
  149. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/cs/LC_MESSAGES/bootstack.po +0 -0
  150. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/da/LC_MESSAGES/bootstack.mo +0 -0
  151. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/da/LC_MESSAGES/bootstack.po +0 -0
  152. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/de/LC_MESSAGES/bootstack.mo +0 -0
  153. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/de/LC_MESSAGES/bootstack.po +0 -0
  154. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/en/LC_MESSAGES/bootstack.mo +0 -0
  155. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/en/LC_MESSAGES/bootstack.po +0 -0
  156. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/es/LC_MESSAGES/bootstack.mo +0 -0
  157. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/es/LC_MESSAGES/bootstack.po +0 -0
  158. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/fr/LC_MESSAGES/bootstack.mo +0 -0
  159. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/fr/LC_MESSAGES/bootstack.po +0 -0
  160. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/he/LC_MESSAGES/bootstack.mo +0 -0
  161. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/he/LC_MESSAGES/bootstack.po +0 -0
  162. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/hi/LC_MESSAGES/bootstack.mo +0 -0
  163. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/hi/LC_MESSAGES/bootstack.po +0 -0
  164. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/it/LC_MESSAGES/bootstack.mo +0 -0
  165. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/it/LC_MESSAGES/bootstack.po +0 -0
  166. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/ja/LC_MESSAGES/bootstack.mo +0 -0
  167. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/ja/LC_MESSAGES/bootstack.po +0 -0
  168. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/ko/LC_MESSAGES/bootstack.mo +0 -0
  169. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/ko/LC_MESSAGES/bootstack.po +0 -0
  170. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/nb/LC_MESSAGES/bootstack.mo +0 -0
  171. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/nb/LC_MESSAGES/bootstack.po +0 -0
  172. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/nl/LC_MESSAGES/bootstack.mo +0 -0
  173. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/nl/LC_MESSAGES/bootstack.po +0 -0
  174. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/pl/LC_MESSAGES/bootstack.mo +0 -0
  175. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/pl/LC_MESSAGES/bootstack.po +0 -0
  176. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/pt/LC_MESSAGES/bootstack.mo +0 -0
  177. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/pt/LC_MESSAGES/bootstack.po +0 -0
  178. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.mo +0 -0
  179. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.po +0 -0
  180. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/sl/LC_MESSAGES/bootstack.mo +0 -0
  181. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/sl/LC_MESSAGES/bootstack.po +0 -0
  182. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/sv/LC_MESSAGES/bootstack.mo +0 -0
  183. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/sv/LC_MESSAGES/bootstack.po +0 -0
  184. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/tr/LC_MESSAGES/bootstack.mo +0 -0
  185. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/tr/LC_MESSAGES/bootstack.po +0 -0
  186. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.mo +0 -0
  187. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.po +0 -0
  188. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.mo +0 -0
  189. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.po +0 -0
  190. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/cli/__init__.py +0 -0
  191. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/cli/__main__.py +0 -0
  192. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/cli/add.py +0 -0
  193. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/cli/appicon.py +0 -0
  194. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/cli/build.py +0 -0
  195. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/cli/config.py +0 -0
  196. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/cli/demo.py +0 -0
  197. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/cli/dev.py +0 -0
  198. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/cli/doctor.py +0 -0
  199. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/cli/icons.py +0 -0
  200. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/cli/promote.py +0 -0
  201. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/cli/pyinstaller.py +0 -0
  202. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/cli/run.py +0 -0
  203. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/cli/start.py +0 -0
  204. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/cli/templates/__init__.py +0 -0
  205. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/clipboard.py +0 -0
  206. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/constants.py +0 -0
  207. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/data/README.md +0 -0
  208. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/data/__init__.py +0 -0
  209. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/data/_observable.py +0 -0
  210. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/data/base.py +0 -0
  211. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/data/file_source.py +0 -0
  212. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/data/memory_source.py +0 -0
  213. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/data/query.py +0 -0
  214. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/data/readers.py +0 -0
  215. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/data/sqlite_source.py +0 -0
  216. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/data/types.py +0 -0
  217. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/data/writers.py +0 -0
  218. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/dev/__init__.py +0 -0
  219. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/dev/_capture.py +0 -0
  220. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/dev/_env.py +0 -0
  221. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/dev/_registry.py +0 -0
  222. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/dev/_reloader.py +0 -0
  223. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/dev/_reset.py +0 -0
  224. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/dev/_watcher.py +0 -0
  225. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/dialogs/__init__.py +0 -0
  226. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/dialogs/_impl/__init__.py +0 -0
  227. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/dialogs/_impl/datedialog.py +0 -0
  228. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/dialogs/_impl/filterdialog.py +0 -0
  229. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/dialogs/_impl/fontdialog.py +0 -0
  230. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/dialogs/_impl/formdialog.py +0 -0
  231. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/dialogs/_impl/message.py +0 -0
  232. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/dialogs/_impl/query.py +0 -0
  233. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/errors.py +0 -0
  234. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/events/__init__.py +0 -0
  235. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/events/_event.py +0 -0
  236. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/events/_payloads.py +0 -0
  237. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/events/_subscription.py +0 -0
  238. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/i18n/README.md +0 -0
  239. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/i18n/__init__.py +0 -0
  240. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/i18n/catalog.py +0 -0
  241. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/i18n/intl_format.py +0 -0
  242. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/i18n/msgcat.py +0 -0
  243. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/i18n/specs.py +0 -0
  244. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/images.py +0 -0
  245. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/py.typed +0 -0
  246. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/scheduling/__init__.py +0 -0
  247. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/scheduling/_schedule.py +0 -0
  248. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/shortcuts.py +0 -0
  249. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/signals/README.md +0 -0
  250. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/signals/__init__.py +0 -0
  251. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/signals/integration.py +0 -0
  252. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/signals/types.py +0 -0
  253. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/store.py +0 -0
  254. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/streams/__init__.py +0 -0
  255. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/streams/_stream.py +0 -0
  256. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/__init__.py +0 -0
  257. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/__init__.py +0 -0
  258. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/badge.py +0 -0
  259. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/button.py +0 -0
  260. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/buttongroup.py +0 -0
  261. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/calendar.py +0 -0
  262. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/checkbutton.py +0 -0
  263. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/combobox.py +0 -0
  264. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/contextmenu.py +0 -0
  265. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/entry.py +0 -0
  266. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/expander.py +0 -0
  267. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/field.py +0 -0
  268. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/frame.py +0 -0
  269. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/label.py +0 -0
  270. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/labelframe.py +0 -0
  271. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/listview.py +0 -0
  272. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/menubar.py +0 -0
  273. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/menubutton.py +0 -0
  274. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/panedwindow.py +0 -0
  275. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/progressbar.py +0 -0
  276. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/radiobutton.py +0 -0
  277. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/scale.py +0 -0
  278. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/scrollbar.py +0 -0
  279. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/separator.py +0 -0
  280. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/sidenav.py +0 -0
  281. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/sizegrip.py +0 -0
  282. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/spinbox.py +0 -0
  283. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/switch.py +0 -0
  284. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/tabitem.py +0 -0
  285. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/togglegroup.py +0 -0
  286. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/toolbutton.py +0 -0
  287. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/tooltip.py +0 -0
  288. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/treeview.py +0 -0
  289. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders/utils.py +0 -0
  290. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders_tk/__init__.py +0 -0
  291. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/builders_tk/defaults.py +0 -0
  292. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/element.py +0 -0
  293. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/fonts.py +0 -0
  294. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/style.py +0 -0
  295. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/style_builder_base.py +0 -0
  296. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/style_builder_mixed.py +0 -0
  297. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/style_builder_tk.py +0 -0
  298. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/style_builder_ttk.py +0 -0
  299. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/style_resolver.py +0 -0
  300. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/theme.py +0 -0
  301. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/theme_provider.py +0 -0
  302. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/themes/__init__.py +0 -0
  303. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/tk_patch.py +0 -0
  304. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/token_maps.py +0 -0
  305. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/types.py +0 -0
  306. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/typography.py +0 -0
  307. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/style/utility.py +0 -0
  308. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/types.py +0 -0
  309. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/validation/__init__.py +0 -0
  310. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/validation/types.py +0 -0
  311. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/validation/validation_result.py +0 -0
  312. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/__init__.py +0 -0
  313. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_core/__init__.py +0 -0
  314. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_core/app_config.py +0 -0
  315. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_core/choices.py +0 -0
  316. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_core/container.py +0 -0
  317. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_core/context.py +0 -0
  318. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_core/events.py +0 -0
  319. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_core/icon_image_props.py +0 -0
  320. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_core/image_binding.py +0 -0
  321. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_core/kwargs.py +0 -0
  322. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_core/navmodel.py +0 -0
  323. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_core/options.py +0 -0
  324. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_core/selection_group.py +0 -0
  325. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_core/window_controls.py +0 -0
  326. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_core/window_menu.py +0 -0
  327. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/__init__.py +0 -0
  328. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/_internal/__init__.py +0 -0
  329. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/_internal/wrapper_base.py +0 -0
  330. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/_parts/__init__.py +0 -0
  331. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/_parts/numberentry_part.py +0 -0
  332. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/__init__.py +0 -0
  333. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/_dateutils.py +0 -0
  334. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/_image_fit.py +0 -0
  335. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/accordion.py +0 -0
  336. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/avatar.py +0 -0
  337. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/buttongroup.py +0 -0
  338. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/calendar.py +0 -0
  339. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/carousel.py +0 -0
  340. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/chart.py +0 -0
  341. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/compositeframe.py +0 -0
  342. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/contextmenu.py +0 -0
  343. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/dateentry.py +0 -0
  344. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/dropdownbutton.py +0 -0
  345. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/field.py +0 -0
  346. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/gallery.py +0 -0
  347. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/list/__init__.py +0 -0
  348. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/list/listitem.py +0 -0
  349. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/menu/__init__.py +0 -0
  350. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/menu/model.py +0 -0
  351. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/menu/render_native.py +0 -0
  352. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/menu/render_themed.py +0 -0
  353. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/meter.py +0 -0
  354. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/numericentry.py +0 -0
  355. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/pagestack.py +0 -0
  356. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/passwordentry.py +0 -0
  357. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/pathentry.py +0 -0
  358. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/picture.py +0 -0
  359. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/radiogroup.py +0 -0
  360. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/scrolledtext.py +0 -0
  361. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/scrolledtext.pyi +0 -0
  362. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/scrollview.py +0 -0
  363. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/selectbox.py +0 -0
  364. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/shell/__init__.py +0 -0
  365. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/shell/content_host.py +0 -0
  366. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/shell/layout.py +0 -0
  367. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/shell/nav_panel.py +0 -0
  368. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/shell/providers.py +0 -0
  369. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/shell/rail.py +0 -0
  370. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/shell/shell.py +0 -0
  371. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/shell/workspace.py +0 -0
  372. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/sidenav/__init__.py +0 -0
  373. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/sidenav/header.py +0 -0
  374. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/sidenav/separator.py +0 -0
  375. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/slider/__init__.py +0 -0
  376. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/slider/_shared.py +0 -0
  377. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/slider/rangeslider.py +0 -0
  378. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/slider/slider.py +0 -0
  379. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/spinnerentry.py +0 -0
  380. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/tableview/__init__.py +0 -0
  381. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/tableview/types.py +0 -0
  382. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/tabs/__init__.py +0 -0
  383. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/tabs/tabs.py +0 -0
  384. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/tabs/tabview.py +0 -0
  385. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/textarea/__init__.py +0 -0
  386. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/textarea/change.py +0 -0
  387. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/textarea/codeeditor.py +0 -0
  388. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/textarea/decoration.py +0 -0
  389. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/textarea/diff.py +0 -0
  390. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/textarea/extensions/__init__.py +0 -0
  391. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/textarea/extensions/bracket_matcher.py +0 -0
  392. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/textarea/extensions/indent_guides.py +0 -0
  393. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/textarea/extensions/line_numbers.py +0 -0
  394. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/textarea/extensions/pygments_highlighter.py +0 -0
  395. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/textarea/extensions/smart_indent.py +0 -0
  396. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/textarea/filter.py +0 -0
  397. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/textarea/redirector.py +0 -0
  398. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/textarea/search_overlay.py +0 -0
  399. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/textarea/sidebar.py +0 -0
  400. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/textarea/style_registry.py +0 -0
  401. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/textarea/undo.py +0 -0
  402. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/textentry.py +0 -0
  403. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/timeentry.py +0 -0
  404. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/toast.py +0 -0
  405. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/toast_stack.py +0 -0
  406. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/togglegroup.py +0 -0
  407. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/toolbar.py +0 -0
  408. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/tooltip.py +0 -0
  409. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/tree/__init__.py +0 -0
  410. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/tree/source_binding.py +0 -0
  411. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/tree/treeitem.py +0 -0
  412. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/tree/treenode.py +0 -0
  413. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/composites/tree/treeview.py +0 -0
  414. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/mixins/__init__.py +0 -0
  415. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/mixins/configure_mixin.py +0 -0
  416. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/mixins/entry_mixin.py +0 -0
  417. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/mixins/font_mixin.py +0 -0
  418. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/mixins/icon_mixin.py +0 -0
  419. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/mixins/validation_mixin.py +0 -0
  420. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/primitives/__init__.py +0 -0
  421. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/primitives/_menubutton.py +0 -0
  422. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/primitives/badge.py +0 -0
  423. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/primitives/button.py +0 -0
  424. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/primitives/card.py +0 -0
  425. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/primitives/checkbutton.py +0 -0
  426. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/primitives/checktoggle.py +0 -0
  427. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/primitives/combobox.py +0 -0
  428. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/primitives/entry.py +0 -0
  429. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/primitives/flexframe.py +0 -0
  430. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/primitives/frame.py +0 -0
  431. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/primitives/label.py +0 -0
  432. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/primitives/labelframe.py +0 -0
  433. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/primitives/panedwindow.py +0 -0
  434. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/primitives/progressbar.py +0 -0
  435. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/primitives/radiobutton.py +0 -0
  436. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/primitives/radiotoggle.py +0 -0
  437. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/primitives/scrollbar.py +0 -0
  438. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/primitives/separator.py +0 -0
  439. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/primitives/sizegrip.py +0 -0
  440. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/primitives/spinbox.py +0 -0
  441. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/primitives/switch.py +0 -0
  442. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/_impl/primitives/treeview.py +0 -0
  443. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/app.py +0 -0
  444. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/appshell.py +0 -0
  445. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/avatar.py +0 -0
  446. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/button.py +0 -0
  447. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/buttongroup.py +0 -0
  448. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/calendar.py +0 -0
  449. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/card.py +0 -0
  450. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/carousel.py +0 -0
  451. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/contextmenu.py +0 -0
  452. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/divider.py +0 -0
  453. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/expander.py +0 -0
  454. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/form.py +0 -0
  455. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/gallery.py +0 -0
  456. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/gauge.py +0 -0
  457. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/grid.py +0 -0
  458. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/groupbox.py +0 -0
  459. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/label.py +0 -0
  460. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/listview.py +0 -0
  461. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/pagestack.py +0 -0
  462. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/progressbar.py +0 -0
  463. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/radio_variants.py +0 -0
  464. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/radiogroup.py +0 -0
  465. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/scrollbar.py +0 -0
  466. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/scrollview.py +0 -0
  467. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/sidebar_toggle.py +0 -0
  468. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/sizegrip.py +0 -0
  469. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/slider.py +0 -0
  470. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/spinbox.py +0 -0
  471. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/splash.py +0 -0
  472. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/stacks.py +0 -0
  473. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/tabs.py +0 -0
  474. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/theme_toggle.py +0 -0
  475. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/toast.py +0 -0
  476. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/togglegroup.py +0 -0
  477. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/tooltip.py +0 -0
  478. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/tree.py +0 -0
  479. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/types.py +0 -0
  480. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack/widgets/window.py +0 -0
  481. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack.egg-info/dependency_links.txt +0 -0
  482. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack.egg-info/entry_points.txt +0 -0
  483. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack.egg-info/requires.txt +0 -0
  484. {bootstack-0.3.2 → bootstack-0.4.1}/src/bootstack.egg-info/top_level.txt +0 -0
  485. {bootstack-0.3.2 → bootstack-0.4.1}/tests/test_dialog_anchor.py +0 -0
  486. {bootstack-0.3.2 → bootstack-0.4.1}/tests/test_events_doc_coverage.py +0 -0
  487. {bootstack-0.3.2 → bootstack-0.4.1}/tests/test_hot_reload.py +0 -0
  488. {bootstack-0.3.2 → bootstack-0.4.1}/tests/test_images.py +0 -0
  489. {bootstack-0.3.2 → bootstack-0.4.1}/tests/test_images_gui.py +0 -0
  490. {bootstack-0.3.2 → bootstack-0.4.1}/tests/test_intl_format.py +0 -0
  491. {bootstack-0.3.2 → bootstack-0.4.1}/tests/test_navmodel.py +0 -0
  492. {bootstack-0.3.2 → bootstack-0.4.1}/tests/test_on_color_contrast.py +0 -0
  493. {bootstack-0.3.2 → bootstack-0.4.1}/tests/test_public_surface.py +0 -0
  494. {bootstack-0.3.2 → bootstack-0.4.1}/tests/test_store.py +0 -0
  495. {bootstack-0.3.2 → bootstack-0.4.1}/tests/test_theme_from_existing.py +0 -0
  496. {bootstack-0.3.2 → bootstack-0.4.1}/tests/test_validation_rules.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bootstack
3
- Version: 0.3.2
3
+ Version: 0.4.1
4
4
  Summary: Build desktop GUI apps in pure Python and ship them as a standalone executable — built on Tk, no Tkinter boilerplate.
5
5
  Author-email: Israel Dryer <israel.dryer@gmail.com>
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "bootstack"
7
- version = "0.3.2"
7
+ version = "0.4.1"
8
8
  description = "Build desktop GUI apps in pure Python and ship them as a standalone executable — built on Tk, no Tkinter boilerplate."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -114,7 +114,7 @@ where = ["src"]
114
114
  ]
115
115
 
116
116
  [tool.bumpversion]
117
- current_version = "0.3.2"
117
+ current_version = "0.4.1"
118
118
  parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)((?P<pre>a|b|rc)(?P<pre_n>\\d+))?"
119
119
  serialize = [
120
120
  "{major}.{minor}.{patch}{pre}{pre_n}",
@@ -2,7 +2,6 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from . import colorutils, publisher, capabilities
6
5
  from bootstack._core.exceptions import (
7
6
  ThemeError,
8
7
  NavigationError,
@@ -11,9 +10,6 @@ from bootstack._core.exceptions import (
11
10
  )
12
11
 
13
12
  __all__ = [
14
- "colorutils",
15
- "publisher",
16
- "capabilities",
17
13
  "ThemeError",
18
14
  "NavigationError",
19
15
  "StyleBuilderError",
@@ -0,0 +1,387 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Mapping, Any, Callable, TypedDict, Unpack, Self
4
+
5
+
6
+ class ClipboardKwargs(TypedDict, total=False):
7
+ """Keyword options accepted by clipboard operations."""
8
+
9
+ displayof: Any
10
+ """Widget or window whose display to target. Omit for the main application display."""
11
+ type: str
12
+ """Clipboard type name (e.g., `'STRING'`, `'UTF8_STRING'`). Platform-dependent."""
13
+ format: str
14
+ """Data format for representing selection data to the X server (e.g., `'STRING'`). Platform-dependent."""
15
+
16
+
17
+ class GridKwargs(TypedDict, total=False):
18
+ """Keyword options for `grid()` and `grid_configure()`."""
19
+
20
+ row: int
21
+ """Row index (0-based). Defaults to the next available row."""
22
+ column: int
23
+ """Column index (0-based). Defaults to 0."""
24
+ rowspan: int
25
+ """Number of rows to span. Defaults to 1."""
26
+ columnspan: int
27
+ """Number of columns to span. Defaults to 1."""
28
+ sticky: str
29
+ """How the widget expands within its cell (e.g., `'nsew'`, `'ew'`, `'n'`). Defaults to `''`."""
30
+ padx: int | tuple[int, int]
31
+ """Horizontal external padding in pixels. A tuple sets (left, right) independently."""
32
+ pady: int | tuple[int, int]
33
+ """Vertical external padding in pixels. A tuple sets (top, bottom) independently."""
34
+ ipadx: int
35
+ """Horizontal internal padding in pixels."""
36
+ ipady: int
37
+ """Vertical internal padding in pixels."""
38
+ in_: Any
39
+ """Parent widget to grid into (rarely needed — defaults to the widget's own master)."""
40
+
41
+
42
+ class GridRowColumnKwargs(TypedDict, total=False):
43
+ """Keyword options for `grid_rowconfigure()` and `grid_columnconfigure()`."""
44
+
45
+ weight: int
46
+ """How extra space is distributed among rows/columns. 0 means no expansion. Defaults to 0."""
47
+ minsize: int
48
+ """Minimum row/column size in pixels. Defaults to 0."""
49
+ pad: int
50
+ """Extra padding added to the row/column in pixels. Defaults to 0."""
51
+ uniform: str
52
+ """Group name — rows/columns sharing a group are given equal size."""
53
+
54
+
55
+ class PackKwargs(TypedDict, total=False):
56
+ """Keyword options for `pack()` and `pack_configure()`."""
57
+
58
+ side: str
59
+ """Side to pack against — `'top'`, `'bottom'`, `'left'`, or `'right'`. Defaults to `'top'`."""
60
+ fill: str
61
+ """How to fill extra space — `'x'`, `'y'`, `'both'`, or `'none'`. Defaults to `'none'`."""
62
+ expand: bool | int
63
+ """If True/1, the widget expands to fill extra space in the packing direction. Defaults to False."""
64
+ anchor: str
65
+ """Where to place the widget when it does not fill available space (e.g., `'center'`, `'nw'`). Defaults to `'center'`."""
66
+ padx: int | tuple[int, int]
67
+ """Horizontal external padding in pixels. A tuple sets (left, right) independently."""
68
+ pady: int | tuple[int, int]
69
+ """Vertical external padding in pixels. A tuple sets (top, bottom) independently."""
70
+ ipadx: int
71
+ """Horizontal internal padding in pixels."""
72
+ ipady: int
73
+ """Vertical internal padding in pixels."""
74
+ before: Any
75
+ """Pack this widget immediately before the given widget."""
76
+ after: Any
77
+ """Pack this widget immediately after the given widget."""
78
+ in_: Any
79
+ """Parent widget to pack into (rarely needed — defaults to the widget's own master)."""
80
+
81
+
82
+ class WidgetCapabilitiesMixin:
83
+ """Common widget API surface (tk + ttk).
84
+
85
+ This mixin aggregates documented capability mixins into a single interface
86
+ suitable for both Tk and ttk widgets, plus a small set of commonly used
87
+ widget operations (configure/cget/destroy, stacking order, etc.).
88
+ """
89
+
90
+ # -------------------------------------------------------------------------
91
+ # Lifecycle
92
+ # -------------------------------------------------------------------------
93
+
94
+ def destroy(self) -> None:
95
+ """Destroy this widget and release its Tk resources."""
96
+ return super().destroy() # type: ignore[misc]
97
+
98
+ # -------------------------------------------------------------------------
99
+ # Configuration
100
+ # -------------------------------------------------------------------------
101
+
102
+ def configure(self, cnf: Mapping[str, Any] | None = None, **kw: Any) -> Any:
103
+ """Configure widget options.
104
+
105
+ Args:
106
+ cnf: Optional mapping of option values.
107
+ **kw: Option values as keyword arguments.
108
+
109
+ Returns:
110
+ Tk returns configuration details when called with no args; otherwise
111
+ the return value is implementation-dependent.
112
+ """
113
+ if cnf is None:
114
+ return super().configure(**kw) # type: ignore[misc]
115
+ return super().configure(cnf, **kw) # type: ignore[misc]
116
+
117
+ config = configure
118
+
119
+ def cget(self, key: str) -> Any:
120
+ """Return the current value for an option.
121
+
122
+ Args:
123
+ key: Option name (with or without a leading dash).
124
+
125
+ Returns:
126
+ The option value.
127
+ """
128
+ return super().cget(key) # type: ignore[misc]
129
+
130
+ # -------------------------------------------------------------------------
131
+ # Stacking order
132
+ # -------------------------------------------------------------------------
133
+
134
+ def lift(self, aboveThis: Any | None = None) -> None:
135
+ """Raise this widget above its siblings.
136
+
137
+ Args:
138
+ aboveThis: Optional sibling widget to raise above.
139
+ """
140
+ return super().lift(aboveThis) # type: ignore[misc]
141
+
142
+ tkraise = lift
143
+
144
+ def lower(self, belowThis: Any | None = None) -> None:
145
+ """Lower this widget below its siblings.
146
+
147
+ Args:
148
+ belowThis: Optional sibling widget to lower below.
149
+ """
150
+ return super().lower(belowThis) # type: ignore[misc]
151
+
152
+ def after_repeat(
153
+ self, ms: int, func: Callable[..., Any], *args: Any
154
+ ) -> Callable[[], None]:
155
+ """Call `func` repeatedly every `ms` milliseconds.
156
+
157
+ This helper schedules `func` and then automatically reschedules it after
158
+ each run. It returns a `cancel()` function you can call to stop repetition.
159
+
160
+ Args:
161
+ ms: Interval in milliseconds.
162
+ func: Callback to run each interval.
163
+ *args: Arguments to pass to `func`.
164
+
165
+ Returns:
166
+ A `cancel()` callable. Call it to stop the repeating schedule.
167
+
168
+ Examples:
169
+ >>> cancel = widget.after_repeat(250, tick)
170
+ >>> cancel()
171
+ """
172
+ cancelled = False
173
+ token: str | None = None
174
+
175
+ def _run():
176
+ nonlocal token
177
+ if cancelled:
178
+ return
179
+ func(*args)
180
+ token = self.after(ms, _run)
181
+
182
+ token = self.after(ms, _run)
183
+
184
+ def cancel() -> None:
185
+ nonlocal cancelled, token
186
+ cancelled = True
187
+ if token is not None:
188
+ try:
189
+ self.after_cancel(token)
190
+ except Exception:
191
+ pass
192
+ token = None
193
+
194
+ return cancel
195
+
196
+ def bindtags_prepend(self, tag: str) -> tuple[str, ...]:
197
+ """Prepend a tag to the bindtags list.
198
+
199
+ This increases the tag's priority (it will be processed earlier).
200
+
201
+ Args:
202
+ tag: Tag name to prepend.
203
+
204
+ Returns:
205
+ The updated bindtags tuple.
206
+ """
207
+ current = list(self.bindtags())
208
+ if tag not in current:
209
+ current.insert(0, tag)
210
+ self.bindtags(current)
211
+ return tuple(current)
212
+
213
+ def bindtags_append(self, tag: str) -> tuple[str, ...]:
214
+ """Append a tag to the bindtags list.
215
+
216
+ This decreases the tag's priority (it will be processed later).
217
+
218
+ Args:
219
+ tag: Tag name to append.
220
+
221
+ Returns:
222
+ The updated bindtags tuple.
223
+ """
224
+ current = list(self.bindtags())
225
+ if tag not in current:
226
+ current.append(tag)
227
+ self.bindtags(current)
228
+ return tuple(current)
229
+
230
+ def bindtags_remove(self, tag: str) -> tuple[str, ...]:
231
+ """Remove a tag from the bindtags list.
232
+
233
+ Args:
234
+ tag: Tag name to remove.
235
+
236
+ Returns:
237
+ The updated bindtags tuple.
238
+ """
239
+ current = [t for t in self.bindtags() if t != tag]
240
+ self.bindtags(current)
241
+ return tuple(current)
242
+
243
+ def bindtags_replace(self, old: str, new: str) -> tuple[str, ...]:
244
+ """Replace a bindtag with another tag.
245
+
246
+ Args:
247
+ old: Existing tag name.
248
+ new: Replacement tag name.
249
+
250
+ Returns:
251
+ The updated bindtags tuple.
252
+ """
253
+ current = list(self.bindtags())
254
+ try:
255
+ idx = current.index(old)
256
+ except ValueError:
257
+ return tuple(current)
258
+ current[idx] = new
259
+ self.bindtags(current)
260
+ return tuple(current)
261
+
262
+ def clipboard_set(self, text: str, **kw: Unpack[ClipboardKwargs]) -> None:
263
+ """Replace clipboard contents with *text*.
264
+
265
+ Convenience wrapper for `clipboard_clear()` + `clipboard_append()`.
266
+
267
+ Args:
268
+ text: Text to set on the clipboard.
269
+ **kw: See `ClipboardKwargs`. Forwarded to both clear and append.
270
+ """
271
+ self.clipboard_clear(**kw)
272
+ self.clipboard_append(text, **kw)
273
+
274
+ def grid(self, cnf: dict[str, Any] | None = None, **kw: Unpack[GridKwargs]) -> Self:
275
+ """Position this widget using the grid geometry manager.
276
+
277
+ Args:
278
+ cnf: Optional dict of grid options (same keys as `GridKwargs`).
279
+ **kw: See `GridKwargs`.
280
+
281
+ Returns:
282
+ Self for method chaining.
283
+ """
284
+ options = cnf or {}
285
+ options.update(kw)
286
+
287
+ parent = self.master # type: ignore[attr-defined]
288
+ if hasattr(parent, "_on_child_grid"):
289
+ parent._on_child_grid(self, **options)
290
+ else:
291
+ super().grid(**options) # type: ignore[misc]
292
+ return self # type: ignore[return-value]
293
+
294
+ def grid_configure(
295
+ self, cnf: dict[str, Any] | None = None, **kw: Unpack[GridKwargs]
296
+ ) -> Self:
297
+ """Alias for `grid()`.
298
+
299
+ Args:
300
+ cnf: Optional dict of grid options.
301
+ **kw: See `GridKwargs`.
302
+
303
+ Returns:
304
+ Self for method chaining.
305
+ """
306
+ return self.grid(cnf, **kw)
307
+
308
+ def grid_forget(self) -> Self:
309
+ """Unmap this widget and forget its grid configuration.
310
+
311
+ The widget is removed from the layout, and its previous grid options
312
+ are discarded.
313
+
314
+ Returns:
315
+ Self for method chaining.
316
+ """
317
+ parent = self.master # type: ignore[attr-defined]
318
+ if hasattr(parent, "_on_child_grid_forget"):
319
+ parent._on_child_grid_forget(self)
320
+ else:
321
+ super().grid_forget() # type: ignore[misc]
322
+ return self # type: ignore[return-value]
323
+
324
+ def grid_remove(self) -> Self:
325
+ """Unmap this widget but remember its grid configuration.
326
+
327
+ Use `grid()` with no args to restore it to its previous grid location.
328
+
329
+ Returns:
330
+ Self for method chaining.
331
+ """
332
+ parent = self.master # type: ignore[attr-defined]
333
+ if hasattr(parent, "_on_child_grid_remove"):
334
+ parent._on_child_grid_remove(self)
335
+ else:
336
+ super().grid_remove() # type: ignore[misc]
337
+ return self # type: ignore[return-value]
338
+
339
+ def pack(self, cnf: dict[str, Any] | None = None, **kw: Unpack[PackKwargs]) -> Self:
340
+ """Position this widget using the pack geometry manager.
341
+
342
+ Args:
343
+ cnf: Optional dict of pack options (same keys as `PackKwargs`).
344
+ **kw: See `PackKwargs`.
345
+
346
+ Returns:
347
+ Self for method chaining.
348
+ """
349
+ options = cnf or {}
350
+ options.update(kw)
351
+
352
+ parent = self.master # type: ignore[attr-defined]
353
+ if hasattr(parent, "_on_child_pack"):
354
+ parent._on_child_pack(self, **options)
355
+ else:
356
+ super().pack(**options) # type: ignore[misc]
357
+ return self # type: ignore[return-value]
358
+
359
+ def pack_configure(
360
+ self, cnf: dict[str, Any] | None = None, **kw: Unpack[PackKwargs]
361
+ ) -> Self:
362
+ """Alias for `pack()`.
363
+
364
+ Args:
365
+ cnf: Optional dict of pack options.
366
+ **kw: See `PackKwargs`.
367
+
368
+ Returns:
369
+ Self for method chaining.
370
+ """
371
+ return self.pack(cnf, **kw)
372
+
373
+ def pack_forget(self) -> Self:
374
+ """Unmap this widget and forget its pack configuration.
375
+
376
+ The widget is removed from the layout, and its previous pack options
377
+ are discarded.
378
+
379
+ Returns:
380
+ Self for method chaining.
381
+ """
382
+ parent = self.master # type: ignore[attr-defined]
383
+ if hasattr(parent, "_on_child_pack_forget"):
384
+ parent._on_child_pack_forget(self)
385
+ else:
386
+ super().pack_forget() # type: ignore[misc]
387
+ return self # type: ignore[return-value]
@@ -157,7 +157,8 @@ def create_signal(default_value: Any) -> SignalBinding:
157
157
  0.0
158
158
  """
159
159
  from bootstack.signals import Signal
160
- signal = Signal(default_value)
160
+ # (str, set) mirrors Signal._empty_value()'s own rule
161
+ signal = Signal(default_value, allow_empty=isinstance(default_value, (str, set)))
161
162
  return SignalBinding(
162
163
  signal=signal,
163
164
  variable=signal.var,
@@ -19,7 +19,6 @@ from typing_extensions import Unpack
19
19
  from bootstack.constants import *
20
20
  from bootstack.i18n.intl_format import detect_locale
21
21
  from bootstack.i18n.msgcat import MessageCatalog
22
- from bootstack._core.publisher import Publisher
23
22
  from bootstack._core.mixins.widget import WidgetCapabilitiesMixin
24
23
  from bootstack._runtime.base_window import BaseWindow
25
24
  from bootstack._runtime.utility import enable_high_dpi_awareness
@@ -156,7 +155,6 @@ def apply_class_bindings(window: tkinter.Widget | App) -> None:
156
155
  def apply_all_bindings(window: tkinter.Widget | App) -> None:
157
156
  """Add bindings to all widgets in the application"""
158
157
  window.bind_all('<Map>', on_map_child, '+')
159
- window.bind_all('<Destroy>', lambda e: Publisher.unsubscribe(e.widget))
160
158
 
161
159
 
162
160
  def on_disabled_readonly_state(event: tkinter.Event) -> None:
@@ -382,10 +380,6 @@ class App(BaseWindow, WidgetCapabilitiesMixin, tkinter.Tk):
382
380
  """The primary application window and entry point.
383
381
 
384
382
  App adds theming, localization, and platform setup on top of `tkinter.Tk`.
385
-
386
- The standard widget API (events, scheduling, clipboard, geometry managers,
387
- winfo, etc.) is documented under bootstack capabilities and is available
388
- on App via inheritance.
389
383
  """
390
384
 
391
385
  def __init__(
@@ -5,9 +5,6 @@ window management functionality used by both the main App and Toplevel classes.
5
5
  This eliminates code duplication and ensures consistent behavior across all
6
6
  window types.
7
7
 
8
- Standard widget APIs (events, scheduling, clipboard, geometry managers, winfo) are documented under capabilities and are
9
- available through normal Tk/Ttk inheritance.”
10
-
11
8
  The BaseWindow mixin provides:
12
9
  - Window manager (wm) pass-throughs with modern docstrings
13
10
  - Window configuration (size, position, constraints)
@@ -0,0 +1,109 @@
1
+ """Modal grab capture and restore, shared by the dialog and window paths.
2
+
3
+ Tk releases a grab when the window holding it is destroyed, but it does NOT
4
+ restore the grab that window displaced. Anything that takes a modal grab has to
5
+ hand back what it found, or the window underneath is left on screen, still
6
+ blocking its caller, holding nothing (#440 for dialogs, #444 for windows).
7
+
8
+ These live here rather than beside the dialogs because the import direction runs
9
+ dialogs -> _runtime: `dialogs/_impl/dialog.py` imports `Toplevel` from this
10
+ package, so `_runtime` reaching back the other way would be a cycle.
11
+ """
12
+ from __future__ import annotations
13
+
14
+ import tkinter
15
+ from typing import Any
16
+
17
+ def capture_grab(widget: Any) -> tuple[Any, str | None] | None:
18
+ """Record who holds the modal grab and HOW, for `restore_grab` to hand back.
19
+
20
+ Returns `None` when nothing holds the grab — the outermost case, which needs
21
+ no restore. Otherwise returns the holder paired with its grab KIND.
22
+
23
+ ⚠ Call this BEFORE taking the grab. Once another window grabs, the previous
24
+ holder's `grab_status()` reads `None`, so a kind read afterwards is always
25
+ wrong — measured, and the reason this pairing exists as one function rather
26
+ than two steps a caller has to sequence correctly.
27
+
28
+ The kind matters because Tk has two: `bs.Window(modal="app")` takes a GLOBAL
29
+ grab, and restoring that as a local one silently narrows the window's
30
+ modality (it would block only this application). Reading the kind back from
31
+ Tk rather than assuming it keeps this correct on every window system without
32
+ a platform branch — whatever Tk reported, we hand back.
33
+
34
+ A holder this cannot ADDRESS reads the same as no holder at all. Resolving
35
+ who holds the grab goes through a name lookup that raises for a window the
36
+ toolkit created on its own — a posted combobox popdown is one — and there is
37
+ nothing to hand back to a window we cannot name. This runs on the SETUP path,
38
+ where a raise would escape into the application, so it degrades to `None` and
39
+ logs rather than propagating.
40
+ """
41
+ try:
42
+ holder = widget.grab_current()
43
+ except (AttributeError, KeyError, tkinter.TclError):
44
+ _log_grab_failure("could not identify the current grab holder")
45
+ return None
46
+ if holder is None:
47
+ return None
48
+ try:
49
+ kind = holder.grab_status()
50
+ except (AttributeError, tkinter.TclError):
51
+ # Fall back to the narrower grab rather than guessing global.
52
+ kind = "local"
53
+ return (holder, kind)
54
+
55
+
56
+ def restore_grab(previous: tuple[Any, str | None] | None) -> None:
57
+ """Hand the modal grab back to whatever held it before the caller took it.
58
+
59
+ Tk releases a grab when the window holding it is destroyed, but it does NOT
60
+ restore the grab that window displaced. So a modal opened from inside
61
+ another modal — `bs.alert()` from a dialog button command, or a
62
+ `bs.Window(modal=True)` opened from a dialog's "Advanced..." button — took
63
+ the grab over and then dropped it on the floor when it closed. The OUTER
64
+ window was left on screen and still blocking its caller, yet holding no
65
+ grab at all: the user could click straight back into the main window and
66
+ drive the app underneath it, against something that was modal in appearance
67
+ only (issue #440 for dialogs, #444 for windows).
68
+
69
+ Pass the token `capture_grab()` returned. `None` means nothing held the
70
+ grab, which is the outermost case and needs no restore.
71
+
72
+ A failure here is deliberately swallowed. This runs on a teardown path,
73
+ where the previous holder may itself have been destroyed while the inner
74
+ window was up, or the whole interpreter may be going down — and something
75
+ that has already closed must not raise on its way out. It is LOGGED rather
76
+ than passed over in silence, because a failed restore is the very defect
77
+ this function exists to prevent: the outer window stays on screen holding
78
+ nothing.
79
+
80
+ ⚠ A global restore can fail where a local one cannot — `grab set -global`
81
+ is the call Tk's viewability rule guards, and on X11 it can also lose to
82
+ another client. That is the one way this is riskier than always restoring
83
+ a local grab, so a failed global restore DEGRADES TO LOCAL rather than to
84
+ nothing: modal within the application is imperfect, but it is not the #440
85
+ symptom.
86
+ """
87
+ if previous is None:
88
+ return
89
+ holder, kind = previous
90
+ try:
91
+ if not holder.winfo_exists():
92
+ return
93
+ if kind == "global":
94
+ try:
95
+ holder.grab_set_global()
96
+ except tkinter.TclError:
97
+ _log_grab_failure("could not restore a global grab; falling back to local")
98
+ holder.grab_set()
99
+ else:
100
+ holder.grab_set()
101
+ except (AttributeError, tkinter.TclError):
102
+ _log_grab_failure("could not restore the previous grab holder")
103
+
104
+
105
+ def _log_grab_failure(message: str) -> None:
106
+ """Report a grab failure without ever raising from a teardown path."""
107
+ from bootstack._runtime.utility import debug_log_exception
108
+
109
+ debug_log_exception(message)
@@ -7,6 +7,7 @@ from typing import Any, Callable, Literal, Optional, Tuple
7
7
 
8
8
  from bootstack._core.mixins.widget import WidgetCapabilitiesMixin
9
9
  from bootstack._runtime.base_window import BaseWindow
10
+ from bootstack._runtime.grab import capture_grab, restore_grab
10
11
 
11
12
 
12
13
  class Toplevel(BaseWindow, WidgetCapabilitiesMixin, tkinter.Toplevel):
@@ -15,10 +16,6 @@ class Toplevel(BaseWindow, WidgetCapabilitiesMixin, tkinter.Toplevel):
15
16
  This class wraps `tkinter.Toplevel` and adds bootstack window conveniences
16
17
  (title/geometry helpers, centering, alpha/topmost/toolwindow helpers, etc.).
17
18
 
18
- The standard widget API (events, scheduling, clipboard, geometry managers,
19
- winfo, etc.) is available through inheritance and is documented under
20
- bootstack capabilities.
21
-
22
19
  For additional information on the underlying Tk/Tkinter behavior, see:
23
20
  - Tcl/Tk `toplevel` command documentation
24
21
  - Python `tkinter.Toplevel` documentation
@@ -107,6 +104,10 @@ class Toplevel(BaseWindow, WidgetCapabilitiesMixin, tkinter.Toplevel):
107
104
  # modal level — stored for use in show()
108
105
  self._modal = modal
109
106
 
107
+ # Grab handed back when this window is destroyed; see show().
108
+ self._previous_grab: tuple[Any, str | None] | None = None
109
+ self._grab_restore_bound = False
110
+
110
111
  # Apply Aqua MacWindowStyle BEFORE any setup that might pump the
111
112
  # event loop (icons, geometry, update_idletasks). Tk's docs require
112
113
  # the style to be set on a freshly-created, never-mapped window;
@@ -223,15 +224,60 @@ class Toplevel(BaseWindow, WidgetCapabilitiesMixin, tkinter.Toplevel):
223
224
  """Show the window and apply modal grab if configured."""
224
225
  super().show()
225
226
  if self._modal:
227
+ # Remember who held the grab, and how, so it can be handed back when
228
+ # this window goes away. Tk drops a grab on destroy but never
229
+ # restores the one it displaced, so a modal opened from inside
230
+ # another modal used to leave its opener on screen, still blocking
231
+ # its caller, holding nothing at all (#444 — #440 fixed the same
232
+ # defect on the dialog path). Captured BEFORE the grab: once another
233
+ # window grabs, the previous holder's grab_status() reads None.
234
+ #
235
+ # Captured ONCE. show() is re-callable — show(anchor_to=) re-anchors
236
+ # an open window and block_until_closed() shows it itself — and a
237
+ # later capture finds this window already holding the grab, so it
238
+ # would record the window as its own previous holder.
239
+ if not self._grab_restore_bound:
240
+ self._previous_grab = capture_grab(self)
226
241
  try:
227
242
  if self._modal == "app":
228
243
  self.grab_set_global()
229
244
  else:
230
245
  self.grab_set()
246
+ except tkinter.TclError:
247
+ pass
248
+ else:
249
+ # Owed because the grab was TAKEN, so bound off the grab alone —
250
+ # focus gets its own guard rather than standing between the two.
251
+ self._bind_grab_restore()
252
+ try:
231
253
  self.focus_set()
232
254
  except tkinter.TclError:
233
255
  pass
234
256
 
257
+ def _bind_grab_restore(self) -> None:
258
+ """Hand the displaced grab back when this window is destroyed.
259
+
260
+ Bound on destroy rather than paired around `block_until_closed()`,
261
+ because a modal window does not have to block — `show()` followed by a
262
+ later `destroy()` is an ordinary path, and pairing on the blocking one
263
+ alone would leave it unfixed. Measured before choosing it: the restore
264
+ wins its race with Tk's own grab release, so `grab_current()` reads the
265
+ opener again once the dust settles
266
+ (`development/probe_444_grab_restore_ordering.py`).
267
+ """
268
+ if self._grab_restore_bound:
269
+ return
270
+ self._grab_restore_bound = True
271
+
272
+ def _restore(event: Any) -> None:
273
+ # <Destroy> fires for every descendant, not just the window.
274
+ if event.widget is not self:
275
+ return
276
+ restore_grab(self._previous_grab)
277
+ self._previous_grab = None
278
+
279
+ self.bind("<Destroy>", _restore, add="+")
280
+
235
281
  # -------------------------------------------------------------------------
236
282
  # result property + block_until_closed()
237
283
  # -------------------------------------------------------------------------