bootstack 0.1.0a1__py3-none-any.whl

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 (419) hide show
  1. bootstack/__init__.py +249 -0
  2. bootstack/__main__.py +5 -0
  3. bootstack/api/__init__.py +127 -0
  4. bootstack/api/app.py +30 -0
  5. bootstack/api/constants.py +3 -0
  6. bootstack/api/data.py +23 -0
  7. bootstack/api/dialogs.py +44 -0
  8. bootstack/api/i18n.py +17 -0
  9. bootstack/api/localization.py +16 -0
  10. bootstack/api/menu.py +7 -0
  11. bootstack/api/style.py +23 -0
  12. bootstack/api/utils.py +24 -0
  13. bootstack/api/widgets.py +137 -0
  14. bootstack/assets/__init__.py +24 -0
  15. bootstack/assets/bootstack-transparent.png +0 -0
  16. bootstack/assets/bootstack.ico +0 -0
  17. bootstack/assets/bootstack.png +0 -0
  18. bootstack/assets/elements/__init__.py +0 -0
  19. bootstack/assets/elements/badge-pill.png +0 -0
  20. bootstack/assets/elements/badge-square.png +0 -0
  21. bootstack/assets/elements/border.png +0 -0
  22. bootstack/assets/elements/button-compact.png +0 -0
  23. bootstack/assets/elements/button-default.png +0 -0
  24. bootstack/assets/elements/button-group-horizontal-after-compact.png +0 -0
  25. bootstack/assets/elements/button-group-horizontal-after-default.png +0 -0
  26. bootstack/assets/elements/button-group-horizontal-before-compact.png +0 -0
  27. bootstack/assets/elements/button-group-horizontal-before-default.png +0 -0
  28. bootstack/assets/elements/button-group-horizontal-center-compact.png +0 -0
  29. bootstack/assets/elements/button-group-horizontal-center-default.png +0 -0
  30. bootstack/assets/elements/button-group-vertical-after-compact.png +0 -0
  31. bootstack/assets/elements/button-group-vertical-after-default.png +0 -0
  32. bootstack/assets/elements/button-group-vertical-before-compact.png +0 -0
  33. bootstack/assets/elements/button-group-vertical-before-default.png +0 -0
  34. bootstack/assets/elements/button-group-vertical-center-compact.png +0 -0
  35. bootstack/assets/elements/button-group-vertical-center-default.png +0 -0
  36. bootstack/assets/elements/checkbox-checked.png +0 -0
  37. bootstack/assets/elements/checkbox-indeterminate.png +0 -0
  38. bootstack/assets/elements/checkbox-unchecked.png +0 -0
  39. bootstack/assets/elements/field.png +0 -0
  40. bootstack/assets/elements/input-after-compact.png +0 -0
  41. bootstack/assets/elements/input-after-default.png +0 -0
  42. bootstack/assets/elements/input-before-compact.png +0 -0
  43. bootstack/assets/elements/input-before-default.png +0 -0
  44. bootstack/assets/elements/input-compact.png +0 -0
  45. bootstack/assets/elements/input-default.png +0 -0
  46. bootstack/assets/elements/list-item-separated.png +0 -0
  47. bootstack/assets/elements/list-item.png +0 -0
  48. bootstack/assets/elements/manifest.toml +480 -0
  49. bootstack/assets/elements/menu-item.png +0 -0
  50. bootstack/assets/elements/nav-button-compact.png +0 -0
  51. bootstack/assets/elements/nav-button-default.png +0 -0
  52. bootstack/assets/elements/nav-icon-button-compact.png +0 -0
  53. bootstack/assets/elements/nav-icon-button-default.png +0 -0
  54. bootstack/assets/elements/notebook-client-border.png +0 -0
  55. bootstack/assets/elements/notebook-tab-active.png +0 -0
  56. bootstack/assets/elements/notebook-tab-bar.png +0 -0
  57. bootstack/assets/elements/notebook-tab-normal.png +0 -0
  58. bootstack/assets/elements/notebook-tab-pill.png +0 -0
  59. bootstack/assets/elements/progress-bar-horizontal-striped.png +0 -0
  60. bootstack/assets/elements/progress-bar-solid.png +0 -0
  61. bootstack/assets/elements/progress-bar-thin.png +0 -0
  62. bootstack/assets/elements/progress-bar-vertical-striped.png +0 -0
  63. bootstack/assets/elements/radio-selected.png +0 -0
  64. bootstack/assets/elements/radio-unselected.png +0 -0
  65. bootstack/assets/elements/scrollbar-horizontal.png +0 -0
  66. bootstack/assets/elements/scrollbar-vertical.png +0 -0
  67. bootstack/assets/elements/slider-handle-focus.png +0 -0
  68. bootstack/assets/elements/slider-handle.png +0 -0
  69. bootstack/assets/elements/slider-track-horizontal.png +0 -0
  70. bootstack/assets/elements/slider-track-vertical.png +0 -0
  71. bootstack/assets/elements/switch-off.png +0 -0
  72. bootstack/assets/elements/switch-on.png +0 -0
  73. bootstack/assets/elements/tabs-bar-horizontal.png +0 -0
  74. bootstack/assets/elements/tabs-bar-vertical.png +0 -0
  75. bootstack/assets/elements/tabs-pill.png +0 -0
  76. bootstack/assets/locales/ar/LC_MESSAGES/bootstack.mo +0 -0
  77. bootstack/assets/locales/ar/LC_MESSAGES/bootstack.po +853 -0
  78. bootstack/assets/locales/bg/LC_MESSAGES/bootstack.po +875 -0
  79. bootstack/assets/locales/cs/LC_MESSAGES/bootstack.mo +0 -0
  80. bootstack/assets/locales/cs/LC_MESSAGES/bootstack.po +853 -0
  81. bootstack/assets/locales/da/LC_MESSAGES/bootstack.mo +0 -0
  82. bootstack/assets/locales/da/LC_MESSAGES/bootstack.po +853 -0
  83. bootstack/assets/locales/de/LC_MESSAGES/bootstack.mo +0 -0
  84. bootstack/assets/locales/de/LC_MESSAGES/bootstack.po +853 -0
  85. bootstack/assets/locales/en/LC_MESSAGES/bootstack.mo +0 -0
  86. bootstack/assets/locales/en/LC_MESSAGES/bootstack.po +875 -0
  87. bootstack/assets/locales/es/LC_MESSAGES/bootstack.mo +0 -0
  88. bootstack/assets/locales/es/LC_MESSAGES/bootstack.po +853 -0
  89. bootstack/assets/locales/fr/LC_MESSAGES/bootstack.mo +0 -0
  90. bootstack/assets/locales/fr/LC_MESSAGES/bootstack.po +853 -0
  91. bootstack/assets/locales/he/LC_MESSAGES/bootstack.mo +0 -0
  92. bootstack/assets/locales/he/LC_MESSAGES/bootstack.po +851 -0
  93. bootstack/assets/locales/hi/LC_MESSAGES/bootstack.mo +0 -0
  94. bootstack/assets/locales/hi/LC_MESSAGES/bootstack.po +842 -0
  95. bootstack/assets/locales/it/LC_MESSAGES/bootstack.mo +0 -0
  96. bootstack/assets/locales/it/LC_MESSAGES/bootstack.po +841 -0
  97. bootstack/assets/locales/ja/LC_MESSAGES/bootstack.mo +0 -0
  98. bootstack/assets/locales/ja/LC_MESSAGES/bootstack.po +914 -0
  99. bootstack/assets/locales/ko/LC_MESSAGES/bootstack.mo +0 -0
  100. bootstack/assets/locales/ko/LC_MESSAGES/bootstack.po +842 -0
  101. bootstack/assets/locales/nb/LC_MESSAGES/bootstack.mo +0 -0
  102. bootstack/assets/locales/nb/LC_MESSAGES/bootstack.po +841 -0
  103. bootstack/assets/locales/nl/LC_MESSAGES/bootstack.mo +0 -0
  104. bootstack/assets/locales/nl/LC_MESSAGES/bootstack.po +841 -0
  105. bootstack/assets/locales/pl/LC_MESSAGES/bootstack.mo +0 -0
  106. bootstack/assets/locales/pl/LC_MESSAGES/bootstack.po +842 -0
  107. bootstack/assets/locales/pt/LC_MESSAGES/bootstack.mo +0 -0
  108. bootstack/assets/locales/pt/LC_MESSAGES/bootstack.po +842 -0
  109. bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.mo +0 -0
  110. bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.po +842 -0
  111. bootstack/assets/locales/sl/LC_MESSAGES/bootstack.mo +0 -0
  112. bootstack/assets/locales/sl/LC_MESSAGES/bootstack.po +842 -0
  113. bootstack/assets/locales/sv/LC_MESSAGES/bootstack.mo +0 -0
  114. bootstack/assets/locales/sv/LC_MESSAGES/bootstack.po +842 -0
  115. bootstack/assets/locales/tr/LC_MESSAGES/bootstack.mo +0 -0
  116. bootstack/assets/locales/tr/LC_MESSAGES/bootstack.po +842 -0
  117. bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.mo +0 -0
  118. bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.po +842 -0
  119. bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.mo +0 -0
  120. bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.po +842 -0
  121. bootstack/assets/themes/__init__.py +0 -0
  122. bootstack/assets/themes/amber-dark.json +32 -0
  123. bootstack/assets/themes/amber-light.json +32 -0
  124. bootstack/assets/themes/aurora-dark.json +32 -0
  125. bootstack/assets/themes/aurora-light.json +32 -0
  126. bootstack/assets/themes/bootstrap-dark.json +32 -0
  127. bootstack/assets/themes/bootstrap-light.json +32 -0
  128. bootstack/assets/themes/classic-dark.json +32 -0
  129. bootstack/assets/themes/classic-light.json +32 -0
  130. bootstack/assets/themes/docs-dark.json +32 -0
  131. bootstack/assets/themes/docs-light.json +32 -0
  132. bootstack/assets/themes/forest-dark.json +32 -0
  133. bootstack/assets/themes/forest-light.json +32 -0
  134. bootstack/assets/themes/ocean-dark.json +32 -0
  135. bootstack/assets/themes/ocean-light.json +32 -0
  136. bootstack/assets/themes/rose-dark.json +32 -0
  137. bootstack/assets/themes/rose-light.json +32 -0
  138. bootstack/assets/widgets/__init__.py +0 -0
  139. bootstack/assets/widgets/badge-default.png +0 -0
  140. bootstack/assets/widgets/badge-pill.png +0 -0
  141. bootstack/assets/widgets/border.png +0 -0
  142. bootstack/assets/widgets/button-group-horizontal-after.png +0 -0
  143. bootstack/assets/widgets/button-group-horizontal-before.png +0 -0
  144. bootstack/assets/widgets/button-group-horizontal-center.png +0 -0
  145. bootstack/assets/widgets/button-group-vertical-after.png +0 -0
  146. bootstack/assets/widgets/button-group-vertical-before.png +0 -0
  147. bootstack/assets/widgets/button-group-vertical-center.png +0 -0
  148. bootstack/assets/widgets/button.png +0 -0
  149. bootstack/assets/widgets/checkbox-checked.png +0 -0
  150. bootstack/assets/widgets/checkbox-indeterminate.png +0 -0
  151. bootstack/assets/widgets/checkbox-unchecked.png +0 -0
  152. bootstack/assets/widgets/field.png +0 -0
  153. bootstack/assets/widgets/icon-button.png +0 -0
  154. bootstack/assets/widgets/input-inner.png +0 -0
  155. bootstack/assets/widgets/input-prefix.png +0 -0
  156. bootstack/assets/widgets/input-suffix.png +0 -0
  157. bootstack/assets/widgets/input.png +0 -0
  158. bootstack/assets/widgets/list-item-focus.png +0 -0
  159. bootstack/assets/widgets/list-item-separated.png +0 -0
  160. bootstack/assets/widgets/menu-item-separated.png +0 -0
  161. bootstack/assets/widgets/notebook-client-border.png +0 -0
  162. bootstack/assets/widgets/notebook-pill-active.png +0 -0
  163. bootstack/assets/widgets/notebook-pill-inactive.png +0 -0
  164. bootstack/assets/widgets/notebook-tab-active.png +0 -0
  165. bootstack/assets/widgets/notebook-tab-border.png +0 -0
  166. bootstack/assets/widgets/notebook-tab-normal.png +0 -0
  167. bootstack/assets/widgets/notebook-underline.png +0 -0
  168. bootstack/assets/widgets/progress-bar-horizontal-default.png +0 -0
  169. bootstack/assets/widgets/progress-bar-horizontal-striped.png +0 -0
  170. bootstack/assets/widgets/progress-bar-vertical-default.png +0 -0
  171. bootstack/assets/widgets/progress-bar-vertical-striped.png +0 -0
  172. bootstack/assets/widgets/progress-trough-horizontal.png +0 -0
  173. bootstack/assets/widgets/progress-trough-vertical.png +0 -0
  174. bootstack/assets/widgets/radio-selected.png +0 -0
  175. bootstack/assets/widgets/radio-unselected.png +0 -0
  176. bootstack/assets/widgets/scrollbar-horizontal-rounded.png +0 -0
  177. bootstack/assets/widgets/scrollbar-vertical-rounded.png +0 -0
  178. bootstack/assets/widgets/separator-horizontal.png +0 -0
  179. bootstack/assets/widgets/separator-vertical.png +0 -0
  180. bootstack/assets/widgets/slider-handle-focus.png +0 -0
  181. bootstack/assets/widgets/slider-handle.png +0 -0
  182. bootstack/assets/widgets/slider-track-horizontal.png +0 -0
  183. bootstack/assets/widgets/slider-track-vertical.png +0 -0
  184. bootstack/assets/widgets/switch-off.png +0 -0
  185. bootstack/assets/widgets/switch-on.png +0 -0
  186. bootstack/assets/widgets/tabs-bar-horizontal.png +0 -0
  187. bootstack/assets/widgets/tabs-bar-vertical.png +0 -0
  188. bootstack/assets/widgets/tabs-pill.png +0 -0
  189. bootstack/cli/__init__.py +124 -0
  190. bootstack/cli/__main__.py +6 -0
  191. bootstack/cli/add.py +439 -0
  192. bootstack/cli/build.py +115 -0
  193. bootstack/cli/config.py +287 -0
  194. bootstack/cli/demo.py +1267 -0
  195. bootstack/cli/doctor.py +195 -0
  196. bootstack/cli/list_cmd.py +71 -0
  197. bootstack/cli/promote.py +120 -0
  198. bootstack/cli/pyinstaller.py +246 -0
  199. bootstack/cli/run.py +99 -0
  200. bootstack/cli/start.py +105 -0
  201. bootstack/cli/templates/__init__.py +861 -0
  202. bootstack/constants.py +325 -0
  203. bootstack/core/__init__.py +34 -0
  204. bootstack/core/capabilities/__init__.py +45 -0
  205. bootstack/core/capabilities/after.py +103 -0
  206. bootstack/core/capabilities/bind.py +154 -0
  207. bootstack/core/capabilities/bindtags.py +112 -0
  208. bootstack/core/capabilities/busy.py +61 -0
  209. bootstack/core/capabilities/clipboard.py +88 -0
  210. bootstack/core/capabilities/focus.py +118 -0
  211. bootstack/core/capabilities/grab.py +65 -0
  212. bootstack/core/capabilities/grid.py +188 -0
  213. bootstack/core/capabilities/localization.py +231 -0
  214. bootstack/core/capabilities/pack.py +119 -0
  215. bootstack/core/capabilities/place.py +92 -0
  216. bootstack/core/capabilities/selection.py +136 -0
  217. bootstack/core/capabilities/signals.py +242 -0
  218. bootstack/core/capabilities/winfo.py +315 -0
  219. bootstack/core/colorutils.py +234 -0
  220. bootstack/core/exceptions.py +95 -0
  221. bootstack/core/images.py +283 -0
  222. bootstack/core/localization/README.md +90 -0
  223. bootstack/core/localization/__init__.py +13 -0
  224. bootstack/core/localization/intl_format.py +580 -0
  225. bootstack/core/localization/msgcat.py +425 -0
  226. bootstack/core/localization/specs.py +143 -0
  227. bootstack/core/mixins/__init__.py +1 -0
  228. bootstack/core/mixins/ttk_state.py +35 -0
  229. bootstack/core/mixins/widget.py +132 -0
  230. bootstack/core/publisher.py +147 -0
  231. bootstack/core/signals/README.md +112 -0
  232. bootstack/core/signals/__init__.py +8 -0
  233. bootstack/core/signals/integration.py +100 -0
  234. bootstack/core/signals/signal.py +317 -0
  235. bootstack/core/signals/types.py +4 -0
  236. bootstack/core/validation/__init__.py +5 -0
  237. bootstack/core/validation/types.py +13 -0
  238. bootstack/core/validation/validation_result.py +17 -0
  239. bootstack/core/validation/validation_rules.py +112 -0
  240. bootstack/core/variables.py +62 -0
  241. bootstack/datasource/README.md +607 -0
  242. bootstack/datasource/__init__.py +51 -0
  243. bootstack/datasource/base.py +474 -0
  244. bootstack/datasource/file_source.py +541 -0
  245. bootstack/datasource/memory_source.py +482 -0
  246. bootstack/datasource/sqlite_source.py +453 -0
  247. bootstack/datasource/types.py +259 -0
  248. bootstack/dialogs/__init__.py +56 -0
  249. bootstack/dialogs/colorchooser.py +674 -0
  250. bootstack/dialogs/colordropper.py +257 -0
  251. bootstack/dialogs/datedialog.py +404 -0
  252. bootstack/dialogs/dialog.py +514 -0
  253. bootstack/dialogs/filterdialog.py +358 -0
  254. bootstack/dialogs/fontdialog.py +339 -0
  255. bootstack/dialogs/formdialog.py +541 -0
  256. bootstack/dialogs/message.py +489 -0
  257. bootstack/dialogs/query.py +561 -0
  258. bootstack/py.typed +1 -0
  259. bootstack/runtime/__init__.py +3 -0
  260. bootstack/runtime/app.py +879 -0
  261. bootstack/runtime/base_window.py +786 -0
  262. bootstack/runtime/events.py +399 -0
  263. bootstack/runtime/menu.py +510 -0
  264. bootstack/runtime/shortcuts.py +423 -0
  265. bootstack/runtime/tk_patch.py +31 -0
  266. bootstack/runtime/toplevel.py +131 -0
  267. bootstack/runtime/utility.py +371 -0
  268. bootstack/runtime/visual_focus.py +228 -0
  269. bootstack/runtime/window_utilities.py +1043 -0
  270. bootstack/style/__init__.py +5498 -0
  271. bootstack/style/bootstyle.py +507 -0
  272. bootstack/style/bootstyle_builder_base.py +752 -0
  273. bootstack/style/bootstyle_builder_mixed.py +93 -0
  274. bootstack/style/bootstyle_builder_tk.py +109 -0
  275. bootstack/style/bootstyle_builder_ttk.py +354 -0
  276. bootstack/style/builders/__init__.py +51 -0
  277. bootstack/style/builders/badge.py +44 -0
  278. bootstack/style/builders/button.py +453 -0
  279. bootstack/style/builders/buttongroup.py +344 -0
  280. bootstack/style/builders/calendar.py +271 -0
  281. bootstack/style/builders/checkbutton.py +95 -0
  282. bootstack/style/builders/combobox.py +112 -0
  283. bootstack/style/builders/contextmenu.py +268 -0
  284. bootstack/style/builders/entry.py +83 -0
  285. bootstack/style/builders/expander.py +171 -0
  286. bootstack/style/builders/field.py +312 -0
  287. bootstack/style/builders/frame.py +27 -0
  288. bootstack/style/builders/label.py +28 -0
  289. bootstack/style/builders/labelframe.py +41 -0
  290. bootstack/style/builders/listview.py +267 -0
  291. bootstack/style/builders/menubar.py +74 -0
  292. bootstack/style/builders/menubutton.py +408 -0
  293. bootstack/style/builders/notebook.py +316 -0
  294. bootstack/style/builders/panedwindow.py +25 -0
  295. bootstack/style/builders/progressbar.py +71 -0
  296. bootstack/style/builders/radiobutton.py +68 -0
  297. bootstack/style/builders/scale.py +66 -0
  298. bootstack/style/builders/scrollbar.py +360 -0
  299. bootstack/style/builders/separator.py +45 -0
  300. bootstack/style/builders/sidenav.py +313 -0
  301. bootstack/style/builders/sizegrip.py +15 -0
  302. bootstack/style/builders/spinbox.py +119 -0
  303. bootstack/style/builders/switch.py +67 -0
  304. bootstack/style/builders/tabitem.py +205 -0
  305. bootstack/style/builders/toolbutton.py +260 -0
  306. bootstack/style/builders/tooltip.py +26 -0
  307. bootstack/style/builders/treeview.py +269 -0
  308. bootstack/style/builders/utils.py +404 -0
  309. bootstack/style/builders_tk/__init__.py +16 -0
  310. bootstack/style/builders_tk/defaults.py +229 -0
  311. bootstack/style/element.py +173 -0
  312. bootstack/style/style.py +499 -0
  313. bootstack/style/theme_provider.py +449 -0
  314. bootstack/style/tk_patch.py +5 -0
  315. bootstack/style/token_maps.py +42 -0
  316. bootstack/style/types.py +32 -0
  317. bootstack/style/typography.py +527 -0
  318. bootstack/style/utility.py +696 -0
  319. bootstack/themes/__init__.py +12 -0
  320. bootstack/themes/standard.py +415 -0
  321. bootstack/themes/user.py +45 -0
  322. bootstack/widgets/__init__.py +53 -0
  323. bootstack/widgets/composites/__init__.py +38 -0
  324. bootstack/widgets/composites/accordion.py +385 -0
  325. bootstack/widgets/composites/appshell.py +445 -0
  326. bootstack/widgets/composites/buttongroup.py +391 -0
  327. bootstack/widgets/composites/calendar.py +914 -0
  328. bootstack/widgets/composites/compositeframe.py +282 -0
  329. bootstack/widgets/composites/contextmenu.py +1754 -0
  330. bootstack/widgets/composites/dateentry.py +261 -0
  331. bootstack/widgets/composites/dropdownbutton.py +190 -0
  332. bootstack/widgets/composites/expander.py +508 -0
  333. bootstack/widgets/composites/field.py +448 -0
  334. bootstack/widgets/composites/floodgauge.py +434 -0
  335. bootstack/widgets/composites/form.py +983 -0
  336. bootstack/widgets/composites/labeledscale.py +209 -0
  337. bootstack/widgets/composites/list/__init__.py +15 -0
  338. bootstack/widgets/composites/list/listitem.py +733 -0
  339. bootstack/widgets/composites/list/listview.py +1507 -0
  340. bootstack/widgets/composites/menubar.py +303 -0
  341. bootstack/widgets/composites/meter.py +882 -0
  342. bootstack/widgets/composites/numericentry.py +183 -0
  343. bootstack/widgets/composites/pagestack.py +330 -0
  344. bootstack/widgets/composites/passwordentry.py +149 -0
  345. bootstack/widgets/composites/pathentry.py +223 -0
  346. bootstack/widgets/composites/radiogroup.py +466 -0
  347. bootstack/widgets/composites/scrolledtext.py +388 -0
  348. bootstack/widgets/composites/scrolledtext.pyi +186 -0
  349. bootstack/widgets/composites/scrollview.py +675 -0
  350. bootstack/widgets/composites/selectbox.py +544 -0
  351. bootstack/widgets/composites/sidenav/__init__.py +24 -0
  352. bootstack/widgets/composites/sidenav/group.py +485 -0
  353. bootstack/widgets/composites/sidenav/header.py +83 -0
  354. bootstack/widgets/composites/sidenav/item.py +413 -0
  355. bootstack/widgets/composites/sidenav/separator.py +51 -0
  356. bootstack/widgets/composites/sidenav/view.py +919 -0
  357. bootstack/widgets/composites/spinnerentry.py +232 -0
  358. bootstack/widgets/composites/tableview/__init__.py +5 -0
  359. bootstack/widgets/composites/tableview/tableview.py +2254 -0
  360. bootstack/widgets/composites/tableview/types.py +169 -0
  361. bootstack/widgets/composites/tabs/__init__.py +6 -0
  362. bootstack/widgets/composites/tabs/tabitem.py +372 -0
  363. bootstack/widgets/composites/tabs/tabs.py +478 -0
  364. bootstack/widgets/composites/tabs/tabview.py +352 -0
  365. bootstack/widgets/composites/textentry.py +90 -0
  366. bootstack/widgets/composites/timeentry.py +189 -0
  367. bootstack/widgets/composites/toast.py +364 -0
  368. bootstack/widgets/composites/togglegroup.py +382 -0
  369. bootstack/widgets/composites/toolbar.py +393 -0
  370. bootstack/widgets/composites/tooltip.py +404 -0
  371. bootstack/widgets/internal/__init__.py +0 -0
  372. bootstack/widgets/internal/wrapper_base.py +304 -0
  373. bootstack/widgets/mixins/__init__.py +25 -0
  374. bootstack/widgets/mixins/configure_mixin.py +186 -0
  375. bootstack/widgets/mixins/entry_mixin.py +70 -0
  376. bootstack/widgets/mixins/font_mixin.py +346 -0
  377. bootstack/widgets/mixins/icon_mixin.py +38 -0
  378. bootstack/widgets/mixins/localization_mixin.py +255 -0
  379. bootstack/widgets/mixins/signal_mixin.py +272 -0
  380. bootstack/widgets/mixins/validation_mixin.py +204 -0
  381. bootstack/widgets/parts/__init__.py +11 -0
  382. bootstack/widgets/parts/numberentry_part.py +345 -0
  383. bootstack/widgets/parts/spinnerentry_part.py +394 -0
  384. bootstack/widgets/parts/textentry_part.py +344 -0
  385. bootstack/widgets/primitives/__init__.py +55 -0
  386. bootstack/widgets/primitives/badge.py +44 -0
  387. bootstack/widgets/primitives/button.py +89 -0
  388. bootstack/widgets/primitives/card.py +66 -0
  389. bootstack/widgets/primitives/checkbutton.py +124 -0
  390. bootstack/widgets/primitives/checktoggle.py +53 -0
  391. bootstack/widgets/primitives/combobox.py +165 -0
  392. bootstack/widgets/primitives/entry.py +98 -0
  393. bootstack/widgets/primitives/frame.py +206 -0
  394. bootstack/widgets/primitives/gridframe.py +479 -0
  395. bootstack/widgets/primitives/label.py +95 -0
  396. bootstack/widgets/primitives/labelframe.py +63 -0
  397. bootstack/widgets/primitives/menubutton.py +118 -0
  398. bootstack/widgets/primitives/notebook.py +551 -0
  399. bootstack/widgets/primitives/optionmenu.py +248 -0
  400. bootstack/widgets/primitives/packframe.py +228 -0
  401. bootstack/widgets/primitives/panedwindow.py +58 -0
  402. bootstack/widgets/primitives/progressbar.py +95 -0
  403. bootstack/widgets/primitives/radiobutton.py +115 -0
  404. bootstack/widgets/primitives/radiotoggle.py +50 -0
  405. bootstack/widgets/primitives/scale.py +85 -0
  406. bootstack/widgets/primitives/scrollbar.py +56 -0
  407. bootstack/widgets/primitives/separator.py +56 -0
  408. bootstack/widgets/primitives/sizegrip.py +47 -0
  409. bootstack/widgets/primitives/spinbox.py +91 -0
  410. bootstack/widgets/primitives/switch.py +41 -0
  411. bootstack/widgets/primitives/treeview.py +77 -0
  412. bootstack/widgets/types.py +20 -0
  413. bootstack-0.1.0a1.dist-info/METADATA +196 -0
  414. bootstack-0.1.0a1.dist-info/RECORD +419 -0
  415. bootstack-0.1.0a1.dist-info/WHEEL +5 -0
  416. bootstack-0.1.0a1.dist-info/entry_points.txt +2 -0
  417. bootstack-0.1.0a1.dist-info/licenses/LICENSE +22 -0
  418. bootstack-0.1.0a1.dist-info/licenses/NOTICE +10 -0
  419. bootstack-0.1.0a1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,391 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any, Callable, Literal, TypedDict, TYPE_CHECKING
4
+ from typing_extensions import Unpack
5
+
6
+ from bootstack.widgets.primitives.button import Button
7
+ from bootstack.widgets.mixins.configure_mixin import configure_delegate
8
+ from bootstack.widgets.primitives import Frame
9
+ from bootstack.widgets.primitives.checkbutton import CheckButton
10
+ from bootstack.widgets.primitives.checktoggle import CheckToggle
11
+ from bootstack.widgets.primitives.radiobutton import RadioButton
12
+ from bootstack.widgets.primitives.radiotoggle import RadioToggle
13
+ from bootstack.widgets.types import Master
14
+
15
+ if TYPE_CHECKING:
16
+ import tkinter as tk
17
+
18
+
19
+ class ButtonGroupKwargs(TypedDict, total=False):
20
+ orient: Literal['horizontal', 'vertical']
21
+ accent: str
22
+ variant: str
23
+ state: Literal['normal', 'disabled']
24
+ surface: str
25
+ density: Literal['default', 'compact']
26
+ style_options: dict[str, Any]
27
+ # Frame options
28
+ padding: Any
29
+ width: int
30
+ height: int
31
+
32
+
33
+ class ButtonGroup(Frame):
34
+ """A group of buttons with automatic positioning and styling.
35
+
36
+ ButtonGroup provides visual grouping of buttons (or other widgets) without
37
+ state tracking. Perfect for toolbars, action button groups, or any scenario
38
+ where you want buttons visually connected but don't need to track which is
39
+ selected.
40
+ """
41
+
42
+ def __init__(
43
+ self,
44
+ master: Master = None,
45
+ *,
46
+ orient: Literal['horizontal', 'vertical'] = 'horizontal',
47
+ accent: str = None,
48
+ variant: str = 'solid',
49
+ density: Literal['default', 'compact'] = 'default',
50
+ state: Literal['normal', 'disabled'] = 'normal',
51
+ **kwargs: Unpack[ButtonGroupKwargs]
52
+ ):
53
+ """Initialize the ButtonGroup.
54
+
55
+ Args:
56
+ master: Parent widget. If None, uses the default root window.
57
+
58
+ Other Parameters:
59
+ orient (str): Layout orientation - 'horizontal' (default) or 'vertical'.
60
+ accent (str): The accent token (e.g., 'primary', 'success', 'danger').
61
+ variant (str): The style variant (e.g., 'solid', 'outline', 'ghost'). Defaults to 'solid',
62
+ state (str): Initial state for all buttons - 'normal' (default) or 'disabled'.
63
+ surface (str): Optional surface token; otherwise inherited.
64
+ density (str): The vertical and horizontal compactness of widget content, e.g. 'default', 'compact'.
65
+ padding (int | tuple): Frame padding. Defaults to 1.
66
+ width (int): Requested width in pixels.
67
+ height (int): Requested height in pixels.
68
+ style_options (dict): Additional style options passed to child widgets.
69
+ """
70
+ # Store ButtonGroup-specific options from explicit parameters
71
+ # NOTE: _color and _variant are set AFTER super().__init__() because
72
+ # the bootstyle wrapper in TTKWrapperBase sets them to None/extracted values
73
+ self._orientation = orient
74
+ self._state = state
75
+
76
+ style_options = kwargs.pop('style_options', {})
77
+ kwargs.pop('show_border', None) # not allowed
78
+
79
+ # Initialize internal state
80
+ self._widgets: dict[str, tk.Widget] = {}
81
+ self._counter = 0 # For auto-generating keys
82
+
83
+ # Handle padding default
84
+ if 'padding' not in kwargs:
85
+ kwargs['padding'] = 1
86
+
87
+ super().__init__(master, style_options=style_options, **kwargs)
88
+
89
+ # Set accent/variant AFTER super().__init__() to override wrapper's values
90
+ self._accent = accent
91
+ self._variant = variant
92
+ self._density = density
93
+
94
+ def add(
95
+ self,
96
+ text: str = None,
97
+ *,
98
+ key: str = None,
99
+ widget_type: type = None,
100
+ command: Callable[[], Any] = None,
101
+ **kwargs: Any
102
+ ) -> 'tk.Widget':
103
+ """Add a widget to the group.
104
+
105
+ Args:
106
+ text: Text to display on the widget.
107
+ key: Unique identifier. Auto-generated if not provided.
108
+ widget_type: Widget class to instantiate (defaults to Button).
109
+ command: Callback for button press.
110
+ **kwargs: Additional arguments passed to the widget constructor.
111
+
112
+ Returns:
113
+ The created widget instance.
114
+
115
+ Raises:
116
+ ValueError: If a widget with the same key already exists.
117
+ """
118
+ # Auto-generate key if not provided
119
+ if key is None:
120
+ key = f"widget_{self._counter}"
121
+ self._counter += 1
122
+
123
+ if key in self._widgets:
124
+ raise ValueError(f"A widget with the key '{key}' already exists.")
125
+
126
+ # Default to Button if no widget type specified
127
+ if widget_type is None:
128
+ widget_type = Button
129
+ elif not callable(widget_type):
130
+ raise TypeError(f"widget_type must be a class or callable, got {type(widget_type).__name__}")
131
+
132
+ widget_kwargs = kwargs.copy()
133
+
134
+ # Apply buttongroup styling using ttk_class='ButtonGroup'
135
+ widget_kwargs.setdefault('ttk_class', 'ButtonGroup')
136
+
137
+ # Apply accent/variant for styling
138
+ if self._accent or self._variant:
139
+ # New API: use accent and variant directly
140
+ if 'accent' not in widget_kwargs:
141
+ widget_kwargs['accent'] = self._accent
142
+ if 'variant' not in widget_kwargs:
143
+ widget_kwargs['variant'] = self._variant
144
+
145
+ # force uniform density
146
+ widget_kwargs['density'] = self._density
147
+
148
+ # Apply positioning via style_options
149
+ existing_style_opts = widget_kwargs.get('style_options', {}).copy()
150
+ existing_style_opts['orient'] = self._orientation
151
+ existing_style_opts['density'] = self._density
152
+ existing_style_opts.setdefault('position', 'before')
153
+
154
+ # Set active_state for non-radio/check button types
155
+ _radio_check_types = (CheckButton, CheckToggle, RadioButton, RadioToggle)
156
+ if not (isinstance(widget_type, type) and issubclass(widget_type, _radio_check_types)):
157
+ existing_style_opts.setdefault('active_state', True)
158
+
159
+ widget_kwargs['style_options'] = existing_style_opts
160
+
161
+ # Apply state if not explicitly provided
162
+ if 'state' not in widget_kwargs:
163
+ widget_kwargs['state'] = self._state
164
+
165
+ # Build constructor arguments
166
+ ctor_args = {'text': text} if text is not None else {}
167
+ if command is not None:
168
+ ctor_args['command'] = command
169
+ ctor_args.update(widget_kwargs)
170
+
171
+ # Create the widget
172
+ widget = widget_type(self, **ctor_args)
173
+
174
+ # Pack based on orientation
175
+ if self._orientation == 'horizontal':
176
+ widget.pack(side='left')
177
+ else: # vertical
178
+ widget.pack(side='top', fill='x')
179
+
180
+ self._widgets[key] = widget
181
+ self._update_widget_positions()
182
+ return widget
183
+
184
+ def _update_widget_positions(self):
185
+ """Update widget styles based on their position in the group.
186
+
187
+ Note: Relies on dictionary insertion order (Python 3.7+) to maintain
188
+ widget order based on when they were added.
189
+ """
190
+ widget_list = list(self._widgets.values())
191
+ num_widgets = len(widget_list)
192
+
193
+ if num_widgets == 0:
194
+ return
195
+
196
+ for idx, widget in enumerate(widget_list):
197
+ if num_widgets == 1:
198
+ position = 'before'
199
+ elif idx == 0:
200
+ position = 'before'
201
+ elif idx == num_widgets - 1:
202
+ position = 'after'
203
+ else:
204
+ position = 'center'
205
+
206
+ # Update position if widget supports configure_style_options
207
+ if hasattr(widget, 'configure_style_options'):
208
+ current_position = widget.configure_style_options('position')
209
+ if current_position != position:
210
+ widget.configure_style_options(position=position)
211
+ # Rebuild style with new position
212
+ if hasattr(widget, 'rebuild_style'):
213
+ widget.rebuild_style()
214
+
215
+ def remove(self, key: str):
216
+ """Remove a widget by its key.
217
+
218
+ Args:
219
+ key: The key of the widget to remove.
220
+
221
+ Raises:
222
+ KeyError: If no widget with the given key exists.
223
+ """
224
+ if key not in self._widgets:
225
+ raise KeyError(f"No widget with key '{key}'")
226
+ widget = self._widgets.pop(key)
227
+ widget.destroy()
228
+ self._update_widget_positions()
229
+
230
+ def item(self, key: str) -> 'tk.Widget':
231
+ """Get a widget by its key.
232
+
233
+ Args:
234
+ key: The key of the widget to retrieve.
235
+
236
+ Returns:
237
+ The widget instance.
238
+
239
+ Raises:
240
+ KeyError: If no widget with the given key exists.
241
+ """
242
+ if key not in self._widgets:
243
+ raise KeyError(f"No widget with key '{key}'")
244
+ return self._widgets[key]
245
+
246
+ def configure_item(self, key: str, option: str = None, **kwargs: Any):
247
+ """Configure a specific widget by its key.
248
+
249
+ Args:
250
+ key: The key of the widget to configure.
251
+ option: If provided, return the value of this option.
252
+ **kwargs: Configuration options to apply to the widget.
253
+
254
+ Returns:
255
+ If option is provided, returns the value of that option.
256
+
257
+ Examples:
258
+ group.configure_item("save_btn", state='disabled')
259
+ current_state = group.configure_item("save_btn", 'state')
260
+ """
261
+ widget = self.item(key)
262
+ if option is not None:
263
+ return widget.cget(option)
264
+ widget.configure(**kwargs)
265
+
266
+ def items(self) -> tuple['tk.Widget', ...]:
267
+ """Get all widgets in the group.
268
+
269
+ Returns:
270
+ A tuple of all widget instances in the group.
271
+ """
272
+ return tuple(self._widgets.values())
273
+
274
+ def keys(self) -> tuple[str, ...]:
275
+ """Get all widget keys.
276
+
277
+ Returns:
278
+ A tuple of all widget keys in the group.
279
+ """
280
+ return tuple(self._widgets.keys())
281
+
282
+ def __len__(self) -> int:
283
+ """Return the number of widgets in the group.
284
+
285
+ Examples:
286
+ >>> count = len(button_group)
287
+ """
288
+ return len(self._widgets)
289
+
290
+ def __contains__(self, key: str) -> bool:
291
+ """Check if a widget with the given key exists in the group.
292
+
293
+ Examples:
294
+ >>> if 'save' in button_group:
295
+ ... print('Save button exists')
296
+ """
297
+ return key in self._widgets
298
+
299
+ def __iter__(self):
300
+ """Iterate over the widgets in the group.
301
+
302
+ Examples:
303
+ >>> for widget in button_group:
304
+ ... widget.configure(state='disabled')
305
+ """
306
+ return iter(self._widgets.values())
307
+
308
+ @configure_delegate('accent')
309
+ def _delegate_accent(self, value=None):
310
+ """Get or set the accent. Updates all widgets when changed."""
311
+ if value is None:
312
+ return self._accent
313
+
314
+ self._accent = value
315
+ self._reconfigure_all_widgets()
316
+
317
+ @configure_delegate('density')
318
+ def _delegate_density(self, value=None):
319
+ """Get or set the density. Updates all widgets when changed."""
320
+ if value is None:
321
+ return self._density
322
+
323
+ self._density = value
324
+ self._reconfigure_all_widgets()
325
+
326
+ @configure_delegate('variant')
327
+ def _delegate_variant(self, value=None):
328
+ """Get or set the variant. Updates all widgets when changed."""
329
+ if value is None:
330
+ return self._variant
331
+
332
+ self._variant = value
333
+ self._reconfigure_all_widgets()
334
+
335
+ def _reconfigure_all_widgets(self):
336
+ """Reconfigure all widgets with current accent/variant/density"""
337
+ for widget in self._widgets.values():
338
+ # Update density in style_options
339
+ if hasattr(widget, 'configure_style_options'):
340
+ widget.configure_style_options(density=self._density)
341
+ if hasattr(widget, 'configure'):
342
+ if self._accent or self._variant:
343
+ widget.configure(accent=self._accent, variant=self._variant)
344
+ if hasattr(widget, 'rebuild_style'):
345
+ widget.rebuild_style()
346
+ self._update_widget_positions()
347
+
348
+ @configure_delegate('orient')
349
+ def _delegate_orient(self, value=None):
350
+ """Get or set orientation ('horizontal' or 'vertical'). Repacks widgets when changed."""
351
+ if value is None:
352
+ return self._orientation
353
+
354
+ if value not in ('horizontal', 'vertical'):
355
+ raise ValueError("orient must be 'horizontal' or 'vertical'")
356
+
357
+ self._orientation = value
358
+
359
+ # Repack all widgets
360
+ for widget in self._widgets.values():
361
+ widget.pack_forget()
362
+ if hasattr(widget, 'configure_style_options'):
363
+ widget.configure_style_options(orient=value)
364
+ # Rebuild style with new orientation
365
+ if hasattr(widget, 'rebuild_style'):
366
+ widget.rebuild_style()
367
+
368
+ if self._orientation == 'horizontal':
369
+ widget.pack(side='left')
370
+ else:
371
+ widget.pack(side='top', fill='x')
372
+
373
+ self._update_widget_positions()
374
+
375
+ @configure_delegate('state')
376
+ def _delegate_state(self, value=None):
377
+ """Get or set state for all widgets ('normal' or 'disabled')."""
378
+ if value is None:
379
+ return self._state
380
+
381
+ if value not in ('normal', 'disabled'):
382
+ raise ValueError("state must be 'normal' or 'disabled'")
383
+
384
+ self._state = value
385
+ # Update all widgets with new state
386
+ for widget in self._widgets.values():
387
+ try:
388
+ widget.configure(state=value)
389
+ except (AttributeError, TypeError):
390
+ # Widget doesn't support state configuration
391
+ pass