bootstack 0.1.0a1__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 (419) hide show
  1. bootstack/__init__.py +249 -0
  2. bootstack/__main__.py +5 -0
  3. bootstack/api/__init__.py +127 -0
  4. bootstack/api/app.py +30 -0
  5. bootstack/api/constants.py +3 -0
  6. bootstack/api/data.py +23 -0
  7. bootstack/api/dialogs.py +44 -0
  8. bootstack/api/i18n.py +17 -0
  9. bootstack/api/localization.py +16 -0
  10. bootstack/api/menu.py +7 -0
  11. bootstack/api/style.py +23 -0
  12. bootstack/api/utils.py +24 -0
  13. bootstack/api/widgets.py +137 -0
  14. bootstack/assets/__init__.py +24 -0
  15. bootstack/assets/bootstack-transparent.png +0 -0
  16. bootstack/assets/bootstack.ico +0 -0
  17. bootstack/assets/bootstack.png +0 -0
  18. bootstack/assets/elements/__init__.py +0 -0
  19. bootstack/assets/elements/badge-pill.png +0 -0
  20. bootstack/assets/elements/badge-square.png +0 -0
  21. bootstack/assets/elements/border.png +0 -0
  22. bootstack/assets/elements/button-compact.png +0 -0
  23. bootstack/assets/elements/button-default.png +0 -0
  24. bootstack/assets/elements/button-group-horizontal-after-compact.png +0 -0
  25. bootstack/assets/elements/button-group-horizontal-after-default.png +0 -0
  26. bootstack/assets/elements/button-group-horizontal-before-compact.png +0 -0
  27. bootstack/assets/elements/button-group-horizontal-before-default.png +0 -0
  28. bootstack/assets/elements/button-group-horizontal-center-compact.png +0 -0
  29. bootstack/assets/elements/button-group-horizontal-center-default.png +0 -0
  30. bootstack/assets/elements/button-group-vertical-after-compact.png +0 -0
  31. bootstack/assets/elements/button-group-vertical-after-default.png +0 -0
  32. bootstack/assets/elements/button-group-vertical-before-compact.png +0 -0
  33. bootstack/assets/elements/button-group-vertical-before-default.png +0 -0
  34. bootstack/assets/elements/button-group-vertical-center-compact.png +0 -0
  35. bootstack/assets/elements/button-group-vertical-center-default.png +0 -0
  36. bootstack/assets/elements/checkbox-checked.png +0 -0
  37. bootstack/assets/elements/checkbox-indeterminate.png +0 -0
  38. bootstack/assets/elements/checkbox-unchecked.png +0 -0
  39. bootstack/assets/elements/field.png +0 -0
  40. bootstack/assets/elements/input-after-compact.png +0 -0
  41. bootstack/assets/elements/input-after-default.png +0 -0
  42. bootstack/assets/elements/input-before-compact.png +0 -0
  43. bootstack/assets/elements/input-before-default.png +0 -0
  44. bootstack/assets/elements/input-compact.png +0 -0
  45. bootstack/assets/elements/input-default.png +0 -0
  46. bootstack/assets/elements/list-item-separated.png +0 -0
  47. bootstack/assets/elements/list-item.png +0 -0
  48. bootstack/assets/elements/manifest.toml +480 -0
  49. bootstack/assets/elements/menu-item.png +0 -0
  50. bootstack/assets/elements/nav-button-compact.png +0 -0
  51. bootstack/assets/elements/nav-button-default.png +0 -0
  52. bootstack/assets/elements/nav-icon-button-compact.png +0 -0
  53. bootstack/assets/elements/nav-icon-button-default.png +0 -0
  54. bootstack/assets/elements/notebook-client-border.png +0 -0
  55. bootstack/assets/elements/notebook-tab-active.png +0 -0
  56. bootstack/assets/elements/notebook-tab-bar.png +0 -0
  57. bootstack/assets/elements/notebook-tab-normal.png +0 -0
  58. bootstack/assets/elements/notebook-tab-pill.png +0 -0
  59. bootstack/assets/elements/progress-bar-horizontal-striped.png +0 -0
  60. bootstack/assets/elements/progress-bar-solid.png +0 -0
  61. bootstack/assets/elements/progress-bar-thin.png +0 -0
  62. bootstack/assets/elements/progress-bar-vertical-striped.png +0 -0
  63. bootstack/assets/elements/radio-selected.png +0 -0
  64. bootstack/assets/elements/radio-unselected.png +0 -0
  65. bootstack/assets/elements/scrollbar-horizontal.png +0 -0
  66. bootstack/assets/elements/scrollbar-vertical.png +0 -0
  67. bootstack/assets/elements/slider-handle-focus.png +0 -0
  68. bootstack/assets/elements/slider-handle.png +0 -0
  69. bootstack/assets/elements/slider-track-horizontal.png +0 -0
  70. bootstack/assets/elements/slider-track-vertical.png +0 -0
  71. bootstack/assets/elements/switch-off.png +0 -0
  72. bootstack/assets/elements/switch-on.png +0 -0
  73. bootstack/assets/elements/tabs-bar-horizontal.png +0 -0
  74. bootstack/assets/elements/tabs-bar-vertical.png +0 -0
  75. bootstack/assets/elements/tabs-pill.png +0 -0
  76. bootstack/assets/locales/ar/LC_MESSAGES/bootstack.mo +0 -0
  77. bootstack/assets/locales/ar/LC_MESSAGES/bootstack.po +853 -0
  78. bootstack/assets/locales/bg/LC_MESSAGES/bootstack.po +875 -0
  79. bootstack/assets/locales/cs/LC_MESSAGES/bootstack.mo +0 -0
  80. bootstack/assets/locales/cs/LC_MESSAGES/bootstack.po +853 -0
  81. bootstack/assets/locales/da/LC_MESSAGES/bootstack.mo +0 -0
  82. bootstack/assets/locales/da/LC_MESSAGES/bootstack.po +853 -0
  83. bootstack/assets/locales/de/LC_MESSAGES/bootstack.mo +0 -0
  84. bootstack/assets/locales/de/LC_MESSAGES/bootstack.po +853 -0
  85. bootstack/assets/locales/en/LC_MESSAGES/bootstack.mo +0 -0
  86. bootstack/assets/locales/en/LC_MESSAGES/bootstack.po +875 -0
  87. bootstack/assets/locales/es/LC_MESSAGES/bootstack.mo +0 -0
  88. bootstack/assets/locales/es/LC_MESSAGES/bootstack.po +853 -0
  89. bootstack/assets/locales/fr/LC_MESSAGES/bootstack.mo +0 -0
  90. bootstack/assets/locales/fr/LC_MESSAGES/bootstack.po +853 -0
  91. bootstack/assets/locales/he/LC_MESSAGES/bootstack.mo +0 -0
  92. bootstack/assets/locales/he/LC_MESSAGES/bootstack.po +851 -0
  93. bootstack/assets/locales/hi/LC_MESSAGES/bootstack.mo +0 -0
  94. bootstack/assets/locales/hi/LC_MESSAGES/bootstack.po +842 -0
  95. bootstack/assets/locales/it/LC_MESSAGES/bootstack.mo +0 -0
  96. bootstack/assets/locales/it/LC_MESSAGES/bootstack.po +841 -0
  97. bootstack/assets/locales/ja/LC_MESSAGES/bootstack.mo +0 -0
  98. bootstack/assets/locales/ja/LC_MESSAGES/bootstack.po +914 -0
  99. bootstack/assets/locales/ko/LC_MESSAGES/bootstack.mo +0 -0
  100. bootstack/assets/locales/ko/LC_MESSAGES/bootstack.po +842 -0
  101. bootstack/assets/locales/nb/LC_MESSAGES/bootstack.mo +0 -0
  102. bootstack/assets/locales/nb/LC_MESSAGES/bootstack.po +841 -0
  103. bootstack/assets/locales/nl/LC_MESSAGES/bootstack.mo +0 -0
  104. bootstack/assets/locales/nl/LC_MESSAGES/bootstack.po +841 -0
  105. bootstack/assets/locales/pl/LC_MESSAGES/bootstack.mo +0 -0
  106. bootstack/assets/locales/pl/LC_MESSAGES/bootstack.po +842 -0
  107. bootstack/assets/locales/pt/LC_MESSAGES/bootstack.mo +0 -0
  108. bootstack/assets/locales/pt/LC_MESSAGES/bootstack.po +842 -0
  109. bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.mo +0 -0
  110. bootstack/assets/locales/pt_BR/LC_MESSAGES/bootstack.po +842 -0
  111. bootstack/assets/locales/sl/LC_MESSAGES/bootstack.mo +0 -0
  112. bootstack/assets/locales/sl/LC_MESSAGES/bootstack.po +842 -0
  113. bootstack/assets/locales/sv/LC_MESSAGES/bootstack.mo +0 -0
  114. bootstack/assets/locales/sv/LC_MESSAGES/bootstack.po +842 -0
  115. bootstack/assets/locales/tr/LC_MESSAGES/bootstack.mo +0 -0
  116. bootstack/assets/locales/tr/LC_MESSAGES/bootstack.po +842 -0
  117. bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.mo +0 -0
  118. bootstack/assets/locales/zh_CN/LC_MESSAGES/bootstack.po +842 -0
  119. bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.mo +0 -0
  120. bootstack/assets/locales/zh_TW/LC_MESSAGES/bootstack.po +842 -0
  121. bootstack/assets/themes/__init__.py +0 -0
  122. bootstack/assets/themes/amber-dark.json +32 -0
  123. bootstack/assets/themes/amber-light.json +32 -0
  124. bootstack/assets/themes/aurora-dark.json +32 -0
  125. bootstack/assets/themes/aurora-light.json +32 -0
  126. bootstack/assets/themes/bootstrap-dark.json +32 -0
  127. bootstack/assets/themes/bootstrap-light.json +32 -0
  128. bootstack/assets/themes/classic-dark.json +32 -0
  129. bootstack/assets/themes/classic-light.json +32 -0
  130. bootstack/assets/themes/docs-dark.json +32 -0
  131. bootstack/assets/themes/docs-light.json +32 -0
  132. bootstack/assets/themes/forest-dark.json +32 -0
  133. bootstack/assets/themes/forest-light.json +32 -0
  134. bootstack/assets/themes/ocean-dark.json +32 -0
  135. bootstack/assets/themes/ocean-light.json +32 -0
  136. bootstack/assets/themes/rose-dark.json +32 -0
  137. bootstack/assets/themes/rose-light.json +32 -0
  138. bootstack/assets/widgets/__init__.py +0 -0
  139. bootstack/assets/widgets/badge-default.png +0 -0
  140. bootstack/assets/widgets/badge-pill.png +0 -0
  141. bootstack/assets/widgets/border.png +0 -0
  142. bootstack/assets/widgets/button-group-horizontal-after.png +0 -0
  143. bootstack/assets/widgets/button-group-horizontal-before.png +0 -0
  144. bootstack/assets/widgets/button-group-horizontal-center.png +0 -0
  145. bootstack/assets/widgets/button-group-vertical-after.png +0 -0
  146. bootstack/assets/widgets/button-group-vertical-before.png +0 -0
  147. bootstack/assets/widgets/button-group-vertical-center.png +0 -0
  148. bootstack/assets/widgets/button.png +0 -0
  149. bootstack/assets/widgets/checkbox-checked.png +0 -0
  150. bootstack/assets/widgets/checkbox-indeterminate.png +0 -0
  151. bootstack/assets/widgets/checkbox-unchecked.png +0 -0
  152. bootstack/assets/widgets/field.png +0 -0
  153. bootstack/assets/widgets/icon-button.png +0 -0
  154. bootstack/assets/widgets/input-inner.png +0 -0
  155. bootstack/assets/widgets/input-prefix.png +0 -0
  156. bootstack/assets/widgets/input-suffix.png +0 -0
  157. bootstack/assets/widgets/input.png +0 -0
  158. bootstack/assets/widgets/list-item-focus.png +0 -0
  159. bootstack/assets/widgets/list-item-separated.png +0 -0
  160. bootstack/assets/widgets/menu-item-separated.png +0 -0
  161. bootstack/assets/widgets/notebook-client-border.png +0 -0
  162. bootstack/assets/widgets/notebook-pill-active.png +0 -0
  163. bootstack/assets/widgets/notebook-pill-inactive.png +0 -0
  164. bootstack/assets/widgets/notebook-tab-active.png +0 -0
  165. bootstack/assets/widgets/notebook-tab-border.png +0 -0
  166. bootstack/assets/widgets/notebook-tab-normal.png +0 -0
  167. bootstack/assets/widgets/notebook-underline.png +0 -0
  168. bootstack/assets/widgets/progress-bar-horizontal-default.png +0 -0
  169. bootstack/assets/widgets/progress-bar-horizontal-striped.png +0 -0
  170. bootstack/assets/widgets/progress-bar-vertical-default.png +0 -0
  171. bootstack/assets/widgets/progress-bar-vertical-striped.png +0 -0
  172. bootstack/assets/widgets/progress-trough-horizontal.png +0 -0
  173. bootstack/assets/widgets/progress-trough-vertical.png +0 -0
  174. bootstack/assets/widgets/radio-selected.png +0 -0
  175. bootstack/assets/widgets/radio-unselected.png +0 -0
  176. bootstack/assets/widgets/scrollbar-horizontal-rounded.png +0 -0
  177. bootstack/assets/widgets/scrollbar-vertical-rounded.png +0 -0
  178. bootstack/assets/widgets/separator-horizontal.png +0 -0
  179. bootstack/assets/widgets/separator-vertical.png +0 -0
  180. bootstack/assets/widgets/slider-handle-focus.png +0 -0
  181. bootstack/assets/widgets/slider-handle.png +0 -0
  182. bootstack/assets/widgets/slider-track-horizontal.png +0 -0
  183. bootstack/assets/widgets/slider-track-vertical.png +0 -0
  184. bootstack/assets/widgets/switch-off.png +0 -0
  185. bootstack/assets/widgets/switch-on.png +0 -0
  186. bootstack/assets/widgets/tabs-bar-horizontal.png +0 -0
  187. bootstack/assets/widgets/tabs-bar-vertical.png +0 -0
  188. bootstack/assets/widgets/tabs-pill.png +0 -0
  189. bootstack/cli/__init__.py +124 -0
  190. bootstack/cli/__main__.py +6 -0
  191. bootstack/cli/add.py +439 -0
  192. bootstack/cli/build.py +115 -0
  193. bootstack/cli/config.py +287 -0
  194. bootstack/cli/demo.py +1267 -0
  195. bootstack/cli/doctor.py +195 -0
  196. bootstack/cli/list_cmd.py +71 -0
  197. bootstack/cli/promote.py +120 -0
  198. bootstack/cli/pyinstaller.py +246 -0
  199. bootstack/cli/run.py +99 -0
  200. bootstack/cli/start.py +105 -0
  201. bootstack/cli/templates/__init__.py +861 -0
  202. bootstack/constants.py +325 -0
  203. bootstack/core/__init__.py +34 -0
  204. bootstack/core/capabilities/__init__.py +45 -0
  205. bootstack/core/capabilities/after.py +103 -0
  206. bootstack/core/capabilities/bind.py +154 -0
  207. bootstack/core/capabilities/bindtags.py +112 -0
  208. bootstack/core/capabilities/busy.py +61 -0
  209. bootstack/core/capabilities/clipboard.py +88 -0
  210. bootstack/core/capabilities/focus.py +118 -0
  211. bootstack/core/capabilities/grab.py +65 -0
  212. bootstack/core/capabilities/grid.py +188 -0
  213. bootstack/core/capabilities/localization.py +231 -0
  214. bootstack/core/capabilities/pack.py +119 -0
  215. bootstack/core/capabilities/place.py +92 -0
  216. bootstack/core/capabilities/selection.py +136 -0
  217. bootstack/core/capabilities/signals.py +242 -0
  218. bootstack/core/capabilities/winfo.py +315 -0
  219. bootstack/core/colorutils.py +234 -0
  220. bootstack/core/exceptions.py +95 -0
  221. bootstack/core/images.py +283 -0
  222. bootstack/core/localization/README.md +90 -0
  223. bootstack/core/localization/__init__.py +13 -0
  224. bootstack/core/localization/intl_format.py +580 -0
  225. bootstack/core/localization/msgcat.py +425 -0
  226. bootstack/core/localization/specs.py +143 -0
  227. bootstack/core/mixins/__init__.py +1 -0
  228. bootstack/core/mixins/ttk_state.py +35 -0
  229. bootstack/core/mixins/widget.py +132 -0
  230. bootstack/core/publisher.py +147 -0
  231. bootstack/core/signals/README.md +112 -0
  232. bootstack/core/signals/__init__.py +8 -0
  233. bootstack/core/signals/integration.py +100 -0
  234. bootstack/core/signals/signal.py +317 -0
  235. bootstack/core/signals/types.py +4 -0
  236. bootstack/core/validation/__init__.py +5 -0
  237. bootstack/core/validation/types.py +13 -0
  238. bootstack/core/validation/validation_result.py +17 -0
  239. bootstack/core/validation/validation_rules.py +112 -0
  240. bootstack/core/variables.py +62 -0
  241. bootstack/datasource/README.md +607 -0
  242. bootstack/datasource/__init__.py +51 -0
  243. bootstack/datasource/base.py +474 -0
  244. bootstack/datasource/file_source.py +541 -0
  245. bootstack/datasource/memory_source.py +482 -0
  246. bootstack/datasource/sqlite_source.py +453 -0
  247. bootstack/datasource/types.py +259 -0
  248. bootstack/dialogs/__init__.py +56 -0
  249. bootstack/dialogs/colorchooser.py +674 -0
  250. bootstack/dialogs/colordropper.py +257 -0
  251. bootstack/dialogs/datedialog.py +404 -0
  252. bootstack/dialogs/dialog.py +514 -0
  253. bootstack/dialogs/filterdialog.py +358 -0
  254. bootstack/dialogs/fontdialog.py +339 -0
  255. bootstack/dialogs/formdialog.py +541 -0
  256. bootstack/dialogs/message.py +489 -0
  257. bootstack/dialogs/query.py +561 -0
  258. bootstack/py.typed +1 -0
  259. bootstack/runtime/__init__.py +3 -0
  260. bootstack/runtime/app.py +879 -0
  261. bootstack/runtime/base_window.py +786 -0
  262. bootstack/runtime/events.py +399 -0
  263. bootstack/runtime/menu.py +510 -0
  264. bootstack/runtime/shortcuts.py +423 -0
  265. bootstack/runtime/tk_patch.py +31 -0
  266. bootstack/runtime/toplevel.py +131 -0
  267. bootstack/runtime/utility.py +371 -0
  268. bootstack/runtime/visual_focus.py +228 -0
  269. bootstack/runtime/window_utilities.py +1043 -0
  270. bootstack/style/__init__.py +5498 -0
  271. bootstack/style/bootstyle.py +507 -0
  272. bootstack/style/bootstyle_builder_base.py +752 -0
  273. bootstack/style/bootstyle_builder_mixed.py +93 -0
  274. bootstack/style/bootstyle_builder_tk.py +109 -0
  275. bootstack/style/bootstyle_builder_ttk.py +354 -0
  276. bootstack/style/builders/__init__.py +51 -0
  277. bootstack/style/builders/badge.py +44 -0
  278. bootstack/style/builders/button.py +453 -0
  279. bootstack/style/builders/buttongroup.py +344 -0
  280. bootstack/style/builders/calendar.py +271 -0
  281. bootstack/style/builders/checkbutton.py +95 -0
  282. bootstack/style/builders/combobox.py +112 -0
  283. bootstack/style/builders/contextmenu.py +268 -0
  284. bootstack/style/builders/entry.py +83 -0
  285. bootstack/style/builders/expander.py +171 -0
  286. bootstack/style/builders/field.py +312 -0
  287. bootstack/style/builders/frame.py +27 -0
  288. bootstack/style/builders/label.py +28 -0
  289. bootstack/style/builders/labelframe.py +41 -0
  290. bootstack/style/builders/listview.py +267 -0
  291. bootstack/style/builders/menubar.py +74 -0
  292. bootstack/style/builders/menubutton.py +408 -0
  293. bootstack/style/builders/notebook.py +316 -0
  294. bootstack/style/builders/panedwindow.py +25 -0
  295. bootstack/style/builders/progressbar.py +71 -0
  296. bootstack/style/builders/radiobutton.py +68 -0
  297. bootstack/style/builders/scale.py +66 -0
  298. bootstack/style/builders/scrollbar.py +360 -0
  299. bootstack/style/builders/separator.py +45 -0
  300. bootstack/style/builders/sidenav.py +313 -0
  301. bootstack/style/builders/sizegrip.py +15 -0
  302. bootstack/style/builders/spinbox.py +119 -0
  303. bootstack/style/builders/switch.py +67 -0
  304. bootstack/style/builders/tabitem.py +205 -0
  305. bootstack/style/builders/toolbutton.py +260 -0
  306. bootstack/style/builders/tooltip.py +26 -0
  307. bootstack/style/builders/treeview.py +269 -0
  308. bootstack/style/builders/utils.py +404 -0
  309. bootstack/style/builders_tk/__init__.py +16 -0
  310. bootstack/style/builders_tk/defaults.py +229 -0
  311. bootstack/style/element.py +173 -0
  312. bootstack/style/style.py +499 -0
  313. bootstack/style/theme_provider.py +449 -0
  314. bootstack/style/tk_patch.py +5 -0
  315. bootstack/style/token_maps.py +42 -0
  316. bootstack/style/types.py +32 -0
  317. bootstack/style/typography.py +527 -0
  318. bootstack/style/utility.py +696 -0
  319. bootstack/themes/__init__.py +12 -0
  320. bootstack/themes/standard.py +415 -0
  321. bootstack/themes/user.py +45 -0
  322. bootstack/widgets/__init__.py +53 -0
  323. bootstack/widgets/composites/__init__.py +38 -0
  324. bootstack/widgets/composites/accordion.py +385 -0
  325. bootstack/widgets/composites/appshell.py +445 -0
  326. bootstack/widgets/composites/buttongroup.py +391 -0
  327. bootstack/widgets/composites/calendar.py +914 -0
  328. bootstack/widgets/composites/compositeframe.py +282 -0
  329. bootstack/widgets/composites/contextmenu.py +1754 -0
  330. bootstack/widgets/composites/dateentry.py +261 -0
  331. bootstack/widgets/composites/dropdownbutton.py +190 -0
  332. bootstack/widgets/composites/expander.py +508 -0
  333. bootstack/widgets/composites/field.py +448 -0
  334. bootstack/widgets/composites/floodgauge.py +434 -0
  335. bootstack/widgets/composites/form.py +983 -0
  336. bootstack/widgets/composites/labeledscale.py +209 -0
  337. bootstack/widgets/composites/list/__init__.py +15 -0
  338. bootstack/widgets/composites/list/listitem.py +733 -0
  339. bootstack/widgets/composites/list/listview.py +1507 -0
  340. bootstack/widgets/composites/menubar.py +303 -0
  341. bootstack/widgets/composites/meter.py +882 -0
  342. bootstack/widgets/composites/numericentry.py +183 -0
  343. bootstack/widgets/composites/pagestack.py +330 -0
  344. bootstack/widgets/composites/passwordentry.py +149 -0
  345. bootstack/widgets/composites/pathentry.py +223 -0
  346. bootstack/widgets/composites/radiogroup.py +466 -0
  347. bootstack/widgets/composites/scrolledtext.py +388 -0
  348. bootstack/widgets/composites/scrolledtext.pyi +186 -0
  349. bootstack/widgets/composites/scrollview.py +675 -0
  350. bootstack/widgets/composites/selectbox.py +544 -0
  351. bootstack/widgets/composites/sidenav/__init__.py +24 -0
  352. bootstack/widgets/composites/sidenav/group.py +485 -0
  353. bootstack/widgets/composites/sidenav/header.py +83 -0
  354. bootstack/widgets/composites/sidenav/item.py +413 -0
  355. bootstack/widgets/composites/sidenav/separator.py +51 -0
  356. bootstack/widgets/composites/sidenav/view.py +919 -0
  357. bootstack/widgets/composites/spinnerentry.py +232 -0
  358. bootstack/widgets/composites/tableview/__init__.py +5 -0
  359. bootstack/widgets/composites/tableview/tableview.py +2254 -0
  360. bootstack/widgets/composites/tableview/types.py +169 -0
  361. bootstack/widgets/composites/tabs/__init__.py +6 -0
  362. bootstack/widgets/composites/tabs/tabitem.py +372 -0
  363. bootstack/widgets/composites/tabs/tabs.py +478 -0
  364. bootstack/widgets/composites/tabs/tabview.py +352 -0
  365. bootstack/widgets/composites/textentry.py +90 -0
  366. bootstack/widgets/composites/timeentry.py +189 -0
  367. bootstack/widgets/composites/toast.py +364 -0
  368. bootstack/widgets/composites/togglegroup.py +382 -0
  369. bootstack/widgets/composites/toolbar.py +393 -0
  370. bootstack/widgets/composites/tooltip.py +404 -0
  371. bootstack/widgets/internal/__init__.py +0 -0
  372. bootstack/widgets/internal/wrapper_base.py +304 -0
  373. bootstack/widgets/mixins/__init__.py +25 -0
  374. bootstack/widgets/mixins/configure_mixin.py +186 -0
  375. bootstack/widgets/mixins/entry_mixin.py +70 -0
  376. bootstack/widgets/mixins/font_mixin.py +346 -0
  377. bootstack/widgets/mixins/icon_mixin.py +38 -0
  378. bootstack/widgets/mixins/localization_mixin.py +255 -0
  379. bootstack/widgets/mixins/signal_mixin.py +272 -0
  380. bootstack/widgets/mixins/validation_mixin.py +204 -0
  381. bootstack/widgets/parts/__init__.py +11 -0
  382. bootstack/widgets/parts/numberentry_part.py +345 -0
  383. bootstack/widgets/parts/spinnerentry_part.py +394 -0
  384. bootstack/widgets/parts/textentry_part.py +344 -0
  385. bootstack/widgets/primitives/__init__.py +55 -0
  386. bootstack/widgets/primitives/badge.py +44 -0
  387. bootstack/widgets/primitives/button.py +89 -0
  388. bootstack/widgets/primitives/card.py +66 -0
  389. bootstack/widgets/primitives/checkbutton.py +124 -0
  390. bootstack/widgets/primitives/checktoggle.py +53 -0
  391. bootstack/widgets/primitives/combobox.py +165 -0
  392. bootstack/widgets/primitives/entry.py +98 -0
  393. bootstack/widgets/primitives/frame.py +206 -0
  394. bootstack/widgets/primitives/gridframe.py +479 -0
  395. bootstack/widgets/primitives/label.py +95 -0
  396. bootstack/widgets/primitives/labelframe.py +63 -0
  397. bootstack/widgets/primitives/menubutton.py +118 -0
  398. bootstack/widgets/primitives/notebook.py +551 -0
  399. bootstack/widgets/primitives/optionmenu.py +248 -0
  400. bootstack/widgets/primitives/packframe.py +228 -0
  401. bootstack/widgets/primitives/panedwindow.py +58 -0
  402. bootstack/widgets/primitives/progressbar.py +95 -0
  403. bootstack/widgets/primitives/radiobutton.py +115 -0
  404. bootstack/widgets/primitives/radiotoggle.py +50 -0
  405. bootstack/widgets/primitives/scale.py +85 -0
  406. bootstack/widgets/primitives/scrollbar.py +56 -0
  407. bootstack/widgets/primitives/separator.py +56 -0
  408. bootstack/widgets/primitives/sizegrip.py +47 -0
  409. bootstack/widgets/primitives/spinbox.py +91 -0
  410. bootstack/widgets/primitives/switch.py +41 -0
  411. bootstack/widgets/primitives/treeview.py +77 -0
  412. bootstack/widgets/types.py +20 -0
  413. bootstack-0.1.0a1.dist-info/METADATA +196 -0
  414. bootstack-0.1.0a1.dist-info/RECORD +419 -0
  415. bootstack-0.1.0a1.dist-info/WHEEL +5 -0
  416. bootstack-0.1.0a1.dist-info/entry_points.txt +2 -0
  417. bootstack-0.1.0a1.dist-info/licenses/LICENSE +22 -0
  418. bootstack-0.1.0a1.dist-info/licenses/NOTICE +10 -0
  419. bootstack-0.1.0a1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,242 @@
1
+ """Signal binding capability for bootstack widgets.
2
+
3
+ This module provides the core framework service for binding Signals and tkinter
4
+ Variables to widgets. It handles normalization, bidirectional synchronization,
5
+ and lazy creation of Signals.
6
+
7
+ The widget mixins (TextSignalMixin, SignalMixin) delegate to these functions
8
+ to remain thin glue layers.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import tkinter as tk
14
+ from dataclasses import dataclass
15
+ from typing import Any, Callable, TYPE_CHECKING
16
+
17
+ if TYPE_CHECKING:
18
+ from bootstack.core.signals import Signal
19
+
20
+
21
+ # =============================================================================
22
+ # Type Detection Helpers
23
+ # =============================================================================
24
+
25
+ def is_signal(obj: Any) -> bool:
26
+ """Check if an object is a Signal using duck typing.
27
+
28
+ Args:
29
+ obj: Object to check.
30
+
31
+ Returns:
32
+ True if object has Signal-like interface (var, subscribe, get, set).
33
+ """
34
+ return (
35
+ hasattr(obj, 'var')
36
+ and hasattr(obj, 'subscribe')
37
+ and hasattr(obj, 'get')
38
+ and hasattr(obj, 'set')
39
+ )
40
+
41
+
42
+ def is_variable(obj: Any) -> bool:
43
+ """Check if an object is a tkinter Variable.
44
+
45
+ Args:
46
+ obj: Object to check.
47
+
48
+ Returns:
49
+ True if object is a tkinter Variable instance.
50
+ """
51
+ return isinstance(obj, tk.Variable)
52
+
53
+
54
+ # =============================================================================
55
+ # Signal Binding Result
56
+ # =============================================================================
57
+
58
+ @dataclass
59
+ class SignalBinding:
60
+ """Result of normalizing a Signal or Variable for widget binding.
61
+
62
+ Attributes:
63
+ signal: The Signal instance (created or provided).
64
+ variable: The underlying tk.Variable for widget configuration.
65
+ tk_value: The value to pass to the ttk widget's configure method.
66
+ """
67
+ signal: 'Signal[Any]'
68
+ variable: tk.Variable
69
+ tk_value: tk.Variable
70
+
71
+
72
+ # =============================================================================
73
+ # Normalization Functions
74
+ # =============================================================================
75
+
76
+ def normalize_signal(
77
+ value: Any,
78
+ *,
79
+ default_value: Any = "",
80
+ ) -> SignalBinding | None:
81
+ """Normalize a Signal, Variable, or value into a SignalBinding.
82
+
83
+ This function handles the conversion logic for binding signals to widgets.
84
+ It accepts either a Signal, a tk.Variable, or passes through None/strings.
85
+
86
+ Args:
87
+ value: The value to normalize. Can be:
88
+ - A Signal instance: extracts the underlying variable
89
+ - A tk.Variable: wraps it in a Signal
90
+ - None: returns None (no binding)
91
+ - A string (Tcl variable name): returns None (let caller handle)
92
+ default_value: Default value for creating new Signals (unused for
93
+ existing Signal/Variable).
94
+
95
+ Returns:
96
+ A SignalBinding with the signal, variable, and tk_value, or None if
97
+ the value cannot be normalized (e.g., string Tcl name, None).
98
+
99
+ Examples:
100
+ >>> from bootstack.core.signals import Signal
101
+ >>> sig = Signal("hello")
102
+ >>> binding = normalize_signal(sig)
103
+ >>> binding.signal is sig
104
+ True
105
+ >>> binding.variable is sig.var
106
+ True
107
+
108
+ >>> var = tk.StringVar(value="world")
109
+ >>> binding = normalize_signal(var)
110
+ >>> binding.variable is var
111
+ True
112
+ >>> binding.signal.get()
113
+ 'world'
114
+ """
115
+ if value is None:
116
+ return None
117
+
118
+ if is_signal(value):
119
+ # It's a Signal - extract the variable
120
+ return SignalBinding(
121
+ signal=value,
122
+ variable=value.var,
123
+ tk_value=value.var,
124
+ )
125
+
126
+ if is_variable(value):
127
+ # It's a tk.Variable - wrap it in a Signal
128
+ from bootstack.core.signals import Signal
129
+ signal = Signal.from_variable(value)
130
+ return SignalBinding(
131
+ signal=signal,
132
+ variable=value,
133
+ tk_value=value,
134
+ )
135
+
136
+ # String (Tcl variable name) or other - cannot normalize
137
+ return None
138
+
139
+
140
+ def create_signal(default_value: Any) -> SignalBinding:
141
+ """Create a new Signal with the given default value.
142
+
143
+ Args:
144
+ default_value: The initial value for the Signal.
145
+
146
+ Returns:
147
+ A SignalBinding with the new signal, variable, and tk_value.
148
+
149
+ Examples:
150
+ >>> binding = create_signal("")
151
+ >>> binding.signal.get()
152
+ ''
153
+ >>> binding = create_signal(0.0)
154
+ >>> binding.signal.get()
155
+ 0.0
156
+ """
157
+ from bootstack.core.signals import Signal
158
+ signal = Signal(default_value)
159
+ return SignalBinding(
160
+ signal=signal,
161
+ variable=signal.var,
162
+ tk_value=signal.var,
163
+ )
164
+
165
+
166
+ def infer_default_value_for_widget(widget_class: str) -> Any:
167
+ """Infer an appropriate default value based on widget class.
168
+
169
+ Args:
170
+ widget_class: The Tk widget class name (e.g., "TCheckbutton", "TScale").
171
+
172
+ Returns:
173
+ An appropriate default value for the widget type:
174
+ - False for checkbuttons
175
+ - 0 for radiobuttons
176
+ - 0.0 for scales
177
+ - 0 for progressbars
178
+ - "" for others
179
+ """
180
+ # Checkbutton typically uses boolean
181
+ if widget_class in ('TCheckbutton', 'Checkbutton'):
182
+ return False
183
+ # Radiobutton typically uses int
184
+ elif widget_class in ('TRadiobutton', 'Radiobutton'):
185
+ return 0
186
+ # Scale uses float
187
+ elif widget_class in ('TScale', 'Scale'):
188
+ return 0.0
189
+ # Progressbar uses int
190
+ elif widget_class in ('TProgressbar', 'Progressbar'):
191
+ return 0
192
+ # Default to empty string
193
+ else:
194
+ return ""
195
+
196
+
197
+ # =============================================================================
198
+ # Query Functions
199
+ # =============================================================================
200
+
201
+ def query_binding(
202
+ stored_signal: 'Signal[Any] | None',
203
+ stored_variable: tk.Variable | None,
204
+ ttk_base: type,
205
+ widget: Any,
206
+ option_name: str,
207
+ ) -> 'Signal[Any] | tk.Variable | None':
208
+ """Query the current signal/variable binding for a widget option.
209
+
210
+ Returns the signal if available, otherwise the variable, otherwise
211
+ queries the widget directly.
212
+
213
+ Args:
214
+ stored_signal: The cached Signal, if any.
215
+ stored_variable: The cached Variable, if any.
216
+ ttk_base: The ttk base class for querying.
217
+ widget: The widget instance.
218
+ option_name: The option name to query ("textvariable" or "variable").
219
+
220
+ Returns:
221
+ The Signal if stored, else the Variable if stored, else the widget's
222
+ configured value for the option.
223
+ """
224
+ if stored_signal is not None:
225
+ return stored_signal
226
+ if stored_variable is not None:
227
+ return stored_variable
228
+ try:
229
+ return ttk_base.cget(widget, option_name)
230
+ except Exception:
231
+ return None
232
+
233
+
234
+ __all__ = [
235
+ "is_signal",
236
+ "is_variable",
237
+ "SignalBinding",
238
+ "normalize_signal",
239
+ "create_signal",
240
+ "infer_default_value_for_widget",
241
+ "query_binding",
242
+ ]
@@ -0,0 +1,315 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+
6
+ class WinfoMixin:
7
+ """Widget information (winfo) helpers.
8
+
9
+ Tk uses the term **window** to mean **any widget** with a Tk window handle
10
+ (not just a `Toplevel`). In bootstack documentation we use the word
11
+ **widget** unless we specifically mean a top-level window.
12
+
13
+ Tk's `winfo` command family exposes runtime information about a widget/window:
14
+ geometry, hierarchy, mapping/visibility, pointer location, screen metrics, and more.
15
+
16
+ This mixin provides thin pass-through methods with modern Google-style
17
+ docstrings for commonly used `winfo_*` APIs in Tkinter.
18
+
19
+ Intended usage:
20
+ class Widget(WinfoMixin, ttk.Widget): ...
21
+ class App(WinfoMixin, tkinter.Tk): ...
22
+ class Window(WinfoMixin, tkinter.Toplevel): ...
23
+
24
+ Notes:
25
+ - All methods delegate to the underlying Tkinter implementation.
26
+ - Many `winfo_*` values are only meaningful after the widget has been
27
+ realized and geometry has been computed. If you need up-to-date sizes,
28
+ call `update_idletasks()` first.
29
+ """
30
+
31
+ # -------------------------------------------------------------------------
32
+ # Existence / mapping / visibility
33
+ # -------------------------------------------------------------------------
34
+
35
+ def winfo_exists(self) -> int:
36
+ """Return whether this widget exists.
37
+
38
+ Returns:
39
+ 1 if the widget exists, 0 otherwise.
40
+ """
41
+ return super().winfo_exists() # type: ignore[misc]
42
+
43
+ def winfo_ismapped(self) -> int:
44
+ """Return whether this widget is currently mapped (shown) on screen.
45
+
46
+ A widget may exist but not be mapped (e.g., never packed/gridded/placed,
47
+ or explicitly unmapped).
48
+
49
+ Returns:
50
+ 1 if mapped, 0 otherwise.
51
+ """
52
+ return super().winfo_ismapped() # type: ignore[misc]
53
+
54
+ def winfo_viewable(self) -> int:
55
+ """Return whether this widget and all its ancestors are mapped.
56
+
57
+ A widget can be mapped but not viewable if an ancestor is not mapped.
58
+
59
+ Returns:
60
+ 1 if viewable, 0 otherwise.
61
+ """
62
+ return super().winfo_viewable() # type: ignore[misc]
63
+
64
+ # -------------------------------------------------------------------------
65
+ # Widget identity / hierarchy
66
+ # -------------------------------------------------------------------------
67
+
68
+ def winfo_id(self) -> int:
69
+ """Return a platform-specific identifier for the underlying window.
70
+
71
+ Returns:
72
+ An integer window identifier. Meaning varies by platform.
73
+ """
74
+ return super().winfo_id() # type: ignore[misc]
75
+
76
+ def winfo_name(self) -> str:
77
+ """Return the widget's Tk name (path component, not full path).
78
+
79
+ Returns:
80
+ The widget's name (e.g. "button", "frame", etc.).
81
+ """
82
+ return super().winfo_name() # type: ignore[misc]
83
+
84
+ def winfo_pathname(self, id: int, displayof: int | None = None) -> str:
85
+ """Return the Tk pathname for a window id.
86
+
87
+ This is an advanced helper; most apps won't need it.
88
+
89
+ Args:
90
+ id: A platform-specific window id (often from `winfo_id()`).
91
+ displayof: Optional display selector (Tk-specific). Rarely needed.
92
+
93
+ Returns:
94
+ The Tk pathname corresponding to `id`.
95
+ """
96
+ if displayof is None:
97
+ return super().winfo_pathname(id) # type: ignore[misc]
98
+ return super().winfo_pathname(id, displayof) # type: ignore[misc]
99
+
100
+ def winfo_parent(self) -> str:
101
+ """Return the Tk pathname of this widget's parent.
102
+
103
+ Returns:
104
+ The parent's Tk pathname.
105
+ """
106
+ return super().winfo_parent() # type: ignore[misc]
107
+
108
+ def winfo_toplevel(self) -> Any:
109
+ """Return the toplevel window that contains this widget.
110
+
111
+ Returns:
112
+ The toplevel widget instance.
113
+ """
114
+ return super().winfo_toplevel() # type: ignore[misc]
115
+
116
+ def winfo_children(self) -> list[Any]:
117
+ """Return this widget's direct children.
118
+
119
+ Returns:
120
+ A list of child widget instances.
121
+ """
122
+ return super().winfo_children() # type: ignore[misc]
123
+
124
+ def winfo_class(self) -> str:
125
+ """Return the Tk class name for this widget (e.g. 'TButton').
126
+
127
+ Returns:
128
+ The Tk class name string.
129
+ """
130
+ return super().winfo_class() # type: ignore[misc]
131
+
132
+ def winfo_manager(self) -> str:
133
+ """Return the geometry manager controlling this widget.
134
+
135
+ Typical values are: "pack", "grid", "place", or "" if unmanaged.
136
+
137
+ Returns:
138
+ The name of the geometry manager or an empty string.
139
+ """
140
+ return super().winfo_manager() # type: ignore[misc]
141
+
142
+ # -------------------------------------------------------------------------
143
+ # Geometry: local position/size (relative to parent)
144
+ # -------------------------------------------------------------------------
145
+
146
+ def winfo_x(self) -> int:
147
+ """Return the x-coordinate of this widget relative to its parent.
148
+
149
+ Returns:
150
+ The x position in pixels.
151
+ """
152
+ return super().winfo_x() # type: ignore[misc]
153
+
154
+ def winfo_y(self) -> int:
155
+ """Return the y-coordinate of this widget relative to its parent.
156
+
157
+ Returns:
158
+ The y position in pixels.
159
+ """
160
+ return super().winfo_y() # type: ignore[misc]
161
+
162
+ def winfo_width(self) -> int:
163
+ """Return the current width of this widget in pixels.
164
+
165
+ Note:
166
+ Geometry may be stale until Tk processes idle tasks. Use
167
+ `update_idletasks()` if you need a fresh value.
168
+
169
+ Returns:
170
+ The width in pixels.
171
+ """
172
+ return super().winfo_width() # type: ignore[misc]
173
+
174
+ def winfo_height(self) -> int:
175
+ """Return the current height of this widget in pixels.
176
+
177
+ Note:
178
+ Geometry may be stale until Tk processes idle tasks. Use
179
+ `update_idletasks()` if you need a fresh value.
180
+
181
+ Returns:
182
+ The height in pixels.
183
+ """
184
+ return super().winfo_height() # type: ignore[misc]
185
+
186
+ def winfo_reqwidth(self) -> int:
187
+ """Return the requested width (geometry request) in pixels.
188
+
189
+ This is the size the widget asks for before geometry management.
190
+
191
+ Returns:
192
+ The requested width in pixels.
193
+ """
194
+ return super().winfo_reqwidth() # type: ignore[misc]
195
+
196
+ def winfo_reqheight(self) -> int:
197
+ """Return the requested height (geometry request) in pixels.
198
+
199
+ This is the size the widget asks for before geometry management.
200
+
201
+ Returns:
202
+ The requested height in pixels.
203
+ """
204
+ return super().winfo_reqheight() # type: ignore[misc]
205
+
206
+ def winfo_rootx(self) -> int:
207
+ """Return the absolute x-coordinate of this widget on the screen.
208
+
209
+ Returns:
210
+ The screen x position in pixels.
211
+ """
212
+ return super().winfo_rootx() # type: ignore[misc]
213
+
214
+ def winfo_rooty(self) -> int:
215
+ """Return the absolute y-coordinate of this widget on the screen.
216
+
217
+ Returns:
218
+ The screen y position in pixels.
219
+ """
220
+ return super().winfo_rooty() # type: ignore[misc]
221
+
222
+ # -------------------------------------------------------------------------
223
+ # Pointer (mouse) information
224
+ # -------------------------------------------------------------------------
225
+
226
+ def winfo_pointerx(self) -> int:
227
+ """Return the pointer x-coordinate on the screen.
228
+
229
+ This returns the mouse pointer position in screen (root) coordinates.
230
+
231
+ Returns:
232
+ The screen x position of the pointer in pixels.
233
+ """
234
+ return super().winfo_pointerx() # type: ignore[misc]
235
+
236
+ def winfo_pointery(self) -> int:
237
+ """Return the pointer y-coordinate on the screen.
238
+
239
+ This returns the mouse pointer position in screen (root) coordinates.
240
+
241
+ Returns:
242
+ The screen y position of the pointer in pixels.
243
+ """
244
+ return super().winfo_pointery() # type: ignore[misc]
245
+
246
+ def winfo_pointerxy(self) -> tuple[int, int]:
247
+ """Return the pointer (x, y) coordinates on the screen.
248
+
249
+ Returns:
250
+ A tuple (x, y) in screen (root) coordinates.
251
+ """
252
+ return super().winfo_pointerxy() # type: ignore[misc]
253
+
254
+ def winfo_containing(self, rootx: int, rooty: int) -> Any:
255
+ """Return the widget that contains the given screen coordinate.
256
+
257
+ Args:
258
+ rootx: Screen x coordinate in pixels.
259
+ rooty: Screen y coordinate in pixels.
260
+
261
+ Returns:
262
+ The widget instance at that screen coordinate, or None if no widget
263
+ is present at that location.
264
+ """
265
+ return super().winfo_containing(rootx, rooty) # type: ignore[misc]
266
+
267
+ # -------------------------------------------------------------------------
268
+ # Screen / display metrics
269
+ # -------------------------------------------------------------------------
270
+
271
+ def winfo_screenwidth(self) -> int:
272
+ """Return the width of the screen in pixels.
273
+
274
+ Returns:
275
+ Screen width in pixels.
276
+ """
277
+ return super().winfo_screenwidth() # type: ignore[misc]
278
+
279
+ def winfo_screenheight(self) -> int:
280
+ """Return the height of the screen in pixels.
281
+
282
+ Returns:
283
+ Screen height in pixels.
284
+ """
285
+ return super().winfo_screenheight() # type: ignore[misc]
286
+
287
+ def winfo_fpixels(self, number: str) -> float:
288
+ """Convert a distance string to pixels (floating point).
289
+
290
+ Tk distance strings can include units like:
291
+ - "c" (centimeters)
292
+ - "i" (inches)
293
+ - "m" (millimeters)
294
+ - "p" (points)
295
+
296
+ Plain numbers are pixels.
297
+
298
+ Args:
299
+ number: A Tk distance string (e.g. "2c", "0.5i", "10").
300
+
301
+ Returns:
302
+ The distance in pixels as a float.
303
+ """
304
+ return super().winfo_fpixels(number) # type: ignore[misc]
305
+
306
+ def winfo_pixels(self, number: str) -> int:
307
+ """Convert a distance string to pixels (integer).
308
+
309
+ Args:
310
+ number: A Tk distance string (e.g. "2c", "0.5i", "10").
311
+
312
+ Returns:
313
+ The distance in pixels as an int (rounded by Tk).
314
+ """
315
+ return super().winfo_pixels(number) # type: ignore[misc]