bootstack 0.1.0a7__tar.gz → 0.1.0a9__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 (432) hide show
  1. {bootstack-0.1.0a7/src/bootstack.egg-info → bootstack-0.1.0a9}/PKG-INFO +1 -1
  2. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/pyproject.toml +2 -2
  3. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/datasource/README.md +7 -2
  4. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/datasource/base.py +42 -6
  5. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/datasource/memory_source.py +54 -12
  6. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/datasource/sqlite_source.py +15 -3
  7. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/datasource/types.py +40 -7
  8. bootstack-0.1.0a9/src/bootstack/style/builders/checkbutton.py +125 -0
  9. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/listview.py +4 -7
  10. bootstack-0.1.0a9/src/bootstack/style/builders/radiobutton.py +97 -0
  11. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/utils.py +28 -2
  12. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/list/listitem.py +28 -46
  13. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/list/listview.py +64 -359
  14. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/radiogroup.py +8 -0
  15. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/checkbutton.py +12 -2
  16. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/checktoggle.py +6 -1
  17. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/radiobutton.py +12 -2
  18. {bootstack-0.1.0a7 → bootstack-0.1.0a9/src/bootstack.egg-info}/PKG-INFO +1 -1
  19. bootstack-0.1.0a7/src/bootstack/style/builders/checkbutton.py +0 -95
  20. bootstack-0.1.0a7/src/bootstack/style/builders/radiobutton.py +0 -68
  21. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/LICENSE +0 -0
  22. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/MANIFEST.in +0 -0
  23. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/NOTICE +0 -0
  24. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/README.md +0 -0
  25. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/setup.cfg +0 -0
  26. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/__init__.py +0 -0
  27. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/__main__.py +0 -0
  28. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/api/__init__.py +0 -0
  29. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/api/app.py +0 -0
  30. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/api/constants.py +0 -0
  31. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/api/data.py +0 -0
  32. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/api/dialogs.py +0 -0
  33. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/api/i18n.py +0 -0
  34. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/api/localization.py +0 -0
  35. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/api/menu.py +0 -0
  36. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/api/style.py +0 -0
  37. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/api/utils.py +0 -0
  38. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/api/widgets.py +0 -0
  39. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/__init__.py +0 -0
  40. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/bootstack-dark.ico +0 -0
  41. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/bootstack-light.ico +0 -0
  42. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/bootstack-transparent.png +0 -0
  43. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/bootstack.ico +0 -0
  44. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/bootstack.png +0 -0
  45. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/__init__.py +0 -0
  46. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/badge-pill.png +0 -0
  47. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/badge-square.png +0 -0
  48. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/border.png +0 -0
  49. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/button-compact.png +0 -0
  50. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/button-default.png +0 -0
  51. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/button-group-horizontal-after-compact.png +0 -0
  52. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/button-group-horizontal-after-default.png +0 -0
  53. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/button-group-horizontal-before-compact.png +0 -0
  54. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/button-group-horizontal-before-default.png +0 -0
  55. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/button-group-horizontal-center-compact.png +0 -0
  56. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/button-group-horizontal-center-default.png +0 -0
  57. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/button-group-vertical-after-compact.png +0 -0
  58. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/button-group-vertical-after-default.png +0 -0
  59. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/button-group-vertical-before-compact.png +0 -0
  60. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/button-group-vertical-before-default.png +0 -0
  61. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/button-group-vertical-center-compact.png +0 -0
  62. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/button-group-vertical-center-default.png +0 -0
  63. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/checkbox-checked.png +0 -0
  64. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/checkbox-indeterminate.png +0 -0
  65. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/checkbox-unchecked.png +0 -0
  66. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/field.png +0 -0
  67. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/input-after-compact.png +0 -0
  68. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/input-after-default.png +0 -0
  69. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/input-before-compact.png +0 -0
  70. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/input-before-default.png +0 -0
  71. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/input-compact.png +0 -0
  72. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/input-default.png +0 -0
  73. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/list-item-separated.png +0 -0
  74. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/list-item.png +0 -0
  75. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/manifest.toml +0 -0
  76. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/menu-item.png +0 -0
  77. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/nav-button-compact.png +0 -0
  78. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/nav-button-default.png +0 -0
  79. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/nav-icon-button-compact.png +0 -0
  80. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/nav-icon-button-default.png +0 -0
  81. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/notebook-client-border.png +0 -0
  82. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/notebook-tab-active.png +0 -0
  83. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/notebook-tab-bar.png +0 -0
  84. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/notebook-tab-normal.png +0 -0
  85. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/notebook-tab-pill.png +0 -0
  86. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/progress-bar-horizontal-striped.png +0 -0
  87. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/progress-bar-solid.png +0 -0
  88. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/progress-bar-thin.png +0 -0
  89. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/progress-bar-vertical-striped.png +0 -0
  90. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/radio-selected.png +0 -0
  91. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/radio-unselected.png +0 -0
  92. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/scrollbar-horizontal.png +0 -0
  93. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/scrollbar-vertical.png +0 -0
  94. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/slider-handle-focus.png +0 -0
  95. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/slider-handle.png +0 -0
  96. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/slider-track-horizontal.png +0 -0
  97. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/slider-track-vertical.png +0 -0
  98. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/switch-off.png +0 -0
  99. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/switch-on.png +0 -0
  100. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/tabs-bar-horizontal.png +0 -0
  101. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/tabs-bar-vertical.png +0 -0
  102. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/elements/tabs-pill.png +0 -0
  103. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/ar/LC_MESSAGES/bootstack.mo +0 -0
  104. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/ar/LC_MESSAGES/bootstack.po +0 -0
  105. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/bg/LC_MESSAGES/bootstack.po +0 -0
  106. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/cs/LC_MESSAGES/bootstack.mo +0 -0
  107. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/cs/LC_MESSAGES/bootstack.po +0 -0
  108. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/da/LC_MESSAGES/bootstack.mo +0 -0
  109. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/da/LC_MESSAGES/bootstack.po +0 -0
  110. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/de/LC_MESSAGES/bootstack.mo +0 -0
  111. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/de/LC_MESSAGES/bootstack.po +0 -0
  112. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/en/LC_MESSAGES/bootstack.mo +0 -0
  113. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/en/LC_MESSAGES/bootstack.po +0 -0
  114. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/es/LC_MESSAGES/bootstack.mo +0 -0
  115. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/es/LC_MESSAGES/bootstack.po +0 -0
  116. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/fr/LC_MESSAGES/bootstack.mo +0 -0
  117. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/fr/LC_MESSAGES/bootstack.po +0 -0
  118. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/he/LC_MESSAGES/bootstack.mo +0 -0
  119. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/he/LC_MESSAGES/bootstack.po +0 -0
  120. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/hi/LC_MESSAGES/bootstack.mo +0 -0
  121. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/hi/LC_MESSAGES/bootstack.po +0 -0
  122. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/it/LC_MESSAGES/bootstack.mo +0 -0
  123. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/it/LC_MESSAGES/bootstack.po +0 -0
  124. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/ja/LC_MESSAGES/bootstack.mo +0 -0
  125. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/ja/LC_MESSAGES/bootstack.po +0 -0
  126. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/ko/LC_MESSAGES/bootstack.mo +0 -0
  127. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/ko/LC_MESSAGES/bootstack.po +0 -0
  128. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/nb/LC_MESSAGES/bootstack.mo +0 -0
  129. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/nb/LC_MESSAGES/bootstack.po +0 -0
  130. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/nl/LC_MESSAGES/bootstack.mo +0 -0
  131. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/nl/LC_MESSAGES/bootstack.po +0 -0
  132. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/pl/LC_MESSAGES/bootstack.mo +0 -0
  133. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/pl/LC_MESSAGES/bootstack.po +0 -0
  134. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/pt/LC_MESSAGES/bootstack.mo +0 -0
  135. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/pt/LC_MESSAGES/bootstack.po +0 -0
  136. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.mo +0 -0
  137. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.po +0 -0
  138. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/sl/LC_MESSAGES/bootstack.mo +0 -0
  139. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/sl/LC_MESSAGES/bootstack.po +0 -0
  140. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/sv/LC_MESSAGES/bootstack.mo +0 -0
  141. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/sv/LC_MESSAGES/bootstack.po +0 -0
  142. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/tr/LC_MESSAGES/bootstack.mo +0 -0
  143. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/tr/LC_MESSAGES/bootstack.po +0 -0
  144. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.mo +0 -0
  145. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.po +0 -0
  146. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.mo +0 -0
  147. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.po +0 -0
  148. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/themes/__init__.py +0 -0
  149. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/themes/amber-dark.json +0 -0
  150. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/themes/amber-light.json +0 -0
  151. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/themes/aurora-dark.json +0 -0
  152. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/themes/aurora-light.json +0 -0
  153. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/themes/bootstrap-dark.json +0 -0
  154. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/themes/bootstrap-light.json +0 -0
  155. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/themes/classic-dark.json +0 -0
  156. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/themes/classic-light.json +0 -0
  157. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/themes/docs-dark.json +0 -0
  158. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/themes/docs-light.json +0 -0
  159. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/themes/forest-dark.json +0 -0
  160. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/themes/forest-light.json +0 -0
  161. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/themes/ocean-dark.json +0 -0
  162. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/themes/ocean-light.json +0 -0
  163. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/themes/rose-dark.json +0 -0
  164. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/themes/rose-light.json +0 -0
  165. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/__init__.py +0 -0
  166. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/badge-default.png +0 -0
  167. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/badge-pill.png +0 -0
  168. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/border.png +0 -0
  169. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/button-group-horizontal-after.png +0 -0
  170. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/button-group-horizontal-before.png +0 -0
  171. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/button-group-horizontal-center.png +0 -0
  172. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/button-group-vertical-after.png +0 -0
  173. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/button-group-vertical-before.png +0 -0
  174. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/button-group-vertical-center.png +0 -0
  175. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/button.png +0 -0
  176. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/checkbox-checked.png +0 -0
  177. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/checkbox-indeterminate.png +0 -0
  178. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/checkbox-unchecked.png +0 -0
  179. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/field.png +0 -0
  180. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/icon-button.png +0 -0
  181. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/input-inner.png +0 -0
  182. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/input-prefix.png +0 -0
  183. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/input-suffix.png +0 -0
  184. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/input.png +0 -0
  185. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/list-item-focus.png +0 -0
  186. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/list-item-separated.png +0 -0
  187. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/menu-item-separated.png +0 -0
  188. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/notebook-client-border.png +0 -0
  189. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/notebook-pill-active.png +0 -0
  190. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/notebook-pill-inactive.png +0 -0
  191. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/notebook-tab-active.png +0 -0
  192. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/notebook-tab-border.png +0 -0
  193. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/notebook-tab-normal.png +0 -0
  194. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/notebook-underline.png +0 -0
  195. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/progress-bar-horizontal-default.png +0 -0
  196. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/progress-bar-horizontal-striped.png +0 -0
  197. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/progress-bar-vertical-default.png +0 -0
  198. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/progress-bar-vertical-striped.png +0 -0
  199. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/progress-trough-horizontal.png +0 -0
  200. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/progress-trough-vertical.png +0 -0
  201. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/radio-selected.png +0 -0
  202. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/radio-unselected.png +0 -0
  203. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/scrollbar-horizontal-rounded.png +0 -0
  204. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/scrollbar-vertical-rounded.png +0 -0
  205. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/separator-horizontal.png +0 -0
  206. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/separator-vertical.png +0 -0
  207. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/slider-handle-focus.png +0 -0
  208. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/slider-handle.png +0 -0
  209. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/slider-track-horizontal.png +0 -0
  210. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/slider-track-vertical.png +0 -0
  211. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/switch-off.png +0 -0
  212. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/switch-on.png +0 -0
  213. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/tabs-bar-horizontal.png +0 -0
  214. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/tabs-bar-vertical.png +0 -0
  215. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/assets/widgets/tabs-pill.png +0 -0
  216. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/cli/__init__.py +0 -0
  217. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/cli/__main__.py +0 -0
  218. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/cli/add.py +0 -0
  219. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/cli/build.py +0 -0
  220. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/cli/config.py +0 -0
  221. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/cli/demo.py +0 -0
  222. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/cli/doctor.py +0 -0
  223. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/cli/icons.py +0 -0
  224. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/cli/list_cmd.py +0 -0
  225. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/cli/promote.py +0 -0
  226. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/cli/pyinstaller.py +0 -0
  227. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/cli/run.py +0 -0
  228. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/cli/start.py +0 -0
  229. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/cli/templates/__init__.py +0 -0
  230. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/constants.py +0 -0
  231. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/__init__.py +0 -0
  232. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/capabilities/__init__.py +0 -0
  233. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/capabilities/after.py +0 -0
  234. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/capabilities/bind.py +0 -0
  235. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/capabilities/bindtags.py +0 -0
  236. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/capabilities/busy.py +0 -0
  237. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/capabilities/clipboard.py +0 -0
  238. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/capabilities/focus.py +0 -0
  239. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/capabilities/grab.py +0 -0
  240. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/capabilities/grid.py +0 -0
  241. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/capabilities/localization.py +0 -0
  242. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/capabilities/pack.py +0 -0
  243. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/capabilities/place.py +0 -0
  244. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/capabilities/selection.py +0 -0
  245. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/capabilities/signals.py +0 -0
  246. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/capabilities/winfo.py +0 -0
  247. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/colorutils.py +0 -0
  248. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/exceptions.py +0 -0
  249. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/images.py +0 -0
  250. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/localization/README.md +0 -0
  251. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/localization/__init__.py +0 -0
  252. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/localization/intl_format.py +0 -0
  253. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/localization/msgcat.py +0 -0
  254. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/localization/specs.py +0 -0
  255. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/mixins/__init__.py +0 -0
  256. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/mixins/ttk_state.py +0 -0
  257. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/mixins/widget.py +0 -0
  258. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/publisher.py +0 -0
  259. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/signals/README.md +0 -0
  260. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/signals/__init__.py +0 -0
  261. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/signals/integration.py +0 -0
  262. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/signals/signal.py +0 -0
  263. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/signals/types.py +0 -0
  264. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/validation/__init__.py +0 -0
  265. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/validation/types.py +0 -0
  266. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/validation/validation_result.py +0 -0
  267. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/validation/validation_rules.py +0 -0
  268. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/core/variables.py +0 -0
  269. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/datasource/__init__.py +0 -0
  270. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/datasource/file_source.py +0 -0
  271. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/dialogs/__init__.py +0 -0
  272. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/dialogs/colorchooser.py +0 -0
  273. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/dialogs/colordropper.py +0 -0
  274. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/dialogs/datedialog.py +0 -0
  275. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/dialogs/dialog.py +0 -0
  276. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/dialogs/filterdialog.py +0 -0
  277. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/dialogs/fontdialog.py +0 -0
  278. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/dialogs/formdialog.py +0 -0
  279. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/dialogs/message.py +0 -0
  280. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/dialogs/query.py +0 -0
  281. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/py.typed +0 -0
  282. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/runtime/__init__.py +0 -0
  283. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/runtime/app.py +0 -0
  284. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/runtime/base_window.py +0 -0
  285. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/runtime/events.py +0 -0
  286. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/runtime/menu.py +0 -0
  287. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/runtime/shortcuts.py +0 -0
  288. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/runtime/tk_patch.py +0 -0
  289. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/runtime/toplevel.py +0 -0
  290. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/runtime/utility.py +0 -0
  291. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/runtime/visual_focus.py +0 -0
  292. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/runtime/window_utilities.py +0 -0
  293. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/__init__.py +0 -0
  294. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/bootstyle.py +0 -0
  295. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/bootstyle_builder_base.py +0 -0
  296. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/bootstyle_builder_mixed.py +0 -0
  297. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/bootstyle_builder_tk.py +0 -0
  298. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/bootstyle_builder_ttk.py +0 -0
  299. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/__init__.py +0 -0
  300. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/badge.py +0 -0
  301. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/button.py +0 -0
  302. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/buttongroup.py +0 -0
  303. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/calendar.py +0 -0
  304. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/combobox.py +0 -0
  305. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/contextmenu.py +0 -0
  306. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/entry.py +0 -0
  307. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/expander.py +0 -0
  308. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/field.py +0 -0
  309. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/frame.py +0 -0
  310. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/label.py +0 -0
  311. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/labelframe.py +0 -0
  312. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/menubar.py +0 -0
  313. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/menubutton.py +0 -0
  314. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/notebook.py +0 -0
  315. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/panedwindow.py +0 -0
  316. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/progressbar.py +0 -0
  317. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/scale.py +0 -0
  318. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/scrollbar.py +0 -0
  319. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/separator.py +0 -0
  320. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/sidenav.py +0 -0
  321. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/sizegrip.py +0 -0
  322. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/spinbox.py +0 -0
  323. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/switch.py +0 -0
  324. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/tabitem.py +0 -0
  325. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/toolbutton.py +0 -0
  326. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/tooltip.py +0 -0
  327. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders/treeview.py +0 -0
  328. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders_tk/__init__.py +0 -0
  329. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/builders_tk/defaults.py +0 -0
  330. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/element.py +0 -0
  331. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/style.py +0 -0
  332. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/theme_provider.py +0 -0
  333. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/tk_patch.py +0 -0
  334. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/token_maps.py +0 -0
  335. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/types.py +0 -0
  336. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/typography.py +0 -0
  337. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/style/utility.py +0 -0
  338. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/themes/__init__.py +0 -0
  339. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/themes/standard.py +0 -0
  340. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/themes/user.py +0 -0
  341. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/__init__.py +0 -0
  342. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/__init__.py +0 -0
  343. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/accordion.py +0 -0
  344. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/appshell.py +0 -0
  345. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/buttongroup.py +0 -0
  346. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/calendar.py +0 -0
  347. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/compositeframe.py +0 -0
  348. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/contextmenu.py +0 -0
  349. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/dateentry.py +0 -0
  350. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/dropdownbutton.py +0 -0
  351. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/expander.py +0 -0
  352. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/field.py +0 -0
  353. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/floodgauge.py +0 -0
  354. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/form.py +0 -0
  355. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/labeledscale.py +0 -0
  356. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/list/__init__.py +0 -0
  357. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/menubar.py +0 -0
  358. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/meter.py +0 -0
  359. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/numericentry.py +0 -0
  360. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/pagestack.py +0 -0
  361. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/passwordentry.py +0 -0
  362. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/pathentry.py +0 -0
  363. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/scrolledtext.py +0 -0
  364. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/scrolledtext.pyi +0 -0
  365. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/scrollview.py +0 -0
  366. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/selectbox.py +0 -0
  367. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/sidenav/__init__.py +0 -0
  368. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/sidenav/group.py +0 -0
  369. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/sidenav/header.py +0 -0
  370. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/sidenav/item.py +0 -0
  371. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/sidenav/separator.py +0 -0
  372. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/sidenav/view.py +0 -0
  373. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/spinnerentry.py +0 -0
  374. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/tableview/__init__.py +0 -0
  375. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/tableview/tableview.py +0 -0
  376. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/tableview/types.py +0 -0
  377. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/tabs/__init__.py +0 -0
  378. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/tabs/tabitem.py +0 -0
  379. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/tabs/tabs.py +0 -0
  380. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/tabs/tabview.py +0 -0
  381. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/textentry.py +0 -0
  382. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/timeentry.py +0 -0
  383. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/toast.py +0 -0
  384. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/togglegroup.py +0 -0
  385. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/toolbar.py +0 -0
  386. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/composites/tooltip.py +0 -0
  387. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/internal/__init__.py +0 -0
  388. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/internal/wrapper_base.py +0 -0
  389. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/mixins/__init__.py +0 -0
  390. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/mixins/configure_mixin.py +0 -0
  391. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/mixins/entry_mixin.py +0 -0
  392. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/mixins/font_mixin.py +0 -0
  393. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/mixins/icon_mixin.py +0 -0
  394. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/mixins/localization_mixin.py +0 -0
  395. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/mixins/signal_mixin.py +0 -0
  396. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/mixins/validation_mixin.py +0 -0
  397. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/parts/__init__.py +0 -0
  398. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/parts/numberentry_part.py +0 -0
  399. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/parts/spinnerentry_part.py +0 -0
  400. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/parts/textentry_part.py +0 -0
  401. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/__init__.py +0 -0
  402. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/badge.py +0 -0
  403. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/button.py +0 -0
  404. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/card.py +0 -0
  405. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/combobox.py +0 -0
  406. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/entry.py +0 -0
  407. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/frame.py +0 -0
  408. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/gridframe.py +0 -0
  409. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/label.py +0 -0
  410. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/labelframe.py +0 -0
  411. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/menubutton.py +0 -0
  412. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/notebook.py +0 -0
  413. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/optionmenu.py +0 -0
  414. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/packframe.py +0 -0
  415. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/panedwindow.py +0 -0
  416. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/progressbar.py +0 -0
  417. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/radiotoggle.py +0 -0
  418. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/scale.py +0 -0
  419. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/scrollbar.py +0 -0
  420. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/separator.py +0 -0
  421. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/sizegrip.py +0 -0
  422. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/spinbox.py +0 -0
  423. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/switch.py +0 -0
  424. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/primitives/treeview.py +0 -0
  425. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack/widgets/types.py +0 -0
  426. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack.egg-info/SOURCES.txt +0 -0
  427. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack.egg-info/dependency_links.txt +0 -0
  428. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack.egg-info/entry_points.txt +0 -0
  429. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack.egg-info/requires.txt +0 -0
  430. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/src/bootstack.egg-info/top_level.txt +0 -0
  431. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/tests/test_togglegroup.py +0 -0
  432. {bootstack-0.1.0a7 → bootstack-0.1.0a9}/tests/test_variables.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bootstack
3
- Version: 0.1.0a7
3
+ Version: 0.1.0a9
4
4
  Summary: A full UI framework for Python desktop apps built on tkinter — rich widgets, theming, and application structure out of the box.
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.0a7"
7
+ version = "0.1.0a9"
8
8
  description = "A full UI framework for Python desktop apps built on tkinter — rich widgets, theming, and application structure out of the box."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -82,7 +82,7 @@ where = ["src"]
82
82
  ]
83
83
 
84
84
  [tool.bumpversion]
85
- current_version = "0.1.0a7"
85
+ current_version = "0.1.0a9"
86
86
  parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)((?P<pre>a|b|rc)(?P<pre_n>\\d+))?"
87
87
  serialize = [
88
88
  "{major}.{minor}.{patch}{pre}{pre_n}",
@@ -333,13 +333,18 @@ class AuditedDataSource(BaseDataSource):
333
333
  - `delete_record(record_id)` - Delete record by ID
334
334
 
335
335
  #### Selection Management
336
+ - `is_selected(record_id)` - Check whether a record is selected
336
337
  - `select_record(record_id)` - Mark record as selected
337
- - `unselect_record(record_id)` - Unmark record
338
+ - `deselect_record(record_id)` - Unmark record
338
339
  - `select_all(current_page_only=False)` - Select all/page records
339
- - `unselect_all(current_page_only=False)` - Unselect all/page records
340
+ - `deselect_all(current_page_only=False)` - Deselect all/page records
340
341
  - `get_selected(page=None)` - Get selected records
341
342
  - `selected_count()` - Count selected records
342
343
 
344
+ #### Lifecycle / reorder
345
+ - `reload()` - Re-read from source (no-op for in-memory)
346
+ - `move_record(record_id, target_index)` - Reorder a record
347
+
343
348
  #### Export
344
349
  - `export_to_csv(filepath, include_all=True)` - Export to CSV
345
350
 
@@ -194,6 +194,18 @@ class BaseDataSource(ABC):
194
194
  ...
195
195
 
196
196
  # Selection Management
197
+ @abstractmethod
198
+ def is_selected(self, record_id: Any) -> bool:
199
+ """Check whether a record is currently selected.
200
+
201
+ Args:
202
+ record_id: Unique identifier of the record
203
+
204
+ Returns:
205
+ True if the record is selected, False otherwise (including missing records)
206
+ """
207
+ ...
208
+
197
209
  @abstractmethod
198
210
  def select_record(self, record_id: Any) -> bool:
199
211
  """Mark record as selected.
@@ -207,14 +219,14 @@ class BaseDataSource(ABC):
207
219
  ...
208
220
 
209
221
  @abstractmethod
210
- def unselect_record(self, record_id: Any) -> bool:
222
+ def deselect_record(self, record_id: Any) -> bool:
211
223
  """Mark record as unselected.
212
224
 
213
225
  Args:
214
226
  record_id: Unique identifier of the record
215
227
 
216
228
  Returns:
217
- True if record was unselected, False if not found
229
+ True if record was deselected, False if not found
218
230
  """
219
231
  ...
220
232
 
@@ -231,14 +243,14 @@ class BaseDataSource(ABC):
231
243
  ...
232
244
 
233
245
  @abstractmethod
234
- def unselect_all(self, current_page_only: bool = False) -> int:
235
- """Unselect all records (optionally only current page).
246
+ def deselect_all(self, current_page_only: bool = False) -> int:
247
+ """Deselect all records (optionally only current page).
236
248
 
237
249
  Args:
238
- current_page_only: If True, unselect only records on current page
250
+ current_page_only: If True, deselect only records on current page
239
251
 
240
252
  Returns:
241
- Number of records unselected
253
+ Number of records deselected
242
254
  """
243
255
  ...
244
256
 
@@ -288,6 +300,30 @@ class BaseDataSource(ABC):
288
300
  """
289
301
  ...
290
302
 
303
+ # Lifecycle / reorder — concrete defaults; subclasses may override
304
+ def reload(self) -> None:
305
+ """Re-read data from the underlying source.
306
+
307
+ Default is a no-op suitable for in-memory implementations.
308
+ File- and database-backed sources should override to re-query.
309
+ """
310
+ return None
311
+
312
+ def move_record(self, record_id: Any, target_index: int) -> bool:
313
+ """Reorder a record to a new position.
314
+
315
+ Default returns False (not supported). Subclasses that maintain
316
+ an explicit ordering should override.
317
+
318
+ Args:
319
+ record_id: Unique identifier of the record to move
320
+ target_index: Zero-based destination index (clamped to valid range)
321
+
322
+ Returns:
323
+ True if the record was moved, False if not supported or not found
324
+ """
325
+ return False
326
+
291
327
  # ========== SHARED UTILITY METHODS ==========
292
328
 
293
329
  @staticmethod
@@ -108,18 +108,29 @@ class MemoryDataSource(BaseDataSource):
108
108
  r.setdefault("selected", 0)
109
109
 
110
110
  def _ensure_id(self) -> None:
111
- """Ensure all records have unique integer IDs."""
112
- used = set()
111
+ """Ensure all records have unique integer IDs.
112
+
113
+ Records whose `id` is already an int and not a duplicate are
114
+ preserved as-is. Records with missing, non-integer, or duplicate
115
+ IDs get a freshly-allocated integer ID.
116
+ """
117
+ used: set[int] = set()
118
+ needs_id: list[Dict[str, Any]] = []
113
119
  max_id = 0
114
120
  for r in self._data:
115
- if "id" in r and isinstance(r["id"], int):
116
- used.add(r["id"])
117
- max_id = max(max_id, r["id"])
118
- for r in self._data:
119
- if "id" not in r or not isinstance(r["id"], int) or r["id"] in used:
121
+ rid = r.get("id")
122
+ if isinstance(rid, int) and rid not in used:
123
+ used.add(rid)
124
+ if rid > max_id:
125
+ max_id = rid
126
+ else:
127
+ needs_id.append(r)
128
+ for r in needs_id:
129
+ max_id += 1
130
+ while max_id in used:
120
131
  max_id += 1
121
- r["id"] = max_id
122
- used.add(max_id)
132
+ r["id"] = max_id
133
+ used.add(max_id)
123
134
  self._rebuild_id_index()
124
135
 
125
136
  @staticmethod
@@ -389,11 +400,18 @@ class MemoryDataSource(BaseDataSource):
389
400
  self._rebuild_id_index()
390
401
  return True
391
402
 
403
+ def is_selected(self, record_id: Any) -> bool:
404
+ """Check whether a record is currently selected."""
405
+ idx = self._id_index.get(record_id)
406
+ if idx is None:
407
+ return False
408
+ return bool(self._data[idx].get("selected", 0))
409
+
392
410
  def select_record(self, record_id: Any) -> bool:
393
411
  """Mark record as selected."""
394
412
  return self._set_selected_flag(record_id, 1)
395
413
 
396
- def unselect_record(self, record_id: Any) -> bool:
414
+ def deselect_record(self, record_id: Any) -> bool:
397
415
  """Mark record as unselected."""
398
416
  return self._set_selected_flag(record_id, 0)
399
417
 
@@ -417,8 +435,8 @@ class MemoryDataSource(BaseDataSource):
417
435
  count += 1
418
436
  return count
419
437
 
420
- def unselect_all(self, current_page_only: bool = False) -> int:
421
- """Unselect all records (optionally only current page)."""
438
+ def deselect_all(self, current_page_only: bool = False) -> int:
439
+ """Deselect all records (optionally only current page)."""
422
440
  self._ensure_selected_column()
423
441
  if current_page_only:
424
442
  ids = [r["id"] for r in self.get_page()]
@@ -437,6 +455,30 @@ class MemoryDataSource(BaseDataSource):
437
455
  count += 1
438
456
  return count
439
457
 
458
+ def move_record(self, record_id: Any, target_index: int) -> bool:
459
+ """Reorder a record within the in-memory list."""
460
+ if not self._data:
461
+ return False
462
+
463
+ source_index = self._id_index.get(record_id)
464
+ if source_index is None:
465
+ return False
466
+
467
+ clamped_target = max(0, min(int(target_index), len(self._data) - 1))
468
+ if source_index == clamped_target:
469
+ return False
470
+
471
+ record = self._data.pop(source_index)
472
+ if clamped_target > source_index:
473
+ clamped_target -= 1
474
+ self._data.insert(clamped_target, record)
475
+
476
+ start = min(source_index, clamped_target)
477
+ end = max(source_index, clamped_target) + 1
478
+ for i in range(start, end):
479
+ self._id_index[self._data[i]["id"]] = i
480
+ return True
481
+
440
482
  def _set_selected_flag(self, record_id: Any, flag: int) -> bool:
441
483
  """Set selection flag for record by ID."""
442
484
  self._ensure_selected_column()
@@ -330,11 +330,23 @@ class SqliteDataSource(BaseDataSource):
330
330
 
331
331
  # === SELECTION ====
332
332
 
333
+ def is_selected(self, record_id: Any) -> bool:
334
+ """Check whether a record is currently selected."""
335
+ if _ROW_SEL not in self._columns:
336
+ return False
337
+ row = self.conn.execute(
338
+ f"SELECT {_ROW_SEL} FROM {self._table} WHERE {_ROW_ID} = ?",
339
+ (record_id,),
340
+ ).fetchone()
341
+ if row is None:
342
+ return False
343
+ return bool(row[0])
344
+
333
345
  def select_record(self, record_id: Any) -> bool:
334
346
  """Mark record as selected."""
335
347
  return self._set_selected_flag(record_id, 1)
336
348
 
337
- def unselect_record(self, record_id: Any) -> bool:
349
+ def deselect_record(self, record_id: Any) -> bool:
338
350
  """Mark record as unselected."""
339
351
  return self._set_selected_flag(record_id, 0)
340
352
 
@@ -355,8 +367,8 @@ class SqliteDataSource(BaseDataSource):
355
367
  cur = self.conn.execute(f"UPDATE {self._table} SET {_ROW_SEL} = 1")
356
368
  return cur.rowcount
357
369
 
358
- def unselect_all(self, current_page_only: bool = False) -> int:
359
- """Unselect all records (optionally only current page)."""
370
+ def deselect_all(self, current_page_only: bool = False) -> int:
371
+ """Deselect all records (optionally only current page)."""
360
372
  self._ensure_selected_column()
361
373
  if current_page_only:
362
374
  ids = [row[_ROW_ID] for row in self.get_page()]
@@ -7,9 +7,10 @@ The DataSourceProtocol provides a unified interface for:
7
7
  - Data loading and configuration (set_data, set_filter, set_sort)
8
8
  - Pagination (get_page, next_page, prev_page, has_next_page)
9
9
  - CRUD operations (create, read, update, delete)
10
- - Selection management (select/unselect records)
10
+ - Selection management (is_selected, select/deselect records)
11
11
  - Data export (CSV export)
12
12
  - Index-based access (get_page_from_index)
13
+ - Lifecycle and reorder (reload, move_record)
13
14
 
14
15
  All datasource implementations should conform to this protocol to ensure
15
16
  compatibility with datasource-aware widgets and utilities.
@@ -172,6 +173,17 @@ class DataSourceProtocol(Protocol):
172
173
  ...
173
174
 
174
175
  # ---------- selection ----------
176
+ def is_selected(self, record_id: Any) -> bool:
177
+ """Check whether a record is currently selected.
178
+
179
+ Args:
180
+ record_id: Unique identifier of the record
181
+
182
+ Returns:
183
+ True if the record is selected, False otherwise (including missing records)
184
+ """
185
+ ...
186
+
175
187
  def select_record(self, record_id: Any) -> bool:
176
188
  """Mark record as selected.
177
189
 
@@ -183,14 +195,14 @@ class DataSourceProtocol(Protocol):
183
195
  """
184
196
  ...
185
197
 
186
- def unselect_record(self, record_id: Any) -> bool:
198
+ def deselect_record(self, record_id: Any) -> bool:
187
199
  """Mark record as unselected.
188
200
 
189
201
  Args:
190
202
  record_id: Unique identifier of the record
191
203
 
192
204
  Returns:
193
- True if record was unselected, False if not found
205
+ True if record was deselected, False if not found
194
206
  """
195
207
  ...
196
208
 
@@ -205,14 +217,14 @@ class DataSourceProtocol(Protocol):
205
217
  """
206
218
  ...
207
219
 
208
- def unselect_all(self, current_page_only: bool = False) -> int:
209
- """Unselect all records (optionally only current page).
220
+ def deselect_all(self, current_page_only: bool = False) -> int:
221
+ """Deselect all records (optionally only current page).
210
222
 
211
223
  Args:
212
- current_page_only: If True, unselect only records on current page
224
+ current_page_only: If True, deselect only records on current page
213
225
 
214
226
  Returns:
215
- Number of records unselected
227
+ Number of records deselected
216
228
  """
217
229
  ...
218
230
 
@@ -235,6 +247,27 @@ class DataSourceProtocol(Protocol):
235
247
  """
236
248
  ...
237
249
 
250
+ # ---------- lifecycle / reorder ----------
251
+ def reload(self) -> None:
252
+ """Re-read data from the underlying source.
253
+
254
+ For in-memory implementations this is typically a no-op. For
255
+ file- or database-backed sources, this re-queries or re-reads.
256
+ """
257
+ ...
258
+
259
+ def move_record(self, record_id: Any, target_index: int) -> bool:
260
+ """Reorder a record to a new position.
261
+
262
+ Args:
263
+ record_id: Unique identifier of the record to move
264
+ target_index: Zero-based destination index (clamped to valid range)
265
+
266
+ Returns:
267
+ True if the record was moved, False if not supported or not found
268
+ """
269
+ ...
270
+
238
271
  # ---------- export ----------
239
272
  def export_to_csv(self, filepath: str, include_all: bool = True) -> None:
240
273
  """Export records to CSV file.
@@ -0,0 +1,125 @@
1
+ """Checkbutton widget style builders.
2
+
3
+ This module contains style builders for ttk.Checkbutton widgets and variants.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from bootstack.style.bootstyle_builder_ttk import BootstyleBuilderTTk
9
+ from bootstack.style.element import Element, ElementImage
10
+ from bootstack.style.utility import create_transparent_image, recolor_element_image
11
+ from bootstack.style.builders.utils import icon_size, resolve_icon_spec
12
+
13
+
14
+ @BootstyleBuilderTTk.register_builder('default', 'TCheckbutton')
15
+ def build_checkbutton_style(b: BootstyleBuilderTTk, ttk_style: str, accent: str = 'primary', **options):
16
+ accent_token = accent or 'primary'
17
+ surface_token = options.get('surface', 'content')
18
+
19
+ background = b.color(surface_token)
20
+ background_hover = b.active(background)
21
+ foreground = b.on_color(background)
22
+ foreground_disabled = b.disabled('text', background)
23
+
24
+ normal = b.color(accent_token)
25
+ pressed = b.pressed(normal)
26
+ hovered = b.active(normal)
27
+ border = b.border(background)
28
+ focus = hovered
29
+ focus_ring = b.focus_ring(normal, background)
30
+ disabled = b.disabled()
31
+
32
+ show_indicator = options.get('show_indicator', True)
33
+
34
+ if show_indicator:
35
+ spacer_img = create_transparent_image(6, 1)
36
+ b.create_style_element_image(ElementImage(f'{ttk_style}.spacer', spacer_img, sticky="ew"))
37
+
38
+ normal_checked_img = recolor_element_image('checkbox_checked', background, normal, background)
39
+ normal_unchecked_img = recolor_element_image('checkbox_unchecked', background, border, background)
40
+ normal_indeterminate_img = recolor_element_image('checkbox_indeterminate', background, normal, background)
41
+
42
+ hovered_checked_img = recolor_element_image('checkbox_checked', background, hovered, background)
43
+ hovered_unchecked_img = recolor_element_image('checkbox_unchecked', background_hover, border, background)
44
+ hovered_indeterminate_img = recolor_element_image('checkbox_indeterminate', background, hovered, background)
45
+
46
+ pressed_checked_img = recolor_element_image('checkbox_checked', background, pressed, background)
47
+ pressed_unchecked_img = recolor_element_image('checkbox_unchecked', background_hover, pressed, background)
48
+ pressed_indeterminate_img = recolor_element_image('checkbox_indeterminate', background, pressed, background)
49
+
50
+ focus_checked_img = recolor_element_image('checkbox_checked', background, focus, focus_ring)
51
+ focus_unchecked_img = recolor_element_image('checkbox_unchecked', background_hover, focus, focus_ring)
52
+ focus_indeterminate_img = recolor_element_image('checkbox_indeterminate', background, focus, focus_ring)
53
+
54
+ disabled_checked_img = recolor_element_image('checkbox_checked', disabled, foreground_disabled, background)
55
+ disabled_unchecked_img = recolor_element_image(
56
+ 'checkbox_unchecked', foreground_disabled, foreground_disabled, background)
57
+ disabled_indeterminate_img = recolor_element_image(
58
+ 'checkbox_indeterminate', disabled, foreground_disabled, background)
59
+
60
+ b.create_style_element_image(
61
+ ElementImage(f'{ttk_style}.indicator', normal_unchecked_img.image, sticky="ns").state_specs(
62
+ [
63
+ # Disabled states
64
+ ('disabled alternate !selected', disabled_indeterminate_img.image),
65
+ ('disabled selected', disabled_checked_img.image),
66
+ ('disabled !selected !alternate', disabled_unchecked_img.image),
67
+
68
+ # Focused states
69
+ ('focus alternate !selected', focus_indeterminate_img.image),
70
+ ('focus selected', focus_checked_img.image),
71
+ ('focus !selected !alternate', focus_unchecked_img.image),
72
+
73
+ # Pressed states
74
+ ('pressed alternate !selected', pressed_indeterminate_img.image),
75
+ ('pressed selected', pressed_checked_img.image),
76
+ ('pressed !selected !alternate', pressed_unchecked_img.image),
77
+
78
+ # Hover states
79
+ ('hover alternate !selected', hovered_indeterminate_img.image),
80
+ ('hover selected', hovered_checked_img.image),
81
+ ('hover !selected !alternate', hovered_unchecked_img.image),
82
+
83
+ # Normal base states
84
+ ('alternate !selected', normal_indeterminate_img.image),
85
+ ('selected', normal_checked_img.image),
86
+ ('!selected !alternate', normal_unchecked_img.image),
87
+ ]
88
+ ))
89
+
90
+ # Label-area icon: stateful, independent of show_indicator.
91
+ # Accent color when selected, foreground when unselected.
92
+ icon_images = []
93
+ icon_spec_raw = resolve_icon_spec(options)
94
+ if icon_spec_raw is not None:
95
+ icon_spec = b.normalize_icon_spec(icon_spec_raw, icon_size(False, 'default'))
96
+ fg_spec = [
97
+ ('disabled', foreground_disabled),
98
+ ('selected !disabled', normal),
99
+ ('', foreground),
100
+ ]
101
+ icon_images = b.map_stateful_icons(icon_spec, fg_spec)
102
+
103
+ layout_children = []
104
+ if show_indicator:
105
+ layout_children += [
106
+ Element(f'{ttk_style}.indicator', side="left", sticky=""),
107
+ Element(f'{ttk_style}.spacer', side="left"),
108
+ ]
109
+ layout_children.append(Element('Checkbutton.label', side="left", sticky="nsew"))
110
+
111
+ b.create_style_layout(
112
+ ttk_style, Element('Checkbutton.padding', sticky="nsew").children(layout_children)
113
+ )
114
+
115
+ b.configure_style(ttk_style, background=background, foreground=foreground, font="body")
116
+
117
+ map_kwargs = {
118
+ 'background': [],
119
+ 'foreground': [('disabled', foreground_disabled), ('', foreground)],
120
+ }
121
+ if icon_images:
122
+ map_kwargs['image'] = icon_images
123
+ if not options.get('icon_only', False):
124
+ map_kwargs['compound'] = 'left'
125
+ b.map_style(ttk_style, **map_kwargs)
@@ -77,8 +77,8 @@ def build_list_item_style(
77
77
  active_img = recolor_element_image(image_key, active, border_normal, active)
78
78
  selected_img = recolor_element_image(image_key, selected, border_normal, indicator)
79
79
 
80
- focus_img = recolor_element_image(image_key, active, border_normal, indicator)
81
- focus_pressed_img = recolor_element_image(image_key, pressed, border_normal, indicator)
80
+ focus_img = recolor_element_image(image_key, active, border_normal, active)
81
+ focus_pressed_img = recolor_element_image(image_key, pressed, border_normal, pressed)
82
82
 
83
83
  image_state_specs = [
84
84
  ('selected', selected_img.image),
@@ -173,13 +173,12 @@ def _list_icon_size(b: BootstyleBuilderTTk, density: str) -> int:
173
173
  def build_list_icon(b: BootstyleBuilderTTk, ttk_style: str, accent: str = None, **options):
174
174
  hoverable = options.get('hoverable', True)
175
175
  surface_token = options.get('surface', 'content')
176
- select_background_token = options.get('selected_background', 'primary')
177
176
  density = normalize_button_density(options.get('density', 'default'))
178
177
 
179
178
  background = b.color(surface_token)
180
179
  active = b.elevate(background, 1)
181
180
  pressed = b.pressed(background)
182
- selected = b.subtle(select_background_token, background)
181
+ selected = b.subtle(accent or 'primary', background)
183
182
  on_background = b.on_color(background)
184
183
  on_selected = b.on_color(selected)
185
184
  on_disabled = b.disabled('text', background)
@@ -236,19 +235,17 @@ def build_list_item_label(b: BootstyleBuilderTTk, ttk_style: str, accent: str =
236
235
 
237
236
  Style Options
238
237
  * surface
239
- * selected_background
240
238
  * hoverable
241
239
  * foreground
242
240
  """
243
241
  hoverable = options.get('hoverable', True)
244
242
  surface_token = options.get('surface', 'content')
245
- select_background_token = options.get('selected_background', 'primary')
246
243
  foreground_token = options.get('foreground', None)
247
244
 
248
245
  background = b.color(surface_token)
249
246
  active = b.elevate(background, 1)
250
247
  pressed = b.pressed(background)
251
- selected = b.subtle(select_background_token, background)
248
+ selected = b.subtle(accent or 'primary', background)
252
249
  on_selected = b.on_color(selected)
253
250
  on_background = b.color(foreground_token) if foreground_token else b.on_color(background)
254
251
 
@@ -0,0 +1,97 @@
1
+ """Radio Button widget style builders.
2
+
3
+ This module contains style builders for ttk.Radiobutton widgets and variants.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from bootstack.style.bootstyle_builder_ttk import BootstyleBuilderTTk
9
+ from bootstack.style.element import Element, ElementImage
10
+ from bootstack.style.utility import create_transparent_image, recolor_element_image
11
+ from bootstack.style.builders.utils import icon_size, resolve_icon_spec
12
+
13
+
14
+ @BootstyleBuilderTTk.register_builder('default', 'TRadiobutton')
15
+ def build_radiobutton_style(b: BootstyleBuilderTTk, ttk_style: str, accent: str = 'primary', **options):
16
+ accent_token = accent or 'primary'
17
+ surface_token = options.get('surface', 'content')
18
+
19
+ background = b.color(surface_token)
20
+ background_hover = b.active(background)
21
+ foreground = b.on_color(background)
22
+ foreground_disabled = b.disabled('text', background)
23
+
24
+ normal = b.color(accent_token)
25
+ hovered = b.active(normal)
26
+ border = b.border(background)
27
+ focus = hovered
28
+ focus_ring = b.focus_ring(normal, background)
29
+
30
+ show_indicator = options.get('show_indicator', True)
31
+
32
+ if show_indicator:
33
+ spacer_img = create_transparent_image(6, 1)
34
+ b.create_style_element_image(ElementImage(f'{ttk_style}.spacer', spacer_img, sticky="ew"))
35
+
36
+ normal_checked_img = recolor_element_image('radio_selected', background, normal, background)
37
+ normal_unchecked_img = recolor_element_image('radio_unselected', background, border, background)
38
+
39
+ focus_checked_img = recolor_element_image('radio_selected', background, focus, focus_ring)
40
+ focus_unchecked_img = recolor_element_image('radio_unselected', background_hover, focus, focus_ring)
41
+
42
+ disabled_checked_img = recolor_element_image('radio_selected', background, foreground_disabled, background)
43
+ disabled_unchecked_img = recolor_element_image('radio_unselected', background, foreground_disabled, background)
44
+
45
+ b.create_style_element_image(
46
+ ElementImage(f'{ttk_style}.indicator', normal_unchecked_img.image, sticky="ns", padding=b.scale(4)).state_specs(
47
+ [
48
+ # Disabled states
49
+ ('disabled selected', disabled_checked_img.image),
50
+ ('disabled !selected !alternate', disabled_unchecked_img.image),
51
+
52
+ # Focused states
53
+ ('focus selected', focus_checked_img.image),
54
+ ('focus !selected !alternate', focus_unchecked_img.image),
55
+
56
+ # Normal base states
57
+ ('selected', normal_checked_img.image),
58
+ ('!selected !alternate', normal_unchecked_img.image),
59
+ ]
60
+ ))
61
+
62
+ # Label-area icon: stateful, independent of show_indicator.
63
+ # Accent color when selected, foreground when unselected.
64
+ icon_images = []
65
+ icon_spec_raw = resolve_icon_spec(options)
66
+ if icon_spec_raw is not None:
67
+ icon_spec = b.normalize_icon_spec(icon_spec_raw, icon_size(False, 'default'))
68
+ fg_spec = [
69
+ ('disabled', foreground_disabled),
70
+ ('selected !disabled', normal),
71
+ ('', foreground),
72
+ ]
73
+ icon_images = b.map_stateful_icons(icon_spec, fg_spec)
74
+
75
+ layout_children = []
76
+ if show_indicator:
77
+ layout_children += [
78
+ Element(f'{ttk_style}.indicator', side="left", sticky=""),
79
+ Element(f'{ttk_style}.spacer', side="left"),
80
+ ]
81
+ layout_children.append(Element('Radiobutton.label', side="left", sticky="nsew"))
82
+
83
+ b.create_style_layout(
84
+ ttk_style, Element('Radiobutton.padding', sticky="nsew").children(layout_children)
85
+ )
86
+
87
+ b.configure_style(ttk_style, background=background, foreground=foreground, font="body")
88
+
89
+ map_kwargs = {
90
+ 'background': [],
91
+ 'foreground': [('disabled', foreground_disabled), ('', foreground)],
92
+ }
93
+ if icon_images:
94
+ map_kwargs['image'] = icon_images
95
+ if not options.get('icon_only', False):
96
+ map_kwargs['compound'] = 'left'
97
+ b.map_style(ttk_style, **map_kwargs)