bootstack 0.1.6__tar.gz → 0.1.8__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 (491) hide show
  1. {bootstack-0.1.6/src/bootstack.egg-info → bootstack-0.1.8}/PKG-INFO +1 -1
  2. {bootstack-0.1.6 → bootstack-0.1.8}/pyproject.toml +2 -2
  3. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_runtime/utility.py +14 -2
  4. bootstack-0.1.8/src/bootstack/_runtime/wheel.py +152 -0
  5. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/typography.py +15 -6
  6. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_core/base.py +24 -0
  7. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/_parts/numberentry_part.py +26 -26
  8. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/gallery.py +22 -10
  9. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/list/listview.py +46 -32
  10. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/scrolledtext.py +34 -36
  11. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/scrollview.py +41 -36
  12. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/tabs/tabs.py +23 -18
  13. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/textarea/core.py +18 -19
  14. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/tree/treeview.py +33 -16
  15. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/primitives/spinbox.py +24 -7
  16. {bootstack-0.1.6 → bootstack-0.1.8/src/bootstack.egg-info}/PKG-INFO +1 -1
  17. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack.egg-info/SOURCES.txt +1 -0
  18. {bootstack-0.1.6 → bootstack-0.1.8}/LICENSE +0 -0
  19. {bootstack-0.1.6 → bootstack-0.1.8}/MANIFEST.in +0 -0
  20. {bootstack-0.1.6 → bootstack-0.1.8}/NOTICE +0 -0
  21. {bootstack-0.1.6 → bootstack-0.1.8}/README.md +0 -0
  22. {bootstack-0.1.6 → bootstack-0.1.8}/setup.cfg +0 -0
  23. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/__init__.py +0 -0
  24. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/__main__.py +0 -0
  25. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_core/__init__.py +0 -0
  26. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_core/capabilities/__init__.py +0 -0
  27. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_core/capabilities/after.py +0 -0
  28. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_core/capabilities/bind.py +0 -0
  29. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_core/capabilities/bindtags.py +0 -0
  30. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_core/capabilities/busy.py +0 -0
  31. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_core/capabilities/clipboard.py +0 -0
  32. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_core/capabilities/focus.py +0 -0
  33. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_core/capabilities/grab.py +0 -0
  34. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_core/capabilities/grid.py +0 -0
  35. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_core/capabilities/localization.py +0 -0
  36. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_core/capabilities/pack.py +0 -0
  37. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_core/capabilities/place.py +0 -0
  38. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_core/capabilities/selection.py +0 -0
  39. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_core/capabilities/signals.py +0 -0
  40. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_core/capabilities/winfo.py +0 -0
  41. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_core/colorutils.py +0 -0
  42. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_core/exceptions.py +0 -0
  43. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_core/images.py +0 -0
  44. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_core/mixins/__init__.py +0 -0
  45. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_core/mixins/ttk_state.py +0 -0
  46. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_core/mixins/widget.py +0 -0
  47. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_core/paths.py +0 -0
  48. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_core/publisher.py +0 -0
  49. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_core/variables.py +0 -0
  50. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_runtime/__init__.py +0 -0
  51. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_runtime/app.py +0 -0
  52. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_runtime/base_window.py +0 -0
  53. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_runtime/events.py +0 -0
  54. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_runtime/shortcuts.py +0 -0
  55. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_runtime/tk_patch.py +0 -0
  56. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_runtime/toplevel.py +0 -0
  57. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_runtime/visual_focus.py +0 -0
  58. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/_runtime/window_utilities.py +0 -0
  59. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/__init__.py +0 -0
  60. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/bootstack.ico +0 -0
  61. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/bootstack.png +0 -0
  62. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/__init__.py +0 -0
  63. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/badge-pill.png +0 -0
  64. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/badge-square.png +0 -0
  65. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/button-compact.png +0 -0
  66. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/button-default.png +0 -0
  67. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/buttongroup-after-h-compact.png +0 -0
  68. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/buttongroup-after-h-default.png +0 -0
  69. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/buttongroup-after-v-compact.png +0 -0
  70. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/buttongroup-after-v-default.png +0 -0
  71. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/buttongroup-before-h-compact.png +0 -0
  72. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/buttongroup-before-h-default.png +0 -0
  73. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/buttongroup-before-v-compact.png +0 -0
  74. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/buttongroup-before-v-default.png +0 -0
  75. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/buttongroup-center-h-compact.png +0 -0
  76. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/buttongroup-center-h-default.png +0 -0
  77. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/buttongroup-center-v-compact.png +0 -0
  78. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/buttongroup-center-v-default.png +0 -0
  79. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/card.png +0 -0
  80. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/checkbox-checked.png +0 -0
  81. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/checkbox-indeterminate.png +0 -0
  82. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/checkbox-unchecked.png +0 -0
  83. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/field.png +0 -0
  84. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/input-addon-compact.png +0 -0
  85. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/input-addon-default.png +0 -0
  86. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/input-compact.png +0 -0
  87. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/input-default.png +0 -0
  88. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/list-item-separated.png +0 -0
  89. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/list-item.png +0 -0
  90. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/listrow-compact.png +0 -0
  91. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/listrow-default.png +0 -0
  92. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/manifest.toml +0 -0
  93. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/menu-item.png +0 -0
  94. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/navitem-compact.png +0 -0
  95. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/navitem-default.png +0 -0
  96. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/progressbar-h-compact.png +0 -0
  97. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/progressbar-h-default.png +0 -0
  98. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/progressbar-v-compact.png +0 -0
  99. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/progressbar-v-default.png +0 -0
  100. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/radiobutton.png +0 -0
  101. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/scrollbar-horizontal.png +0 -0
  102. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/scrollbar-vertical.png +0 -0
  103. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/slider-handle.png +0 -0
  104. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/slider-track-h.png +0 -0
  105. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/slider-track-v.png +0 -0
  106. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/switch-off.png +0 -0
  107. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/switch-on.png +0 -0
  108. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/tab-h.png +0 -0
  109. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/elements/tab-v.png +0 -0
  110. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/icons/bootstrap.ttf +0 -0
  111. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/icons/glyphmap.json +0 -0
  112. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/icons/icon_metrics.json +0 -0
  113. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/ar/LC_MESSAGES/bootstack.mo +0 -0
  114. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/ar/LC_MESSAGES/bootstack.po +0 -0
  115. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/bg/LC_MESSAGES/bootstack.mo +0 -0
  116. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/bg/LC_MESSAGES/bootstack.po +0 -0
  117. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/cs/LC_MESSAGES/bootstack.mo +0 -0
  118. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/cs/LC_MESSAGES/bootstack.po +0 -0
  119. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/da/LC_MESSAGES/bootstack.mo +0 -0
  120. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/da/LC_MESSAGES/bootstack.po +0 -0
  121. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/de/LC_MESSAGES/bootstack.mo +0 -0
  122. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/de/LC_MESSAGES/bootstack.po +0 -0
  123. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/en/LC_MESSAGES/bootstack.mo +0 -0
  124. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/en/LC_MESSAGES/bootstack.po +0 -0
  125. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/es/LC_MESSAGES/bootstack.mo +0 -0
  126. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/es/LC_MESSAGES/bootstack.po +0 -0
  127. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/fr/LC_MESSAGES/bootstack.mo +0 -0
  128. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/fr/LC_MESSAGES/bootstack.po +0 -0
  129. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/he/LC_MESSAGES/bootstack.mo +0 -0
  130. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/he/LC_MESSAGES/bootstack.po +0 -0
  131. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/hi/LC_MESSAGES/bootstack.mo +0 -0
  132. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/hi/LC_MESSAGES/bootstack.po +0 -0
  133. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/it/LC_MESSAGES/bootstack.mo +0 -0
  134. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/it/LC_MESSAGES/bootstack.po +0 -0
  135. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/ja/LC_MESSAGES/bootstack.mo +0 -0
  136. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/ja/LC_MESSAGES/bootstack.po +0 -0
  137. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/ko/LC_MESSAGES/bootstack.mo +0 -0
  138. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/ko/LC_MESSAGES/bootstack.po +0 -0
  139. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/nb/LC_MESSAGES/bootstack.mo +0 -0
  140. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/nb/LC_MESSAGES/bootstack.po +0 -0
  141. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/nl/LC_MESSAGES/bootstack.mo +0 -0
  142. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/nl/LC_MESSAGES/bootstack.po +0 -0
  143. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/pl/LC_MESSAGES/bootstack.mo +0 -0
  144. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/pl/LC_MESSAGES/bootstack.po +0 -0
  145. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/pt/LC_MESSAGES/bootstack.mo +0 -0
  146. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/pt/LC_MESSAGES/bootstack.po +0 -0
  147. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.mo +0 -0
  148. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.po +0 -0
  149. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/sl/LC_MESSAGES/bootstack.mo +0 -0
  150. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/sl/LC_MESSAGES/bootstack.po +0 -0
  151. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/sv/LC_MESSAGES/bootstack.mo +0 -0
  152. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/sv/LC_MESSAGES/bootstack.po +0 -0
  153. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/tr/LC_MESSAGES/bootstack.mo +0 -0
  154. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/tr/LC_MESSAGES/bootstack.po +0 -0
  155. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.mo +0 -0
  156. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.po +0 -0
  157. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.mo +0 -0
  158. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.po +0 -0
  159. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/cli/__init__.py +0 -0
  160. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/cli/__main__.py +0 -0
  161. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/cli/add.py +0 -0
  162. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/cli/appicon.py +0 -0
  163. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/cli/build.py +0 -0
  164. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/cli/config.py +0 -0
  165. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/cli/demo.py +0 -0
  166. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/cli/dev.py +0 -0
  167. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/cli/doctor.py +0 -0
  168. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/cli/icons.py +0 -0
  169. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/cli/promote.py +0 -0
  170. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/cli/pyinstaller.py +0 -0
  171. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/cli/run.py +0 -0
  172. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/cli/start.py +0 -0
  173. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/cli/templates/__init__.py +0 -0
  174. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/clipboard.py +0 -0
  175. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/constants.py +0 -0
  176. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/data/README.md +0 -0
  177. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/data/__init__.py +0 -0
  178. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/data/_observable.py +0 -0
  179. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/data/base.py +0 -0
  180. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/data/file_source.py +0 -0
  181. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/data/memory_source.py +0 -0
  182. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/data/query.py +0 -0
  183. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/data/readers.py +0 -0
  184. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/data/sqlite_source.py +0 -0
  185. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/data/types.py +0 -0
  186. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/data/writers.py +0 -0
  187. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/dev/__init__.py +0 -0
  188. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/dev/_capture.py +0 -0
  189. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/dev/_env.py +0 -0
  190. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/dev/_registry.py +0 -0
  191. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/dev/_reloader.py +0 -0
  192. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/dev/_reset.py +0 -0
  193. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/dev/_watcher.py +0 -0
  194. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/dialogs/__init__.py +0 -0
  195. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/dialogs/_impl/__init__.py +0 -0
  196. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/dialogs/_impl/colorchooser.py +0 -0
  197. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/dialogs/_impl/datedialog.py +0 -0
  198. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/dialogs/_impl/dialog.py +0 -0
  199. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/dialogs/_impl/filterdialog.py +0 -0
  200. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/dialogs/_impl/fontdialog.py +0 -0
  201. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/dialogs/_impl/formdialog.py +0 -0
  202. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/dialogs/_impl/message.py +0 -0
  203. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/dialogs/_impl/query.py +0 -0
  204. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/errors.py +0 -0
  205. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/events/__init__.py +0 -0
  206. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/events/_event.py +0 -0
  207. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/events/_payloads.py +0 -0
  208. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/events/_subscription.py +0 -0
  209. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/i18n/README.md +0 -0
  210. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/i18n/__init__.py +0 -0
  211. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/i18n/catalog.py +0 -0
  212. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/i18n/intl_format.py +0 -0
  213. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/i18n/msgcat.py +0 -0
  214. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/i18n/specs.py +0 -0
  215. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/images.py +0 -0
  216. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/py.typed +0 -0
  217. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/scheduling/__init__.py +0 -0
  218. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/scheduling/_schedule.py +0 -0
  219. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/shortcuts.py +0 -0
  220. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/signals/README.md +0 -0
  221. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/signals/__init__.py +0 -0
  222. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/signals/integration.py +0 -0
  223. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/signals/signal.py +0 -0
  224. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/signals/types.py +0 -0
  225. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/store.py +0 -0
  226. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/streams/__init__.py +0 -0
  227. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/streams/_stream.py +0 -0
  228. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/__init__.py +0 -0
  229. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/__init__.py +0 -0
  230. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/badge.py +0 -0
  231. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/button.py +0 -0
  232. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/buttongroup.py +0 -0
  233. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/calendar.py +0 -0
  234. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/checkbutton.py +0 -0
  235. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/combobox.py +0 -0
  236. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/contextmenu.py +0 -0
  237. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/entry.py +0 -0
  238. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/expander.py +0 -0
  239. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/field.py +0 -0
  240. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/frame.py +0 -0
  241. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/label.py +0 -0
  242. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/labelframe.py +0 -0
  243. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/listview.py +0 -0
  244. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/menubar.py +0 -0
  245. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/menubutton.py +0 -0
  246. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/panedwindow.py +0 -0
  247. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/progressbar.py +0 -0
  248. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/radiobutton.py +0 -0
  249. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/scale.py +0 -0
  250. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/scrollbar.py +0 -0
  251. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/separator.py +0 -0
  252. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/sidenav.py +0 -0
  253. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/sizegrip.py +0 -0
  254. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/spinbox.py +0 -0
  255. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/switch.py +0 -0
  256. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/tabitem.py +0 -0
  257. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/togglegroup.py +0 -0
  258. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/toolbutton.py +0 -0
  259. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/tooltip.py +0 -0
  260. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/treeview.py +0 -0
  261. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders/utils.py +0 -0
  262. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders_tk/__init__.py +0 -0
  263. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/builders_tk/defaults.py +0 -0
  264. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/element.py +0 -0
  265. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/fonts.py +0 -0
  266. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/style.py +0 -0
  267. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/style_builder_base.py +0 -0
  268. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/style_builder_mixed.py +0 -0
  269. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/style_builder_tk.py +0 -0
  270. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/style_builder_ttk.py +0 -0
  271. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/style_resolver.py +0 -0
  272. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/theme.py +0 -0
  273. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/theme_provider.py +0 -0
  274. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/themes/__init__.py +0 -0
  275. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/tk_patch.py +0 -0
  276. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/token_maps.py +0 -0
  277. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/types.py +0 -0
  278. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/style/utility.py +0 -0
  279. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/types.py +0 -0
  280. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/validation/__init__.py +0 -0
  281. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/validation/types.py +0 -0
  282. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/validation/validation_result.py +0 -0
  283. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/validation/validation_rules.py +0 -0
  284. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/__init__.py +0 -0
  285. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_core/__init__.py +0 -0
  286. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_core/app_config.py +0 -0
  287. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_core/container.py +0 -0
  288. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_core/context.py +0 -0
  289. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_core/events.py +0 -0
  290. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_core/field_mixin.py +0 -0
  291. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_core/icon_image_props.py +0 -0
  292. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_core/image_binding.py +0 -0
  293. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_core/kwargs.py +0 -0
  294. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_core/navmodel.py +0 -0
  295. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_core/options.py +0 -0
  296. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_core/selection_group.py +0 -0
  297. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_core/window_controls.py +0 -0
  298. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_core/window_menu.py +0 -0
  299. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/__init__.py +0 -0
  300. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/_internal/__init__.py +0 -0
  301. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/_internal/wrapper_base.py +0 -0
  302. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/_parts/__init__.py +0 -0
  303. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/_parts/spinnerentry_part.py +0 -0
  304. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/_parts/textentry_part.py +0 -0
  305. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/__init__.py +0 -0
  306. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/_dateutils.py +0 -0
  307. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/_image_fit.py +0 -0
  308. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/accordion.py +0 -0
  309. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/avatar.py +0 -0
  310. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/buttongroup.py +0 -0
  311. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/calendar.py +0 -0
  312. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/carousel.py +0 -0
  313. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/chart.py +0 -0
  314. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/compositeframe.py +0 -0
  315. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/contextmenu.py +0 -0
  316. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/dateentry.py +0 -0
  317. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/dropdownbutton.py +0 -0
  318. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/expander.py +0 -0
  319. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/field.py +0 -0
  320. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/form.py +0 -0
  321. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/list/__init__.py +0 -0
  322. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/list/listitem.py +0 -0
  323. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/menu/__init__.py +0 -0
  324. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/menu/model.py +0 -0
  325. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/menu/render_native.py +0 -0
  326. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/menu/render_themed.py +0 -0
  327. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/meter.py +0 -0
  328. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/numericentry.py +0 -0
  329. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/pagestack.py +0 -0
  330. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/passwordentry.py +0 -0
  331. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/pathentry.py +0 -0
  332. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/picture.py +0 -0
  333. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/radiogroup.py +0 -0
  334. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/scrolledtext.pyi +0 -0
  335. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/selectbox.py +0 -0
  336. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/shell/__init__.py +0 -0
  337. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/shell/content_host.py +0 -0
  338. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/shell/layout.py +0 -0
  339. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/shell/nav_panel.py +0 -0
  340. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/shell/providers.py +0 -0
  341. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/shell/rail.py +0 -0
  342. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/shell/shell.py +0 -0
  343. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/shell/workspace.py +0 -0
  344. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/sidenav/__init__.py +0 -0
  345. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/sidenav/header.py +0 -0
  346. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/sidenav/separator.py +0 -0
  347. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/slider/__init__.py +0 -0
  348. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/slider/_shared.py +0 -0
  349. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/slider/rangeslider.py +0 -0
  350. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/slider/slider.py +0 -0
  351. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/spinnerentry.py +0 -0
  352. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/tableview/__init__.py +0 -0
  353. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/tableview/tableview.py +0 -0
  354. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/tableview/types.py +0 -0
  355. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/tabs/__init__.py +0 -0
  356. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/tabs/tabitem.py +0 -0
  357. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/tabs/tabview.py +0 -0
  358. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/textarea/__init__.py +0 -0
  359. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/textarea/change.py +0 -0
  360. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/textarea/codeeditor.py +0 -0
  361. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/textarea/decoration.py +0 -0
  362. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/textarea/diff.py +0 -0
  363. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/textarea/extensions/__init__.py +0 -0
  364. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/textarea/extensions/bracket_matcher.py +0 -0
  365. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/textarea/extensions/indent_guides.py +0 -0
  366. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/textarea/extensions/line_numbers.py +0 -0
  367. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/textarea/extensions/pygments_highlighter.py +0 -0
  368. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/textarea/extensions/smart_indent.py +0 -0
  369. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/textarea/filter.py +0 -0
  370. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/textarea/search_overlay.py +0 -0
  371. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/textarea/sidebar.py +0 -0
  372. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/textarea/style_registry.py +0 -0
  373. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/textarea/textarea.py +0 -0
  374. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/textarea/undo.py +0 -0
  375. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/textentry.py +0 -0
  376. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/timeentry.py +0 -0
  377. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/toast.py +0 -0
  378. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/toast_stack.py +0 -0
  379. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/togglegroup.py +0 -0
  380. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/toolbar.py +0 -0
  381. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/tooltip.py +0 -0
  382. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/tree/__init__.py +0 -0
  383. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/tree/source_binding.py +0 -0
  384. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/tree/treeitem.py +0 -0
  385. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/composites/tree/treenode.py +0 -0
  386. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/mixins/__init__.py +0 -0
  387. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/mixins/configure_mixin.py +0 -0
  388. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/mixins/entry_mixin.py +0 -0
  389. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/mixins/font_mixin.py +0 -0
  390. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/mixins/icon_mixin.py +0 -0
  391. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/mixins/localization_mixin.py +0 -0
  392. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/mixins/signal_mixin.py +0 -0
  393. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/mixins/validation_mixin.py +0 -0
  394. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/primitives/__init__.py +0 -0
  395. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/primitives/_menubutton.py +0 -0
  396. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/primitives/badge.py +0 -0
  397. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/primitives/button.py +0 -0
  398. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/primitives/card.py +0 -0
  399. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/primitives/checkbutton.py +0 -0
  400. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/primitives/checktoggle.py +0 -0
  401. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/primitives/combobox.py +0 -0
  402. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/primitives/entry.py +0 -0
  403. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/primitives/flexframe.py +0 -0
  404. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/primitives/frame.py +0 -0
  405. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/primitives/gridframe.py +0 -0
  406. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/primitives/label.py +0 -0
  407. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/primitives/labelframe.py +0 -0
  408. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/primitives/optionmenu.py +0 -0
  409. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/primitives/packframe.py +0 -0
  410. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/primitives/panedwindow.py +0 -0
  411. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/primitives/progressbar.py +0 -0
  412. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/primitives/radiobutton.py +0 -0
  413. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/primitives/radiotoggle.py +0 -0
  414. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/primitives/scrollbar.py +0 -0
  415. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/primitives/separator.py +0 -0
  416. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/primitives/sizegrip.py +0 -0
  417. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/primitives/switch.py +0 -0
  418. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/_impl/primitives/treeview.py +0 -0
  419. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/app.py +0 -0
  420. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/appshell.py +0 -0
  421. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/avatar.py +0 -0
  422. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/boolean_controls.py +0 -0
  423. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/button.py +0 -0
  424. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/buttongroup.py +0 -0
  425. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/calendar.py +0 -0
  426. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/card.py +0 -0
  427. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/carousel.py +0 -0
  428. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/chart.py +0 -0
  429. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/codeeditor.py +0 -0
  430. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/contextmenu.py +0 -0
  431. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/datatable.py +0 -0
  432. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/datefield.py +0 -0
  433. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/divider.py +0 -0
  434. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/expander.py +0 -0
  435. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/form.py +0 -0
  436. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/gallery.py +0 -0
  437. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/gauge.py +0 -0
  438. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/grid.py +0 -0
  439. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/groupbox.py +0 -0
  440. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/label.py +0 -0
  441. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/listview.py +0 -0
  442. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/menubutton.py +0 -0
  443. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/numberfield.py +0 -0
  444. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/pagestack.py +0 -0
  445. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/passwordfield.py +0 -0
  446. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/pathfield.py +0 -0
  447. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/picture.py +0 -0
  448. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/progressbar.py +0 -0
  449. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/radio_variants.py +0 -0
  450. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/radiogroup.py +0 -0
  451. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/scrollbar.py +0 -0
  452. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/scrollview.py +0 -0
  453. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/select.py +0 -0
  454. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/selectbutton.py +0 -0
  455. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/sidebar_toggle.py +0 -0
  456. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/sizegrip.py +0 -0
  457. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/slider.py +0 -0
  458. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/spinbox.py +0 -0
  459. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/spinnerfield.py +0 -0
  460. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/splash.py +0 -0
  461. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/splitview.py +0 -0
  462. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/stacks.py +0 -0
  463. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/statusbar.py +0 -0
  464. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/tabs.py +0 -0
  465. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/textarea.py +0 -0
  466. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/textfield.py +0 -0
  467. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/theme_toggle.py +0 -0
  468. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/timefield.py +0 -0
  469. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/toast.py +0 -0
  470. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/togglegroup.py +0 -0
  471. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/toolbar.py +0 -0
  472. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/tooltip.py +0 -0
  473. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/tree.py +0 -0
  474. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/types.py +0 -0
  475. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack/widgets/window.py +0 -0
  476. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack.egg-info/dependency_links.txt +0 -0
  477. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack.egg-info/entry_points.txt +0 -0
  478. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack.egg-info/requires.txt +0 -0
  479. {bootstack-0.1.6 → bootstack-0.1.8}/src/bootstack.egg-info/top_level.txt +0 -0
  480. {bootstack-0.1.6 → bootstack-0.1.8}/tests/test_dialog_anchor.py +0 -0
  481. {bootstack-0.1.6 → bootstack-0.1.8}/tests/test_events_doc_coverage.py +0 -0
  482. {bootstack-0.1.6 → bootstack-0.1.8}/tests/test_hot_reload.py +0 -0
  483. {bootstack-0.1.6 → bootstack-0.1.8}/tests/test_images.py +0 -0
  484. {bootstack-0.1.6 → bootstack-0.1.8}/tests/test_images_gui.py +0 -0
  485. {bootstack-0.1.6 → bootstack-0.1.8}/tests/test_intl_format.py +0 -0
  486. {bootstack-0.1.6 → bootstack-0.1.8}/tests/test_navmodel.py +0 -0
  487. {bootstack-0.1.6 → bootstack-0.1.8}/tests/test_on_color_contrast.py +0 -0
  488. {bootstack-0.1.6 → bootstack-0.1.8}/tests/test_public_surface.py +0 -0
  489. {bootstack-0.1.6 → bootstack-0.1.8}/tests/test_store.py +0 -0
  490. {bootstack-0.1.6 → bootstack-0.1.8}/tests/test_theme_from_existing.py +0 -0
  491. {bootstack-0.1.6 → bootstack-0.1.8}/tests/test_validation_rules.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bootstack
3
- Version: 0.1.6
3
+ Version: 0.1.8
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.1.6"
7
+ version = "0.1.8"
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.1.6"
117
+ current_version = "0.1.8"
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}",
@@ -30,11 +30,18 @@ def _platform_baseline() -> float:
30
30
 
31
31
  Tk scaling is measured in pixels-per-point (72 points per inch).
32
32
  - Windows/Linux default DPI is 96 → baseline = 96/72 ≈ 1.334
33
- - macOS default DPI is 72 → baseline = 72/72 = 1.0
33
+ - macOS default DPI is 72 on Tk 8.6 → baseline = 72/72 = 1.0
34
34
  (Retina pixel-doubling is handled by the OS, not Tk scaling)
35
+
36
+ Tk 9 changed Aqua's nominal resolution from 72 to 96 DPI, aligning it with
37
+ Windows/X11 (#375). The pixel grid is unchanged — only the physical-size
38
+ claim moved — so the baseline must key off the Tk version, not the platform
39
+ alone. Keying off platform alone reports ui_scale ~1.333 instead of 1.0 on
40
+ macOS + Tk 9 and inflates every DPI-derived measurement by a third.
35
41
  """
36
42
  import platform
37
- if platform.system() == 'Darwin':
43
+ import tkinter
44
+ if platform.system() == 'Darwin' and tkinter.TkVersion < 9.0:
38
45
  return 1.0
39
46
  return 1.33398982438864281 # 96 DPI / 72
40
47
 
@@ -54,6 +61,11 @@ class _ScalingState:
54
61
  """Get the current global scale factor."""
55
62
  return cls._scale_factor
56
63
 
64
+ @classmethod
65
+ def get_baseline(cls) -> float:
66
+ """Get the platform's nominal Tk scaling (pixels per point)."""
67
+ return cls._baseline
68
+
57
69
  @classmethod
58
70
  def get_ui_scale(cls) -> float:
59
71
  """Get the UI scale factor (relative to baseline)."""
@@ -0,0 +1,152 @@
1
+ """Scroll-gesture normalization across Tk 8.6 and Tk 9.
2
+
3
+ Tk 9 changed the scroll-event contract in two ways that break code written
4
+ against Tk 8.6:
5
+
6
+ * A precise-delta device — every Apple trackpad, Magic Mouse and Magic
7
+ Trackpad — now fires `<TouchpadScroll>` and **never** `<MouseWheel>`.
8
+ Binding only `<MouseWheel>` leaves those devices completely dead.
9
+ * Wheel deltas are normalized to multiples of 120 on every windowing
10
+ system. On Aqua a notch used to report 1; it now reports 120.
11
+
12
+ On X11, `<Button-4>`/`<Button-5>` are no longer delivered to scripts at
13
+ all — Tk translates them to `<MouseWheel>` internally.
14
+
15
+ This module hides all of that behind one vocabulary. Callers ask for the
16
+ sequences to bind, then convert an incoming event to either wheel
17
+ *notches* or precise *pixels*.
18
+
19
+ Sign convention (matching Tk's own bindings): a positive value means the
20
+ wheel rolled away from the user, i.e. the view should move toward the
21
+ *start* of the content. Callers therefore negate to get a scroll amount.
22
+ """
23
+
24
+ from __future__ import annotations
25
+
26
+ import tkinter as tk
27
+
28
+ TOUCHPAD_SCROLL = "<TouchpadScroll>"
29
+ """Sequence for precise-delta scroll gestures. Tk 8.7+ only."""
30
+
31
+ _WHEEL_UNITS = 120.0
32
+ """Delta reported for one wheel notch on a normalized (Tk 8.7+) build."""
33
+
34
+ _TOUCHPAD_TK = 8.7
35
+ """First Tk release generating `<TouchpadScroll>` and normalized deltas."""
36
+
37
+
38
+ def _windowingsystem(widget: tk.Misc) -> str:
39
+ try:
40
+ return str(widget.tk.call("tk", "windowingsystem")).lower()
41
+ except Exception:
42
+ return ""
43
+
44
+
45
+ def has_touchpad_scroll() -> bool:
46
+ """Whether the running Tk generates `<TouchpadScroll>` events."""
47
+ return tk.TkVersion >= _TOUCHPAD_TK
48
+
49
+
50
+ def uses_x11_buttons(widget: tk.Misc) -> bool:
51
+ """Whether wheel input arrives as `<Button-4>`/`<Button-5>` here.
52
+
53
+ True only on legacy X11 builds. Tk 8.7+ translates those buttons to
54
+ `<MouseWheel>` and stops delivering them to scripts.
55
+ """
56
+ return not has_touchpad_scroll() and _windowingsystem(widget) == "x11"
57
+
58
+
59
+ def wheel_sequences(widget: tk.Misc, *, shift: bool = False) -> tuple[str, ...]:
60
+ """Event sequences carrying wheel notches for `widget`.
61
+
62
+ Args:
63
+ widget: Any widget; used to resolve the windowing system.
64
+ shift: Request the horizontal (Shift-modified) sequences.
65
+ """
66
+ if uses_x11_buttons(widget):
67
+ if shift:
68
+ return ("<Shift-Button-4>", "<Shift-Button-5>")
69
+ return ("<Button-4>", "<Button-5>")
70
+ return ("<Shift-MouseWheel>",) if shift else ("<MouseWheel>",)
71
+
72
+
73
+ def wheel_notches(widget: tk.Misc, event: tk.Event) -> float:
74
+ """Signed notch count for a wheel event.
75
+
76
+ Returns a positive value when the wheel rolled away from the user.
77
+ One physical notch is 1.0 on every platform and Tk version.
78
+ """
79
+ num = getattr(event, "num", None)
80
+ if num in (4, 6):
81
+ return 1.0
82
+ if num in (5, 7):
83
+ return -1.0
84
+
85
+ try:
86
+ delta = float(event.delta)
87
+ except (AttributeError, TypeError, ValueError):
88
+ return 0.0
89
+ if not delta:
90
+ return 0.0
91
+
92
+ # Tk 8.6 on Aqua reported one notch as 1; everything else uses 120.
93
+ if not has_touchpad_scroll() and _windowingsystem(widget) == "aqua":
94
+ return delta
95
+ return delta / _WHEEL_UNITS
96
+
97
+
98
+ def precise_deltas(event: tk.Event) -> tuple[int, int]:
99
+ """Unpack a `<TouchpadScroll>` event into `(dx, dy)` pixels.
100
+
101
+ Tk packs both axes into the delta field as two signed 16-bit values.
102
+ This mirrors Tcl's `::tk::PreciseScrollDeltas`.
103
+ """
104
+ try:
105
+ packed = int(event.delta)
106
+ except (AttributeError, TypeError, ValueError):
107
+ return (0, 0)
108
+ dx = packed >> 16
109
+ low = packed & 0xFFFF
110
+ dy = low if low < 0x8000 else low - 0x10000
111
+ return (dx, dy)
112
+
113
+
114
+ def scale_num(widget: tk.Misc, value: float) -> int:
115
+ """Scale a pixel amount for display density, like `::tk::ScaleNum`."""
116
+ try:
117
+ scaling = float(widget.tk.call("tk", "scaling"))
118
+ except Exception:
119
+ scaling = 1.0
120
+ return round(value * scaling * 0.75)
121
+
122
+
123
+ class PixelAccumulator:
124
+ """Converts precise pixel deltas into whole discrete scroll steps.
125
+
126
+ A touchpad reports small deltas roughly sixty times a second. Widgets
127
+ that scroll by rows or canvas units cannot act on each one, so the
128
+ fractional remainder is carried forward until it adds up to a step.
129
+ """
130
+
131
+ __slots__ = ("_x", "_y")
132
+
133
+ def __init__(self) -> None:
134
+ self._x = 0.0
135
+ self._y = 0.0
136
+
137
+ def add(self, dx: float, dy: float, step_x: float, step_y: float) -> tuple[int, int]:
138
+ """Add a delta and return the whole `(x, y)` steps it completes."""
139
+ step_x = step_x if step_x and step_x > 0 else 1.0
140
+ step_y = step_y if step_y and step_y > 0 else 1.0
141
+ self._x += dx
142
+ self._y += dy
143
+ out_x = int(self._x / step_x)
144
+ out_y = int(self._y / step_y)
145
+ self._x -= out_x * step_x
146
+ self._y -= out_y * step_y
147
+ return (out_x, out_y)
148
+
149
+ def reset(self) -> None:
150
+ """Drop any carried remainder."""
151
+ self._x = 0.0
152
+ self._y = 0.0
@@ -8,6 +8,8 @@ from tkinter import Misc, font as tkfont
8
8
  from tkinter.font import Font as TkFont
9
9
  from typing import Any, Literal, NamedTuple
10
10
 
11
+ from bootstack._runtime.utility import _ScalingState
12
+
11
13
 
12
14
  # =============================================================================
13
15
  # Token model
@@ -90,12 +92,19 @@ def build_desktop_tokens(
90
92
  elif system == "darwin":
91
93
  default_ui = "SF Pro Text"
92
94
  default_mono = "Menlo"
93
- # Tk's pt-to-pixel conversion uses the active scaling factor.
94
- # macOS defaults to 1.0 (72 DPI baseline) vs ~1.334 on Win/Linux,
95
- # so the same point size renders ~25% smaller on Mac. Bump the
96
- # base to keep visual parity across platforms and align with the
97
- # macOS HIG default control text size (13pt).
98
- base = _clamp_base_size(base + 2)
95
+ # Tk's pt-to-pixel conversion uses the active scaling factor. On Tk 8.6
96
+ # macOS defaults to 1.0 (72 DPI baseline) vs ~1.334 on Win/Linux, so
97
+ # the same point size renders ~25% smaller on Mac. Bump the base to
98
+ # align with the macOS HIG default control text size (13pt).
99
+ #
100
+ # Tk 9 moved Aqua to a 96 DPI baseline (#375), so a "point" is no
101
+ # longer the same physical size and the raw bump double-counts (a
102
+ # `body` label rendered at 20px linespace instead of 16px). The target
103
+ # is a physical size, so express it in the active point unit: divide by
104
+ # the baseline ratio. Tk 8.6 -> 13pt (unchanged), Tk 9 -> 10pt, which
105
+ # is the same rendered size and matches the point size Tk 9 itself
106
+ # picks for TkDefaultFont.
107
+ base = _clamp_base_size(round((base + 2) / _ScalingState.get_baseline()))
99
108
  else:
100
109
  default_ui = "DejaVu Sans"
101
110
  default_mono = "DejaVu Sans Mono"
@@ -355,6 +355,7 @@ class PublicWidgetBase:
355
355
  options.update(_flex_child_opts(self, kwargs))
356
356
  master.add_child(self._internal, options, index=index)
357
357
  placement.options = options
358
+ self._recolor_on_attach()
358
359
  return
359
360
 
360
361
  if kwargs:
@@ -376,6 +377,29 @@ class PublicWidgetBase:
376
377
  options.update({k: v for k, v in kwargs.items() if k in PLACE_KEYS})
377
378
  self._internal.place(in_=master, **options)
378
379
  placement.options = options
380
+ self._recolor_on_attach()
381
+
382
+ def _recolor_on_attach(self) -> None:
383
+ """Recolor after a theme change that arrived while detached.
384
+
385
+ The theme walk skips off-screen widgets, so a widget detached across a
386
+ theme change comes back carrying the old palette. Attaching is the
387
+ genuine "now visible" trigger, matching PageStack navigation and
388
+ Expander expansion. Deferred to idle so the widget is mapped first.
389
+ """
390
+ widget = self._internal
391
+
392
+ def _recolor() -> None:
393
+ from bootstack.style.style import get_style
394
+ try:
395
+ get_style().apply_theme_walk(widget, only_stale=True)
396
+ except tkinter.TclError:
397
+ pass # destroyed between attach and the idle callback
398
+
399
+ try:
400
+ widget.after_idle(_recolor)
401
+ except tkinter.TclError:
402
+ pass
379
403
 
380
404
  @overload
381
405
  def on_destroy(self) -> "Stream": ...
@@ -6,10 +6,14 @@ wheel support.
6
6
  """
7
7
 
8
8
 
9
+ from bootstack._runtime import wheel
9
10
  from bootstack.events import ChangeEvent
10
11
  from bootstack.widgets._impl.mixins.configure_mixin import configure_delegate
11
12
  from bootstack.widgets._impl._parts.textentry_part import TextEntryPart
12
13
 
14
+ _TOUCHPAD_STEP_PX = 40
15
+ """Trackpad travel, in pixels, that advances a stepper by one increment."""
16
+
13
17
 
14
18
  class NumberEntryPart(TextEntryPart):
15
19
  """Numeric entry widget with stepping and bounds validation.
@@ -111,12 +115,13 @@ class NumberEntryPart(TextEntryPart):
111
115
  self.bind('<Up>', self._handle_up_key, add=True)
112
116
  self.bind('<Down>', self._handle_down_key, add=True)
113
117
 
114
- # Bind mouse wheel (Windows/macOS)
115
- self.bind('<MouseWheel>', self._handle_mouse_wheel, add=True)
116
-
117
- # Bind mouse wheel (Linux/X11)
118
- self.bind('<Button-4>', self._handle_wheel_up, add=True)
119
- self.bind('<Button-5>', self._handle_wheel_down, add=True)
118
+ # Bind wheel stepping. A wheel arrives as <MouseWheel> everywhere
119
+ # except legacy X11; a trackpad fires <TouchpadScroll> on Tk 8.7+.
120
+ for seq in wheel.wheel_sequences(self):
121
+ self.bind(seq, self._handle_mouse_wheel, add=True)
122
+ if wheel.has_touchpad_scroll():
123
+ self._touchpad = wheel.PixelAccumulator()
124
+ self.bind(wheel.TOUCHPAD_SCROLL, self._handle_touchpad_scroll, add=True)
120
125
 
121
126
  # Listen for increment/decrement events to invoke step
122
127
  self.bind('<<Increment>>', self._handle_increment_event, add=True)
@@ -137,33 +142,28 @@ class NumberEntryPart(TextEntryPart):
137
142
  return 'break' # Prevent default behavior
138
143
 
139
144
  def _handle_mouse_wheel(self, event):
140
- """Handle mouse wheel on Windows/macOS."""
145
+ """Handle a wheel notch by stepping the value once."""
141
146
  if not self._is_interactive():
142
147
  return 'break'
143
- try:
144
- delta = int(event.delta)
145
- except (AttributeError, ValueError):
146
- delta = 0
147
-
148
- if delta != 0:
149
- if delta > 0:
150
- self.event_generate('<<Increment>>', data={'value': self._value})
151
- else:
152
- self.event_generate('<<Decrement>>', data={'value': self._value})
148
+ notches = wheel.wheel_notches(self, event)
149
+ if notches:
150
+ name = '<<Increment>>' if notches > 0 else '<<Decrement>>'
151
+ self.event_generate(name, data={'value': self._value})
153
152
  return 'break'
154
153
 
155
- def _handle_wheel_up(self, event):
156
- """Handle mouse wheel up on Linux/X11."""
157
- if not self._is_interactive():
158
- return 'break'
159
- self.event_generate('<<Increment>>', data={'value': self._value})
160
- return 'break'
154
+ def _handle_touchpad_scroll(self, event):
155
+ """Step once per `_TOUCHPAD_STEP_PX` of trackpad travel.
161
156
 
162
- def _handle_wheel_down(self, event):
163
- """Handle mouse wheel down on Linux/X11."""
157
+ A trackpad reports around sixty events a second; stepping on each
158
+ one would run the value away from the user.
159
+ """
164
160
  if not self._is_interactive():
165
161
  return 'break'
166
- self.event_generate('<<Decrement>>', data={'value': self._value})
162
+ _dx, dy = wheel.precise_deltas(event)
163
+ _sx, steps = self._touchpad.add(0, dy, 1, _TOUCHPAD_STEP_PX)
164
+ name = '<<Increment>>' if steps > 0 else '<<Decrement>>'
165
+ for _ in range(abs(steps)):
166
+ self.event_generate(name, data={'value': self._value})
167
167
  return 'break'
168
168
 
169
169
  def _handle_increment_event(self, event):
@@ -20,6 +20,7 @@ from PIL import Image as PILImage, ImageDraw
20
20
  from PIL.Image import Resampling
21
21
  from PIL.ImageTk import PhotoImage
22
22
 
23
+ from bootstack._runtime import wheel
23
24
  from bootstack.data import MemoryDataSource, DataSourceProtocol
24
25
  from bootstack.style.style import get_style
25
26
  from bootstack.widgets._impl.composites._image_fit import (
@@ -223,6 +224,7 @@ class Gallery(Frame):
223
224
  self._start_row = 0
224
225
  self._ring_photo: PhotoImage | None = None
225
226
  self._row_h = self._th + 2 * _RING_PAD + (_CAPTION_H if caption_field else 0) + gap
227
+ self._touchpad = wheel.PixelAccumulator()
226
228
 
227
229
  sb_surface = getattr(self, '_surface', None)
228
230
  sb_kw = {'surface': sb_surface} if sb_surface else {}
@@ -450,22 +452,32 @@ class Gallery(Frame):
450
452
  self._update_tiles()
451
453
 
452
454
  def _bind_scroll(self, widget) -> None:
453
- widget.bind("<MouseWheel>", self._on_wheel, add="+")
454
- widget.bind("<Button-4>", self._on_wheel, add="+")
455
- widget.bind("<Button-5>", self._on_wheel, add="+")
455
+ for seq in wheel.wheel_sequences(self):
456
+ widget.bind(seq, self._on_wheel, add="+")
457
+ if wheel.has_touchpad_scroll():
458
+ widget.bind(wheel.TOUCHPAD_SCROLL, self._on_touchpad_scroll, add="+")
456
459
 
457
460
  def _on_wheel(self, event) -> None:
458
- if getattr(event, "num", None) == 4:
459
- delta = 1
460
- elif getattr(event, "num", None) == 5:
461
- delta = -1
462
- else:
463
- delta = 1 if event.delta < 0 else -1
464
- self._start_row += delta
461
+ notches = wheel.wheel_notches(self, event)
462
+ if not notches:
463
+ return "break"
464
+ self._start_row += -1 if notches > 0 else 1
465
465
  self._clamp()
466
466
  self._update_tiles()
467
467
  return "break"
468
468
 
469
+ def _on_touchpad_scroll(self, event) -> None:
470
+ """Scroll by whole tile rows as a trackpad gesture accumulates pixels."""
471
+ _dx, dy = wheel.precise_deltas(event)
472
+ if not dy:
473
+ return "break"
474
+ _sx, rows = self._touchpad.add(0, dy, 1, self._row_h or 1)
475
+ if rows:
476
+ self._start_row -= rows
477
+ self._clamp()
478
+ self._update_tiles()
479
+ return "break"
480
+
469
481
  def scroll_to_top(self) -> None:
470
482
  self._start_row = 0
471
483
  self._update_tiles()
@@ -5,6 +5,7 @@ from tkinter import TclError
5
5
  from typing import Any, Callable, Literal
6
6
  from typing_extensions import Unpack
7
7
 
8
+ from bootstack._runtime import wheel
8
9
  from bootstack.data import MemoryDataSource, DataSourceProtocol
9
10
  from bootstack.widgets._impl.composites.list.listitem import ListItem
10
11
  from bootstack.widgets._impl.primitives.frame import Frame, FrameKwargs
@@ -87,9 +88,8 @@ class ListView(Frame):
87
88
 
88
89
  self._accent = _user_accent or 'primary'
89
90
 
90
- # Cache the windowing system so scroll bindings can dispatch
91
- # platform-correctly: Aqua/Win send <MouseWheel>, X11 sends
92
- # <Button-4>/<Button-5>.
91
+ # Cached for the platform branches elsewhere in this widget; scroll
92
+ # bindings resolve their own sequences through `_runtime.wheel`.
93
93
  self.winsys = self.tk.call('tk', 'windowingsystem')
94
94
 
95
95
  # Configuration
@@ -114,6 +114,7 @@ class ListView(Frame):
114
114
  self._prev_start_index = 0
115
115
  self._visible_rows = VISIBLE_ROWS
116
116
  self._row_height = ROW_HEIGHT
117
+ self._touchpad = wheel.PixelAccumulator()
117
118
  self._page_size = VISIBLE_ROWS + OVERSCAN_ROWS
118
119
 
119
120
  # Data source
@@ -570,49 +571,62 @@ class ListView(Frame):
570
571
  def _bind_scroll_events(self, widget) -> None:
571
572
  """Bind the platform-correct scroll-wheel events to `widget`.
572
573
 
573
- On Aqua/Win the event is `<MouseWheel>` with `event.delta`
574
- carrying direction and magnitude. On X11 there's no MouseWheel —
575
- scroll up is `<Button-4>` and scroll down is `<Button-5>`.
574
+ A wheel arrives as `<MouseWheel>` everywhere except legacy X11,
575
+ where it is `<Button-4>`/`<Button-5>`. A trackpad or other
576
+ precise-delta device instead fires `<TouchpadScroll>` on Tk 8.7+.
576
577
  """
577
- if self.winsys.lower() == 'x11':
578
- widget.bind('<Button-4>', self._on_mousewheel, add='+')
579
- widget.bind('<Button-5>', self._on_mousewheel, add='+')
580
- else:
581
- widget.bind('<MouseWheel>', self._on_mousewheel, add='+')
582
-
583
- def _on_mousewheel(self, event):
584
- """Handle mouse wheel scrolling.
578
+ for seq in wheel.wheel_sequences(self):
579
+ widget.bind(seq, self._on_mousewheel, add='+')
580
+ if wheel.has_touchpad_scroll():
581
+ widget.bind(wheel.TOUCHPAD_SCROLL, self._on_touchpad_scroll, add='+')
585
582
 
586
- Args:
587
- event: Tkinter mouse wheel event.
588
- """
589
- # Check if mouse is over this widget
583
+ def _pointer_within(self, event) -> bool:
584
+ """Whether the pointer is over this list or one of its descendants."""
590
585
  widget_under_mouse = self.winfo_containing(event.x_root, event.y_root)
591
586
  if widget_under_mouse is None:
592
- return
593
-
594
- # Check if the widget under mouse is a child of this ListView
587
+ return False
595
588
  current = widget_under_mouse
596
- is_child = False
597
589
  while current is not None:
598
590
  if current == self:
599
- is_child = True
600
- break
591
+ return True
601
592
  try:
602
593
  current = current.master
603
594
  except AttributeError:
604
595
  break
596
+ return False
597
+
598
+ def _on_mousewheel(self, event):
599
+ """Handle mouse wheel scrolling.
605
600
 
606
- if not is_child:
601
+ Args:
602
+ event: Tkinter mouse wheel event.
603
+ """
604
+ if not self._pointer_within(event):
607
605
  return
608
606
 
609
- # Resolve scroll direction per platform: X11 carries it in event.num
610
- # (4=up, 5=down) and has no event.delta; Aqua/Win use event.delta.
611
- if self.winsys.lower() == 'x11':
612
- delta = -1 if getattr(event, 'num', 0) == 4 else 1
613
- else:
614
- delta = -1 if event.delta > 0 else 1
615
- self._start_index += delta
607
+ notches = wheel.wheel_notches(self, event)
608
+ if not notches:
609
+ return
610
+ self._start_index += -1 if notches > 0 else 1
611
+ self._clamp_indices()
612
+ self._update_rows()
613
+
614
+ def _on_touchpad_scroll(self, event):
615
+ """Scroll by whole rows as a trackpad gesture accumulates pixels.
616
+
617
+ Args:
618
+ event: Tkinter touchpad scroll event.
619
+ """
620
+ if not self._pointer_within(event):
621
+ return
622
+
623
+ _dx, dy = wheel.precise_deltas(event)
624
+ if not dy:
625
+ return
626
+ _sx, rows = self._touchpad.add(0, dy, 1, self._row_height or 1)
627
+ if not rows:
628
+ return
629
+ self._start_index -= rows
616
630
  self._clamp_indices()
617
631
  self._update_rows()
618
632
 
@@ -6,6 +6,7 @@ from bootstack.widgets._impl.primitives.frame import Frame
6
6
  from bootstack.widgets._impl.mixins.configure_mixin import configure_delegate
7
7
  from bootstack.widgets._impl.primitives.scrollbar import Scrollbar
8
8
  from bootstack.widgets.types import Master
9
+ from bootstack._runtime import wheel
9
10
 
10
11
  ScrollDirection = Literal['horizontal', 'vertical', 'both']
11
12
  ScrollbarVisibility = Literal['always', 'never', 'hover', 'scroll']
@@ -176,14 +177,12 @@ class ScrolledText(Frame):
176
177
 
177
178
  def _setup_scroll_tag_bindings(self):
178
179
  """Setup bindings on our custom bind tag."""
179
- if self.winsys.lower() == "x11":
180
- self.bind_class(self._scroll_tag, "<Button-4>", self._on_mousewheel)
181
- self.bind_class(self._scroll_tag, "<Button-5>", self._on_mousewheel)
182
- self.bind_class(self._scroll_tag, "<Shift-Button-4>", self._on_shift_mousewheel)
183
- self.bind_class(self._scroll_tag, "<Shift-Button-5>", self._on_shift_mousewheel)
184
- else:
185
- self.bind_class(self._scroll_tag, "<MouseWheel>", self._on_mousewheel)
186
- self.bind_class(self._scroll_tag, "<Shift-MouseWheel>", self._on_shift_mousewheel)
180
+ for seq in wheel.wheel_sequences(self):
181
+ self.bind_class(self._scroll_tag, seq, self._on_mousewheel)
182
+ for seq in wheel.wheel_sequences(self, shift=True):
183
+ self.bind_class(self._scroll_tag, seq, self._on_shift_mousewheel)
184
+ if wheel.has_touchpad_scroll():
185
+ self.bind_class(self._scroll_tag, wheel.TOUCHPAD_SCROLL, self._on_touchpad_scroll)
187
186
 
188
187
  def _layout_widgets(self):
189
188
  """Layout the text widget and scrollbars."""
@@ -265,16 +264,7 @@ class ScrolledText(Frame):
265
264
  self.after_cancel(self._hide_timer)
266
265
  self._hide_timer = self.after(self._autohide_delay, self._hide_scrollbars)
267
266
 
268
- # Calculate delta based on platform
269
- delta = 0
270
- if self.winsys.lower() == "win32":
271
- delta = -int(event.delta / 120)
272
- elif self.winsys.lower() == "aqua":
273
- delta = -event.delta
274
- elif event.num == 4:
275
- delta = -1
276
- elif event.num == 5:
277
- delta = 1
267
+ delta = -round(wheel.wheel_notches(self, event))
278
268
 
279
269
  # Scroll vertically
280
270
  if self._direction in ('vertical', 'both') and delta != 0:
@@ -289,21 +279,33 @@ class ScrolledText(Frame):
289
279
  self.after_cancel(self._hide_timer)
290
280
  self._hide_timer = self.after(self._autohide_delay, self._hide_scrollbars)
291
281
 
292
- # Calculate delta based on platform
293
- delta = 0
294
- if self.winsys.lower() == "win32":
295
- delta = -int(event.delta / 120)
296
- elif self.winsys.lower() == "aqua":
297
- delta = -event.delta
298
- elif event.num == 4:
299
- delta = -1
300
- elif event.num == 5:
301
- delta = 1
282
+ delta = -round(wheel.wheel_notches(self, event))
302
283
 
303
284
  # Scroll horizontally
304
285
  if self._direction in ('horizontal', 'both') and delta != 0:
305
286
  self._text.xview_scroll(delta, 'units')
306
287
 
288
+ def _on_touchpad_scroll(self, event):
289
+ """Handle a precise-delta scroll gesture (trackpad).
290
+
291
+ A text widget scrolls by pixels directly, so the deltas are spent
292
+ as they arrive rather than accumulated into whole lines.
293
+ """
294
+ dx, dy = wheel.precise_deltas(event)
295
+ if not dx and not dy:
296
+ return
297
+
298
+ if self._scrollbar_visibility == 'scroll':
299
+ self._show_scrollbars()
300
+ if self._hide_timer:
301
+ self.after_cancel(self._hide_timer)
302
+ self._hide_timer = self.after(self._autohide_delay, self._hide_scrollbars)
303
+
304
+ if dy and self._direction in ('vertical', 'both'):
305
+ self._text.yview_scroll(wheel.scale_num(self, -dy), 'pixels')
306
+ if dx and self._direction in ('horizontal', 'both'):
307
+ self._text.xview_scroll(wheel.scale_num(self, -dx), 'pixels')
308
+
307
309
  def _add_scroll_binding(self, widget):
308
310
  """Add scroll bind tag to widget."""
309
311
  try:
@@ -325,14 +327,10 @@ class ScrolledText(Frame):
325
327
  self._hide_timer = None
326
328
 
327
329
  # Unbind class bindings for the scroll tag
328
- if self.winsys.lower() == "x11":
329
- self.unbind_class(self._scroll_tag, "<Button-4>")
330
- self.unbind_class(self._scroll_tag, "<Button-5>")
331
- self.unbind_class(self._scroll_tag, "<Shift-Button-4>")
332
- self.unbind_class(self._scroll_tag, "<Shift-Button-5>")
333
- else:
334
- self.unbind_class(self._scroll_tag, "<MouseWheel>")
335
- self.unbind_class(self._scroll_tag, "<Shift-MouseWheel>")
330
+ for seq in wheel.wheel_sequences(self) + wheel.wheel_sequences(self, shift=True):
331
+ self.unbind_class(self._scroll_tag, seq)
332
+ if wheel.has_touchpad_scroll():
333
+ self.unbind_class(self._scroll_tag, wheel.TOUCHPAD_SCROLL)
336
334
 
337
335
  # Call parent destroy
338
336
  super().destroy()