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,399 @@
1
+ """Enhanced event system for bootstack.
2
+
3
+ This module patches the standard tkinter event system to enable passing custom
4
+ data with virtual events. This provides a more powerful and flexible event
5
+ handling mechanism than the default tkinter implementation.
6
+
7
+ Features:
8
+ - Pass custom Python objects as data with virtual events
9
+ - Automatic memory management with LRU cache to prevent leaks
10
+ - Consistent Event objects for both regular and virtual events
11
+ - All standard event attributes preserved (x, y, widget, etc.)
12
+ - Backwards compatible with existing tkinter code
13
+
14
+ Examples:
15
+ ```python
16
+ import tkinter as tk
17
+ import bootstack as bs
18
+
19
+ root = bs.Window()
20
+
21
+ def handler(event):
22
+ print(f"Received: {event.data}")
23
+
24
+ root.bind('<<CustomEvent>>', handler)
25
+ root.event_generate('<<CustomEvent>>', data={'key': 'value', 'items': [1, 2, 3]})
26
+
27
+ root.mainloop()
28
+ ```
29
+
30
+ Note:
31
+ This module automatically patches tkinter when imported. The patches are
32
+ applied globally and affect all tkinter widgets in the application.
33
+ """
34
+
35
+ import tkinter as tk
36
+ import uuid
37
+ import weakref
38
+ from collections import OrderedDict
39
+ from typing import Any, Callable, Optional, Union
40
+
41
+
42
+ # Global storage for event data with LRU cache behavior
43
+ _event_data_cache: OrderedDict[str, Any] = OrderedDict()
44
+ _MAX_CACHE_SIZE = 100 # Prevent unbounded growth
45
+
46
+ # Store original tkinter methods before patching
47
+ _original_event_generate: Callable = tk.Misc.event_generate
48
+ _original_bind: Callable = tk.Misc.bind
49
+
50
+
51
+ def _patched_event_generate(
52
+ self: tk.Misc,
53
+ sequence: str,
54
+ data: Optional[Any] = None,
55
+ **kw
56
+ ) -> None:
57
+ """Enhanced event_generate that supports custom data parameter.
58
+
59
+ This patched version of tkinter's event_generate method allows passing
60
+ arbitrary Python objects as event data. The data is stored in a cache
61
+ with a unique identifier that is passed through the event system.
62
+
63
+ Args:
64
+ self: The widget instance (automatically provided)
65
+ sequence: Virtual event name (e.g., '<<MyEvent>>')
66
+ data: Optional custom data to attach to the event. Can be any Python object.
67
+ **kw: Additional keyword arguments passed to the original event_generate
68
+
69
+ Examples:
70
+ ```python
71
+ widget.event_generate('<<Save>>', data={'filename': 'doc.txt', 'author': 'John'})
72
+ ```
73
+
74
+ Note:
75
+ The cache uses LRU eviction to prevent memory leaks. Old entries are
76
+ automatically removed when the cache exceeds _MAX_CACHE_SIZE.
77
+ """
78
+ if data is not None:
79
+ # Generate unique identifier for this data
80
+ guid = str(uuid.uuid4())
81
+ _event_data_cache[guid] = data
82
+
83
+ # Limit cache size using LRU eviction
84
+ if len(_event_data_cache) > _MAX_CACHE_SIZE:
85
+ # Remove oldest entry (FIFO from OrderedDict)
86
+ _event_data_cache.popitem(last=False)
87
+
88
+ # Pass GUID through tkinter's event system
89
+ kw['data'] = guid
90
+
91
+ return _original_event_generate(self, sequence, **kw)
92
+
93
+
94
+ def _patched_bind(
95
+ self: tk.Misc,
96
+ sequence: Optional[str] = None,
97
+ func: Optional[Callable] = None,
98
+ add: Optional[Union[bool, str]] = None
99
+ ) -> Optional[str]:
100
+ """Enhanced bind that supports data attribute on all events.
101
+
102
+ This patched version of tkinter's bind method ensures that:
103
+ 1. Virtual events (<<EventName>>) receive custom data if provided
104
+ 2. All event objects have a 'data' attribute (None for regular events)
105
+ 3. Virtual events get properly formatted Event objects with __str__
106
+
107
+ Args:
108
+ self: The widget instance (automatically provided)
109
+ sequence: Event sequence (e.g., '<Button-1>', '<<MyEvent>>')
110
+ func: Callback function to handle the event
111
+ add: If True/'+', add binding without removing existing ones
112
+
113
+ Returns:
114
+ Tkinter function name string if binding was created, None otherwise
115
+
116
+ Examples:
117
+ ```python
118
+ def handler(event):
119
+ print(f"Event: {event}, Data: {event.data}")
120
+
121
+ widget.bind('<<CustomEvent>>', handler)
122
+ ```
123
+ """
124
+ if func is not None and sequence is not None:
125
+ is_virtual = sequence and sequence.startswith('<<')
126
+
127
+ if is_virtual:
128
+ # Create wrapper for virtual events to handle data retrieval
129
+ widget_ref = weakref.ref(self) # Avoid circular references
130
+
131
+ def wrapper(
132
+ data_guid, serial, num, height, width, keycode, state, time,
133
+ x, y, x_root, y_root, char, keysym, keysym_num, event_type,
134
+ send_event, delta
135
+ ):
136
+ """Internal wrapper that constructs Event objects for virtual events.
137
+
138
+ This function is called by tkinter's event system with all the
139
+ standard event substitution values plus our custom data GUID.
140
+ """
141
+
142
+ class VirtualEvent:
143
+ """Event object for virtual events with enhanced functionality.
144
+
145
+ This class mimics tkinter's Event class but adds:
146
+ - Custom data attribute from event_generate
147
+ - Proper __str__ representation showing event details
148
+ - All standard tkinter event attributes
149
+ """
150
+
151
+ def __init__(self, widget: tk.Misc) -> None:
152
+ """Initialize event with standard tkinter attributes.
153
+
154
+ Args:
155
+ widget: The widget that received the event
156
+ """
157
+ self.serial = serial
158
+ self.num = num
159
+ self.height = height
160
+ self.width = width
161
+ self.keycode = keycode
162
+ self.state = state
163
+ self.time = time
164
+ self.x = x
165
+ self.y = y
166
+ self.x_root = x_root
167
+ self.y_root = y_root
168
+ self.char = char
169
+ self.keysym = keysym
170
+ self.keysym_num = keysym_num
171
+ self.type = event_type
172
+ self.send_event = send_event
173
+ self.delta = delta
174
+ self.widget = widget
175
+ self.data: Optional[Any] = None
176
+
177
+ def __str__(self) -> str:
178
+ """Return human-readable event representation.
179
+
180
+ Returns:
181
+ Formatted string like: <VirtualEvent type=MyEvent x=10 y=20 data={'key': 'value'}>
182
+ """
183
+ # Extract event name from sequence (remove << and >>)
184
+ event_name = sequence.strip('<').strip('>')
185
+ parts = [f"type={event_name}"]
186
+
187
+ # Add position if available
188
+ if self.x is not None and self.x != '??':
189
+ parts.append(f"x={self.x}")
190
+ if self.y is not None and self.y != '??':
191
+ parts.append(f"y={self.y}")
192
+
193
+ # Add data if present (truncate if too long)
194
+ if self.data is not None:
195
+ data_repr = repr(self.data)
196
+ max_length = 50
197
+ if len(data_repr) > max_length:
198
+ parts.append(f"data={data_repr[:max_length]}...")
199
+ else:
200
+ parts.append(f"data={data_repr}")
201
+
202
+ return f"<VirtualEvent {' '.join(parts)}>"
203
+
204
+ def __repr__(self) -> str:
205
+ """Return repr string (same as __str__)."""
206
+ return self.__str__()
207
+
208
+ # Retrieve widget from weakref
209
+ widget = widget_ref()
210
+ if widget is None:
211
+ # Widget was destroyed, clean up cache entry if present
212
+ if data_guid and data_guid in _event_data_cache:
213
+ _event_data_cache.pop(data_guid)
214
+ return
215
+
216
+ # Create event object
217
+ event = VirtualEvent(widget)
218
+
219
+ # Attach custom data (don't pop yet - multiple handlers may need it)
220
+ if data_guid and data_guid in _event_data_cache:
221
+ event.data = _event_data_cache[data_guid]
222
+ # Schedule cleanup after all handlers have run
223
+ widget.after_idle(lambda: _event_data_cache.pop(data_guid, None))
224
+ else:
225
+ # Data might have been evicted from cache already
226
+ event.data = None
227
+
228
+ return func(event)
229
+
230
+ # Register wrapper function with tkinter
231
+ name = self._register(wrapper)
232
+
233
+ # Build command with all substitutions including %d for data GUID
234
+ # Substitution codes: https://tcl.tk/man/tcl8.6/TkCmd/bind.htm
235
+ cmd = f'{name} %d %# %b %h %w %k %s %t %x %y %X %Y %A %K %N %T %E %D'
236
+
237
+ # Bind to widget
238
+ self.tk.call('bind', self._w, sequence, cmd if not add else '+' + cmd)
239
+
240
+ return name
241
+ else:
242
+ # For regular events, wrap to add data=None attribute
243
+ def regular_wrapper(event):
244
+ """Wrapper for regular events to add consistent data attribute."""
245
+ if not hasattr(event, 'data'):
246
+ event.data = None
247
+ return func(event)
248
+
249
+ return _original_bind(self, sequence, regular_wrapper, add)
250
+
251
+ # No function or sequence provided, pass through to original
252
+ return _original_bind(self, sequence, func, add)
253
+
254
+
255
+ def cleanup_event_cache() -> None:
256
+ """Manually clear the entire event data cache.
257
+
258
+ This function removes all cached event data. It's useful for:
259
+ - Forcing memory cleanup in long-running applications
260
+ - Resetting state during testing
261
+ - Manual intervention when cache grows unexpectedly
262
+
263
+ Note:
264
+ Normally cache cleanup is automatic via LRU eviction. Manual cleanup
265
+ should rarely be needed in production code.
266
+
267
+ Examples:
268
+ ```python
269
+ from bootstack.events import cleanup_event_cache
270
+
271
+ # After processing many events
272
+ cleanup_event_cache()
273
+ ```
274
+ """
275
+ _event_data_cache.clear()
276
+
277
+
278
+ def enable_periodic_cache_cleanup(
279
+ root: tk.Misc,
280
+ interval: int = 60000,
281
+ threshold: int = 10
282
+ ) -> None:
283
+ """Enable automatic periodic cleanup of the event cache.
284
+
285
+ This function sets up a recurring timer that checks the cache size
286
+ and performs cleanup when it exceeds a threshold. This helps prevent
287
+ cache growth in long-running applications that generate many events.
288
+
289
+ Args:
290
+ root: Root window or any widget (needed for .after() scheduling)
291
+ interval: Cleanup check interval in milliseconds (default: 60000 = 1 minute)
292
+ threshold: Only clean if cache has more than this many entries (default: 10)
293
+
294
+ Examples:
295
+ ```python
296
+ import bootstack as bs
297
+ from bootstack.events import enable_periodic_cache_cleanup
298
+
299
+ root = bs.Window()
300
+ enable_periodic_cache_cleanup(root, interval=30000) # Check every 30 seconds
301
+ root.mainloop()
302
+ ```
303
+
304
+ Note:
305
+ This is optional. The LRU cache already prevents unbounded growth.
306
+ Periodic cleanup is only needed for applications that generate
307
+ thousands of events and want more aggressive memory management.
308
+ """
309
+ def cleanup_task():
310
+ """Internal task that performs conditional cache cleanup."""
311
+ if len(_event_data_cache) > threshold:
312
+ # Remove half of the oldest entries
313
+ to_remove = list(_event_data_cache.keys())[:len(_event_data_cache) // 2]
314
+ for key in to_remove:
315
+ _event_data_cache.pop(key, None)
316
+
317
+ # Schedule next cleanup
318
+ root.after(interval, cleanup_task)
319
+
320
+ # Start the cleanup cycle
321
+ cleanup_task()
322
+
323
+
324
+ def get_cache_size() -> int:
325
+ """Get the current number of entries in the event data cache.
326
+
327
+ This is primarily useful for debugging and monitoring cache behavior.
328
+
329
+ Returns:
330
+ Number of cached event data objects
331
+
332
+ Examples:
333
+ ```python
334
+ from bootstack.events import get_cache_size
335
+
336
+ print(f"Current cache size: {get_cache_size()}")
337
+ ```
338
+ """
339
+ return len(_event_data_cache)
340
+
341
+
342
+ def install_enhanced_events() -> None:
343
+ """Install the enhanced event system by patching tkinter methods.
344
+
345
+ This function applies monkey patches to tkinter's Misc class,
346
+ replacing event_generate and bind with enhanced versions that
347
+ support passing custom data through virtual events.
348
+
349
+ The patches are applied globally and affect all tkinter widgets
350
+ in the application. This function is called automatically when
351
+ bootstack is imported.
352
+
353
+ Note:
354
+ You should not need to call this manually unless you've explicitly
355
+ uninstalled the patches and need to reinstall them.
356
+
357
+ Examples:
358
+ ```python
359
+ from bootstack.events import install_enhanced_events
360
+
361
+ # Reinstall if needed
362
+ install_enhanced_events()
363
+ ```
364
+ """
365
+ tk.Misc.event_generate = _patched_event_generate
366
+ tk.Misc.bind = _patched_bind
367
+
368
+
369
+ def uninstall_enhanced_events() -> None:
370
+ """Restore original tkinter event methods.
371
+
372
+ This function removes the patches and restores tkinter to its
373
+ original behavior. Useful for testing or if conflicts arise.
374
+
375
+ Warning:
376
+ After calling this, event_generate will no longer accept
377
+ the 'data' parameter, and existing bindings may not work
378
+ as expected.
379
+
380
+ Examples:
381
+ ```python
382
+ from bootstack.events import uninstall_enhanced_events
383
+
384
+ # Restore original tkinter behavior
385
+ uninstall_enhanced_events()
386
+ ```
387
+ """
388
+ tk.Misc.event_generate = _original_event_generate
389
+ tk.Misc.bind = _original_bind
390
+ cleanup_event_cache()
391
+
392
+
393
+ __all__ = [
394
+ 'cleanup_event_cache',
395
+ 'enable_periodic_cache_cleanup',
396
+ 'get_cache_size',
397
+ 'install_enhanced_events',
398
+ 'uninstall_enhanced_events',
399
+ ]