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,445 @@
1
+ """AppShell - a top-level application window with built-in navigation.
2
+
3
+ Provides a convenient way to scaffold the standard desktop app layout:
4
+ toolbar at top, sidebar navigation on the left, and page content on the right.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from typing import Any, Callable, Literal
10
+
11
+ from typing_extensions import TypedDict, Unpack
12
+
13
+ from bootstack.widgets.primitives.frame import Frame
14
+ from bootstack.widgets.composites.toolbar import Toolbar
15
+ from bootstack.widgets.composites.sidenav import SideNav
16
+ from bootstack.widgets.composites.pagestack import PageStack
17
+ from bootstack.widgets.composites.scrollview import ScrollView
18
+ from bootstack.widgets.mixins import configure_delegate
19
+ from bootstack.runtime.app import App
20
+
21
+
22
+ class AppShellKwargs(TypedDict, total=False):
23
+ title: str
24
+ theme: str
25
+ size: tuple[int, int]
26
+ position: tuple[int, int]
27
+ minsize: tuple[int, int]
28
+ maxsize: tuple[int, int]
29
+ resizable: tuple[bool, bool]
30
+ frameless: bool
31
+ show_toolbar: bool
32
+ show_window_controls: bool
33
+ draggable: bool
34
+ toolbar_density: Literal['default', 'compact']
35
+ show_nav: bool
36
+ nav_display_mode: Literal['expanded', 'compact', 'minimal']
37
+ nav_accent: str
38
+
39
+
40
+ class AppShell(App):
41
+ """A top-level application window with built-in navigation.
42
+
43
+ AppShell extends `App` and wires together a `Toolbar`,
44
+ `SideNav`, and `PageStack` into the common
45
+ toolbar + sidebar + content layout. Each component is optional
46
+ and exposed as a property for customization.
47
+
48
+ Example:
49
+ ```python
50
+ import bootstack as bs
51
+
52
+ shell = bs.AppShell(title='My App', size=(1000, 650))
53
+
54
+ home = shell.add_page('home', text='Home', icon='house')
55
+ bs.Label(home, text='Welcome!').pack(padx=20, pady=20)
56
+
57
+ docs = shell.add_page('docs', text='Documents', icon='file-earmark-text')
58
+ bs.Label(docs, text='Your documents.').pack(padx=20, pady=20)
59
+
60
+ shell.mainloop()
61
+ ```
62
+ """
63
+
64
+ def __init__(
65
+ self,
66
+ title: str = '',
67
+ theme: str | None = None,
68
+ size: tuple[int, int] | None = None,
69
+ position: tuple[int, int] | None = None,
70
+ minsize: tuple[int, int] | None = None,
71
+ maxsize: tuple[int, int] | None = None,
72
+ resizable: tuple[bool, bool] | None = None,
73
+ frameless: bool = False,
74
+ show_toolbar: bool = True,
75
+ show_window_controls: bool = False,
76
+ draggable: bool = False,
77
+ toolbar_density: Literal['default', 'compact'] = 'default',
78
+ show_nav: bool = True,
79
+ nav_display_mode: Literal['expanded', 'compact', 'minimal'] = 'expanded',
80
+ nav_accent: str = 'primary',
81
+ **kwargs: Unpack[AppShellKwargs],
82
+ ):
83
+ """Initialize an AppShell.
84
+
85
+ Args:
86
+ title: Title displayed in the toolbar and window title bar.
87
+ theme: Theme name. If None, uses the default theme.
88
+ size: Initial window size as (width, height).
89
+ position: Initial window position as (x, y).
90
+ minsize: Minimum window size as (width, height).
91
+ maxsize: Maximum window size as (width, height).
92
+ resizable: Whether the window is resizable as (width, height).
93
+ frameless: If True, remove OS window chrome (title bar, borders)
94
+ and rely on the toolbar for window controls and dragging.
95
+ Automatically enables `show_window_controls` and
96
+ `draggable` when True. Default False.
97
+ show_toolbar: Include the toolbar at the top. Default True.
98
+ show_window_controls: Show minimize/maximize/close buttons
99
+ in the toolbar. Default False.
100
+ draggable: Enable window dragging via the toolbar. Default False.
101
+ toolbar_density: Toolbar button density ('default' or 'compact').
102
+ show_nav: Include the sidebar navigation. Default True.
103
+ nav_display_mode: Initial SideNav display mode
104
+ ('expanded', 'compact', or 'minimal'). Default 'expanded'.
105
+ nav_accent: Accent color for navigation selection. Default 'primary'.
106
+ **kwargs: Additional arguments passed to App.
107
+ """
108
+ # Frameless mode: remove OS chrome and enable toolbar controls
109
+ if frameless:
110
+ show_window_controls = True
111
+ draggable = True
112
+
113
+ super().__init__(
114
+ title=title,
115
+ theme=theme,
116
+ size=size,
117
+ position=position,
118
+ minsize=minsize,
119
+ maxsize=maxsize,
120
+ resizable=resizable,
121
+ override_redirect=frameless,
122
+ **kwargs,
123
+ )
124
+
125
+ self._shell_title = title
126
+ self._show_toolbar = show_toolbar
127
+ self._show_nav = show_nav
128
+
129
+ # Track which nav keys have associated pages
130
+ self._page_keys: set[str] = set()
131
+ self._first_page_added = False
132
+ self._navigating = False # Guard against re-entrant navigation
133
+
134
+ # Build components
135
+ self._toolbar: Toolbar | None = None
136
+ self._nav: SideNav | None = None
137
+ self._pages: PageStack | None = None
138
+
139
+ self._build_shell(
140
+ show_toolbar=show_toolbar,
141
+ show_window_controls=show_window_controls,
142
+ draggable=draggable,
143
+ toolbar_density=toolbar_density,
144
+ show_nav=show_nav,
145
+ nav_display_mode=nav_display_mode,
146
+ nav_accent=nav_accent,
147
+ )
148
+
149
+ def _build_shell(
150
+ self,
151
+ *,
152
+ show_toolbar: bool,
153
+ show_window_controls: bool,
154
+ draggable: bool,
155
+ toolbar_density: str,
156
+ show_nav: bool,
157
+ nav_display_mode: str,
158
+ nav_accent: str,
159
+ ):
160
+ """Build the internal widget structure."""
161
+ # --- Toolbar ---
162
+ if show_toolbar:
163
+ self._toolbar = Toolbar(
164
+ self,
165
+ surface='chrome',
166
+ density=toolbar_density,
167
+ show_window_controls=show_window_controls,
168
+ draggable=draggable,
169
+ )
170
+ self._toolbar.pack(side='top', fill='x')
171
+
172
+ # Hamburger button (only when nav is present)
173
+ if show_nav:
174
+ self._toolbar.add_button(
175
+ icon='list',
176
+ command=self._toggle_nav,
177
+ )
178
+ self._toolbar.add_separator()
179
+
180
+ # Title label
181
+ self._title_label = None
182
+ if self._shell_title:
183
+ self._title_label = self._toolbar.add_label(text=self._shell_title, font='heading-md')
184
+
185
+ # Spacer pushes subsequent user-added buttons to the right
186
+ self._toolbar.add_spacer()
187
+
188
+ # --- Body (nav + pages) ---
189
+ body = Frame(self)
190
+ body.pack(side='top', fill='both', expand=True)
191
+
192
+ # --- SideNav ---
193
+ if show_nav:
194
+ # When toolbar is present, nav hides its own header and hamburger;
195
+ # AppShell puts the hamburger in the toolbar instead.
196
+ # When toolbar is absent, nav manages its own toggle.
197
+ self._nav = SideNav(
198
+ body,
199
+ show_header=False,
200
+ collapsible=not show_toolbar,
201
+ display_mode=nav_display_mode,
202
+ accent=nav_accent,
203
+ )
204
+ self._nav.pack(side='left', fill='y')
205
+
206
+ # Wire selection changes to page navigation
207
+ self._nav.on_selection_changed(self._on_nav_selection_changed)
208
+
209
+ # --- PageStack ---
210
+ self._pages = PageStack(body)
211
+ self._pages.pack(side='left', fill='both', expand=True)
212
+
213
+ # --- Internal Handlers ---
214
+
215
+ def _toggle_nav(self):
216
+ """Toggle the SideNav pane."""
217
+ if self._nav is not None:
218
+ self._nav.toggle_pane()
219
+
220
+ def _on_nav_selection_changed(self, event):
221
+ """Handle SideNav selection changes."""
222
+ key = event.data.get('key', '')
223
+ if not key or key not in self._page_keys:
224
+ return # Not a page item (e.g. action-only item)
225
+
226
+ if self._navigating:
227
+ return # Guard against re-entrant calls
228
+
229
+ self._navigating = True
230
+ try:
231
+ self._pages.navigate(key)
232
+ finally:
233
+ self._navigating = False
234
+
235
+ # --- Public API: Adding Content ---
236
+
237
+ def add_page(
238
+ self,
239
+ key: str,
240
+ text: str = '',
241
+ icon: str | dict = None,
242
+ page=None,
243
+ group: str = None,
244
+ is_footer: bool = False,
245
+ scrollable: bool = False,
246
+ **nav_kwargs,
247
+ ):
248
+ """Add a navigation item and its corresponding page in one call.
249
+
250
+ Args:
251
+ key: Unique identifier for both the nav item and the page.
252
+ text: Display text for the nav item.
253
+ icon: Icon name or configuration for the nav item.
254
+ page: An existing widget to use as the page. If None, a Frame
255
+ is created automatically.
256
+ group: Key of the nav group to add this item to.
257
+ is_footer: If True, add the nav item to the footer section.
258
+ scrollable: If True, the page is wrapped in a ScrollView with
259
+ vertical scrolling. The returned widget is the ScrollView
260
+ content frame, so widgets can be packed into it as usual.
261
+ **nav_kwargs: Additional arguments passed to the nav item.
262
+
263
+ Returns:
264
+ The page widget (passed or auto-created Frame). When
265
+ `scrollable=True`, returns the ScrollView so that children
266
+ are packed into the scrollable area.
267
+
268
+ Raises:
269
+ RuntimeError: If `show_nav=False` was set. Use
270
+ `shell.pages.add()` directly instead.
271
+ """
272
+ if self._nav is None:
273
+ raise RuntimeError(
274
+ "Cannot use add_page() when show_nav=False. "
275
+ "Use shell.pages.add() directly instead."
276
+ )
277
+
278
+ # Add nav item
279
+ if is_footer:
280
+ self._nav.add_footer_item(key, text=text, icon=icon, **nav_kwargs)
281
+ elif group is not None:
282
+ self._nav.add_item(key, text=text, icon=icon, group=group, **nav_kwargs)
283
+ else:
284
+ self._nav.add_item(key, text=text, icon=icon, **nav_kwargs)
285
+
286
+ # Add page
287
+ page_widget = self._pages.add(key, page=page)
288
+ self._page_keys.add(key)
289
+
290
+ # Wrap in ScrollView when requested
291
+ if scrollable:
292
+ sv = ScrollView(
293
+ page_widget,
294
+ scroll_direction="vertical",
295
+ scrollbar_visibility="hover",
296
+ )
297
+ sv.pack(fill="both", expand=True)
298
+ page_widget = sv.add()
299
+
300
+ # Stretch content frame to canvas width so fill=X works
301
+ def _on_canvas_resize(event, _sv=sv):
302
+ _sv.canvas.itemconfigure(_sv._window_id, width=event.width)
303
+ sv.canvas.bind('<Configure>', _on_canvas_resize, add='+')
304
+
305
+ # Auto-navigate to the first page added
306
+ if not self._first_page_added:
307
+ self._first_page_added = True
308
+ self.navigate(key)
309
+
310
+ return page_widget
311
+
312
+ def add_group(
313
+ self,
314
+ key: str,
315
+ text: str = '',
316
+ icon: str | dict = None,
317
+ is_expanded: bool = False,
318
+ **kwargs,
319
+ ):
320
+ """Add a navigation group.
321
+
322
+ Passthrough to `nav.add_group()`.
323
+
324
+ Args:
325
+ key: Unique identifier for the group.
326
+ text: Display text.
327
+ icon: Icon name or configuration.
328
+ is_expanded: Initial expansion state.
329
+ **kwargs: Additional arguments passed to SideNavGroup.
330
+
331
+ Returns:
332
+ SideNavGroup: The created group.
333
+ """
334
+ if self._nav is None:
335
+ raise RuntimeError("Cannot add groups when show_nav=False.")
336
+ return self._nav.add_group(key, text=text, icon=icon, is_expanded=is_expanded, **kwargs)
337
+
338
+ def add_header(self, text: str, **kwargs):
339
+ """Add a section header to the navigation.
340
+
341
+ Passthrough to `nav.add_header()`.
342
+
343
+ Args:
344
+ text: Header text.
345
+ **kwargs: Additional arguments passed to SideNavHeader.
346
+
347
+ Returns:
348
+ SideNavHeader: The created header.
349
+ """
350
+ if self._nav is None:
351
+ raise RuntimeError("Cannot add headers when show_nav=False.")
352
+ return self._nav.add_header(text, **kwargs)
353
+
354
+ def add_separator(self, **kwargs):
355
+ """Add a separator to the navigation.
356
+
357
+ Passthrough to `nav.add_separator()`.
358
+
359
+ Args:
360
+ **kwargs: Additional arguments passed to SideNavSeparator.
361
+
362
+ Returns:
363
+ SideNavSeparator: The created separator.
364
+ """
365
+ if self._nav is None:
366
+ raise RuntimeError("Cannot add separators when show_nav=False.")
367
+ return self._nav.add_separator(**kwargs)
368
+
369
+ # --- Public API: Navigation ---
370
+
371
+ def navigate(self, key: str, data: dict = None):
372
+ """Programmatic navigation: updates nav selection and navigates PageStack.
373
+
374
+ Args:
375
+ key: The page key to navigate to.
376
+ data: Optional data to pass to the page.
377
+ """
378
+ if self._navigating:
379
+ return
380
+
381
+ self._navigating = True
382
+ try:
383
+ # Update nav selection (which will NOT re-trigger navigation
384
+ # because we set the guard)
385
+ if self._nav is not None and key in self._page_keys:
386
+ self._nav.select(key)
387
+
388
+ # Navigate the page stack
389
+ if key in self._page_keys:
390
+ self._pages.navigate(key, data=data)
391
+ finally:
392
+ self._navigating = False
393
+
394
+ def select(self, key: str, data: dict = None):
395
+ """Alias for `navigate()`.
396
+
397
+ Args:
398
+ key: The page key to navigate to.
399
+ data: Optional data to pass to the page.
400
+ """
401
+ self.navigate(key, data=data)
402
+
403
+ # --- Public API: Event Binding ---
404
+
405
+ def on_page_changed(self, callback: Callable) -> str:
406
+ """Bind to page change events on the PageStack.
407
+
408
+ Args:
409
+ callback: Function to call when the page changes.
410
+
411
+ Returns:
412
+ Binding identifier for use with `off_page_changed()`.
413
+ """
414
+ return self._pages.on_page_changed(callback)
415
+
416
+ def off_page_changed(self, bind_id: str = None):
417
+ """Unbind from page change events.
418
+
419
+ Args:
420
+ bind_id: The binding identifier returned by `on_page_changed()`.
421
+ """
422
+ self._pages.off_page_changed(bind_id)
423
+
424
+ # --- Properties ---
425
+
426
+ @property
427
+ def toolbar(self) -> Toolbar | None:
428
+ """The Toolbar widget, or None if `show_toolbar=False`."""
429
+ return self._toolbar
430
+
431
+ @property
432
+ def nav(self) -> SideNav | None:
433
+ """The SideNav widget, or None if `show_nav=False`."""
434
+ return self._nav
435
+
436
+ @property
437
+ def pages(self) -> PageStack:
438
+ """The PageStack widget (always present)."""
439
+ return self._pages
440
+
441
+ @property
442
+ def current_page(self) -> str | None:
443
+ """The key of the currently displayed page, or None."""
444
+ result = self._pages.current()
445
+ return result[0] if result else None