bootstack 0.1.0__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 (471) hide show
  1. bootstack/__init__.py +157 -0
  2. bootstack/__main__.py +5 -0
  3. bootstack/_core/__init__.py +21 -0
  4. bootstack/_core/capabilities/__init__.py +45 -0
  5. bootstack/_core/capabilities/after.py +103 -0
  6. bootstack/_core/capabilities/bind.py +192 -0
  7. bootstack/_core/capabilities/bindtags.py +112 -0
  8. bootstack/_core/capabilities/busy.py +72 -0
  9. bootstack/_core/capabilities/clipboard.py +89 -0
  10. bootstack/_core/capabilities/focus.py +118 -0
  11. bootstack/_core/capabilities/grab.py +65 -0
  12. bootstack/_core/capabilities/grid.py +211 -0
  13. bootstack/_core/capabilities/localization.py +231 -0
  14. bootstack/_core/capabilities/pack.py +140 -0
  15. bootstack/_core/capabilities/place.py +113 -0
  16. bootstack/_core/capabilities/selection.py +136 -0
  17. bootstack/_core/capabilities/signals.py +244 -0
  18. bootstack/_core/capabilities/winfo.py +315 -0
  19. bootstack/_core/colorutils.py +234 -0
  20. bootstack/_core/exceptions.py +25 -0
  21. bootstack/_core/images.py +463 -0
  22. bootstack/_core/mixins/__init__.py +1 -0
  23. bootstack/_core/mixins/ttk_state.py +35 -0
  24. bootstack/_core/mixins/widget.py +132 -0
  25. bootstack/_core/paths.py +49 -0
  26. bootstack/_core/publisher.py +149 -0
  27. bootstack/_core/variables.py +62 -0
  28. bootstack/_runtime/__init__.py +3 -0
  29. bootstack/_runtime/app.py +930 -0
  30. bootstack/_runtime/base_window.py +945 -0
  31. bootstack/_runtime/events.py +399 -0
  32. bootstack/_runtime/shortcuts.py +496 -0
  33. bootstack/_runtime/tk_patch.py +43 -0
  34. bootstack/_runtime/toplevel.py +276 -0
  35. bootstack/_runtime/utility.py +457 -0
  36. bootstack/_runtime/visual_focus.py +240 -0
  37. bootstack/_runtime/window_utilities.py +1123 -0
  38. bootstack/assets/__init__.py +21 -0
  39. bootstack/assets/bootstack.ico +0 -0
  40. bootstack/assets/bootstack.png +0 -0
  41. bootstack/assets/elements/__init__.py +0 -0
  42. bootstack/assets/elements/badge-pill.png +0 -0
  43. bootstack/assets/elements/badge-square.png +0 -0
  44. bootstack/assets/elements/button-compact.png +0 -0
  45. bootstack/assets/elements/button-default.png +0 -0
  46. bootstack/assets/elements/buttongroup-after-h-compact.png +0 -0
  47. bootstack/assets/elements/buttongroup-after-h-default.png +0 -0
  48. bootstack/assets/elements/buttongroup-after-v-compact.png +0 -0
  49. bootstack/assets/elements/buttongroup-after-v-default.png +0 -0
  50. bootstack/assets/elements/buttongroup-before-h-compact.png +0 -0
  51. bootstack/assets/elements/buttongroup-before-h-default.png +0 -0
  52. bootstack/assets/elements/buttongroup-before-v-compact.png +0 -0
  53. bootstack/assets/elements/buttongroup-before-v-default.png +0 -0
  54. bootstack/assets/elements/buttongroup-center-h-compact.png +0 -0
  55. bootstack/assets/elements/buttongroup-center-h-default.png +0 -0
  56. bootstack/assets/elements/buttongroup-center-v-compact.png +0 -0
  57. bootstack/assets/elements/buttongroup-center-v-default.png +0 -0
  58. bootstack/assets/elements/card.png +0 -0
  59. bootstack/assets/elements/checkbox-checked.png +0 -0
  60. bootstack/assets/elements/checkbox-indeterminate.png +0 -0
  61. bootstack/assets/elements/checkbox-unchecked.png +0 -0
  62. bootstack/assets/elements/field.png +0 -0
  63. bootstack/assets/elements/input-addon-compact.png +0 -0
  64. bootstack/assets/elements/input-addon-default.png +0 -0
  65. bootstack/assets/elements/input-compact.png +0 -0
  66. bootstack/assets/elements/input-default.png +0 -0
  67. bootstack/assets/elements/list-item-separated.png +0 -0
  68. bootstack/assets/elements/list-item.png +0 -0
  69. bootstack/assets/elements/listrow-compact.png +0 -0
  70. bootstack/assets/elements/listrow-default.png +0 -0
  71. bootstack/assets/elements/manifest.toml +361 -0
  72. bootstack/assets/elements/menu-item.png +0 -0
  73. bootstack/assets/elements/navitem-compact.png +0 -0
  74. bootstack/assets/elements/navitem-default.png +0 -0
  75. bootstack/assets/elements/progressbar-h-compact.png +0 -0
  76. bootstack/assets/elements/progressbar-h-default.png +0 -0
  77. bootstack/assets/elements/progressbar-v-compact.png +0 -0
  78. bootstack/assets/elements/progressbar-v-default.png +0 -0
  79. bootstack/assets/elements/radiobutton.png +0 -0
  80. bootstack/assets/elements/scrollbar-horizontal.png +0 -0
  81. bootstack/assets/elements/scrollbar-vertical.png +0 -0
  82. bootstack/assets/elements/slider-handle.png +0 -0
  83. bootstack/assets/elements/slider-track-h.png +0 -0
  84. bootstack/assets/elements/slider-track-v.png +0 -0
  85. bootstack/assets/elements/switch-off.png +0 -0
  86. bootstack/assets/elements/switch-on.png +0 -0
  87. bootstack/assets/elements/tab-h.png +0 -0
  88. bootstack/assets/elements/tab-v.png +0 -0
  89. bootstack/assets/icons/bootstrap.ttf +0 -0
  90. bootstack/assets/icons/glyphmap.json +2080 -0
  91. bootstack/assets/icons/icon_metrics.json +12470 -0
  92. bootstack/assets/locales/ar/LC_MESSAGES/bootstack.mo +0 -0
  93. bootstack/assets/locales/ar/LC_MESSAGES/bootstack.po +856 -0
  94. bootstack/assets/locales/bg/LC_MESSAGES/bootstack.mo +0 -0
  95. bootstack/assets/locales/bg/LC_MESSAGES/bootstack.po +878 -0
  96. bootstack/assets/locales/cs/LC_MESSAGES/bootstack.mo +0 -0
  97. bootstack/assets/locales/cs/LC_MESSAGES/bootstack.po +856 -0
  98. bootstack/assets/locales/da/LC_MESSAGES/bootstack.mo +0 -0
  99. bootstack/assets/locales/da/LC_MESSAGES/bootstack.po +856 -0
  100. bootstack/assets/locales/de/LC_MESSAGES/bootstack.mo +0 -0
  101. bootstack/assets/locales/de/LC_MESSAGES/bootstack.po +856 -0
  102. bootstack/assets/locales/en/LC_MESSAGES/bootstack.mo +0 -0
  103. bootstack/assets/locales/en/LC_MESSAGES/bootstack.po +878 -0
  104. bootstack/assets/locales/es/LC_MESSAGES/bootstack.mo +0 -0
  105. bootstack/assets/locales/es/LC_MESSAGES/bootstack.po +856 -0
  106. bootstack/assets/locales/fr/LC_MESSAGES/bootstack.mo +0 -0
  107. bootstack/assets/locales/fr/LC_MESSAGES/bootstack.po +856 -0
  108. bootstack/assets/locales/he/LC_MESSAGES/bootstack.mo +0 -0
  109. bootstack/assets/locales/he/LC_MESSAGES/bootstack.po +854 -0
  110. bootstack/assets/locales/hi/LC_MESSAGES/bootstack.mo +0 -0
  111. bootstack/assets/locales/hi/LC_MESSAGES/bootstack.po +845 -0
  112. bootstack/assets/locales/it/LC_MESSAGES/bootstack.mo +0 -0
  113. bootstack/assets/locales/it/LC_MESSAGES/bootstack.po +844 -0
  114. bootstack/assets/locales/ja/LC_MESSAGES/bootstack.mo +0 -0
  115. bootstack/assets/locales/ja/LC_MESSAGES/bootstack.po +917 -0
  116. bootstack/assets/locales/ko/LC_MESSAGES/bootstack.mo +0 -0
  117. bootstack/assets/locales/ko/LC_MESSAGES/bootstack.po +845 -0
  118. bootstack/assets/locales/nb/LC_MESSAGES/bootstack.mo +0 -0
  119. bootstack/assets/locales/nb/LC_MESSAGES/bootstack.po +844 -0
  120. bootstack/assets/locales/nl/LC_MESSAGES/bootstack.mo +0 -0
  121. bootstack/assets/locales/nl/LC_MESSAGES/bootstack.po +844 -0
  122. bootstack/assets/locales/pl/LC_MESSAGES/bootstack.mo +0 -0
  123. bootstack/assets/locales/pl/LC_MESSAGES/bootstack.po +845 -0
  124. bootstack/assets/locales/pt/LC_MESSAGES/bootstack.mo +0 -0
  125. bootstack/assets/locales/pt/LC_MESSAGES/bootstack.po +845 -0
  126. bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.mo +0 -0
  127. bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.po +845 -0
  128. bootstack/assets/locales/sl/LC_MESSAGES/bootstack.mo +0 -0
  129. bootstack/assets/locales/sl/LC_MESSAGES/bootstack.po +845 -0
  130. bootstack/assets/locales/sv/LC_MESSAGES/bootstack.mo +0 -0
  131. bootstack/assets/locales/sv/LC_MESSAGES/bootstack.po +845 -0
  132. bootstack/assets/locales/tr/LC_MESSAGES/bootstack.mo +0 -0
  133. bootstack/assets/locales/tr/LC_MESSAGES/bootstack.po +845 -0
  134. bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.mo +0 -0
  135. bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.po +845 -0
  136. bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.mo +0 -0
  137. bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.po +845 -0
  138. bootstack/cli/__init__.py +133 -0
  139. bootstack/cli/__main__.py +6 -0
  140. bootstack/cli/add.py +395 -0
  141. bootstack/cli/appicon.py +285 -0
  142. bootstack/cli/build.py +115 -0
  143. bootstack/cli/config.py +313 -0
  144. bootstack/cli/demo.py +564 -0
  145. bootstack/cli/dev.py +153 -0
  146. bootstack/cli/doctor.py +195 -0
  147. bootstack/cli/icons.py +98 -0
  148. bootstack/cli/promote.py +120 -0
  149. bootstack/cli/pyinstaller.py +268 -0
  150. bootstack/cli/run.py +95 -0
  151. bootstack/cli/start.py +117 -0
  152. bootstack/cli/templates/__init__.py +931 -0
  153. bootstack/clipboard.py +48 -0
  154. bootstack/constants.py +318 -0
  155. bootstack/data/README.md +615 -0
  156. bootstack/data/__init__.py +78 -0
  157. bootstack/data/_observable.py +276 -0
  158. bootstack/data/base.py +780 -0
  159. bootstack/data/file_source.py +367 -0
  160. bootstack/data/memory_source.py +450 -0
  161. bootstack/data/query.py +367 -0
  162. bootstack/data/readers.py +289 -0
  163. bootstack/data/sqlite_source.py +869 -0
  164. bootstack/data/types.py +354 -0
  165. bootstack/data/writers.py +232 -0
  166. bootstack/dev/__init__.py +36 -0
  167. bootstack/dev/_capture.py +141 -0
  168. bootstack/dev/_env.py +43 -0
  169. bootstack/dev/_registry.py +140 -0
  170. bootstack/dev/_reloader.py +351 -0
  171. bootstack/dev/_reset.py +50 -0
  172. bootstack/dev/_watcher.py +91 -0
  173. bootstack/dialogs/__init__.py +948 -0
  174. bootstack/dialogs/_impl/__init__.py +47 -0
  175. bootstack/dialogs/_impl/colorchooser.py +588 -0
  176. bootstack/dialogs/_impl/datedialog.py +450 -0
  177. bootstack/dialogs/_impl/dialog.py +594 -0
  178. bootstack/dialogs/_impl/filterdialog.py +358 -0
  179. bootstack/dialogs/_impl/fontdialog.py +364 -0
  180. bootstack/dialogs/_impl/formdialog.py +564 -0
  181. bootstack/dialogs/_impl/message.py +486 -0
  182. bootstack/dialogs/_impl/query.py +570 -0
  183. bootstack/errors.py +67 -0
  184. bootstack/events/__init__.py +111 -0
  185. bootstack/events/_event.py +135 -0
  186. bootstack/events/_payloads.py +539 -0
  187. bootstack/events/_subscription.py +38 -0
  188. bootstack/i18n/README.md +77 -0
  189. bootstack/i18n/__init__.py +23 -0
  190. bootstack/i18n/catalog.py +121 -0
  191. bootstack/i18n/intl_format.py +584 -0
  192. bootstack/i18n/msgcat.py +425 -0
  193. bootstack/i18n/specs.py +156 -0
  194. bootstack/images.py +563 -0
  195. bootstack/py.typed +1 -0
  196. bootstack/scheduling/__init__.py +11 -0
  197. bootstack/scheduling/_schedule.py +218 -0
  198. bootstack/shortcuts.py +21 -0
  199. bootstack/signals/README.md +98 -0
  200. bootstack/signals/__init__.py +10 -0
  201. bootstack/signals/integration.py +100 -0
  202. bootstack/signals/signal.py +353 -0
  203. bootstack/signals/types.py +6 -0
  204. bootstack/store.py +286 -0
  205. bootstack/streams/__init__.py +12 -0
  206. bootstack/streams/_stream.py +321 -0
  207. bootstack/style/__init__.py +38 -0
  208. bootstack/style/builders/__init__.py +51 -0
  209. bootstack/style/builders/badge.py +46 -0
  210. bootstack/style/builders/button.py +339 -0
  211. bootstack/style/builders/buttongroup.py +311 -0
  212. bootstack/style/builders/calendar.py +271 -0
  213. bootstack/style/builders/checkbutton.py +110 -0
  214. bootstack/style/builders/combobox.py +113 -0
  215. bootstack/style/builders/contextmenu.py +268 -0
  216. bootstack/style/builders/entry.py +82 -0
  217. bootstack/style/builders/expander.py +148 -0
  218. bootstack/style/builders/field.py +335 -0
  219. bootstack/style/builders/frame.py +50 -0
  220. bootstack/style/builders/label.py +28 -0
  221. bootstack/style/builders/labelframe.py +34 -0
  222. bootstack/style/builders/listview.py +369 -0
  223. bootstack/style/builders/menubar.py +91 -0
  224. bootstack/style/builders/menubutton.py +359 -0
  225. bootstack/style/builders/panedwindow.py +25 -0
  226. bootstack/style/builders/progressbar.py +67 -0
  227. bootstack/style/builders/radiobutton.py +99 -0
  228. bootstack/style/builders/scale.py +64 -0
  229. bootstack/style/builders/scrollbar.py +225 -0
  230. bootstack/style/builders/separator.py +49 -0
  231. bootstack/style/builders/sidenav.py +643 -0
  232. bootstack/style/builders/sizegrip.py +15 -0
  233. bootstack/style/builders/spinbox.py +119 -0
  234. bootstack/style/builders/switch.py +70 -0
  235. bootstack/style/builders/tabitem.py +204 -0
  236. bootstack/style/builders/togglegroup.py +294 -0
  237. bootstack/style/builders/toolbutton.py +275 -0
  238. bootstack/style/builders/tooltip.py +26 -0
  239. bootstack/style/builders/treeview.py +193 -0
  240. bootstack/style/builders/utils.py +455 -0
  241. bootstack/style/builders_tk/__init__.py +16 -0
  242. bootstack/style/builders_tk/defaults.py +229 -0
  243. bootstack/style/element.py +173 -0
  244. bootstack/style/fonts.py +123 -0
  245. bootstack/style/style.py +609 -0
  246. bootstack/style/style_builder_base.py +716 -0
  247. bootstack/style/style_builder_mixed.py +93 -0
  248. bootstack/style/style_builder_tk.py +109 -0
  249. bootstack/style/style_builder_ttk.py +353 -0
  250. bootstack/style/style_resolver.py +447 -0
  251. bootstack/style/theme.py +245 -0
  252. bootstack/style/theme_provider.py +471 -0
  253. bootstack/style/themes/__init__.py +128 -0
  254. bootstack/style/tk_patch.py +5 -0
  255. bootstack/style/token_maps.py +41 -0
  256. bootstack/style/types.py +32 -0
  257. bootstack/style/typography.py +523 -0
  258. bootstack/style/utility.py +746 -0
  259. bootstack/types.py +39 -0
  260. bootstack/validation/__init__.py +6 -0
  261. bootstack/validation/types.py +15 -0
  262. bootstack/validation/validation_result.py +17 -0
  263. bootstack/validation/validation_rules.py +205 -0
  264. bootstack/widgets/__init__.py +74 -0
  265. bootstack/widgets/_core/__init__.py +31 -0
  266. bootstack/widgets/_core/app_config.py +266 -0
  267. bootstack/widgets/_core/base.py +461 -0
  268. bootstack/widgets/_core/container.py +334 -0
  269. bootstack/widgets/_core/context.py +35 -0
  270. bootstack/widgets/_core/events.py +130 -0
  271. bootstack/widgets/_core/field_mixin.py +353 -0
  272. bootstack/widgets/_core/icon_image_props.py +72 -0
  273. bootstack/widgets/_core/image_binding.py +93 -0
  274. bootstack/widgets/_core/navmodel.py +345 -0
  275. bootstack/widgets/_core/options.py +210 -0
  276. bootstack/widgets/_core/selection_group.py +130 -0
  277. bootstack/widgets/_core/window_controls.py +96 -0
  278. bootstack/widgets/_core/window_menu.py +246 -0
  279. bootstack/widgets/_impl/__init__.py +1 -0
  280. bootstack/widgets/_impl/_internal/__init__.py +0 -0
  281. bootstack/widgets/_impl/_internal/wrapper_base.py +307 -0
  282. bootstack/widgets/_impl/_parts/__init__.py +11 -0
  283. bootstack/widgets/_impl/_parts/numberentry_part.py +385 -0
  284. bootstack/widgets/_impl/_parts/spinnerentry_part.py +434 -0
  285. bootstack/widgets/_impl/_parts/textentry_part.py +406 -0
  286. bootstack/widgets/_impl/composites/__init__.py +33 -0
  287. bootstack/widgets/_impl/composites/_dateutils.py +33 -0
  288. bootstack/widgets/_impl/composites/_image_fit.py +105 -0
  289. bootstack/widgets/_impl/composites/accordion.py +381 -0
  290. bootstack/widgets/_impl/composites/avatar.py +191 -0
  291. bootstack/widgets/_impl/composites/buttongroup.py +371 -0
  292. bootstack/widgets/_impl/composites/calendar.py +972 -0
  293. bootstack/widgets/_impl/composites/carousel.py +567 -0
  294. bootstack/widgets/_impl/composites/chart.py +882 -0
  295. bootstack/widgets/_impl/composites/compositeframe.py +298 -0
  296. bootstack/widgets/_impl/composites/contextmenu.py +1951 -0
  297. bootstack/widgets/_impl/composites/dateentry.py +404 -0
  298. bootstack/widgets/_impl/composites/dropdownbutton.py +325 -0
  299. bootstack/widgets/_impl/composites/expander.py +515 -0
  300. bootstack/widgets/_impl/composites/field.py +670 -0
  301. bootstack/widgets/_impl/composites/form.py +1066 -0
  302. bootstack/widgets/_impl/composites/gallery.py +551 -0
  303. bootstack/widgets/_impl/composites/list/__init__.py +15 -0
  304. bootstack/widgets/_impl/composites/list/listitem.py +802 -0
  305. bootstack/widgets/_impl/composites/list/listview.py +1433 -0
  306. bootstack/widgets/_impl/composites/menu/__init__.py +18 -0
  307. bootstack/widgets/_impl/composites/menu/model.py +358 -0
  308. bootstack/widgets/_impl/composites/menu/render_native.py +134 -0
  309. bootstack/widgets/_impl/composites/menu/render_themed.py +134 -0
  310. bootstack/widgets/_impl/composites/meter.py +860 -0
  311. bootstack/widgets/_impl/composites/numericentry.py +201 -0
  312. bootstack/widgets/_impl/composites/pagestack.py +395 -0
  313. bootstack/widgets/_impl/composites/passwordentry.py +142 -0
  314. bootstack/widgets/_impl/composites/pathentry.py +168 -0
  315. bootstack/widgets/_impl/composites/picture.py +289 -0
  316. bootstack/widgets/_impl/composites/radiogroup.py +511 -0
  317. bootstack/widgets/_impl/composites/scrolledtext.py +375 -0
  318. bootstack/widgets/_impl/composites/scrolledtext.pyi +186 -0
  319. bootstack/widgets/_impl/composites/scrollview.py +764 -0
  320. bootstack/widgets/_impl/composites/selectbox.py +1026 -0
  321. bootstack/widgets/_impl/composites/shell/__init__.py +40 -0
  322. bootstack/widgets/_impl/composites/shell/content_host.py +52 -0
  323. bootstack/widgets/_impl/composites/shell/layout.py +335 -0
  324. bootstack/widgets/_impl/composites/shell/nav_panel.py +345 -0
  325. bootstack/widgets/_impl/composites/shell/providers.py +558 -0
  326. bootstack/widgets/_impl/composites/shell/rail.py +117 -0
  327. bootstack/widgets/_impl/composites/shell/shell.py +581 -0
  328. bootstack/widgets/_impl/composites/shell/workspace.py +273 -0
  329. bootstack/widgets/_impl/composites/sidenav/__init__.py +16 -0
  330. bootstack/widgets/_impl/composites/sidenav/header.py +81 -0
  331. bootstack/widgets/_impl/composites/sidenav/separator.py +44 -0
  332. bootstack/widgets/_impl/composites/slider/__init__.py +7 -0
  333. bootstack/widgets/_impl/composites/slider/_shared.py +195 -0
  334. bootstack/widgets/_impl/composites/slider/rangeslider.py +982 -0
  335. bootstack/widgets/_impl/composites/slider/slider.py +851 -0
  336. bootstack/widgets/_impl/composites/spinnerentry.py +185 -0
  337. bootstack/widgets/_impl/composites/tableview/__init__.py +5 -0
  338. bootstack/widgets/_impl/composites/tableview/tableview.py +3388 -0
  339. bootstack/widgets/_impl/composites/tableview/types.py +169 -0
  340. bootstack/widgets/_impl/composites/tabs/__init__.py +23 -0
  341. bootstack/widgets/_impl/composites/tabs/tabitem.py +389 -0
  342. bootstack/widgets/_impl/composites/tabs/tabs.py +974 -0
  343. bootstack/widgets/_impl/composites/tabs/tabview.py +650 -0
  344. bootstack/widgets/_impl/composites/textarea/__init__.py +26 -0
  345. bootstack/widgets/_impl/composites/textarea/change.py +46 -0
  346. bootstack/widgets/_impl/composites/textarea/codeeditor.py +526 -0
  347. bootstack/widgets/_impl/composites/textarea/core.py +495 -0
  348. bootstack/widgets/_impl/composites/textarea/decoration.py +42 -0
  349. bootstack/widgets/_impl/composites/textarea/diff.py +127 -0
  350. bootstack/widgets/_impl/composites/textarea/extensions/__init__.py +1 -0
  351. bootstack/widgets/_impl/composites/textarea/extensions/bracket_matcher.py +138 -0
  352. bootstack/widgets/_impl/composites/textarea/extensions/indent_guides.py +158 -0
  353. bootstack/widgets/_impl/composites/textarea/extensions/line_numbers.py +138 -0
  354. bootstack/widgets/_impl/composites/textarea/extensions/pygments_highlighter.py +312 -0
  355. bootstack/widgets/_impl/composites/textarea/extensions/smart_indent.py +177 -0
  356. bootstack/widgets/_impl/composites/textarea/filter.py +171 -0
  357. bootstack/widgets/_impl/composites/textarea/search_overlay.py +459 -0
  358. bootstack/widgets/_impl/composites/textarea/sidebar.py +88 -0
  359. bootstack/widgets/_impl/composites/textarea/style_registry.py +178 -0
  360. bootstack/widgets/_impl/composites/textarea/textarea.py +606 -0
  361. bootstack/widgets/_impl/composites/textarea/undo.py +217 -0
  362. bootstack/widgets/_impl/composites/textentry.py +57 -0
  363. bootstack/widgets/_impl/composites/timeentry.py +176 -0
  364. bootstack/widgets/_impl/composites/toast.py +390 -0
  365. bootstack/widgets/_impl/composites/toast_stack.py +156 -0
  366. bootstack/widgets/_impl/composites/togglegroup.py +418 -0
  367. bootstack/widgets/_impl/composites/toolbar.py +608 -0
  368. bootstack/widgets/_impl/composites/tooltip.py +491 -0
  369. bootstack/widgets/_impl/composites/tree/__init__.py +7 -0
  370. bootstack/widgets/_impl/composites/tree/source_binding.py +136 -0
  371. bootstack/widgets/_impl/composites/tree/treeitem.py +393 -0
  372. bootstack/widgets/_impl/composites/tree/treenode.py +174 -0
  373. bootstack/widgets/_impl/composites/tree/treeview.py +841 -0
  374. bootstack/widgets/_impl/mixins/__init__.py +24 -0
  375. bootstack/widgets/_impl/mixins/configure_mixin.py +216 -0
  376. bootstack/widgets/_impl/mixins/entry_mixin.py +134 -0
  377. bootstack/widgets/_impl/mixins/font_mixin.py +368 -0
  378. bootstack/widgets/_impl/mixins/icon_mixin.py +61 -0
  379. bootstack/widgets/_impl/mixins/localization_mixin.py +253 -0
  380. bootstack/widgets/_impl/mixins/signal_mixin.py +268 -0
  381. bootstack/widgets/_impl/mixins/validation_mixin.py +226 -0
  382. bootstack/widgets/_impl/primitives/__init__.py +49 -0
  383. bootstack/widgets/_impl/primitives/_menubutton.py +107 -0
  384. bootstack/widgets/_impl/primitives/badge.py +45 -0
  385. bootstack/widgets/_impl/primitives/button.py +76 -0
  386. bootstack/widgets/_impl/primitives/card.py +45 -0
  387. bootstack/widgets/_impl/primitives/checkbutton.py +124 -0
  388. bootstack/widgets/_impl/primitives/checktoggle.py +62 -0
  389. bootstack/widgets/_impl/primitives/combobox.py +156 -0
  390. bootstack/widgets/_impl/primitives/entry.py +87 -0
  391. bootstack/widgets/_impl/primitives/flexframe.py +448 -0
  392. bootstack/widgets/_impl/primitives/frame.py +185 -0
  393. bootstack/widgets/_impl/primitives/gridframe.py +546 -0
  394. bootstack/widgets/_impl/primitives/label.py +84 -0
  395. bootstack/widgets/_impl/primitives/labelframe.py +54 -0
  396. bootstack/widgets/_impl/primitives/optionmenu.py +387 -0
  397. bootstack/widgets/_impl/primitives/packframe.py +227 -0
  398. bootstack/widgets/_impl/primitives/panedwindow.py +45 -0
  399. bootstack/widgets/_impl/primitives/progressbar.py +83 -0
  400. bootstack/widgets/_impl/primitives/radiobutton.py +115 -0
  401. bootstack/widgets/_impl/primitives/radiotoggle.py +54 -0
  402. bootstack/widgets/_impl/primitives/scrollbar.py +42 -0
  403. bootstack/widgets/_impl/primitives/separator.py +43 -0
  404. bootstack/widgets/_impl/primitives/sizegrip.py +33 -0
  405. bootstack/widgets/_impl/primitives/spinbox.py +95 -0
  406. bootstack/widgets/_impl/primitives/switch.py +44 -0
  407. bootstack/widgets/_impl/primitives/treeview.py +69 -0
  408. bootstack/widgets/app.py +371 -0
  409. bootstack/widgets/appshell.py +1179 -0
  410. bootstack/widgets/avatar.py +140 -0
  411. bootstack/widgets/boolean_controls.py +455 -0
  412. bootstack/widgets/button.py +224 -0
  413. bootstack/widgets/buttongroup.py +239 -0
  414. bootstack/widgets/calendar.py +195 -0
  415. bootstack/widgets/card.py +159 -0
  416. bootstack/widgets/carousel.py +241 -0
  417. bootstack/widgets/chart.py +302 -0
  418. bootstack/widgets/codeeditor.py +675 -0
  419. bootstack/widgets/contextmenu.py +371 -0
  420. bootstack/widgets/datatable.py +688 -0
  421. bootstack/widgets/datefield.py +395 -0
  422. bootstack/widgets/divider.py +60 -0
  423. bootstack/widgets/expander.py +579 -0
  424. bootstack/widgets/form.py +200 -0
  425. bootstack/widgets/gallery.py +250 -0
  426. bootstack/widgets/gauge.py +168 -0
  427. bootstack/widgets/grid.py +121 -0
  428. bootstack/widgets/groupbox.py +162 -0
  429. bootstack/widgets/label.py +229 -0
  430. bootstack/widgets/listview.py +354 -0
  431. bootstack/widgets/menubutton.py +419 -0
  432. bootstack/widgets/numberfield.py +431 -0
  433. bootstack/widgets/pagestack.py +345 -0
  434. bootstack/widgets/passwordfield.py +383 -0
  435. bootstack/widgets/pathfield.py +454 -0
  436. bootstack/widgets/picture.py +251 -0
  437. bootstack/widgets/progressbar.py +106 -0
  438. bootstack/widgets/radio_variants.py +271 -0
  439. bootstack/widgets/radiogroup.py +228 -0
  440. bootstack/widgets/scrollbar.py +64 -0
  441. bootstack/widgets/scrollview.py +186 -0
  442. bootstack/widgets/select.py +302 -0
  443. bootstack/widgets/selectbutton.py +182 -0
  444. bootstack/widgets/sidebar_toggle.py +130 -0
  445. bootstack/widgets/sizegrip.py +42 -0
  446. bootstack/widgets/slider.py +408 -0
  447. bootstack/widgets/spinbox.py +147 -0
  448. bootstack/widgets/spinnerfield.py +413 -0
  449. bootstack/widgets/splash.py +367 -0
  450. bootstack/widgets/splitview.py +482 -0
  451. bootstack/widgets/stacks.py +249 -0
  452. bootstack/widgets/statusbar.py +189 -0
  453. bootstack/widgets/tabs.py +425 -0
  454. bootstack/widgets/textarea.py +459 -0
  455. bootstack/widgets/textfield.py +410 -0
  456. bootstack/widgets/theme_toggle.py +92 -0
  457. bootstack/widgets/timefield.py +340 -0
  458. bootstack/widgets/toast.py +314 -0
  459. bootstack/widgets/togglegroup.py +231 -0
  460. bootstack/widgets/toolbar.py +347 -0
  461. bootstack/widgets/tooltip.py +94 -0
  462. bootstack/widgets/tree.py +648 -0
  463. bootstack/widgets/types.py +305 -0
  464. bootstack/widgets/window.py +307 -0
  465. bootstack-0.1.0.dist-info/METADATA +301 -0
  466. bootstack-0.1.0.dist-info/RECORD +471 -0
  467. bootstack-0.1.0.dist-info/WHEEL +5 -0
  468. bootstack-0.1.0.dist-info/entry_points.txt +2 -0
  469. bootstack-0.1.0.dist-info/licenses/LICENSE +21 -0
  470. bootstack-0.1.0.dist-info/licenses/NOTICE +10 -0
  471. bootstack-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,371 @@
1
+ from __future__ import annotations
2
+
3
+ import sys
4
+ from typing import TYPE_CHECKING, Any, Callable, Literal, Sequence
5
+
6
+ from bootstack._runtime.app import App as _InternalApp, LocalizeMode
7
+
8
+ if TYPE_CHECKING:
9
+ from bootstack.images import AppIcon, Image
10
+ from bootstack.widgets._impl.primitives.flexframe import FlexFrame
11
+ from bootstack.widgets._core.app_config import AppConfigMixin, APP_CONFIG_KWARGS
12
+ from bootstack.widgets._core.container import FlexContainer
13
+ from bootstack.widgets._core.window_controls import WindowControlsMixin
14
+ from bootstack.widgets._core.window_menu import ChromeHostMixin
15
+ from bootstack.widgets.types import (
16
+ Padding, HAlign, VArrange, SurfaceToken, WindowStyle,
17
+ )
18
+
19
+
20
+ class App(AppConfigMixin, WindowControlsMixin, ChromeHostMixin, FlexContainer):
21
+ """The application window. Behaves as an implicit Column from the user's
22
+ perspective: accepts `padding`, `gap`, `horizontal_items`, `vertical_items`,
23
+ and `grow_items` and applies them to its internal content frame.
24
+
25
+ Configuration is a single flat path: pass options as constructor kwargs and
26
+ read or change them through matching `app.*` properties (e.g. `app.theme`,
27
+ `app.locale`). Setting `app.theme` or `app.locale` takes effect live.
28
+
29
+ Args:
30
+ title: Window title bar text and the app's display name.
31
+ size: Initial window size as `(width, height)`.
32
+ icon: Title-bar and taskbar icon — an icon file path, an `Image` handle,
33
+ or an `AppIcon`. Defaults to the bootstack icon.
34
+ theme: Theme name to apply on startup (e.g. `'bootstrap-dark'`).
35
+ light_theme: Theme used for the light end of system-appearance
36
+ tracking and `toggle_theme`.
37
+ dark_theme: Theme used for the dark end of system-appearance
38
+ tracking and `toggle_theme`.
39
+ follow_system_appearance: If True, switch between `light_theme` and
40
+ `dark_theme` to match the OS (currently effective on macOS).
41
+ available_themes: Theme names to expose to theme pickers. Empty means
42
+ all registered themes.
43
+ locale: Locale identifier (e.g. `'en_US'`, `'de_DE'`). Auto-detected
44
+ from the system when not given.
45
+ localize_mode: Localization behavior.
46
+ window_style: Windows-only window effect, or None to disable.
47
+ macos_quit_behavior: macOS close / Cmd+Q behavior. No-op on Win/Linux.
48
+ remember_window_state: If True, window geometry is saved on close and
49
+ restored on next launch.
50
+ state_path: Optional override for the persisted window-state file.
51
+ on_close: Handler invoked when the user clicks the window's close button.
52
+ Return `False` to veto the close; return `None` or `True` to allow
53
+ it. Not called by the programmatic `close()`.
54
+ position: Initial window position as `(x, y)`.
55
+ min_size: Minimum window size as `(width, height)`.
56
+ max_size: Maximum window size as `(width, height)`.
57
+ resizable: Whether the window can be resized as `(width, height)`.
58
+ scaling: Explicit UI scaling factor. When None, scaling is automatic.
59
+ hdpi: Enable high-DPI awareness for the application. Default `True`.
60
+ undecorated: Remove the OS title bar and border (borderless window).
61
+ Ignored on macOS. The app gets a built-in draggable title bar with
62
+ min/max/close so it stays movable and closeable; add your own with
63
+ `add_toolbar(show_window_controls=True)` to take over the chrome.
64
+ padding: Inner padding applied to the content frame.
65
+ gap: Spacing between stacked children. Default `0`.
66
+ horizontal_items: Horizontal alignment of children — `'left'`,
67
+ `'center'`, `'right'`, or `'stretch'` (fill the width). Default
68
+ `'center'`.
69
+ vertical_items: How children are arranged top to bottom — `'top'`,
70
+ `'center'`, `'bottom'`, or a `'space-*'` mode. Default `'top'`.
71
+ grow_items: When `True`, children grow equally to fill the height.
72
+ Default `False`.
73
+ surface: Background surface for the content frame.
74
+ """
75
+
76
+ _auto_place = False # no parent
77
+ _dev_supports_inprocess = True # supports in-process hot reload (bootstack dev)
78
+
79
+ def __init__(
80
+ self,
81
+ *,
82
+ title: str | None = None,
83
+ size: tuple[int, int] | None = None,
84
+ icon: "str | Image | AppIcon | None" = None,
85
+ theme: str | None = None,
86
+ # theme
87
+ light_theme: str = "bootstrap-light",
88
+ dark_theme: str = "bootstrap-dark",
89
+ follow_system_appearance: bool = False,
90
+ available_themes: Sequence[str] = (),
91
+ # localization
92
+ locale: str | None = None,
93
+ localize_mode: LocalizeMode = "auto",
94
+ # platform / window-state persistence
95
+ window_style: WindowStyle | str | None = "mica",
96
+ macos_quit_behavior: Literal['native', 'classic'] = "native",
97
+ remember_window_state: bool = False,
98
+ state_path: str | None = None,
99
+ on_close: Callable[[], bool | None] | None = None,
100
+ # window placement / display
101
+ position: tuple[int, int] | None = None,
102
+ min_size: tuple[int, int] | None = None,
103
+ max_size: tuple[int, int] | None = None,
104
+ resizable: tuple[bool, bool] | None = None,
105
+ scaling: float | None = None,
106
+ hdpi: bool = True,
107
+ undecorated: bool = False,
108
+ # Child-guidance (applied to the internal content frame)
109
+ padding: Padding | None = None,
110
+ gap: int = 0,
111
+ horizontal_items: HAlign = "center",
112
+ vertical_items: VArrange = "top",
113
+ grow_items: bool = False,
114
+ surface: SurfaceToken | str | None = None,
115
+ # Extra kwargs forwarded to the internal App (icon, position, etc.)
116
+ **app_kwargs: Any,
117
+ ) -> None:
118
+ self._parent = None
119
+ self._dev_body = None # set in __enter__ under `bootstack dev`
120
+
121
+ # Under `bootstack dev`, persist window geometry by default so a
122
+ # process-restart reload re-opens the window where it was. Honors an
123
+ # explicit choice; uses a dev-scoped state file so it never clobbers the
124
+ # app's real saved state.
125
+ from bootstack.dev._env import DEV_MIN_SIZE, is_dev_mode
126
+
127
+ if is_dev_mode():
128
+ if not remember_window_state and state_path is None:
129
+ from bootstack._core.paths import app_config_file
130
+
131
+ remember_window_state = True
132
+ state_path = str(app_config_file("dev_window_state.json", title or "bootstack"))
133
+ # A usable floor so a reload window starts/stays a sensible size.
134
+ if min_size is None:
135
+ min_size = DEV_MIN_SIZE
136
+
137
+ init_kwargs: dict[str, Any] = {
138
+ "light_theme": light_theme,
139
+ "dark_theme": dark_theme,
140
+ "follow_system_appearance": follow_system_appearance,
141
+ "available_themes": available_themes,
142
+ "locale": locale,
143
+ "localize_mode": localize_mode,
144
+ "window_style": window_style,
145
+ "macos_quit_behavior": macos_quit_behavior,
146
+ "remember_window_state": remember_window_state,
147
+ "state_path": state_path,
148
+ "scaling": scaling,
149
+ "hdpi": hdpi,
150
+ "override_redirect": undecorated,
151
+ }
152
+ # overrideredirect has no effect on macOS — so the borderless treatment
153
+ # (custom border + title bar) is Windows/Linux only.
154
+ self._undecorated = undecorated and sys.platform != "darwin"
155
+ if title is not None:
156
+ init_kwargs["title"] = title
157
+ if size is not None:
158
+ init_kwargs["size"] = size
159
+ if theme is not None:
160
+ init_kwargs["theme"] = theme
161
+ if position is not None:
162
+ init_kwargs["position"] = position
163
+ if min_size is not None:
164
+ init_kwargs["minsize"] = min_size
165
+ if max_size is not None:
166
+ init_kwargs["maxsize"] = max_size
167
+ if resizable is not None:
168
+ init_kwargs["resizable"] = resizable
169
+ if on_close is not None:
170
+ init_kwargs["on_close"] = on_close
171
+
172
+ init_kwargs.update(app_kwargs)
173
+
174
+ self._tk_root = _InternalApp(**init_kwargs)
175
+
176
+ # Resolve the icon AFTER the root exists. An `AppIcon` may resolve theme
177
+ # color tokens (which need the style/root) and a deferred `Image` must be
178
+ # rendered against the root — doing either before the root would spin up
179
+ # a stray default root and bind the icon to the wrong interpreter.
180
+ self._app_icon_photo = None
181
+ if icon is not None:
182
+ from bootstack.widgets._core.image_binding import resolve_window_icon
183
+
184
+ icon_path, icon_image = resolve_window_icon(icon)
185
+ if icon_path is not None:
186
+ self._tk_root._setup_icon(icon_path)
187
+ elif icon_image is not None:
188
+ self._app_icon_photo = icon_image._materialize()
189
+ self._tk_root._setup_icon(self._app_icon_photo)
190
+
191
+ frame_kwargs: dict[str, Any] = {
192
+ "direction": "vertical",
193
+ "gap": gap,
194
+ "horizontal_items": horizontal_items,
195
+ "vertical_items": vertical_items,
196
+ "grow_items": grow_items,
197
+ }
198
+ if padding is not None:
199
+ frame_kwargs["padding"] = padding
200
+ if surface is not None:
201
+ frame_kwargs["surface"] = surface
202
+
203
+ # In undecorated mode the OS border is gone; a 1px themed border frame
204
+ # substitutes it and hosts both the chrome stack and the content.
205
+ if self._undecorated:
206
+ from bootstack.widgets._impl.primitives.frame import Frame
207
+
208
+ self._region_root = Frame(self._tk_root, show_border=True, padding=1)
209
+ self._region_root.pack(fill="both", expand=True)
210
+ else:
211
+ self._region_root = self._tk_root
212
+
213
+ # Stash the content-frame config so dev hot reload can rebuild a fresh
214
+ # content frame with identical guidance after tearing the old one down.
215
+ self._dev_frame_kwargs = dict(frame_kwargs)
216
+ self._content_frame = FlexFrame(self._region_root, **frame_kwargs)
217
+ self._content_frame.pack(fill="both", expand=True)
218
+
219
+ self._internal = self._tk_root
220
+
221
+ def _toolbar_stack_parent(self) -> Any:
222
+ # The chrome stack lives inside the (bordered) region root, above content.
223
+ return getattr(self, "_region_root", self._tk_root)
224
+
225
+ @classmethod
226
+ def from_store(cls, store: Any, **overrides: Any) -> "App":
227
+ """Construct an `App` from a persisted `Store` (or plain dict).
228
+
229
+ Reads configuration from `store` and applies it as constructor kwargs,
230
+ tolerantly ignoring any keys that are not valid `App` configuration —
231
+ so a settings file written by an older or newer version (with renamed
232
+ or removed keys) still restores cleanly instead of raising. Explicit
233
+ keyword `overrides` win over stored values.
234
+
235
+ Args:
236
+ store: A `Store` (anything with `as_dict()`) or a mapping of
237
+ configuration values.
238
+ **overrides: Configuration kwargs that take precedence over the
239
+ stored values.
240
+
241
+ Returns:
242
+ A new `App` configured from the store.
243
+
244
+ Example:
245
+ .. code-block:: python
246
+
247
+ from bootstack.store import Store
248
+
249
+ store = Store("settings")
250
+ app = bs.App.from_store(store)
251
+ app.on_theme_change(lambda t: store.update(theme=t))
252
+ """
253
+ data = store.as_dict() if hasattr(store, "as_dict") else dict(store)
254
+ kwargs = {k: v for k, v in data.items() if k in APP_CONFIG_KWARGS}
255
+ kwargs.update(overrides)
256
+ return cls(**kwargs)
257
+
258
+ def _config_app(self) -> Any:
259
+ return self._tk_root
260
+
261
+ @property
262
+ def _flex_frame(self):
263
+ """Children flow into the content frame, not the Tk root."""
264
+ return self._content_frame
265
+
266
+ def run(self) -> None:
267
+ """Show the window and start the event loop."""
268
+ self._ensure_default_titlebar()
269
+ from bootstack.dev._env import is_dev_mode
270
+
271
+ if is_dev_mode():
272
+ from bootstack.dev._reloader import install_reloader
273
+
274
+ install_reloader(self)
275
+ # Let the internal mainloop center and *then* show the window — it
276
+ # flushes layout and applies the window style while still withdrawn, so
277
+ # the window is fully drawn and positioned before it becomes visible.
278
+ # (Deiconifying here first would map it uncentered, then jump on center.)
279
+ self._tk_root.mainloop()
280
+
281
+ def __enter__(self) -> "App":
282
+ result = super().__enter__()
283
+ # Under `bootstack dev`, capture where this `with` body lives so a save
284
+ # can re-exec it. No-op (and zero cost) outside dev mode.
285
+ from bootstack.dev._env import is_dev_mode
286
+
287
+ if is_dev_mode() and self._dev_body is None:
288
+ import sys as _sys
289
+ from bootstack.dev._capture import capture_from_frame
290
+
291
+ try:
292
+ self._dev_body = capture_from_frame(_sys._getframe(1))
293
+ except Exception:
294
+ self._dev_body = None
295
+ return result
296
+
297
+ def __exit__(self, exc_type, exc, tb) -> None:
298
+ super().__exit__(exc_type, exc, tb)
299
+ try:
300
+ self._tk_root.update_idletasks()
301
+ except Exception:
302
+ pass
303
+ return None
304
+
305
+ # ----- dev hot-reload hooks ----------------------------------------------
306
+ # Used only under `bootstack dev`; see bootstack.dev. AppShell/Workbench
307
+ # override the route hooks to preserve the selected page across a reload.
308
+
309
+ def _dev_reset_region(self) -> None:
310
+ """Tear down the chrome + content the `with` body built, keep the root."""
311
+ stack = getattr(self, "_toolbar_stack", None)
312
+ if stack is not None:
313
+ try:
314
+ stack.destroy()
315
+ except Exception:
316
+ pass
317
+ self._toolbar_stack = None
318
+ self._chrome_toolbars = []
319
+ self._native_menu_renderer = None
320
+ self._cancel_native_menu_pending()
321
+ # Clear the native menu bar (macOS) so a rebuild doesn't double it.
322
+ try:
323
+ root = self._menu_root()
324
+ if root is not None:
325
+ root["menu"] = ""
326
+ except Exception:
327
+ pass
328
+ # Replace the content frame wholesale — destroying the subtree fires
329
+ # <Destroy> on every descendant (the normal teardown path) and avoids
330
+ # carrying stale flex bookkeeping into the rebuild.
331
+ old = getattr(self, "_content_frame", None)
332
+ if old is not None:
333
+ try:
334
+ old.destroy()
335
+ except Exception:
336
+ pass
337
+ self._content_frame = FlexFrame(self._region_root, **self._dev_frame_kwargs)
338
+ self._content_frame.pack(fill="both", expand=True)
339
+ try:
340
+ from bootstack.dev import _registry
341
+
342
+ _registry.reset_mounts()
343
+ except Exception:
344
+ pass
345
+
346
+ def _dev_after_rebuild(self) -> None:
347
+ """Re-apply window chrome that lives outside the body, then flush.
348
+
349
+ Grows the window to fit if the rebuilt layout needs more room than the
350
+ current geometry, but never shrinks it — so a reload that adds content
351
+ doesn't clip it, without the jarring shrink when content is removed.
352
+ """
353
+ self._ensure_default_titlebar()
354
+ try:
355
+ root = self._tk_root
356
+ root.update_idletasks()
357
+ cur_w, cur_h = root.winfo_width(), root.winfo_height()
358
+ new_w = max(cur_w, root.winfo_reqwidth())
359
+ new_h = max(cur_h, root.winfo_reqheight())
360
+ if new_w > cur_w or new_h > cur_h:
361
+ root.geometry(f"{new_w}x{new_h}+{root.winfo_x()}+{root.winfo_y()}")
362
+ except Exception:
363
+ pass
364
+
365
+ def _dev_capture_route(self) -> Any:
366
+ """Route to restore after a reload. Plain App has none."""
367
+ return None
368
+
369
+ def _dev_restore_route(self, route: Any) -> None:
370
+ """Restore a route captured before a reload. No-op for plain App."""
371
+ return None