pgwidgets-js 0.2.3__tar.gz → 0.3.1__tar.gz

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 (204) hide show
  1. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/PKG-INFO +1 -1
  2. pgwidgets_js-0.3.1/docs/WhatsNew.rst +599 -0
  3. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/docs/for-developers.rst +170 -31
  4. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/docs/styling.rst +114 -0
  5. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/docs/widgets/display.rst +107 -10
  6. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/docs/widgets/layout.rst +12 -0
  7. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/docs/widgets/text.rst +7 -1
  8. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/package.json +1 -1
  9. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/defs.py +43 -2
  10. pgwidgets_js-0.3.1/pgwidgets_js/static/css/Image.css +59 -0
  11. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/TreeView.css +28 -0
  12. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/Widget.css +14 -0
  13. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/AbstractScrollArea.js +0 -6
  14. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/Box.js +44 -12
  15. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/Button.js +0 -8
  16. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/Callback.js +11 -6
  17. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/Canvas.js +0 -5
  18. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/CheckBox.js +0 -5
  19. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/ColorDialog.js +0 -4
  20. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/ColorWidget.js +0 -3
  21. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/ComboBox.js +0 -18
  22. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/ComboBoxNative.js +0 -11
  23. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/Dial.js +3 -15
  24. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/Dialog.js +0 -7
  25. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/ExternalWidget.js +0 -4
  26. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/FileDialog.js +11 -8
  27. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/FixedLayout.js +0 -1
  28. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/Frame.js +0 -5
  29. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/GridBox.js +0 -14
  30. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/HtmlView.js +0 -10
  31. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/Image.js +48 -22
  32. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/Label.js +25 -10
  33. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/MDIWidget.js +0 -40
  34. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/Menu.js +0 -9
  35. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/MenuAction.js +0 -10
  36. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/MenuBar.js +1 -8
  37. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/ProgressBar.js +0 -4
  38. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/RadioButton.js +1 -7
  39. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/RemoteInterface.js +386 -41
  40. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/ScrollArea.js +0 -1
  41. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/ScrollBar.js +0 -6
  42. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/Slider.js +1 -9
  43. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/SpinBox.js +1 -9
  44. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/Splitter.js +6 -8
  45. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/StatusBar.js +0 -4
  46. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/TabWidget.js +1 -18
  47. pgwidgets_js-0.3.1/pgwidgets_js/static/modules/TableView.js +85 -0
  48. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/TextArea.js +0 -10
  49. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/TextEntry.js +1 -10
  50. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/TextEntrySet.js +0 -3
  51. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/TextSource.js +34 -21
  52. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/TextWidget.js +0 -5
  53. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/Timer.js +0 -11
  54. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/ToggleButton.js +1 -7
  55. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/ToolBar.js +0 -5
  56. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/ToolBarAction.js +2 -12
  57. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/TopLevel.js +0 -16
  58. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/TreeView.js +932 -53
  59. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/VideoWidget.js +0 -19
  60. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/Widget.js +48 -35
  61. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js.egg-info/PKG-INFO +1 -1
  62. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js.egg-info/SOURCES.txt +1 -0
  63. pgwidgets_js-0.3.1/tests/test_recent_additions.py +108 -0
  64. pgwidgets_js-0.2.3/docs/WhatsNew.rst +0 -273
  65. pgwidgets_js-0.2.3/pgwidgets_js/static/css/Image.css +0 -23
  66. pgwidgets_js-0.2.3/pgwidgets_js/static/modules/TableView.js +0 -41
  67. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/.flake8 +0 -0
  68. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/.github/workflows/tests.yml +0 -0
  69. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/.gitignore +0 -0
  70. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/.readthedocs.yaml +0 -0
  71. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/LICENSE.md +0 -0
  72. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/MANIFEST.in +0 -0
  73. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/README.md +0 -0
  74. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/Widgets.css +0 -0
  75. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/Widgets.js +0 -0
  76. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/docs/Makefile +0 -0
  77. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/docs/callbacks.rst +0 -0
  78. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/docs/conf.py +0 -0
  79. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/docs/electron.rst +0 -0
  80. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/docs/external-widgets.rst +0 -0
  81. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/docs/frameworks.rst +0 -0
  82. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/docs/getting-started.rst +0 -0
  83. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/docs/index.rst +0 -0
  84. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/docs/pyodide.rst +0 -0
  85. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/docs/remote.rst +0 -0
  86. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/docs/widgets/controls.rst +0 -0
  87. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/docs/widgets/dialogs.rst +0 -0
  88. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/docs/widgets/index.rst +0 -0
  89. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/docs/widgets/menus.rst +0 -0
  90. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/docs/widgets/nonvisual.rst +0 -0
  91. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/all_widgets.html +0 -0
  92. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/all_widgets_pyodide.html +0 -0
  93. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/all_widgets_pyodide.py +0 -0
  94. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/all_widgets_pyscript.html +0 -0
  95. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/all_widgets_pyscript.py +0 -0
  96. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/box.html +0 -0
  97. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/button.html +0 -0
  98. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/canvas.html +0 -0
  99. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/checkbox.html +0 -0
  100. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/colordialog.html +0 -0
  101. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/combobox.html +0 -0
  102. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/debug_spinbox.html +0 -0
  103. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/dial.html +0 -0
  104. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/dialog.html +0 -0
  105. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/electron/.gitignore +0 -0
  106. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/electron/.npmrc +0 -0
  107. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/electron/index.html +0 -0
  108. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/electron/main.js +0 -0
  109. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/electron/package.json +0 -0
  110. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/expander.html +0 -0
  111. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/external_widgets.html +0 -0
  112. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/fixedlayout.html +0 -0
  113. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/frame.html +0 -0
  114. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/gridbox.html +0 -0
  115. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/htmlview.html +0 -0
  116. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/image.html +0 -0
  117. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/label.html +0 -0
  118. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/mdi_widget.html +0 -0
  119. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/menu.html +0 -0
  120. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/progressbar.html +0 -0
  121. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/pyodide_demo.html +0 -0
  122. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/pyscript.toml +0 -0
  123. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/radiobutton.html +0 -0
  124. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/remote.html +0 -0
  125. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/remote_demo.py +0 -0
  126. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/remote_demo_async.py +0 -0
  127. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/scroll_area.html +0 -0
  128. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/scrollable.html +0 -0
  129. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/scrollbar.html +0 -0
  130. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/slider.html +0 -0
  131. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/spinbox.html +0 -0
  132. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/splitter.html +0 -0
  133. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/tab_widget.html +0 -0
  134. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/tableview.html +0 -0
  135. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/text_entry.html +0 -0
  136. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/textarea.html +0 -0
  137. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/textentryset.html +0 -0
  138. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/textsource.html +0 -0
  139. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/togglebutton.html +0 -0
  140. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/toolbar.html +0 -0
  141. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/treeview.html +0 -0
  142. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/examples/videowidget.html +0 -0
  143. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/__init__.py +0 -0
  144. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/pyodide/__init__.py +0 -0
  145. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/pyodide/log.py +0 -0
  146. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/pyodide/widget.py +0 -0
  147. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/Widgets.css +0 -0
  148. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/Widgets.js +0 -0
  149. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/AbstractScrollArea.css +0 -0
  150. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/Box.css +0 -0
  151. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/Button.css +0 -0
  152. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/CheckBox.css +0 -0
  153. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/ColorDialog.css +0 -0
  154. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/ComboBox.css +0 -0
  155. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/Dial.css +0 -0
  156. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/Dialog.css +0 -0
  157. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/Expander.css +0 -0
  158. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/ExternalWidget.css +0 -0
  159. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/FixedLayout.css +0 -0
  160. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/Frame.css +0 -0
  161. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/GridBox.css +0 -0
  162. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/HtmlView.css +0 -0
  163. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/Label.css +0 -0
  164. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/MDIWidget.css +0 -0
  165. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/Menu.css +0 -0
  166. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/ProgressBar.css +0 -0
  167. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/RadioButton.css +0 -0
  168. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/ScrollArea.css +0 -0
  169. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/ScrollBar.css +0 -0
  170. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/Slider.css +0 -0
  171. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/SpinBox.css +0 -0
  172. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/Splitter.css +0 -0
  173. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/StatusBar.css +0 -0
  174. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/TabWidget.css +0 -0
  175. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/Text.css +0 -0
  176. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/TextArea.css +0 -0
  177. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/TextEntrySet.css +0 -0
  178. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/TextSource.css +0 -0
  179. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/ToggleButton.css +0 -0
  180. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/ToolBar.css +0 -0
  181. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/TopLevel.css +0 -0
  182. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/VideoWidget.css +0 -0
  183. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/css/WindowMenu.css +0 -0
  184. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/icons/file.svg +0 -0
  185. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/icons/folder.svg +0 -0
  186. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/icons/hdots.svg +0 -0
  187. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/icons/pgicon.svg +0 -0
  188. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/icons/pgwidgets-logo.png +0 -0
  189. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/icons/pgwidgets-logo.svg +0 -0
  190. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/icons/vdots.svg +0 -0
  191. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/Expander.js +0 -0
  192. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/Page.js +0 -0
  193. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/modules/WindowMenu.js +0 -0
  194. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js/static/remote.html +0 -0
  195. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js.egg-info/dependency_links.txt +0 -0
  196. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js.egg-info/requires.txt +0 -0
  197. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pgwidgets_js.egg-info/top_level.txt +0 -0
  198. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/pyproject.toml +0 -0
  199. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/setup.cfg +0 -0
  200. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/setup.py +0 -0
  201. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/tests/__init__.py +0 -0
  202. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/tests/test_consistency.py +0 -0
  203. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/tests/test_defs.py +0 -0
  204. {pgwidgets_js-0.2.3 → pgwidgets_js-0.3.1}/tests/test_static_assets.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pgwidgets-js
3
- Version: 0.2.3
3
+ Version: 0.3.1
4
4
  Summary: pgwidgets JavaScript widget library — static assets for use with Python servers
5
5
  Author: PGWidgets Developers
6
6
  License: BSD-3-Clause
@@ -0,0 +1,599 @@
1
+ What's New
2
+ ==========
3
+
4
+ Recent changes — since ``v0.3.0``
5
+ ---------------------------------
6
+
7
+ Custom fonts: ``register-font`` / ``set-default-font``
8
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9
+
10
+ Two new remote-protocol message types let the Python side push
11
+ custom font files to the browser and apply a document-wide
12
+ default font.
13
+
14
+ * ``register-font`` -- the JS handler creates a ``FontFace``,
15
+ awaits its ``load()``, and adds it to ``document.fonts``,
16
+ after which any widget ``set_font(family, ...)`` resolves
17
+ against it. The accompanying ``url`` is resolved against
18
+ ``window.location.href`` so the same path works under the
19
+ built-in HTTP server, Flask / nginx, and pyodide.
20
+ * ``set-default-font`` -- manages a single
21
+ ``<style id="pg-default-font">`` element on ``<head>`` that
22
+ writes ``--pg-default-font-{family,size,weight,style}`` CSS
23
+ variables on ``:root``. The base ``body`` rule consumes
24
+ those variables with safe fallbacks
25
+ (``sans-serif`` / ``13px`` / ``normal`` / ``normal``), so
26
+ apps that never opt in see no behavioural change. Per-
27
+ widget ``set_font(...)`` still wins via inline-style
28
+ specificity.
29
+
30
+ Weight / style normalisation in the JS handler translates
31
+ descriptive TTF metadata names -- ``thin``, ``light``,
32
+ ``medium``, ``semibold``, ``extrabold``, ``black``, ``heavy``,
33
+ etc. -- to the numeric CSS values per the CSS Fonts spec, so
34
+ fonts shipped with descriptive weight names load without
35
+ raising ``Invalid font descriptor`` errors. Numeric strings
36
+ and valid CSS keywords pass through unchanged.
37
+
38
+ See :ref:`custom-fonts` for the matching Python-side API.
39
+
40
+ TreeView: column-boundary alignment
41
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
42
+
43
+ Three related fixes keep the header columns pinned to the body
44
+ columns in every case:
45
+
46
+ * ``_syncScrollbars`` writes ``this._header.style.width =
47
+ this._body.scrollWidth`` so ``1fr`` grid units resolve to
48
+ identical pixel widths in the header and body grids -- a
49
+ body grown to ``max-content`` by wide row content no longer
50
+ drifts wider than the header.
51
+ * ``_gridTemplate`` wraps every ``fr`` track in
52
+ ``minmax(0, fr)``. Without it a single widget cell whose
53
+ content can't shrink (a ``<button>Reset</button>`` or
54
+ ``<select>``) forces its column wider than the matching
55
+ empty-content header track; ``minmax(0, fr)`` lets the
56
+ ``fr`` distribution dominate. Oversize content is clipped
57
+ by the cell's own ``overflow: hidden``.
58
+ * ``_setupColumnResize`` lowers the minimum drag width from
59
+ 30 px to 5 px so genuinely small icon / checkbox columns
60
+ (``colwidth: 10`` and similar) can be resized instead of
61
+ inflating to 30 the moment a drag starts.
62
+
63
+ Image (animation-frame): wrapper div
64
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
65
+
66
+ Animation-frame ``Image`` mode wraps its canvas in a
67
+ ``<div class="image-widget">`` and positions the canvas
68
+ ``absolute; inset: 0; width: 100%; height: 100%``. The wrapper
69
+ sits in the layout chain like any plain block, and absolutely-
70
+ positioned children contribute zero to their parent's
71
+ auto-resolved size -- so writing ``canvas.width`` /
72
+ ``canvas.height`` in the resize callback (which the browser
73
+ mirrors back as an ``aspect-ratio: auto W/H`` presentational
74
+ hint) can no longer feed back into layout. Resolves the
75
+ runaway-vertical-growth feedback loop that ``contain: size`` on
76
+ a bare canvas couldn't fully gate.
77
+
78
+ The wrapper has no width/height of its own -- callers must
79
+ give it size via ``set_expanding(True, True)``, packing with
80
+ ``stretch > 0``, or ``resize(w, h)``.
81
+
82
+ Box / Widget: respect user-set min sizes
83
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
84
+
85
+ ``Box._applyBoxChildSizing`` (in the ``stretch > 0`` and
86
+ ``mainExpand`` branches) and ``Widget.set_expanding`` were
87
+ both writing ``min-width: 0`` / ``min-height: 0`` unconditionally
88
+ to override the browser's default ``min: auto`` on flex items.
89
+ Either of them running second silently erased a floor declared
90
+ via ``set_min_size``. Both call sites now guard with
91
+ ``if (!s.minWidth) s.minWidth = '0'`` so user-set mins survive
92
+ regardless of call order.
93
+
94
+ TreeView / TableView: widget-typed cells
95
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
96
+
97
+ Column descriptors gained an optional ``widget`` field that
98
+ swaps a column's plain-text cells for a real DOM input element:
99
+
100
+ * ``"checkbox"`` -- ``<input type="checkbox">`` bound to a
101
+ boolean cell value;
102
+ * ``"combobox"`` -- ``<select>`` populated from a ``choices``
103
+ array;
104
+ * ``"progress"`` -- ``<progress>`` driven by ``min`` / ``max``
105
+ (read-only);
106
+ * ``"button"`` -- ``<button>`` whose label is the cell value
107
+ (or the column's ``text`` fallback).
108
+
109
+ Editable widget cells fire ``cell_edited(widget, path, col_key,
110
+ old, new)``; buttons fire a new ``cell_action(widget,
111
+ row_values, col_key)`` callback. Two more column-descriptor
112
+ keys gate the per-row widget by row-dict field name:
113
+ ``enabled_key`` (greys the widget out when the named field is
114
+ falsy) and ``visible_key`` (suppresses the widget entirely on
115
+ that row -- the cell stays empty).
116
+
117
+ .. code-block:: javascript
118
+
119
+ table.set_columns([
120
+ {label: "Name", key: "NAME", type: "string"},
121
+ {label: "Done", key: "DONE", type: "bool",
122
+ widget: "checkbox", enabled_key: "CAN_EDIT"},
123
+ {label: "", key: "GO", type: "string",
124
+ widget: "button", text: "Open",
125
+ visible_key: "OPENABLE"},
126
+ ]);
127
+
128
+ Cell / row / column / table colour overrides
129
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
130
+
131
+ Four new override layers paint cells without touching the
132
+ underlying data: ``set_cell_color(path, col_key, fg, bg, bold)``,
133
+ ``set_row_color(path, fg, bg, bold)``, ``set_column_color(col_key,
134
+ fg, bg, bold)``, and ``set_table_color(fg, bg, bold)``.
135
+ Specificity cascades cell → row → column → table per-channel,
136
+ so a row-level fg + column-level bg compose into the same
137
+ cell. Each method also accepts an optional ``bold`` argument
138
+ that toggles the cell font weight.
139
+
140
+ Matching ``clear_*_color`` helpers and ``clear_all_colors()``
141
+ drop overrides at any layer.
142
+
143
+ Cell-level selection and clipboard
144
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
145
+
146
+ TreeView / TableView gained two new ``selection_mode`` values --
147
+ ``"single-cell"`` and ``"multiple-cell"`` -- that let the user
148
+ select individual cells rather than whole rows. Cell selections
149
+ fire a new ``cell_selected`` callback with the list of selected
150
+ ``{path, col_key, value}`` cells.
151
+
152
+ Widget-level Ctrl/Cmd+C/X/V keyboard handlers feed three new
153
+ callbacks: ``copy``, ``cut``, ``paste``. The
154
+ ``copy_selection`` / ``cut_selection`` / ``paste_selection``
155
+ methods do the same programmatically. Cell-mode cuts emit a
156
+ TSV payload built from the selected cells; row mode emits the
157
+ whole row.
158
+
159
+ ``activated`` callback now reports the clicked column
160
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
161
+
162
+ The ``activated`` callback signature gained a 4th argument:
163
+ ``(widget, values, path, col_key)``. Handlers that destructure
164
+ the first three keep working; new code can branch on which
165
+ column the user double-clicked.
166
+
167
+ Widget: ``set_bg`` + Label: ``set_valign``
168
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
169
+
170
+ Two small style helpers:
171
+
172
+ * ``Widget.set_bg(color)`` on the base class -- generic
173
+ background-colour setter, accepts a CSS string or ``null``
174
+ to clear. Works on transparent containers (Box / Grid /
175
+ ScrollArea) too.
176
+ * ``Label.set_valign(align)`` -- ``"top"`` / ``"center"`` /
177
+ ``"bottom"`` vertical placement of the label text within
178
+ whatever vertical space the parent allocates. Only visible
179
+ when the label is given more height than its text needs.
180
+
181
+ Box: ``set_align`` (cross-axis)
182
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
183
+
184
+ Boxes (and the ``HBox`` / ``VBox`` shortcuts) gained a single
185
+ orientation-aware ``set_align(align)`` method controlling the
186
+ cross-axis placement of children:
187
+
188
+ * horizontal box → ``"top"`` / ``"center"`` / ``"bottom"``;
189
+ * vertical box → ``"left"`` / ``"center"`` / ``"right"``.
190
+
191
+ Mismatched names raise. Maps to flex ``align-items`` on the
192
+ box element.
193
+
194
+ TableView: positional row API
195
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
196
+
197
+ ``TableView`` gained an explicit positional-row API so callers
198
+ that maintain row data as positional arrays (one common
199
+ cross-backend pattern) don't have to wrap every row in a dict:
200
+
201
+ * ``set_data(rows)`` now accepts either a list of dicts
202
+ (preferred, keyed by column key) *or* a list of positional
203
+ arrays mapped to columns in order.
204
+ * ``insert_row(index, values)`` -- new method. ``values`` is
205
+ a dict or an array; ``index`` is the 0-based visible
206
+ position, out-of-range clamps to append. Returns the new
207
+ row's path so the caller can address it afterwards.
208
+ * ``append_row(values)`` is the index-at-end shortcut.
209
+
210
+ The row-key generator stays internal (``row0``, ``row1`` ...);
211
+ sort order, selection, and the per-cell colour overrides all
212
+ follow rows by key rather than by visible index, so positional
213
+ inserts compose with the existing higher-level APIs.
214
+
215
+ Other improvements
216
+ ~~~~~~~~~~~~~~~~~~
217
+
218
+ * TreeView: fix two cell-editing / rendering bugs. The per-
219
+ cell ``dblclick`` handler captured the loop counter ``i``
220
+ from the *outer* scope -- which had already advanced past
221
+ the row by the time the click fired -- and a sibling
222
+ rendering path miscomputed the row index when columns were
223
+ hidden. Both surfaced when wiring inline editing through
224
+ cross-backend table widgets.
225
+
226
+ ----
227
+
228
+ Recent changes — since ``v0.2.3``
229
+ ---------------------------------
230
+
231
+ Chunked binary transport (both directions, raw frames)
232
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
233
+
234
+ The remote interface gained a unified chunked binary transport
235
+ that works in both directions and ships raw binary WebSocket
236
+ frames by default. A new ``binary-call-chunked`` announce opens
237
+ a transfer; subsequent ``binary-chunk`` messages each carry a
238
+ JSON header plus one raw binary frame (or, optionally, an
239
+ inline base64 payload). Optional ``shape`` + ``dtype`` fields on
240
+ the announce promote the reassembled payload from a raw
241
+ ``ArrayBuffer`` to a typed array (``Uint8Array``,
242
+ ``Float32Array``, …) before dispatch — the JS-side companion to
243
+ pgwidgets-python's new :class:`pgwidgets.Buffer` descriptor.
244
+
245
+ The browser-side file upload path was migrated to the same
246
+ envelope. Drag-and-drop and ``FileDialog`` now read files with
247
+ ``readAsArrayBuffer`` instead of ``readAsDataURL`` and ship the
248
+ bytes via binary frames; the ``payload.files[i].data`` field is
249
+ now an ``ArrayBuffer`` (JavaScript side) / ``bytes`` (Python
250
+ side) rather than a ``"data:<mime>;base64,…"`` string. Each
251
+ file dict carries an explicit ``encoding`` field (currently
252
+ always ``"bytes"``; reserved for future ``"base64"``) so
253
+ receivers can branch on it.
254
+
255
+ **Pre-1.0 API break**: any drop or FileDialog handler that did
256
+ ``base64.b64decode(data.split(",", 1)[1])`` should now just use
257
+ ``data`` directly.
258
+
259
+ Constructor-bind hack removed
260
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
261
+
262
+ The legacy ``this.foo = this.foo.bind(this)`` constructor lines
263
+ were removed from every widget module — 443 line deletions
264
+ across 48 files. The codebase never relied on bare method
265
+ references (DOM handlers etc. use arrow wrappers), so the
266
+ preemptive binding was redundant. A handful of places that
267
+ *did* register handlers via ``addEventListener("event",
268
+ this.method)`` were converted to class-field arrow methods
269
+ (``onMouseMove = (e) => { ... }``) so the handler identity is
270
+ stable per instance — critical for the paired
271
+ ``removeEventListener`` to find the same function.
272
+
273
+ **Pre-1.0 API break**: code outside the library that passed a
274
+ pgwidgets method as a bare reference (``setTimeout(button.set_text,
275
+ 0)``, ``el.addEventListener("click", widget.foo)``, etc.) must
276
+ now wrap with an arrow at the call site (``() =>
277
+ button.set_text(s)``) or apply ``.bind`` itself.
278
+
279
+ Wid-collision fix in ``_handleCreate``
280
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
281
+
282
+ When a class registered in ``classMap`` doesn't extend
283
+ ``Callback`` (e.g. a plain JS class layered on top of
284
+ pgwidgets-js — gingajs's ``Controller`` is one), its constructor
285
+ doesn't allocate a wid. The next widget's ``super()`` would
286
+ then auto-assign a wid that the previous Python-allocated widget
287
+ was sitting at, silently overwriting it in the registry.
288
+ Two complementary safeguards:
289
+
290
+ - ``_handleCreate`` now bumps ``Callback._nextId`` past
291
+ ``msg.wid`` *before* calling ``new cls(...)``.
292
+ - ``Callback``'s constructor skips occupied registry slots when
293
+ allocating, as a defensive backstop.
294
+
295
+ A binding that only ever uses classes which extend ``Callback``
296
+ is safe without either mitigation, but having both removes a
297
+ whole class of mysterious "Unknown widget id" errors.
298
+
299
+ TreeView: per-column ``colwidth``
300
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
301
+
302
+ Column descriptors accept an optional ``colwidth`` field set
303
+ initial column widths declaratively::
304
+
305
+ tree.set_columns([
306
+ {label: "Name", key: "NAME", type: "string", colwidth: 240},
307
+ {label: "Type", key: "TYPE", type: "string", colwidth: "10em"},
308
+ {label: "Size", key: "SIZE", type: "integer"}, // -> 1fr
309
+ ])
310
+
311
+ Numbers are treated as pixels; strings pass through as CSS grid
312
+ track values. Columns without ``colwidth`` keep the previous
313
+ default of ``"1fr"``. ``set_column_width(key, w)`` continues to
314
+ work for runtime adjustments.
315
+
316
+ Other improvements
317
+ ~~~~~~~~~~~~~~~~~~
318
+
319
+ - ``TextSource`` gained internal ``_setCursorOffset`` /
320
+ ``_setSelectionOffsets`` helpers used by the ref-binding
321
+ machinery on reconstruction.
322
+ - For-developers documentation expanded: the "Things That Will
323
+ Bite You" section now covers the wid-collision rule, the
324
+ ``encoding`` field on chunks, atomic chunk emission, indexed
325
+ reassembly, dtype-falls-back-to-ArrayBuffer, and the
326
+ ``f.data``-is-bytes API break.
327
+
328
+ ----
329
+
330
+ Recent changes — since ``v0.2.1``
331
+ ---------------------------------
332
+
333
+ TextSource: TextBufferRef objects replace raw offsets
334
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
335
+
336
+ ``TextSource`` and ``TextArea`` (which embeds a ``TextSource``) now
337
+ take and return ``TextBufferRef`` objects in place of raw character
338
+ offsets. A ref tracks a position in the buffer as edits happen
339
+ around it, so a cursor or selection endpoint stays attached to "the
340
+ character it was on" rather than being silently shifted by an
341
+ unrelated insert.
342
+
343
+ ``TextBufferRef`` is itself a ``Callback`` subclass with a wid, so
344
+ refs are first-class objects that cross the WebSocket wire. This
345
+ lets the Python binding return refs from ``create_ref`` /
346
+ ``get_cursor`` / ``set_cursor`` and pass them straight into other
347
+ methods. Named refs (``create_ref("bookmark1", ...)``) make it
348
+ easy to revisit a tracked location, and unused refs are reclaimed
349
+ via weak-reference tracking.
350
+
351
+ New ``TextBufferRef`` navigation / mutation methods include
352
+ ``next_char``, ``prev_char``, ``next_word``, ``prev_word``,
353
+ ``line_start``, ``line_end``, ``insert``, ``delete_forward``,
354
+ ``delete_backward``, and comparison helpers.
355
+
356
+ Widget: ``map`` lifecycle callback
357
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
358
+
359
+ Every visual widget now fires a one-shot ``map`` callback the first
360
+ time it gains a non-zero visible box on the page. This is the
361
+ right hook for code that needs the widget's real laid-out size
362
+ before it can run — for example, generating a server-side bitmap
363
+ that exactly matches an ``Image`` widget's flex-allocated size.
364
+
365
+ ``map`` fires reliably across reconnection / reconstruction. The
366
+ ``RemoteInterface`` keeps two ``requestAnimationFrame`` backstops
367
+ at the end of reconstruction: a visibility-aware re-check, and a
368
+ force-fire pass for widgets in detached subtrees (e.g. inactive
369
+ ``TabWidget`` pages) so handlers run even before the user opens
370
+ that tab.
371
+
372
+ ``set_expanding(horizontal, vertical)``
373
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
374
+
375
+ New base-class size policy method, mirroring Qt's
376
+ ``QSizePolicy::Expanding``. A widget with ``set_expanding(True,
377
+ True)`` will fill the available space along both axes inside a
378
+ flex container.
379
+
380
+ Image: native-resolution rendering, no drawImage scaling
381
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
382
+
383
+ In ``use_animation_frame`` mode the canvas drawing-buffer is now
384
+ pinned to the image's natural size and ``drawImage`` runs at native
385
+ scale. The browser's CSS-box scaling handles display sizing
386
+ without us re-encoding pixels — so a server-generated image that
387
+ was rendered to match the widget's reported size never gets
388
+ re-scaled into a mismatched aspect ratio.
389
+
390
+ ``set_min_size`` / ``set_max_size`` work again in animation mode,
391
+ and the canvas can shrink inside a flex container (``min-width:
392
+ 0``). After reconstruction, a synthetic ``resize`` and
393
+ ``area-resize`` are fired at the final layout-settled size so
394
+ handlers that regenerate sized content catch up.
395
+
396
+ Other improvements
397
+ ~~~~~~~~~~~~~~~~~~
398
+
399
+ - ``Menu`` popup z-index raised to ``1000000`` so popups stay above
400
+ any ``TopLevel`` that has been ``raise_()``-d a few times
401
+ (``raise_()`` assigns ``max + 1`` across all ``document.body``
402
+ children, including open menus, so a small menu z-index could
403
+ eventually be overtaken).
404
+ - ``RadioButton`` defaults to ``sans-serif`` to match
405
+ ``Label`` / ``Menu`` / ``ToolBar`` / ``StatusBar`` / etc.
406
+ - New documentation page: :doc:`for-developers`, aimed at someone
407
+ implementing a new language binding or transport. Covers the
408
+ WebSocket message protocol, serialization rules, widget identity
409
+ and creation, callback subscription, server-side state tracking,
410
+ and the full step-by-step of reconstruction (including the
411
+ subtle passive-vs-user-set-state distinction).
412
+ - New project logo.
413
+
414
+ ----
415
+
416
+ Earlier — since ``v0.1.2``
417
+ --------------------------
418
+
419
+ Major changes
420
+ ~~~~~~~~~~~~~
421
+
422
+ TreeView: dict-tree model with stable key paths
423
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
424
+
425
+ ``TreeView`` (and its subclass ``TableView``) now stores tree data as
426
+ a hierarchy of dicts keyed by stable string identifiers. Paths to
427
+ nodes are arrays of those keys, so a path stays valid no matter how
428
+ the visible tree is sorted.
429
+
430
+ .. code-block:: javascript
431
+
432
+ tree.set_tree({
433
+ "Documents": {
434
+ "report.pdf": {TYPE: "PDF", SIZE: 2400},
435
+ "notes.txt": {TYPE: "Text", SIZE: 12},
436
+ },
437
+ "Pictures": {
438
+ "photo.jpg": {TYPE: "JPEG", SIZE: 3200},
439
+ },
440
+ });
441
+
442
+ The first column auto-displays the node's dict key when the row
443
+ supplies no value for it, so most interiors need no explicit values
444
+ at all. Mixed dicts (primitives plus nested objects) split
445
+ automatically: the primitives become the interior's own column
446
+ values; the objects become its children. An ``__values__`` sentinel
447
+ is available for the rare case where the split is ambiguous. See
448
+ :ref:`widget-treeview` for the full reference.
449
+
450
+ Column descriptors and types
451
+ """"""""""""""""""""""""""""
452
+
453
+ Columns now carry a stable ``key`` (auto-generated as ``_col0``,
454
+ ``_col1`` ... if not supplied), and a richer set of types:
455
+ ``"string"`` (alias ``"str"``), ``"integer"`` (alias ``"int"``),
456
+ ``"float"`` (alias ``"number"``), ``"boolean"`` (renders ✓ when
457
+ truthy), and ``"icon"``. An ``halign`` field controls horizontal
458
+ alignment with sensible per-type defaults (numeric → right,
459
+ boolean / icon → center, otherwise left).
460
+
461
+ All per-column / per-row methods now take a key (not an index):
462
+ ``set_column_width(col_key, width)``,
463
+ ``sort_by_column(col_key, ascending)``,
464
+ ``insert_column(column, before=null)``, ``delete_column(col_key)``,
465
+ ``set_cell(path, col_key, value)``, etc.
466
+
467
+ Auto-spanning
468
+ """""""""""""
469
+
470
+ Within a row, a column whose key is missing (or whose value is
471
+ ``null``/``undefined``) is "absent" and the preceding present cell
472
+ extends across it via CSS grid spans. Explicit empty strings still
473
+ render as their own (empty) cell. This lets parent rows be terse:
474
+ ``{NAME: "Documents"}`` with the rest of the columns omitted
475
+ renders as a single cell across the row.
476
+
477
+ New tree methods
478
+ """"""""""""""""
479
+
480
+ - ``add_tree(tree, parent=null)`` -- merge a dict-tree under a
481
+ parent path; existing same-key children are replaced subtree-deep.
482
+ - ``update_tree(tree)`` -- replace the tree, but preserve selection
483
+ by path (previously ``set_tree`` cleared selection unconditionally).
484
+ - ``get_subtree(status)`` -- return a dict-tree containing
485
+ ``"all"``, ``"selected"``, ``"expanded"``, or ``"collapsed"``
486
+ nodes (with descendants and ancestors so the result is connected).
487
+ - ``clear_selection()`` -- explicit method to drop all selection.
488
+ - ``set_sortable(tf)`` -- toggle click-to-sort.
489
+
490
+ Window controls (TopLevel and MDISubWindow)
491
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
492
+
493
+ ``TopLevel`` now supports the same window controls that
494
+ ``MDISubWindow`` has, plus a "shade" (roll up to title bar) state
495
+ on both.
496
+
497
+ New ``TopLevel`` options (all default ``false`` except
498
+ ``shadeable`` which defaults ``true``):
499
+
500
+ - ``minimizable`` -- show a minimize button. Minimized windows
501
+ auto-stack along the bottom of the viewport, wrapping rows when
502
+ full.
503
+ - ``maximizable`` -- show a maximize button. Maximize fills the
504
+ browser viewport (snapshot at click time; doesn't follow viewport
505
+ resizes).
506
+ - ``lowerable`` -- show a send-to-back button.
507
+ - ``shadeable`` -- allow rolling up to just the title bar. Default
508
+ ``true``. Available from the right-click context menu and via
509
+ double-click on the title bar.
510
+ - ``icon`` -- URL or ``data:`` URI for a title-bar icon.
511
+
512
+ New methods: ``set_icon(url)``, ``toggle_minimize()``,
513
+ ``toggle_maximize()``, ``toggle_shade()``,
514
+ ``set_window_state(state)``, ``get_window_state()``.
515
+
516
+ New callback: ``window-state`` -- fires with the new state name
517
+ (``"normal"``, ``"shaded"``, ``"minimized"``, ``"maximized"``).
518
+ The Python side syncs this so window state survives reconnect.
519
+
520
+ ``MDIWidget.add_widget`` accepts ``shadeable`` (default ``true``).
521
+ Sub-windows gain ``toggle_shade()`` and the right-click context menu.
522
+ The active (topmost) sub-window's title bar is now drawn slightly
523
+ lighter, like the active tab in a TabWidget.
524
+
525
+ Right-click title-bar context menu
526
+ """"""""""""""""""""""""""""""""""
527
+
528
+ Both ``TopLevel`` and ``MDISubWindow`` show a context menu on
529
+ right-click of the title bar. Items are gated by the relevant
530
+ options (Raise is always shown; Lower / Shade / Minimize / Maximize
531
+ / Close appear when the corresponding option is enabled). The menu
532
+ supports both click-release and press-drag-release styles, like a
533
+ menubar. Drag (title bar) and resize (corner grips) are now
534
+ restricted to the left mouse button so right- and middle-click
535
+ gestures don't accidentally move or resize the window.
536
+
537
+ Image: binary-frame protocol
538
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
539
+
540
+ ``Image.set_binary_image(format, buffer)`` accepts raw bytes from a
541
+ WebSocket binary frame and renders them via a ``Blob`` of the
542
+ matching MIME type (``"jpeg"`` / ``"png"`` / ``"webp"`` / ``"gif"``).
543
+ This avoids the ~33% base64 overhead of the JSON ``set_image`` path
544
+ and is intended for streaming use cases (animation, video frames,
545
+ etc.). The Python side's binding stores the latest frame so it is
546
+ replayed on reconnect.
547
+
548
+ Browser text-select disabled by default
549
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
550
+
551
+ Drag-to-highlight inside widgets is now disabled by default — it
552
+ interferes with row click/drag, shift-click range select, etc.
553
+ Form controls (``TextEntry``, ``TextArea``, ``TextSource``,
554
+ ``TextEntrySet``, the ``treeview`` cell editor) and ``contenteditable``
555
+ elements always allow selection regardless. Per-widget opt-in via
556
+ the new ``set_allow_text_selection(tf)`` method on the ``Widget``
557
+ base class (or via constructor option on ``TreeView`` / ``TableView``).
558
+
559
+ Other notable additions
560
+ ~~~~~~~~~~~~~~~~~~~~~~~
561
+
562
+ - ``MenuAction`` ``activated`` callback signature simplified. Old:
563
+ ``handler(widget, text, checked)``. New: ``handler(widget)`` for
564
+ non-checkable actions; ``handler(widget, checked)`` for checkable
565
+ ones. The label can still be queried via ``widget.get_text()``.
566
+ *This is a breaking change for any handler that took the text arg.*
567
+ - ``Button.set_color(bg)`` now uses the ``background`` shorthand so
568
+ the requested colour shows through the new sculpted gradient and
569
+ ``:hover`` / ``:active`` rules. Pass an empty string to revert.
570
+ - New ``WindowMenu`` shared helper module powers both context menus.
571
+ - ``Widget`` base class now adds a ``pgwidgets-widget`` class to
572
+ every widget element and exposes ``set_allow_text_selection``.
573
+ - Restyled widgets: sans-serif default, sculpted buttons, distinct
574
+ slider/dial thumbs, etc.
575
+ - ``ScrollArea`` and ``AbstractScrollArea`` improvements; new
576
+ ``set_thumb_percent`` API and shared scrollbar code.
577
+ - ``Box`` / ``GridBox`` layout fixes: rigid ``stretch=0`` children,
578
+ cells that re-flow on resize, ``set_min_size`` / ``set_max_size``
579
+ on layout containers.
580
+ - Reconstruction hardening: ``MenuBar`` menus rebuild correctly,
581
+ ``TabWidget`` tab removal respects state, ``MDISubWindow`` is
582
+ restored properly.
583
+ - ``ComboBox`` auto-selects the first item; dropdown raised above
584
+ modal dialogs.
585
+ - ``StatusBar`` widget added; ``Label`` interactive + context menu.
586
+ - ``FixedLayout`` container added: places children at fixed
587
+ ``(x, y)`` offsets at their natural size (or whatever
588
+ ``resize()`` set). See :ref:`widget-fixedlayout`.
589
+
590
+ Bug fixes
591
+ ~~~~~~~~~
592
+
593
+ - Sub-widgets created during a widget's constructor (e.g.
594
+ ``ScrollBar`` instances inside ``TreeView``) no longer collide
595
+ with later-allocated Python widget IDs. ``_handleCreate`` now
596
+ relocates a displaced occupant and reports the new
597
+ ``next_wid`` to the Python side so future allocations skip past
598
+ any auto-allocated IDs. This was the cause of "callback fires on
599
+ the wrong widget" reports.