bootstack 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (471) hide show
  1. bootstack/__init__.py +157 -0
  2. bootstack/__main__.py +5 -0
  3. bootstack/_core/__init__.py +21 -0
  4. bootstack/_core/capabilities/__init__.py +45 -0
  5. bootstack/_core/capabilities/after.py +103 -0
  6. bootstack/_core/capabilities/bind.py +192 -0
  7. bootstack/_core/capabilities/bindtags.py +112 -0
  8. bootstack/_core/capabilities/busy.py +72 -0
  9. bootstack/_core/capabilities/clipboard.py +89 -0
  10. bootstack/_core/capabilities/focus.py +118 -0
  11. bootstack/_core/capabilities/grab.py +65 -0
  12. bootstack/_core/capabilities/grid.py +211 -0
  13. bootstack/_core/capabilities/localization.py +231 -0
  14. bootstack/_core/capabilities/pack.py +140 -0
  15. bootstack/_core/capabilities/place.py +113 -0
  16. bootstack/_core/capabilities/selection.py +136 -0
  17. bootstack/_core/capabilities/signals.py +244 -0
  18. bootstack/_core/capabilities/winfo.py +315 -0
  19. bootstack/_core/colorutils.py +234 -0
  20. bootstack/_core/exceptions.py +25 -0
  21. bootstack/_core/images.py +463 -0
  22. bootstack/_core/mixins/__init__.py +1 -0
  23. bootstack/_core/mixins/ttk_state.py +35 -0
  24. bootstack/_core/mixins/widget.py +132 -0
  25. bootstack/_core/paths.py +49 -0
  26. bootstack/_core/publisher.py +149 -0
  27. bootstack/_core/variables.py +62 -0
  28. bootstack/_runtime/__init__.py +3 -0
  29. bootstack/_runtime/app.py +930 -0
  30. bootstack/_runtime/base_window.py +945 -0
  31. bootstack/_runtime/events.py +399 -0
  32. bootstack/_runtime/shortcuts.py +496 -0
  33. bootstack/_runtime/tk_patch.py +43 -0
  34. bootstack/_runtime/toplevel.py +276 -0
  35. bootstack/_runtime/utility.py +457 -0
  36. bootstack/_runtime/visual_focus.py +240 -0
  37. bootstack/_runtime/window_utilities.py +1123 -0
  38. bootstack/assets/__init__.py +21 -0
  39. bootstack/assets/bootstack.ico +0 -0
  40. bootstack/assets/bootstack.png +0 -0
  41. bootstack/assets/elements/__init__.py +0 -0
  42. bootstack/assets/elements/badge-pill.png +0 -0
  43. bootstack/assets/elements/badge-square.png +0 -0
  44. bootstack/assets/elements/button-compact.png +0 -0
  45. bootstack/assets/elements/button-default.png +0 -0
  46. bootstack/assets/elements/buttongroup-after-h-compact.png +0 -0
  47. bootstack/assets/elements/buttongroup-after-h-default.png +0 -0
  48. bootstack/assets/elements/buttongroup-after-v-compact.png +0 -0
  49. bootstack/assets/elements/buttongroup-after-v-default.png +0 -0
  50. bootstack/assets/elements/buttongroup-before-h-compact.png +0 -0
  51. bootstack/assets/elements/buttongroup-before-h-default.png +0 -0
  52. bootstack/assets/elements/buttongroup-before-v-compact.png +0 -0
  53. bootstack/assets/elements/buttongroup-before-v-default.png +0 -0
  54. bootstack/assets/elements/buttongroup-center-h-compact.png +0 -0
  55. bootstack/assets/elements/buttongroup-center-h-default.png +0 -0
  56. bootstack/assets/elements/buttongroup-center-v-compact.png +0 -0
  57. bootstack/assets/elements/buttongroup-center-v-default.png +0 -0
  58. bootstack/assets/elements/card.png +0 -0
  59. bootstack/assets/elements/checkbox-checked.png +0 -0
  60. bootstack/assets/elements/checkbox-indeterminate.png +0 -0
  61. bootstack/assets/elements/checkbox-unchecked.png +0 -0
  62. bootstack/assets/elements/field.png +0 -0
  63. bootstack/assets/elements/input-addon-compact.png +0 -0
  64. bootstack/assets/elements/input-addon-default.png +0 -0
  65. bootstack/assets/elements/input-compact.png +0 -0
  66. bootstack/assets/elements/input-default.png +0 -0
  67. bootstack/assets/elements/list-item-separated.png +0 -0
  68. bootstack/assets/elements/list-item.png +0 -0
  69. bootstack/assets/elements/listrow-compact.png +0 -0
  70. bootstack/assets/elements/listrow-default.png +0 -0
  71. bootstack/assets/elements/manifest.toml +361 -0
  72. bootstack/assets/elements/menu-item.png +0 -0
  73. bootstack/assets/elements/navitem-compact.png +0 -0
  74. bootstack/assets/elements/navitem-default.png +0 -0
  75. bootstack/assets/elements/progressbar-h-compact.png +0 -0
  76. bootstack/assets/elements/progressbar-h-default.png +0 -0
  77. bootstack/assets/elements/progressbar-v-compact.png +0 -0
  78. bootstack/assets/elements/progressbar-v-default.png +0 -0
  79. bootstack/assets/elements/radiobutton.png +0 -0
  80. bootstack/assets/elements/scrollbar-horizontal.png +0 -0
  81. bootstack/assets/elements/scrollbar-vertical.png +0 -0
  82. bootstack/assets/elements/slider-handle.png +0 -0
  83. bootstack/assets/elements/slider-track-h.png +0 -0
  84. bootstack/assets/elements/slider-track-v.png +0 -0
  85. bootstack/assets/elements/switch-off.png +0 -0
  86. bootstack/assets/elements/switch-on.png +0 -0
  87. bootstack/assets/elements/tab-h.png +0 -0
  88. bootstack/assets/elements/tab-v.png +0 -0
  89. bootstack/assets/icons/bootstrap.ttf +0 -0
  90. bootstack/assets/icons/glyphmap.json +2080 -0
  91. bootstack/assets/icons/icon_metrics.json +12470 -0
  92. bootstack/assets/locales/ar/LC_MESSAGES/bootstack.mo +0 -0
  93. bootstack/assets/locales/ar/LC_MESSAGES/bootstack.po +856 -0
  94. bootstack/assets/locales/bg/LC_MESSAGES/bootstack.mo +0 -0
  95. bootstack/assets/locales/bg/LC_MESSAGES/bootstack.po +878 -0
  96. bootstack/assets/locales/cs/LC_MESSAGES/bootstack.mo +0 -0
  97. bootstack/assets/locales/cs/LC_MESSAGES/bootstack.po +856 -0
  98. bootstack/assets/locales/da/LC_MESSAGES/bootstack.mo +0 -0
  99. bootstack/assets/locales/da/LC_MESSAGES/bootstack.po +856 -0
  100. bootstack/assets/locales/de/LC_MESSAGES/bootstack.mo +0 -0
  101. bootstack/assets/locales/de/LC_MESSAGES/bootstack.po +856 -0
  102. bootstack/assets/locales/en/LC_MESSAGES/bootstack.mo +0 -0
  103. bootstack/assets/locales/en/LC_MESSAGES/bootstack.po +878 -0
  104. bootstack/assets/locales/es/LC_MESSAGES/bootstack.mo +0 -0
  105. bootstack/assets/locales/es/LC_MESSAGES/bootstack.po +856 -0
  106. bootstack/assets/locales/fr/LC_MESSAGES/bootstack.mo +0 -0
  107. bootstack/assets/locales/fr/LC_MESSAGES/bootstack.po +856 -0
  108. bootstack/assets/locales/he/LC_MESSAGES/bootstack.mo +0 -0
  109. bootstack/assets/locales/he/LC_MESSAGES/bootstack.po +854 -0
  110. bootstack/assets/locales/hi/LC_MESSAGES/bootstack.mo +0 -0
  111. bootstack/assets/locales/hi/LC_MESSAGES/bootstack.po +845 -0
  112. bootstack/assets/locales/it/LC_MESSAGES/bootstack.mo +0 -0
  113. bootstack/assets/locales/it/LC_MESSAGES/bootstack.po +844 -0
  114. bootstack/assets/locales/ja/LC_MESSAGES/bootstack.mo +0 -0
  115. bootstack/assets/locales/ja/LC_MESSAGES/bootstack.po +917 -0
  116. bootstack/assets/locales/ko/LC_MESSAGES/bootstack.mo +0 -0
  117. bootstack/assets/locales/ko/LC_MESSAGES/bootstack.po +845 -0
  118. bootstack/assets/locales/nb/LC_MESSAGES/bootstack.mo +0 -0
  119. bootstack/assets/locales/nb/LC_MESSAGES/bootstack.po +844 -0
  120. bootstack/assets/locales/nl/LC_MESSAGES/bootstack.mo +0 -0
  121. bootstack/assets/locales/nl/LC_MESSAGES/bootstack.po +844 -0
  122. bootstack/assets/locales/pl/LC_MESSAGES/bootstack.mo +0 -0
  123. bootstack/assets/locales/pl/LC_MESSAGES/bootstack.po +845 -0
  124. bootstack/assets/locales/pt/LC_MESSAGES/bootstack.mo +0 -0
  125. bootstack/assets/locales/pt/LC_MESSAGES/bootstack.po +845 -0
  126. bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.mo +0 -0
  127. bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.po +845 -0
  128. bootstack/assets/locales/sl/LC_MESSAGES/bootstack.mo +0 -0
  129. bootstack/assets/locales/sl/LC_MESSAGES/bootstack.po +845 -0
  130. bootstack/assets/locales/sv/LC_MESSAGES/bootstack.mo +0 -0
  131. bootstack/assets/locales/sv/LC_MESSAGES/bootstack.po +845 -0
  132. bootstack/assets/locales/tr/LC_MESSAGES/bootstack.mo +0 -0
  133. bootstack/assets/locales/tr/LC_MESSAGES/bootstack.po +845 -0
  134. bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.mo +0 -0
  135. bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.po +845 -0
  136. bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.mo +0 -0
  137. bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.po +845 -0
  138. bootstack/cli/__init__.py +133 -0
  139. bootstack/cli/__main__.py +6 -0
  140. bootstack/cli/add.py +395 -0
  141. bootstack/cli/appicon.py +285 -0
  142. bootstack/cli/build.py +115 -0
  143. bootstack/cli/config.py +313 -0
  144. bootstack/cli/demo.py +564 -0
  145. bootstack/cli/dev.py +153 -0
  146. bootstack/cli/doctor.py +195 -0
  147. bootstack/cli/icons.py +98 -0
  148. bootstack/cli/promote.py +120 -0
  149. bootstack/cli/pyinstaller.py +268 -0
  150. bootstack/cli/run.py +95 -0
  151. bootstack/cli/start.py +117 -0
  152. bootstack/cli/templates/__init__.py +931 -0
  153. bootstack/clipboard.py +48 -0
  154. bootstack/constants.py +318 -0
  155. bootstack/data/README.md +615 -0
  156. bootstack/data/__init__.py +78 -0
  157. bootstack/data/_observable.py +276 -0
  158. bootstack/data/base.py +780 -0
  159. bootstack/data/file_source.py +367 -0
  160. bootstack/data/memory_source.py +450 -0
  161. bootstack/data/query.py +367 -0
  162. bootstack/data/readers.py +289 -0
  163. bootstack/data/sqlite_source.py +869 -0
  164. bootstack/data/types.py +354 -0
  165. bootstack/data/writers.py +232 -0
  166. bootstack/dev/__init__.py +36 -0
  167. bootstack/dev/_capture.py +141 -0
  168. bootstack/dev/_env.py +43 -0
  169. bootstack/dev/_registry.py +140 -0
  170. bootstack/dev/_reloader.py +351 -0
  171. bootstack/dev/_reset.py +50 -0
  172. bootstack/dev/_watcher.py +91 -0
  173. bootstack/dialogs/__init__.py +948 -0
  174. bootstack/dialogs/_impl/__init__.py +47 -0
  175. bootstack/dialogs/_impl/colorchooser.py +588 -0
  176. bootstack/dialogs/_impl/datedialog.py +450 -0
  177. bootstack/dialogs/_impl/dialog.py +594 -0
  178. bootstack/dialogs/_impl/filterdialog.py +358 -0
  179. bootstack/dialogs/_impl/fontdialog.py +364 -0
  180. bootstack/dialogs/_impl/formdialog.py +564 -0
  181. bootstack/dialogs/_impl/message.py +486 -0
  182. bootstack/dialogs/_impl/query.py +570 -0
  183. bootstack/errors.py +67 -0
  184. bootstack/events/__init__.py +111 -0
  185. bootstack/events/_event.py +135 -0
  186. bootstack/events/_payloads.py +539 -0
  187. bootstack/events/_subscription.py +38 -0
  188. bootstack/i18n/README.md +77 -0
  189. bootstack/i18n/__init__.py +23 -0
  190. bootstack/i18n/catalog.py +121 -0
  191. bootstack/i18n/intl_format.py +584 -0
  192. bootstack/i18n/msgcat.py +425 -0
  193. bootstack/i18n/specs.py +156 -0
  194. bootstack/images.py +563 -0
  195. bootstack/py.typed +1 -0
  196. bootstack/scheduling/__init__.py +11 -0
  197. bootstack/scheduling/_schedule.py +218 -0
  198. bootstack/shortcuts.py +21 -0
  199. bootstack/signals/README.md +98 -0
  200. bootstack/signals/__init__.py +10 -0
  201. bootstack/signals/integration.py +100 -0
  202. bootstack/signals/signal.py +353 -0
  203. bootstack/signals/types.py +6 -0
  204. bootstack/store.py +286 -0
  205. bootstack/streams/__init__.py +12 -0
  206. bootstack/streams/_stream.py +321 -0
  207. bootstack/style/__init__.py +38 -0
  208. bootstack/style/builders/__init__.py +51 -0
  209. bootstack/style/builders/badge.py +46 -0
  210. bootstack/style/builders/button.py +339 -0
  211. bootstack/style/builders/buttongroup.py +311 -0
  212. bootstack/style/builders/calendar.py +271 -0
  213. bootstack/style/builders/checkbutton.py +110 -0
  214. bootstack/style/builders/combobox.py +113 -0
  215. bootstack/style/builders/contextmenu.py +268 -0
  216. bootstack/style/builders/entry.py +82 -0
  217. bootstack/style/builders/expander.py +148 -0
  218. bootstack/style/builders/field.py +335 -0
  219. bootstack/style/builders/frame.py +50 -0
  220. bootstack/style/builders/label.py +28 -0
  221. bootstack/style/builders/labelframe.py +34 -0
  222. bootstack/style/builders/listview.py +369 -0
  223. bootstack/style/builders/menubar.py +91 -0
  224. bootstack/style/builders/menubutton.py +359 -0
  225. bootstack/style/builders/panedwindow.py +25 -0
  226. bootstack/style/builders/progressbar.py +67 -0
  227. bootstack/style/builders/radiobutton.py +99 -0
  228. bootstack/style/builders/scale.py +64 -0
  229. bootstack/style/builders/scrollbar.py +225 -0
  230. bootstack/style/builders/separator.py +49 -0
  231. bootstack/style/builders/sidenav.py +643 -0
  232. bootstack/style/builders/sizegrip.py +15 -0
  233. bootstack/style/builders/spinbox.py +119 -0
  234. bootstack/style/builders/switch.py +70 -0
  235. bootstack/style/builders/tabitem.py +204 -0
  236. bootstack/style/builders/togglegroup.py +294 -0
  237. bootstack/style/builders/toolbutton.py +275 -0
  238. bootstack/style/builders/tooltip.py +26 -0
  239. bootstack/style/builders/treeview.py +193 -0
  240. bootstack/style/builders/utils.py +455 -0
  241. bootstack/style/builders_tk/__init__.py +16 -0
  242. bootstack/style/builders_tk/defaults.py +229 -0
  243. bootstack/style/element.py +173 -0
  244. bootstack/style/fonts.py +123 -0
  245. bootstack/style/style.py +609 -0
  246. bootstack/style/style_builder_base.py +716 -0
  247. bootstack/style/style_builder_mixed.py +93 -0
  248. bootstack/style/style_builder_tk.py +109 -0
  249. bootstack/style/style_builder_ttk.py +353 -0
  250. bootstack/style/style_resolver.py +447 -0
  251. bootstack/style/theme.py +245 -0
  252. bootstack/style/theme_provider.py +471 -0
  253. bootstack/style/themes/__init__.py +128 -0
  254. bootstack/style/tk_patch.py +5 -0
  255. bootstack/style/token_maps.py +41 -0
  256. bootstack/style/types.py +32 -0
  257. bootstack/style/typography.py +523 -0
  258. bootstack/style/utility.py +746 -0
  259. bootstack/types.py +39 -0
  260. bootstack/validation/__init__.py +6 -0
  261. bootstack/validation/types.py +15 -0
  262. bootstack/validation/validation_result.py +17 -0
  263. bootstack/validation/validation_rules.py +205 -0
  264. bootstack/widgets/__init__.py +74 -0
  265. bootstack/widgets/_core/__init__.py +31 -0
  266. bootstack/widgets/_core/app_config.py +266 -0
  267. bootstack/widgets/_core/base.py +461 -0
  268. bootstack/widgets/_core/container.py +334 -0
  269. bootstack/widgets/_core/context.py +35 -0
  270. bootstack/widgets/_core/events.py +130 -0
  271. bootstack/widgets/_core/field_mixin.py +353 -0
  272. bootstack/widgets/_core/icon_image_props.py +72 -0
  273. bootstack/widgets/_core/image_binding.py +93 -0
  274. bootstack/widgets/_core/navmodel.py +345 -0
  275. bootstack/widgets/_core/options.py +210 -0
  276. bootstack/widgets/_core/selection_group.py +130 -0
  277. bootstack/widgets/_core/window_controls.py +96 -0
  278. bootstack/widgets/_core/window_menu.py +246 -0
  279. bootstack/widgets/_impl/__init__.py +1 -0
  280. bootstack/widgets/_impl/_internal/__init__.py +0 -0
  281. bootstack/widgets/_impl/_internal/wrapper_base.py +307 -0
  282. bootstack/widgets/_impl/_parts/__init__.py +11 -0
  283. bootstack/widgets/_impl/_parts/numberentry_part.py +385 -0
  284. bootstack/widgets/_impl/_parts/spinnerentry_part.py +434 -0
  285. bootstack/widgets/_impl/_parts/textentry_part.py +406 -0
  286. bootstack/widgets/_impl/composites/__init__.py +33 -0
  287. bootstack/widgets/_impl/composites/_dateutils.py +33 -0
  288. bootstack/widgets/_impl/composites/_image_fit.py +105 -0
  289. bootstack/widgets/_impl/composites/accordion.py +381 -0
  290. bootstack/widgets/_impl/composites/avatar.py +191 -0
  291. bootstack/widgets/_impl/composites/buttongroup.py +371 -0
  292. bootstack/widgets/_impl/composites/calendar.py +972 -0
  293. bootstack/widgets/_impl/composites/carousel.py +567 -0
  294. bootstack/widgets/_impl/composites/chart.py +882 -0
  295. bootstack/widgets/_impl/composites/compositeframe.py +298 -0
  296. bootstack/widgets/_impl/composites/contextmenu.py +1951 -0
  297. bootstack/widgets/_impl/composites/dateentry.py +404 -0
  298. bootstack/widgets/_impl/composites/dropdownbutton.py +325 -0
  299. bootstack/widgets/_impl/composites/expander.py +515 -0
  300. bootstack/widgets/_impl/composites/field.py +670 -0
  301. bootstack/widgets/_impl/composites/form.py +1066 -0
  302. bootstack/widgets/_impl/composites/gallery.py +551 -0
  303. bootstack/widgets/_impl/composites/list/__init__.py +15 -0
  304. bootstack/widgets/_impl/composites/list/listitem.py +802 -0
  305. bootstack/widgets/_impl/composites/list/listview.py +1433 -0
  306. bootstack/widgets/_impl/composites/menu/__init__.py +18 -0
  307. bootstack/widgets/_impl/composites/menu/model.py +358 -0
  308. bootstack/widgets/_impl/composites/menu/render_native.py +134 -0
  309. bootstack/widgets/_impl/composites/menu/render_themed.py +134 -0
  310. bootstack/widgets/_impl/composites/meter.py +860 -0
  311. bootstack/widgets/_impl/composites/numericentry.py +201 -0
  312. bootstack/widgets/_impl/composites/pagestack.py +395 -0
  313. bootstack/widgets/_impl/composites/passwordentry.py +142 -0
  314. bootstack/widgets/_impl/composites/pathentry.py +168 -0
  315. bootstack/widgets/_impl/composites/picture.py +289 -0
  316. bootstack/widgets/_impl/composites/radiogroup.py +511 -0
  317. bootstack/widgets/_impl/composites/scrolledtext.py +375 -0
  318. bootstack/widgets/_impl/composites/scrolledtext.pyi +186 -0
  319. bootstack/widgets/_impl/composites/scrollview.py +764 -0
  320. bootstack/widgets/_impl/composites/selectbox.py +1026 -0
  321. bootstack/widgets/_impl/composites/shell/__init__.py +40 -0
  322. bootstack/widgets/_impl/composites/shell/content_host.py +52 -0
  323. bootstack/widgets/_impl/composites/shell/layout.py +335 -0
  324. bootstack/widgets/_impl/composites/shell/nav_panel.py +345 -0
  325. bootstack/widgets/_impl/composites/shell/providers.py +558 -0
  326. bootstack/widgets/_impl/composites/shell/rail.py +117 -0
  327. bootstack/widgets/_impl/composites/shell/shell.py +581 -0
  328. bootstack/widgets/_impl/composites/shell/workspace.py +273 -0
  329. bootstack/widgets/_impl/composites/sidenav/__init__.py +16 -0
  330. bootstack/widgets/_impl/composites/sidenav/header.py +81 -0
  331. bootstack/widgets/_impl/composites/sidenav/separator.py +44 -0
  332. bootstack/widgets/_impl/composites/slider/__init__.py +7 -0
  333. bootstack/widgets/_impl/composites/slider/_shared.py +195 -0
  334. bootstack/widgets/_impl/composites/slider/rangeslider.py +982 -0
  335. bootstack/widgets/_impl/composites/slider/slider.py +851 -0
  336. bootstack/widgets/_impl/composites/spinnerentry.py +185 -0
  337. bootstack/widgets/_impl/composites/tableview/__init__.py +5 -0
  338. bootstack/widgets/_impl/composites/tableview/tableview.py +3388 -0
  339. bootstack/widgets/_impl/composites/tableview/types.py +169 -0
  340. bootstack/widgets/_impl/composites/tabs/__init__.py +23 -0
  341. bootstack/widgets/_impl/composites/tabs/tabitem.py +389 -0
  342. bootstack/widgets/_impl/composites/tabs/tabs.py +974 -0
  343. bootstack/widgets/_impl/composites/tabs/tabview.py +650 -0
  344. bootstack/widgets/_impl/composites/textarea/__init__.py +26 -0
  345. bootstack/widgets/_impl/composites/textarea/change.py +46 -0
  346. bootstack/widgets/_impl/composites/textarea/codeeditor.py +526 -0
  347. bootstack/widgets/_impl/composites/textarea/core.py +495 -0
  348. bootstack/widgets/_impl/composites/textarea/decoration.py +42 -0
  349. bootstack/widgets/_impl/composites/textarea/diff.py +127 -0
  350. bootstack/widgets/_impl/composites/textarea/extensions/__init__.py +1 -0
  351. bootstack/widgets/_impl/composites/textarea/extensions/bracket_matcher.py +138 -0
  352. bootstack/widgets/_impl/composites/textarea/extensions/indent_guides.py +158 -0
  353. bootstack/widgets/_impl/composites/textarea/extensions/line_numbers.py +138 -0
  354. bootstack/widgets/_impl/composites/textarea/extensions/pygments_highlighter.py +312 -0
  355. bootstack/widgets/_impl/composites/textarea/extensions/smart_indent.py +177 -0
  356. bootstack/widgets/_impl/composites/textarea/filter.py +171 -0
  357. bootstack/widgets/_impl/composites/textarea/search_overlay.py +459 -0
  358. bootstack/widgets/_impl/composites/textarea/sidebar.py +88 -0
  359. bootstack/widgets/_impl/composites/textarea/style_registry.py +178 -0
  360. bootstack/widgets/_impl/composites/textarea/textarea.py +606 -0
  361. bootstack/widgets/_impl/composites/textarea/undo.py +217 -0
  362. bootstack/widgets/_impl/composites/textentry.py +57 -0
  363. bootstack/widgets/_impl/composites/timeentry.py +176 -0
  364. bootstack/widgets/_impl/composites/toast.py +390 -0
  365. bootstack/widgets/_impl/composites/toast_stack.py +156 -0
  366. bootstack/widgets/_impl/composites/togglegroup.py +418 -0
  367. bootstack/widgets/_impl/composites/toolbar.py +608 -0
  368. bootstack/widgets/_impl/composites/tooltip.py +491 -0
  369. bootstack/widgets/_impl/composites/tree/__init__.py +7 -0
  370. bootstack/widgets/_impl/composites/tree/source_binding.py +136 -0
  371. bootstack/widgets/_impl/composites/tree/treeitem.py +393 -0
  372. bootstack/widgets/_impl/composites/tree/treenode.py +174 -0
  373. bootstack/widgets/_impl/composites/tree/treeview.py +841 -0
  374. bootstack/widgets/_impl/mixins/__init__.py +24 -0
  375. bootstack/widgets/_impl/mixins/configure_mixin.py +216 -0
  376. bootstack/widgets/_impl/mixins/entry_mixin.py +134 -0
  377. bootstack/widgets/_impl/mixins/font_mixin.py +368 -0
  378. bootstack/widgets/_impl/mixins/icon_mixin.py +61 -0
  379. bootstack/widgets/_impl/mixins/localization_mixin.py +253 -0
  380. bootstack/widgets/_impl/mixins/signal_mixin.py +268 -0
  381. bootstack/widgets/_impl/mixins/validation_mixin.py +226 -0
  382. bootstack/widgets/_impl/primitives/__init__.py +49 -0
  383. bootstack/widgets/_impl/primitives/_menubutton.py +107 -0
  384. bootstack/widgets/_impl/primitives/badge.py +45 -0
  385. bootstack/widgets/_impl/primitives/button.py +76 -0
  386. bootstack/widgets/_impl/primitives/card.py +45 -0
  387. bootstack/widgets/_impl/primitives/checkbutton.py +124 -0
  388. bootstack/widgets/_impl/primitives/checktoggle.py +62 -0
  389. bootstack/widgets/_impl/primitives/combobox.py +156 -0
  390. bootstack/widgets/_impl/primitives/entry.py +87 -0
  391. bootstack/widgets/_impl/primitives/flexframe.py +448 -0
  392. bootstack/widgets/_impl/primitives/frame.py +185 -0
  393. bootstack/widgets/_impl/primitives/gridframe.py +546 -0
  394. bootstack/widgets/_impl/primitives/label.py +84 -0
  395. bootstack/widgets/_impl/primitives/labelframe.py +54 -0
  396. bootstack/widgets/_impl/primitives/optionmenu.py +387 -0
  397. bootstack/widgets/_impl/primitives/packframe.py +227 -0
  398. bootstack/widgets/_impl/primitives/panedwindow.py +45 -0
  399. bootstack/widgets/_impl/primitives/progressbar.py +83 -0
  400. bootstack/widgets/_impl/primitives/radiobutton.py +115 -0
  401. bootstack/widgets/_impl/primitives/radiotoggle.py +54 -0
  402. bootstack/widgets/_impl/primitives/scrollbar.py +42 -0
  403. bootstack/widgets/_impl/primitives/separator.py +43 -0
  404. bootstack/widgets/_impl/primitives/sizegrip.py +33 -0
  405. bootstack/widgets/_impl/primitives/spinbox.py +95 -0
  406. bootstack/widgets/_impl/primitives/switch.py +44 -0
  407. bootstack/widgets/_impl/primitives/treeview.py +69 -0
  408. bootstack/widgets/app.py +371 -0
  409. bootstack/widgets/appshell.py +1179 -0
  410. bootstack/widgets/avatar.py +140 -0
  411. bootstack/widgets/boolean_controls.py +455 -0
  412. bootstack/widgets/button.py +224 -0
  413. bootstack/widgets/buttongroup.py +239 -0
  414. bootstack/widgets/calendar.py +195 -0
  415. bootstack/widgets/card.py +159 -0
  416. bootstack/widgets/carousel.py +241 -0
  417. bootstack/widgets/chart.py +302 -0
  418. bootstack/widgets/codeeditor.py +675 -0
  419. bootstack/widgets/contextmenu.py +371 -0
  420. bootstack/widgets/datatable.py +688 -0
  421. bootstack/widgets/datefield.py +395 -0
  422. bootstack/widgets/divider.py +60 -0
  423. bootstack/widgets/expander.py +579 -0
  424. bootstack/widgets/form.py +200 -0
  425. bootstack/widgets/gallery.py +250 -0
  426. bootstack/widgets/gauge.py +168 -0
  427. bootstack/widgets/grid.py +121 -0
  428. bootstack/widgets/groupbox.py +162 -0
  429. bootstack/widgets/label.py +229 -0
  430. bootstack/widgets/listview.py +354 -0
  431. bootstack/widgets/menubutton.py +419 -0
  432. bootstack/widgets/numberfield.py +431 -0
  433. bootstack/widgets/pagestack.py +345 -0
  434. bootstack/widgets/passwordfield.py +383 -0
  435. bootstack/widgets/pathfield.py +454 -0
  436. bootstack/widgets/picture.py +251 -0
  437. bootstack/widgets/progressbar.py +106 -0
  438. bootstack/widgets/radio_variants.py +271 -0
  439. bootstack/widgets/radiogroup.py +228 -0
  440. bootstack/widgets/scrollbar.py +64 -0
  441. bootstack/widgets/scrollview.py +186 -0
  442. bootstack/widgets/select.py +302 -0
  443. bootstack/widgets/selectbutton.py +182 -0
  444. bootstack/widgets/sidebar_toggle.py +130 -0
  445. bootstack/widgets/sizegrip.py +42 -0
  446. bootstack/widgets/slider.py +408 -0
  447. bootstack/widgets/spinbox.py +147 -0
  448. bootstack/widgets/spinnerfield.py +413 -0
  449. bootstack/widgets/splash.py +367 -0
  450. bootstack/widgets/splitview.py +482 -0
  451. bootstack/widgets/stacks.py +249 -0
  452. bootstack/widgets/statusbar.py +189 -0
  453. bootstack/widgets/tabs.py +425 -0
  454. bootstack/widgets/textarea.py +459 -0
  455. bootstack/widgets/textfield.py +410 -0
  456. bootstack/widgets/theme_toggle.py +92 -0
  457. bootstack/widgets/timefield.py +340 -0
  458. bootstack/widgets/toast.py +314 -0
  459. bootstack/widgets/togglegroup.py +231 -0
  460. bootstack/widgets/toolbar.py +347 -0
  461. bootstack/widgets/tooltip.py +94 -0
  462. bootstack/widgets/tree.py +648 -0
  463. bootstack/widgets/types.py +305 -0
  464. bootstack/widgets/window.py +307 -0
  465. bootstack-0.1.0.dist-info/METADATA +301 -0
  466. bootstack-0.1.0.dist-info/RECORD +471 -0
  467. bootstack-0.1.0.dist-info/WHEEL +5 -0
  468. bootstack-0.1.0.dist-info/entry_points.txt +2 -0
  469. bootstack-0.1.0.dist-info/licenses/LICENSE +21 -0
  470. bootstack-0.1.0.dist-info/licenses/NOTICE +10 -0
  471. bootstack-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,371 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any, Callable, Literal
4
+
5
+ from bootstack.widgets._impl.composites.contextmenu import ContextMenu as _InternalContextMenu
6
+ from bootstack.widgets._impl.composites.contextmenu import ContextMenuItem
7
+ from bootstack.widgets.types import WidgetDensity, Anchor
8
+ from bootstack.events import MenuSelectEvent
9
+
10
+ _TRIGGER_MAP: dict[str | None, str | None] = {
11
+ "right_click": "right-click",
12
+ "left_click": "left-click",
13
+ "double_click": "double-click",
14
+ "manual": None,
15
+ None: None,
16
+ }
17
+ _VALID_TRIGGERS = frozenset(_TRIGGER_MAP)
18
+
19
+ # Public item type names → internal ContextMenu type strings.
20
+ _ITEM_TYPE_MAP: dict[str, str] = {
21
+ "command": "command",
22
+ "check": "checkbutton",
23
+ "radio": "radiobutton",
24
+ "divider": "separator",
25
+ # accept the internal names too so existing code doesn't break
26
+ "checkbutton": "checkbutton",
27
+ "radiobutton": "radiobutton",
28
+ "separator": "separator",
29
+ }
30
+
31
+
32
+ def _resolve_item_type(type_: str) -> str:
33
+ resolved = _ITEM_TYPE_MAP.get(type_)
34
+ if resolved is None:
35
+ raise ValueError(
36
+ f"Unknown item type {type_!r}. "
37
+ f"Use 'command', 'check', 'radio', or 'divider'."
38
+ )
39
+ return resolved
40
+
41
+
42
+ def _translate_item(item: Any) -> Any:
43
+ """Translate a public item dict to the internal shape.
44
+
45
+ Maps the public `type` name and the public `on_click` callback key to the
46
+ internal equivalents. Non-dict items (`ContextMenuItem` objects) pass through
47
+ unchanged.
48
+ """
49
+ if not isinstance(item, dict):
50
+ return item
51
+ item = dict(item)
52
+ if "type" in item:
53
+ item["type"] = _resolve_item_type(item["type"])
54
+ if "on_click" in item:
55
+ item["command"] = item.pop("on_click")
56
+ return item
57
+
58
+
59
+ def _resolve_tk(widget: Any) -> Any:
60
+ """Return the underlying Tk widget from a public wrapper or pass through."""
61
+ return getattr(widget, "_internal", widget)
62
+
63
+
64
+ class ContextMenu:
65
+ """A popup menu that attaches to a target widget and opens on a gesture or manual call.
66
+
67
+ The menu renders as a themed floating popup on Windows and Linux, and as a
68
+ native system menu on macOS. The public API is identical across platforms.
69
+
70
+ Args:
71
+ target: Widget the menu attaches to for positioning and auto-trigger
72
+ binding. Accepts any bootstack widget. When the target is a
73
+ container, the trigger fires anywhere inside it, including over its
74
+ children present at attach time. If omitted, call
75
+ `show(position=(x, y))` manually.
76
+ min_width: Minimum menu width in pixels. Default `150`.
77
+ width: Fixed menu width in pixels. Defaults to auto (uses `min_width`).
78
+ min_height: Minimum menu height in pixels. Defaults to auto.
79
+ height: Fixed menu height in pixels. Defaults to auto-size to content.
80
+ anchor: Point on the menu aligned to `attach` on the target. Default
81
+ `'nw'`.
82
+ attach: Point on the target the menu aligns to. Default `'se'`.
83
+ offset: `(dx, dy)` pixel nudge applied after alignment.
84
+ hide_on_outside_click: Hide the menu when the user clicks outside it.
85
+ Default `True`.
86
+ trigger: Gesture that auto-shows the menu on `target`. `None` means
87
+ manual only — call `show()` yourself. Default `'right_click'`.
88
+ on_select: Callback fired whenever any item is activated. Called with a
89
+ :class:`~bootstack.events.MenuSelectEvent` (`type`, `text`, `value`
90
+ of the activated item).
91
+ items: Initial items — `ContextMenuItem` objects or item dicts (each with
92
+ a `type` key plus item kwargs such as `text`, `icon`, `on_click`).
93
+ density: Item density. Default `'default'`.
94
+ parent: Parent widget for the Tk hierarchy. Defaults to `target`.
95
+ """
96
+
97
+ def __init__(
98
+ self,
99
+ target: Any = None,
100
+ *,
101
+ min_width: int = 150,
102
+ width: int | None = None,
103
+ min_height: int | None = None,
104
+ height: int | None = None,
105
+ anchor: Anchor = "nw",
106
+ attach: Anchor = "se",
107
+ offset: tuple[int, int] | None = None,
108
+ hide_on_outside_click: bool = True,
109
+ trigger: Literal["right_click", "left_click", "double_click", "manual"] | None = "right_click",
110
+ on_select: Callable[[MenuSelectEvent], Any] | None = None,
111
+ items: list[Any] | None = None,
112
+ density: WidgetDensity = "default",
113
+ parent: Any = None,
114
+ ) -> None:
115
+ tk_target = _resolve_tk(target) if target is not None else None
116
+ tk_master = _resolve_tk(parent) if parent is not None else tk_target
117
+
118
+ if trigger not in _VALID_TRIGGERS:
119
+ valid = ", ".join(repr(k) for k in _VALID_TRIGGERS if k is not None)
120
+ raise ValueError(f"Invalid trigger {trigger!r}. Valid values: {valid}")
121
+
122
+ internal_kwargs: dict[str, Any] = {
123
+ "minwidth": min_width,
124
+ "trigger": _TRIGGER_MAP[trigger],
125
+ "density": density,
126
+ "anchor": anchor,
127
+ "attach": attach,
128
+ "hide_on_outside_click": hide_on_outside_click,
129
+ }
130
+ if width is not None:
131
+ internal_kwargs["width"] = width
132
+ if min_height is not None:
133
+ internal_kwargs["minheight"] = min_height
134
+ if height is not None:
135
+ internal_kwargs["height"] = height
136
+ if offset is not None:
137
+ internal_kwargs["offset"] = offset
138
+ if on_select is not None:
139
+ _user_on_select = on_select
140
+ def _on_select(data: dict[str, Any]) -> None:
141
+ _user_on_select(MenuSelectEvent(
142
+ type=data.get("type", ""),
143
+ text=data.get("text", ""),
144
+ value=data.get("value"),
145
+ ))
146
+ internal_kwargs["command"] = _on_select
147
+ if items is not None:
148
+ internal_kwargs["items"] = [_translate_item(it) for it in items]
149
+ if tk_target is not None:
150
+ internal_kwargs["target"] = tk_target
151
+
152
+ self._internal = _InternalContextMenu(tk_master, **internal_kwargs)
153
+ self._radio_var: Any = None # shared StringVar for all radio items
154
+
155
+ # ----- Item management -----
156
+
157
+ def add_item(
158
+ self,
159
+ label: str,
160
+ *,
161
+ on_click: Callable[[], Any] | None = None,
162
+ icon: str | None = None,
163
+ shortcut: str | None = None,
164
+ disabled: bool = False,
165
+ key: str | None = None,
166
+ ) -> str:
167
+ """Add a command item.
168
+
169
+ Args:
170
+ label: Item label text.
171
+ on_click: Callback fired when the item is clicked.
172
+ icon: Icon name shown beside the label.
173
+ shortcut: Keyboard shortcut hint displayed on the right. Accepts a
174
+ modifier pattern (`'Mod+S'` → `'Ctrl+S'` / `'⌘S'`), a key
175
+ registered with the Shortcuts service, or a literal string.
176
+ disabled: If `True`, item is visible but non-interactive.
177
+ key: Unique string identifier. Auto-generated if omitted.
178
+
179
+ Returns:
180
+ The key assigned to this item.
181
+ """
182
+ kw: dict[str, Any] = {"text": label, "disabled": disabled}
183
+ if on_click is not None:
184
+ kw["command"] = on_click
185
+ if icon is not None:
186
+ kw["icon"] = icon
187
+ if shortcut is not None:
188
+ kw["shortcut"] = shortcut
189
+ if key is not None:
190
+ kw["key"] = key
191
+ self._internal.add_command(**kw)
192
+ return self._internal.keys()[-1]
193
+
194
+ def add_check_item(
195
+ self,
196
+ label: str,
197
+ *,
198
+ value: bool = False,
199
+ on_click: Callable[[], Any] | None = None,
200
+ key: str | None = None,
201
+ ) -> str:
202
+ """Add a checkbutton item.
203
+
204
+ Args:
205
+ label: Item label text.
206
+ value: Initial checked state. Default `False`.
207
+ on_click: Callback fired when the item is toggled.
208
+ key: Unique string identifier. Auto-generated if omitted.
209
+
210
+ Returns:
211
+ The key assigned to this item.
212
+ """
213
+ kw: dict[str, Any] = {"text": label, "value": value}
214
+ if on_click is not None:
215
+ kw["command"] = on_click
216
+ if key is not None:
217
+ kw["key"] = key
218
+ self._internal.add_checkbutton(**kw)
219
+ return self._internal.keys()[-1]
220
+
221
+ def add_radio_item(
222
+ self,
223
+ label: str,
224
+ *,
225
+ value: Any = None,
226
+ on_click: Callable[[], Any] | None = None,
227
+ key: str | None = None,
228
+ ) -> str:
229
+ """Add a radiobutton item.
230
+
231
+ All radio items in a menu share one group — selecting one deselects
232
+ the others. Use check items if you need independent toggles.
233
+
234
+ Args:
235
+ label: Item label text.
236
+ value: Value passed to `on_select` when this item is selected.
237
+ on_click: Callback fired when the item is selected.
238
+ key: Unique string identifier. Auto-generated if omitted.
239
+
240
+ Returns:
241
+ The key assigned to this item.
242
+ """
243
+ import tkinter
244
+ if self._radio_var is None:
245
+ self._radio_var = tkinter.StringVar()
246
+ kw: dict[str, Any] = {"text": label, "variable": self._radio_var}
247
+ if value is not None:
248
+ kw["value"] = value
249
+ if on_click is not None:
250
+ kw["command"] = on_click
251
+ if key is not None:
252
+ kw["key"] = key
253
+ self._internal.add_radiobutton(**kw)
254
+ return self._internal.keys()[-1]
255
+
256
+ def add_divider(self, *, key: str | None = None) -> str:
257
+ """Add a horizontal divider.
258
+
259
+ Args:
260
+ key: Unique string identifier. Auto-generated if omitted.
261
+
262
+ Returns:
263
+ The key assigned to this divider.
264
+ """
265
+ kw: dict[str, Any] = {}
266
+ if key is not None:
267
+ kw["key"] = key
268
+ self._internal.add_separator(**kw)
269
+ return self._internal.keys()[-1]
270
+
271
+ def add_items(self, items: list[ContextMenuItem | dict[str, Any]]) -> None:
272
+ """Add multiple items at once.
273
+
274
+ Args:
275
+ items: List of `ContextMenuItem` objects or item dicts. Each dict has
276
+ a `type` key (`'command'`, `'check'`, `'radio'`, or `'divider'`)
277
+ plus item kwargs such as `text`, `icon`, `value`, and `on_click`.
278
+ """
279
+ self._internal.add_items([_translate_item(it) for it in items])
280
+
281
+ def insert_item(
282
+ self,
283
+ index: int,
284
+ type: str,
285
+ *,
286
+ on_click: Callable[[], Any] | None = None,
287
+ **kwargs: Any,
288
+ ) -> str:
289
+ """Insert an item at a specific position.
290
+
291
+ Args:
292
+ index: Zero-based position to insert at.
293
+ type: Item type — `'command'`, `'check'`, `'radio'`, or `'divider'`.
294
+ on_click: Callback fired when the item is activated.
295
+ **kwargs: Other item options (`text`, `icon`, `value`, `disabled`,
296
+ `key`, ...).
297
+
298
+ Returns:
299
+ The key assigned to the new item.
300
+ """
301
+ if on_click is not None:
302
+ kwargs["command"] = on_click
303
+ result = self._internal.insert_item(index, _resolve_item_type(type), **kwargs)
304
+ return result.key if hasattr(result, "key") else result
305
+
306
+ def move_item(self, key: str, to_index: int) -> None:
307
+ """Move an existing item to a new position.
308
+
309
+ Args:
310
+ key: Key of the item to move.
311
+ to_index: Target zero-based index.
312
+ """
313
+ self._internal.move_item(key, to_index)
314
+
315
+ def update_item(self, key: str, **kwargs: Any) -> None:
316
+ """Reconfigure an item after creation.
317
+
318
+ Args:
319
+ key: Key returned by an `add_*` method.
320
+ **kwargs: Item options to change (`text`, `icon`, `disabled`,
321
+ `on_click`, ...).
322
+ """
323
+ if "on_click" in kwargs:
324
+ kwargs["command"] = kwargs.pop("on_click")
325
+ self._internal.configure_item(key, **kwargs)
326
+
327
+ def item(self, key: str) -> dict[str, Any]:
328
+ """Return an item's current configuration as a dict.
329
+
330
+ Args:
331
+ key: Key returned by an `add_*` method.
332
+ """
333
+ return self._internal.item(key)
334
+
335
+ def remove_item(self, key: str) -> None:
336
+ """Remove an item by key.
337
+
338
+ Args:
339
+ key: Key returned by an `add_*` method.
340
+ """
341
+ self._internal.remove_item(key)
342
+
343
+ # ----- Properties -----
344
+
345
+ @property
346
+ def keys(self) -> tuple[str, ...]:
347
+ """Keys of all items in insertion order."""
348
+ return self._internal.keys()
349
+
350
+ # ----- Display / lifecycle -----
351
+
352
+ def show(self, position: tuple[int, int] | None = None) -> "ContextMenu":
353
+ """Show the menu, optionally at an explicit screen position.
354
+
355
+ Args:
356
+ position: Screen `(x, y)` coordinates. If omitted, the menu is
357
+ positioned relative to its `target` widget.
358
+
359
+ Returns:
360
+ `self` — allows chaining: `menu.add_item("Edit").show()`.
361
+ """
362
+ self._internal.show(position)
363
+ return self
364
+
365
+ def hide(self) -> None:
366
+ """Hide the menu without destroying it."""
367
+ self._internal.hide()
368
+
369
+ def destroy(self) -> None:
370
+ """Destroy the menu and release all resources."""
371
+ self._internal.destroy()