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,383 @@
1
+ from __future__ import annotations
2
+
3
+ import tkinter
4
+ from typing import overload, Any, Callable, TYPE_CHECKING
5
+
6
+ from bootstack.widgets._impl.composites.passwordentry import PasswordEntry as _InternalPasswordEntry
7
+ from bootstack.widgets._core.base import PublicWidgetBase, adapt_handler
8
+ from bootstack.widgets._core.events import resolve_event, register_widget_events
9
+ from bootstack.widgets._core.field_mixin import FieldAddonMixin
10
+ from bootstack.events import ChangeEvent, InputEvent, Subscription, ValidationEvent
11
+ from bootstack.streams import Stream
12
+ from bootstack.widgets.textfield import _INNER_ENTRY_SEQUENCES
13
+ from bootstack.widgets.types import AccentToken, Event, WidgetDensity
14
+
15
+ if TYPE_CHECKING:
16
+ from bootstack.signals import Signal
17
+
18
+ _PASSWORD_FIELD_EVENTS: dict[str, str] = {
19
+ "input": "<<Input>>",
20
+ "change": "<<Change>>",
21
+ "valid": "<<Valid>>",
22
+ "invalid": "<<Invalid>>",
23
+ "validate": "<<Validate>>",
24
+ "submit": "<Return>",
25
+ "focus": "<FocusIn>",
26
+ "blur": "<FocusOut>",
27
+ }
28
+
29
+
30
+ class PasswordField(FieldAddonMixin, PublicWidgetBase):
31
+ """A masked text field for password input with an optional visibility toggle.
32
+
33
+ The initial value is the first positional argument. All options are
34
+ keyword-only.
35
+
36
+ Args:
37
+ value: Initial password value (displayed masked).
38
+ placeholder: Ghost text shown when the field is empty and unfocused.
39
+ textsignal: Reactive `Signal[str]` bound to the field text. The
40
+ field value and signal stay in sync automatically.
41
+ label: Label displayed above the field.
42
+ message: Hint or helper text displayed below the field.
43
+ required: If `True`, marks the field as required and prevents empty
44
+ submission.
45
+ mask: Character used to mask each typed character. Defaults to
46
+ `'•'`.
47
+ show_visibility_toggle: If `True` (default), shows the eye-icon
48
+ button that reveals the password while held.
49
+ read_only: If `True`, text is visible and selectable but not
50
+ editable.
51
+ disabled: If `True`, field is fully non-interactive and dimmed.
52
+ width: Width in character units.
53
+ accent: Accent token applied to the focus ring.
54
+ density: Padding density.
55
+ parent: Explicit parent widget. If omitted, the current context-stack
56
+ container is used.
57
+ **kwargs: Layout placement options applied by the parent container —
58
+ `fill`, `expand`, `anchor`, `margin`, `row`, `column`, `sticky`.
59
+ See :doc:`/tasks/layout`.
60
+ """
61
+
62
+ def __init__(
63
+ self,
64
+ value: str = "",
65
+ *,
66
+ placeholder: str | None = None,
67
+ textsignal: "Signal[str] | None" = None,
68
+ label: str | None = None,
69
+ message: str | None = None,
70
+ required: bool = False,
71
+ mask: str = "•",
72
+ show_visibility_toggle: bool = True,
73
+ read_only: bool = False,
74
+ disabled: bool = False,
75
+ width: int | None = None,
76
+ accent: AccentToken | str | None = None,
77
+ density: WidgetDensity | None = None,
78
+ parent: Any = None,
79
+ **kwargs: Any,
80
+ ) -> None:
81
+ self._parent = self._resolve_parent(parent)
82
+ layout_kw = self._split_layout_kwargs(kwargs)
83
+ tk_master = self._parent._child_master() if self._parent else None
84
+
85
+ internal_kwargs: dict[str, Any] = {
86
+ "show": mask,
87
+ "show_visibility_toggle": show_visibility_toggle,
88
+ }
89
+ if value:
90
+ internal_kwargs["value"] = value
91
+ if placeholder is not None:
92
+ internal_kwargs["placeholder"] = placeholder
93
+ if textsignal is not None:
94
+ internal_kwargs["textsignal"] = textsignal
95
+ if label is not None:
96
+ internal_kwargs["label"] = label
97
+ if message is not None:
98
+ internal_kwargs["message"] = message
99
+ if required:
100
+ internal_kwargs["required"] = True
101
+ if disabled:
102
+ internal_kwargs["state"] = "disabled"
103
+ elif read_only:
104
+ internal_kwargs["state"] = "readonly"
105
+ if width is not None:
106
+ internal_kwargs["width"] = width
107
+ if accent is not None:
108
+ internal_kwargs["accent"] = accent
109
+ if density is not None:
110
+ internal_kwargs["density"] = density
111
+
112
+ self._internal = _InternalPasswordEntry(tk_master, **internal_kwargs)
113
+ self._attach_to_parent(layout_kw)
114
+
115
+ # ----- Event routing -----
116
+
117
+ def _entry_widget(self) -> tkinter.Misc:
118
+ return self._internal._entry
119
+
120
+ @overload
121
+ def on(self, event: str) -> Stream: ...
122
+ @overload
123
+ def on(self, event: str, handler: Callable[[Event], Any]) -> Subscription: ...
124
+ def on(self, event: str, handler: Callable[[Event], Any] | None = None) -> Stream | Subscription:
125
+ """Register a callback for an event by name.
126
+
127
+ A generic, string-keyed escape hatch — prefer the typed `on_*`
128
+ shorthands (e.g. `on_change`), which carry the precise payload type.
129
+ Called with no handler, returns a composable `Stream`; with a handler,
130
+ binds it and returns a `Subscription`.
131
+
132
+ Args:
133
+ event: Event name (for example `'change'` or `'focus'`).
134
+ handler: Called with the event payload. Omit to get a composable
135
+ :class:`~bootstack.streams.Stream` instead.
136
+
137
+ Returns:
138
+ A cancellable :class:`~bootstack.events.Subscription` when a handler
139
+ is given, otherwise a :class:`~bootstack.streams.Stream`.
140
+ """
141
+ sequence = resolve_event(self, str(event))
142
+ target = self._entry_widget() if sequence in _INNER_ENTRY_SEQUENCES else self._internal
143
+ if handler is None:
144
+ def _source(h):
145
+ t = self._entry_widget() if sequence in _INNER_ENTRY_SEQUENCES else self._internal
146
+ bid = t.bind(sequence, adapt_handler(h), add="+")
147
+ return Subscription(t, sequence, bid)
148
+ return Stream(self._internal, _source=_source)
149
+ bid = target.bind(sequence, adapt_handler(handler), add="+")
150
+ return Subscription(target, sequence, bid)
151
+
152
+ # ----- Properties -----
153
+
154
+ @property
155
+ def value(self) -> str:
156
+ """The current text value of the field (unmasked)."""
157
+ return self._internal.value
158
+
159
+ @value.setter
160
+ def value(self, v: str) -> None:
161
+ self._internal.value = v
162
+
163
+ @property
164
+ def signal(self) -> "Signal[str] | None":
165
+ """The reactive `Signal` bound to this field, or `None`."""
166
+ return getattr(self._internal, 'signal', None)
167
+
168
+ @property
169
+ def read_only(self) -> bool:
170
+ """Whether the field is visible but not editable."""
171
+ return str(self._entry_widget().cget("state")) == "readonly"
172
+
173
+ @read_only.setter
174
+ def read_only(self, v: bool) -> None:
175
+ self._internal.configure(state="readonly" if v else "normal")
176
+
177
+ @property
178
+ def disabled(self) -> bool:
179
+ """Whether the field is fully non-interactive."""
180
+ return str(self._entry_widget().cget("state")) == "disabled"
181
+
182
+ @disabled.setter
183
+ def disabled(self, v: bool) -> None:
184
+ self._internal.configure(state="disabled" if v else "normal")
185
+
186
+ # ----- Methods -----
187
+
188
+ def reveal(self) -> None:
189
+ """Remove character masking to show the password in plain text."""
190
+ self._internal.reveal()
191
+
192
+ def hide(self) -> None:
193
+ """Restore character masking."""
194
+ self._internal.hide()
195
+
196
+ def validate(self) -> bool:
197
+ """Run validation rules against the current value.
198
+
199
+ Returns:
200
+ `True` if all rules pass, `False` otherwise.
201
+ """
202
+ entry = self._internal._entry
203
+ return entry.validate(entry._get_validation_value(), trigger="manual")
204
+
205
+ def focus(self) -> None:
206
+ """Give keyboard focus to this field."""
207
+ self._entry_widget().focus_set()
208
+
209
+ def clear(self) -> None:
210
+ """Clear the field text."""
211
+ self._internal.value = ""
212
+
213
+ def select_all(self) -> None:
214
+ """Select all text in the field."""
215
+ self._entry_widget().selection_range(0, "end")
216
+
217
+ def select_range(self, start: int, end: int) -> None:
218
+ """Select text between `start` and `end` character positions.
219
+
220
+ Args:
221
+ start: Start index (0-based, inclusive).
222
+ end: End index (exclusive).
223
+ """
224
+ self._entry_widget().selection_range(start, end)
225
+
226
+ def insert(self, index: int, text: str) -> None:
227
+ """Insert `text` at `index`.
228
+
229
+ Args:
230
+ index: Character position to insert at.
231
+ text: Text to insert.
232
+ """
233
+ self._entry_widget().insert(index, text)
234
+
235
+ def delete(self, start: int, end: int | None = None) -> None:
236
+ """Delete characters from `start` to `end`.
237
+
238
+ Args:
239
+ start: Start index (inclusive).
240
+ end: End index (exclusive). If `None`, deletes to end of field.
241
+ """
242
+ self._entry_widget().delete(start, "end" if end is None else end)
243
+
244
+ # ----- Event shorthands -----
245
+
246
+ @overload
247
+ def on_input(self) -> Stream: ...
248
+ @overload
249
+ def on_input(self, handler: Callable[[InputEvent], Any]) -> Subscription: ...
250
+ def on_input(self, handler: Callable[[InputEvent], Any] | None = None) -> Stream | Subscription:
251
+ """Register a callback fired on every keystroke.
252
+
253
+ Args:
254
+ handler: Called with an :class:`~bootstack.events.InputEvent`. Omit to
255
+ get a composable :class:`~bootstack.streams.Stream` instead.
256
+
257
+ Returns:
258
+ A cancellable :class:`~bootstack.events.Subscription` when a
259
+ handler is given, otherwise a :class:`~bootstack.streams.Stream`.
260
+ """
261
+ return self.on("input", handler)
262
+
263
+ @overload
264
+ def on_change(self) -> Stream: ...
265
+ @overload
266
+ def on_change(self, handler: Callable[[ChangeEvent], Any]) -> Subscription: ...
267
+ def on_change(self, handler: Callable[[ChangeEvent], Any] | None = None) -> Stream | Subscription:
268
+ """Register a callback fired when the field value is committed.
269
+
270
+ Args:
271
+ handler: Called with a :class:`~bootstack.events.ChangeEvent`. Omit to
272
+ get a composable :class:`~bootstack.streams.Stream` instead.
273
+
274
+ Returns:
275
+ A cancellable :class:`~bootstack.events.Subscription` when a
276
+ handler is given, otherwise a :class:`~bootstack.streams.Stream`.
277
+ """
278
+ return self.on("change", handler)
279
+
280
+ @overload
281
+ def on_submit(self) -> Stream: ...
282
+ @overload
283
+ def on_submit(self, handler: Callable[[Event], Any]) -> Subscription: ...
284
+ def on_submit(self, handler: Callable[[Event], Any] | None = None) -> Stream | Subscription:
285
+ """Register a callback fired when the user presses Enter.
286
+
287
+ Args:
288
+ handler: Called with an :class:`~bootstack.events.Event`. Omit to
289
+ get a composable :class:`~bootstack.streams.Stream` instead.
290
+
291
+ Returns:
292
+ A cancellable :class:`~bootstack.events.Subscription` when a
293
+ handler is given, otherwise a :class:`~bootstack.streams.Stream`.
294
+ """
295
+ return self.on("submit", handler)
296
+
297
+ @overload
298
+ def on_focus(self) -> Stream: ...
299
+ @overload
300
+ def on_focus(self, handler: Callable[[Event], Any]) -> Subscription: ...
301
+ def on_focus(self, handler: Callable[[Event], Any] | None = None) -> Stream | Subscription:
302
+ """Register a callback fired when the field gains focus.
303
+
304
+ Args:
305
+ handler: Called with an :class:`~bootstack.events.Event`. Omit to
306
+ get a composable :class:`~bootstack.streams.Stream` instead.
307
+
308
+ Returns:
309
+ A cancellable :class:`~bootstack.events.Subscription` when a
310
+ handler is given, otherwise a :class:`~bootstack.streams.Stream`.
311
+ """
312
+ return self.on("focus", handler)
313
+
314
+ @overload
315
+ def on_blur(self) -> Stream: ...
316
+ @overload
317
+ def on_blur(self, handler: Callable[[Event], Any]) -> Subscription: ...
318
+ def on_blur(self, handler: Callable[[Event], Any] | None = None) -> Stream | Subscription:
319
+ """Register a callback fired when the field loses focus.
320
+
321
+ Args:
322
+ handler: Called with an :class:`~bootstack.events.Event`. Omit to
323
+ get a composable :class:`~bootstack.streams.Stream` instead.
324
+
325
+ Returns:
326
+ A cancellable :class:`~bootstack.events.Subscription` when a
327
+ handler is given, otherwise a :class:`~bootstack.streams.Stream`.
328
+ """
329
+ return self.on("blur", handler)
330
+
331
+ @overload
332
+ def on_valid(self) -> Stream: ...
333
+ @overload
334
+ def on_valid(self, handler: Callable[[ValidationEvent], Any]) -> Subscription: ...
335
+ def on_valid(self, handler: Callable[[ValidationEvent], Any] | None = None) -> Stream | Subscription:
336
+ """Register a callback fired when validation passes.
337
+
338
+ Args:
339
+ handler: Called with a :class:`~bootstack.events.ValidationEvent`. Omit to
340
+ get a composable :class:`~bootstack.streams.Stream` instead.
341
+
342
+ Returns:
343
+ A cancellable :class:`~bootstack.events.Subscription` when a
344
+ handler is given, otherwise a :class:`~bootstack.streams.Stream`.
345
+ """
346
+ return self.on("valid", handler)
347
+
348
+ @overload
349
+ def on_invalid(self) -> Stream: ...
350
+ @overload
351
+ def on_invalid(self, handler: Callable[[ValidationEvent], Any]) -> Subscription: ...
352
+ def on_invalid(self, handler: Callable[[ValidationEvent], Any] | None = None) -> Stream | Subscription:
353
+ """Register a callback fired when validation fails.
354
+
355
+ Args:
356
+ handler: Called with a :class:`~bootstack.events.ValidationEvent`. Omit to
357
+ get a composable :class:`~bootstack.streams.Stream` instead.
358
+
359
+ Returns:
360
+ A cancellable :class:`~bootstack.events.Subscription` when a
361
+ handler is given, otherwise a :class:`~bootstack.streams.Stream`.
362
+ """
363
+ return self.on("invalid", handler)
364
+
365
+ @overload
366
+ def on_validate(self) -> Stream: ...
367
+ @overload
368
+ def on_validate(self, handler: Callable[[ValidationEvent], Any]) -> Subscription: ...
369
+ def on_validate(self, handler: Callable[[ValidationEvent], Any] | None = None) -> Stream | Subscription:
370
+ """Register a callback fired after any validation run.
371
+
372
+ Args:
373
+ handler: Called with a :class:`~bootstack.events.ValidationEvent`. Omit to
374
+ get a composable :class:`~bootstack.streams.Stream` instead.
375
+
376
+ Returns:
377
+ A cancellable :class:`~bootstack.events.Subscription` when a
378
+ handler is given, otherwise a :class:`~bootstack.streams.Stream`.
379
+ """
380
+ return self.on("validate", handler)
381
+
382
+
383
+ register_widget_events(PasswordField, _PASSWORD_FIELD_EVENTS)