pgwidgets-js 0.1.2__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 (185) hide show
  1. pgwidgets_js-0.1.2/.flake8 +3 -0
  2. pgwidgets_js-0.1.2/.gitignore +38 -0
  3. pgwidgets_js-0.1.2/.readthedocs.yaml +16 -0
  4. pgwidgets_js-0.1.2/LICENSE.md +29 -0
  5. pgwidgets_js-0.1.2/MANIFEST.in +7 -0
  6. pgwidgets_js-0.1.2/PKG-INFO +298 -0
  7. pgwidgets_js-0.1.2/README.md +271 -0
  8. pgwidgets_js-0.1.2/Widgets.css +1 -0
  9. pgwidgets_js-0.1.2/Widgets.js +1 -0
  10. pgwidgets_js-0.1.2/docs/Makefile +15 -0
  11. pgwidgets_js-0.1.2/docs/callbacks.rst +94 -0
  12. pgwidgets_js-0.1.2/docs/conf.py +17 -0
  13. pgwidgets_js-0.1.2/docs/electron.rst +204 -0
  14. pgwidgets_js-0.1.2/docs/external-widgets.rst +229 -0
  15. pgwidgets_js-0.1.2/docs/frameworks.rst +237 -0
  16. pgwidgets_js-0.1.2/docs/getting-started.rst +117 -0
  17. pgwidgets_js-0.1.2/docs/index.rst +42 -0
  18. pgwidgets_js-0.1.2/docs/pyodide.rst +92 -0
  19. pgwidgets_js-0.1.2/docs/remote.rst +90 -0
  20. pgwidgets_js-0.1.2/docs/styling.rst +218 -0
  21. pgwidgets_js-0.1.2/docs/widgets/controls.rst +384 -0
  22. pgwidgets_js-0.1.2/docs/widgets/dialogs.rst +144 -0
  23. pgwidgets_js-0.1.2/docs/widgets/display.rst +376 -0
  24. pgwidgets_js-0.1.2/docs/widgets/index.rst +65 -0
  25. pgwidgets_js-0.1.2/docs/widgets/layout.rst +437 -0
  26. pgwidgets_js-0.1.2/docs/widgets/menus.rst +186 -0
  27. pgwidgets_js-0.1.2/docs/widgets/nonvisual.rst +57 -0
  28. pgwidgets_js-0.1.2/docs/widgets/text.rst +307 -0
  29. pgwidgets_js-0.1.2/examples/all_widgets.html +716 -0
  30. pgwidgets_js-0.1.2/examples/all_widgets_pyodide.html +79 -0
  31. pgwidgets_js-0.1.2/examples/all_widgets_pyodide.py +594 -0
  32. pgwidgets_js-0.1.2/examples/all_widgets_pyscript.html +31 -0
  33. pgwidgets_js-0.1.2/examples/all_widgets_pyscript.py +603 -0
  34. pgwidgets_js-0.1.2/examples/box.html +36 -0
  35. pgwidgets_js-0.1.2/examples/button.html +78 -0
  36. pgwidgets_js-0.1.2/examples/canvas.html +71 -0
  37. pgwidgets_js-0.1.2/examples/checkbox.html +44 -0
  38. pgwidgets_js-0.1.2/examples/colordialog.html +68 -0
  39. pgwidgets_js-0.1.2/examples/combobox.html +83 -0
  40. pgwidgets_js-0.1.2/examples/debug_spinbox.html +49 -0
  41. pgwidgets_js-0.1.2/examples/dial.html +113 -0
  42. pgwidgets_js-0.1.2/examples/dialog.html +105 -0
  43. pgwidgets_js-0.1.2/examples/electron/.gitignore +2 -0
  44. pgwidgets_js-0.1.2/examples/electron/.npmrc +3 -0
  45. pgwidgets_js-0.1.2/examples/electron/index.html +99 -0
  46. pgwidgets_js-0.1.2/examples/electron/main.js +28 -0
  47. pgwidgets_js-0.1.2/examples/electron/package.json +13 -0
  48. pgwidgets_js-0.1.2/examples/expander.html +46 -0
  49. pgwidgets_js-0.1.2/examples/external_widgets.html +89 -0
  50. pgwidgets_js-0.1.2/examples/frame.html +57 -0
  51. pgwidgets_js-0.1.2/examples/gridbox.html +76 -0
  52. pgwidgets_js-0.1.2/examples/htmlview.html +129 -0
  53. pgwidgets_js-0.1.2/examples/image.html +55 -0
  54. pgwidgets_js-0.1.2/examples/label.html +113 -0
  55. pgwidgets_js-0.1.2/examples/mdi_widget.html +49 -0
  56. pgwidgets_js-0.1.2/examples/menu.html +147 -0
  57. pgwidgets_js-0.1.2/examples/progressbar.html +90 -0
  58. pgwidgets_js-0.1.2/examples/pyodide_demo.html +154 -0
  59. pgwidgets_js-0.1.2/examples/pyscript.toml +5 -0
  60. pgwidgets_js-0.1.2/examples/radiobutton.html +84 -0
  61. pgwidgets_js-0.1.2/examples/remote.html +25 -0
  62. pgwidgets_js-0.1.2/examples/remote_demo.py +243 -0
  63. pgwidgets_js-0.1.2/examples/remote_demo_async.py +231 -0
  64. pgwidgets_js-0.1.2/examples/scroll_area.html +44 -0
  65. pgwidgets_js-0.1.2/examples/scrollable.html +31 -0
  66. pgwidgets_js-0.1.2/examples/scrollbar.html +86 -0
  67. pgwidgets_js-0.1.2/examples/slider.html +76 -0
  68. pgwidgets_js-0.1.2/examples/spinbox.html +70 -0
  69. pgwidgets_js-0.1.2/examples/splitter.html +39 -0
  70. pgwidgets_js-0.1.2/examples/tab_widget.html +94 -0
  71. pgwidgets_js-0.1.2/examples/tableview.html +139 -0
  72. pgwidgets_js-0.1.2/examples/text_entry.html +43 -0
  73. pgwidgets_js-0.1.2/examples/textarea.html +65 -0
  74. pgwidgets_js-0.1.2/examples/textentryset.html +77 -0
  75. pgwidgets_js-0.1.2/examples/textsource.html +139 -0
  76. pgwidgets_js-0.1.2/examples/togglebutton.html +77 -0
  77. pgwidgets_js-0.1.2/examples/toolbar.html +125 -0
  78. pgwidgets_js-0.1.2/examples/treeview.html +95 -0
  79. pgwidgets_js-0.1.2/examples/videowidget.html +103 -0
  80. pgwidgets_js-0.1.2/package.json +35 -0
  81. pgwidgets_js-0.1.2/pgwidgets_js/__init__.py +25 -0
  82. pgwidgets_js-0.1.2/pgwidgets_js/defs.py +772 -0
  83. pgwidgets_js-0.1.2/pgwidgets_js/pyodide/__init__.py +42 -0
  84. pgwidgets_js-0.1.2/pgwidgets_js/pyodide/widget.py +194 -0
  85. pgwidgets_js-0.1.2/pgwidgets_js/static/Widgets.css +42 -0
  86. pgwidgets_js-0.1.2/pgwidgets_js/static/Widgets.js +69 -0
  87. pgwidgets_js-0.1.2/pgwidgets_js/static/css/Box.css +26 -0
  88. pgwidgets_js-0.1.2/pgwidgets_js/static/css/Button.css +24 -0
  89. pgwidgets_js-0.1.2/pgwidgets_js/static/css/CheckBox.css +8 -0
  90. pgwidgets_js-0.1.2/pgwidgets_js/static/css/ColorDialog.css +53 -0
  91. pgwidgets_js-0.1.2/pgwidgets_js/static/css/ComboBox.css +63 -0
  92. pgwidgets_js-0.1.2/pgwidgets_js/static/css/Dial.css +47 -0
  93. pgwidgets_js-0.1.2/pgwidgets_js/static/css/Dialog.css +24 -0
  94. pgwidgets_js-0.1.2/pgwidgets_js/static/css/Expander.css +44 -0
  95. pgwidgets_js-0.1.2/pgwidgets_js/static/css/ExternalWidget.css +11 -0
  96. pgwidgets_js-0.1.2/pgwidgets_js/static/css/Frame.css +30 -0
  97. pgwidgets_js-0.1.2/pgwidgets_js/static/css/GridBox.css +11 -0
  98. pgwidgets_js-0.1.2/pgwidgets_js/static/css/HtmlView.css +49 -0
  99. pgwidgets_js-0.1.2/pgwidgets_js/static/css/Image.css +6 -0
  100. pgwidgets_js-0.1.2/pgwidgets_js/static/css/MDIWidget.css +202 -0
  101. pgwidgets_js-0.1.2/pgwidgets_js/static/css/Menu.css +107 -0
  102. pgwidgets_js-0.1.2/pgwidgets_js/static/css/ProgressBar.css +39 -0
  103. pgwidgets_js-0.1.2/pgwidgets_js/static/css/RadioButton.css +45 -0
  104. pgwidgets_js-0.1.2/pgwidgets_js/static/css/ScrollArea.css +45 -0
  105. pgwidgets_js-0.1.2/pgwidgets_js/static/css/ScrollBar.css +34 -0
  106. pgwidgets_js-0.1.2/pgwidgets_js/static/css/Slider.css +21 -0
  107. pgwidgets_js-0.1.2/pgwidgets_js/static/css/SpinBox.css +63 -0
  108. pgwidgets_js-0.1.2/pgwidgets_js/static/css/Splitter.css +56 -0
  109. pgwidgets_js-0.1.2/pgwidgets_js/static/css/TabWidget.css +148 -0
  110. pgwidgets_js-0.1.2/pgwidgets_js/static/css/Text.css +8 -0
  111. pgwidgets_js-0.1.2/pgwidgets_js/static/css/TextArea.css +52 -0
  112. pgwidgets_js-0.1.2/pgwidgets_js/static/css/TextEntrySet.css +38 -0
  113. pgwidgets_js-0.1.2/pgwidgets_js/static/css/TextSource.css +130 -0
  114. pgwidgets_js-0.1.2/pgwidgets_js/static/css/ToggleButton.css +21 -0
  115. pgwidgets_js-0.1.2/pgwidgets_js/static/css/ToolBar.css +95 -0
  116. pgwidgets_js-0.1.2/pgwidgets_js/static/css/TopLevel.css +90 -0
  117. pgwidgets_js-0.1.2/pgwidgets_js/static/css/TreeView.css +230 -0
  118. pgwidgets_js-0.1.2/pgwidgets_js/static/css/VideoWidget.css +19 -0
  119. pgwidgets_js-0.1.2/pgwidgets_js/static/css/Widget.css +4 -0
  120. pgwidgets_js-0.1.2/pgwidgets_js/static/icons/file.svg +100 -0
  121. pgwidgets_js-0.1.2/pgwidgets_js/static/icons/folder.svg +65 -0
  122. pgwidgets_js-0.1.2/pgwidgets_js/static/icons/hdots.svg +44 -0
  123. pgwidgets_js-0.1.2/pgwidgets_js/static/icons/pgicon.svg +95 -0
  124. pgwidgets_js-0.1.2/pgwidgets_js/static/icons/pgwidgets-logo.svg +273 -0
  125. pgwidgets_js-0.1.2/pgwidgets_js/static/icons/vdots.svg +44 -0
  126. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/Box.js +137 -0
  127. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/Button.js +102 -0
  128. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/Callback.js +150 -0
  129. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/Canvas.js +154 -0
  130. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/CheckBox.js +66 -0
  131. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/ColorDialog.js +99 -0
  132. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/ColorWidget.js +464 -0
  133. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/ComboBox.js +293 -0
  134. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/ComboBoxNative.js +174 -0
  135. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/Dial.js +408 -0
  136. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/Dialog.js +103 -0
  137. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/Expander.js +111 -0
  138. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/ExternalWidget.js +73 -0
  139. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/FileDialog.js +185 -0
  140. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/Frame.js +73 -0
  141. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/GridBox.js +272 -0
  142. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/HtmlView.js +171 -0
  143. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/Image.js +155 -0
  144. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/Label.js +79 -0
  145. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/MDIWidget.js +750 -0
  146. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/Menu.js +137 -0
  147. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/MenuAction.js +142 -0
  148. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/MenuBar.js +169 -0
  149. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/Page.js +52 -0
  150. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/ProgressBar.js +65 -0
  151. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/RadioButton.js +119 -0
  152. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/RemoteInterface.js +395 -0
  153. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/ScrollArea.js +154 -0
  154. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/ScrollBar.js +187 -0
  155. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/Slider.js +162 -0
  156. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/SpinBox.js +205 -0
  157. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/Splitter.js +229 -0
  158. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/TabWidget.js +373 -0
  159. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/TableView.js +41 -0
  160. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/TextArea.js +160 -0
  161. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/TextEntry.js +143 -0
  162. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/TextEntrySet.js +67 -0
  163. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/TextSource.js +1170 -0
  164. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/TextWidget.js +67 -0
  165. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/Timer.js +152 -0
  166. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/ToggleButton.js +128 -0
  167. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/ToolBar.js +87 -0
  168. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/ToolBarAction.js +180 -0
  169. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/TopLevel.js +337 -0
  170. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/TreeView.js +1410 -0
  171. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/VideoWidget.js +259 -0
  172. pgwidgets_js-0.1.2/pgwidgets_js/static/modules/Widget.js +900 -0
  173. pgwidgets_js-0.1.2/pgwidgets_js/static/remote.html +29 -0
  174. pgwidgets_js-0.1.2/pgwidgets_js.egg-info/PKG-INFO +298 -0
  175. pgwidgets_js-0.1.2/pgwidgets_js.egg-info/SOURCES.txt +183 -0
  176. pgwidgets_js-0.1.2/pgwidgets_js.egg-info/dependency_links.txt +1 -0
  177. pgwidgets_js-0.1.2/pgwidgets_js.egg-info/requires.txt +7 -0
  178. pgwidgets_js-0.1.2/pgwidgets_js.egg-info/top_level.txt +1 -0
  179. pgwidgets_js-0.1.2/pyproject.toml +45 -0
  180. pgwidgets_js-0.1.2/setup.cfg +4 -0
  181. pgwidgets_js-0.1.2/setup.py +2 -0
  182. pgwidgets_js-0.1.2/tests/__init__.py +1 -0
  183. pgwidgets_js-0.1.2/tests/test_consistency.py +141 -0
  184. pgwidgets_js-0.1.2/tests/test_defs.py +110 -0
  185. pgwidgets_js-0.1.2/tests/test_static_assets.py +58 -0
@@ -0,0 +1,3 @@
1
+ [flake8]
2
+ max-line-length = 100
3
+ extend-ignore = E501
@@ -0,0 +1,38 @@
1
+ # ignore some commonly problematic files
2
+
3
+ # python compiled files
4
+ *.py[co]
5
+
6
+ # emacs backups
7
+ *~
8
+ \#*\#
9
+
10
+ # Compiled files
11
+ __pycache__
12
+
13
+ # Other generated files
14
+ version.py
15
+
16
+ # Sphinx
17
+ _build
18
+
19
+ # Packages/installer info
20
+ *.egg
21
+ *.egg-info
22
+ dist
23
+ build
24
+ eggs
25
+ sdist
26
+ develop-eggs
27
+ .installed.cfg
28
+ distribute-*.tar.gz
29
+
30
+ # Other
31
+ .*.swp
32
+
33
+ # Node
34
+ node_modules
35
+
36
+ # Mac OSX
37
+ .DS_Store
38
+
@@ -0,0 +1,16 @@
1
+ version: 2
2
+
3
+ build:
4
+ os: ubuntu-22.04
5
+ tools:
6
+ python: "3.12"
7
+
8
+ sphinx:
9
+ configuration: docs/conf.py
10
+
11
+ python:
12
+ install:
13
+ - method: pip
14
+ path: .
15
+ extra_requirements:
16
+ - dev
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, PGWidgets developers
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,7 @@
1
+ include Widgets.js
2
+ include Widgets.css
3
+ include LICENSE.md
4
+ recursive-include modules *.js
5
+ recursive-include css *.css
6
+ recursive-include icons *.svg
7
+ recursive-include pgwidgets_js *.py *.html
@@ -0,0 +1,298 @@
1
+ Metadata-Version: 2.4
2
+ Name: pgwidgets-js
3
+ Version: 0.1.2
4
+ Summary: pgwidgets JavaScript widget library — static assets for use with Python servers
5
+ Author: PGWidgets Developers
6
+ License: BSD-3-Clause
7
+ Project-URL: Homepage, https://github.com/naojsoft/pgwidgets-js
8
+ Project-URL: Repository, https://github.com/naojsoft/pgwidgets-js
9
+ Keywords: widgets,ui,gui,javascript,websocket
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: BSD License
13
+ Classifier: Programming Language :: JavaScript
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Software Development :: User Interfaces
18
+ Requires-Python: >=3.12
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE.md
21
+ Provides-Extra: dev
22
+ Requires-Dist: sphinx; extra == "dev"
23
+ Requires-Dist: furo; extra == "dev"
24
+ Provides-Extra: test
25
+ Requires-Dist: pytest; extra == "test"
26
+ Dynamic: license-file
27
+
28
+ <p align="center">
29
+ <img src="pgwidgets_js/static/icons/pgwidgets-logo.svg" alt="pgwidgets logo" width="300">
30
+ </p>
31
+
32
+ <p align="center">
33
+ A native JavaScript widget toolkit with Qt/GTK-style layout and controls.<br>
34
+ No frameworks. No build step. No dependencies.
35
+ </p>
36
+
37
+ ---
38
+
39
+ ## What is PGWidgets?
40
+
41
+ pgwidgets is a pure JavaScript widget library that brings desktop-style UI
42
+ controls to the browser. If you've used Qt, GTK, or Tkinter, the API will
43
+ feel familiar: create widgets, pack them into layout containers, and wire
44
+ up callbacks.
45
+
46
+ ```javascript
47
+ import { Widgets } from "./Widgets.js";
48
+
49
+ let top = new Widgets.TopLevel({title: "Hello", resizable: true});
50
+ top.resize(400, 300);
51
+
52
+ let vbox = new Widgets.VBox();
53
+ vbox.set_spacing(8);
54
+ vbox.set_padding(10);
55
+
56
+ let label = new Widgets.Label("Click the button!");
57
+ let button = new Widgets.Button("Click me");
58
+ button.add_callback('activated', () => label.set_text("Clicked!"));
59
+
60
+ vbox.add_widget(button, 0);
61
+ vbox.add_widget(label, 1);
62
+ top.set_widget(vbox);
63
+ top.show();
64
+ ```
65
+
66
+ ## Features
67
+
68
+ - **Zero dependencies** -- pure JavaScript ES modules, works directly in the browser
69
+ - **No build step** -- just include `Widgets.js` and `Widgets.css`
70
+ - **Desktop-style layouts** -- VBox, HBox, GridBox, Splitter, TabWidget, ScrollArea
71
+ - **MDI workspace** -- multiple draggable, resizable sub-windows with cascade/tile
72
+ - **Remote interface** -- drive the UI over WebSocket from Python or any language
73
+ - **Familiar API** -- callbacks, containers, and widget hierarchy inspired by Qt/GTK
74
+
75
+ ## Widgets
76
+
77
+ ### Layout & Containers
78
+
79
+ | Widget | Description |
80
+ |--------|-------------|
81
+ | **TopLevel** | Top-level window with optional title bar, dragging, and resize grips |
82
+ | **VBox / HBox** | Vertical and horizontal box layouts with spacing and stretch factors |
83
+ | **GridBox** | Grid layout with row/column placement |
84
+ | **Splitter** | Resizable split pane (horizontal or vertical) |
85
+ | **TabWidget** | Tabbed container with switchable pages |
86
+ | **StackWidget** | Stacked pages without tab headers |
87
+ | **ScrollArea** | Scrollable viewport with custom scrollbars |
88
+ | **Frame** | Titled border container |
89
+ | **Expander** | Collapsible section with a clickable header |
90
+ | **MDIWidget** | Multiple Document Interface workspace with sub-windows |
91
+
92
+ ### Controls
93
+
94
+ | Widget | Description |
95
+ |--------|-------------|
96
+ | **Button** | Push button with optional icon |
97
+ | **ToggleButton** | Two-state button, supports exclusive groups |
98
+ | **CheckBox** | Checkbox with label |
99
+ | **RadioButton** | Radio button with exclusive group support |
100
+ | **ComboBox** | Dropdown with optional editable text, filtering, and scroll limit |
101
+ | **Slider** | Range slider (integer or float) |
102
+ | **SpinBox** | Numeric input with increment/decrement buttons |
103
+ | **Dial** | Rotary knob control |
104
+ | **ScrollBar** | Standalone scrollbar with draggable thumb |
105
+ | **ProgressBar** | Determinate progress indicator |
106
+
107
+ ### Text & Display
108
+
109
+ | Widget | Description |
110
+ |--------|-------------|
111
+ | **Label** | Static text with alignment, color, and font options |
112
+ | **TextEntry** | Single-line text input with line history |
113
+ | **TextEntrySet** | Text entry with a submit button |
114
+ | **TextArea** | Multi-line text editor |
115
+ | **Image** | Image display widget |
116
+ | **Canvas** | HTML5 canvas for custom drawing |
117
+ | **TreeView** | Hierarchical tree/table with columns, sorting, icons, and multi-selection |
118
+
119
+ ### Menus & Toolbars
120
+
121
+ | Widget | Description |
122
+ |--------|-------------|
123
+ | **MenuBar** | Horizontal menu bar |
124
+ | **Menu** | Dropdown menu with actions |
125
+ | **ToolBar** | Toolbar with buttons, toggles, and separators |
126
+
127
+ ### Dialogs
128
+
129
+ | Widget | Description |
130
+ |--------|-------------|
131
+ | **Dialog** | Modal or non-modal dialog with configurable buttons |
132
+ | **ColorDialog** | Color picker with SV plane, hue strip, and RGB/HSV/hex inputs |
133
+
134
+ ## Installation
135
+
136
+ ### Standalone (no tooling)
137
+
138
+ Copy the repository and include it directly:
139
+
140
+ ```html
141
+ <link rel="stylesheet" href="path/to/Widgets.css" />
142
+ <script type="module">
143
+ import { Widgets } from "path/to/Widgets.js";
144
+ // ...
145
+ </script>
146
+ ```
147
+
148
+ ### npm
149
+
150
+ ```bash
151
+ npm install pgwidgets # once published
152
+ # or install directly from GitHub:
153
+ npm install github:naojsoft/pgwidgets-js
154
+ ```
155
+
156
+ Then in your bundled app:
157
+
158
+ ```javascript
159
+ import { Widgets } from "pgwidgets";
160
+ import "pgwidgets/Widgets.css";
161
+ ```
162
+
163
+ ## Using from Python (Pyodide / PyScript)
164
+
165
+ pgwidgets can be used directly from Python in the browser via
166
+ [Pyodide](https://pyodide.org) or [PyScript](https://pyscript.net).
167
+ The `pgwidgets_js.pyodide` module provides Pythonic wrappers with
168
+ normal construction syntax, automatic type conversion, and callback
169
+ management.
170
+
171
+ ```python
172
+ from pgwidgets_js.pyodide import Widgets
173
+
174
+ top = Widgets.TopLevel(title="Hello", resizable=True)
175
+ top.resize(400, 300)
176
+
177
+ vbox = Widgets.VBox(spacing=8, padding=10)
178
+
179
+ label = Widgets.Label("Click the button!")
180
+ button = Widgets.Button("Click me")
181
+ button.on("activated", lambda: label.set_text("Clicked!"))
182
+
183
+ vbox.add_widget(button, 0)
184
+ vbox.add_widget(label, 1)
185
+ top.set_widget(vbox)
186
+ top.show()
187
+ ```
188
+
189
+ No WebSocket server needed -- everything runs in the browser. The same
190
+ Python code works with both Pyodide and PyScript; only the HTML loader
191
+ differs. See `examples/pyodide_demo.html` for a minimal Pyodide example,
192
+ `examples/all_widgets_pyodide.html` for a full demo via Pyodide, and
193
+ `examples/all_widgets_pyscript.html` for the same demo via PyScript.
194
+
195
+ ## Remote Interface (WebSocket)
196
+
197
+ pgwidgets can also be controlled from a Python server over WebSocket
198
+ using the [pgwidgets-python](https://github.com/naojsoft/pgwidgets-python)
199
+ package. The browser page connects to the server, which sends JSON
200
+ messages to create widgets, call methods, and receive callbacks.
201
+
202
+ ```python
203
+ from pgwidgets.sync import Application
204
+
205
+ app = Application()
206
+ app.start()
207
+ W = app.get_widgets()
208
+ app.wait_for_connection()
209
+
210
+ top = W.TopLevel(title="Remote App", resizable=True)
211
+ top.resize(400, 300)
212
+
213
+ vbox = W.VBox(spacing=8)
214
+ btn = W.Button("Click me")
215
+ status = W.Label("Ready")
216
+
217
+ btn.on("activated", lambda: status.set_text("Clicked!"))
218
+
219
+ vbox.add_widget(btn, 0)
220
+ vbox.add_widget(status, 1)
221
+ top.set_widget(vbox)
222
+ top.show()
223
+
224
+ app.run()
225
+ ```
226
+
227
+ See `examples/remote_demo.py` and `examples/remote_demo_async.py`
228
+ for complete working examples.
229
+
230
+ ## Building Desktop Apps with Electron
231
+
232
+ Because pgwidgets is just a browser library with no dependencies, it
233
+ runs unchanged inside an [Electron](https://electronjs.org) renderer
234
+ process. This lets you ship pgwidgets UIs as native desktop apps with
235
+ their own window chrome, system menus, and access to the file system.
236
+
237
+ A minimal example lives in `examples/electron/`:
238
+
239
+ ```bash
240
+ cd examples/electron
241
+ npm install # one-time, installs Electron locally
242
+ npm start # launches the all_widgets demo in an Electron window
243
+ ```
244
+
245
+ The Electron entry point (`main.js`) is about 20 lines and simply
246
+ creates a `BrowserWindow` that loads an HTML file -- no
247
+ Electron-specific changes are needed in pgwidgets itself. To use your
248
+ own UI, edit `main.js` to point at a different HTML file.
249
+
250
+ ## Embedding Third-Party Libraries
251
+
252
+ The `ExternalWidget` class lets you embed content from third-party
253
+ JavaScript libraries -- Plotly charts, Bokeh plots, Leaflet maps, D3
254
+ visualizations, and more -- into pgwidgets layout containers. The
255
+ widget participates in pgwidgets layout (stretch factors, splitters,
256
+ tabs) while its content area is managed by the external library.
257
+
258
+ ```javascript
259
+ let chart = new Widgets.ExternalWidget();
260
+ vbox.add_widget(chart, 1); // stretch=1 fills available space
261
+
262
+ Plotly.newPlot(chart.get_content_element(), data, layout,
263
+ {responsive: true});
264
+ ```
265
+
266
+ See the [documentation](docs/external-widgets.rst) for full examples
267
+ with Plotly, Bokeh, and other libraries.
268
+
269
+ ## Running the Examples
270
+
271
+ Start a local web server from the repository root:
272
+
273
+ ```bash
274
+ python -m http.server --bind localhost 8000
275
+ ```
276
+
277
+ Then open any example in your browser:
278
+
279
+ - [all_widgets.html](http://localhost:8000/examples/all_widgets.html) -- MDI workspace showcasing every widget (JavaScript)
280
+ - [all_widgets_pyodide.html](http://localhost:8000/examples/all_widgets_pyodide.html) -- Same demo, written entirely in Python via Pyodide
281
+ - [all_widgets_pyscript.html](http://localhost:8000/examples/all_widgets_pyscript.html) -- Same demo via PyScript
282
+ - [pyodide_demo.html](http://localhost:8000/examples/pyodide_demo.html) -- Minimal Pyodide example
283
+ - [treeview.html](http://localhost:8000/examples/treeview.html) -- TreeView with icons, sorting, and multi-selection
284
+ - [mdi_widget.html](http://localhost:8000/examples/mdi_widget.html) -- MDI with cascade/tile
285
+ - [dialog.html](http://localhost:8000/examples/dialog.html) -- Modal and non-modal dialogs
286
+ - [colordialog.html](http://localhost:8000/examples/colordialog.html) -- Color picker dialog
287
+ - [combobox.html](http://localhost:8000/examples/combobox.html) -- ComboBox variants
288
+ - [splitter.html](http://localhost:8000/examples/splitter.html) -- Resizable split panes
289
+ - [tab_widget.html](http://localhost:8000/examples/tab_widget.html) -- Tabbed interface
290
+ - [htmlview.html](http://localhost:8000/examples/htmlview.html) -- Rich HTML content display
291
+ - [videowidget.html](http://localhost:8000/examples/videowidget.html) -- Video playback with controls
292
+ - [external_widgets.html](http://localhost:8000/examples/external_widgets.html) -- Plotly and Bokeh in a splitter
293
+
294
+ And many more in the `examples/` directory.
295
+
296
+ ## License
297
+
298
+ BSD 3-Clause
@@ -0,0 +1,271 @@
1
+ <p align="center">
2
+ <img src="pgwidgets_js/static/icons/pgwidgets-logo.svg" alt="pgwidgets logo" width="300">
3
+ </p>
4
+
5
+ <p align="center">
6
+ A native JavaScript widget toolkit with Qt/GTK-style layout and controls.<br>
7
+ No frameworks. No build step. No dependencies.
8
+ </p>
9
+
10
+ ---
11
+
12
+ ## What is PGWidgets?
13
+
14
+ pgwidgets is a pure JavaScript widget library that brings desktop-style UI
15
+ controls to the browser. If you've used Qt, GTK, or Tkinter, the API will
16
+ feel familiar: create widgets, pack them into layout containers, and wire
17
+ up callbacks.
18
+
19
+ ```javascript
20
+ import { Widgets } from "./Widgets.js";
21
+
22
+ let top = new Widgets.TopLevel({title: "Hello", resizable: true});
23
+ top.resize(400, 300);
24
+
25
+ let vbox = new Widgets.VBox();
26
+ vbox.set_spacing(8);
27
+ vbox.set_padding(10);
28
+
29
+ let label = new Widgets.Label("Click the button!");
30
+ let button = new Widgets.Button("Click me");
31
+ button.add_callback('activated', () => label.set_text("Clicked!"));
32
+
33
+ vbox.add_widget(button, 0);
34
+ vbox.add_widget(label, 1);
35
+ top.set_widget(vbox);
36
+ top.show();
37
+ ```
38
+
39
+ ## Features
40
+
41
+ - **Zero dependencies** -- pure JavaScript ES modules, works directly in the browser
42
+ - **No build step** -- just include `Widgets.js` and `Widgets.css`
43
+ - **Desktop-style layouts** -- VBox, HBox, GridBox, Splitter, TabWidget, ScrollArea
44
+ - **MDI workspace** -- multiple draggable, resizable sub-windows with cascade/tile
45
+ - **Remote interface** -- drive the UI over WebSocket from Python or any language
46
+ - **Familiar API** -- callbacks, containers, and widget hierarchy inspired by Qt/GTK
47
+
48
+ ## Widgets
49
+
50
+ ### Layout & Containers
51
+
52
+ | Widget | Description |
53
+ |--------|-------------|
54
+ | **TopLevel** | Top-level window with optional title bar, dragging, and resize grips |
55
+ | **VBox / HBox** | Vertical and horizontal box layouts with spacing and stretch factors |
56
+ | **GridBox** | Grid layout with row/column placement |
57
+ | **Splitter** | Resizable split pane (horizontal or vertical) |
58
+ | **TabWidget** | Tabbed container with switchable pages |
59
+ | **StackWidget** | Stacked pages without tab headers |
60
+ | **ScrollArea** | Scrollable viewport with custom scrollbars |
61
+ | **Frame** | Titled border container |
62
+ | **Expander** | Collapsible section with a clickable header |
63
+ | **MDIWidget** | Multiple Document Interface workspace with sub-windows |
64
+
65
+ ### Controls
66
+
67
+ | Widget | Description |
68
+ |--------|-------------|
69
+ | **Button** | Push button with optional icon |
70
+ | **ToggleButton** | Two-state button, supports exclusive groups |
71
+ | **CheckBox** | Checkbox with label |
72
+ | **RadioButton** | Radio button with exclusive group support |
73
+ | **ComboBox** | Dropdown with optional editable text, filtering, and scroll limit |
74
+ | **Slider** | Range slider (integer or float) |
75
+ | **SpinBox** | Numeric input with increment/decrement buttons |
76
+ | **Dial** | Rotary knob control |
77
+ | **ScrollBar** | Standalone scrollbar with draggable thumb |
78
+ | **ProgressBar** | Determinate progress indicator |
79
+
80
+ ### Text & Display
81
+
82
+ | Widget | Description |
83
+ |--------|-------------|
84
+ | **Label** | Static text with alignment, color, and font options |
85
+ | **TextEntry** | Single-line text input with line history |
86
+ | **TextEntrySet** | Text entry with a submit button |
87
+ | **TextArea** | Multi-line text editor |
88
+ | **Image** | Image display widget |
89
+ | **Canvas** | HTML5 canvas for custom drawing |
90
+ | **TreeView** | Hierarchical tree/table with columns, sorting, icons, and multi-selection |
91
+
92
+ ### Menus & Toolbars
93
+
94
+ | Widget | Description |
95
+ |--------|-------------|
96
+ | **MenuBar** | Horizontal menu bar |
97
+ | **Menu** | Dropdown menu with actions |
98
+ | **ToolBar** | Toolbar with buttons, toggles, and separators |
99
+
100
+ ### Dialogs
101
+
102
+ | Widget | Description |
103
+ |--------|-------------|
104
+ | **Dialog** | Modal or non-modal dialog with configurable buttons |
105
+ | **ColorDialog** | Color picker with SV plane, hue strip, and RGB/HSV/hex inputs |
106
+
107
+ ## Installation
108
+
109
+ ### Standalone (no tooling)
110
+
111
+ Copy the repository and include it directly:
112
+
113
+ ```html
114
+ <link rel="stylesheet" href="path/to/Widgets.css" />
115
+ <script type="module">
116
+ import { Widgets } from "path/to/Widgets.js";
117
+ // ...
118
+ </script>
119
+ ```
120
+
121
+ ### npm
122
+
123
+ ```bash
124
+ npm install pgwidgets # once published
125
+ # or install directly from GitHub:
126
+ npm install github:naojsoft/pgwidgets-js
127
+ ```
128
+
129
+ Then in your bundled app:
130
+
131
+ ```javascript
132
+ import { Widgets } from "pgwidgets";
133
+ import "pgwidgets/Widgets.css";
134
+ ```
135
+
136
+ ## Using from Python (Pyodide / PyScript)
137
+
138
+ pgwidgets can be used directly from Python in the browser via
139
+ [Pyodide](https://pyodide.org) or [PyScript](https://pyscript.net).
140
+ The `pgwidgets_js.pyodide` module provides Pythonic wrappers with
141
+ normal construction syntax, automatic type conversion, and callback
142
+ management.
143
+
144
+ ```python
145
+ from pgwidgets_js.pyodide import Widgets
146
+
147
+ top = Widgets.TopLevel(title="Hello", resizable=True)
148
+ top.resize(400, 300)
149
+
150
+ vbox = Widgets.VBox(spacing=8, padding=10)
151
+
152
+ label = Widgets.Label("Click the button!")
153
+ button = Widgets.Button("Click me")
154
+ button.on("activated", lambda: label.set_text("Clicked!"))
155
+
156
+ vbox.add_widget(button, 0)
157
+ vbox.add_widget(label, 1)
158
+ top.set_widget(vbox)
159
+ top.show()
160
+ ```
161
+
162
+ No WebSocket server needed -- everything runs in the browser. The same
163
+ Python code works with both Pyodide and PyScript; only the HTML loader
164
+ differs. See `examples/pyodide_demo.html` for a minimal Pyodide example,
165
+ `examples/all_widgets_pyodide.html` for a full demo via Pyodide, and
166
+ `examples/all_widgets_pyscript.html` for the same demo via PyScript.
167
+
168
+ ## Remote Interface (WebSocket)
169
+
170
+ pgwidgets can also be controlled from a Python server over WebSocket
171
+ using the [pgwidgets-python](https://github.com/naojsoft/pgwidgets-python)
172
+ package. The browser page connects to the server, which sends JSON
173
+ messages to create widgets, call methods, and receive callbacks.
174
+
175
+ ```python
176
+ from pgwidgets.sync import Application
177
+
178
+ app = Application()
179
+ app.start()
180
+ W = app.get_widgets()
181
+ app.wait_for_connection()
182
+
183
+ top = W.TopLevel(title="Remote App", resizable=True)
184
+ top.resize(400, 300)
185
+
186
+ vbox = W.VBox(spacing=8)
187
+ btn = W.Button("Click me")
188
+ status = W.Label("Ready")
189
+
190
+ btn.on("activated", lambda: status.set_text("Clicked!"))
191
+
192
+ vbox.add_widget(btn, 0)
193
+ vbox.add_widget(status, 1)
194
+ top.set_widget(vbox)
195
+ top.show()
196
+
197
+ app.run()
198
+ ```
199
+
200
+ See `examples/remote_demo.py` and `examples/remote_demo_async.py`
201
+ for complete working examples.
202
+
203
+ ## Building Desktop Apps with Electron
204
+
205
+ Because pgwidgets is just a browser library with no dependencies, it
206
+ runs unchanged inside an [Electron](https://electronjs.org) renderer
207
+ process. This lets you ship pgwidgets UIs as native desktop apps with
208
+ their own window chrome, system menus, and access to the file system.
209
+
210
+ A minimal example lives in `examples/electron/`:
211
+
212
+ ```bash
213
+ cd examples/electron
214
+ npm install # one-time, installs Electron locally
215
+ npm start # launches the all_widgets demo in an Electron window
216
+ ```
217
+
218
+ The Electron entry point (`main.js`) is about 20 lines and simply
219
+ creates a `BrowserWindow` that loads an HTML file -- no
220
+ Electron-specific changes are needed in pgwidgets itself. To use your
221
+ own UI, edit `main.js` to point at a different HTML file.
222
+
223
+ ## Embedding Third-Party Libraries
224
+
225
+ The `ExternalWidget` class lets you embed content from third-party
226
+ JavaScript libraries -- Plotly charts, Bokeh plots, Leaflet maps, D3
227
+ visualizations, and more -- into pgwidgets layout containers. The
228
+ widget participates in pgwidgets layout (stretch factors, splitters,
229
+ tabs) while its content area is managed by the external library.
230
+
231
+ ```javascript
232
+ let chart = new Widgets.ExternalWidget();
233
+ vbox.add_widget(chart, 1); // stretch=1 fills available space
234
+
235
+ Plotly.newPlot(chart.get_content_element(), data, layout,
236
+ {responsive: true});
237
+ ```
238
+
239
+ See the [documentation](docs/external-widgets.rst) for full examples
240
+ with Plotly, Bokeh, and other libraries.
241
+
242
+ ## Running the Examples
243
+
244
+ Start a local web server from the repository root:
245
+
246
+ ```bash
247
+ python -m http.server --bind localhost 8000
248
+ ```
249
+
250
+ Then open any example in your browser:
251
+
252
+ - [all_widgets.html](http://localhost:8000/examples/all_widgets.html) -- MDI workspace showcasing every widget (JavaScript)
253
+ - [all_widgets_pyodide.html](http://localhost:8000/examples/all_widgets_pyodide.html) -- Same demo, written entirely in Python via Pyodide
254
+ - [all_widgets_pyscript.html](http://localhost:8000/examples/all_widgets_pyscript.html) -- Same demo via PyScript
255
+ - [pyodide_demo.html](http://localhost:8000/examples/pyodide_demo.html) -- Minimal Pyodide example
256
+ - [treeview.html](http://localhost:8000/examples/treeview.html) -- TreeView with icons, sorting, and multi-selection
257
+ - [mdi_widget.html](http://localhost:8000/examples/mdi_widget.html) -- MDI with cascade/tile
258
+ - [dialog.html](http://localhost:8000/examples/dialog.html) -- Modal and non-modal dialogs
259
+ - [colordialog.html](http://localhost:8000/examples/colordialog.html) -- Color picker dialog
260
+ - [combobox.html](http://localhost:8000/examples/combobox.html) -- ComboBox variants
261
+ - [splitter.html](http://localhost:8000/examples/splitter.html) -- Resizable split panes
262
+ - [tab_widget.html](http://localhost:8000/examples/tab_widget.html) -- Tabbed interface
263
+ - [htmlview.html](http://localhost:8000/examples/htmlview.html) -- Rich HTML content display
264
+ - [videowidget.html](http://localhost:8000/examples/videowidget.html) -- Video playback with controls
265
+ - [external_widgets.html](http://localhost:8000/examples/external_widgets.html) -- Plotly and Bokeh in a splitter
266
+
267
+ And many more in the `examples/` directory.
268
+
269
+ ## License
270
+
271
+ BSD 3-Clause
@@ -0,0 +1 @@
1
+ @import "pgwidgets_js/static/Widgets.css";
@@ -0,0 +1 @@
1
+ export { Widgets } from "./pgwidgets_js/static/Widgets.js";
@@ -0,0 +1,15 @@
1
+ # Minimal makefile for Sphinx documentation
2
+
3
+ SPHINXOPTS ?=
4
+ SPHINXBUILD ?= sphinx-build
5
+ SOURCEDIR = .
6
+ BUILDDIR = _build
7
+
8
+ help:
9
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
10
+
11
+ .PHONY: help Makefile
12
+
13
+ # Catch-all target: route all unknown targets to Sphinx
14
+ %: Makefile
15
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)