qpuiq 0.17__tar.gz → 0.19__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.
Potentially problematic release.
This version of qpuiq might be problematic. Click here for more details.
- {qpuiq-0.17/qpuiq.egg-info → qpuiq-0.19}/PKG-INFO +4 -13
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/base.py +23 -21
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/canvas.py +7 -3
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/layout.py +68 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/__init__.py +1 -1
- {qpuiq-0.17 → qpuiq-0.19}/PUI/dom.py +25 -3
- {qpuiq-0.17 → qpuiq-0.19}/PUI/flet/__init__.py +1 -0
- qpuiq-0.19/PUI/flet/divider.py +14 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/node.py +3 -0
- {qpuiq-0.17 → qpuiq-0.19}/README.md +3 -12
- {qpuiq-0.17 → qpuiq-0.19/qpuiq.egg-info}/PKG-INFO +4 -13
- {qpuiq-0.17 → qpuiq-0.19}/qpuiq.egg-info/SOURCES.txt +1 -0
- {qpuiq-0.17 → qpuiq-0.19}/LICENSE.txt +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/__init__.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/application.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/button.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/checkbox.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/combobox.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/dialog.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/divider.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/image.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/label.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/matplotlib.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/mdi.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/menu.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/modal.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/progressbar.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/radiobutton.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/scroll.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/splitter.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/tab.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/table.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/text.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/textfield.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/toolbar.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/tree.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/PySide6/window.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/common.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/decorator.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/flet/application.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/flet/base.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/flet/button.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/flet/canvas.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/flet/checkbox.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/flet/label.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/flet/layout.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/flet/progressbar.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/flet/radiobutton.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/flet/scroll.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/flet/tab.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/flet/text.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/flet/textfield.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/flet/window.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/interfaces.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/state.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/textual/__init__.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/textual/application.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/textual/base.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/textual/button.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/textual/checkbox.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/textual/label.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/textual/layout.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/textual/progressbar.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/textual/radiobutton.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/textual/scroll.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/textual/tab.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/textual/text.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/textual/textfield.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/textual/window.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/timeline.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/tkinter/__init__.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/tkinter/application.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/tkinter/base.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/tkinter/button.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/tkinter/canvas.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/tkinter/checkbox.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/tkinter/label.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/tkinter/layout.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/tkinter/progressbar.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/tkinter/radiobutton.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/tkinter/scroll.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/tkinter/tab.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/tkinter/text.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/tkinter/textfield.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/tkinter/window.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/utils.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/view.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/wx/__init__.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/wx/application.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/wx/base.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/wx/button.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/wx/canvas.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/wx/checkbox.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/wx/combobox.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/wx/dialog.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/wx/divider.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/wx/label.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/wx/layout.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/wx/progressbar.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/wx/radiobutton.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/wx/scroll.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/wx/text.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/wx/textfield.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/PUI/wx/window.py +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/qpuiq.egg-info/dependency_links.txt +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/qpuiq.egg-info/top_level.txt +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/setup.cfg +0 -0
- {qpuiq-0.17 → qpuiq-0.19}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: qpuiq
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.19
|
|
4
4
|
Summary: "PUI" Python Declarative UI Framework
|
|
5
5
|
Home-page: https://github.com/buganini/PUI
|
|
6
6
|
Author: Buganini Chiu
|
|
@@ -213,38 +213,29 @@ Then PUI will take care of view update [(code)](https://github.com/buganini/PUI/
|
|
|
213
213
|
* no canvas
|
|
214
214
|
|
|
215
215
|
# Documents
|
|
216
|
-
* [Components Reference](
|
|
217
|
-
* [
|
|
216
|
+
* [Components Reference](https://buganini.github.io/PUI/doc/Reference.html)
|
|
217
|
+
* [Layout Strategy](https://buganini.github.io/PUI/doc/Layout.html)
|
|
218
218
|
|
|
219
219
|
# Used by
|
|
220
|
-
* https://github.com/buganini/
|
|
220
|
+
* https://github.com/buganini/Kikakuka
|
|
221
221
|
* https://github.com/solvcon/modmesh
|
|
222
222
|
|
|
223
223
|
# TODO
|
|
224
|
-
* Merge node and view
|
|
225
224
|
* Dump with layout parameters and add test cases
|
|
226
225
|
* [Toga](https://beeware.org/project/projects/libraries/toga/)
|
|
227
|
-
* [ISSUE] textual layout sizing (cookbook scroll example)
|
|
228
226
|
* [ISSUE] flet layout sizing (cookbook scroll example)
|
|
229
227
|
* nested state trigger
|
|
230
228
|
* set state in PUIView __init__
|
|
231
229
|
* set state in setup() ?
|
|
232
230
|
* Tabs(`tabposition`)
|
|
233
231
|
* Lazy List
|
|
234
|
-
* StateObject decorator
|
|
235
232
|
* UI Flow
|
|
236
233
|
* Navigation Stack
|
|
237
234
|
* View Router
|
|
238
235
|
* Model Window/Dialog
|
|
239
236
|
* Layout
|
|
240
|
-
* ZBox
|
|
241
237
|
* SwiftUI style overlay ??
|
|
242
238
|
* Canvas
|
|
243
|
-
* Rect
|
|
244
239
|
* Arc
|
|
245
|
-
* Image
|
|
246
240
|
* ...
|
|
247
|
-
* Table
|
|
248
|
-
* Tree
|
|
249
|
-
* Dialog
|
|
250
241
|
* State with Pydantic support?
|
|
@@ -132,17 +132,17 @@ class QtBaseWidget(PUINode):
|
|
|
132
132
|
|
|
133
133
|
def handleDragEnterEvent(self, event):
|
|
134
134
|
if self._onDragEntered:
|
|
135
|
-
self._onDragEntered[0](event, *self._onDragEntered[1], **self._onDragEntered[2])
|
|
135
|
+
return self._onDragEntered[0](event, *self._onDragEntered[1], **self._onDragEntered[2])
|
|
136
136
|
else:
|
|
137
|
-
event.
|
|
138
|
-
|
|
137
|
+
event.ignore()
|
|
138
|
+
return True
|
|
139
139
|
|
|
140
140
|
def handleDropEvent(self, event):
|
|
141
141
|
if self._onDropped:
|
|
142
|
-
self._onDropped[0](event, *self._onDropped[1], **self._onDropped[2])
|
|
142
|
+
return self._onDropped[0](event, *self._onDropped[1], **self._onDropped[2])
|
|
143
143
|
else:
|
|
144
|
-
print("Dropped", event)
|
|
145
144
|
event.ignore()
|
|
145
|
+
return False
|
|
146
146
|
|
|
147
147
|
def qtSizeHint(self):
|
|
148
148
|
node = self.get_node()
|
|
@@ -162,7 +162,11 @@ class QtBaseWidget(PUINode):
|
|
|
162
162
|
self.qt_params[k] = v
|
|
163
163
|
return self
|
|
164
164
|
|
|
165
|
-
class QtBaseLayout(
|
|
165
|
+
class QtBaseLayout(QtBaseWidget):
|
|
166
|
+
pui_terminal = False
|
|
167
|
+
container_x = False
|
|
168
|
+
container_y = False
|
|
169
|
+
|
|
166
170
|
def __init__(self):
|
|
167
171
|
super().__init__()
|
|
168
172
|
self.qt_params = {}
|
|
@@ -178,11 +182,7 @@ class QtBaseLayout(PUINode):
|
|
|
178
182
|
return self.layout
|
|
179
183
|
|
|
180
184
|
def destroy(self, direct):
|
|
181
|
-
if direct:
|
|
182
|
-
if self.ui:
|
|
183
|
-
self.ui.deleteLater()
|
|
184
185
|
self.layout = None
|
|
185
|
-
self.ui = None
|
|
186
186
|
super().destroy(direct)
|
|
187
187
|
|
|
188
188
|
def update(self, prev=None):
|
|
@@ -192,7 +192,6 @@ class QtBaseLayout(PUINode):
|
|
|
192
192
|
self.mounted_children = []
|
|
193
193
|
|
|
194
194
|
super().update(prev)
|
|
195
|
-
_apply_params(self.ui, self)
|
|
196
195
|
|
|
197
196
|
def addChild(self, idx, child):
|
|
198
197
|
from .modal import Modal
|
|
@@ -222,19 +221,22 @@ class QtBaseLayout(PUINode):
|
|
|
222
221
|
self.mounted_children.pop(idx)
|
|
223
222
|
|
|
224
223
|
def postUpdate(self):
|
|
225
|
-
|
|
224
|
+
if self.ui:
|
|
225
|
+
if self._onDropped:
|
|
226
|
+
self.ui.setAcceptDrops(True)
|
|
227
|
+
self.ui.installEventFilter(self.eventFilter)
|
|
228
|
+
else:
|
|
229
|
+
self.ui.setAcceptDrops(False)
|
|
226
230
|
|
|
227
|
-
|
|
228
|
-
child = child.get_node()
|
|
229
|
-
self.mounted_children[i] = child.get_node()
|
|
231
|
+
super().postUpdate()
|
|
230
232
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
+
if self.container_x or self.container_y:
|
|
234
|
+
for i, child in enumerate(self.mounted_children):
|
|
235
|
+
child = child.get_node()
|
|
236
|
+
self.mounted_children[i] = child.get_node()
|
|
233
237
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
self.qt_params[k] = v
|
|
237
|
-
return self
|
|
238
|
+
weight = child.layout_weight
|
|
239
|
+
self.qtlayout.setStretch(i, weight if weight else 0)
|
|
238
240
|
|
|
239
241
|
class QtBaseFrame(QtBaseWidget):
|
|
240
242
|
pui_terminal = False
|
|
@@ -80,6 +80,12 @@ class PUIQtCanvas(QtWidgets.QWidget):
|
|
|
80
80
|
self.update()
|
|
81
81
|
|
|
82
82
|
class ImageResource():
|
|
83
|
+
@staticmethod
|
|
84
|
+
def load(path):
|
|
85
|
+
ir = ImageResource()
|
|
86
|
+
ir.qimage = QImage(path)
|
|
87
|
+
return ir
|
|
88
|
+
|
|
83
89
|
def crop(self, x, y, width, height):
|
|
84
90
|
ir = ImageResource()
|
|
85
91
|
ir.qimage = self.qimage.copy(x, y, width, height)
|
|
@@ -315,9 +321,7 @@ class Canvas(QtBaseWidget):
|
|
|
315
321
|
raise RuntimeError(f"Not implemented: drawShapely({type(shape).__name__}) {dir(shape)}")
|
|
316
322
|
|
|
317
323
|
def loadImage(self, image_path):
|
|
318
|
-
|
|
319
|
-
ir.qimage = QImage(image_path)
|
|
320
|
-
return ir
|
|
324
|
+
return ImageResource.load(image_path)
|
|
321
325
|
|
|
322
326
|
def drawImage(self, image, x=0, y=0, width=None, height=None, src_x=0, src_y=0, src_width=None, src_height=None, opacity=1.0):
|
|
323
327
|
if image.qimage.isNull():
|
|
@@ -1,7 +1,74 @@
|
|
|
1
1
|
from .. import *
|
|
2
2
|
from .base import *
|
|
3
3
|
|
|
4
|
+
class Stack(QtBaseLayout):
|
|
5
|
+
pui_terminal = False
|
|
6
|
+
pui_reversed_order = True
|
|
7
|
+
|
|
8
|
+
def __init__(self):
|
|
9
|
+
super().__init__()
|
|
10
|
+
self.qt_params = {}
|
|
11
|
+
if not isinstance(self.non_virtual_parent, QtBaseLayout):
|
|
12
|
+
self.layout_padding = (11,11,11,11)
|
|
13
|
+
|
|
14
|
+
@property
|
|
15
|
+
def outer(self):
|
|
16
|
+
return self.ui
|
|
17
|
+
|
|
18
|
+
@property
|
|
19
|
+
def inner(self):
|
|
20
|
+
return self.layout
|
|
21
|
+
|
|
22
|
+
def destroy(self, direct):
|
|
23
|
+
self.layout = None
|
|
24
|
+
super().destroy(direct)
|
|
25
|
+
|
|
26
|
+
def update(self, prev=None):
|
|
27
|
+
if prev and prev.ui:
|
|
28
|
+
self.ui = prev.ui
|
|
29
|
+
self.qtlayout = prev.qtlayout
|
|
30
|
+
else:
|
|
31
|
+
self.ui = QtWidgets.QWidget()
|
|
32
|
+
self.qtlayout = QtWidgets.QStackedLayout()
|
|
33
|
+
self.qtlayout.setStackingMode(QtWidgets.QStackedLayout.StackAll)
|
|
34
|
+
self.qtlayout.setContentsMargins(0,0,0,0)
|
|
35
|
+
self.ui.setLayout(self.qtlayout)
|
|
36
|
+
super().update(prev)
|
|
37
|
+
|
|
38
|
+
def addChild(self, idx, child):
|
|
39
|
+
from .modal import Modal
|
|
40
|
+
from .layout import Spacer
|
|
41
|
+
if isinstance(child, Spacer):
|
|
42
|
+
pass
|
|
43
|
+
elif isinstance(child, Modal):
|
|
44
|
+
pass
|
|
45
|
+
elif isinstance(child, QtBaseWidget) or isinstance(child, QtBaseLayout):
|
|
46
|
+
self.qtlayout.insertWidget(idx, child.outer)
|
|
47
|
+
self.mounted_children.insert(idx, child)
|
|
48
|
+
|
|
49
|
+
def removeChild(self, idx, child):
|
|
50
|
+
from .modal import Modal
|
|
51
|
+
from .layout import Spacer
|
|
52
|
+
if isinstance(child, Spacer):
|
|
53
|
+
pass
|
|
54
|
+
elif isinstance(child, Modal):
|
|
55
|
+
pass
|
|
56
|
+
elif isinstance(child, QtBaseWidget) or isinstance(child, QtBaseLayout):
|
|
57
|
+
child.outer.setParent(None)
|
|
58
|
+
self.mounted_children.pop(idx)
|
|
59
|
+
|
|
60
|
+
def postUpdate(self):
|
|
61
|
+
if self.ui:
|
|
62
|
+
if self._onDropped:
|
|
63
|
+
self.ui.setAcceptDrops(True)
|
|
64
|
+
self.ui.installEventFilter(self.eventFilter)
|
|
65
|
+
else:
|
|
66
|
+
self.ui.setAcceptDrops(False)
|
|
67
|
+
|
|
68
|
+
super().postUpdate()
|
|
69
|
+
|
|
4
70
|
class HBox(QtBaseLayout):
|
|
71
|
+
container_x = True
|
|
5
72
|
def update(self, prev):
|
|
6
73
|
if prev and prev.ui:
|
|
7
74
|
self.ui = prev.ui
|
|
@@ -14,6 +81,7 @@ class HBox(QtBaseLayout):
|
|
|
14
81
|
super().update(prev)
|
|
15
82
|
|
|
16
83
|
class VBox(QtBaseLayout):
|
|
84
|
+
container_y = True
|
|
17
85
|
def update(self, prev):
|
|
18
86
|
if prev and prev.ui:
|
|
19
87
|
self.ui = prev.ui
|
|
@@ -17,6 +17,8 @@ def sortGridDOMInPlace(dom):
|
|
|
17
17
|
dom.sort(key=lambda c:(c.grid_row, c.grid_column, c.grid_rowspan, c.grid_columnspan))
|
|
18
18
|
|
|
19
19
|
def dom_remove_node(dom_parent, dom_offset, child):
|
|
20
|
+
if DEBUG:
|
|
21
|
+
print(f"dom_remove_node key={child.key} virtual={child.pui_virtual} children={len(child.children)} dom_parent={dom_parent.key} dom_offset={dom_offset}")
|
|
20
22
|
if child.pui_virtual:
|
|
21
23
|
ret = [child]
|
|
22
24
|
for c in child.children:
|
|
@@ -49,15 +51,30 @@ def sync(node, dom_parent, dom_offset, oldVDOM, newVDOM, depth=0):
|
|
|
49
51
|
if node.pui_grid_layout:
|
|
50
52
|
sortGridDOMInPlace(oldVDOM)
|
|
51
53
|
sortGridDOMInPlace(newVDOM)
|
|
54
|
+
else:
|
|
55
|
+
oldOrdered = [c for c in oldVDOM if not c.pui_outoforder]
|
|
56
|
+
oldOutOfOrdered = [c for c in oldVDOM if c.pui_outoforder]
|
|
57
|
+
newOrdered = [c for c in newVDOM if not c.pui_outoforder]
|
|
58
|
+
newOutOfOrdered = [c for c in newVDOM if c.pui_outoforder]
|
|
59
|
+
|
|
60
|
+
if node.pui_reversed_order:
|
|
61
|
+
oldOrdered.reverse()
|
|
62
|
+
newOrdered.reverse()
|
|
63
|
+
|
|
64
|
+
oldVDOM.clear()
|
|
65
|
+
oldVDOM.extend(oldOrdered + oldOutOfOrdered)
|
|
66
|
+
newVDOM.clear()
|
|
67
|
+
newVDOM.extend(newOrdered + newOutOfOrdered)
|
|
52
68
|
|
|
53
69
|
if DEBUG:
|
|
54
70
|
print(f"{(depth+1)*' '}===OLD===")
|
|
55
71
|
for c in oldVDOM:
|
|
56
|
-
print(f"{(depth+1)*' '}{c.key} virtual={c.pui_virtual} ui={c.ui}")
|
|
72
|
+
print(f"{(depth+1)*' '}{c.key} virtual={c.pui_virtual} children={len(c.children)} ui={c.ui}")
|
|
57
73
|
|
|
58
74
|
print(f"{(depth+1)*' '}===NEW===")
|
|
59
75
|
for c in newVDOM:
|
|
60
|
-
print(f"{(depth+1)*' '}{c.key} virtual={c.pui_virtual}")
|
|
76
|
+
print(f"{(depth+1)*' '}{c.key} virtual={c.pui_virtual} children={len(c.children)}")
|
|
77
|
+
print(f"{(depth+1)*' '}=========")
|
|
61
78
|
|
|
62
79
|
oldVMap = [x.key for x in oldVDOM]
|
|
63
80
|
newVMap = [x.key for x in newVDOM]
|
|
@@ -213,13 +230,18 @@ def sync(node, dom_parent, dom_offset, oldVDOM, newVDOM, depth=0):
|
|
|
213
230
|
break # finish
|
|
214
231
|
|
|
215
232
|
# Step 4. trim removed trail
|
|
233
|
+
if DEBUG:
|
|
234
|
+
print(f"{(depth+1)*' '}S4. TRIM")
|
|
216
235
|
nl = len(newVDOM)
|
|
236
|
+
if DEBUG:
|
|
237
|
+
print(f"{(depth+1)*' '}S4. TRIM", f"dom_offset={dom_offset}", len(oldVDOM), "=>", len(newVDOM))
|
|
217
238
|
while len(oldVDOM) > nl:
|
|
218
239
|
old = oldVDOM.pop(nl)
|
|
240
|
+
print(f"{(depth+2)*' '}", f"key={old.key} virtual={old.pui_virtual} children={len(old.children)}")
|
|
219
241
|
oldVMap.pop(nl)
|
|
220
242
|
nodes = dom_remove_node(dom_parent, dom_offset + nl, old)
|
|
221
243
|
dom_children_num -= len([n for n in nodes if not n.pui_virtual and not n.pui_outoforder])
|
|
222
|
-
toBeDeleted.
|
|
244
|
+
toBeDeleted.append(old)
|
|
223
245
|
|
|
224
246
|
for c in newVDOM:
|
|
225
247
|
c.postUpdate()
|
|
@@ -27,6 +27,9 @@ class PUINode():
|
|
|
27
27
|
# Menu and window-like UI elements, are out-of-order, so they are moved to the end of siblings before DOM syncing to simplify the process
|
|
28
28
|
pui_outoforder = False
|
|
29
29
|
|
|
30
|
+
# When enabled, children are added in reverse order, used by Stack
|
|
31
|
+
pui_reversed_order = False
|
|
32
|
+
|
|
30
33
|
# Used by PUIView
|
|
31
34
|
pui_isview = False
|
|
32
35
|
|
|
@@ -196,38 +196,29 @@ Then PUI will take care of view update [(code)](https://github.com/buganini/PUI/
|
|
|
196
196
|
* no canvas
|
|
197
197
|
|
|
198
198
|
# Documents
|
|
199
|
-
* [Components Reference](
|
|
200
|
-
* [
|
|
199
|
+
* [Components Reference](https://buganini.github.io/PUI/doc/Reference.html)
|
|
200
|
+
* [Layout Strategy](https://buganini.github.io/PUI/doc/Layout.html)
|
|
201
201
|
|
|
202
202
|
# Used by
|
|
203
|
-
* https://github.com/buganini/
|
|
203
|
+
* https://github.com/buganini/Kikakuka
|
|
204
204
|
* https://github.com/solvcon/modmesh
|
|
205
205
|
|
|
206
206
|
# TODO
|
|
207
|
-
* Merge node and view
|
|
208
207
|
* Dump with layout parameters and add test cases
|
|
209
208
|
* [Toga](https://beeware.org/project/projects/libraries/toga/)
|
|
210
|
-
* [ISSUE] textual layout sizing (cookbook scroll example)
|
|
211
209
|
* [ISSUE] flet layout sizing (cookbook scroll example)
|
|
212
210
|
* nested state trigger
|
|
213
211
|
* set state in PUIView __init__
|
|
214
212
|
* set state in setup() ?
|
|
215
213
|
* Tabs(`tabposition`)
|
|
216
214
|
* Lazy List
|
|
217
|
-
* StateObject decorator
|
|
218
215
|
* UI Flow
|
|
219
216
|
* Navigation Stack
|
|
220
217
|
* View Router
|
|
221
218
|
* Model Window/Dialog
|
|
222
219
|
* Layout
|
|
223
|
-
* ZBox
|
|
224
220
|
* SwiftUI style overlay ??
|
|
225
221
|
* Canvas
|
|
226
|
-
* Rect
|
|
227
222
|
* Arc
|
|
228
|
-
* Image
|
|
229
223
|
* ...
|
|
230
|
-
* Table
|
|
231
|
-
* Tree
|
|
232
|
-
* Dialog
|
|
233
224
|
* State with Pydantic support?
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: qpuiq
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.19
|
|
4
4
|
Summary: "PUI" Python Declarative UI Framework
|
|
5
5
|
Home-page: https://github.com/buganini/PUI
|
|
6
6
|
Author: Buganini Chiu
|
|
@@ -213,38 +213,29 @@ Then PUI will take care of view update [(code)](https://github.com/buganini/PUI/
|
|
|
213
213
|
* no canvas
|
|
214
214
|
|
|
215
215
|
# Documents
|
|
216
|
-
* [Components Reference](
|
|
217
|
-
* [
|
|
216
|
+
* [Components Reference](https://buganini.github.io/PUI/doc/Reference.html)
|
|
217
|
+
* [Layout Strategy](https://buganini.github.io/PUI/doc/Layout.html)
|
|
218
218
|
|
|
219
219
|
# Used by
|
|
220
|
-
* https://github.com/buganini/
|
|
220
|
+
* https://github.com/buganini/Kikakuka
|
|
221
221
|
* https://github.com/solvcon/modmesh
|
|
222
222
|
|
|
223
223
|
# TODO
|
|
224
|
-
* Merge node and view
|
|
225
224
|
* Dump with layout parameters and add test cases
|
|
226
225
|
* [Toga](https://beeware.org/project/projects/libraries/toga/)
|
|
227
|
-
* [ISSUE] textual layout sizing (cookbook scroll example)
|
|
228
226
|
* [ISSUE] flet layout sizing (cookbook scroll example)
|
|
229
227
|
* nested state trigger
|
|
230
228
|
* set state in PUIView __init__
|
|
231
229
|
* set state in setup() ?
|
|
232
230
|
* Tabs(`tabposition`)
|
|
233
231
|
* Lazy List
|
|
234
|
-
* StateObject decorator
|
|
235
232
|
* UI Flow
|
|
236
233
|
* Navigation Stack
|
|
237
234
|
* View Router
|
|
238
235
|
* Model Window/Dialog
|
|
239
236
|
* Layout
|
|
240
|
-
* ZBox
|
|
241
237
|
* SwiftUI style overlay ??
|
|
242
238
|
* Canvas
|
|
243
|
-
* Rect
|
|
244
239
|
* Arc
|
|
245
|
-
* Image
|
|
246
240
|
* ...
|
|
247
|
-
* Table
|
|
248
|
-
* Tree
|
|
249
|
-
* Dialog
|
|
250
241
|
* State with Pydantic support?
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|