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,321 @@
1
+ from __future__ import annotations
2
+
3
+ import tkinter as tk
4
+ from typing import Any, Callable, Generic, Optional, TypeVar
5
+
6
+ from bootstack.events import Subscription
7
+
8
+ T = TypeVar("T")
9
+ U = TypeVar("U")
10
+
11
+
12
+ class Handle:
13
+ """Cancellable handle returned by stream terminal operators.
14
+
15
+ Duck-type compatible with `Subscription` — supports `.cancel()`,
16
+ context manager protocol, and `.cancelled` property.
17
+
18
+ Returned by `Stream.listen()` and time-based stream operators
19
+ (`debounce`, `throttle`, `delay`).
20
+ """
21
+
22
+ __slots__ = ("_fn", "_cancelled")
23
+
24
+ def __init__(self, cancel_fn: Callable[[], None]) -> None:
25
+ self._fn = cancel_fn
26
+ self._cancelled = False
27
+
28
+ def cancel(self) -> None:
29
+ """Detach the handler and clean up all resources in the chain."""
30
+ if self._cancelled:
31
+ return
32
+ self._cancelled = True
33
+ try:
34
+ self._fn()
35
+ except Exception:
36
+ pass
37
+
38
+ def __enter__(self) -> "Handle":
39
+ return self
40
+
41
+ def __exit__(self, *_: Any) -> None:
42
+ self.cancel()
43
+
44
+ @property
45
+ def cancelled(self) -> bool:
46
+ """True once `.cancel()` has been called."""
47
+ return self._cancelled
48
+
49
+
50
+ class _Scheduler:
51
+ """Timer adapter for stream operators.
52
+
53
+ Tracks all pending tokens and cancels them when the owner widget is
54
+ destroyed, preventing callbacks from firing on dead widgets.
55
+ """
56
+
57
+ __slots__ = ("_w", "_tokens")
58
+
59
+ def __init__(self, widget: tk.Misc) -> None:
60
+ self._w = widget
61
+ self._tokens: set = set()
62
+ try:
63
+ widget.bind("<Destroy>", self._on_destroy, add=True)
64
+ except Exception:
65
+ pass
66
+
67
+ def call_later(self, ms: int, fn: Callable[[], None]) -> Any:
68
+ tok = self._w.after(max(0, int(ms)), fn)
69
+ self._tokens.add(tok)
70
+ return tok
71
+
72
+ def cancel(self, token: Any) -> None:
73
+ self._tokens.discard(token)
74
+ try:
75
+ self._w.after_cancel(token)
76
+ except Exception:
77
+ pass
78
+
79
+ def _on_destroy(self, *_: Any) -> None:
80
+ for tok in list(self._tokens):
81
+ try:
82
+ self._w.after_cancel(tok)
83
+ except Exception:
84
+ pass
85
+ self._tokens.clear()
86
+
87
+
88
+ # Union of the two subscription-compatible types.
89
+ AnySubscription = Subscription | Handle
90
+
91
+
92
+ class Stream(Generic[T]):
93
+ """A composable push-stream for widget events.
94
+
95
+ Created by `widget.on(event)` (no handler). Chain operators to transform
96
+ or filter events, then call `.listen(handler)` to attach a handler and
97
+ activate the upstream event binding.
98
+
99
+ Usage::
100
+
101
+ # Simple — bind immediately, return Subscription
102
+ sub = widget.on("change", handler)
103
+
104
+ # Composed — lazy bind, activated by .listen()
105
+ sub = (
106
+ widget.on("change")
107
+ .debounce(300)
108
+ .filter(lambda e: len(e.value or "") > 1)
109
+ .listen(on_search)
110
+ )
111
+
112
+ sub.cancel() # detach handler and remove the event binding
113
+
114
+ All operator methods return a new `Stream` — they do not consume the
115
+ original. `.listen()` is the only terminal; it activates the binding and
116
+ returns a cancellable handle.
117
+
118
+ Args:
119
+ owner: Widget used for timer scheduling (debounce/throttle delays).
120
+ _source: Internal — callable that, given a downstream handler,
121
+ installs the upstream binding and returns a handle.
122
+ """
123
+
124
+ def __init__(
125
+ self,
126
+ owner: tk.Misc,
127
+ *,
128
+ _source: Optional[Callable[[Callable[[T], Any]], AnySubscription]] = None,
129
+ _scheduler: Optional[_Scheduler] = None,
130
+ ) -> None:
131
+ self._owner = owner
132
+ self._source = _source
133
+ self._sched = _scheduler or _Scheduler(owner)
134
+
135
+ # ----- operators ---------------------------------------------------------
136
+
137
+ def map(self, fn: Callable[[T], U]) -> "Stream[U]":
138
+ """Transform each event value through `fn`.
139
+
140
+ Args:
141
+ fn: Mapping function applied to each value.
142
+
143
+ Returns:
144
+ New stream emitting transformed values.
145
+ """
146
+ parent = self
147
+
148
+ def _source(handler: Callable[[U], Any]) -> AnySubscription:
149
+ return parent.listen(lambda v: handler(fn(v)))
150
+
151
+ return Stream(self._owner, _source=_source, _scheduler=self._sched)
152
+
153
+ def filter(self, pred: Callable[[T], bool]) -> "Stream[T]":
154
+ """Emit only values for which `pred(value)` is `True`.
155
+
156
+ Args:
157
+ pred: Predicate — values returning `False` are dropped.
158
+
159
+ Returns:
160
+ New stream emitting only matching values.
161
+ """
162
+ parent = self
163
+
164
+ def _source(handler: Callable[[T], Any]) -> AnySubscription:
165
+ return parent.listen(lambda v: handler(v) if pred(v) else None)
166
+
167
+ return Stream(self._owner, _source=_source, _scheduler=self._sched)
168
+
169
+ def tap(self, fn: Callable[[T], Any]) -> "Stream[T]":
170
+ """Call `fn` for side-effects on each value; forward value unchanged.
171
+
172
+ Args:
173
+ fn: Side-effect function (result is ignored).
174
+
175
+ Returns:
176
+ New stream emitting the original values.
177
+ """
178
+ parent = self
179
+
180
+ def _source(handler: Callable[[T], Any]) -> AnySubscription:
181
+ def _tap(v: T) -> None:
182
+ fn(v)
183
+ handler(v)
184
+ return parent.listen(_tap)
185
+
186
+ return Stream(self._owner, _source=_source, _scheduler=self._sched)
187
+
188
+ def debounce(self, ms: int) -> "Stream[T]":
189
+ """Emit after `ms` milliseconds of silence — resets on each new value.
190
+
191
+ Useful for search-as-you-type: only fires after the user stops typing.
192
+
193
+ Args:
194
+ ms: Quiet period in milliseconds before emission.
195
+
196
+ Returns:
197
+ New stream emitting debounced values.
198
+ """
199
+ parent = self
200
+ sched = self._sched
201
+
202
+ def _source(handler: Callable[[T], Any]) -> AnySubscription:
203
+ state: dict[str, Any] = {"token": None, "last": None}
204
+
205
+ def _fire() -> None:
206
+ state["token"] = None
207
+ handler(state["last"])
208
+
209
+ def _on_value(v: T) -> None:
210
+ state["last"] = v
211
+ if state["token"] is not None:
212
+ sched.cancel(state["token"])
213
+ state["token"] = sched.call_later(ms, _fire)
214
+
215
+ upstream = parent.listen(_on_value)
216
+
217
+ def _cancel() -> None:
218
+ if state["token"] is not None:
219
+ sched.cancel(state["token"])
220
+ state["token"] = None
221
+ upstream.cancel()
222
+
223
+ return Handle(_cancel)
224
+
225
+ return Stream(self._owner, _source=_source, _scheduler=self._sched)
226
+
227
+ def throttle(self, ms: int) -> "Stream[T]":
228
+ """Emit at most once per `ms` milliseconds (leading edge).
229
+
230
+ Args:
231
+ ms: Minimum interval between emissions in milliseconds.
232
+
233
+ Returns:
234
+ New stream emitting throttled values.
235
+ """
236
+ parent = self
237
+ sched = self._sched
238
+
239
+ def _source(handler: Callable[[T], Any]) -> AnySubscription:
240
+ state: dict[str, Any] = {"open": True, "token": None}
241
+
242
+ def _reopen() -> None:
243
+ state["open"] = True
244
+ state["token"] = None
245
+
246
+ def _on_value(v: T) -> None:
247
+ if state["open"]:
248
+ state["open"] = False
249
+ handler(v)
250
+ state["token"] = sched.call_later(ms, _reopen)
251
+
252
+ upstream = parent.listen(_on_value)
253
+
254
+ def _cancel() -> None:
255
+ if state["token"] is not None:
256
+ sched.cancel(state["token"])
257
+ state["token"] = None
258
+ upstream.cancel()
259
+
260
+ return Handle(_cancel)
261
+
262
+ return Stream(self._owner, _source=_source, _scheduler=self._sched)
263
+
264
+ def delay(self, ms: int) -> "Stream[T]":
265
+ """Re-emit each value after a fixed `ms` millisecond delay.
266
+
267
+ Args:
268
+ ms: Delay in milliseconds applied to each value.
269
+
270
+ Returns:
271
+ New stream emitting delayed values.
272
+ """
273
+ parent = self
274
+ sched = self._sched
275
+
276
+ def _source(handler: Callable[[T], Any]) -> AnySubscription:
277
+ tokens: set[Any] = set()
278
+
279
+ def _on_value(v: T) -> None:
280
+ tok_holder: list[Any] = [None]
281
+
282
+ def _fire() -> None:
283
+ tokens.discard(tok_holder[0])
284
+ handler(v)
285
+
286
+ tok = sched.call_later(ms, _fire)
287
+ tok_holder[0] = tok
288
+ tokens.add(tok)
289
+
290
+ upstream = parent.listen(_on_value)
291
+
292
+ def _cancel() -> None:
293
+ for tok in list(tokens):
294
+ sched.cancel(tok)
295
+ tokens.clear()
296
+ upstream.cancel()
297
+
298
+ return Handle(_cancel)
299
+
300
+ return Stream(self._owner, _source=_source, _scheduler=self._sched)
301
+
302
+ # ----- terminal ----------------------------------------------------------
303
+
304
+ def listen(self, handler: Callable[[T], Any]) -> AnySubscription:
305
+ """Attach `handler` and activate the upstream event binding.
306
+
307
+ This is the only terminal operator. Returns a cancellable handle —
308
+ call `.cancel()` to detach the handler and clean up all resources
309
+ (event binding, pending timers) in the operator chain.
310
+
311
+ Args:
312
+ handler: Callable invoked for each event value.
313
+
314
+ Returns:
315
+ Cancellable handle.
316
+ """
317
+ if self._source is None:
318
+ raise RuntimeError(
319
+ "Stream has no source. Use widget.on(event) to create a stream."
320
+ )
321
+ return self._source(handler)
@@ -0,0 +1,38 @@
1
+ """Style engine, theming, and typography for bootstack.
2
+
3
+ `Style`, `Typography`, and `Font` are internal engine classes — import them from
4
+ their modules (`bootstack.style.style`, `bootstack.style.typography`) if you need
5
+ them. They are deliberately not part of the public API: `Style` subclasses
6
+ `ttk.Style` (a Tkinter leak), and `Typography`/`Font` are internal registries
7
+ slated to be replaced by a public font-token API.
8
+
9
+ The low-level engine accessors `get_style`, `get_style_builder`, and
10
+ `get_theme_provider` return those internal objects and are likewise not public —
11
+ import them from `bootstack.style.style` if you need them internally.
12
+ """
13
+ from bootstack.style.style import (
14
+ get_theme,
15
+ get_theme_color,
16
+ get_themes,
17
+ set_theme,
18
+ toggle_theme,
19
+ )
20
+ from bootstack.style.theme import Theme, ThemeMode
21
+ from bootstack.style.fonts import (
22
+ get_font_families,
23
+ set_font_family,
24
+ update_font_token,
25
+ )
26
+
27
+ __all__ = [
28
+ "Theme",
29
+ "ThemeMode",
30
+ "get_theme",
31
+ "get_theme_color",
32
+ "get_themes",
33
+ "set_theme",
34
+ "toggle_theme",
35
+ "get_font_families",
36
+ "set_font_family",
37
+ "update_font_token",
38
+ ]
@@ -0,0 +1,51 @@
1
+ """Style builder functions for bootstack widgets.
2
+
3
+ This package contains individual builder functions organized by widget type.
4
+ Each builder is registered with the StyleBuilder registry using decorators.
5
+
6
+ Builder modules are automatically imported to trigger registration.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from . import (
12
+ badge, button, checkbutton, combobox, entry, expander, frame, label, labelframe, menubutton, sidenav,
13
+ panedwindow, progressbar, radiobutton, scale, scrollbar, separator, sizegrip, spinbox, switch,
14
+ treeview, toolbutton, tooltip, field, buttongroup, togglegroup, listview, calendar, contextmenu, tabitem, menubar
15
+ )
16
+
17
+ # Import all builder modules to trigger registration
18
+
19
+ __all__ = [
20
+ 'badge',
21
+ 'button',
22
+ 'expander',
23
+ 'frame',
24
+ 'label',
25
+ 'sidenav',
26
+ 'radiobutton',
27
+ 'checkbutton',
28
+ 'switch',
29
+ 'progressbar',
30
+ 'scale',
31
+ 'scrollbar',
32
+ 'menubutton',
33
+ 'entry',
34
+ 'field',
35
+ 'separator',
36
+ 'combobox',
37
+ 'labelframe',
38
+ 'panedwindow',
39
+ 'sizegrip',
40
+ 'spinbox',
41
+ 'treeview',
42
+ 'toolbutton',
43
+ 'tooltip',
44
+ 'buttongroup',
45
+ 'togglegroup',
46
+ 'listview',
47
+ 'calendar',
48
+ 'contextmenu',
49
+ 'menubar',
50
+ 'tabitem'
51
+ ]
@@ -0,0 +1,46 @@
1
+ """Badge style builders.
2
+
3
+ This module contains style builders for ttk.Label widget badge variants.
4
+ """
5
+ from typing import Optional
6
+
7
+ from bootstack.style.style_builder_ttk import StyleBuilderTtk
8
+ from bootstack.style.element import Element, ElementImage
9
+ from bootstack.style.utility import recolor_element_image
10
+
11
+
12
+ @StyleBuilderTtk.register_builder('square', 'TBadge')
13
+ def build_default_badge_style(b: StyleBuilderTtk, ttk_style: str, accent: Optional[str] = None, **options):
14
+ build_badge(b, ttk_style, accent, 'square', **options)
15
+
16
+ @StyleBuilderTtk.register_builder('pill', 'TBadge')
17
+ def build_pill_badge_style(b: StyleBuilderTtk, ttk_style: str, accent: Optional[str] = None, **options):
18
+ build_badge(b, ttk_style, accent, 'pill', **options)
19
+
20
+
21
+ def build_badge(b: StyleBuilderTtk, ttk_style: str, accent: Optional[str] = None, variant: str = 'square', **options):
22
+ """Create a badge style for the variant specified"""
23
+
24
+ surface_token = options.get('surface', 'content')
25
+ surface = b.color(surface_token)
26
+ normal = b.color(accent or 'primary')
27
+ foreground = b.on_color(normal)
28
+
29
+ badge_img = recolor_element_image(f'badge_{variant}', normal, normal, surface, surface)
30
+
31
+ b.create_style_element_image(ElementImage(f'{ttk_style}.border', badge_img.image,
32
+ border=badge_img.meta.border,
33
+ padding=badge_img.meta.padding,
34
+ height=badge_img.meta.height,
35
+ sticky='nsew'))
36
+
37
+ b.create_style_layout(
38
+ ttk_style, Element(f"{ttk_style}.border", sticky="nsew").children(
39
+ [
40
+ Element("Label.padding", sticky="nsew").children(
41
+ [
42
+ Element("Label.label", sticky="ew")
43
+ ])
44
+ ]))
45
+
46
+ b.configure_style(ttk_style, background=surface, foreground=foreground, padding=(6, 0))