bootstack 0.1.0a4__tar.gz → 0.1.0a6__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 (430) hide show
  1. {bootstack-0.1.0a4/src/bootstack.egg-info → bootstack-0.1.0a6}/PKG-INFO +20 -4
  2. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/README.md +19 -3
  3. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/pyproject.toml +2 -2
  4. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/__init__.py +7 -2
  5. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/api/style.py +4 -1
  6. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/api/widgets.py +3 -0
  7. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/cli/__init__.py +15 -5
  8. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/cli/add.py +2 -2
  9. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/cli/demo.py +3 -3
  10. bootstack-0.1.0a6/src/bootstack/cli/icons.py +28 -0
  11. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/datasource/sqlite_source.py +60 -53
  12. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/field.py +21 -5
  13. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/form.py +1 -2
  14. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/tableview/tableview.py +19 -19
  15. {bootstack-0.1.0a4 → bootstack-0.1.0a6/src/bootstack.egg-info}/PKG-INFO +20 -4
  16. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack.egg-info/SOURCES.txt +1 -0
  17. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/LICENSE +0 -0
  18. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/MANIFEST.in +0 -0
  19. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/NOTICE +0 -0
  20. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/setup.cfg +0 -0
  21. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/__main__.py +0 -0
  22. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/api/__init__.py +0 -0
  23. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/api/app.py +0 -0
  24. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/api/constants.py +0 -0
  25. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/api/data.py +0 -0
  26. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/api/dialogs.py +0 -0
  27. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/api/i18n.py +0 -0
  28. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/api/localization.py +0 -0
  29. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/api/menu.py +0 -0
  30. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/api/utils.py +0 -0
  31. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/__init__.py +0 -0
  32. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/bootstack-dark.ico +0 -0
  33. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/bootstack-light.ico +0 -0
  34. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/bootstack-transparent.png +0 -0
  35. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/bootstack.ico +0 -0
  36. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/bootstack.png +0 -0
  37. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/__init__.py +0 -0
  38. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/badge-pill.png +0 -0
  39. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/badge-square.png +0 -0
  40. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/border.png +0 -0
  41. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/button-compact.png +0 -0
  42. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/button-default.png +0 -0
  43. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/button-group-horizontal-after-compact.png +0 -0
  44. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/button-group-horizontal-after-default.png +0 -0
  45. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/button-group-horizontal-before-compact.png +0 -0
  46. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/button-group-horizontal-before-default.png +0 -0
  47. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/button-group-horizontal-center-compact.png +0 -0
  48. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/button-group-horizontal-center-default.png +0 -0
  49. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/button-group-vertical-after-compact.png +0 -0
  50. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/button-group-vertical-after-default.png +0 -0
  51. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/button-group-vertical-before-compact.png +0 -0
  52. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/button-group-vertical-before-default.png +0 -0
  53. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/button-group-vertical-center-compact.png +0 -0
  54. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/button-group-vertical-center-default.png +0 -0
  55. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/checkbox-checked.png +0 -0
  56. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/checkbox-indeterminate.png +0 -0
  57. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/checkbox-unchecked.png +0 -0
  58. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/field.png +0 -0
  59. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/input-after-compact.png +0 -0
  60. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/input-after-default.png +0 -0
  61. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/input-before-compact.png +0 -0
  62. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/input-before-default.png +0 -0
  63. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/input-compact.png +0 -0
  64. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/input-default.png +0 -0
  65. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/list-item-separated.png +0 -0
  66. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/list-item.png +0 -0
  67. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/manifest.toml +0 -0
  68. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/menu-item.png +0 -0
  69. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/nav-button-compact.png +0 -0
  70. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/nav-button-default.png +0 -0
  71. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/nav-icon-button-compact.png +0 -0
  72. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/nav-icon-button-default.png +0 -0
  73. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/notebook-client-border.png +0 -0
  74. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/notebook-tab-active.png +0 -0
  75. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/notebook-tab-bar.png +0 -0
  76. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/notebook-tab-normal.png +0 -0
  77. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/notebook-tab-pill.png +0 -0
  78. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/progress-bar-horizontal-striped.png +0 -0
  79. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/progress-bar-solid.png +0 -0
  80. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/progress-bar-thin.png +0 -0
  81. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/progress-bar-vertical-striped.png +0 -0
  82. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/radio-selected.png +0 -0
  83. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/radio-unselected.png +0 -0
  84. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/scrollbar-horizontal.png +0 -0
  85. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/scrollbar-vertical.png +0 -0
  86. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/slider-handle-focus.png +0 -0
  87. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/slider-handle.png +0 -0
  88. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/slider-track-horizontal.png +0 -0
  89. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/slider-track-vertical.png +0 -0
  90. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/switch-off.png +0 -0
  91. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/switch-on.png +0 -0
  92. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/tabs-bar-horizontal.png +0 -0
  93. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/tabs-bar-vertical.png +0 -0
  94. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/elements/tabs-pill.png +0 -0
  95. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/ar/LC_MESSAGES/bootstack.mo +0 -0
  96. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/ar/LC_MESSAGES/bootstack.po +0 -0
  97. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/bg/LC_MESSAGES/bootstack.po +0 -0
  98. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/cs/LC_MESSAGES/bootstack.mo +0 -0
  99. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/cs/LC_MESSAGES/bootstack.po +0 -0
  100. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/da/LC_MESSAGES/bootstack.mo +0 -0
  101. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/da/LC_MESSAGES/bootstack.po +0 -0
  102. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/de/LC_MESSAGES/bootstack.mo +0 -0
  103. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/de/LC_MESSAGES/bootstack.po +0 -0
  104. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/en/LC_MESSAGES/bootstack.mo +0 -0
  105. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/en/LC_MESSAGES/bootstack.po +0 -0
  106. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/es/LC_MESSAGES/bootstack.mo +0 -0
  107. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/es/LC_MESSAGES/bootstack.po +0 -0
  108. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/fr/LC_MESSAGES/bootstack.mo +0 -0
  109. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/fr/LC_MESSAGES/bootstack.po +0 -0
  110. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/he/LC_MESSAGES/bootstack.mo +0 -0
  111. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/he/LC_MESSAGES/bootstack.po +0 -0
  112. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/hi/LC_MESSAGES/bootstack.mo +0 -0
  113. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/hi/LC_MESSAGES/bootstack.po +0 -0
  114. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/it/LC_MESSAGES/bootstack.mo +0 -0
  115. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/it/LC_MESSAGES/bootstack.po +0 -0
  116. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/ja/LC_MESSAGES/bootstack.mo +0 -0
  117. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/ja/LC_MESSAGES/bootstack.po +0 -0
  118. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/ko/LC_MESSAGES/bootstack.mo +0 -0
  119. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/ko/LC_MESSAGES/bootstack.po +0 -0
  120. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/nb/LC_MESSAGES/bootstack.mo +0 -0
  121. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/nb/LC_MESSAGES/bootstack.po +0 -0
  122. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/nl/LC_MESSAGES/bootstack.mo +0 -0
  123. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/nl/LC_MESSAGES/bootstack.po +0 -0
  124. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/pl/LC_MESSAGES/bootstack.mo +0 -0
  125. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/pl/LC_MESSAGES/bootstack.po +0 -0
  126. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/pt/LC_MESSAGES/bootstack.mo +0 -0
  127. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/pt/LC_MESSAGES/bootstack.po +0 -0
  128. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.mo +0 -0
  129. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.po +0 -0
  130. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/sl/LC_MESSAGES/bootstack.mo +0 -0
  131. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/sl/LC_MESSAGES/bootstack.po +0 -0
  132. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/sv/LC_MESSAGES/bootstack.mo +0 -0
  133. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/sv/LC_MESSAGES/bootstack.po +0 -0
  134. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/tr/LC_MESSAGES/bootstack.mo +0 -0
  135. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/tr/LC_MESSAGES/bootstack.po +0 -0
  136. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.mo +0 -0
  137. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.po +0 -0
  138. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.mo +0 -0
  139. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.po +0 -0
  140. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/themes/__init__.py +0 -0
  141. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/themes/amber-dark.json +0 -0
  142. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/themes/amber-light.json +0 -0
  143. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/themes/aurora-dark.json +0 -0
  144. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/themes/aurora-light.json +0 -0
  145. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/themes/bootstrap-dark.json +0 -0
  146. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/themes/bootstrap-light.json +0 -0
  147. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/themes/classic-dark.json +0 -0
  148. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/themes/classic-light.json +0 -0
  149. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/themes/docs-dark.json +0 -0
  150. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/themes/docs-light.json +0 -0
  151. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/themes/forest-dark.json +0 -0
  152. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/themes/forest-light.json +0 -0
  153. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/themes/ocean-dark.json +0 -0
  154. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/themes/ocean-light.json +0 -0
  155. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/themes/rose-dark.json +0 -0
  156. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/themes/rose-light.json +0 -0
  157. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/__init__.py +0 -0
  158. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/badge-default.png +0 -0
  159. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/badge-pill.png +0 -0
  160. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/border.png +0 -0
  161. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/button-group-horizontal-after.png +0 -0
  162. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/button-group-horizontal-before.png +0 -0
  163. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/button-group-horizontal-center.png +0 -0
  164. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/button-group-vertical-after.png +0 -0
  165. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/button-group-vertical-before.png +0 -0
  166. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/button-group-vertical-center.png +0 -0
  167. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/button.png +0 -0
  168. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/checkbox-checked.png +0 -0
  169. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/checkbox-indeterminate.png +0 -0
  170. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/checkbox-unchecked.png +0 -0
  171. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/field.png +0 -0
  172. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/icon-button.png +0 -0
  173. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/input-inner.png +0 -0
  174. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/input-prefix.png +0 -0
  175. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/input-suffix.png +0 -0
  176. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/input.png +0 -0
  177. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/list-item-focus.png +0 -0
  178. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/list-item-separated.png +0 -0
  179. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/menu-item-separated.png +0 -0
  180. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/notebook-client-border.png +0 -0
  181. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/notebook-pill-active.png +0 -0
  182. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/notebook-pill-inactive.png +0 -0
  183. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/notebook-tab-active.png +0 -0
  184. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/notebook-tab-border.png +0 -0
  185. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/notebook-tab-normal.png +0 -0
  186. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/notebook-underline.png +0 -0
  187. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/progress-bar-horizontal-default.png +0 -0
  188. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/progress-bar-horizontal-striped.png +0 -0
  189. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/progress-bar-vertical-default.png +0 -0
  190. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/progress-bar-vertical-striped.png +0 -0
  191. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/progress-trough-horizontal.png +0 -0
  192. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/progress-trough-vertical.png +0 -0
  193. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/radio-selected.png +0 -0
  194. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/radio-unselected.png +0 -0
  195. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/scrollbar-horizontal-rounded.png +0 -0
  196. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/scrollbar-vertical-rounded.png +0 -0
  197. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/separator-horizontal.png +0 -0
  198. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/separator-vertical.png +0 -0
  199. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/slider-handle-focus.png +0 -0
  200. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/slider-handle.png +0 -0
  201. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/slider-track-horizontal.png +0 -0
  202. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/slider-track-vertical.png +0 -0
  203. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/switch-off.png +0 -0
  204. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/switch-on.png +0 -0
  205. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/tabs-bar-horizontal.png +0 -0
  206. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/tabs-bar-vertical.png +0 -0
  207. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/assets/widgets/tabs-pill.png +0 -0
  208. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/cli/__main__.py +0 -0
  209. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/cli/build.py +0 -0
  210. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/cli/config.py +0 -0
  211. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/cli/doctor.py +0 -0
  212. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/cli/list_cmd.py +0 -0
  213. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/cli/promote.py +0 -0
  214. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/cli/pyinstaller.py +0 -0
  215. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/cli/run.py +0 -0
  216. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/cli/start.py +0 -0
  217. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/cli/templates/__init__.py +0 -0
  218. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/constants.py +0 -0
  219. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/__init__.py +0 -0
  220. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/capabilities/__init__.py +0 -0
  221. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/capabilities/after.py +0 -0
  222. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/capabilities/bind.py +0 -0
  223. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/capabilities/bindtags.py +0 -0
  224. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/capabilities/busy.py +0 -0
  225. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/capabilities/clipboard.py +0 -0
  226. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/capabilities/focus.py +0 -0
  227. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/capabilities/grab.py +0 -0
  228. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/capabilities/grid.py +0 -0
  229. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/capabilities/localization.py +0 -0
  230. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/capabilities/pack.py +0 -0
  231. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/capabilities/place.py +0 -0
  232. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/capabilities/selection.py +0 -0
  233. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/capabilities/signals.py +0 -0
  234. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/capabilities/winfo.py +0 -0
  235. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/colorutils.py +0 -0
  236. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/exceptions.py +0 -0
  237. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/images.py +0 -0
  238. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/localization/README.md +0 -0
  239. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/localization/__init__.py +0 -0
  240. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/localization/intl_format.py +0 -0
  241. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/localization/msgcat.py +0 -0
  242. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/localization/specs.py +0 -0
  243. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/mixins/__init__.py +0 -0
  244. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/mixins/ttk_state.py +0 -0
  245. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/mixins/widget.py +0 -0
  246. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/publisher.py +0 -0
  247. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/signals/README.md +0 -0
  248. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/signals/__init__.py +0 -0
  249. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/signals/integration.py +0 -0
  250. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/signals/signal.py +0 -0
  251. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/signals/types.py +0 -0
  252. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/validation/__init__.py +0 -0
  253. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/validation/types.py +0 -0
  254. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/validation/validation_result.py +0 -0
  255. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/validation/validation_rules.py +0 -0
  256. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/core/variables.py +0 -0
  257. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/datasource/README.md +0 -0
  258. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/datasource/__init__.py +0 -0
  259. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/datasource/base.py +0 -0
  260. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/datasource/file_source.py +0 -0
  261. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/datasource/memory_source.py +0 -0
  262. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/datasource/types.py +0 -0
  263. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/dialogs/__init__.py +0 -0
  264. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/dialogs/colorchooser.py +0 -0
  265. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/dialogs/colordropper.py +0 -0
  266. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/dialogs/datedialog.py +0 -0
  267. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/dialogs/dialog.py +0 -0
  268. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/dialogs/filterdialog.py +0 -0
  269. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/dialogs/fontdialog.py +0 -0
  270. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/dialogs/formdialog.py +0 -0
  271. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/dialogs/message.py +0 -0
  272. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/dialogs/query.py +0 -0
  273. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/py.typed +0 -0
  274. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/runtime/__init__.py +0 -0
  275. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/runtime/app.py +0 -0
  276. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/runtime/base_window.py +0 -0
  277. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/runtime/events.py +0 -0
  278. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/runtime/menu.py +0 -0
  279. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/runtime/shortcuts.py +0 -0
  280. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/runtime/tk_patch.py +0 -0
  281. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/runtime/toplevel.py +0 -0
  282. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/runtime/utility.py +0 -0
  283. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/runtime/visual_focus.py +0 -0
  284. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/runtime/window_utilities.py +0 -0
  285. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/__init__.py +0 -0
  286. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/bootstyle.py +0 -0
  287. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/bootstyle_builder_base.py +0 -0
  288. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/bootstyle_builder_mixed.py +0 -0
  289. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/bootstyle_builder_tk.py +0 -0
  290. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/bootstyle_builder_ttk.py +0 -0
  291. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/__init__.py +0 -0
  292. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/badge.py +0 -0
  293. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/button.py +0 -0
  294. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/buttongroup.py +0 -0
  295. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/calendar.py +0 -0
  296. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/checkbutton.py +0 -0
  297. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/combobox.py +0 -0
  298. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/contextmenu.py +0 -0
  299. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/entry.py +0 -0
  300. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/expander.py +0 -0
  301. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/field.py +0 -0
  302. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/frame.py +0 -0
  303. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/label.py +0 -0
  304. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/labelframe.py +0 -0
  305. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/listview.py +0 -0
  306. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/menubar.py +0 -0
  307. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/menubutton.py +0 -0
  308. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/notebook.py +0 -0
  309. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/panedwindow.py +0 -0
  310. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/progressbar.py +0 -0
  311. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/radiobutton.py +0 -0
  312. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/scale.py +0 -0
  313. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/scrollbar.py +0 -0
  314. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/separator.py +0 -0
  315. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/sidenav.py +0 -0
  316. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/sizegrip.py +0 -0
  317. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/spinbox.py +0 -0
  318. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/switch.py +0 -0
  319. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/tabitem.py +0 -0
  320. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/toolbutton.py +0 -0
  321. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/tooltip.py +0 -0
  322. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/treeview.py +0 -0
  323. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders/utils.py +0 -0
  324. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders_tk/__init__.py +0 -0
  325. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/builders_tk/defaults.py +0 -0
  326. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/element.py +0 -0
  327. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/style.py +0 -0
  328. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/theme_provider.py +0 -0
  329. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/tk_patch.py +0 -0
  330. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/token_maps.py +0 -0
  331. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/types.py +0 -0
  332. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/typography.py +0 -0
  333. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/style/utility.py +0 -0
  334. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/themes/__init__.py +0 -0
  335. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/themes/standard.py +0 -0
  336. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/themes/user.py +0 -0
  337. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/__init__.py +0 -0
  338. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/__init__.py +0 -0
  339. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/accordion.py +0 -0
  340. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/appshell.py +0 -0
  341. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/buttongroup.py +0 -0
  342. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/calendar.py +0 -0
  343. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/compositeframe.py +0 -0
  344. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/contextmenu.py +0 -0
  345. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/dateentry.py +0 -0
  346. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/dropdownbutton.py +0 -0
  347. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/expander.py +0 -0
  348. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/floodgauge.py +0 -0
  349. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/labeledscale.py +0 -0
  350. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/list/__init__.py +0 -0
  351. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/list/listitem.py +0 -0
  352. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/list/listview.py +0 -0
  353. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/menubar.py +0 -0
  354. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/meter.py +0 -0
  355. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/numericentry.py +0 -0
  356. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/pagestack.py +0 -0
  357. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/passwordentry.py +0 -0
  358. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/pathentry.py +0 -0
  359. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/radiogroup.py +0 -0
  360. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/scrolledtext.py +0 -0
  361. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/scrolledtext.pyi +0 -0
  362. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/scrollview.py +0 -0
  363. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/selectbox.py +0 -0
  364. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/sidenav/__init__.py +0 -0
  365. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/sidenav/group.py +0 -0
  366. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/sidenav/header.py +0 -0
  367. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/sidenav/item.py +0 -0
  368. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/sidenav/separator.py +0 -0
  369. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/sidenav/view.py +0 -0
  370. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/spinnerentry.py +0 -0
  371. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/tableview/__init__.py +0 -0
  372. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/tableview/types.py +0 -0
  373. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/tabs/__init__.py +0 -0
  374. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/tabs/tabitem.py +0 -0
  375. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/tabs/tabs.py +0 -0
  376. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/tabs/tabview.py +0 -0
  377. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/textentry.py +0 -0
  378. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/timeentry.py +0 -0
  379. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/toast.py +0 -0
  380. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/togglegroup.py +0 -0
  381. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/toolbar.py +0 -0
  382. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/composites/tooltip.py +0 -0
  383. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/internal/__init__.py +0 -0
  384. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/internal/wrapper_base.py +0 -0
  385. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/mixins/__init__.py +0 -0
  386. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/mixins/configure_mixin.py +0 -0
  387. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/mixins/entry_mixin.py +0 -0
  388. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/mixins/font_mixin.py +0 -0
  389. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/mixins/icon_mixin.py +0 -0
  390. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/mixins/localization_mixin.py +0 -0
  391. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/mixins/signal_mixin.py +0 -0
  392. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/mixins/validation_mixin.py +0 -0
  393. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/parts/__init__.py +0 -0
  394. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/parts/numberentry_part.py +0 -0
  395. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/parts/spinnerentry_part.py +0 -0
  396. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/parts/textentry_part.py +0 -0
  397. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/__init__.py +0 -0
  398. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/badge.py +0 -0
  399. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/button.py +0 -0
  400. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/card.py +0 -0
  401. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/checkbutton.py +0 -0
  402. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/checktoggle.py +0 -0
  403. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/combobox.py +0 -0
  404. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/entry.py +0 -0
  405. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/frame.py +0 -0
  406. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/gridframe.py +0 -0
  407. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/label.py +0 -0
  408. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/labelframe.py +0 -0
  409. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/menubutton.py +0 -0
  410. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/notebook.py +0 -0
  411. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/optionmenu.py +0 -0
  412. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/packframe.py +0 -0
  413. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/panedwindow.py +0 -0
  414. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/progressbar.py +0 -0
  415. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/radiobutton.py +0 -0
  416. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/radiotoggle.py +0 -0
  417. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/scale.py +0 -0
  418. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/scrollbar.py +0 -0
  419. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/separator.py +0 -0
  420. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/sizegrip.py +0 -0
  421. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/spinbox.py +0 -0
  422. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/switch.py +0 -0
  423. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/primitives/treeview.py +0 -0
  424. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack/widgets/types.py +0 -0
  425. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack.egg-info/dependency_links.txt +0 -0
  426. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack.egg-info/entry_points.txt +0 -0
  427. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack.egg-info/requires.txt +0 -0
  428. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/src/bootstack.egg-info/top_level.txt +0 -0
  429. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/tests/test_togglegroup.py +0 -0
  430. {bootstack-0.1.0a4 → bootstack-0.1.0a6}/tests/test_variables.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bootstack
3
- Version: 0.1.0a4
3
+ Version: 0.1.0a6
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
@@ -44,9 +44,16 @@ Dynamic: license-file
44
44
  ![](https://img.shields.io/github/forks/israel-dryer/bootstack.svg)
45
45
 
46
46
 
47
- **bootstack** is a batteries-included desktop application framework for Python, built on Tk. It grew out of [ttkbootstrap](https://github.com/israel-dryer/ttkbootstrap) — which brought Bootstrap-style theming to ttk widgets — and bundles the layers you'd expect from a modern framework around it: app scaffolding, layout containers, semantic styling, reactive signals, forms and validation, i18n, a data layer, and a CLI for scaffolding and packaging.
47
+ > **From the maker of [ttkbootstrap](https://github.com/israel-dryer/ttkbootstrap).**
48
48
 
49
- The aim is to take you from `pip install` to a working, themed application without wiring those pieces together yourself or dropping down to raw Tk geometry calls.
49
+ **bootstack** is a batteries-included desktop framework for Python, built on Tk.
50
+
51
+ 60+ themed widgets. Reactive state. Declarative layout. Built-in icons and localization. A CLI that scaffolds, builds, and ships. Everything ttkbootstrap was missing.
52
+
53
+ <p align="center">
54
+ <img src="docs/assets/hero-demo-app-light.png" width="49%" alt="bootstack Data Analysis Workbench — light theme">
55
+ <img src="docs/assets/hero-demo-app-dark.png" width="49%" alt="bootstack Data Analysis Workbench — dark theme">
56
+ </p>
50
57
 
51
58
  > **Active alpha.** APIs may change before the first stable release.
52
59
  > See the [documentation](https://bootstack.org) for guides and the API reference.
@@ -61,6 +68,14 @@ bootstack is currently in **active alpha**, so the `--pre` flag is required to o
61
68
  pip install --pre bootstack
62
69
  ```
63
70
 
71
+ ## See it
72
+
73
+ The widget gallery is a single-window tour of everything bootstack ships — every widget, theme switcher, accent variants, and layout containers. Fastest way to see the framework in action without writing a line of code:
74
+
75
+ ```bash
76
+ bootstack gallery
77
+ ```
78
+
64
79
  ## Quick Start
65
80
 
66
81
  ```python
@@ -136,7 +151,7 @@ bs.Button(app, text="+1", command=lambda: counter.set(counter.get() + 1))
136
151
  ## Features
137
152
 
138
153
  - **Application scaffolding** — `App` for blank windows, `AppShell` for toolbar + sidebar + page-stack apps, frameless windows with custom chrome
139
- - **60+ widgets** — ttk-derived primitives plus higher-level composites (TableView, Calendar, DateEntry, Form, FloodGauge, Meter, ToggleGroup, PageStack, Toast, Tooltip, and more)
154
+ - **60+ themed widgets** — ttk-derived primitives plus higher-level composites (TableView, Calendar, DateEntry, Form, FloodGauge, Meter, ToggleGroup, PageStack, Toast, Tooltip, and more)
140
155
  - **9 dialogs** — Message, Query, ColorChooser, ColorDropper, DateDialog, FontDialog, FilterDialog, FormDialog, plus a `Dialog` base
141
156
  - **Layout containers** — `PackFrame` and `GridFrame` for declarative layouts; `ScrollView`, `PanedWindow`, `Accordion`, `Card`, `Expander`
142
157
  - **Design system** — semantic `accent` colors (primary, secondary, success, danger, warning, info) and `variant` tokens (solid, outline, ghost, link, text), consistent across widgets
@@ -168,6 +183,7 @@ bs.Button(app, text="+1", command=lambda: counter.set(counter.get() + 1))
168
183
  bootstack ships with an optional CLI for scaffolding, running, and packaging applications:
169
184
 
170
185
  ```bash
186
+ bootstack gallery # Launch the interactive widget gallery
171
187
  bootstack start MyApp # Create a new project (basic template)
172
188
  bootstack start MyApp --template appshell # ...or with sidebar navigation
173
189
  bootstack run # Run the app defined in the project config
@@ -10,9 +10,16 @@
10
10
  ![](https://img.shields.io/github/forks/israel-dryer/bootstack.svg)
11
11
 
12
12
 
13
- **bootstack** is a batteries-included desktop application framework for Python, built on Tk. It grew out of [ttkbootstrap](https://github.com/israel-dryer/ttkbootstrap) — which brought Bootstrap-style theming to ttk widgets — and bundles the layers you'd expect from a modern framework around it: app scaffolding, layout containers, semantic styling, reactive signals, forms and validation, i18n, a data layer, and a CLI for scaffolding and packaging.
13
+ > **From the maker of [ttkbootstrap](https://github.com/israel-dryer/ttkbootstrap).**
14
14
 
15
- The aim is to take you from `pip install` to a working, themed application without wiring those pieces together yourself or dropping down to raw Tk geometry calls.
15
+ **bootstack** is a batteries-included desktop framework for Python, built on Tk.
16
+
17
+ 60+ themed widgets. Reactive state. Declarative layout. Built-in icons and localization. A CLI that scaffolds, builds, and ships. Everything ttkbootstrap was missing.
18
+
19
+ <p align="center">
20
+ <img src="docs/assets/hero-demo-app-light.png" width="49%" alt="bootstack Data Analysis Workbench — light theme">
21
+ <img src="docs/assets/hero-demo-app-dark.png" width="49%" alt="bootstack Data Analysis Workbench — dark theme">
22
+ </p>
16
23
 
17
24
  > **Active alpha.** APIs may change before the first stable release.
18
25
  > See the [documentation](https://bootstack.org) for guides and the API reference.
@@ -27,6 +34,14 @@ bootstack is currently in **active alpha**, so the `--pre` flag is required to o
27
34
  pip install --pre bootstack
28
35
  ```
29
36
 
37
+ ## See it
38
+
39
+ The widget gallery is a single-window tour of everything bootstack ships — every widget, theme switcher, accent variants, and layout containers. Fastest way to see the framework in action without writing a line of code:
40
+
41
+ ```bash
42
+ bootstack gallery
43
+ ```
44
+
30
45
  ## Quick Start
31
46
 
32
47
  ```python
@@ -102,7 +117,7 @@ bs.Button(app, text="+1", command=lambda: counter.set(counter.get() + 1))
102
117
  ## Features
103
118
 
104
119
  - **Application scaffolding** — `App` for blank windows, `AppShell` for toolbar + sidebar + page-stack apps, frameless windows with custom chrome
105
- - **60+ widgets** — ttk-derived primitives plus higher-level composites (TableView, Calendar, DateEntry, Form, FloodGauge, Meter, ToggleGroup, PageStack, Toast, Tooltip, and more)
120
+ - **60+ themed widgets** — ttk-derived primitives plus higher-level composites (TableView, Calendar, DateEntry, Form, FloodGauge, Meter, ToggleGroup, PageStack, Toast, Tooltip, and more)
106
121
  - **9 dialogs** — Message, Query, ColorChooser, ColorDropper, DateDialog, FontDialog, FilterDialog, FormDialog, plus a `Dialog` base
107
122
  - **Layout containers** — `PackFrame` and `GridFrame` for declarative layouts; `ScrollView`, `PanedWindow`, `Accordion`, `Card`, `Expander`
108
123
  - **Design system** — semantic `accent` colors (primary, secondary, success, danger, warning, info) and `variant` tokens (solid, outline, ghost, link, text), consistent across widgets
@@ -134,6 +149,7 @@ bs.Button(app, text="+1", command=lambda: counter.set(counter.get() + 1))
134
149
  bootstack ships with an optional CLI for scaffolding, running, and packaging applications:
135
150
 
136
151
  ```bash
152
+ bootstack gallery # Launch the interactive widget gallery
137
153
  bootstack start MyApp # Create a new project (basic template)
138
154
  bootstack start MyApp --template appshell # ...or with sidebar navigation
139
155
  bootstack run # Run the app defined in the project config
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "bootstack"
7
- version = "0.1.0a4"
7
+ version = "0.1.0a6"
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.0a4"
85
+ current_version = "0.1.0a6"
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}",
@@ -50,6 +50,7 @@ if TYPE_CHECKING:
50
50
  from bootstack.api.style import (
51
51
  Font,
52
52
  Style,
53
+ Typography,
53
54
  get_style,
54
55
  get_style_builder,
55
56
  get_theme,
@@ -58,6 +59,7 @@ if TYPE_CHECKING:
58
59
  toggle_theme,
59
60
  get_theme_color,
60
61
  get_themes,
62
+ register_user_theme,
61
63
  )
62
64
  from bootstack.api.widgets import (
63
65
  Button,
@@ -80,6 +82,8 @@ if TYPE_CHECKING:
80
82
  Label,
81
83
  LabelFrame,
82
84
  LabeledScale,
85
+ ListItem,
86
+ ListView,
83
87
  MenuBar,
84
88
  MenuButton,
85
89
  Meter,
@@ -158,10 +162,11 @@ _MODULE_EXPORTS = {
158
162
  ],
159
163
  # Style & Theming
160
164
  "bootstack.api.style": [
161
- "BootstrapIcon", "Font", "Style",
165
+ "BootstrapIcon", "Font", "Style", "Typography",
162
166
  "get_style", "get_style_builder", "get_theme",
163
167
  "get_theme_provider", "set_theme", "get_theme_color",
164
168
  "toggle_theme", "get_themes",
169
+ "register_user_theme",
165
170
  ],
166
171
  # Widgets
167
172
  "bootstack.api.widgets": [
@@ -173,7 +178,7 @@ _MODULE_EXPORTS = {
173
178
  "RadioToggle",
174
179
  "Calendar", "ContextMenu", "ContextMenuItem", "DateEntry",
175
180
  "Accordion", "DropdownButton", "Expander", "Field", "FieldOptions", "FloodGauge", "Form",
176
- "GridFrame", "LabeledScale", "MenuBar", "Meter",
181
+ "GridFrame", "LabeledScale", "ListItem", "ListView", "MenuBar", "Meter",
177
182
  "SideNav", "SideNavItem", "SideNavGroup",
178
183
  "SideNavHeader", "SideNavSeparator",
179
184
  "NumericEntry", "PackFrame", "PageStack",
@@ -6,12 +6,14 @@ from ttkbootstrap_icons_bs import BootstrapIcon
6
6
 
7
7
  from bootstack.style.style import (Style, get_style, get_style_builder, get_theme, get_theme_color,
8
8
  get_theme_provider, set_theme, toggle_theme, get_themes)
9
- from bootstack.style.typography import Font
9
+ from bootstack.style.theme_provider import register_user_theme
10
+ from bootstack.style.typography import Font, Typography
10
11
 
11
12
  __all__ = [
12
13
  "BootstrapIcon",
13
14
  "Font",
14
15
  "Style",
16
+ "Typography",
15
17
  "get_style",
16
18
  "get_style_builder",
17
19
  "get_theme",
@@ -20,4 +22,5 @@ __all__ = [
20
22
  "get_theme_provider",
21
23
  "get_theme_color",
22
24
  "get_themes",
25
+ "register_user_theme",
23
26
  ]
@@ -35,6 +35,7 @@ from bootstack.widgets.primitives.gridframe import GridFrame
35
35
  from bootstack.widgets.primitives.label import Label
36
36
  from bootstack.widgets.primitives.labelframe import LabelFrame
37
37
  from bootstack.widgets.composites.labeledscale import LabeledScale
38
+ from bootstack.widgets.composites.list import ListItem, ListView
38
39
  from bootstack.widgets.composites.menubar import MenuBar
39
40
  from bootstack.widgets.primitives.menubutton import MenuButton
40
41
  from bootstack.widgets.composites.meter import Meter
@@ -93,6 +94,8 @@ __all__ = [
93
94
  "Label",
94
95
  "LabelFrame",
95
96
  "LabeledScale",
97
+ "ListItem",
98
+ "ListView",
96
99
  "MenuBar",
97
100
  "SideNav",
98
101
  "SideNavItem",
@@ -19,7 +19,8 @@ Usage:
19
19
  bootstack add i18n Add i18n support
20
20
  bootstack list themes List available themes
21
21
  bootstack doctor Diagnose project and environment health
22
- bootstack demo Launch the widget demo
22
+ bootstack gallery Launch the widget gallery
23
+ bootstack icons Browse Bootstrap Icons
23
24
  """
24
25
 
25
26
  from __future__ import annotations
@@ -28,7 +29,7 @@ import argparse
28
29
  import sys
29
30
  from typing import Sequence
30
31
 
31
- from bootstack.cli import add, build, doctor, list_cmd, promote, run, start
32
+ from bootstack.cli import add, build, doctor, icons, list_cmd, promote, run, start
32
33
  from bootstack.cli.demo import run_demo
33
34
 
34
35
 
@@ -49,7 +50,8 @@ Examples:
49
50
  bootstack add view SettingsView Add a new view
50
51
  bootstack list themes List available themes
51
52
  bootstack doctor Diagnose project and environment health
52
- bootstack demo Launch the widget demo
53
+ bootstack gallery Launch the widget gallery
54
+ bootstack icons Browse Bootstrap Icons
53
55
 
54
56
  For more information on a command:
55
57
  bootstack <command> --help
@@ -82,11 +84,19 @@ For more information on a command:
82
84
  add.add_parser(subparsers)
83
85
  list_cmd.add_parser(subparsers)
84
86
  doctor.add_parser(subparsers)
87
+ icons.add_parser(subparsers)
85
88
 
86
- # Demo command (kept for backwards compatibility)
89
+ # Gallery command
90
+ gallery_parser = subparsers.add_parser(
91
+ "gallery",
92
+ help="Launch the widget gallery",
93
+ )
94
+ gallery_parser.set_defaults(func=lambda args: run_demo())
95
+
96
+ # demo is kept as a backwards-compatible alias
87
97
  demo_parser = subparsers.add_parser(
88
98
  "demo",
89
- help="Launch the widget demo",
99
+ help=argparse.SUPPRESS,
90
100
  )
91
101
  demo_parser.set_defaults(func=lambda args: run_demo())
92
102
 
@@ -305,7 +305,7 @@ def run_add_theme(args: argparse.Namespace) -> None:
305
305
  print()
306
306
  print(" from bootstack.style.theme_provider import register_user_theme")
307
307
  print(f' register_user_theme("{theme_name}", "themes/{theme_name}.json")')
308
- print(f' app = ttk.App(theme="{theme_name}")')
308
+ print(f' app = bs.App(theme="{theme_name}")')
309
309
 
310
310
 
311
311
  def run_add_i18n(args: argparse.Namespace) -> None:
@@ -340,7 +340,7 @@ def run_add_i18n(args: argparse.Namespace) -> None:
340
340
  print("Next steps:")
341
341
  print(" 1. Add translatable strings to your .po files")
342
342
  print(" 2. Compile with: msgfmt locales/<lang>/LC_MESSAGES/messages.po -o locales/<lang>/LC_MESSAGES/messages.mo")
343
- print(" 3. Use translations in code: ttk.mc('Hello')")
343
+ print(" 3. Use translations in code: bs.L('Hello')")
344
344
 
345
345
 
346
346
  _BASE_SHADES = {
@@ -1,5 +1,5 @@
1
1
  """
2
- bootstack Widget Gallery
2
+ Widget Gallery
3
3
 
4
4
  An AppShell-based showcase of bootstack widgets, organized by category
5
5
  to mirror the documentation structure. Each sidebar item opens a page
@@ -1170,7 +1170,7 @@ def _build_theme_page(page):
1170
1170
  def run_demo():
1171
1171
  """Run the bootstack widget gallery as an AppShell application."""
1172
1172
  shell = bs.AppShell(
1173
- title="bootstack Widget Gallery",
1173
+ title="Widget Gallery",
1174
1174
  theme="bootstrap-light",
1175
1175
  size=(1100, 750),
1176
1176
  )
@@ -1261,7 +1261,7 @@ def setup_demo(master):
1261
1261
 
1262
1262
  bs.Label(
1263
1263
  master,
1264
- text="Use 'bootstack demo' to launch the full Widget Gallery.",
1264
+ text="Use 'bootstack gallery' to launch the Widget Gallery.",
1265
1265
  font="heading-lg",
1266
1266
  padding=40,
1267
1267
  ).pack(fill=BOTH, expand=YES)
@@ -0,0 +1,28 @@
1
+ """Icons command — delegates to the ttkbootstrap-icons browser."""
2
+ from __future__ import annotations
3
+
4
+ import argparse
5
+ import subprocess
6
+ import sys
7
+ from pathlib import Path
8
+
9
+
10
+ def add_parser(subparsers: argparse._SubParsersAction) -> None:
11
+ parser = subparsers.add_parser(
12
+ "icons",
13
+ help="Browse Bootstrap Icons available in bootstack",
14
+ description=(
15
+ "Launch the Bootstrap Icons browser.\n\n"
16
+ "Delegates to the ttkbootstrap-icons tool bundled with the "
17
+ "ttkbootstrap_icons_bs package. Any icon name shown there can "
18
+ "be used as the icon= parameter on any bootstack widget."
19
+ ),
20
+ )
21
+ parser.set_defaults(func=lambda args: run_icons())
22
+
23
+
24
+ def run_icons() -> None:
25
+ scripts = Path(sys.executable).parent
26
+ name = "ttkbootstrap-icons.exe" if sys.platform == "win32" else "ttkbootstrap-icons"
27
+ result = subprocess.run([str(scripts / name)])
28
+ sys.exit(result.returncode)
@@ -34,6 +34,10 @@ from typing import Any, Dict, List, Optional, Union, Sequence
34
34
  from bootstack.datasource.base import BaseDataSource
35
35
  from bootstack.datasource.types import Primitive, Record
36
36
 
37
+ # Internal column names — reserved by SqliteDataSource, never exposed to user data.
38
+ _ROW_ID = "_bs_row_id"
39
+ _ROW_SEL = "_bs_selected"
40
+
37
41
 
38
42
  class SqliteDataSource(BaseDataSource):
39
43
  """SQLite-backed data manager with pagination, filtering, sorting, and CRUD operations.
@@ -61,8 +65,9 @@ class SqliteDataSource(BaseDataSource):
61
65
  - The database connection persists for the lifetime of the object
62
66
  - Close the connection explicitly with conn.close() if needed
63
67
  - Schema is inferred from first record's data types
64
- - 'id' field is automatically set as PRIMARY KEY
65
- - 'selected' field is added automatically for selection tracking
68
+ - An internal row-identity column (_bs_row_id) is added automatically as PRIMARY KEY
69
+ - An internal selection column (_bs_selected) is added automatically for selection tracking
70
+ - These internal columns are filtered out of the display column list automatically
66
71
  """
67
72
 
68
73
  def __init__(self, name: str = ":memory:", page_size: int = 10):
@@ -121,12 +126,12 @@ class SqliteDataSource(BaseDataSource):
121
126
  using_dicts = True
122
127
 
123
128
  if using_dicts:
124
- # Ensure helper columns
129
+ # Ensure internal helper columns
125
130
  for i, record in enumerate(records):
126
- if "id" not in record:
127
- record["id"] = i
128
- if "selected" not in record:
129
- record["selected"] = 0
131
+ if _ROW_ID not in record:
132
+ record[_ROW_ID] = i
133
+ if _ROW_SEL not in record:
134
+ record[_ROW_SEL] = 0
130
135
 
131
136
  self._columns = list(records[0].keys())
132
137
  col_types = {col: self._infer_type(records[0][col]) for col in self._columns}
@@ -136,25 +141,25 @@ class SqliteDataSource(BaseDataSource):
136
141
  keys = list(column_keys or [])
137
142
  if not keys:
138
143
  keys = [str(i) for i in range(len(first))]
139
- need_id = "id" not in keys
140
- need_selected = "selected" not in keys
144
+ need_id = _ROW_ID not in keys
145
+ need_sel = _ROW_SEL not in keys
141
146
  if need_id:
142
- keys.append("id")
143
- if need_selected:
144
- keys.append("selected")
147
+ keys.append(_ROW_ID)
148
+ if need_sel:
149
+ keys.append(_ROW_SEL)
145
150
  self._columns = keys
146
151
 
147
152
  # Infer types from first row (pad to keys length)
148
153
  padded_first = list(first) + [None] * (len(keys) - len(first))
149
- if need_id and "id" in keys:
150
- padded_first[keys.index("id")] = 0
151
- if need_selected and "selected" in keys:
152
- padded_first[keys.index("selected")] = 0
154
+ if need_id and _ROW_ID in keys:
155
+ padded_first[keys.index(_ROW_ID)] = 0
156
+ if need_sel and _ROW_SEL in keys:
157
+ padded_first[keys.index(_ROW_SEL)] = 0
153
158
  col_types = {col: self._infer_type(padded_first[idx]) for idx, col in enumerate(keys)}
154
159
 
155
160
  rows_to_insert = []
156
- id_idx = keys.index("id") if "id" in keys else None
157
- sel_idx = keys.index("selected") if "selected" in keys else None
161
+ id_idx = keys.index(_ROW_ID) if _ROW_ID in keys else None
162
+ sel_idx = keys.index(_ROW_SEL) if _ROW_SEL in keys else None
158
163
  value_len = len(keys)
159
164
  for i, row in enumerate(records):
160
165
  base_values = list(row[: value_len]) + [""] * (value_len - len(row))
@@ -165,7 +170,7 @@ class SqliteDataSource(BaseDataSource):
165
170
  rows_to_insert.append(tuple(base_values))
166
171
 
167
172
  col_definitions = ", ".join(
168
- f"{self._quote_identifier(col)} {col_types[col]}" + (" PRIMARY KEY" if col == "id" else "")
173
+ f"{self._quote_identifier(col)} {col_types[col]}" + (" PRIMARY KEY" if col == _ROW_ID else "")
169
174
  for col in self._columns
170
175
  )
171
176
  placeholders = ", ".join("?" for _ in self._columns)
@@ -241,11 +246,11 @@ class SqliteDataSource(BaseDataSource):
241
246
 
242
247
  def create_record(self, record: Dict[str, Any]) -> int:
243
248
  """Create new record and return its ID."""
244
- if "id" not in record:
245
- record["id"] = self._generate_new_id()
249
+ if _ROW_ID not in record:
250
+ record[_ROW_ID] = self._generate_new_id()
246
251
 
247
- if "selected" not in record:
248
- record["selected"] = 0
252
+ if _ROW_SEL not in record:
253
+ record[_ROW_SEL] = 0
249
254
 
250
255
  # Ensure table exists (handles empty datasources)
251
256
  self._ensure_table_for_record(record)
@@ -257,11 +262,11 @@ class SqliteDataSource(BaseDataSource):
257
262
 
258
263
  with self.conn:
259
264
  self.conn.execute(f"INSERT INTO {self._table} ({cols}) VALUES ({placeholders})", values)
260
- return record["id"]
265
+ return record[_ROW_ID]
261
266
 
262
267
  def read_record(self, record_id: Any) -> Optional[Dict[str, Any]]:
263
268
  """Retrieve single record by ID."""
264
- cursor = self.conn.execute(f"SELECT * FROM {self._table} WHERE id = ?", (record_id,))
269
+ cursor = self.conn.execute(f"SELECT * FROM {self._table} WHERE {_ROW_ID} = ?", (record_id,))
265
270
  row = cursor.fetchone()
266
271
  return dict(row) if row else None
267
272
 
@@ -272,19 +277,19 @@ class SqliteDataSource(BaseDataSource):
272
277
  set_clause = ", ".join(f"{self._quote_identifier(k)} = ?" for k in updates)
273
278
  values = tuple(updates.values()) + (record_id,)
274
279
  with self.conn:
275
- cur = self.conn.execute(f"UPDATE {self._table} SET {set_clause} WHERE id = ?", values)
280
+ cur = self.conn.execute(f"UPDATE {self._table} SET {set_clause} WHERE {_ROW_ID} = ?", values)
276
281
  return cur.rowcount > 0
277
282
 
278
283
  def delete_record(self, record_id: Any) -> bool:
279
284
  """Delete record by ID."""
280
285
  with self.conn:
281
- cur = self.conn.execute(f"DELETE FROM {self._table} WHERE id = ?", (record_id,))
286
+ cur = self.conn.execute(f"DELETE FROM {self._table} WHERE {_ROW_ID} = ?", (record_id,))
282
287
  return cur.rowcount > 0
283
288
 
284
289
  def _generate_new_id(self) -> int:
285
290
  """Generate next available integer ID."""
286
291
  try:
287
- cursor = self.conn.execute(f"SELECT MAX(id) FROM {self._table}")
292
+ cursor = self.conn.execute(f"SELECT MAX({_ROW_ID}) FROM {self._table}")
288
293
  max_id = cursor.fetchone()[0]
289
294
  except Exception:
290
295
  max_id = 0
@@ -301,23 +306,23 @@ class SqliteDataSource(BaseDataSource):
301
306
  pass
302
307
 
303
308
  cols = list(self._columns) if self._columns else list(record.keys())
304
- if "id" not in cols:
305
- cols.append("id")
306
- if "selected" not in cols:
307
- cols.append("selected")
309
+ if _ROW_ID not in cols:
310
+ cols.append(_ROW_ID)
311
+ if _ROW_SEL not in cols:
312
+ cols.append(_ROW_SEL)
308
313
  self._columns = cols
309
314
 
310
315
  col_types = {}
311
316
  for c in cols:
312
- if c == "id":
317
+ if c == _ROW_ID:
313
318
  col_types[c] = "INTEGER"
314
- elif c == "selected":
319
+ elif c == _ROW_SEL:
315
320
  col_types[c] = "INTEGER"
316
321
  else:
317
322
  col_types[c] = self._infer_type(record.get(c))
318
323
 
319
324
  col_definitions = ", ".join(
320
- f"{self._quote_identifier(col)} {col_types[col]}" + (" PRIMARY KEY" if col == "id" else "")
325
+ f"{self._quote_identifier(col)} {col_types[col]}" + (" PRIMARY KEY" if col == _ROW_ID else "")
321
326
  for col in cols
322
327
  )
323
328
  with self.conn:
@@ -337,40 +342,40 @@ class SqliteDataSource(BaseDataSource):
337
342
  """Select all records (optionally only current page)."""
338
343
  self._ensure_selected_column()
339
344
  if current_page_only:
340
- ids = [row["id"] for row in self.get_page()]
345
+ ids = [row[_ROW_ID] for row in self.get_page()]
341
346
  if not ids:
342
347
  return 0
343
348
  placeholders = ", ".join("?" for _ in ids)
344
- query = f"UPDATE {self._table} SET selected = 1 WHERE id IN ({placeholders})"
349
+ query = f"UPDATE {self._table} SET {_ROW_SEL} = 1 WHERE {_ROW_ID} IN ({placeholders})"
345
350
  with self.conn:
346
351
  cur = self.conn.execute(query, ids)
347
352
  return cur.rowcount
348
353
  else:
349
354
  with self.conn:
350
- cur = self.conn.execute(f"UPDATE {self._table} SET selected = 1")
355
+ cur = self.conn.execute(f"UPDATE {self._table} SET {_ROW_SEL} = 1")
351
356
  return cur.rowcount
352
357
 
353
358
  def unselect_all(self, current_page_only: bool = False) -> int:
354
359
  """Unselect all records (optionally only current page)."""
355
360
  self._ensure_selected_column()
356
361
  if current_page_only:
357
- ids = [row["id"] for row in self.get_page()]
362
+ ids = [row[_ROW_ID] for row in self.get_page()]
358
363
  if not ids:
359
364
  return 0
360
365
  placeholders = ", ".join("?" for _ in ids)
361
- query = f"UPDATE {self._table} SET selected = 0 WHERE id IN ({placeholders})"
366
+ query = f"UPDATE {self._table} SET {_ROW_SEL} = 0 WHERE {_ROW_ID} IN ({placeholders})"
362
367
  with self.conn:
363
368
  cur = self.conn.execute(query, ids)
364
369
  return cur.rowcount
365
370
  else:
366
371
  with self.conn:
367
- cur = self.conn.execute(f"UPDATE {self._table} SET selected = 0")
372
+ cur = self.conn.execute(f"UPDATE {self._table} SET {_ROW_SEL} = 0")
368
373
  return cur.rowcount
369
374
 
370
375
  def get_selected(self, page: Optional[int] = None) -> List[Dict[str, Any]]:
371
376
  """Get selected records, optionally paginated."""
372
377
  self._ensure_selected_column()
373
- query = f"SELECT * FROM {self._table} WHERE selected = 1"
378
+ query = f"SELECT * FROM {self._table} WHERE {_ROW_SEL} = 1"
374
379
 
375
380
  if page is not None:
376
381
  offset = page * self.page_size
@@ -380,28 +385,30 @@ class SqliteDataSource(BaseDataSource):
380
385
  return [dict(row) for row in cursor.fetchall()]
381
386
 
382
387
  def _ensure_selected_column(self):
383
- """Add 'selected' column to table if it doesn't exist."""
384
- if "selected" not in self._columns:
388
+ """Add selection column to table if it doesn't exist."""
389
+ if _ROW_SEL not in self._columns:
385
390
  with self.conn:
386
- self.conn.execute(f"ALTER TABLE {self._table} ADD COLUMN selected INTEGER DEFAULT 0")
387
- self._columns.append("selected")
391
+ self.conn.execute(f"ALTER TABLE {self._table} ADD COLUMN {_ROW_SEL} INTEGER DEFAULT 0")
392
+ self._columns.append(_ROW_SEL)
388
393
 
389
394
  def selected_count(self) -> int:
390
395
  """Get total number of selected records."""
391
396
  self._ensure_selected_column()
392
- query = f"SELECT COUNT(*) FROM {self._table} WHERE selected = 1"
397
+ query = f"SELECT COUNT(*) FROM {self._table} WHERE {_ROW_SEL} = 1"
393
398
  return self.conn.execute(query).fetchone()[0]
394
399
 
395
400
  def _set_selected_flag(self, record_id: Any, flag: int) -> bool:
396
401
  """Set selection flag for record by ID."""
397
- if "selected" not in self._columns:
398
- # Add selected column if it doesn't exist
402
+ if _ROW_SEL not in self._columns:
399
403
  with self.conn:
400
- self.conn.execute(f"ALTER TABLE {self._table} ADD COLUMN selected INTEGER DEFAULT 0")
401
- self._columns.append("selected")
404
+ self.conn.execute(f"ALTER TABLE {self._table} ADD COLUMN {_ROW_SEL} INTEGER DEFAULT 0")
405
+ self._columns.append(_ROW_SEL)
402
406
 
403
407
  with self.conn:
404
- cur = self.conn.execute(f"UPDATE {self._table} SET selected = ? WHERE id = ?", (flag, record_id))
408
+ cur = self.conn.execute(
409
+ f"UPDATE {self._table} SET {_ROW_SEL} = ? WHERE {_ROW_ID} = ?",
410
+ (flag, record_id),
411
+ )
405
412
  return cur.rowcount > 0
406
413
 
407
414
  # === DATA EXPORT ===
@@ -411,7 +418,7 @@ class SqliteDataSource(BaseDataSource):
411
418
  self._ensure_selected_column()
412
419
  query = f"SELECT * FROM {self._table}"
413
420
  if not include_all:
414
- query += " WHERE selected = 1"
421
+ query += f" WHERE {_ROW_SEL} = 1"
415
422
 
416
423
  cursor = self.conn.execute(query)
417
424
  rows = cursor.fetchall()