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,507 @@
1
+ """Bootstyle parsing and widget integration for bootstack.
2
+
3
+ Handles parsing of bootstyle strings and provides integration layer between
4
+ user-friendly bootstyle syntax and TTK style names.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from typing import Optional
10
+
11
+ from bootstack.runtime.app import get_app_settings
12
+ from bootstack.core.exceptions import BootstyleParsingError
13
+ from bootstack.style.token_maps import (COLOR_TOKENS, CONTAINER_CLASSES, ORIENT_CLASSES, WIDGET_CLASS_MAP)
14
+
15
+
16
+
17
+ def parse_bootstyle_v2(bootstyle: str, widget_class: str) -> dict:
18
+ """Parse bootstyle string using V2 syntax (dash-separated).
19
+
20
+ Syntax: `accent-variant-widget` where all parts are optional.
21
+ Checks actual theme colors and registered variants. Unknown parts are
22
+ treated as custom colors.
23
+
24
+ Args:
25
+ bootstyle: Bootstyle string (e.g., "success-outline", "primary")
26
+ widget_class: TTK widget class name (e.g., "TButton")
27
+
28
+ Returns:
29
+ Dict with: accent, variant, widget_class, cross_widget
30
+ """
31
+ if not bootstyle:
32
+ return {
33
+ 'accent': None,
34
+ 'variant': "default",
35
+ 'widget_class': widget_class,
36
+ 'cross_widget': False,
37
+ 'orient': None,
38
+ }
39
+
40
+ from bootstack.style.bootstyle_builder_ttk import BootstyleBuilderTTk
41
+ from bootstack.style.theme_provider import use_theme
42
+
43
+ theme_colors = use_theme().colors
44
+ if not isinstance(bootstyle, str):
45
+ raise BootstyleParsingError(f'bootstyle must be a string. Received the value: {bootstyle}')
46
+ parts = bootstyle.lower().split('-')
47
+
48
+ accent = None
49
+ variant = None
50
+ resolved_widget = widget_class
51
+ cross_widget = False
52
+ orient = None
53
+
54
+ # First pass: resolve widget target (so variant tokens can be validated)
55
+ for part in parts:
56
+ if part in WIDGET_CLASS_MAP:
57
+ resolved_widget = WIDGET_CLASS_MAP[part]
58
+ if resolved_widget != widget_class:
59
+ cross_widget = True
60
+
61
+ # Second pass: resolve accent/variant/orientation
62
+ for part in parts:
63
+ if part in WIDGET_CLASS_MAP:
64
+ # already handled in first pass
65
+ continue
66
+ if part in theme_colors or part in COLOR_TOKENS or '[' in part:
67
+ accent = part
68
+ continue
69
+ if part in ("horizontal", "vertical"):
70
+ orient = part
71
+ continue
72
+ if BootstyleBuilderTTk.has_builder(resolved_widget, part):
73
+ variant = part
74
+ continue
75
+ # If we reach here, it's unrecognized
76
+ message = f"Unrecognized variant or accent token: '{part}'"
77
+ raise BootstyleParsingError(message)
78
+
79
+ return {
80
+ 'accent': accent,
81
+ 'variant': variant,
82
+ 'widget_class': resolved_widget,
83
+ 'cross_widget': cross_widget,
84
+ 'orient': orient
85
+ }
86
+
87
+
88
+ def to_pascal_case(s: str) -> str:
89
+ """Convert dash-separated string to PascalCase.
90
+
91
+ Examples:
92
+ 'context-check' -> 'ContextCheck'
93
+ 'outline' -> 'Outline'
94
+ 'solid' -> 'Solid'
95
+ """
96
+ return ''.join(part.capitalize() for part in s.split('-'))
97
+
98
+
99
+ def from_pascal_case(s: str) -> str:
100
+ """Convert PascalCase string to dash-separated lowercase.
101
+
102
+ Examples:
103
+ 'ContextCheck' -> 'context-check'
104
+ 'Outline' -> 'outline'
105
+ 'Solid' -> 'solid'
106
+ """
107
+ import re
108
+ # Insert dash before uppercase letters (except at start), then lowercase
109
+ return re.sub(r'(?<!^)(?=[A-Z])', '-', s).lower()
110
+
111
+
112
+ def generate_ttk_style_name(
113
+ accent: Optional[str],
114
+ variant: Optional[str],
115
+ widget_class: str,
116
+ custom_prefix: Optional[str] = None,
117
+ orient: Optional[str] = None,
118
+ ) -> str:
119
+ """Generate TTK style name from parsed components.
120
+
121
+ Returns style name in format: [custom_prefix].[accent].[Variant].[Orient].[Widget]
122
+ """
123
+ parts = []
124
+
125
+ if custom_prefix:
126
+ parts.append(custom_prefix)
127
+ if accent:
128
+ parts.append(accent)
129
+ if variant:
130
+ parts.append(to_pascal_case(variant))
131
+ if orient:
132
+ parts.append(normalize_orientation(orient))
133
+ parts.append(widget_class)
134
+ return '.'.join(parts)
135
+
136
+
137
+ def normalize_orientation(orient: str):
138
+ """Normalize TTK style orientation."""
139
+ if orient.lower().startswith('v'):
140
+ return 'Vertical'
141
+ else:
142
+ return 'Horizontal'
143
+
144
+
145
+
146
+ def parse_bootstyle(bootstyle: str, widget_class: str) -> dict:
147
+ """Parse bootstyle string using configured parsing method.
148
+
149
+ Main entry point for bootstyle parsing.
150
+ """
151
+ return parse_bootstyle_v2(bootstyle, widget_class)
152
+
153
+
154
+ def extract_orient_from_style(ttk_style: str):
155
+ """Extract orientation from TTK style name."""
156
+ if 'horizontal' in ttk_style.lower():
157
+ return 'Horizontal'
158
+ elif 'vertical' in ttk_style.lower():
159
+ return 'Vertical'
160
+ else:
161
+ return None
162
+
163
+
164
+ def extract_accent_from_style(ttk_style: str, default: str = 'primary') -> str:
165
+ """Extract accent token from TTK style name, including modifiers like [subtle]."""
166
+ parts = ttk_style.split('.')
167
+
168
+ # Skip custom prefix if present (e.g., bs[hash] or custom_xyz)
169
+ if parts and (parts[0].startswith('bs[') or parts[0].startswith('custom_')):
170
+ parts = parts[1:]
171
+
172
+ for part in parts:
173
+ part_lower = part.lower()
174
+ # Check exact match first
175
+ if part_lower in COLOR_TOKENS:
176
+ return part_lower
177
+ # Check if base accent (before modifier) is an accent token
178
+ # e.g., 'primary[subtle]' -> 'primary'
179
+ if '[' in part_lower:
180
+ base_accent = part_lower.split('[')[0]
181
+ if base_accent in COLOR_TOKENS:
182
+ return part_lower # Return full token with modifier
183
+
184
+ return default
185
+
186
+
187
+ def extract_variant_from_style(ttk_style: str, widget_class: str = None) -> Optional[str]:
188
+ """Extract variant name from TTK style name.
189
+
190
+ Args:
191
+ ttk_style: The TTK style name to parse.
192
+ widget_class: Optional widget class from winfo_class() to exclude from parsing.
193
+
194
+ Returns:
195
+ Variant name in dash-separated lowercase format (e.g., 'context-check')
196
+ """
197
+ parts = ttk_style.split('.')
198
+
199
+ # Skip custom prefix if present (e.g., bs[hash] or custom_xyz)
200
+ if parts and (parts[0].startswith('bs[') or parts[0].startswith('custom_')):
201
+ parts = parts[1:]
202
+
203
+ # Build set of class-related parts to skip (e.g., 'Expander', 'TLabel')
204
+ class_parts = set()
205
+ if widget_class:
206
+ class_parts.update(widget_class.split('.'))
207
+
208
+ for part in parts:
209
+ part_lower = part.lower()
210
+ # Skip color tokens (including those with modifiers like 'primary[subtle]')
211
+ if part_lower in COLOR_TOKENS:
212
+ continue
213
+ if '[' in part_lower:
214
+ base_color = part_lower.split('[')[0]
215
+ if base_color in COLOR_TOKENS:
216
+ continue
217
+ # Skip known class parts from widget_class
218
+ if part in class_parts:
219
+ continue
220
+ # Skip standard ttk class names (TLabel, TButton, etc.)
221
+ if part.startswith('T'):
222
+ continue
223
+ # Skip orientation parts
224
+ if part in ('Horizontal', 'Vertical'):
225
+ continue
226
+ # Found a variant - convert from PascalCase to dash-separated
227
+ return from_pascal_case(part)
228
+
229
+ return None
230
+
231
+
232
+ def extract_widget_class_from_style(ttk_style: str) -> Optional[str]:
233
+ """Extract widget class from TTK style name."""
234
+ parts = ttk_style.split('.')
235
+
236
+ for part in parts:
237
+ if part.startswith('T'):
238
+ return part
239
+
240
+ return None
241
+
242
+
243
+ class Bootstyle:
244
+ """Widget integration layer for bootstyle functionality.
245
+
246
+ Wires bootstack into tkinter/ttk by overriding widget constructors and
247
+ configure methods to accept `bootstyle` parameter.
248
+ """
249
+
250
+ @staticmethod
251
+ def create_ttk_style(
252
+ widget_class: str,
253
+ style_options: Optional[dict] = None,
254
+ *,
255
+ accent: Optional[str] = None,
256
+ variant: Optional[str] = None,
257
+ ) -> str:
258
+ """Create or get TTK style name for a widget.
259
+
260
+ Args:
261
+ widget_class: TTK widget class (e.g., "TButton")
262
+ style_options: Custom style options dict
263
+ accent: Accent token (e.g., "success", "primary[subtle]")
264
+ variant: Variant name (e.g., "outline", "solid")
265
+
266
+ Returns:
267
+ Generated TTK style name
268
+ """
269
+ from bootstack.style.bootstyle_builder_ttk import BootstyleBuilderTTk
270
+
271
+ # If no accent and no variant, return base widget class
272
+ if not accent and not variant:
273
+ return widget_class
274
+
275
+ # Initialize style_options to empty dict if None
276
+ if style_options is None:
277
+ style_options = {}
278
+
279
+ surface = style_options.get("surface")
280
+
281
+ builder_variant = variant if variant is not None else \
282
+ BootstyleBuilderTTk.get_default_variant(widget_class)
283
+
284
+ custom_prefix = None
285
+
286
+ if style_options.keys() or surface != 'background':
287
+ import hashlib
288
+ import json
289
+ options_str = json.dumps(style_options, sort_keys=True)
290
+ options_hash = hashlib.md5(options_str.encode()).hexdigest()[:8]
291
+ custom_prefix = f"bs[{options_hash}]"
292
+
293
+ ttk_style = generate_ttk_style_name(
294
+ accent=accent,
295
+ variant=variant,
296
+ widget_class=widget_class,
297
+ custom_prefix=custom_prefix,
298
+ orient=style_options.get('orient'),
299
+ )
300
+
301
+ from bootstack.style.style import get_style
302
+ style = get_style()
303
+
304
+ style.create_style(
305
+ widget_class=widget_class,
306
+ variant=builder_variant,
307
+ ttk_style=ttk_style,
308
+ accent=accent,
309
+ options=style_options
310
+ )
311
+
312
+ return ttk_style
313
+
314
+ @staticmethod
315
+ def override_ttk_widget_constructor(func):
316
+ """Override ttk widget __init__ to accept bootstyle, accent, and variant parameters."""
317
+
318
+ def __init__wrapper(self, *args, **kwargs):
319
+
320
+ # Extract accent/variant parameters
321
+ accent = kwargs.pop("accent", None)
322
+ variant = kwargs.pop("variant", None)
323
+ kwargs.pop("bootstyle", None) # removed param — discard silently
324
+
325
+ had_style_kwarg = 'style' in kwargs
326
+
327
+ style_options = kwargs.pop("style_options", {})
328
+ inherit_surface = kwargs.pop('inherit_surface', None)
329
+ surface_token = kwargs.pop('surface', None)
330
+ input_bg_token = kwargs.pop('input_background', None)
331
+
332
+ # Extract ttk_class for style lookup (doesn't affect widget's actual class_)
333
+ # This allows custom style builders without affecting bindtags
334
+ ttk_class = kwargs.pop('ttk_class', None)
335
+
336
+ func(self, *args, **kwargs) # the actual widget constructor
337
+
338
+ # Use ttk_class for style lookup if provided, otherwise use widget's actual class
339
+ widget_class = self.winfo_class()
340
+ style_class = ttk_class or widget_class
341
+
342
+ # ===== Surface color inheritance =====
343
+
344
+ if inherit_surface is None:
345
+ inherit_surface = get_app_settings().inherit_surface_color
346
+
347
+ if hasattr(self, 'master') and self.master is not None:
348
+ parent_surface_token = getattr(self.master, '_surface', 'content')
349
+ else:
350
+ parent_surface_token = 'content'
351
+
352
+ if surface_token:
353
+ effective_surface_token = surface_token
354
+ elif inherit_surface:
355
+ effective_surface_token = parent_surface_token
356
+ else:
357
+ effective_surface_token = 'content'
358
+
359
+ # container widgets can take their surface color from the accent param
360
+ # Use style_class so custom ttk_class like 'Field' can opt out of this behavior
361
+ if accent and style_class in CONTAINER_CLASSES and surface_token is None:
362
+ effective_surface_token = accent
363
+
364
+ # cache the surface color for child components
365
+ setattr(self, '_surface', effective_surface_token)
366
+ if effective_surface_token != 'content' and effective_surface_token is not None:
367
+ style_options.setdefault('surface', effective_surface_token)
368
+
369
+ # ===== Input background inheritance =====
370
+
371
+ if hasattr(self, 'master') and self.master is not None:
372
+ parent_input_bg = getattr(self.master, '_input_background', None)
373
+ else:
374
+ parent_input_bg = None
375
+
376
+ if input_bg_token:
377
+ effective_input_bg = input_bg_token
378
+ elif inherit_surface and parent_input_bg:
379
+ effective_input_bg = parent_input_bg
380
+ else:
381
+ effective_input_bg = None
382
+
383
+ setattr(self, '_input_background', effective_input_bg)
384
+ if effective_input_bg:
385
+ style_options.setdefault('input_background', effective_input_bg)
386
+
387
+ # ==== Orientation =====
388
+
389
+ # handle widgets with orientation
390
+ if widget_class in ORIENT_CLASSES:
391
+ orient = str(self.cget('orient'))
392
+ style_options.setdefault('orient', orient)
393
+
394
+ # ==== Create actual ttk style & assign to widget =====
395
+
396
+ if (accent or variant) and style_class:
397
+
398
+ ttk_style = Bootstyle.create_ttk_style(
399
+ widget_class=style_class,
400
+ style_options=style_options,
401
+ accent=accent,
402
+ variant=variant,
403
+ )
404
+ self.configure(style=ttk_style)
405
+
406
+ elif style_class and not had_style_kwarg:
407
+ from bootstack.style.bootstyle_builder_ttk import BootstyleBuilderTTk
408
+ from bootstack.style.style import get_style
409
+
410
+ default_variant = BootstyleBuilderTTk.get_default_variant(style_class)
411
+
412
+ if BootstyleBuilderTTk.has_builder(style_class, default_variant):
413
+
414
+ # Build options first so we can decide if a custom bs[...] prefix is needed
415
+ custom_prefix = None
416
+ if style_options.keys():
417
+ import hashlib
418
+ import json
419
+ options_str = json.dumps(style_options, sort_keys=True)
420
+ options_hash = hashlib.md5(options_str.encode()).hexdigest()[:8]
421
+ custom_prefix = f"bs[{options_hash}]"
422
+
423
+ ttk_style = generate_ttk_style_name(
424
+ accent=None,
425
+ variant=default_variant,
426
+ widget_class=style_class,
427
+ custom_prefix=custom_prefix,
428
+ )
429
+
430
+ style_instance = get_style()
431
+ if style_instance is not None:
432
+ style_instance.create_style(
433
+ widget_class=style_class,
434
+ variant=default_variant,
435
+ ttk_style=ttk_style,
436
+ options=style_options,
437
+ )
438
+ self.configure(style=ttk_style)
439
+ else:
440
+ self.configure(style=style_class)
441
+
442
+ # Store accent, variant, ttk_class, and style_options for later retrieval
443
+ setattr(self, '_accent', accent)
444
+ setattr(self, '_variant', variant)
445
+ setattr(self, '_ttk_class', ttk_class)
446
+ setattr(self, '_style_options', style_options)
447
+
448
+ return __init__wrapper
449
+
450
+ @staticmethod
451
+ def override_tk_widget_constructor(func):
452
+ """Override Tk widget __init__ to apply theme background when autostyle=True."""
453
+
454
+ def __init__wrapper(self, *args, **kwargs):
455
+
456
+ # capture bootstrap arguments
457
+ auto_style = kwargs.pop("autostyle", True)
458
+ inherit_surface = kwargs.pop('inherit_surface', None)
459
+ if inherit_surface is None:
460
+ inherit_surface = get_app_settings().inherit_surface_color
461
+ surface_token = kwargs.pop('surface', None)
462
+
463
+ func(self, *args, **kwargs) # the actual constructor
464
+
465
+ # ===== Surface color inheritance =====
466
+
467
+ if hasattr(self, 'master') and self.master is not None:
468
+ parent_surface_token = getattr(self.master, '_surface', 'content')
469
+ else:
470
+ parent_surface_token = 'content'
471
+
472
+ if inherit_surface:
473
+ surface_token = parent_surface_token
474
+ else:
475
+ surface_token = surface_token or 'content'
476
+
477
+ setattr(self, '_surface', surface_token)
478
+
479
+ if not auto_style:
480
+ return
481
+
482
+ # ==== Update widget style & register for theme changes =====
483
+
484
+ from bootstack.style.style import get_style
485
+ from bootstack.style.bootstyle_builder_tk import BootstyleBuilderBuilderTk
486
+ style = get_style()
487
+ builder_tk = BootstyleBuilderBuilderTk(
488
+ theme_provider=style.theme_provider if style else None,
489
+ style_instance=style
490
+ )
491
+ surface = getattr(self, '_surface', 'content')
492
+ builder_tk.call_builder(self, surface=surface)
493
+
494
+ style.register_tk_widget(self)
495
+
496
+ return __init__wrapper
497
+
498
+
499
+ __all__ = [
500
+ 'parse_bootstyle',
501
+ 'parse_bootstyle_v2',
502
+ 'generate_ttk_style_name',
503
+ 'extract_accent_from_style',
504
+ 'extract_variant_from_style',
505
+ 'extract_widget_class_from_style',
506
+ 'Bootstyle',
507
+ ]