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,455 @@
1
+ """Utility functions for style builders.
2
+
3
+ This module provides common utilities used across builder functions,
4
+ including accent extraction, variant parsing, and style name manipulation.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from typing import TYPE_CHECKING, Any, Optional
10
+
11
+ from bootstack.style.element import Element
12
+
13
+ if TYPE_CHECKING:
14
+ from bootstack.style.style_builder_ttk import StyleBuilderTtk
15
+
16
+ # Standard bootstack color tokens
17
+ COLORS = {
18
+ 'primary', 'success', 'warning', 'danger', 'blue'
19
+ }
20
+
21
+
22
+ def extract_accent_from_style(ttk_style: str, default: str = 'primary') -> str:
23
+ """Extract accent token from TTK style name.
24
+
25
+ Args:
26
+ ttk_style: Full TTK style name (e.g., "custom_abc.success.Outline.TButton")
27
+ default: Default accent if none found
28
+
29
+ Returns:
30
+ Accent token name (e.g., "success")
31
+
32
+ Examples:
33
+ >>> extract_accent_from_style("success.Outline.TButton")
34
+ 'success'
35
+ >>> extract_accent_from_style("custom_abc.danger.TLabel")
36
+ 'danger'
37
+ >>> extract_accent_from_style("TButton")
38
+ 'primary'
39
+ """
40
+ # Remove custom prefix if present
41
+ parts = ttk_style.split('.')
42
+ if parts and parts[0].startswith('custom_'):
43
+ parts = parts[1:]
44
+
45
+ # Find accent in parts
46
+ for part in parts:
47
+ if part.lower() in COLORS:
48
+ return part.lower()
49
+
50
+ return default
51
+
52
+
53
+ def extract_variant_from_style(ttk_style: str) -> Optional[str]:
54
+ """Extract variant name from TTK style name.
55
+
56
+ Args:
57
+ ttk_style: Full TTK style name (e.g., "success.Outline.TButton")
58
+
59
+ Returns:
60
+ Variant name (lowercase) or None
61
+
62
+ Examples:
63
+ >>> extract_variant_from_style("success.Outline.TButton")
64
+ 'outline'
65
+ >>> extract_variant_from_style("primary.TLabel") is None
66
+ True
67
+ """
68
+ parts = ttk_style.split('.')
69
+
70
+ # Remove custom prefix if present
71
+ if parts and parts[0].startswith('custom_'):
72
+ parts = parts[1:]
73
+
74
+ # Find variant (not accent, not widget class)
75
+ for part in parts:
76
+ part_lower = part.lower()
77
+ if part_lower not in COLORS and not part.startswith('T'):
78
+ return part_lower
79
+
80
+ return None
81
+
82
+
83
+ def extract_widget_class_from_style(ttk_style: str) -> Optional[str]:
84
+ """Extract widget class from TTK style name.
85
+
86
+ Args:
87
+ ttk_style: Full TTK style name (e.g., "success.Outline.TButton")
88
+
89
+ Returns:
90
+ Widget class name or None
91
+
92
+ Examples:
93
+ >>> extract_widget_class_from_style("success.Outline.TButton")
94
+ 'TButton'
95
+ >>> extract_widget_class_from_style("primary.TLabel")
96
+ 'TLabel'
97
+ """
98
+ parts = ttk_style.split('.')
99
+
100
+ # Find widget class (starts with 'T')
101
+ for part in parts:
102
+ if part.startswith('T'):
103
+ return part
104
+
105
+ return None
106
+
107
+
108
+ def parse_style_components(ttk_style: str) -> dict:
109
+ """Parse TTK style name into all components.
110
+
111
+ Args:
112
+ ttk_style: Full TTK style name
113
+
114
+ Returns:
115
+ Dictionary with parsed components:
116
+ {
117
+ 'custom_prefix': 'custom_abc123' or None,
118
+ 'accent': 'success' or default,
119
+ 'variant': 'outline' or None,
120
+ 'widget_class': 'TButton'
121
+ }
122
+
123
+ Examples:
124
+ >>> parse_style_components("custom_abc.success.Outline.TButton")
125
+ {'custom_prefix': 'custom_abc', 'accent': 'success', 'variant': 'outline', 'widget_class': 'TButton'}
126
+ >>> parse_style_components("danger.TLabel")
127
+ {'custom_prefix': None, 'accent': 'danger', 'variant': None, 'widget_class': 'TLabel'}
128
+ """
129
+ parts = ttk_style.split('.')
130
+
131
+ # Check for custom prefix
132
+ custom_prefix = None
133
+ if parts and parts[0].startswith('custom_'):
134
+ custom_prefix = parts[0]
135
+
136
+ return {
137
+ 'custom_prefix': custom_prefix,
138
+ 'accent': extract_accent_from_style(ttk_style),
139
+ 'variant': extract_variant_from_style(ttk_style),
140
+ 'widget_class': extract_widget_class_from_style(ttk_style),
141
+ }
142
+
143
+
144
+ # Button utilities
145
+ # These utilities are used by button style builders and can be reused by other widgets.
146
+
147
+ # Valid button densities: 'default' (normal) and 'compact' (smaller/tighter)
148
+ BUTTON_DENSITIES = {'default', 'compact'}
149
+
150
+
151
+ def normalize_button_density(density: str) -> str:
152
+ """Normalize button density to valid values ('default' or 'compact').
153
+
154
+ Args:
155
+ density: The requested button density.
156
+
157
+ Returns:
158
+ 'compact' for compact buttons, 'default' for all other densities.
159
+ """
160
+ return 'compact' if density == 'compact' else 'default'
161
+
162
+
163
+ def button_layout(ttk_style: str) -> Element:
164
+ """Create the standard button element layout.
165
+
166
+ Args:
167
+ ttk_style: The TTK style name prefix for the button.
168
+
169
+ Returns:
170
+ Element tree representing the button layout.
171
+ """
172
+ return Element(f"{ttk_style}.Button.border", sticky="nsew").children(
173
+ [
174
+ Element("Button.padding", sticky="nsew").children(
175
+ [
176
+ Element("Button.label", sticky="nsew")
177
+ ])
178
+ ])
179
+
180
+
181
+ def toolbutton_layout(ttk_style: str) -> Element:
182
+ """Create the standard toolbutton element layout.
183
+
184
+ Args:
185
+ ttk_style: The TTK style name prefix for the toolbutton.
186
+
187
+ Returns:
188
+ Element tree representing the toolbutton layout.
189
+ """
190
+ return Element(f"{ttk_style}.border", sticky="nsew").children(
191
+ [
192
+ Element("Toolbutton.padding", sticky="nsew").children(
193
+ [
194
+ Element("Toolbutton.label", sticky="nsew")
195
+ ])
196
+ ])
197
+
198
+
199
+ def icon_size(icon_only: bool, density: str) -> int:
200
+ """Determine icon size based on button density and icon_only flag.
201
+
202
+ Args:
203
+ icon_only: Whether the button displays only an icon (no text).
204
+ density: The button density ('default' or 'compact').
205
+
206
+ Returns:
207
+ The icon size in pixels.
208
+ """
209
+ from tkinter import font
210
+
211
+ if icon_only:
212
+ return 20 if density != 'compact' else 17
213
+
214
+ # Size the icon to the label's cap height (font ascent) for alignment.
215
+ # Different buffers compensate for y_bias effect per density.
216
+ font_name = 'caption' if density == 'compact' else 'body'
217
+ f = font.nametofont(font_name)
218
+ buffer = 4 if density == 'compact' else 3
219
+ ascent = f.metrics()['ascent'] + buffer
220
+
221
+ # The ascent is already in physical pixels (named Tk fonts render at the
222
+ # current scaling), but this value is handed to normalize_icon_spec, which
223
+ # re-applies DPI scaling. Return the logical size (divide the scaling back
224
+ # out) so the icon is scaled exactly once and tracks the cap height at any
225
+ # DPI, instead of double-scaling to ~ui_scale x too large (#305).
226
+ from bootstack._runtime.utility import _ScalingState
227
+ ui_scale = _ScalingState.get_ui_scale() or 1.0
228
+ return round(ascent / ui_scale)
229
+
230
+
231
+ def button_font(density: str) -> str:
232
+ """Get the font token for a button based on its density.
233
+
234
+ Args:
235
+ density: The button density ('default' or 'compact').
236
+
237
+ Returns:
238
+ The font token name.
239
+ """
240
+ return 'caption' if density == 'compact' else 'body'
241
+
242
+
243
+ def button_height(b: StyleBuilderTtk, density: str) -> int:
244
+ """Get button height based on density, matching the total height of input fields.
245
+
246
+ Args:
247
+ b: The style builder instance.
248
+ density: The button density ('default' or 'compact').
249
+
250
+ Returns:
251
+ Scaled height in pixels.
252
+ """
253
+ return b.scale(37) if density == 'compact' else b.scale(43)
254
+
255
+
256
+ def button_padding(b: StyleBuilderTtk, icon_only: bool, density: Any) -> int | tuple[int, ...]:
257
+ """Calculate button padding based on options.
258
+
259
+ Args:
260
+ b: The style builder instance.
261
+ icon_only: Whether the button displays only an icon.
262
+ density: The button density ('default' or 'compact').
263
+
264
+ Returns:
265
+ Padding value (0 for icon_only, scaled tuple otherwise).
266
+ """
267
+ if icon_only:
268
+ return b.scale((2, 3, 2, 3)) if density == 'compact' else 0
269
+ if density == 'compact':
270
+ # (left, top, right, bottom) - extra top padding to center text
271
+ return b.scale((6, 5, 6, 3))
272
+ return b.scale((8, 0))
273
+
274
+
275
+ def resolve_icon_spec(options: dict) -> 'str | dict | None':
276
+ """Resolve on_icon/off_icon/icon kwargs into a unified icon spec.
277
+
278
+ Handles the three icon kwargs accepted by toggle-style widgets:
279
+ - icon: base icon for all states (color changes with state)
280
+ - off_icon: icon for the unselected/off state
281
+ - on_icon: icon for the selected/on state
282
+
283
+ Returns an IconSpec dict (or plain name string) suitable for passing
284
+ to normalize_icon_spec, or None if no icon was provided.
285
+ """
286
+ on_icon = options.get('on_icon')
287
+ off_icon = options.get('off_icon')
288
+ icon = options.get('icon')
289
+
290
+ if not on_icon and not off_icon:
291
+ return icon # None, str, or full IconSpec dict
292
+
293
+ base = off_icon or icon or on_icon
294
+ spec: dict = {'name': base}
295
+ if on_icon:
296
+ spec['state'] = [('selected', on_icon)]
297
+ return spec
298
+
299
+
300
+ def apply_icon_mapping(
301
+ b: StyleBuilderTtk,
302
+ options: dict,
303
+ state_spec: dict,
304
+ default_size: int | None = None
305
+ ) -> dict:
306
+ """Apply icon mapping to a state specification dictionary.
307
+
308
+ Args:
309
+ b: The style builder instance.
310
+ options: Style options dictionary containing 'icon', 'on_icon', 'off_icon',
311
+ and 'icon_only' keys.
312
+ state_spec: The state specification dictionary to update.
313
+ default_size: Default icon size, or None to use normalize_icon_spec defaults.
314
+
315
+ Returns:
316
+ Updated state_spec with icon mappings applied.
317
+ """
318
+ icon = resolve_icon_spec(options)
319
+ if icon is None:
320
+ return state_spec
321
+
322
+ if default_size is None:
323
+ icon = b.normalize_icon_spec(icon)
324
+ else:
325
+ icon = b.normalize_icon_spec(icon, default_size)
326
+
327
+ state_spec['image'] = b.map_stateful_icons(icon, state_spec['foreground'])
328
+ # Set compound to 'left' so text is visible alongside the icon
329
+ icon_only = options.get('icon_only', False)
330
+ if not icon_only:
331
+ state_spec['compound'] = 'left'
332
+ return state_spec
333
+
334
+
335
+ # Entry/Field utilities
336
+ # These utilities are used by entry-type style builders (Entry, Combobox, Spinbox, Field).
337
+
338
+ def entry_font(density: str) -> str:
339
+ """Get the font for an entry widget based on its density.
340
+
341
+ Args:
342
+ density: The entry density ('default' or 'compact').
343
+
344
+ Returns:
345
+ The Tk font name.
346
+ """
347
+ from bootstack.style.typography import get_font
348
+ font_token = 'caption' if density == 'compact' else 'body'
349
+ return str(get_font(font_token))
350
+
351
+
352
+ def entry_padding(b: StyleBuilderTtk, density: str) -> tuple:
353
+ """Get entry padding based on density.
354
+
355
+ Args:
356
+ b: The style builder instance.
357
+ density: The entry density ('default' or 'compact').
358
+
359
+ Returns:
360
+ Scaled padding tuple (horizontal, vertical).
361
+ """
362
+ if density == 'compact':
363
+ return b.scale((6, 0))
364
+ return b.scale((6, 0))
365
+
366
+ def field_height(b: StyleBuilderTtk, density: str) -> int:
367
+ """Get entry element height based on density.
368
+
369
+ Args:
370
+ b: The style builder instance.
371
+ density: The entry density ('default' or 'compact').
372
+
373
+ Returns:
374
+ Scaled height in pixels.
375
+ """
376
+ return b.scale(26) if density == 'compact' else b.scale(33)
377
+
378
+ def entry_height(b: StyleBuilderTtk, density: str) -> int:
379
+ """Get entry element height based on density.
380
+
381
+ Args:
382
+ b: The style builder instance.
383
+ density: The entry density ('default' or 'compact').
384
+
385
+ Returns:
386
+ Scaled height in pixels.
387
+ """
388
+ return b.scale(25) if density == 'compact' else b.scale(31)
389
+
390
+
391
+ def _snap_even(v: int) -> int:
392
+ return v if v % 2 == 0 else v + 1
393
+
394
+
395
+ def entry_icon_size(b: StyleBuilderTtk, density: str) -> int:
396
+ """Get icon size for entry widgets (chevrons, spinner arrows).
397
+
398
+ Args:
399
+ b: The style builder instance.
400
+ density: The entry density ('default' or 'compact').
401
+
402
+ Returns:
403
+ Scaled icon size in pixels, snapped to an even number.
404
+ """
405
+ return _snap_even(b.scale(12) if density == 'compact' else b.scale(14))
406
+
407
+
408
+ def entry_image_key(base: str, density: str) -> str:
409
+ """Get density-aware manifest key for entry elements.
410
+
411
+ Args:
412
+ base: Base key name (e.g., 'input', 'input_before', 'input_after').
413
+ density: The entry density ('default' or 'compact').
414
+
415
+ Returns:
416
+ Full manifest key with density suffix (e.g., 'input_default', 'input_compact').
417
+ """
418
+ return f'{base}_{density}'
419
+
420
+
421
+ def spinner_arrow_height(b: StyleBuilderTtk, density: str) -> int:
422
+ """Get height for spinner arrow elements based on density.
423
+
424
+ Args:
425
+ b: The style builder instance.
426
+ density: The entry density ('default' or 'compact').
427
+
428
+ Returns:
429
+ Scaled arrow height in pixels, snapped to an even number.
430
+ """
431
+ return _snap_even(b.scale(10) if density == 'compact' else b.scale(13))
432
+
433
+
434
+ def spinner_arrow_width(b: StyleBuilderTtk) -> int:
435
+ """Get width for spinner arrow elements.
436
+
437
+ Args:
438
+ b: The style builder instance.
439
+
440
+ Returns:
441
+ Scaled arrow width in pixels, snapped to an even number.
442
+ """
443
+ return _snap_even(b.scale(16))
444
+
445
+
446
+ def chevron_width(b: StyleBuilderTtk) -> int:
447
+ """Get width for combobox chevron element.
448
+
449
+ Args:
450
+ b: The style builder instance.
451
+
452
+ Returns:
453
+ Scaled chevron width in pixels, snapped to an even number.
454
+ """
455
+ return _snap_even(b.scale(16))
@@ -0,0 +1,16 @@
1
+ """Tk (legacy tkinter) widget builders for bootstack.
2
+
3
+ Importing this package registers default builder functions for common Tk
4
+ widgets using the StyleBuilderTk registry. Builders receive the actual
5
+ widget instance, plus theme/color utilities via the builder object.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ # Import defaults to trigger registration
11
+ from . import defaults # noqa: F401
12
+
13
+ __all__ = [
14
+ 'defaults',
15
+ ]
16
+
@@ -0,0 +1,229 @@
1
+ from __future__ import annotations
2
+
3
+ from typing_extensions import Any
4
+
5
+ from bootstack.style.style_builder_tk import StyleBuilderTk
6
+
7
+
8
+ @StyleBuilderTk.register_builder('Tk')
9
+ def build_tk_root(builder: StyleBuilderTk, widget: Any, **options: Any) -> None:
10
+ bg = builder.color(options.get('surface', 'content'))
11
+ widget.configure(background=bg)
12
+ widget.option_add('*Text*Font', 'TkDefaultFont')
13
+
14
+
15
+ @StyleBuilderTk.register_builder('Toplevel')
16
+ def build_tk_toplevel(builder: StyleBuilderTk, widget: Any, **options: Any) -> None:
17
+ bg = builder.color(options.get('surface', 'content'))
18
+ widget.configure(background=bg)
19
+
20
+
21
+ @StyleBuilderTk.register_builder('Frame')
22
+ def build_tk_frame(builder: StyleBuilderTk, widget: Any, **options: Any) -> None:
23
+ bg = builder.color(options.get('surface', 'content'))
24
+ widget.configure(background=bg)
25
+
26
+
27
+ @StyleBuilderTk.register_builder('Label')
28
+ def build_tk_label(builder: StyleBuilderTk, widget: Any, **options: Any) -> None:
29
+ bg = builder.color(options.get('surface', 'content'))
30
+ fg = builder.on_color(bg)
31
+ widget.configure(background=bg, foreground=fg)
32
+
33
+
34
+ @StyleBuilderTk.register_builder('Button')
35
+ def build_tk_button(builder: StyleBuilderTk, widget: Any, **options: Any) -> None:
36
+ bg = builder.color('primary')
37
+ fg = builder.on_color(bg)
38
+ widget.configure(
39
+ relief='flat',
40
+ background=bg,
41
+ activebackground=bg,
42
+ foreground=fg,
43
+ activeforeground=fg,
44
+ highlightbackground=bg,
45
+ )
46
+
47
+
48
+ @StyleBuilderTk.register_builder('Entry')
49
+ def build_tk_entry(builder: StyleBuilderTk, widget: Any, **options: Any) -> None:
50
+ bg = builder.color('background')
51
+ fg = builder.colors.get('foreground')
52
+ accent = builder.color('primary')
53
+ border = builder.border(bg)
54
+ widget.configure(
55
+ relief='flat',
56
+ highlightthickness=1,
57
+ highlightbackground=border,
58
+ highlightcolor=accent,
59
+ foreground=fg,
60
+ background=bg,
61
+ insertbackground=accent,
62
+ insertwidth=1
63
+ )
64
+
65
+
66
+ @StyleBuilderTk.register_builder('Text')
67
+ def build_tk_text(builder: StyleBuilderTk, widget: Any, **options: Any) -> None:
68
+ bg = builder.color('background')
69
+ fg = builder.colors.get('foreground')
70
+ border = builder.border(bg)
71
+ accent = builder.color('primary')
72
+ accent_fg = builder.on_color(accent)
73
+ widget.configure(
74
+ background=bg,
75
+ foreground=fg,
76
+ highlightcolor=accent,
77
+ highlightbackground=border,
78
+ highlightthickness=0,
79
+ insertbackground=fg,
80
+ selectbackground=accent,
81
+ selectforeground=accent_fg,
82
+ insertwidth=1,
83
+ relief='flat',
84
+ padx=5,
85
+ pady=5
86
+ )
87
+
88
+
89
+ @StyleBuilderTk.register_builder('Canvas')
90
+ def build_tk_canvas(builder: StyleBuilderTk, widget: Any, **options: Any) -> None:
91
+ bg = builder.color(options.get('surface', 'content'))
92
+ widget.configure(background=bg, highlightthickness=0)
93
+
94
+
95
+ @StyleBuilderTk.register_builder('Checkbutton')
96
+ def build_tk_checkbutton(builder: StyleBuilderTk, widget: Any, **options: Any) -> None:
97
+ bg = builder.color(options.get('surface', 'content'))
98
+ fg = builder.colors.get('foreground')
99
+ accent = builder.color('primary')
100
+ widget.configure(
101
+ activebackground=bg,
102
+ activeforeground=accent,
103
+ background=bg,
104
+ foreground=fg,
105
+ selectcolor=bg
106
+ )
107
+
108
+
109
+ @StyleBuilderTk.register_builder('Radiobutton')
110
+ def build_tk_radiobutton(builder: StyleBuilderTk, widget: Any, **options: Any) -> None:
111
+ accent = builder.color('primary')
112
+ bg = builder.color(options.get('surface', 'content'))
113
+ fg = builder.colors.get('foreground')
114
+ widget.configure(
115
+ background=bg,
116
+ foreground=fg,
117
+ activebackground=bg,
118
+ activeforeground=accent,
119
+ highlightbackground=bg,
120
+ selectcolor=bg
121
+ )
122
+
123
+
124
+ @StyleBuilderTk.register_builder('Scale')
125
+ def build_tk_scale(builder: StyleBuilderTk, widget: Any, **options: Any) -> None:
126
+ accent = builder.color('primary')
127
+ hover = builder.active(accent)
128
+ border = builder.color('border')
129
+ widget.configure(
130
+ background=accent,
131
+ showvalue=False,
132
+ sliderrelief='flat',
133
+ borderwidth=0,
134
+ activebackground=hover,
135
+ highlightthickness=1,
136
+ highlightcolor=border,
137
+ highlightbackground=border,
138
+ troughcolor=border
139
+ )
140
+
141
+
142
+ @StyleBuilderTk.register_builder('Listbox')
143
+ def build_tk_listbox(builder: StyleBuilderTk, widget: Any, **options: Any) -> None:
144
+ bg = builder.color('background')
145
+ fg = builder.color('foreground')
146
+ accent = builder.subtle('primary', bg)
147
+ on_accent = builder.on_color(accent)
148
+ border = builder.border(bg)
149
+ widget.configure(
150
+ foreground=fg,
151
+ background=bg,
152
+ selectbackground=accent,
153
+ selectforeground=on_accent,
154
+ highlightbackground=border,
155
+ highlightcolor=accent,
156
+ highlightthickness=1,
157
+ activestyle="none",
158
+ relief='flat'
159
+ )
160
+
161
+
162
+ @StyleBuilderTk.register_builder('Menu')
163
+ def build_tk_menu(builder: StyleBuilderTk, widget: Any, **options: Any) -> None:
164
+ bg = builder.color('background')
165
+ fg = builder.color('foreground')
166
+ accent = builder.elevate(bg, 2)
167
+ on_accent = builder.on_color(accent)
168
+
169
+ widget.configure(
170
+ tearoff=False,
171
+ borderwidth=1,
172
+ foreground=fg,
173
+ activeforeground=on_accent,
174
+ selectcolor=fg,
175
+ activebackground=accent,
176
+ background=bg,
177
+ )
178
+
179
+
180
+ @StyleBuilderTk.register_builder('Menubutton')
181
+ def build_tk_menubutton(builder: StyleBuilderTk, widget: Any, **options: Any) -> None:
182
+ bg = builder.color('primary')
183
+ fg = builder.on_color(bg)
184
+ hover = builder.active(bg)
185
+
186
+ widget.configure(
187
+ background=bg,
188
+ foreground=fg,
189
+ activebackground=hover,
190
+ activeforeground=fg,
191
+ borderwidth=0
192
+ )
193
+
194
+
195
+ @StyleBuilderTk.register_builder('Labelframe')
196
+ def build_tk_labelframe(builder: StyleBuilderTk, widget: Any, **options: Any) -> None:
197
+ bg = builder.color(options.get('surface', 'content'))
198
+ fg = builder.on_color(bg)
199
+ border = builder.border(bg)
200
+ widget.configure(
201
+ background=bg,
202
+ foreground=fg, # does not work on Aqua or Windows
203
+ borderwidth=1,
204
+ highlightthickness=0,
205
+ highlightcolor=border,
206
+ )
207
+
208
+
209
+ @StyleBuilderTk.register_builder('Spinbox')
210
+ def build_tk_spinbox(builder: StyleBuilderTk, widget: Any, **options: Any) -> None:
211
+ bg = builder.color('background')
212
+ fg = builder.color('foreground')
213
+ border = builder.border(bg)
214
+ accent = builder.subtle('primary', bg)
215
+ insert_background = builder.color('primary')
216
+
217
+ widget.configure(
218
+ relief='flat',
219
+ foreground=fg,
220
+ background=bg,
221
+ insertbackground=insert_background,
222
+ insertwidth=1,
223
+ highlightcolor=accent,
224
+ highlightthickness=1,
225
+ highlightbackground=border,
226
+ # button relief ignored by Windows and macOS
227
+ buttonuprelief='flat',
228
+ buttondownrelief='flat',
229
+ )