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,434 @@
1
+ from tkinter import Canvas, Event, IntVar, StringVar
2
+ from typing import Any, Optional, Union
3
+
4
+ from bootstack.widgets.mixins.configure_mixin import ConfigureDelegationMixin, configure_delegate
5
+ from bootstack.widgets.types import Master
6
+
7
+
8
+ class FloodGauge(ConfigureDelegationMixin, Canvas):
9
+ """A canvas-based progress widget with determinate and indeterminate modes.
10
+
11
+ Provides an enhanced alternative to ttk.Progressbar with full styling control,
12
+ horizontal/vertical orientations, customizable text overlays with format masks,
13
+ and bounce-style animation for indeterminate mode.
14
+
15
+ Attributes:
16
+ variable (IntVar): Tkinter IntVar for value binding.
17
+ textvariable (StringVar): Tkinter StringVar for text binding.
18
+ """
19
+
20
+ def __init__(
21
+ self,
22
+ master: Master = None,
23
+ value: int = 0,
24
+ maximum: int = 100,
25
+ mode: str = "determinate",
26
+ mask: Optional[str] = None,
27
+ text: str = "",
28
+ font: Union[tuple[str, int], str] = ("Helvetica", 12),
29
+ accent: str = None,
30
+ orient: str = "horizontal",
31
+ length: int = 200,
32
+ thickness: int = 50,
33
+ increment: int = 1,
34
+ **kwargs: Any
35
+ ) -> None:
36
+ """Initialize a FloodGauge widget.
37
+
38
+ Args:
39
+ master: Parent widget. If None, uses the default root window.
40
+ value (int): Initial progress value (0-maximum).
41
+ maximum (int): Maximum value for determinate range.
42
+ mode (str): Progress mode - `'determinate'` for known progress or
43
+ `'indeterminate'` for unknown duration.
44
+ mask (str): Format string for text overlay with `'{}'` placeholder for
45
+ the value. Examples: `'{}% Complete'` or `'Progress: {}/100'`.
46
+ If None, no automatic text formatting is applied.
47
+ text (str): Static text label shown when no mask is specified.
48
+ font (tuple | str): Font specification as tuple `(family, size)` or
49
+ string like `'Arial 12 bold'`.
50
+ accent (str): Accent token from bootstack (e.g., `'primary'`,
51
+ `'success'`, `'info'`, `'warning'`, `'danger'`).
52
+ orient (str): Widget orientation - `'horizontal'` or `'vertical'`.
53
+ length (int): Size in pixels along the main axis (width if horizontal,
54
+ height if vertical).
55
+ thickness (int): Size in pixels along the minor axis (height if horizontal,
56
+ width if vertical).
57
+ increment (int): Step size for value changes when using `step()` method
58
+ or during animations.
59
+
60
+ Other Parameters:
61
+ variable (IntVar): Tkinter IntVar for value binding.
62
+ textvariable (StringVar): Tkinter StringVar for text binding.
63
+
64
+ Note:
65
+ The widget automatically updates colors when the theme changes via the
66
+ `<<ThemeChanged>>` event. When using variable or textvariable bindings,
67
+ the widget redraws automatically when the variables change.
68
+ """
69
+
70
+ # Handle deprecated bootstyle parameter
71
+ bootstyle = kwargs.pop("bootstyle", None)
72
+
73
+ self._variable = kwargs.pop("variable", IntVar(value=value))
74
+ self._value = self._variable.get()
75
+
76
+ self._textvariable = kwargs.pop("textvariable", StringVar(value=text))
77
+ self._text = self._textvariable.get()
78
+
79
+ self._mode = mode
80
+ self._mask = mask
81
+ self._font = font
82
+ self._accent = accent or bootstyle or "primary"
83
+ self._orient = orient
84
+ self._length = length
85
+ self._thickness = thickness
86
+ self._maximum = maximum
87
+ self._increment = increment
88
+
89
+ self._running = False
90
+ self._after_id = None
91
+ self._pulse_pos = 0
92
+ self._pulse_direction = 1
93
+
94
+ canvas_kwargs = dict(highlightthickness=0, **kwargs)
95
+ if self._orient == "horizontal":
96
+ canvas_kwargs.update(width=self._length, height=self._thickness)
97
+ else:
98
+ canvas_kwargs.update(width=self._thickness, height=self._length)
99
+
100
+ super().__init__(master, **canvas_kwargs)
101
+
102
+ self._variable_trace_id = self._variable.trace_add("write", lambda n, i, m: self._on_var_change())
103
+ self._textvariable_trace_id = self._textvariable.trace_add("write", lambda n, i, m: self._on_text_change())
104
+
105
+ self._update_theme_colors()
106
+
107
+ self.bind("<Configure>", self._on_resize)
108
+
109
+ # Bind to root to receive theme change events
110
+ root = self.nametowidget('.')
111
+ root.bind('<<ThemeChanged>>', lambda e: self._update_theme_colors(), add='+')
112
+
113
+ self._draw()
114
+
115
+ def destroy(self) -> None:
116
+ """Clean up resources before destroying the widget."""
117
+ self.stop()
118
+
119
+ # Remove traces to prevent memory leaks
120
+ if hasattr(self, '_variable') and hasattr(self, '_variable_trace_id'):
121
+ try:
122
+ self._variable.trace_remove('write', self._variable_trace_id)
123
+ except Exception:
124
+ pass
125
+
126
+ if hasattr(self, '_textvariable') and hasattr(self, '_textvariable_trace_id'):
127
+ try:
128
+ self._textvariable.trace_remove('write', self._textvariable_trace_id)
129
+ except Exception:
130
+ pass
131
+
132
+ super().destroy()
133
+
134
+ # ----- Configuration Delegates ------
135
+
136
+ @configure_delegate('mode')
137
+ def _delegate_mode(self, value=None):
138
+ if value is None:
139
+ return self._mode
140
+ self._mode = value
141
+ self._draw()
142
+
143
+ @configure_delegate('mask')
144
+ def _delegate_mask(self, value=None):
145
+ if value is None:
146
+ return self._mask
147
+ self._mask = value
148
+ self._draw()
149
+
150
+ @configure_delegate('font')
151
+ def _delegate_font(self, value=None):
152
+ if value is None:
153
+ return self._font
154
+ self._font = value
155
+ self._draw()
156
+
157
+ @configure_delegate('bootstyle')
158
+ def _delegate_bootstyle(self, value=None):
159
+ if value is None:
160
+ return self._accent
161
+ self._accent = value
162
+ self._update_theme_colors() # calls _draw()
163
+
164
+ @configure_delegate('accent')
165
+ def _delegate_accent(self, value=None):
166
+ if value is None:
167
+ return self._accent
168
+ self._accent = value
169
+ self._update_theme_colors() # calls _draw()
170
+
171
+ @configure_delegate('orient')
172
+ def _delegate_orient(self, value=None):
173
+ if value is None:
174
+ return self._orient
175
+ self._orient = value
176
+ self._draw()
177
+
178
+ @configure_delegate('length')
179
+ def _delegate_length(self, value=None):
180
+ if value is None:
181
+ return self._length
182
+ self._length = value
183
+ if self._orient == "horizontal":
184
+ self.configure(width=self._length)
185
+ else:
186
+ self.configure(height=self._length)
187
+ self._draw()
188
+
189
+ @configure_delegate('thickness')
190
+ def _delegate_thickness(self, value=None):
191
+ if value is None:
192
+ return self._thickness
193
+ self._thickness = value
194
+ if self._orient == "horizontal":
195
+ self.configure(height=self._thickness)
196
+ else:
197
+ self.configure(width=self._thickness)
198
+ self._draw()
199
+
200
+ @configure_delegate('maximum')
201
+ def _delegate_maximum(self, value=None):
202
+ if value is None:
203
+ return self._maximum
204
+ self._maximum = value
205
+ self._draw()
206
+
207
+ @configure_delegate('increment')
208
+ def _delegate_increment(self, value=None):
209
+ if value is None:
210
+ return self._increment
211
+ self._increment = value
212
+ self._draw()
213
+
214
+ @configure_delegate('value')
215
+ def _delegate_value(self, value=None):
216
+ if value is None:
217
+ return self._value
218
+ # Variable trace triggers redraw
219
+ self._variable.set(value)
220
+
221
+ def get(self) -> int:
222
+ """Return the current progress value."""
223
+ return self._value
224
+
225
+ def set(self, value: int) -> None:
226
+ """Set the progress value.
227
+
228
+ Args:
229
+ value: The new progress value.
230
+ """
231
+ self._variable.set(value)
232
+
233
+ @property
234
+ def value(self) -> int:
235
+ """Get or set the progress value."""
236
+ return self.get()
237
+
238
+ @value.setter
239
+ def value(self, value: int) -> None:
240
+ self.set(value)
241
+
242
+ @configure_delegate('text')
243
+ def _delegate_text(self, value=None):
244
+ if value is None:
245
+ return self._text
246
+ # Textvariable trace triggers redraw
247
+ self._textvariable.set(value)
248
+
249
+ @configure_delegate('variable')
250
+ def _delegate_variable(self, value=None):
251
+ if value is None:
252
+ return self._variable
253
+ self._variable.trace_remove('write', self._variable_trace_id)
254
+ self._variable = value
255
+ self._variable_trace_id = self._variable.trace_add("write", lambda n, i, m: self._on_var_change())
256
+ self._value = self._variable.get()
257
+ self._draw()
258
+
259
+ @configure_delegate('textvariable')
260
+ def _delegate_textvariable(self, value=None):
261
+ if value is None:
262
+ return self._textvariable
263
+ self._textvariable.trace_remove('write', self._textvariable_trace_id)
264
+ self._textvariable = value
265
+ self._textvariable_trace_id = self._textvariable.trace_add("write", lambda n, i, m: self._on_text_change())
266
+ self._text = self._textvariable.get()
267
+ self._draw()
268
+
269
+ def _update_theme_colors(self) -> None:
270
+ """Update widget colors based on current theme and bootstyle."""
271
+ from bootstack.style.style import get_style
272
+ style = get_style()
273
+ b = style.style_builder
274
+ surface = b.color('background')
275
+ self._bar_color = b.color(self._accent)
276
+ self._trough_color = b.border(b.subtle(self._accent, surface))
277
+ self._text_color = b.on_color(self._bar_color)
278
+ self._draw()
279
+
280
+ def _on_resize(self, event: Event) -> None:
281
+ """Handle widget resize events and update dimensions."""
282
+ if self._orient == "horizontal":
283
+ self._length = event.width
284
+ self._thickness = event.height
285
+ else:
286
+ self._length = event.height
287
+ self._thickness = event.width
288
+ self._draw()
289
+
290
+ def _draw(self) -> None:
291
+ """Render the progress bar and text overlay on the canvas."""
292
+ self.delete("all")
293
+ # Fallback to configured dimensions if widget not yet mapped
294
+ w = self.winfo_width() or (self._length if self._orient == "horizontal" else self._thickness)
295
+ h = self.winfo_height() or (self._thickness if self._orient == "horizontal" else self._length)
296
+
297
+ self.create_rectangle(0, 0, w, h, fill=self._trough_color, width=0)
298
+
299
+ if self._mode == "determinate":
300
+ ratio = max(0.0, min(1.0, self._value / self._maximum)) if self._maximum > 0 else 0.0
301
+ if self._orient == "horizontal":
302
+ fill = int(ratio * w)
303
+ self.create_rectangle(0, 0, fill, h, fill=self._bar_color, width=0)
304
+ else:
305
+ fill = int(ratio * h)
306
+ self.create_rectangle(0, h - fill, w, h, fill=self._bar_color, width=0)
307
+ else:
308
+ if self._orient == "horizontal":
309
+ pulse_width = max(10, int(w * 0.2))
310
+ x = self._pulse_pos
311
+ self.create_rectangle(x, 0, x + pulse_width, h, fill=self._bar_color, width=0)
312
+ else:
313
+ pulse_height = max(10, int(h * 0.2))
314
+ y = self._pulse_pos
315
+ self.create_rectangle(0, y - pulse_height, w, y, fill=self._bar_color, width=0)
316
+
317
+ if self._mask:
318
+ try:
319
+ label = self._mask.format(int(self._value))
320
+ except (ValueError, KeyError, IndexError):
321
+ label = str(int(self._value))
322
+ # Remove trace to avoid recursive redraw
323
+ self._textvariable.trace_remove('write', self._textvariable_trace_id)
324
+ self._textvariable.set(label)
325
+ self._textvariable_trace_id = self._textvariable.trace_add("write", lambda n, i, m: self._on_text_change())
326
+ elif self._textvariable:
327
+ label = self._textvariable.get()
328
+ else:
329
+ label = self._text
330
+
331
+ if label:
332
+ self.create_text(
333
+ w // 2,
334
+ h // 2,
335
+ text=label,
336
+ font=self._font,
337
+ fill=self._text_color,
338
+ anchor="center"
339
+ )
340
+
341
+ def _on_var_change(self) -> None:
342
+ """Handle changes to the value variable."""
343
+ self._value = self._variable.get()
344
+ self._draw()
345
+
346
+ def _on_text_change(self) -> None:
347
+ """Handle changes to the text variable."""
348
+ self._text = self._textvariable.get()
349
+ self._draw()
350
+
351
+ def step(self, amount: int = 1) -> None:
352
+ """Increment the progress value by the specified amount.
353
+
354
+ Args:
355
+ amount (int): Amount to increment. Value wraps around after reaching
356
+ maximum.
357
+ """
358
+ self._value = (self._value + amount) % (self._maximum + 1)
359
+ self._variable.set(self._value)
360
+ self._draw()
361
+
362
+ def start(self, step_size: Optional[int] = None, interval: Optional[int] = None) -> None:
363
+ """Start the progress animation.
364
+
365
+ For indeterminate mode, starts bouncing animation. For determinate mode,
366
+ auto-increments the value at regular intervals.
367
+
368
+ Args:
369
+ step_size (int): Amount to increment per animation step. Defaults to 8
370
+ for indeterminate mode, 1 for determinate mode.
371
+ interval (int): Time in milliseconds between animation steps. Defaults
372
+ to 20ms for indeterminate mode, 50ms for determinate mode.
373
+ """
374
+ if self._mode == "indeterminate":
375
+ self._increment = step_size if step_size is not None else 8
376
+ interval = interval if interval is not None else 20
377
+ else:
378
+ self._increment = step_size if step_size is not None else 1
379
+ interval = interval if interval is not None else 50
380
+
381
+ self._running = True
382
+ self._pulse_pos = 0 # Reset position
383
+ self._pulse_direction = 1
384
+ self._run_animation(interval)
385
+
386
+ def stop(self) -> None:
387
+ """Stop the progress animation and cancel any scheduled updates."""
388
+ self._running = False
389
+ if self._after_id:
390
+ self.after_cancel(self._after_id)
391
+ self._after_id = None
392
+
393
+ def _run_animation(self, interval: int) -> None:
394
+ """Execute one animation frame and schedule the next."""
395
+ if not self._running:
396
+ return
397
+
398
+ if self._mode == "indeterminate":
399
+ self._animate_indeterminate(interval)
400
+ else:
401
+ self.step(self._increment)
402
+ self._after_id = self.after(interval, lambda: self._run_animation(interval))
403
+
404
+ def _animate_indeterminate(self, interval: int) -> None:
405
+ """Animate the bouncing pulse for indeterminate mode."""
406
+ if not self._running:
407
+ return
408
+
409
+ if self._orient == "horizontal":
410
+ w = self.winfo_width()
411
+ pulse_width = max(10, int(w * 0.2))
412
+ max_pos = w - pulse_width
413
+ self._pulse_pos += self._increment * self._pulse_direction
414
+ if self._pulse_pos >= max_pos:
415
+ self._pulse_pos = max_pos
416
+ self._pulse_direction = -1
417
+ elif self._pulse_pos <= 0:
418
+ self._pulse_pos = 0
419
+ self._pulse_direction = 1
420
+ else:
421
+ h = self.winfo_height()
422
+ pulse_height = max(10, int(h * 0.2))
423
+ max_pos = h
424
+ self._pulse_pos += self._increment * self._pulse_direction
425
+ if self._pulse_pos >= max_pos:
426
+ self._pulse_pos = max_pos
427
+ self._pulse_direction = -1
428
+ elif self._pulse_pos <= pulse_height:
429
+ self._pulse_pos = pulse_height
430
+ self._pulse_direction = 1
431
+
432
+ self._draw()
433
+ self._after_id = self.after(interval, lambda: self._animate_indeterminate(interval))
434
+