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,249 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ from bootstack.widgets._impl.primitives.frame import Frame
6
+ from bootstack.widgets._impl.primitives.flexframe import FlexFrame
7
+ from bootstack.widgets._core.base import PublicWidgetBase
8
+ from bootstack.widgets._core.container import FlexContainer
9
+ from bootstack.widgets.types import (
10
+ AccentToken, SurfaceToken, HAlign, VAlign, HArrange, VArrange, Padding,
11
+ )
12
+
13
+
14
+ class _FlexBase(FlexContainer):
15
+ _direction: str # set by subclass
16
+
17
+ def __init__(
18
+ self,
19
+ *,
20
+ parent: Any = None,
21
+ horizontal_items: str = "left",
22
+ vertical_items: str = "top",
23
+ grow_items: bool = False,
24
+ weights: list[int] | None = None,
25
+ gap: int = 0,
26
+ padding: Padding | None = None,
27
+ surface: SurfaceToken | AccentToken | str | None = None,
28
+ show_border: bool = False,
29
+ width: int | None = None,
30
+ height: int | None = None,
31
+ **kwargs: Any,
32
+ ) -> None:
33
+ # Shared implementation for Row/Column. Each subclass declares its own
34
+ # __init__ so Sphinx renders the (axis-specific) params and value types
35
+ # per class.
36
+ self._parent = self._resolve_parent(parent)
37
+ layout_kw = self._split_layout_kwargs(kwargs)
38
+
39
+ frame_kwargs: dict[str, Any] = {
40
+ "direction": self._direction,
41
+ "horizontal_items": horizontal_items,
42
+ "vertical_items": vertical_items,
43
+ "grow_items": grow_items,
44
+ "weights": weights,
45
+ "gap": gap,
46
+ }
47
+ if padding is not None:
48
+ frame_kwargs["padding"] = padding
49
+ if surface is not None:
50
+ frame_kwargs["surface"] = surface
51
+ if show_border:
52
+ frame_kwargs["show_border"] = show_border
53
+ if width is not None:
54
+ frame_kwargs["width"] = width
55
+ if height is not None:
56
+ frame_kwargs["height"] = height
57
+ if width is not None or height is not None:
58
+ frame_kwargs["propagate"] = False
59
+
60
+ tk_master = self._parent._child_master() if self._parent else None
61
+ self._internal = FlexFrame(tk_master, **frame_kwargs)
62
+ self._attach_to_parent(layout_kw)
63
+
64
+
65
+ class Row(_FlexBase):
66
+ """Lays out children left to right along the horizontal axis.
67
+
68
+ Children flow in order. Position them on each screen axis: `horizontal_items`
69
+ *arranges the group* along the row (`'left'`/`'center'`/`'right'` or a
70
+ `'space-*'` mode), `vertical_items` *aligns* them up and down
71
+ (`'top'`/`'center'`/`'bottom'`/`'stretch'`), and `grow` / `weights` let
72
+ children share the available width. Drop a `Spacer` between children to push a
73
+ group aside without nesting.
74
+
75
+ Example::
76
+
77
+ with bs.Row(gap=8, vertical_items="center"):
78
+ bs.Label("Name:")
79
+ bs.TextField(grow=1)
80
+
81
+ Args:
82
+ horizontal_items: How the whole group of children is arranged along the
83
+ row — `'left'`, `'center'`, `'right'`, or the `'space-*'` modes. Has
84
+ no effect once any child grows. Defaults to `'left'`.
85
+ vertical_items: Vertical alignment of children — `'top'`, `'center'`,
86
+ `'bottom'`, or `'stretch'` (fill the row's height). Override per child
87
+ with `vertical`. Defaults to `'center'`.
88
+ grow_items: When `True`, every child grows equally to fill the row.
89
+ Defaults to `False`.
90
+ weights: Explicit per-child width weights (e.g. `[1, 2, 1]`) — shorthand
91
+ for setting `grow` on each child positionally. Overrides `grow_items`
92
+ and per-child `grow`. Defaults to `None`.
93
+ gap: Spacing in pixels between adjacent children. Defaults to `0`.
94
+ padding: Space in pixels between the row border and its content. Defaults
95
+ to `None` (no padding).
96
+ surface: Background token. Accepts a surface token, an accent token, or
97
+ any token with modifiers (e.g. `'primary[subtle]'`). Defaults to
98
+ `None` (inherits from parent surface).
99
+ show_border: When `True`, draws a 1 px border around the row frame.
100
+ Defaults to `False`.
101
+ width: Fixed width in pixels. Disables frame propagation so children
102
+ cannot resize the container. Defaults to `None` (size from children).
103
+ height: Fixed height in pixels. Disables frame propagation so children
104
+ cannot resize the container. Defaults to `None` (size from children).
105
+ parent: Override the context-stack parent widget.
106
+ **kwargs: Per-child placement options — `grow` (`bool | int`: `grow=True`
107
+ fills the leftover width with weight 1, `grow=N` takes N shares),
108
+ `vertical` (this child's vertical alignment: `'top'`/`'center'`/
109
+ `'bottom'`/`'stretch'`), `margin`, `index`. See :doc:`/tasks/layout`.
110
+ """
111
+ _direction = "horizontal"
112
+
113
+ def __init__(
114
+ self,
115
+ *,
116
+ parent: Any = None,
117
+ horizontal_items: HArrange = "left",
118
+ vertical_items: VAlign = "center",
119
+ grow_items: bool = False,
120
+ weights: list[int] | None = None,
121
+ gap: int = 0,
122
+ padding: Padding | None = None,
123
+ surface: SurfaceToken | AccentToken | str | None = None,
124
+ show_border: bool = False,
125
+ width: int | None = None,
126
+ height: int | None = None,
127
+ **kwargs: Any,
128
+ ) -> None:
129
+ super().__init__(
130
+ parent=parent, horizontal_items=horizontal_items,
131
+ vertical_items=vertical_items, grow_items=grow_items, weights=weights,
132
+ gap=gap, padding=padding, surface=surface, show_border=show_border,
133
+ width=width, height=height, **kwargs,
134
+ )
135
+
136
+
137
+ class Column(_FlexBase):
138
+ """Lays out children top to bottom along the vertical axis.
139
+
140
+ Children flow in order. Position them on each screen axis: `vertical_items`
141
+ *arranges the group* down the column (`'top'`/`'center'`/`'bottom'` or a
142
+ `'space-*'` mode), `horizontal_items` *aligns* them left and right
143
+ (`'left'`/`'center'`/`'right'`/`'stretch'`), and `grow` / `weights` let
144
+ children share the available height. Use `horizontal_items='stretch'` for a
145
+ full-width form column.
146
+
147
+ Example::
148
+
149
+ with bs.Column(gap=12, horizontal_items="stretch", padding=16):
150
+ bs.Label("Title", font="heading-md")
151
+ bs.TextField()
152
+ bs.Button("Submit", accent="primary")
153
+
154
+ Args:
155
+ horizontal_items: Horizontal alignment of children — `'left'`,
156
+ `'center'`, `'right'`, or `'stretch'` (fill the column's width).
157
+ Override per child with `horizontal`. Defaults to `'center'`.
158
+ vertical_items: How the whole group of children is arranged down the
159
+ column — `'top'`, `'center'`, `'bottom'`, or the `'space-*'` modes.
160
+ Has no effect once any child grows. Defaults to `'top'`.
161
+ grow_items: When `True`, every child grows equally to fill the column.
162
+ Defaults to `False`.
163
+ weights: Explicit per-child height weights (e.g. `[1, 2, 1]`) — shorthand
164
+ for setting `grow` on each child positionally. Overrides `grow_items`
165
+ and per-child `grow`. Defaults to `None`.
166
+ gap: Spacing in pixels between adjacent children. Defaults to `0`.
167
+ padding: Space in pixels between the column border and its content.
168
+ Defaults to `None` (no padding).
169
+ surface: Background token. Accepts a surface token, an accent token, or
170
+ any token with modifiers (e.g. `'primary[subtle]'`). Defaults to
171
+ `None` (inherits from parent surface).
172
+ show_border: When `True`, draws a 1 px border around the column frame.
173
+ Defaults to `False`.
174
+ width: Fixed width in pixels. Disables frame propagation so children
175
+ cannot resize the container. Defaults to `None` (size from children).
176
+ height: Fixed height in pixels. Disables frame propagation so children
177
+ cannot resize the container. Defaults to `None` (size from children).
178
+ parent: Override the context-stack parent widget.
179
+ **kwargs: Per-child placement options — `grow` (`bool | int`: `grow=True`
180
+ fills the leftover height with weight 1, `grow=N` takes N shares),
181
+ `horizontal` (this child's horizontal alignment: `'left'`/`'center'`/
182
+ `'right'`/`'stretch'`), `margin`, `index`. See :doc:`/tasks/layout`.
183
+ """
184
+ _direction = "vertical"
185
+
186
+ def __init__(
187
+ self,
188
+ *,
189
+ parent: Any = None,
190
+ horizontal_items: HAlign = "center",
191
+ vertical_items: VArrange = "top",
192
+ grow_items: bool = False,
193
+ weights: list[int] | None = None,
194
+ gap: int = 0,
195
+ padding: Padding | None = None,
196
+ surface: SurfaceToken | AccentToken | str | None = None,
197
+ show_border: bool = False,
198
+ width: int | None = None,
199
+ height: int | None = None,
200
+ **kwargs: Any,
201
+ ) -> None:
202
+ super().__init__(
203
+ parent=parent, horizontal_items=horizontal_items,
204
+ vertical_items=vertical_items, grow_items=grow_items, weights=weights,
205
+ gap=gap, padding=padding, surface=surface, show_border=show_border,
206
+ width=width, height=height, **kwargs,
207
+ )
208
+
209
+
210
+ class Spacer(PublicWidgetBase):
211
+ """A composable break that pushes neighbors apart in a Row or Column.
212
+
213
+ Flexible by default — it absorbs the available stacking-axis space, so items
214
+ before it cluster at the start and items after it at the end. `Spacer(size=N)`
215
+ is instead a fixed N-pixel gap, and `Spacer(weight=N)` shares slack with
216
+ other spacers in proportion to their weights.
217
+
218
+ Unlike `horizontal_items`/`vertical_items` (which arrange the *whole* group),
219
+ a `Spacer` is a local break at one point — use it for clustered toolbars and
220
+ footers without nesting::
221
+
222
+ with bs.Row(gap=4):
223
+ bs.Button("New"); bs.Button("Open")
224
+ bs.Spacer()
225
+ bs.Button("Settings")
226
+
227
+ Args:
228
+ size: Fixed size in pixels. When set, the spacer is a rigid gap rather
229
+ than flexible slack. Defaults to `None` (flexible).
230
+ weight: Relative share of the leftover space when flexible. Ignored when
231
+ `size` is set. Defaults to `1`.
232
+ parent: Override the context-stack parent widget.
233
+ """
234
+
235
+ _is_spacer = True
236
+
237
+ def __init__(
238
+ self,
239
+ *,
240
+ size: int | None = None,
241
+ weight: int = 1,
242
+ parent: Any = None,
243
+ ) -> None:
244
+ self._parent = self._resolve_parent(parent)
245
+ self._spacer_size = size
246
+ self._spacer_weight = 0 if size is not None else weight
247
+ tk_master = self._parent._child_master() if self._parent else None
248
+ self._internal = Frame(tk_master, width=1, height=1)
249
+ self._attach_to_parent({})
@@ -0,0 +1,189 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Any, Literal
4
+
5
+ from bootstack.widgets._impl.composites.toolbar import Toolbar as _InternalToolbar
6
+ from bootstack.widgets._core.base import PublicWidgetBase
7
+ from bootstack.widgets.types import SurfaceToken, WidgetDensity
8
+
9
+ if TYPE_CHECKING:
10
+ from bootstack.signals import Signal
11
+
12
+
13
+ class StatusBar(PublicWidgetBase):
14
+ """A horizontal status band of passive segments — counts, sync state, a ready
15
+ message.
16
+
17
+ Intended for *passive* status (whether static or bound to a `Signal` for live
18
+ updates). Interactive controls (buttons, a search box) belong on a
19
+ :class:`Toolbar <bootstack.Toolbar>` by convention; nothing enforces it,
20
+ but the status bar reads best as a quiet display strip. Segments add
21
+ left-to-right; an `add_spacer()` (or `side='right'`) pushes the following
22
+ segments to the right cluster.
23
+
24
+ Use it standalone — `bs.StatusBar(horizontal="stretch")` spans the bottom of
25
+ any `App`/`Window` (place it last and let the content above `grow`) — or read
26
+ `shell.statusbar` for the one built
27
+ into an :class:`AppShell <bootstack.AppShell>`. Add widgets by class with
28
+ `add_widget()`, or create custom widgets with `parent=statusbar` (they add to
29
+ the left cluster automatically).
30
+
31
+ Args:
32
+ surface: Background surface token. Defaults to the theme's `'chrome'`
33
+ surface (a quiet band, distinct from the content area).
34
+ density: Size of the band's segments. Default `'compact'`.
35
+ padding: Inner padding in pixels — an int or a `(horizontal, vertical)`
36
+ tuple. Defaults to a thin compact padding.
37
+ parent: Override the context-stack parent.
38
+ **kwargs: Layout placement options applied by the parent container —
39
+ `fill`, `side`, `expand`, `anchor`, `margin`. See :doc:`/tasks/layout`.
40
+ """
41
+
42
+ _auto_place = True
43
+
44
+ def __init__(
45
+ self,
46
+ *,
47
+ surface: SurfaceToken | str | None = "chrome",
48
+ density: WidgetDensity = "compact",
49
+ padding: int | tuple[int, int] | None = None,
50
+ parent: Any = None,
51
+ _toolbar: Any = None,
52
+ _show: Any = None,
53
+ **kwargs: Any,
54
+ ) -> None:
55
+ self._has_right_spacer = False
56
+ if _toolbar is not None:
57
+ # Shell adoption: wrap the AppShell's pre-built status band. `_show`
58
+ # reveals the (content-driven) band on the first segment added.
59
+ self._internal = _toolbar
60
+ self._parent = None
61
+ self._show = _show or (lambda: None)
62
+ return
63
+
64
+ # Standalone: build our own bar (the Toolbar pattern).
65
+ self._parent = self._resolve_parent(parent)
66
+ layout_kw = self._split_layout_kwargs(kwargs)
67
+ tk_master = self._parent._child_master() if self._parent else None
68
+ internal_kwargs: dict[str, Any] = {"density": density, "draggable": False}
69
+ if surface is not None:
70
+ internal_kwargs["surface"] = surface
71
+ if padding is not None:
72
+ internal_kwargs["padding"] = padding
73
+ internal_kwargs.update(kwargs)
74
+ self._internal = _InternalToolbar(tk_master, **internal_kwargs)
75
+ self._attach_to_parent(layout_kw)
76
+ # Standalone bars are placed/shown by the caller — nothing to reveal.
77
+ self._show = lambda: None
78
+
79
+ # ----- Container protocol (so `parent=statusbar` works) -----
80
+
81
+ def _child_master(self) -> Any:
82
+ return self._internal.content
83
+
84
+ def guide_layout(self, child: Any, **layout_kw: Any) -> None:
85
+ # A widget created with `parent=statusbar` adds to the left cluster.
86
+ self._internal.add_widget(child._internal)
87
+ self._show()
88
+
89
+ @property
90
+ def content(self) -> Any:
91
+ """The band's content frame — parent custom widgets here."""
92
+ return self._internal.content
93
+
94
+ # ----- Segments -----
95
+
96
+ def _ensure_right(self) -> None:
97
+ if not self._has_right_spacer:
98
+ self._internal.add_spacer()
99
+ self._has_right_spacer = True
100
+
101
+ def add_widget(
102
+ self, widget_cls: Any, *, side: Literal["left", "right"] = "left", **kwargs: Any
103
+ ) -> Any:
104
+ """Build a widget on the left or right cluster from its class.
105
+
106
+ Pass a widget **class** — the bar builds it, applying its own `density`
107
+ and `surface` (for any the class accepts) so the widget matches the band,
108
+ and forwarding `kwargs` to the constructor:
109
+
110
+ status.add_widget(bs.ThemeToggle, side="right")
111
+ status.add_widget(bs.ProgressBar, value=65)
112
+
113
+ To add a widget you have already built yourself, parent it onto the bar
114
+ directly (it lands in the left cluster):
115
+
116
+ bs.MyCustomWidget(parent=status)
117
+
118
+ Args:
119
+ widget_cls: The widget class to build on the band.
120
+ side: `'left'` (default) or `'right'` (after the spacer).
121
+ **kwargs: Constructor arguments for the widget.
122
+
123
+ Returns:
124
+ The new widget instance.
125
+ """
126
+ if side == "right":
127
+ self._ensure_right()
128
+ self._apply_bar_defaults(widget_cls, kwargs)
129
+ return widget_cls(parent=self, **kwargs)
130
+
131
+ def _apply_bar_defaults(self, widget_cls: type, kwargs: dict[str, Any]) -> None:
132
+ """Default `density`/`surface` from the band onto a class being built, but
133
+ only for parameters the widget actually accepts (and not if the caller
134
+ already passed them)."""
135
+ import inspect
136
+
137
+ try:
138
+ params = inspect.signature(widget_cls).parameters
139
+ except (TypeError, ValueError):
140
+ return
141
+ if "density" in params:
142
+ kwargs.setdefault("density", self._internal.density)
143
+ if "surface" in params:
144
+ kwargs.setdefault("surface", self._internal._surface)
145
+
146
+ def add_text(
147
+ self,
148
+ text: str = "",
149
+ *,
150
+ textsignal: "Signal | None" = None,
151
+ side: Literal["left", "right"] = "left",
152
+ icon: str | None = None,
153
+ font: str | None = None,
154
+ ) -> None:
155
+ """Add a text (and optional icon) segment to a cluster.
156
+
157
+ Pass `textsignal` to make the segment **reactive** — a `Signal` whose
158
+ value drives the text and updates it live as the signal changes (e.g. a
159
+ running count or sync state). `text` seeds a static segment instead.
160
+
161
+ Args:
162
+ text: The static label text (ignored when `textsignal` is given).
163
+ textsignal: A reactive `Signal[str]` bound to the segment's text.
164
+ side: `'left'` (default) or `'right'` (after the spacer).
165
+ icon: Optional icon name displayed beside the text.
166
+ font: Optional font token, e.g. `'caption'`.
167
+ """
168
+ if side == "right":
169
+ self._ensure_right()
170
+ kwargs: dict[str, Any] = {"icon": icon, "font": font}
171
+ if textsignal is not None:
172
+ kwargs["textsignal"] = textsignal
173
+ self._internal.add_label(text, **kwargs)
174
+ self._show()
175
+
176
+ def add_spacer(self) -> None:
177
+ """Add a flexible spacer that pushes following items to the right."""
178
+ self._internal.add_spacer()
179
+ self._has_right_spacer = True
180
+ self._show()
181
+
182
+ def clear(self) -> None:
183
+ """Remove all status segments."""
184
+ for child in list(self._internal.content.winfo_children()):
185
+ try:
186
+ child.destroy()
187
+ except Exception:
188
+ pass
189
+ self._has_right_spacer = False