bootstack 0.4.5__tar.gz → 0.4.7__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 (480) hide show
  1. {bootstack-0.4.5/src/bootstack.egg-info → bootstack-0.4.7}/PKG-INFO +1 -1
  2. {bootstack-0.4.5 → bootstack-0.4.7}/pyproject.toml +2 -2
  3. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/_runtime/app.py +4 -0
  4. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/_runtime/wheel.py +6 -0
  5. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/_parts/numberentry_part.py +6 -6
  6. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/contextmenu.py +21 -0
  7. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/numericentry.py +13 -8
  8. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/selectbox.py +47 -5
  9. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/tableview/tableview.py +2 -1
  10. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/tabs/tabitem.py +13 -3
  11. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/textarea/core.py +1 -12
  12. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/textarea/extensions/smart_indent.py +4 -1
  13. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/textarea/textarea.py +4 -1
  14. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/tree/treeitem.py +7 -0
  15. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/primitives/spinbox.py +5 -3
  16. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/numberfield.py +6 -4
  17. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/select.py +5 -1
  18. {bootstack-0.4.5 → bootstack-0.4.7/src/bootstack.egg-info}/PKG-INFO +1 -1
  19. {bootstack-0.4.5 → bootstack-0.4.7}/LICENSE +0 -0
  20. {bootstack-0.4.5 → bootstack-0.4.7}/MANIFEST.in +0 -0
  21. {bootstack-0.4.5 → bootstack-0.4.7}/NOTICE +0 -0
  22. {bootstack-0.4.5 → bootstack-0.4.7}/README.md +0 -0
  23. {bootstack-0.4.5 → bootstack-0.4.7}/setup.cfg +0 -0
  24. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/__init__.py +0 -0
  25. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/__main__.py +0 -0
  26. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/_core/__init__.py +0 -0
  27. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/_core/capture.py +0 -0
  28. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/_core/exceptions.py +0 -0
  29. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/_core/images.py +0 -0
  30. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/_core/localization.py +0 -0
  31. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/_core/mixins/__init__.py +0 -0
  32. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/_core/mixins/ttk_state.py +0 -0
  33. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/_core/mixins/widget.py +0 -0
  34. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/_core/paths.py +0 -0
  35. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/_core/signal_binding.py +0 -0
  36. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/_core/variables.py +0 -0
  37. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/_runtime/__init__.py +0 -0
  38. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/_runtime/base_window.py +0 -0
  39. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/_runtime/events.py +0 -0
  40. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/_runtime/grab.py +0 -0
  41. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/_runtime/shortcuts.py +0 -0
  42. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/_runtime/tk_patch.py +0 -0
  43. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/_runtime/toplevel.py +0 -0
  44. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/_runtime/utility.py +0 -0
  45. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/_runtime/visual_focus.py +0 -0
  46. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/_runtime/window_utilities.py +0 -0
  47. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/__init__.py +0 -0
  48. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/bootstack.ico +0 -0
  49. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/bootstack.png +0 -0
  50. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/__init__.py +0 -0
  51. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/badge-pill.png +0 -0
  52. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/badge-square.png +0 -0
  53. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/button-compact.png +0 -0
  54. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/button-default.png +0 -0
  55. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/buttongroup-after-h-compact.png +0 -0
  56. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/buttongroup-after-h-default.png +0 -0
  57. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/buttongroup-after-v-compact.png +0 -0
  58. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/buttongroup-after-v-default.png +0 -0
  59. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/buttongroup-before-h-compact.png +0 -0
  60. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/buttongroup-before-h-default.png +0 -0
  61. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/buttongroup-before-v-compact.png +0 -0
  62. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/buttongroup-before-v-default.png +0 -0
  63. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/buttongroup-center-h-compact.png +0 -0
  64. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/buttongroup-center-h-default.png +0 -0
  65. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/buttongroup-center-v-compact.png +0 -0
  66. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/buttongroup-center-v-default.png +0 -0
  67. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/card.png +0 -0
  68. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/checkbox-checked.png +0 -0
  69. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/checkbox-indeterminate.png +0 -0
  70. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/checkbox-unchecked.png +0 -0
  71. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/field.png +0 -0
  72. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/input-addon-compact.png +0 -0
  73. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/input-addon-default.png +0 -0
  74. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/input-compact.png +0 -0
  75. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/input-default.png +0 -0
  76. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/list-item-separated.png +0 -0
  77. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/list-item.png +0 -0
  78. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/listrow-compact.png +0 -0
  79. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/listrow-default.png +0 -0
  80. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/manifest.toml +0 -0
  81. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/menu-item.png +0 -0
  82. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/navitem-compact.png +0 -0
  83. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/navitem-default.png +0 -0
  84. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/progressbar-h-compact.png +0 -0
  85. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/progressbar-h-default.png +0 -0
  86. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/progressbar-v-compact.png +0 -0
  87. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/progressbar-v-default.png +0 -0
  88. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/radiobutton.png +0 -0
  89. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/scrollbar-horizontal.png +0 -0
  90. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/scrollbar-vertical.png +0 -0
  91. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/slider-handle.png +0 -0
  92. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/slider-track-h.png +0 -0
  93. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/slider-track-v.png +0 -0
  94. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/switch-off.png +0 -0
  95. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/switch-on.png +0 -0
  96. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/tab-h.png +0 -0
  97. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/elements/tab-v.png +0 -0
  98. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/icons/bootstrap.ttf +0 -0
  99. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/icons/glyphmap.json +0 -0
  100. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/icons/icon_metrics.json +0 -0
  101. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/ar/LC_MESSAGES/bootstack.mo +0 -0
  102. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/ar/LC_MESSAGES/bootstack.po +0 -0
  103. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/bg/LC_MESSAGES/bootstack.mo +0 -0
  104. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/bg/LC_MESSAGES/bootstack.po +0 -0
  105. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/cs/LC_MESSAGES/bootstack.mo +0 -0
  106. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/cs/LC_MESSAGES/bootstack.po +0 -0
  107. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/da/LC_MESSAGES/bootstack.mo +0 -0
  108. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/da/LC_MESSAGES/bootstack.po +0 -0
  109. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/de/LC_MESSAGES/bootstack.mo +0 -0
  110. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/de/LC_MESSAGES/bootstack.po +0 -0
  111. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/en/LC_MESSAGES/bootstack.mo +0 -0
  112. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/en/LC_MESSAGES/bootstack.po +0 -0
  113. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/es/LC_MESSAGES/bootstack.mo +0 -0
  114. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/es/LC_MESSAGES/bootstack.po +0 -0
  115. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/fr/LC_MESSAGES/bootstack.mo +0 -0
  116. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/fr/LC_MESSAGES/bootstack.po +0 -0
  117. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/he/LC_MESSAGES/bootstack.mo +0 -0
  118. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/he/LC_MESSAGES/bootstack.po +0 -0
  119. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/hi/LC_MESSAGES/bootstack.mo +0 -0
  120. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/hi/LC_MESSAGES/bootstack.po +0 -0
  121. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/it/LC_MESSAGES/bootstack.mo +0 -0
  122. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/it/LC_MESSAGES/bootstack.po +0 -0
  123. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/ja/LC_MESSAGES/bootstack.mo +0 -0
  124. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/ja/LC_MESSAGES/bootstack.po +0 -0
  125. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/ko/LC_MESSAGES/bootstack.mo +0 -0
  126. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/ko/LC_MESSAGES/bootstack.po +0 -0
  127. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/nb/LC_MESSAGES/bootstack.mo +0 -0
  128. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/nb/LC_MESSAGES/bootstack.po +0 -0
  129. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/nl/LC_MESSAGES/bootstack.mo +0 -0
  130. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/nl/LC_MESSAGES/bootstack.po +0 -0
  131. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/pl/LC_MESSAGES/bootstack.mo +0 -0
  132. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/pl/LC_MESSAGES/bootstack.po +0 -0
  133. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/pt/LC_MESSAGES/bootstack.mo +0 -0
  134. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/pt/LC_MESSAGES/bootstack.po +0 -0
  135. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.mo +0 -0
  136. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.po +0 -0
  137. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/sl/LC_MESSAGES/bootstack.mo +0 -0
  138. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/sl/LC_MESSAGES/bootstack.po +0 -0
  139. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/sv/LC_MESSAGES/bootstack.mo +0 -0
  140. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/sv/LC_MESSAGES/bootstack.po +0 -0
  141. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/tr/LC_MESSAGES/bootstack.mo +0 -0
  142. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/tr/LC_MESSAGES/bootstack.po +0 -0
  143. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.mo +0 -0
  144. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.po +0 -0
  145. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.mo +0 -0
  146. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.po +0 -0
  147. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/cli/__init__.py +0 -0
  148. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/cli/__main__.py +0 -0
  149. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/cli/add.py +0 -0
  150. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/cli/appicon.py +0 -0
  151. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/cli/build.py +0 -0
  152. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/cli/config.py +0 -0
  153. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/cli/demo.py +0 -0
  154. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/cli/dev.py +0 -0
  155. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/cli/doctor.py +0 -0
  156. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/cli/icons.py +0 -0
  157. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/cli/promote.py +0 -0
  158. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/cli/pyinstaller.py +0 -0
  159. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/cli/run.py +0 -0
  160. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/cli/start.py +0 -0
  161. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/cli/templates/__init__.py +0 -0
  162. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/clipboard.py +0 -0
  163. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/constants.py +0 -0
  164. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/data/README.md +0 -0
  165. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/data/__init__.py +0 -0
  166. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/data/_observable.py +0 -0
  167. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/data/base.py +0 -0
  168. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/data/file_source.py +0 -0
  169. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/data/memory_source.py +0 -0
  170. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/data/query.py +0 -0
  171. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/data/readers.py +0 -0
  172. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/data/sqlite_source.py +0 -0
  173. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/data/types.py +0 -0
  174. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/data/writers.py +0 -0
  175. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/dev/__init__.py +0 -0
  176. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/dev/_capture.py +0 -0
  177. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/dev/_env.py +0 -0
  178. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/dev/_registry.py +0 -0
  179. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/dev/_reloader.py +0 -0
  180. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/dev/_reset.py +0 -0
  181. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/dev/_watcher.py +0 -0
  182. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/dialogs/__init__.py +0 -0
  183. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/dialogs/_impl/__init__.py +0 -0
  184. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/dialogs/_impl/colorchooser.py +0 -0
  185. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/dialogs/_impl/datedialog.py +0 -0
  186. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/dialogs/_impl/dialog.py +0 -0
  187. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/dialogs/_impl/filterdialog.py +0 -0
  188. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/dialogs/_impl/fontdialog.py +0 -0
  189. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/dialogs/_impl/formdialog.py +0 -0
  190. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/dialogs/_impl/message.py +0 -0
  191. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/dialogs/_impl/query.py +0 -0
  192. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/errors.py +0 -0
  193. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/events/__init__.py +0 -0
  194. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/events/_event.py +0 -0
  195. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/events/_payloads.py +0 -0
  196. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/events/_subscription.py +0 -0
  197. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/i18n/README.md +0 -0
  198. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/i18n/__init__.py +0 -0
  199. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/i18n/catalog.py +0 -0
  200. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/i18n/intl_format.py +0 -0
  201. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/i18n/msgcat.py +0 -0
  202. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/i18n/specs.py +0 -0
  203. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/images.py +0 -0
  204. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/py.typed +0 -0
  205. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/scheduling/__init__.py +0 -0
  206. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/scheduling/_schedule.py +0 -0
  207. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/shortcuts.py +0 -0
  208. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/signals/README.md +0 -0
  209. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/signals/__init__.py +0 -0
  210. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/signals/integration.py +0 -0
  211. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/signals/signal.py +0 -0
  212. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/signals/types.py +0 -0
  213. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/store.py +0 -0
  214. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/streams/__init__.py +0 -0
  215. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/streams/_stream.py +0 -0
  216. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/__init__.py +0 -0
  217. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/__init__.py +0 -0
  218. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/badge.py +0 -0
  219. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/button.py +0 -0
  220. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/buttongroup.py +0 -0
  221. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/calendar.py +0 -0
  222. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/checkbutton.py +0 -0
  223. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/combobox.py +0 -0
  224. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/contextmenu.py +0 -0
  225. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/entry.py +0 -0
  226. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/expander.py +0 -0
  227. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/field.py +0 -0
  228. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/frame.py +0 -0
  229. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/label.py +0 -0
  230. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/labelframe.py +0 -0
  231. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/listview.py +0 -0
  232. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/menubar.py +0 -0
  233. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/menubutton.py +0 -0
  234. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/panedwindow.py +0 -0
  235. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/progressbar.py +0 -0
  236. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/radiobutton.py +0 -0
  237. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/scale.py +0 -0
  238. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/scrollbar.py +0 -0
  239. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/separator.py +0 -0
  240. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/sidenav.py +0 -0
  241. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/sizegrip.py +0 -0
  242. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/spinbox.py +0 -0
  243. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/switch.py +0 -0
  244. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/tabitem.py +0 -0
  245. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/togglegroup.py +0 -0
  246. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/toolbutton.py +0 -0
  247. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/tooltip.py +0 -0
  248. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/treeview.py +0 -0
  249. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders/utils.py +0 -0
  250. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders_tk/__init__.py +0 -0
  251. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/builders_tk/defaults.py +0 -0
  252. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/element.py +0 -0
  253. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/fonts.py +0 -0
  254. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/style.py +0 -0
  255. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/style_builder_base.py +0 -0
  256. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/style_builder_mixed.py +0 -0
  257. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/style_builder_tk.py +0 -0
  258. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/style_builder_ttk.py +0 -0
  259. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/style_resolver.py +0 -0
  260. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/theme.py +0 -0
  261. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/theme_provider.py +0 -0
  262. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/themes/__init__.py +0 -0
  263. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/tk_patch.py +0 -0
  264. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/token_maps.py +0 -0
  265. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/types.py +0 -0
  266. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/typography.py +0 -0
  267. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/style/utility.py +0 -0
  268. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/types.py +0 -0
  269. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/validation/__init__.py +0 -0
  270. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/validation/types.py +0 -0
  271. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/validation/validation_result.py +0 -0
  272. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/validation/validation_rules.py +0 -0
  273. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/__init__.py +0 -0
  274. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_core/__init__.py +0 -0
  275. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_core/app_config.py +0 -0
  276. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_core/base.py +0 -0
  277. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_core/choices.py +0 -0
  278. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_core/container.py +0 -0
  279. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_core/context.py +0 -0
  280. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_core/events.py +0 -0
  281. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_core/field_mixin.py +0 -0
  282. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_core/icon_image_props.py +0 -0
  283. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_core/image_binding.py +0 -0
  284. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_core/kwargs.py +0 -0
  285. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_core/navmodel.py +0 -0
  286. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_core/options.py +0 -0
  287. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_core/selection_group.py +0 -0
  288. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_core/window_controls.py +0 -0
  289. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_core/window_menu.py +0 -0
  290. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/__init__.py +0 -0
  291. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/_internal/__init__.py +0 -0
  292. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/_internal/wrapper_base.py +0 -0
  293. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/_parts/__init__.py +0 -0
  294. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/_parts/spinnerentry_part.py +0 -0
  295. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/_parts/textentry_part.py +0 -0
  296. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/__init__.py +0 -0
  297. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/_dateutils.py +0 -0
  298. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/_image_fit.py +0 -0
  299. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/accordion.py +0 -0
  300. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/avatar.py +0 -0
  301. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/buttongroup.py +0 -0
  302. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/calendar.py +0 -0
  303. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/carousel.py +0 -0
  304. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/chart.py +0 -0
  305. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/compositeframe.py +0 -0
  306. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/dateentry.py +0 -0
  307. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/dropdownbutton.py +0 -0
  308. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/expander.py +0 -0
  309. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/field.py +0 -0
  310. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/form.py +0 -0
  311. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/gallery.py +0 -0
  312. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/list/__init__.py +0 -0
  313. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/list/listitem.py +0 -0
  314. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/list/listview.py +0 -0
  315. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/menu/__init__.py +0 -0
  316. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/menu/model.py +0 -0
  317. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/menu/render_native.py +0 -0
  318. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/menu/render_themed.py +0 -0
  319. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/meter.py +0 -0
  320. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/pagestack.py +0 -0
  321. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/passwordentry.py +0 -0
  322. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/pathentry.py +0 -0
  323. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/picture.py +0 -0
  324. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/radiogroup.py +0 -0
  325. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/scrolledtext.py +0 -0
  326. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/scrolledtext.pyi +0 -0
  327. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/scrollview.py +0 -0
  328. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/shell/__init__.py +0 -0
  329. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/shell/content_host.py +0 -0
  330. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/shell/layout.py +0 -0
  331. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/shell/nav_panel.py +0 -0
  332. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/shell/providers.py +0 -0
  333. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/shell/rail.py +0 -0
  334. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/shell/shell.py +0 -0
  335. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/shell/workspace.py +0 -0
  336. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/sidenav/__init__.py +0 -0
  337. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/sidenav/header.py +0 -0
  338. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/sidenav/separator.py +0 -0
  339. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/slider/__init__.py +0 -0
  340. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/slider/_shared.py +0 -0
  341. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/slider/rangeslider.py +0 -0
  342. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/slider/slider.py +0 -0
  343. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/spinnerentry.py +0 -0
  344. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/tableview/__init__.py +0 -0
  345. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/tableview/types.py +0 -0
  346. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/tabs/__init__.py +0 -0
  347. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/tabs/tabs.py +0 -0
  348. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/tabs/tabview.py +0 -0
  349. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/textarea/__init__.py +0 -0
  350. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/textarea/change.py +0 -0
  351. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/textarea/codeeditor.py +0 -0
  352. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/textarea/decoration.py +0 -0
  353. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/textarea/diff.py +0 -0
  354. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/textarea/extensions/__init__.py +0 -0
  355. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/textarea/extensions/bracket_matcher.py +0 -0
  356. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/textarea/extensions/indent_guides.py +0 -0
  357. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/textarea/extensions/line_numbers.py +0 -0
  358. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/textarea/extensions/pygments_highlighter.py +0 -0
  359. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/textarea/filter.py +0 -0
  360. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/textarea/redirector.py +0 -0
  361. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/textarea/search_overlay.py +0 -0
  362. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/textarea/sidebar.py +0 -0
  363. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/textarea/style_registry.py +0 -0
  364. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/textarea/undo.py +0 -0
  365. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/textentry.py +0 -0
  366. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/timeentry.py +0 -0
  367. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/toast.py +0 -0
  368. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/toast_stack.py +0 -0
  369. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/togglegroup.py +0 -0
  370. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/toolbar.py +0 -0
  371. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/tooltip.py +0 -0
  372. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/tree/__init__.py +0 -0
  373. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/tree/source_binding.py +0 -0
  374. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/tree/treenode.py +0 -0
  375. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/composites/tree/treeview.py +0 -0
  376. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/mixins/__init__.py +0 -0
  377. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/mixins/configure_mixin.py +0 -0
  378. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/mixins/entry_mixin.py +0 -0
  379. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/mixins/font_mixin.py +0 -0
  380. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/mixins/icon_mixin.py +0 -0
  381. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/mixins/localization_mixin.py +0 -0
  382. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/mixins/signal_mixin.py +0 -0
  383. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/mixins/validation_mixin.py +0 -0
  384. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/primitives/__init__.py +0 -0
  385. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/primitives/_menubutton.py +0 -0
  386. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/primitives/badge.py +0 -0
  387. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/primitives/button.py +0 -0
  388. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/primitives/card.py +0 -0
  389. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/primitives/checkbutton.py +0 -0
  390. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/primitives/checktoggle.py +0 -0
  391. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/primitives/combobox.py +0 -0
  392. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/primitives/entry.py +0 -0
  393. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/primitives/flexframe.py +0 -0
  394. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/primitives/frame.py +0 -0
  395. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/primitives/gridframe.py +0 -0
  396. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/primitives/label.py +0 -0
  397. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/primitives/labelframe.py +0 -0
  398. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/primitives/optionmenu.py +0 -0
  399. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/primitives/packframe.py +0 -0
  400. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/primitives/panedwindow.py +0 -0
  401. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/primitives/progressbar.py +0 -0
  402. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/primitives/radiobutton.py +0 -0
  403. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/primitives/radiotoggle.py +0 -0
  404. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/primitives/scrollbar.py +0 -0
  405. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/primitives/separator.py +0 -0
  406. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/primitives/sizegrip.py +0 -0
  407. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/primitives/switch.py +0 -0
  408. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/_impl/primitives/treeview.py +0 -0
  409. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/app.py +0 -0
  410. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/appshell.py +0 -0
  411. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/avatar.py +0 -0
  412. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/boolean_controls.py +0 -0
  413. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/button.py +0 -0
  414. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/buttongroup.py +0 -0
  415. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/calendar.py +0 -0
  416. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/card.py +0 -0
  417. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/carousel.py +0 -0
  418. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/chart.py +0 -0
  419. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/codeeditor.py +0 -0
  420. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/contextmenu.py +0 -0
  421. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/datatable.py +0 -0
  422. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/datefield.py +0 -0
  423. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/divider.py +0 -0
  424. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/expander.py +0 -0
  425. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/form.py +0 -0
  426. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/gallery.py +0 -0
  427. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/gauge.py +0 -0
  428. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/grid.py +0 -0
  429. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/groupbox.py +0 -0
  430. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/label.py +0 -0
  431. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/listview.py +0 -0
  432. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/menubutton.py +0 -0
  433. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/pagestack.py +0 -0
  434. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/passwordfield.py +0 -0
  435. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/pathfield.py +0 -0
  436. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/picture.py +0 -0
  437. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/progressbar.py +0 -0
  438. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/radio_variants.py +0 -0
  439. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/radiogroup.py +0 -0
  440. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/scrollbar.py +0 -0
  441. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/scrollview.py +0 -0
  442. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/selectbutton.py +0 -0
  443. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/sidebar_toggle.py +0 -0
  444. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/sizegrip.py +0 -0
  445. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/slider.py +0 -0
  446. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/spinbox.py +0 -0
  447. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/spinnerfield.py +0 -0
  448. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/splash.py +0 -0
  449. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/splitview.py +0 -0
  450. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/stacks.py +0 -0
  451. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/statusbar.py +0 -0
  452. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/tabs.py +0 -0
  453. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/textarea.py +0 -0
  454. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/textfield.py +0 -0
  455. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/theme_toggle.py +0 -0
  456. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/timefield.py +0 -0
  457. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/toast.py +0 -0
  458. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/togglegroup.py +0 -0
  459. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/toolbar.py +0 -0
  460. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/tooltip.py +0 -0
  461. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/tree.py +0 -0
  462. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/types.py +0 -0
  463. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack/widgets/window.py +0 -0
  464. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack.egg-info/SOURCES.txt +0 -0
  465. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack.egg-info/dependency_links.txt +0 -0
  466. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack.egg-info/entry_points.txt +0 -0
  467. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack.egg-info/requires.txt +0 -0
  468. {bootstack-0.4.5 → bootstack-0.4.7}/src/bootstack.egg-info/top_level.txt +0 -0
  469. {bootstack-0.4.5 → bootstack-0.4.7}/tests/test_dialog_anchor.py +0 -0
  470. {bootstack-0.4.5 → bootstack-0.4.7}/tests/test_events_doc_coverage.py +0 -0
  471. {bootstack-0.4.5 → bootstack-0.4.7}/tests/test_hot_reload.py +0 -0
  472. {bootstack-0.4.5 → bootstack-0.4.7}/tests/test_images.py +0 -0
  473. {bootstack-0.4.5 → bootstack-0.4.7}/tests/test_images_gui.py +0 -0
  474. {bootstack-0.4.5 → bootstack-0.4.7}/tests/test_intl_format.py +0 -0
  475. {bootstack-0.4.5 → bootstack-0.4.7}/tests/test_navmodel.py +0 -0
  476. {bootstack-0.4.5 → bootstack-0.4.7}/tests/test_on_color_contrast.py +0 -0
  477. {bootstack-0.4.5 → bootstack-0.4.7}/tests/test_public_surface.py +0 -0
  478. {bootstack-0.4.5 → bootstack-0.4.7}/tests/test_store.py +0 -0
  479. {bootstack-0.4.5 → bootstack-0.4.7}/tests/test_theme_from_existing.py +0 -0
  480. {bootstack-0.4.5 → bootstack-0.4.7}/tests/test_validation_rules.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bootstack
3
- Version: 0.4.5
3
+ Version: 0.4.7
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.4.5"
7
+ version = "0.4.7"
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.4.5"
117
+ current_version = "0.4.7"
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}",
@@ -135,6 +135,10 @@ def apply_class_bindings(window: tkinter.Widget | App) -> None:
135
135
  sequence=sequence,
136
136
  func=on_select_all)
137
137
 
138
+ for sequence in window.bind_class("TSpinbox"):
139
+ if any(s in sequence for s in ("Wheel", "Button-4", "Button-5", "Touchpad")):
140
+ window.unbind_class("TSpinbox", sequence)
141
+
138
142
  window.unbind_class("TButton", "<Key-space>")
139
143
 
140
144
  def button_default_binding(event: tkinter.Event) -> None:
@@ -46,6 +46,12 @@ def has_touchpad_scroll() -> bool:
46
46
  """Whether the running Tk generates `<TouchpadScroll>` events."""
47
47
  return tk.TkVersion >= _TOUCHPAD_TK
48
48
 
49
+ def has_focus(widget: tk.Misc) -> bool:
50
+ """Whether `widget` holds keyboard focus in its application"""
51
+ try:
52
+ return widget.focus_get() is widget
53
+ except (tk.TclError, KeyError):
54
+ return False
49
55
 
50
56
  def uses_x11_buttons(widget: tk.Misc) -> bool:
51
57
  """Whether wheel input arrives as `<Button-4>`/`<Button-5>` here.
@@ -29,7 +29,7 @@ class NumberEntryPart(TextEntryPart):
29
29
  master=None,
30
30
  *,
31
31
  value: int | float | str = 0,
32
- value_format: str = None,
32
+ value_format: str | None = None,
33
33
  minvalue: int | float | None = None,
34
34
  maxvalue: int | float | None = None,
35
35
  increment: int | float = 1,
@@ -142,9 +142,9 @@ class NumberEntryPart(TextEntryPart):
142
142
  return 'break' # Prevent default behavior
143
143
 
144
144
  def _handle_mouse_wheel(self, event):
145
- """Handle a wheel notch by stepping the value once."""
146
- if not self._is_interactive():
147
- return 'break'
145
+ """Step once per wheel notch while the field has focus"""
146
+ if not wheel.has_focus(self) or not self._is_interactive():
147
+ return None
148
148
  notches = wheel.wheel_notches(self, event)
149
149
  if notches:
150
150
  name = '<<Increment>>' if notches > 0 else '<<Decrement>>'
@@ -157,8 +157,8 @@ class NumberEntryPart(TextEntryPart):
157
157
  A trackpad reports around sixty events a second; stepping on each
158
158
  one would run the value away from the user.
159
159
  """
160
- if not self._is_interactive():
161
- return 'break'
160
+ if not wheel.has_focus(self) or not self._is_interactive():
161
+ return None
162
162
  _dx, dy = wheel.precise_deltas(event)
163
163
  _sx, steps = self._touchpad.add(0, dy, 1, _TOUCHPAD_STEP_PX)
164
164
  name = '<<Increment>>' if steps > 0 else '<<Decrement>>'
@@ -4,6 +4,7 @@ Provides a customizable context menu with support for commands, checkbuttons,
4
4
  radiobuttons, and separators.
5
5
  """
6
6
 
7
+ import weakref
7
8
  from tkinter import BooleanVar, IntVar, Misc, StringVar, TclError, Toplevel, Widget
8
9
  from typing_extensions import Unpack
9
10
  from typing import Any, Callable, Literal
@@ -42,6 +43,23 @@ On Windows and Linux the result is the created widget. On macOS (native
42
43
  # explicitly" (no target — no positioning, no auto-trigger).
43
44
  _TARGET_DEFAULT: Any = object()
44
45
 
46
+ # Themed menus currently shown. Weak, so a new menu torn down with its parent
47
+ # is not pinned here (it's destroy()) is never called.
48
+ _OPEN_MENUS: "weakref.WeakSet[_ToplevelContextMenu]" = weakref.WeakSet()
49
+
50
+
51
+ def hide_open_menus() -> None:
52
+ """Hide every open themed context menu.
53
+
54
+ Call this from a click handler that returns 'break': the break stops the
55
+ click before the window-level outside-click handler can close the menu.
56
+ """
57
+ for menu in list(_OPEN_MENUS):
58
+ try:
59
+ menu.hide()
60
+ except TclError:
61
+ _OPEN_MENUS.discard(menu)
62
+
45
63
 
46
64
  class _CommandItemFrame(CompositeFrame):
47
65
  """Container frame for command items that delegates to the inner button.
@@ -648,6 +666,7 @@ class _ToplevelContextMenu(CustomConfigMixin):
648
666
  self._toplevel.attributes('-topmost', True)
649
667
  self._toplevel.lift()
650
668
  self._toplevel.focus_force()
669
+ _OPEN_MENUS.add(self)
651
670
 
652
671
  # Start with no item highlighted (keyboard nav will highlight on first arrow key)
653
672
  self._highlighted_index = -1
@@ -737,6 +756,7 @@ class _ToplevelContextMenu(CustomConfigMixin):
737
756
 
738
757
  def hide(self) -> None:
739
758
  """Hide the context menu."""
759
+ _OPEN_MENUS.discard(self)
740
760
  # Unbind click handler first
741
761
  self._cancel_click_outside_after()
742
762
  self._unbind_click_outside_handler()
@@ -756,6 +776,7 @@ class _ToplevelContextMenu(CustomConfigMixin):
756
776
 
757
777
  def destroy(self) -> None:
758
778
  """Destroy the context menu and cleanup resources."""
779
+ _OPEN_MENUS.discard(self)
759
780
  # Unbind click handler
760
781
  self._cancel_click_outside_after()
761
782
  self._unbind_click_outside_handler()
@@ -4,15 +4,18 @@ Provides a specialized entry field for numeric input with increment/decrement
4
4
  buttons and keyboard/mouse wheel support.
5
5
  """
6
6
 
7
- from typing import Any, Callable
7
+ from typing import Any, Callable, cast, TYPE_CHECKING
8
8
  from tkinter import TclError
9
9
  from typing_extensions import Unpack
10
10
 
11
11
  from bootstack.widgets._impl.primitives.button import Button
12
12
  from bootstack.widgets._impl.composites.field import Field, FieldOptions
13
+
13
14
  from bootstack.widgets._impl.mixins import configure_delegate
14
15
  from bootstack.widgets.types import Master
15
16
 
17
+ if TYPE_CHECKING:
18
+ from bootstack.widgets._impl._parts import NumberEntryPart
16
19
 
17
20
  class NumericEntry(Field):
18
21
  """A numeric entry field widget with increment/decrement spin buttons.
@@ -21,12 +24,14 @@ class NumericEntry(Field):
21
24
  keyboard stepping (Up/Down arrows), mouse wheel support, and optional wrapping.
22
25
  """
23
26
 
27
+ entry_widget: "NumberEntryPart"
28
+
24
29
  def __init__(
25
30
  self,
26
31
  master: Master = None,
27
32
  value: int | float = 0,
28
- label: str = None,
29
- message: str = None,
33
+ label: str | None = None,
34
+ message: str | None = None,
30
35
  show_spin_buttons: bool = True,
31
36
  minvalue: int | float | None = None,
32
37
  maxvalue: int | float | None = None,
@@ -80,8 +85,8 @@ class NumericEntry(Field):
80
85
  self._show_spin_buttons = show_spin_buttons
81
86
 
82
87
  # pack info
83
- self._increment_pack_info = {}
84
- self._decrement_pack_info = {}
88
+ self._increment_pack_info: Any = {}
89
+ self._decrement_pack_info: Any = {}
85
90
 
86
91
  # buttons
87
92
  self.insert_addon(
@@ -96,12 +101,12 @@ class NumericEntry(Field):
96
101
  @property
97
102
  def increment_widget(self) -> Button:
98
103
  """Get the increment spin button widget."""
99
- return self.addons['increment']
104
+ return cast(Button, self.addons['increment'])
100
105
 
101
106
  @property
102
107
  def decrement_widget(self) -> Button:
103
108
  """Get the decrement spin button widget."""
104
- return self.addons['decrement']
109
+ return cast(Button, self.addons['decrement'])
105
110
 
106
111
  def increment(self) -> None:
107
112
  """Increment the numeric value by one step."""
@@ -182,7 +187,7 @@ class NumericEntry(Field):
182
187
  pass
183
188
 
184
189
  @configure_delegate('show_spin_buttons')
185
- def _delegate_show_spin_buttons(self, value: bool = None):
190
+ def _delegate_show_spin_buttons(self, value: bool | None = None):
186
191
  """Get or set the visibility of spin buttons."""
187
192
  if value is None:
188
193
  return self._show_spin_buttons
@@ -391,7 +391,48 @@ class SelectBox(Field):
391
391
  text = self.entry_widget.get()
392
392
  if text in self._value_by_text and self._value_by_text[text] != text:
393
393
  return self._value_by_text[text]
394
- return self._entry_live_validation_value()
394
+ return self._decode_custom_text(text, self._entry_live_validation_value)
395
+
396
+ def _numeric_option_kind(self):
397
+ """`int` or `float` when every option value shares that type, else None."""
398
+ # type(), not isinstance: bool never reads as int here, so a bool option
399
+ # list falls out as "not numeric" without a special case.
400
+ kinds = {type(rec.value) for rec in self._records}
401
+ if len(kinds) != 1:
402
+ return None
403
+ kind = kinds.pop()
404
+ return kind if kind in (int, float) else None
405
+
406
+ def _decode_custom_text(self, text, fallback):
407
+ """Decode text that names no option: the options' own type when they share one.
408
+
409
+ A value typed by the user arrives as text with nothing to parse it,
410
+ while one assigned from code arrives already typed. When every option
411
+ value is an `int`, or every one a `float`, numeric text is parsed to
412
+ that type so both routes agree. Anything else — a mixed or empty
413
+ list, `str` or `bool` options, text that is not a number, an entry
414
+ that parses through its own `value_format` — is handed to `fallback`,
415
+ which is what the entry reported before.
416
+
417
+ A whole-number `float` narrows to `int` for `int` options; `'6.5'`
418
+ against `int` options stays `6.5` rather than being truncated.
419
+ """
420
+ if self.entry_widget._value_format is not None:
421
+ return fallback()
422
+ if getattr(self.entry_widget, "_showing_placeholder", False):
423
+ return fallback()
424
+ kind = self._numeric_option_kind()
425
+ if kind is None:
426
+ return fallback()
427
+ try:
428
+ parsed = self.entry_widget._fmt.parse(text, "decimal")
429
+ except ValueError:
430
+ return fallback()
431
+ if parsed is None:
432
+ return fallback()
433
+ if kind is int and not parsed.is_integer():
434
+ return parsed
435
+ return kind(parsed)
395
436
 
396
437
  def _register_retired_value(self, value: Any) -> None:
397
438
  """Make a value that is not in the option list decodable.
@@ -1185,16 +1226,17 @@ class SelectBox(Field):
1185
1226
  """The selected value, or None when the field is empty.
1186
1227
 
1187
1228
  For a decoupled option (its display text differs from its value) this
1188
- returns the option's value. Otherwise it returns the entry's own raw
1189
- value, so `value_format` parsing — e.g. TimeField's `datetime.time` —
1190
- is preserved.
1229
+ returns the option's value. A custom value typed by the user takes the
1230
+ type the options share when that is `int` or `float`. Otherwise it
1231
+ returns the entry's own raw value, so `value_format` parsing — e.g.
1232
+ TimeField's `datetime.time` — is preserved.
1191
1233
  """
1192
1234
  text = self.entry_widget.get()
1193
1235
  if text == "":
1194
1236
  return None
1195
1237
  if text in self._value_by_text and self._value_by_text[text] != text:
1196
1238
  return self._value_by_text[text]
1197
- return Field.value.fget(self)
1239
+ return self._decode_custom_text(text, lambda: Field.value.fget(self))
1198
1240
 
1199
1241
  @value.setter
1200
1242
  def value(self, value):
@@ -30,7 +30,7 @@ from bootstack.data.sqlite_source import SqliteDataSource
30
30
  from bootstack.data.query import col, any_of, all_of
31
31
  from bootstack.widgets._impl.primitives.button import Button
32
32
  from bootstack._runtime.utility import bind_right_click, debug_log_exception
33
- from bootstack.widgets._impl.composites.contextmenu import ContextMenu
33
+ from bootstack.widgets._impl.composites.contextmenu import ContextMenu, hide_open_menus
34
34
  from bootstack.widgets._impl.composites.tooltip import ToolTip
35
35
  from bootstack.widgets._impl.composites.dropdownbutton import DropdownButton
36
36
  from bootstack.widgets._impl.primitives.entry import Entry
@@ -1644,6 +1644,7 @@ class TableView(Frame):
1644
1644
  # ------------------------------------------------------------------ Row context menu
1645
1645
  def _dismiss_context_menus(self) -> None:
1646
1646
  """Hide any open built-in row/header context menu (idempotent)."""
1647
+ hide_open_menus()
1647
1648
  for menu in (self._row_menu, self._header_menu):
1648
1649
  if menu is not None:
1649
1650
  try:
@@ -113,9 +113,7 @@ class TabItem(CompositeFrame):
113
113
  self._close_button: Button | None = None
114
114
 
115
115
  self._build_widget(accent, surface)
116
-
117
- if self._min_width:
118
- self.after_idle(self._apply_min_width)
116
+ self._schedule_min_width()
119
117
 
120
118
  # Set up signal/variable after widget is built
121
119
  if signal is not None:
@@ -137,6 +135,14 @@ class TabItem(CompositeFrame):
137
135
  self.pack_propagate(False)
138
136
  self.configure(width=self._min_width, height=self.winfo_reqheight())
139
137
 
138
+ def _schedule_min_width(self):
139
+ """Re-measure the minimum width once the current content has laid out"""
140
+ if not self._min_width:
141
+ return
142
+ self.pack_propagate(True)
143
+ self.configure(width=0, height=0)
144
+ self.after_idle(self._apply_min_width)
145
+
140
146
  def _on_destroy(self, event=None):
141
147
  """Clean up variable trace when widget is destroyed."""
142
148
  if event.widget is not self:
@@ -310,6 +316,7 @@ class TabItem(CompositeFrame):
310
316
  self._text = value
311
317
  if self._label is not None:
312
318
  self._label.configure(text=value)
319
+ self._schedule_min_width()
313
320
  return None
314
321
 
315
322
  @configure_delegate('icon')
@@ -320,6 +327,7 @@ class TabItem(CompositeFrame):
320
327
  self._icon = value
321
328
  if self._label is not None:
322
329
  self._label.configure(icon=value)
330
+ self._schedule_min_width()
323
331
  return None
324
332
 
325
333
  @configure_delegate('compound')
@@ -330,6 +338,7 @@ class TabItem(CompositeFrame):
330
338
  self._compound = value
331
339
  if self._label is not None:
332
340
  self._label.configure(compound=value)
341
+ self._schedule_min_width()
333
342
  return None
334
343
 
335
344
  @configure_delegate('value')
@@ -370,6 +379,7 @@ class TabItem(CompositeFrame):
370
379
  self._close_button.place_forget()
371
380
  self._close_button.destroy()
372
381
  self._close_button = None
382
+ self._schedule_min_width()
373
383
  return None
374
384
 
375
385
  @configure_delegate('signal')
@@ -524,26 +524,15 @@ class _MultilineCore(tk.Frame):
524
524
 
525
525
  # ── convenience: forward common Text API to self ──────────────────────
526
526
 
527
- def bind(self, sequence=None, func=None, add=None):
528
- return self.text.bind(sequence, func, add)
529
-
530
- def unbind(self, sequence, funcid=None):
531
- return self.text.unbind(sequence, funcid)
532
-
533
527
  def focus_set(self):
534
528
  self.text.focus_set()
535
529
 
536
530
  # ── cleanup ───────────────────────────────────────────────────────────
537
531
 
538
532
  def _on_destroy(self, event: tk.Event) -> None:
539
- # Released for any Destroy in this subtree, not just our own: the event
540
- # this handler receives names the inner Text, never the core, so gating
541
- # the release on `is self` releases nothing and the subscription outlives
542
- # the widget. The rest of the block stays behind the guard -- it has
543
- # never run, and starting it here is not this change's business.
544
- self._unbind_signal()
545
533
  if event.widget is not self:
546
534
  return
535
+ self._unbind_signal()
547
536
  self._chain.destroy()
548
537
  try:
549
538
  for seq in wheel.wheel_sequences(self):
@@ -45,7 +45,10 @@ class SmartIndent(EditFilter):
45
45
  core.text.bind("<Return>", self._on_return, add="+")
46
46
  core.text.bind("<Tab>", self._on_tab, add="+")
47
47
  core.text.bind("<Shift-Tab>", self._on_shift_tab, add="+")
48
- core.text.bind("<ISO_Left_Tab>", self._on_shift_tab, add="+") # Linux/X11
48
+
49
+ # X11 reports Shift+Tab as ISO_Left_Tab; other Tk builds may reject the keysym
50
+ if core.winsys == "x11":
51
+ core.text.bind("<ISO_Left_Tab>", self._on_shift_tab, add="+")
49
52
 
50
53
  def detach(self, core: _MultilineCore) -> None:
51
54
  self._core = None
@@ -173,7 +173,10 @@ class TextArea(GridFrame):
173
173
  # it is a separate composite and is unaffected.)
174
174
  self._core.text.bind("<Tab>", self._focus_next, add="+")
175
175
  self._core.text.bind("<Shift-Tab>", self._focus_prev, add="+")
176
- self._core.text.bind("<ISO_Left_Tab>", self._focus_prev, add="+")
176
+
177
+ # X11 reports Shift+Tab as ISO_Left_Tab; other Tk builds may reject the keysym
178
+ if self._core.winsys == "x11":
179
+ self._core.text.bind("<ISO_Left_Tab>", self._focus_prev, add="+")
177
180
 
178
181
  # ── message label (row 2) ─────────────────────────────────────────
179
182
  self._message_lbl = Label(self, text=message or "", font="caption",
@@ -14,6 +14,7 @@ from tkinter import TclError
14
14
  from typing import Any, Optional
15
15
 
16
16
  from bootstack.widgets._impl.composites.compositeframe import CompositeFrame
17
+ from bootstack.widgets._impl.composites.contextmenu import hide_open_menus
17
18
  from bootstack.widgets._impl.primitives.button import Button
18
19
  from bootstack.widgets._impl.primitives.frame import Frame
19
20
  from bootstack.widgets._impl.primitives.label import Label
@@ -193,6 +194,9 @@ class TreeItem(CompositeFrame):
193
194
  self._emit("<<TreeItemSelect>>", self._node)
194
195
 
195
196
  def _on_ctrl_click(self, event=None) -> str:
197
+ # The 'break' below stops the click before an open menu's outside-click
198
+ # handler sees it, so close the open menus here
199
+ hide_open_menus()
196
200
  if self._node is not None:
197
201
  if self._focusable:
198
202
  self.focus()
@@ -209,6 +213,9 @@ class TreeItem(CompositeFrame):
209
213
  return "break"
210
214
 
211
215
  def _on_right_click(self, event) -> str:
216
+ # The 'break' below stops the click before an open menu's outside-click
217
+ # handler sees it, so close open menus before this row opens its own
218
+ hide_open_menus()
212
219
  if self._node is not None:
213
220
  self._emit(
214
221
  "<<TreeItemRightClick>>",
@@ -72,9 +72,7 @@ class Spinbox(TextSignalMixin, TTKWrapperBase, WidgetCapabilitiesMixin, TtkState
72
72
  kwargs['font'] = 'caption'
73
73
  kwargs.update(style_options=self._capture_style_options(['density'], kwargs))
74
74
  super().__init__(master, **kwargs)
75
- # Handle mousewheel explicitly so we can return "break" and stop the
76
- # event from leaking to parent scroll containers. Instance bindings run
77
- # before class bindings in Tk's chain, so we must do the spin ourselves.
75
+
78
76
  for seq in wheel.wheel_sequences(self):
79
77
  self.bind(seq, self._on_mousewheel)
80
78
  if wheel.has_touchpad_scroll():
@@ -82,6 +80,8 @@ class Spinbox(TextSignalMixin, TTKWrapperBase, WidgetCapabilitiesMixin, TtkState
82
80
  self.bind(wheel.TOUCHPAD_SCROLL, self._on_touchpad_scroll)
83
81
 
84
82
  def _on_mousewheel(self, event):
83
+ if not wheel.has_focus(self):
84
+ return None
85
85
  notches = wheel.wheel_notches(self, event)
86
86
  if notches:
87
87
  self.event_generate("<Up>" if notches > 0 else "<Down>")
@@ -93,6 +93,8 @@ class Spinbox(TextSignalMixin, TTKWrapperBase, WidgetCapabilitiesMixin, TtkState
93
93
  A trackpad reports around sixty events a second; stepping on each
94
94
  one would run the value away from the user.
95
95
  """
96
+ if not wheel.has_focus(self):
97
+ return None
96
98
  _dx, dy = wheel.precise_deltas(event)
97
99
  _sx, steps = self._touchpad.add(0, dy, 1, _TOUCHPAD_STEP_PX)
98
100
  for _ in range(abs(steps)):
@@ -14,6 +14,8 @@ from bootstack.widgets.types import AccentToken, Event, Justify, WidgetDensity
14
14
 
15
15
  if TYPE_CHECKING:
16
16
  from bootstack.signals import Signal
17
+ from bootstack.widgets._impl.composites.numericentry import NumericEntry
18
+
17
19
 
18
20
  def _as_number(raw: Any) -> int | float | None:
19
21
  """Coerce a field's stored value to a number, regardless of representation.
@@ -48,8 +50,8 @@ class NumberField(ValueSignalMixin, FieldAddonMixin, PublicWidgetBase):
48
50
  """A numeric input field with optional stepper buttons.
49
51
 
50
52
  Accepts integer or float values. Up/Down arrow keys and the mouse wheel
51
- step the value by `step`. The field validates that the typed value is
52
- numeric and within `min_value`/`max_value` bounds.
53
+ step the value by `step` while the field has focus. The field validates
54
+ that the typed value is numeric and within `min_value`/`max_value` bounds.
53
55
 
54
56
  The initial value is the first positional argument. All options are
55
57
  keyword-only.
@@ -131,7 +133,7 @@ class NumberField(ValueSignalMixin, FieldAddonMixin, PublicWidgetBase):
131
133
  layout_kw = self._split_layout_kwargs(kwargs)
132
134
  tk_master = self._parent._child_master() if self._parent else None
133
135
 
134
- internal_kwargs: dict[str, Any] = {
136
+ internal_kwargs: Any = {
135
137
  "value": value,
136
138
  "increment": step,
137
139
  "show_spin_buttons": show_steppers,
@@ -165,7 +167,7 @@ class NumberField(ValueSignalMixin, FieldAddonMixin, PublicWidgetBase):
165
167
  if density is not None:
166
168
  internal_kwargs["density"] = density
167
169
 
168
- self._internal = _InternalNumericEntry(tk_master, **internal_kwargs)
170
+ self._internal: "NumericEntry" = _InternalNumericEntry(tk_master, **internal_kwargs)
169
171
  self._attach_to_parent(layout_kw)
170
172
 
171
173
  if signal is not None:
@@ -50,7 +50,11 @@ class Select(ValueSignalMixin, FieldAddonMixin, PublicWidgetBase):
50
50
  searchable: If `True`, typing in the field filters the option
51
51
  list. Defaults to `False`.
52
52
  allow_custom_values: If `True`, users may type values not in
53
- `options`. Defaults to `False`.
53
+ `options`. A typed value takes the type the option values share:
54
+ when every option value is an `int`, or every one a `float`,
55
+ numeric text is read as that type; otherwise, and for text that
56
+ is not a number, the value is the text as typed. Defaults to
57
+ `False`.
54
58
  group_by: Name of an option field to cluster the popup rows under
55
59
  non-selectable group headers (e.g. `'category'`). The field is read
56
60
  from each option's flat record, so it may be any carried bag key (or
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bootstack
3
- Version: 0.4.5
3
+ Version: 0.4.7
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
File without changes
File without changes
File without changes
File without changes
File without changes