bootstack 0.3.1__tar.gz → 0.3.2__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 (494) hide show
  1. {bootstack-0.3.1/src/bootstack.egg-info → bootstack-0.3.2}/PKG-INFO +1 -1
  2. {bootstack-0.3.1 → bootstack-0.3.2}/pyproject.toml +2 -2
  3. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/selectbox.py +151 -32
  4. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/select.py +20 -7
  5. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/timefield.py +23 -7
  6. {bootstack-0.3.1 → bootstack-0.3.2/src/bootstack.egg-info}/PKG-INFO +1 -1
  7. {bootstack-0.3.1 → bootstack-0.3.2}/LICENSE +0 -0
  8. {bootstack-0.3.1 → bootstack-0.3.2}/MANIFEST.in +0 -0
  9. {bootstack-0.3.1 → bootstack-0.3.2}/NOTICE +0 -0
  10. {bootstack-0.3.1 → bootstack-0.3.2}/README.md +0 -0
  11. {bootstack-0.3.1 → bootstack-0.3.2}/setup.cfg +0 -0
  12. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/__init__.py +0 -0
  13. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/__main__.py +0 -0
  14. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_core/__init__.py +0 -0
  15. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_core/capabilities/__init__.py +0 -0
  16. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_core/capabilities/after.py +0 -0
  17. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_core/capabilities/bind.py +0 -0
  18. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_core/capabilities/bindtags.py +0 -0
  19. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_core/capabilities/busy.py +0 -0
  20. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_core/capabilities/clipboard.py +0 -0
  21. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_core/capabilities/focus.py +0 -0
  22. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_core/capabilities/grab.py +0 -0
  23. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_core/capabilities/grid.py +0 -0
  24. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_core/capabilities/localization.py +0 -0
  25. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_core/capabilities/pack.py +0 -0
  26. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_core/capabilities/place.py +0 -0
  27. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_core/capabilities/selection.py +0 -0
  28. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_core/capabilities/signals.py +0 -0
  29. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_core/capabilities/winfo.py +0 -0
  30. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_core/capture.py +0 -0
  31. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_core/colorutils.py +0 -0
  32. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_core/exceptions.py +0 -0
  33. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_core/images.py +0 -0
  34. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_core/mixins/__init__.py +0 -0
  35. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_core/mixins/ttk_state.py +0 -0
  36. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_core/mixins/widget.py +0 -0
  37. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_core/paths.py +0 -0
  38. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_core/publisher.py +0 -0
  39. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_core/variables.py +0 -0
  40. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_runtime/__init__.py +0 -0
  41. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_runtime/app.py +0 -0
  42. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_runtime/base_window.py +0 -0
  43. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_runtime/events.py +0 -0
  44. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_runtime/shortcuts.py +0 -0
  45. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_runtime/tk_patch.py +0 -0
  46. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_runtime/toplevel.py +0 -0
  47. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_runtime/utility.py +0 -0
  48. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_runtime/visual_focus.py +0 -0
  49. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_runtime/wheel.py +0 -0
  50. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/_runtime/window_utilities.py +0 -0
  51. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/__init__.py +0 -0
  52. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/bootstack.ico +0 -0
  53. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/bootstack.png +0 -0
  54. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/__init__.py +0 -0
  55. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/badge-pill.png +0 -0
  56. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/badge-square.png +0 -0
  57. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/button-compact.png +0 -0
  58. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/button-default.png +0 -0
  59. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/buttongroup-after-h-compact.png +0 -0
  60. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/buttongroup-after-h-default.png +0 -0
  61. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/buttongroup-after-v-compact.png +0 -0
  62. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/buttongroup-after-v-default.png +0 -0
  63. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/buttongroup-before-h-compact.png +0 -0
  64. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/buttongroup-before-h-default.png +0 -0
  65. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/buttongroup-before-v-compact.png +0 -0
  66. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/buttongroup-before-v-default.png +0 -0
  67. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/buttongroup-center-h-compact.png +0 -0
  68. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/buttongroup-center-h-default.png +0 -0
  69. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/buttongroup-center-v-compact.png +0 -0
  70. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/buttongroup-center-v-default.png +0 -0
  71. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/card.png +0 -0
  72. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/checkbox-checked.png +0 -0
  73. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/checkbox-indeterminate.png +0 -0
  74. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/checkbox-unchecked.png +0 -0
  75. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/field.png +0 -0
  76. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/input-addon-compact.png +0 -0
  77. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/input-addon-default.png +0 -0
  78. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/input-compact.png +0 -0
  79. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/input-default.png +0 -0
  80. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/list-item-separated.png +0 -0
  81. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/list-item.png +0 -0
  82. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/listrow-compact.png +0 -0
  83. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/listrow-default.png +0 -0
  84. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/manifest.toml +0 -0
  85. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/menu-item.png +0 -0
  86. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/navitem-compact.png +0 -0
  87. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/navitem-default.png +0 -0
  88. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/progressbar-h-compact.png +0 -0
  89. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/progressbar-h-default.png +0 -0
  90. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/progressbar-v-compact.png +0 -0
  91. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/progressbar-v-default.png +0 -0
  92. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/radiobutton.png +0 -0
  93. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/scrollbar-horizontal.png +0 -0
  94. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/scrollbar-vertical.png +0 -0
  95. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/slider-handle.png +0 -0
  96. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/slider-track-h.png +0 -0
  97. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/slider-track-v.png +0 -0
  98. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/switch-off.png +0 -0
  99. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/switch-on.png +0 -0
  100. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/tab-h.png +0 -0
  101. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/elements/tab-v.png +0 -0
  102. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/icons/bootstrap.ttf +0 -0
  103. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/icons/glyphmap.json +0 -0
  104. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/icons/icon_metrics.json +0 -0
  105. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/ar/LC_MESSAGES/bootstack.mo +0 -0
  106. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/ar/LC_MESSAGES/bootstack.po +0 -0
  107. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/bg/LC_MESSAGES/bootstack.mo +0 -0
  108. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/bg/LC_MESSAGES/bootstack.po +0 -0
  109. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/cs/LC_MESSAGES/bootstack.mo +0 -0
  110. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/cs/LC_MESSAGES/bootstack.po +0 -0
  111. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/da/LC_MESSAGES/bootstack.mo +0 -0
  112. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/da/LC_MESSAGES/bootstack.po +0 -0
  113. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/de/LC_MESSAGES/bootstack.mo +0 -0
  114. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/de/LC_MESSAGES/bootstack.po +0 -0
  115. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/en/LC_MESSAGES/bootstack.mo +0 -0
  116. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/en/LC_MESSAGES/bootstack.po +0 -0
  117. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/es/LC_MESSAGES/bootstack.mo +0 -0
  118. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/es/LC_MESSAGES/bootstack.po +0 -0
  119. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/fr/LC_MESSAGES/bootstack.mo +0 -0
  120. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/fr/LC_MESSAGES/bootstack.po +0 -0
  121. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/he/LC_MESSAGES/bootstack.mo +0 -0
  122. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/he/LC_MESSAGES/bootstack.po +0 -0
  123. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/hi/LC_MESSAGES/bootstack.mo +0 -0
  124. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/hi/LC_MESSAGES/bootstack.po +0 -0
  125. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/it/LC_MESSAGES/bootstack.mo +0 -0
  126. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/it/LC_MESSAGES/bootstack.po +0 -0
  127. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/ja/LC_MESSAGES/bootstack.mo +0 -0
  128. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/ja/LC_MESSAGES/bootstack.po +0 -0
  129. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/ko/LC_MESSAGES/bootstack.mo +0 -0
  130. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/ko/LC_MESSAGES/bootstack.po +0 -0
  131. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/nb/LC_MESSAGES/bootstack.mo +0 -0
  132. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/nb/LC_MESSAGES/bootstack.po +0 -0
  133. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/nl/LC_MESSAGES/bootstack.mo +0 -0
  134. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/nl/LC_MESSAGES/bootstack.po +0 -0
  135. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/pl/LC_MESSAGES/bootstack.mo +0 -0
  136. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/pl/LC_MESSAGES/bootstack.po +0 -0
  137. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/pt/LC_MESSAGES/bootstack.mo +0 -0
  138. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/pt/LC_MESSAGES/bootstack.po +0 -0
  139. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.mo +0 -0
  140. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.po +0 -0
  141. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/sl/LC_MESSAGES/bootstack.mo +0 -0
  142. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/sl/LC_MESSAGES/bootstack.po +0 -0
  143. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/sv/LC_MESSAGES/bootstack.mo +0 -0
  144. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/sv/LC_MESSAGES/bootstack.po +0 -0
  145. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/tr/LC_MESSAGES/bootstack.mo +0 -0
  146. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/tr/LC_MESSAGES/bootstack.po +0 -0
  147. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.mo +0 -0
  148. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.po +0 -0
  149. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.mo +0 -0
  150. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.po +0 -0
  151. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/cli/__init__.py +0 -0
  152. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/cli/__main__.py +0 -0
  153. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/cli/add.py +0 -0
  154. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/cli/appicon.py +0 -0
  155. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/cli/build.py +0 -0
  156. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/cli/config.py +0 -0
  157. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/cli/demo.py +0 -0
  158. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/cli/dev.py +0 -0
  159. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/cli/doctor.py +0 -0
  160. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/cli/icons.py +0 -0
  161. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/cli/promote.py +0 -0
  162. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/cli/pyinstaller.py +0 -0
  163. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/cli/run.py +0 -0
  164. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/cli/start.py +0 -0
  165. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/cli/templates/__init__.py +0 -0
  166. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/clipboard.py +0 -0
  167. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/constants.py +0 -0
  168. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/data/README.md +0 -0
  169. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/data/__init__.py +0 -0
  170. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/data/_observable.py +0 -0
  171. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/data/base.py +0 -0
  172. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/data/file_source.py +0 -0
  173. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/data/memory_source.py +0 -0
  174. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/data/query.py +0 -0
  175. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/data/readers.py +0 -0
  176. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/data/sqlite_source.py +0 -0
  177. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/data/types.py +0 -0
  178. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/data/writers.py +0 -0
  179. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/dev/__init__.py +0 -0
  180. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/dev/_capture.py +0 -0
  181. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/dev/_env.py +0 -0
  182. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/dev/_registry.py +0 -0
  183. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/dev/_reloader.py +0 -0
  184. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/dev/_reset.py +0 -0
  185. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/dev/_watcher.py +0 -0
  186. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/dialogs/__init__.py +0 -0
  187. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/dialogs/_impl/__init__.py +0 -0
  188. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/dialogs/_impl/colorchooser.py +0 -0
  189. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/dialogs/_impl/datedialog.py +0 -0
  190. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/dialogs/_impl/dialog.py +0 -0
  191. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/dialogs/_impl/filterdialog.py +0 -0
  192. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/dialogs/_impl/fontdialog.py +0 -0
  193. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/dialogs/_impl/formdialog.py +0 -0
  194. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/dialogs/_impl/message.py +0 -0
  195. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/dialogs/_impl/query.py +0 -0
  196. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/errors.py +0 -0
  197. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/events/__init__.py +0 -0
  198. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/events/_event.py +0 -0
  199. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/events/_payloads.py +0 -0
  200. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/events/_subscription.py +0 -0
  201. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/i18n/README.md +0 -0
  202. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/i18n/__init__.py +0 -0
  203. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/i18n/catalog.py +0 -0
  204. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/i18n/intl_format.py +0 -0
  205. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/i18n/msgcat.py +0 -0
  206. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/i18n/specs.py +0 -0
  207. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/images.py +0 -0
  208. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/py.typed +0 -0
  209. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/scheduling/__init__.py +0 -0
  210. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/scheduling/_schedule.py +0 -0
  211. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/shortcuts.py +0 -0
  212. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/signals/README.md +0 -0
  213. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/signals/__init__.py +0 -0
  214. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/signals/integration.py +0 -0
  215. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/signals/signal.py +0 -0
  216. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/signals/types.py +0 -0
  217. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/store.py +0 -0
  218. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/streams/__init__.py +0 -0
  219. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/streams/_stream.py +0 -0
  220. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/__init__.py +0 -0
  221. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/__init__.py +0 -0
  222. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/badge.py +0 -0
  223. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/button.py +0 -0
  224. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/buttongroup.py +0 -0
  225. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/calendar.py +0 -0
  226. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/checkbutton.py +0 -0
  227. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/combobox.py +0 -0
  228. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/contextmenu.py +0 -0
  229. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/entry.py +0 -0
  230. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/expander.py +0 -0
  231. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/field.py +0 -0
  232. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/frame.py +0 -0
  233. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/label.py +0 -0
  234. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/labelframe.py +0 -0
  235. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/listview.py +0 -0
  236. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/menubar.py +0 -0
  237. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/menubutton.py +0 -0
  238. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/panedwindow.py +0 -0
  239. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/progressbar.py +0 -0
  240. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/radiobutton.py +0 -0
  241. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/scale.py +0 -0
  242. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/scrollbar.py +0 -0
  243. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/separator.py +0 -0
  244. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/sidenav.py +0 -0
  245. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/sizegrip.py +0 -0
  246. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/spinbox.py +0 -0
  247. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/switch.py +0 -0
  248. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/tabitem.py +0 -0
  249. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/togglegroup.py +0 -0
  250. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/toolbutton.py +0 -0
  251. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/tooltip.py +0 -0
  252. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/treeview.py +0 -0
  253. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders/utils.py +0 -0
  254. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders_tk/__init__.py +0 -0
  255. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/builders_tk/defaults.py +0 -0
  256. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/element.py +0 -0
  257. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/fonts.py +0 -0
  258. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/style.py +0 -0
  259. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/style_builder_base.py +0 -0
  260. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/style_builder_mixed.py +0 -0
  261. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/style_builder_tk.py +0 -0
  262. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/style_builder_ttk.py +0 -0
  263. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/style_resolver.py +0 -0
  264. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/theme.py +0 -0
  265. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/theme_provider.py +0 -0
  266. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/themes/__init__.py +0 -0
  267. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/tk_patch.py +0 -0
  268. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/token_maps.py +0 -0
  269. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/types.py +0 -0
  270. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/typography.py +0 -0
  271. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/style/utility.py +0 -0
  272. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/types.py +0 -0
  273. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/validation/__init__.py +0 -0
  274. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/validation/types.py +0 -0
  275. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/validation/validation_result.py +0 -0
  276. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/validation/validation_rules.py +0 -0
  277. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/__init__.py +0 -0
  278. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_core/__init__.py +0 -0
  279. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_core/app_config.py +0 -0
  280. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_core/base.py +0 -0
  281. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_core/choices.py +0 -0
  282. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_core/container.py +0 -0
  283. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_core/context.py +0 -0
  284. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_core/events.py +0 -0
  285. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_core/field_mixin.py +0 -0
  286. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_core/icon_image_props.py +0 -0
  287. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_core/image_binding.py +0 -0
  288. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_core/kwargs.py +0 -0
  289. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_core/navmodel.py +0 -0
  290. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_core/options.py +0 -0
  291. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_core/selection_group.py +0 -0
  292. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_core/window_controls.py +0 -0
  293. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_core/window_menu.py +0 -0
  294. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/__init__.py +0 -0
  295. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/_internal/__init__.py +0 -0
  296. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/_internal/wrapper_base.py +0 -0
  297. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/_parts/__init__.py +0 -0
  298. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/_parts/numberentry_part.py +0 -0
  299. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/_parts/spinnerentry_part.py +0 -0
  300. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/_parts/textentry_part.py +0 -0
  301. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/__init__.py +0 -0
  302. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/_dateutils.py +0 -0
  303. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/_image_fit.py +0 -0
  304. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/accordion.py +0 -0
  305. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/avatar.py +0 -0
  306. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/buttongroup.py +0 -0
  307. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/calendar.py +0 -0
  308. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/carousel.py +0 -0
  309. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/chart.py +0 -0
  310. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/compositeframe.py +0 -0
  311. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/contextmenu.py +0 -0
  312. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/dateentry.py +0 -0
  313. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/dropdownbutton.py +0 -0
  314. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/expander.py +0 -0
  315. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/field.py +0 -0
  316. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/form.py +0 -0
  317. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/gallery.py +0 -0
  318. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/list/__init__.py +0 -0
  319. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/list/listitem.py +0 -0
  320. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/list/listview.py +0 -0
  321. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/menu/__init__.py +0 -0
  322. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/menu/model.py +0 -0
  323. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/menu/render_native.py +0 -0
  324. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/menu/render_themed.py +0 -0
  325. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/meter.py +0 -0
  326. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/numericentry.py +0 -0
  327. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/pagestack.py +0 -0
  328. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/passwordentry.py +0 -0
  329. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/pathentry.py +0 -0
  330. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/picture.py +0 -0
  331. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/radiogroup.py +0 -0
  332. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/scrolledtext.py +0 -0
  333. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/scrolledtext.pyi +0 -0
  334. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/scrollview.py +0 -0
  335. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/shell/__init__.py +0 -0
  336. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/shell/content_host.py +0 -0
  337. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/shell/layout.py +0 -0
  338. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/shell/nav_panel.py +0 -0
  339. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/shell/providers.py +0 -0
  340. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/shell/rail.py +0 -0
  341. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/shell/shell.py +0 -0
  342. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/shell/workspace.py +0 -0
  343. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/sidenav/__init__.py +0 -0
  344. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/sidenav/header.py +0 -0
  345. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/sidenav/separator.py +0 -0
  346. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/slider/__init__.py +0 -0
  347. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/slider/_shared.py +0 -0
  348. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/slider/rangeslider.py +0 -0
  349. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/slider/slider.py +0 -0
  350. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/spinnerentry.py +0 -0
  351. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/tableview/__init__.py +0 -0
  352. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/tableview/tableview.py +0 -0
  353. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/tableview/types.py +0 -0
  354. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/tabs/__init__.py +0 -0
  355. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/tabs/tabitem.py +0 -0
  356. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/tabs/tabs.py +0 -0
  357. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/tabs/tabview.py +0 -0
  358. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/textarea/__init__.py +0 -0
  359. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/textarea/change.py +0 -0
  360. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/textarea/codeeditor.py +0 -0
  361. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/textarea/core.py +0 -0
  362. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/textarea/decoration.py +0 -0
  363. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/textarea/diff.py +0 -0
  364. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/textarea/extensions/__init__.py +0 -0
  365. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/textarea/extensions/bracket_matcher.py +0 -0
  366. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/textarea/extensions/indent_guides.py +0 -0
  367. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/textarea/extensions/line_numbers.py +0 -0
  368. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/textarea/extensions/pygments_highlighter.py +0 -0
  369. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/textarea/extensions/smart_indent.py +0 -0
  370. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/textarea/filter.py +0 -0
  371. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/textarea/redirector.py +0 -0
  372. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/textarea/search_overlay.py +0 -0
  373. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/textarea/sidebar.py +0 -0
  374. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/textarea/style_registry.py +0 -0
  375. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/textarea/textarea.py +0 -0
  376. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/textarea/undo.py +0 -0
  377. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/textentry.py +0 -0
  378. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/timeentry.py +0 -0
  379. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/toast.py +0 -0
  380. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/toast_stack.py +0 -0
  381. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/togglegroup.py +0 -0
  382. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/toolbar.py +0 -0
  383. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/tooltip.py +0 -0
  384. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/tree/__init__.py +0 -0
  385. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/tree/source_binding.py +0 -0
  386. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/tree/treeitem.py +0 -0
  387. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/tree/treenode.py +0 -0
  388. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/composites/tree/treeview.py +0 -0
  389. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/mixins/__init__.py +0 -0
  390. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/mixins/configure_mixin.py +0 -0
  391. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/mixins/entry_mixin.py +0 -0
  392. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/mixins/font_mixin.py +0 -0
  393. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/mixins/icon_mixin.py +0 -0
  394. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/mixins/localization_mixin.py +0 -0
  395. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/mixins/signal_mixin.py +0 -0
  396. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/mixins/validation_mixin.py +0 -0
  397. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/primitives/__init__.py +0 -0
  398. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/primitives/_menubutton.py +0 -0
  399. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/primitives/badge.py +0 -0
  400. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/primitives/button.py +0 -0
  401. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/primitives/card.py +0 -0
  402. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/primitives/checkbutton.py +0 -0
  403. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/primitives/checktoggle.py +0 -0
  404. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/primitives/combobox.py +0 -0
  405. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/primitives/entry.py +0 -0
  406. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/primitives/flexframe.py +0 -0
  407. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/primitives/frame.py +0 -0
  408. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/primitives/gridframe.py +0 -0
  409. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/primitives/label.py +0 -0
  410. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/primitives/labelframe.py +0 -0
  411. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/primitives/optionmenu.py +0 -0
  412. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/primitives/packframe.py +0 -0
  413. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/primitives/panedwindow.py +0 -0
  414. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/primitives/progressbar.py +0 -0
  415. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/primitives/radiobutton.py +0 -0
  416. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/primitives/radiotoggle.py +0 -0
  417. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/primitives/scrollbar.py +0 -0
  418. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/primitives/separator.py +0 -0
  419. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/primitives/sizegrip.py +0 -0
  420. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/primitives/spinbox.py +0 -0
  421. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/primitives/switch.py +0 -0
  422. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/_impl/primitives/treeview.py +0 -0
  423. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/app.py +0 -0
  424. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/appshell.py +0 -0
  425. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/avatar.py +0 -0
  426. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/boolean_controls.py +0 -0
  427. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/button.py +0 -0
  428. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/buttongroup.py +0 -0
  429. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/calendar.py +0 -0
  430. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/card.py +0 -0
  431. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/carousel.py +0 -0
  432. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/chart.py +0 -0
  433. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/codeeditor.py +0 -0
  434. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/contextmenu.py +0 -0
  435. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/datatable.py +0 -0
  436. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/datefield.py +0 -0
  437. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/divider.py +0 -0
  438. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/expander.py +0 -0
  439. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/form.py +0 -0
  440. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/gallery.py +0 -0
  441. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/gauge.py +0 -0
  442. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/grid.py +0 -0
  443. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/groupbox.py +0 -0
  444. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/label.py +0 -0
  445. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/listview.py +0 -0
  446. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/menubutton.py +0 -0
  447. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/numberfield.py +0 -0
  448. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/pagestack.py +0 -0
  449. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/passwordfield.py +0 -0
  450. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/pathfield.py +0 -0
  451. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/picture.py +0 -0
  452. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/progressbar.py +0 -0
  453. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/radio_variants.py +0 -0
  454. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/radiogroup.py +0 -0
  455. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/scrollbar.py +0 -0
  456. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/scrollview.py +0 -0
  457. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/selectbutton.py +0 -0
  458. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/sidebar_toggle.py +0 -0
  459. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/sizegrip.py +0 -0
  460. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/slider.py +0 -0
  461. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/spinbox.py +0 -0
  462. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/spinnerfield.py +0 -0
  463. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/splash.py +0 -0
  464. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/splitview.py +0 -0
  465. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/stacks.py +0 -0
  466. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/statusbar.py +0 -0
  467. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/tabs.py +0 -0
  468. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/textarea.py +0 -0
  469. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/textfield.py +0 -0
  470. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/theme_toggle.py +0 -0
  471. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/toast.py +0 -0
  472. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/togglegroup.py +0 -0
  473. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/toolbar.py +0 -0
  474. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/tooltip.py +0 -0
  475. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/tree.py +0 -0
  476. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/types.py +0 -0
  477. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack/widgets/window.py +0 -0
  478. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack.egg-info/SOURCES.txt +0 -0
  479. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack.egg-info/dependency_links.txt +0 -0
  480. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack.egg-info/entry_points.txt +0 -0
  481. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack.egg-info/requires.txt +0 -0
  482. {bootstack-0.3.1 → bootstack-0.3.2}/src/bootstack.egg-info/top_level.txt +0 -0
  483. {bootstack-0.3.1 → bootstack-0.3.2}/tests/test_dialog_anchor.py +0 -0
  484. {bootstack-0.3.1 → bootstack-0.3.2}/tests/test_events_doc_coverage.py +0 -0
  485. {bootstack-0.3.1 → bootstack-0.3.2}/tests/test_hot_reload.py +0 -0
  486. {bootstack-0.3.1 → bootstack-0.3.2}/tests/test_images.py +0 -0
  487. {bootstack-0.3.1 → bootstack-0.3.2}/tests/test_images_gui.py +0 -0
  488. {bootstack-0.3.1 → bootstack-0.3.2}/tests/test_intl_format.py +0 -0
  489. {bootstack-0.3.1 → bootstack-0.3.2}/tests/test_navmodel.py +0 -0
  490. {bootstack-0.3.1 → bootstack-0.3.2}/tests/test_on_color_contrast.py +0 -0
  491. {bootstack-0.3.1 → bootstack-0.3.2}/tests/test_public_surface.py +0 -0
  492. {bootstack-0.3.1 → bootstack-0.3.2}/tests/test_store.py +0 -0
  493. {bootstack-0.3.1 → bootstack-0.3.2}/tests/test_theme_from_existing.py +0 -0
  494. {bootstack-0.3.1 → bootstack-0.3.2}/tests/test_validation_rules.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bootstack
3
- Version: 0.3.1
3
+ Version: 0.3.2
4
4
  Summary: Build desktop GUI apps in pure Python and ship them as a standalone executable — built on Tk, no Tkinter boilerplate.
5
5
  Author-email: Israel Dryer <israel.dryer@gmail.com>
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "bootstack"
7
- version = "0.3.1"
7
+ version = "0.3.2"
8
8
  description = "Build desktop GUI apps in pure Python and ship them as a standalone executable — built on Tk, no Tkinter boilerplate."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -114,7 +114,7 @@ where = ["src"]
114
114
  ]
115
115
 
116
116
  [tool.bumpversion]
117
- current_version = "0.3.1"
117
+ current_version = "0.3.2"
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}",
@@ -1,4 +1,4 @@
1
- from tkinter import Toplevel
1
+ from tkinter import TclError, Toplevel
2
2
 
3
3
  from typing_extensions import Unpack
4
4
 
@@ -44,6 +44,7 @@ class SelectBox(Field):
44
44
  enable_search: bool = False,
45
45
  group_by: str = None,
46
46
  max_visible_items: int = None,
47
+ readonly: bool = False,
47
48
  **kwargs: Unpack[FieldOptions]
48
49
  ):
49
50
  """Args:
@@ -60,6 +61,12 @@ class SelectBox(Field):
60
61
  message: Optional helper/error message shown below the field.
61
62
  allow_custom_values: If True, the entry is editable so users can type
62
63
  arbitrary values in addition to choosing from the list.
64
+ readonly: If True, the value is visible but cannot be changed — no
65
+ typing and no popup, from the dropdown button or the entry. It
66
+ suppresses `allow_custom_values`/`enable_search` rather than
67
+ discarding them, so clearing it restores whichever was asked
68
+ for. Distinct from `state='disabled'`, which also dims the
69
+ whole field and drops it out of the tab order.
63
70
  show_dropdown_button: If True (default), the dropdown button is shown. This option is
64
71
  ignored if custom values are allowed.
65
72
  dropdown_button_icon: The icon to display on the dropdown button.
@@ -95,6 +102,14 @@ class SelectBox(Field):
95
102
  width: Width of the entry in characters.
96
103
  required: If True, field cannot be empty.
97
104
  """
105
+ # On select, readonly means the popup does not open and no typing, but allow_custom_values by itself
106
+ # without readonly just means standard combobox behavior.
107
+ #
108
+ # Every input the interaction state is derived from is set BEFORE
109
+ # `super().__init__()`, because Field's constructor calls
110
+ # `_sync_addon_state()`, which this class overrides to read them.
111
+ self._readonly = readonly
112
+ self._search_enabled = enable_search
98
113
  # Localization mode for option display (entry face + popup rows). None
99
114
  # defers to the app's localize_mode; False keeps the raw labels.
100
115
  self._localize = kwargs.pop('localize', None)
@@ -126,7 +141,6 @@ class SelectBox(Field):
126
141
  # Re-translate the displayed text + option maps on a live locale switch.
127
142
  self.winfo_toplevel().bind('<<LocaleChanged>>', self._on_locale_changed_refresh, add='+')
128
143
 
129
- self._search_enabled = enable_search
130
144
  self._group_by = group_by
131
145
  self._max_visible_items = max_visible_items
132
146
  self._popup_open = False
@@ -137,24 +151,98 @@ class SelectBox(Field):
137
151
  self._item_labels = []
138
152
  self._group_headers = []
139
153
 
140
- # Add dropdown button if needed
141
- if allow_custom_values or show_dropdown_button:
142
- self.insert_addon(
143
- Button,
144
- position="after",
145
- name="dropdown",
146
- icon=self._dropdown_button_icon,
147
- icon_only=True,
148
- command=self._on_dropdown_click
149
- )
150
-
151
- # Configure entry state based on search and custom value settings
152
- if allow_custom_values or enable_search:
153
- self.entry_widget.state(['!readonly'])
154
+ # A typeable entry is the only way the popup can lose an entrance: a
155
+ # click there has to place a text cursor rather than open the list, so
156
+ # the button becomes the sole way in. `show_dropdown_button=False` is
157
+ # honored only while the entry is NOT typeable.
158
+ #
159
+ # This decision is made ONCE, here. A later `configure()` that turns
160
+ # typing on does NOT insert a button the caller asked not to build.
161
+ if self._entry_is_typeable() or show_dropdown_button:
162
+ self._insert_dropdown_button()
163
+
164
+ # Bind click-to-open unconditionally and gate it inside the handler.
165
+ # Binding on the transition instead would mean unbinding on the way
166
+ # back, and a released tkinter binding name is reused immediately, so a
167
+ # deferred unbind can delete a different, live binding (cost a critical
168
+ # defect in #392).
169
+ self.entry_widget.bind('<Button-1>', self._on_entry_click, add='+')
170
+
171
+ self._apply_interaction_state()
172
+
173
+ # ----- Interaction state: typing, popup, dropdown button -----
174
+
175
+ def _entry_is_typeable(self) -> bool:
176
+ """Whether the user may type into the entry.
177
+
178
+ Read-only SUPPRESSES free typing rather than discarding it, so clearing
179
+ it restores whatever `allow_custom_values`/`enable_search` asked for
180
+ instead of falling back to a plain select.
181
+ """
182
+ if self._readonly:
183
+ return False
184
+ return bool(self._allow_custom_values or self._search_enabled)
185
+
186
+ def _popup_allowed(self) -> bool:
187
+ """Whether the option list may open, from either entrance."""
188
+ if self._readonly:
189
+ return False
190
+ return not self.entry_widget.instate(['disabled'])
191
+
192
+ def _insert_dropdown_button(self) -> None:
193
+ """Add the dropdown addon, marked read-only safe.
194
+
195
+ `active_when_readonly=True` stops `Field` dimming it for the ttk
196
+ `readonly` state, which on a select only means "no free typing" and is
197
+ the default. Dimming for a genuine read-only select is applied in
198
+ `_sync_addon_state` instead, off `_readonly`.
199
+ """
200
+ self.insert_addon(
201
+ Button,
202
+ position="after",
203
+ name="dropdown",
204
+ icon=self._dropdown_button_icon,
205
+ icon_only=True,
206
+ command=self._on_dropdown_click,
207
+ active_when_readonly=True,
208
+ )
209
+
210
+ def _apply_interaction_state(self) -> None:
211
+ """Recompute everything derived from readonly / custom values / search.
212
+
213
+ The ttk `readonly` state is an OUTPUT of this method, never storage.
214
+ It doubles as the widget's own "no free typing" flag, and writing it
215
+ from more than one place is exactly what let a caller's `read_only`
216
+ be silently overwritten (#453).
217
+ """
218
+ typeable = self._entry_is_typeable()
219
+ self.entry_widget.state(['!readonly'] if typeable else ['readonly'])
220
+
221
+ # Only a click that actually opens the list should advertise itself.
222
+ if typeable or not self._popup_allowed():
223
+ self.entry_widget.configure(cursor='')
154
224
  else:
155
- # Set entry to readonly but keep dropdown button enabled
156
- self.entry_widget.state(['readonly'])
157
- self.after_idle(self._bind_readonly_selection_on_click)
225
+ self.entry_widget.configure(cursor='hand2')
226
+
227
+ self._sync_addon_state()
228
+
229
+ def _sync_addon_state(self, event: Any = None) -> None:
230
+ """Match the addons to the field state, then apply the read-only rule.
231
+
232
+ `Field` dims every addon while the entry is `readonly`, assuming an
233
+ addon mutates the value. Here `readonly` is also how "no free typing"
234
+ is expressed and the dropdown is the primary interaction, so it opts
235
+ out via `active_when_readonly` and is dimmed from here on the real
236
+ read-only flag instead.
237
+ """
238
+ super()._sync_addon_state(event)
239
+ button = self._addons.get('dropdown')
240
+ if button is None:
241
+ return
242
+ try:
243
+ button.configure(state='!disabled' if self._popup_allowed() else 'disabled')
244
+ except TclError:
245
+ pass
158
246
 
159
247
  # ----- Option normalization + value<->text mapping -----
160
248
 
@@ -332,19 +420,29 @@ class SelectBox(Field):
332
420
 
333
421
  def _on_dropdown_click(self):
334
422
  """Handle dropdown button click by focusing entry then showing popup."""
423
+ if not self._popup_allowed():
424
+ return
335
425
  self.entry_widget.focus_set()
336
426
  self._show_selection_options()
337
427
 
338
- def _bind_readonly_selection_on_click(self):
339
- """Bind entry click to show popup when in readonly mode."""
340
- self.entry_widget.configure(cursor="hand2")
341
- self.entry_widget.bind('<Button-1>', lambda _: self.after_idle(self._show_selection_options), add='+')
428
+ def _on_entry_click(self, _event: Any = None) -> None:
429
+ """Open the list when a click on the entry cannot mean anything else.
430
+
431
+ Bound for the widget's whole life and gated here, because a typeable
432
+ entry has to place a text cursor instead — and rebinding on every
433
+ transition risks deleting a recycled binding name (#392).
434
+ """
435
+ if self._entry_is_typeable() or not self._popup_allowed():
436
+ return
437
+ self.after_idle(self._show_selection_options)
342
438
 
343
439
  def _show_selection_options(self):
344
440
  """Create and display the popup list of selectable items."""
345
441
  if not self._records or self._popup_open:
346
442
  return
347
- if self.entry_widget.instate(['disabled']):
443
+ # Both entrances gate on this too; it is repeated here so no future
444
+ # caller can reach the popup around them.
445
+ if not self._popup_allowed():
348
446
  return
349
447
 
350
448
  self._popup_open = True
@@ -954,10 +1052,7 @@ class SelectBox(Field):
954
1052
  return self._allow_custom_values
955
1053
  else:
956
1054
  self._allow_custom_values = value
957
- if value or self._search_enabled:
958
- self.entry_widget.state(['!readonly'])
959
- else:
960
- self.readonly(True)
1055
+ self._apply_interaction_state()
961
1056
  return None
962
1057
 
963
1058
  @configure_delegate('enable_search')
@@ -967,12 +1062,36 @@ class SelectBox(Field):
967
1062
  return self._search_enabled
968
1063
  else:
969
1064
  self._search_enabled = value
970
- if value or self._allow_custom_values:
971
- self.entry_widget.state(['!readonly'])
972
- else:
973
- self.readonly(True)
1065
+ self._apply_interaction_state()
974
1066
  return None
975
1067
 
1068
+ @configure_delegate('readonly')
1069
+ def _delegate_readonly(self, value: bool = None):
1070
+ """Get or set read-only: the value is visible but cannot be changed.
1071
+
1072
+ Distinct from a plain select, which is already untypeable but whose
1073
+ list still opens, and from `disabled`, which additionally dims the
1074
+ field and drops it out of the tab order.
1075
+ """
1076
+ if value is None:
1077
+ return self._readonly
1078
+ self._readonly = bool(value)
1079
+ self._apply_interaction_state()
1080
+ return None
1081
+
1082
+ @configure_delegate('state')
1083
+ def _delegate_state(self, value=None):
1084
+ """Apply the field state, then re-derive what read-only owns.
1085
+
1086
+ `Field` writes `readonly`/`normal` straight onto the entry, so
1087
+ `state='normal'` — which is what clearing `disabled` sends — would
1088
+ otherwise silently clear a read-only select as well.
1089
+ """
1090
+ result = super()._delegate_state(value)
1091
+ if value is not None:
1092
+ self._apply_interaction_state()
1093
+ return result
1094
+
976
1095
  @configure_delegate('group_by')
977
1096
  def _delegate_group_by(self, value=None):
978
1097
  """Get or set the option field the popup clusters rows under.
@@ -59,8 +59,12 @@ class Select(PublicWidgetBase):
59
59
  before it scrolls (height is `max_visible_items * row_height`).
60
60
  Group headers and separators consume some of that budget, so the
61
61
  count is approximate. `None` (default) uses the built-in cap.
62
- read_only: If `True`, value is visible but the popup cannot be
63
- opened.
62
+ read_only: If `True`, the value is visible but cannot be changed
63
+ neither the dropdown arrow nor a click in the field opens the
64
+ option list, and the arrow is dimmed to show it. Takes precedence
65
+ over `searchable` and `allow_custom_values` while set, and restores
66
+ them when cleared. Unlike `disabled`, the field keeps its normal
67
+ appearance and stays in the tab order. Defaults to `False`.
64
68
  disabled: If `True`, field is fully non-interactive and dimmed.
65
69
  width: Width in character units.
66
70
  accent: Accent token applied to the focus ring.
@@ -118,6 +122,7 @@ class Select(PublicWidgetBase):
118
122
  "allow_custom_values": allow_custom_values,
119
123
  "group_by": group_by,
120
124
  "max_visible_items": max_visible_items,
125
+ "readonly": read_only
121
126
  }
122
127
  if value is not None:
123
128
  internal_kwargs["value"] = value
@@ -131,8 +136,6 @@ class Select(PublicWidgetBase):
131
136
  internal_kwargs["required"] = True
132
137
  if disabled:
133
138
  internal_kwargs["state"] = "disabled"
134
- elif read_only:
135
- internal_kwargs["state"] = "readonly"
136
139
  if width is not None:
137
140
  internal_kwargs["width"] = width
138
141
  if accent is not None:
@@ -282,12 +285,22 @@ class Select(PublicWidgetBase):
282
285
 
283
286
  @property
284
287
  def read_only(self) -> bool:
285
- """Whether the field is visible but the popup cannot be opened."""
286
- return str(self._entry_widget().cget("state")) == "readonly"
288
+ """Whether the field is read-only the value shows but cannot be changed.
289
+
290
+ An ordinary `Select` already refuses free typing, which is not the same
291
+ thing. A read-only one also keeps the option list shut, from both the
292
+ dropdown button and the field itself.
293
+ """
294
+ # Report the setting, never the state derived from it — reporting the
295
+ # derivation is what made every select claim to be read-only (#453).
296
+ # Read it with `cget`, never `configure(name)`: the delegating form of
297
+ # `configure` answers a query with a 5-tuple, which is unconditionally
298
+ # truthy and would silently restore that behavior.
299
+ return bool(self._internal.cget("readonly"))
287
300
 
288
301
  @read_only.setter
289
302
  def read_only(self, v: bool) -> None:
290
- self._internal.configure(state="readonly" if v else "normal")
303
+ self._internal.configure(readonly=bool(v))
291
304
 
292
305
  @property
293
306
  def disabled(self) -> bool:
@@ -52,8 +52,10 @@ class TimeField(ValueSignalMixin, FieldAddonMixin, PublicWidgetBase):
52
52
  way to bind a time field.
53
53
  required: If `True`, field cannot be left empty.
54
54
  disabled: If `True`, field is non-interactive.
55
- read_only: If `True`, free-text entry is blocked; user must pick
56
- from the dropdown.
55
+ read_only: If `True`, the time is visible but cannot be changed —
56
+ typing is blocked, and neither the clock button nor a click in the
57
+ field opens the time list. Unlike `disabled`, the field keeps its
58
+ normal appearance and stays in the tab order. Defaults to `False`.
57
59
  width: Width in character cells.
58
60
  accent: Accent color applied to the focus ring. Default `'primary'`.
59
61
  density: Widget density.
@@ -111,10 +113,14 @@ class TimeField(ValueSignalMixin, FieldAddonMixin, PublicWidgetBase):
111
113
  internal_kwargs["message"] = message
112
114
  if required:
113
115
  internal_kwargs["required"] = True
116
+ # Read-only rides its own option, not `state="readonly"` — the internal
117
+ # here is a select, where the ttk `readonly` state is an OUTPUT of the
118
+ # interaction state ("no free typing") and is re-derived at the end of
119
+ # construction, so a state write is overwritten before anyone sees it
120
+ # (#453). Same shape as the setter below and as `Select`.
121
+ internal_kwargs["readonly"] = read_only
114
122
  if disabled:
115
123
  internal_kwargs["state"] = "disabled"
116
- elif read_only:
117
- internal_kwargs["state"] = "readonly"
118
124
  if width is not None:
119
125
  internal_kwargs["width"] = width
120
126
  if accent is not None:
@@ -162,12 +168,22 @@ class TimeField(ValueSignalMixin, FieldAddonMixin, PublicWidgetBase):
162
168
 
163
169
  @property
164
170
  def read_only(self) -> bool:
165
- """Whether the field is read-only (selectable but not editable)."""
166
- return self._internal._entry.instate(("readonly",))
171
+ """Whether the field is read-only the time shows but cannot be changed."""
172
+ # Report the setting, not the state derived from it. The two agree at
173
+ # rest, but the derivation is cleared and restored around a programmatic
174
+ # value write, so reading it answers `False` for a locked field from
175
+ # inside that window (#453). Same reason `Select.read_only` reads the
176
+ # setting; `cget`, never `configure(name)`, which answers a query with a
177
+ # truthy 5-tuple.
178
+ return bool(self._internal.cget("readonly"))
167
179
 
168
180
  @read_only.setter
169
181
  def read_only(self, v: bool) -> None:
170
- self._internal.configure(state="readonly" if v else "normal")
182
+ # Route through the `readonly` option, not `state="readonly"`. The
183
+ # internal here is a select, where the ttk `readonly` state is an
184
+ # OUTPUT of the interaction state ("no free typing") and is re-derived
185
+ # on every change — so a state write is overwritten immediately (#453).
186
+ self._internal.configure(readonly=bool(v))
171
187
 
172
188
  # ----- Methods -----
173
189
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bootstack
3
- Version: 0.3.1
3
+ Version: 0.3.2
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