qpuiq 0.13__py3-none-any.whl → 0.14__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of qpuiq might be problematic. Click here for more details.
- PUI/PySide6/base.py +3 -3
- PUI/PySide6/canvas.py +38 -2
- PUI/PySide6/combobox.py +12 -2
- PUI/PySide6/image.py +20 -2
- PUI/PySide6/layout.py +8 -8
- PUI/PySide6/tree.py +25 -15
- PUI/__init__.py +1 -1
- PUI/common.py +6 -0
- PUI/textual/__init__.py +1 -0
- PUI/textual/base.py +94 -59
- PUI/textual/label.py +2 -2
- PUI/textual/layout.py +4 -0
- PUI/textual/scroll.py +6 -4
- PUI/tkinter/canvas.py +3 -0
- PUI/wx/base.py +109 -65
- PUI/wx/canvas.py +2 -2
- PUI/wx/combobox.py +13 -4
- PUI/wx/layout.py +6 -0
- PUI/wx/scroll.py +13 -2
- {qpuiq-0.13.dist-info → qpuiq-0.14.dist-info}/METADATA +12 -4
- {qpuiq-0.13.dist-info → qpuiq-0.14.dist-info}/RECORD +24 -24
- {qpuiq-0.13.dist-info → qpuiq-0.14.dist-info}/WHEEL +1 -1
- {qpuiq-0.13.dist-info → qpuiq-0.14.dist-info/licenses}/LICENSE.txt +0 -0
- {qpuiq-0.13.dist-info → qpuiq-0.14.dist-info}/top_level.txt +0 -0
PUI/PySide6/base.py
CHANGED
|
@@ -193,20 +193,20 @@ class QtBaseLayout(PUINode):
|
|
|
193
193
|
from .modal import Modal
|
|
194
194
|
from .layout import Spacer
|
|
195
195
|
if isinstance(child, Spacer):
|
|
196
|
-
self.
|
|
196
|
+
self.qtlayout.insertItem(idx, child.outer)
|
|
197
197
|
elif isinstance(child, Modal):
|
|
198
198
|
pass
|
|
199
199
|
elif isinstance(child, QtBaseWidget) or isinstance(child, QtBaseLayout):
|
|
200
200
|
params = {}
|
|
201
201
|
if not child.layout_weight is None:
|
|
202
202
|
params["stretch"] = child.layout_weight
|
|
203
|
-
self.
|
|
203
|
+
self.qtlayout.insertWidget(idx, child.outer, **params)
|
|
204
204
|
|
|
205
205
|
def removeChild(self, idx, child):
|
|
206
206
|
from .modal import Modal
|
|
207
207
|
from .layout import Spacer
|
|
208
208
|
if isinstance(child, Spacer):
|
|
209
|
-
self.
|
|
209
|
+
self.qtlayout.removeItem(child.outer)
|
|
210
210
|
elif isinstance(child, Modal):
|
|
211
211
|
pass
|
|
212
212
|
elif isinstance(child, QtBaseWidget) or isinstance(child, QtBaseLayout):
|
PUI/PySide6/canvas.py
CHANGED
|
@@ -2,8 +2,7 @@ from .. import *
|
|
|
2
2
|
from .base import *
|
|
3
3
|
|
|
4
4
|
from PySide6 import QtWidgets, QtGui
|
|
5
|
-
from PySide6.QtGui import QPainter, QColor, QPainterPath
|
|
6
|
-
from PySide6.QtCore import QPoint
|
|
5
|
+
from PySide6.QtGui import QPainter, QColor, QPainterPath, QImage
|
|
7
6
|
|
|
8
7
|
class PUIQtCanvas(QtWidgets.QWidget):
|
|
9
8
|
def __init__(self, node, width=None, height=None):
|
|
@@ -46,6 +45,17 @@ class PUIQtCanvas(QtWidgets.QWidget):
|
|
|
46
45
|
e.x_delta = event.pixelDelta().x()
|
|
47
46
|
e.v_delta = event.angleDelta().y()
|
|
48
47
|
e.h_delta = event.angleDelta().x()
|
|
48
|
+
modifier = 0
|
|
49
|
+
emodifiers = event.modifiers()
|
|
50
|
+
if emodifiers & QtCore.Qt.ShiftModifier:
|
|
51
|
+
modifier |= KeyModifier.SHIFT
|
|
52
|
+
if emodifiers & QtCore.Qt.ControlModifier:
|
|
53
|
+
modifier |= KeyModifier.CTRL
|
|
54
|
+
if emodifiers & QtCore.Qt.AltModifier:
|
|
55
|
+
modifier |= KeyModifier.ALT
|
|
56
|
+
if emodifiers & QtCore.Qt.MetaModifier:
|
|
57
|
+
modifier |= KeyModifier.META
|
|
58
|
+
e.modifiers = modifier
|
|
49
59
|
self.node._wheel(e)
|
|
50
60
|
|
|
51
61
|
def paintEvent(self, event):
|
|
@@ -61,6 +71,8 @@ class PUIQtCanvas(QtWidgets.QWidget):
|
|
|
61
71
|
rect = QtCore.QRect(0, 0, self.width or self.geometry().width(), self.height or self.geometry().height())
|
|
62
72
|
node.qpainter.fillRect(rect, bgBrush)
|
|
63
73
|
|
|
74
|
+
node.width = self.geometry().width()
|
|
75
|
+
node.height = self.geometry().height()
|
|
64
76
|
node.painter(node, *node.args)
|
|
65
77
|
|
|
66
78
|
node.qpainter.end()
|
|
@@ -286,3 +298,27 @@ class Canvas(QtBaseWidget):
|
|
|
286
298
|
self.drawPolyline(shape.coords, color=stroke, width=width)
|
|
287
299
|
else:
|
|
288
300
|
raise RuntimeError(f"Not implemented: drawShapely({type(shape).__name__}) {dir(shape)}")
|
|
301
|
+
|
|
302
|
+
def loadImage(self, image_path):
|
|
303
|
+
return QImage(image_path)
|
|
304
|
+
|
|
305
|
+
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):
|
|
306
|
+
if image.isNull():
|
|
307
|
+
return
|
|
308
|
+
|
|
309
|
+
if src_width is None:
|
|
310
|
+
src_width = image.width() - src_x
|
|
311
|
+
if src_height is None:
|
|
312
|
+
src_height = image.height() - src_y
|
|
313
|
+
|
|
314
|
+
source_rect = QtCore.QRect(src_x, src_y, src_width, src_height)
|
|
315
|
+
|
|
316
|
+
if width is None:
|
|
317
|
+
width = src_width
|
|
318
|
+
if height is None:
|
|
319
|
+
height = src_height
|
|
320
|
+
|
|
321
|
+
dest_rect = QtCore.QRect(x, y, width, height)
|
|
322
|
+
self.qpainter.setOpacity(opacity)
|
|
323
|
+
self.qpainter.drawImage(dest_rect, image, source_rect)
|
|
324
|
+
self.qpainter.setOpacity(1.0)
|
PUI/PySide6/combobox.py
CHANGED
|
@@ -24,13 +24,16 @@ class ComboBox(QtBaseWidget):
|
|
|
24
24
|
super().update(prev)
|
|
25
25
|
|
|
26
26
|
def postSync(self):
|
|
27
|
+
index = 0
|
|
28
|
+
text = ""
|
|
29
|
+
|
|
27
30
|
if self.index_model:
|
|
28
31
|
index = self.index_model.value
|
|
29
32
|
text = self.children[index].text
|
|
30
33
|
elif self.text_model:
|
|
31
34
|
text = str(self.text_model.value)
|
|
32
35
|
try:
|
|
33
|
-
index = [c.
|
|
36
|
+
index = [c.value for c in self.children].index(text)
|
|
34
37
|
except:
|
|
35
38
|
index = 0
|
|
36
39
|
|
|
@@ -51,11 +54,15 @@ class ComboBox(QtBaseWidget):
|
|
|
51
54
|
def on_currentIndexChanged(self, idx):
|
|
52
55
|
if self.index_model:
|
|
53
56
|
self.index_model.value = idx
|
|
57
|
+
if self.text_model:
|
|
58
|
+
self.text_model.value = self.children[idx].value
|
|
54
59
|
e = PUIEvent()
|
|
55
60
|
e.value = idx
|
|
56
61
|
self._change(e)
|
|
57
62
|
|
|
58
63
|
def on_currentTextChanged(self, text):
|
|
64
|
+
if not self.editable:
|
|
65
|
+
return
|
|
59
66
|
if self.text_model:
|
|
60
67
|
self.text_model.value = text
|
|
61
68
|
e = PUIEvent()
|
|
@@ -69,7 +76,10 @@ class ComboBox(QtBaseWidget):
|
|
|
69
76
|
self.ui.removeItem(idx)
|
|
70
77
|
|
|
71
78
|
class ComboBoxItem(PUINode):
|
|
72
|
-
def __init__(self, text):
|
|
79
|
+
def __init__(self, text, value=None):
|
|
73
80
|
super().__init__()
|
|
74
81
|
self.id(text)
|
|
75
82
|
self.text = text
|
|
83
|
+
if value is None:
|
|
84
|
+
value = text
|
|
85
|
+
self.value = value
|
PUI/PySide6/image.py
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
from .. import *
|
|
2
2
|
from .base import *
|
|
3
|
+
from .label import ClickableQLabel
|
|
4
|
+
from PySide6.QtWidgets import QSizePolicy
|
|
5
|
+
import os
|
|
3
6
|
|
|
4
7
|
class Image(QtBaseWidget):
|
|
5
8
|
def __init__(self, path):
|
|
@@ -10,13 +13,28 @@ class Image(QtBaseWidget):
|
|
|
10
13
|
def update(self, prev):
|
|
11
14
|
if prev and prev.ui:
|
|
12
15
|
self.ui = prev.ui
|
|
16
|
+
self.eventFilter = prev.eventFilter
|
|
13
17
|
self.curr_path = prev.curr_path
|
|
18
|
+
self.curr_path_mtime = prev.curr_path_mtime
|
|
14
19
|
self.pixmap = prev.pixmap
|
|
15
20
|
else:
|
|
16
|
-
self.ui =
|
|
21
|
+
self.ui = ClickableQLabel()
|
|
22
|
+
self.ui.clicked.connect(self._clicked)
|
|
17
23
|
self.curr_path = Prop()
|
|
24
|
+
self.curr_path_mtime = Prop()
|
|
18
25
|
|
|
19
|
-
if self.
|
|
26
|
+
if self._onClicked:
|
|
27
|
+
self.ui.setCursor(QtCore.Qt.PointingHandCursor)
|
|
28
|
+
|
|
29
|
+
if self.layout_weight:
|
|
30
|
+
# XXX keep aspect ratio
|
|
31
|
+
self.ui.setScaledContents(True)
|
|
32
|
+
self.ui.setSizePolicy(QSizePolicy(QSizePolicy.Policy.Ignored, QSizePolicy.Policy.Ignored))
|
|
33
|
+
else:
|
|
34
|
+
self.ui.setScaledContents(False)
|
|
35
|
+
self.ui.setSizePolicy(QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Preferred))
|
|
36
|
+
|
|
37
|
+
if self.curr_path.set(self.path) or self.curr_path_mtime.set(os.path.getmtime(self.path)):
|
|
20
38
|
self.pixmap = QtGui.QPixmap(self.path)
|
|
21
39
|
if self.layout_width is not None and self.layout_height is not None:
|
|
22
40
|
self.pixmap = self.pixmap.scaled(self.layout_width, self.layout_height, QtCore.Qt.KeepAspectRatio, mode=QtCore.Qt.SmoothTransformation)
|
PUI/PySide6/layout.py
CHANGED
|
@@ -5,24 +5,24 @@ class HBox(QtBaseLayout):
|
|
|
5
5
|
def update(self, prev):
|
|
6
6
|
if prev and prev.ui:
|
|
7
7
|
self.ui = prev.ui
|
|
8
|
-
self.
|
|
8
|
+
self.qtlayout = prev.qtlayout
|
|
9
9
|
else:
|
|
10
10
|
self.ui = QtWidgets.QWidget()
|
|
11
|
-
self.
|
|
12
|
-
self.
|
|
13
|
-
self.ui.setLayout(self.
|
|
11
|
+
self.qtlayout = QtWidgets.QHBoxLayout()
|
|
12
|
+
self.qtlayout.setContentsMargins(0,0,0,0)
|
|
13
|
+
self.ui.setLayout(self.qtlayout)
|
|
14
14
|
super().update(prev)
|
|
15
15
|
|
|
16
16
|
class VBox(QtBaseLayout):
|
|
17
17
|
def update(self, prev):
|
|
18
18
|
if prev and prev.ui:
|
|
19
19
|
self.ui = prev.ui
|
|
20
|
-
self.
|
|
20
|
+
self.qtlayout = prev.qtlayout
|
|
21
21
|
else:
|
|
22
22
|
self.ui = QtWidgets.QWidget()
|
|
23
|
-
self.
|
|
24
|
-
self.
|
|
25
|
-
self.ui.setLayout(self.
|
|
23
|
+
self.qtlayout = QtWidgets.QVBoxLayout()
|
|
24
|
+
self.qtlayout.setContentsMargins(0,0,0,0)
|
|
25
|
+
self.ui.setLayout(self.qtlayout)
|
|
26
26
|
super().update(prev)
|
|
27
27
|
|
|
28
28
|
class Spacer(PUINode):
|
PUI/PySide6/tree.py
CHANGED
|
@@ -2,6 +2,9 @@ from .. import *
|
|
|
2
2
|
from .base import *
|
|
3
3
|
from PySide6.QtCore import Qt, QModelIndex, QAbstractItemModel
|
|
4
4
|
|
|
5
|
+
# XXX
|
|
6
|
+
# If click handler triggers a model reset, dblclick handler will not be called
|
|
7
|
+
|
|
5
8
|
class QAbstractItemModelAdapter(QtCore.QAbstractItemModel):
|
|
6
9
|
def __init__(self, model: "BaseTreeAdapter"):
|
|
7
10
|
super().__init__()
|
|
@@ -77,13 +80,12 @@ class QAbstractItemModelAdapter(QtCore.QAbstractItemModel):
|
|
|
77
80
|
self.model.collapsed(node)
|
|
78
81
|
|
|
79
82
|
class QTreeNodeModelAdapter(QtCore.QAbstractItemModel):
|
|
80
|
-
def __init__(self
|
|
83
|
+
def __init__(self):
|
|
81
84
|
super().__init__()
|
|
82
85
|
self.node = None
|
|
83
|
-
self.rootnode = rootnode
|
|
84
86
|
|
|
85
87
|
def index(self, row, column, parent = QtCore.QModelIndex()):
|
|
86
|
-
parent_node = parent.internalPointer() if parent.isValid() else self.
|
|
88
|
+
parent_node = parent.internalPointer() if parent.isValid() else self.node
|
|
87
89
|
if 0 <= row and row < len(parent_node.children):
|
|
88
90
|
child = parent_node.children[row]
|
|
89
91
|
return self.createIndex(row, column, child)
|
|
@@ -130,14 +132,14 @@ class QTreeNodeModelAdapter(QtCore.QAbstractItemModel):
|
|
|
130
132
|
return None
|
|
131
133
|
|
|
132
134
|
def rowCount(self, parent):
|
|
133
|
-
parent_node = parent.internalPointer() if parent.isValid() else self.
|
|
135
|
+
parent_node = parent.internalPointer() if parent.isValid() else self.node
|
|
134
136
|
return len(parent_node.children)
|
|
135
137
|
|
|
136
138
|
def columnCount(self, parent):
|
|
137
139
|
return 1
|
|
138
140
|
|
|
139
141
|
def hasChildren(self, parent):
|
|
140
|
-
parent_node = parent.internalPointer() if parent.isValid() else self.
|
|
142
|
+
parent_node = parent.internalPointer() if parent.isValid() else self.node
|
|
141
143
|
return len(parent_node.children) > 0
|
|
142
144
|
|
|
143
145
|
def clicked(self, node):
|
|
@@ -167,15 +169,21 @@ class Tree(QtBaseWidget):
|
|
|
167
169
|
self.ui = prev.ui
|
|
168
170
|
self.qt_model = prev.qt_model
|
|
169
171
|
self.curr_model = prev.curr_model
|
|
172
|
+
|
|
173
|
+
self.ui.clicked.disconnect()
|
|
174
|
+
self.ui.doubleClicked.disconnect()
|
|
175
|
+
self.ui.expanded.disconnect()
|
|
176
|
+
self.ui.collapsed.disconnect()
|
|
170
177
|
else:
|
|
171
178
|
self.qt_model = None
|
|
172
179
|
self.curr_model = Prop()
|
|
173
180
|
self.ui = QtWidgets.QTreeView()
|
|
174
181
|
self.ui.setHeaderHidden(True)
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
182
|
+
|
|
183
|
+
self.ui.clicked.connect(self.on_item_clicked)
|
|
184
|
+
self.ui.doubleClicked.connect(self.on_item_double_clicked)
|
|
185
|
+
self.ui.expanded.connect(self.on_item_expanded)
|
|
186
|
+
self.ui.collapsed.connect(self.on_item_collapsed)
|
|
179
187
|
|
|
180
188
|
if self.model:
|
|
181
189
|
if self.curr_model.set(self.model):
|
|
@@ -186,11 +194,13 @@ class Tree(QtBaseWidget):
|
|
|
186
194
|
self.qt_model.modelReset.emit()
|
|
187
195
|
else:
|
|
188
196
|
if not self.qt_model:
|
|
189
|
-
self.qt_model = QTreeNodeModelAdapter(
|
|
197
|
+
self.qt_model = QTreeNodeModelAdapter()
|
|
190
198
|
self.qt_model.node = self
|
|
191
199
|
self.ui.setModel(self.qt_model)
|
|
192
200
|
else:
|
|
193
|
-
self.qt_model.
|
|
201
|
+
self.qt_model.beginResetModel()
|
|
202
|
+
self.qt_model.node = self
|
|
203
|
+
self.qt_model.endResetModel()
|
|
194
204
|
|
|
195
205
|
for pending in self.pendings:
|
|
196
206
|
pending[0](*pending[1:])
|
|
@@ -239,19 +249,19 @@ class Tree(QtBaseWidget):
|
|
|
239
249
|
|
|
240
250
|
def on_item_clicked(self, index):
|
|
241
251
|
treenode = index.internalPointer()
|
|
242
|
-
self.qt_model.clicked(treenode)
|
|
252
|
+
self.get_node().qt_model.clicked(treenode)
|
|
243
253
|
|
|
244
254
|
def on_item_double_clicked(self, index):
|
|
245
255
|
treenode = index.internalPointer()
|
|
246
|
-
self.qt_model.dblclicked(treenode)
|
|
256
|
+
self.get_node().qt_model.dblclicked(treenode)
|
|
247
257
|
|
|
248
258
|
def on_item_expanded(self, index):
|
|
249
259
|
treenode = index.internalPointer()
|
|
250
|
-
self.qt_model.expanded(treenode)
|
|
260
|
+
self.get_node().qt_model.expanded(treenode)
|
|
251
261
|
|
|
252
262
|
def on_item_collapsed(self, index):
|
|
253
263
|
treenode = index.internalPointer()
|
|
254
|
-
self.qt_model.collapsed(treenode)
|
|
264
|
+
self.get_node().qt_model.collapsed(treenode)
|
|
255
265
|
|
|
256
266
|
class TreeNode(PUINode):
|
|
257
267
|
def __init__(self, data=""):
|
PUI/__init__.py
CHANGED
PUI/common.py
CHANGED
PUI/textual/__init__.py
CHANGED
PUI/textual/base.py
CHANGED
|
@@ -3,24 +3,57 @@ from textual import widgets, containers
|
|
|
3
3
|
|
|
4
4
|
class TBase(PUINode):
|
|
5
5
|
scroll = False
|
|
6
|
-
container_x = False
|
|
7
|
-
container_y = False
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
6
|
+
container_x = False # axis
|
|
7
|
+
container_y = False # axis
|
|
8
|
+
expand_x_prio = 0
|
|
9
|
+
expand_y_prio = 0
|
|
10
|
+
expand_x1_children = 0
|
|
11
|
+
expand_x2_children = 0
|
|
12
|
+
expand_x3_children = 0
|
|
13
|
+
expand_x4_children = 0
|
|
14
|
+
expand_y1_children = 0
|
|
15
|
+
expand_y2_children = 0
|
|
16
|
+
expand_y3_children = 0
|
|
17
|
+
expand_y4_children = 0
|
|
18
|
+
cached_tparent = None
|
|
16
19
|
|
|
17
20
|
@property
|
|
18
21
|
def expand_x(self):
|
|
19
|
-
|
|
22
|
+
parent = self.cached_tparent
|
|
23
|
+
expand = self.expand_x_prio
|
|
24
|
+
if not parent:
|
|
25
|
+
return False
|
|
26
|
+
|
|
27
|
+
# textual handles 1fr as shrinkable, but we need scrolller's content not to shrink
|
|
28
|
+
# See Exp.1 in refs/textual_layout.py
|
|
29
|
+
if parent.scroll:
|
|
30
|
+
return False
|
|
31
|
+
|
|
32
|
+
# textual populates auto(1fr) to be 1fr(1fr), but we require expanding not to go over the container
|
|
33
|
+
# See Exp.2 in refs/textual_layout.py
|
|
34
|
+
if not parent.expand_x and expand < 3:
|
|
35
|
+
return False
|
|
36
|
+
|
|
37
|
+
return expand
|
|
20
38
|
|
|
21
39
|
@property
|
|
22
40
|
def expand_y(self):
|
|
23
|
-
|
|
41
|
+
parent = self.cached_tparent
|
|
42
|
+
expand = self.expand_y_prio
|
|
43
|
+
if not parent:
|
|
44
|
+
return False
|
|
45
|
+
|
|
46
|
+
# textual handles 1fr as shrinkable, but we need scrolller's content not to shrink
|
|
47
|
+
# See Exp.1 in refs/textual_layout.py
|
|
48
|
+
if parent.scroll:
|
|
49
|
+
return False
|
|
50
|
+
|
|
51
|
+
# textual populates auto(1fr) to be 1fr(1fr), but we require expanding not to go over the container
|
|
52
|
+
# See Exp.2 in refs/textual_layout.py
|
|
53
|
+
if not parent.expand_y and expand < 3:
|
|
54
|
+
return False
|
|
55
|
+
|
|
56
|
+
return expand
|
|
24
57
|
|
|
25
58
|
def tremove(self):
|
|
26
59
|
self.ui.remove()
|
|
@@ -30,57 +63,58 @@ class TBase(PUINode):
|
|
|
30
63
|
return super().destroy(direct)
|
|
31
64
|
|
|
32
65
|
def update(self, prev):
|
|
33
|
-
|
|
66
|
+
super().update(prev)
|
|
67
|
+
|
|
68
|
+
self.cached_tparent = parent = self.tparent
|
|
34
69
|
if parent:
|
|
35
|
-
if
|
|
36
|
-
if parent.
|
|
37
|
-
self.
|
|
38
|
-
if parent.
|
|
39
|
-
self.
|
|
70
|
+
if self.layout_weight:
|
|
71
|
+
if parent.container_x:
|
|
72
|
+
self.expand_x_prio = 4
|
|
73
|
+
if parent.container_y:
|
|
74
|
+
self.expand_y_prio = 4
|
|
75
|
+
|
|
76
|
+
if self.expand_x_prio >= 1:
|
|
77
|
+
parent.expand_x1_children += 1
|
|
78
|
+
if self.expand_x_prio >= 2:
|
|
79
|
+
parent.expand_x2_children += 1
|
|
80
|
+
if self.expand_x_prio >= 3:
|
|
81
|
+
parent.expand_x3_children += 1
|
|
82
|
+
if self.expand_x_prio >= 4:
|
|
83
|
+
parent.expand_x4_children += 1
|
|
84
|
+
|
|
85
|
+
if self.expand_y_prio >= 1:
|
|
86
|
+
parent.expand_y1_children += 1
|
|
87
|
+
if self.expand_y_prio >= 2:
|
|
88
|
+
parent.expand_y2_children += 1
|
|
89
|
+
if self.expand_y_prio >= 3:
|
|
90
|
+
parent.expand_y3_children += 1
|
|
91
|
+
if self.expand_y_prio >= 4:
|
|
92
|
+
parent.expand_y4_children += 1
|
|
40
93
|
|
|
41
|
-
|
|
94
|
+
def postUpdate(self):
|
|
95
|
+
super().postUpdate()
|
|
96
|
+
parent = self.cached_tparent
|
|
97
|
+
if parent:
|
|
42
98
|
if parent.container_x:
|
|
43
|
-
if parent.
|
|
44
|
-
self.
|
|
45
|
-
if self.
|
|
46
|
-
self.
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
p.weak_expand_x = True
|
|
52
|
-
if p==p.parent:
|
|
53
|
-
break
|
|
54
|
-
p = p.parent
|
|
99
|
+
if self.expand_x_prio < 1 and parent.expand_x1_children > 0:
|
|
100
|
+
self.expand_x_prio = 0
|
|
101
|
+
if self.expand_x_prio < 2 and parent.expand_x2_children > 0:
|
|
102
|
+
self.expand_x_prio = 0
|
|
103
|
+
if self.expand_x_prio < 3 and parent.expand_x3_children > 0:
|
|
104
|
+
self.expand_x_prio = 0
|
|
105
|
+
if self.expand_x_prio < 4 and parent.expand_x4_children > 0:
|
|
106
|
+
self.expand_x_prio = 0
|
|
55
107
|
|
|
56
108
|
if parent.container_y:
|
|
57
|
-
if parent.
|
|
58
|
-
self.
|
|
59
|
-
if self.
|
|
60
|
-
self.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
p.weak_expand_y = True
|
|
66
|
-
if p==p.parent:
|
|
67
|
-
break
|
|
68
|
-
p = p.parent
|
|
69
|
-
|
|
70
|
-
if parent.strong_expand_x_children > 0:
|
|
71
|
-
self.nweak_expand_x = True
|
|
72
|
-
if parent.strong_expand_y_children > 0:
|
|
73
|
-
self.nweak_expand_y = True
|
|
74
|
-
|
|
75
|
-
else:
|
|
76
|
-
# mark root node as expanding
|
|
77
|
-
self.strong_expand_x = True
|
|
78
|
-
self.strong_expand_y = True
|
|
109
|
+
if self.expand_y_prio < 1 and parent.expand_y1_children > 0:
|
|
110
|
+
self.expand_y_prio = 0
|
|
111
|
+
if self.expand_y_prio < 2 and parent.expand_y2_children > 0:
|
|
112
|
+
self.expand_y_prio = 0
|
|
113
|
+
if self.expand_y_prio < 3 and parent.expand_y3_children > 0:
|
|
114
|
+
self.expand_y_prio = 0
|
|
115
|
+
if self.expand_y_prio < 4 and parent.expand_y4_children > 0:
|
|
116
|
+
self.expand_y_prio = 0
|
|
79
117
|
|
|
80
|
-
super().update(prev)
|
|
81
|
-
|
|
82
|
-
def postUpdate(self):
|
|
83
|
-
super().postUpdate()
|
|
84
118
|
self.t_update_layout()
|
|
85
119
|
|
|
86
120
|
@property
|
|
@@ -106,8 +140,9 @@ class TBase(PUINode):
|
|
|
106
140
|
height = "1fr"
|
|
107
141
|
|
|
108
142
|
if self._debug:
|
|
109
|
-
print("layout", self.key, f"{width}:{height} expand_x={self.expand_x}", f"expand_y={self.expand_y}", f"
|
|
110
|
-
self.ui.
|
|
143
|
+
print("layout", self.key, f"{width}:{height} expand_x={self.expand_x}", f"expand_y={self.expand_y}", f"expand_x_prio={self.expand_x_prio}", f"expand_y_prio={self.expand_y_prio}")
|
|
144
|
+
self.ui.styles.width = width
|
|
145
|
+
self.ui.styles.height = height
|
|
111
146
|
|
|
112
147
|
class TPUIView(PUIView):
|
|
113
148
|
pui_virtual = True
|
PUI/textual/label.py
CHANGED
|
@@ -13,13 +13,12 @@ class Label(TBase):
|
|
|
13
13
|
self.widget = prev.widget
|
|
14
14
|
else:
|
|
15
15
|
self.ui = containers.Container()
|
|
16
|
-
self.ui.set_styles("width: auto; height: auto;")
|
|
17
16
|
if self._onClicked:
|
|
18
17
|
if self.widget is None or not isinstance(self.widget, widgets.Button):
|
|
19
18
|
if self.widget:
|
|
20
19
|
self.widget.remove()
|
|
21
20
|
self.widget = widgets.Button(self.text)
|
|
22
|
-
self.widget.set_styles("
|
|
21
|
+
self.widget.set_styles("border-top: none; border-bottom: none;")
|
|
23
22
|
self.widget.puinode = self
|
|
24
23
|
else:
|
|
25
24
|
self.widget.label = self.text
|
|
@@ -33,4 +32,5 @@ class Label(TBase):
|
|
|
33
32
|
super().update(prev)
|
|
34
33
|
|
|
35
34
|
def postUpdate(self):
|
|
35
|
+
super().postUpdate()
|
|
36
36
|
self.ui.mount(self.widget)
|
PUI/textual/layout.py
CHANGED
|
@@ -3,6 +3,8 @@ from .base import *
|
|
|
3
3
|
|
|
4
4
|
class VBox(TBase):
|
|
5
5
|
container_y = True
|
|
6
|
+
expand_x_prio = 1
|
|
7
|
+
expand_y_prio = 2
|
|
6
8
|
def update(self, prev):
|
|
7
9
|
if prev and prev.ui:
|
|
8
10
|
self.ui = prev.ui
|
|
@@ -20,6 +22,8 @@ class VBox(TBase):
|
|
|
20
22
|
|
|
21
23
|
class HBox(TBase):
|
|
22
24
|
container_x = True
|
|
25
|
+
expand_x_prio = 2
|
|
26
|
+
expand_y_prio = 1
|
|
23
27
|
def update(self, prev):
|
|
24
28
|
if prev and prev.ui:
|
|
25
29
|
self.ui = prev.ui
|
PUI/textual/scroll.py
CHANGED
|
@@ -4,8 +4,6 @@ import math
|
|
|
4
4
|
|
|
5
5
|
class Scroll(TBase):
|
|
6
6
|
END = -0.0
|
|
7
|
-
weak_expand_x = True
|
|
8
|
-
weak_expand_y = True
|
|
9
7
|
scroll = True
|
|
10
8
|
def __init__(self, vertical=None, horizontal=False):
|
|
11
9
|
self.vertical = vertical
|
|
@@ -19,23 +17,27 @@ class Scroll(TBase):
|
|
|
19
17
|
self.ui = prev.ui
|
|
20
18
|
else:
|
|
21
19
|
self.ui = containers.ScrollableContainer()
|
|
20
|
+
|
|
22
21
|
v = "auto"
|
|
23
22
|
self.container_y = True
|
|
23
|
+
self.expand_y_prio = 3
|
|
24
24
|
if self.vertical is True:
|
|
25
25
|
v = "scroll"
|
|
26
26
|
elif self.vertical is False:
|
|
27
27
|
v = "hidden"
|
|
28
28
|
self.container_y = False
|
|
29
|
-
self.
|
|
29
|
+
self.expand_y_prio = 1
|
|
30
30
|
|
|
31
31
|
h = "auto"
|
|
32
32
|
self.container_x = True
|
|
33
|
+
self.expand_x_prio = 3
|
|
33
34
|
if self.horizontal is True:
|
|
34
35
|
h = "scroll"
|
|
35
36
|
elif self.horizontal is False:
|
|
36
37
|
h = "hidden"
|
|
37
38
|
self.container_x = False
|
|
38
|
-
self.
|
|
39
|
+
self.expand_x_prio = 1
|
|
40
|
+
|
|
39
41
|
self.ui.set_styles(f"overflow-x: {h}; overflow-y: {v};")
|
|
40
42
|
|
|
41
43
|
super().update(prev)
|
PUI/tkinter/canvas.py
CHANGED
PUI/wx/base.py
CHANGED
|
@@ -45,74 +45,86 @@ class WxPUIView(PUIView):
|
|
|
45
45
|
|
|
46
46
|
class WXBase(PUINode):
|
|
47
47
|
scroll = False
|
|
48
|
-
container_x = False
|
|
49
|
-
container_y = False
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
48
|
+
container_x = False # axis
|
|
49
|
+
container_y = False # axis
|
|
50
|
+
expand_x_prio = 0
|
|
51
|
+
expand_y_prio = 0
|
|
52
|
+
expand_x1_children = 0
|
|
53
|
+
expand_x2_children = 0
|
|
54
|
+
expand_x3_children = 0
|
|
55
|
+
expand_x4_children = 0
|
|
56
|
+
expand_y1_children = 0
|
|
57
|
+
expand_y2_children = 0
|
|
58
|
+
expand_y3_children = 0
|
|
59
|
+
expand_y4_children = 0
|
|
60
|
+
cached_wxparent = None
|
|
58
61
|
|
|
59
62
|
@property
|
|
60
63
|
def expand_x(self):
|
|
61
|
-
return self.
|
|
64
|
+
return self.expand_x_prio
|
|
62
65
|
|
|
63
66
|
@property
|
|
64
67
|
def expand_y(self):
|
|
65
|
-
return self.
|
|
68
|
+
return self.expand_y_prio
|
|
66
69
|
|
|
67
70
|
def update(self, prev):
|
|
71
|
+
self.cached_wxparent = parent = self.wxparent
|
|
72
|
+
|
|
68
73
|
parent = self.wxparent
|
|
69
74
|
if parent:
|
|
70
|
-
if
|
|
71
|
-
if parent.
|
|
72
|
-
self.
|
|
73
|
-
if parent.
|
|
74
|
-
self.
|
|
75
|
+
if self.layout_weight:
|
|
76
|
+
if parent.container_x:
|
|
77
|
+
self.expand_x_prio = 4
|
|
78
|
+
if parent.container_y:
|
|
79
|
+
self.expand_y_prio = 4
|
|
80
|
+
|
|
81
|
+
if self.expand_x_prio >= 1:
|
|
82
|
+
parent.expand_x1_children += 1
|
|
83
|
+
if self.expand_x_prio >= 2:
|
|
84
|
+
parent.expand_x2_children += 1
|
|
85
|
+
if self.expand_x_prio >= 3:
|
|
86
|
+
parent.expand_x3_children += 1
|
|
87
|
+
if self.expand_x_prio >= 4:
|
|
88
|
+
parent.expand_x4_children += 1
|
|
89
|
+
|
|
90
|
+
if self.expand_y_prio >= 1:
|
|
91
|
+
parent.expand_y1_children += 1
|
|
92
|
+
if self.expand_y_prio >= 2:
|
|
93
|
+
parent.expand_y2_children += 1
|
|
94
|
+
if self.expand_y_prio >= 3:
|
|
95
|
+
parent.expand_y3_children += 1
|
|
96
|
+
if self.expand_y_prio >= 4:
|
|
97
|
+
parent.expand_y4_children += 1
|
|
98
|
+
|
|
99
|
+
super().update(prev)
|
|
75
100
|
|
|
76
|
-
|
|
101
|
+
def postUpdate(self):
|
|
102
|
+
parent = self.cached_wxparent
|
|
103
|
+
if parent:
|
|
77
104
|
if parent.container_x:
|
|
78
|
-
if parent.
|
|
79
|
-
self.
|
|
80
|
-
if self.
|
|
81
|
-
self.
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
p.weak_expand_x = True
|
|
87
|
-
if p==p.parent:
|
|
88
|
-
break
|
|
89
|
-
p = p.parent
|
|
105
|
+
if self.expand_x_prio < 1 and parent.expand_x1_children > 0:
|
|
106
|
+
self.expand_x_prio = 0
|
|
107
|
+
if self.expand_x_prio < 2 and parent.expand_x2_children > 0:
|
|
108
|
+
self.expand_x_prio = 0
|
|
109
|
+
if self.expand_x_prio < 3 and parent.expand_x3_children > 0:
|
|
110
|
+
self.expand_x_prio = 0
|
|
111
|
+
if self.expand_x_prio < 4 and parent.expand_x4_children > 0:
|
|
112
|
+
self.expand_x_prio = 0
|
|
90
113
|
|
|
91
114
|
if parent.container_y:
|
|
92
|
-
if parent.
|
|
93
|
-
self.
|
|
94
|
-
if self.
|
|
95
|
-
self.
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
p.weak_expand_y = True
|
|
101
|
-
if p==p.parent:
|
|
102
|
-
break
|
|
103
|
-
p = p.parent
|
|
104
|
-
|
|
105
|
-
if parent.strong_expand_x_children > 0:
|
|
106
|
-
self.nweak_expand_x = True
|
|
107
|
-
if parent.strong_expand_y_children > 0:
|
|
108
|
-
self.nweak_expand_y = True
|
|
115
|
+
if self.expand_y_prio < 1 and parent.expand_y1_children > 0:
|
|
116
|
+
self.expand_y_prio = 0
|
|
117
|
+
if self.expand_y_prio < 2 and parent.expand_y2_children > 0:
|
|
118
|
+
self.expand_y_prio = 0
|
|
119
|
+
if self.expand_y_prio < 3 and parent.expand_y3_children > 0:
|
|
120
|
+
self.expand_y_prio = 0
|
|
121
|
+
if self.expand_y_prio < 4 and parent.expand_y4_children > 0:
|
|
122
|
+
self.expand_y_prio = 0
|
|
109
123
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
self.strong_expand_x = True
|
|
113
|
-
self.strong_expand_y = True
|
|
124
|
+
if self._debug:
|
|
125
|
+
print("layout", self.key, f"weight={self.layout_weight}", f"expand_x={self.expand_x}", f"expand_y={self.expand_y}")
|
|
114
126
|
|
|
115
|
-
super().
|
|
127
|
+
super().postUpdate()
|
|
116
128
|
|
|
117
129
|
@property
|
|
118
130
|
def wxparent(self):
|
|
@@ -153,6 +165,7 @@ class WxBaseWidget(WXBase):
|
|
|
153
165
|
class WxBaseLayout(WXBase):
|
|
154
166
|
def __init__(self):
|
|
155
167
|
super().__init__()
|
|
168
|
+
self.relayout = False
|
|
156
169
|
if not isinstance(self.non_virtual_parent, WxBaseLayout):
|
|
157
170
|
self.layout_padding = (11,11,11,11)
|
|
158
171
|
|
|
@@ -161,8 +174,38 @@ class WxBaseLayout(WXBase):
|
|
|
161
174
|
self.ui = None
|
|
162
175
|
super().destroy(direct)
|
|
163
176
|
|
|
177
|
+
def update(self, prev):
|
|
178
|
+
if prev and prev.ui:
|
|
179
|
+
self.sizerItems = prev.sizerItems
|
|
180
|
+
else:
|
|
181
|
+
self.sizerItems = []
|
|
182
|
+
super().update(prev)
|
|
183
|
+
|
|
184
|
+
def postUpdate(self):
|
|
185
|
+
super().postUpdate()
|
|
186
|
+
|
|
187
|
+
for child, si in self.sizerItems:
|
|
188
|
+
if child.expand_x or child.expand_y:
|
|
189
|
+
si.SetFlag(wx.ALL | wx.EXPAND)
|
|
190
|
+
else:
|
|
191
|
+
# si.SetFlag(wx.ALL | wx.ALIGN_CENTER)
|
|
192
|
+
si.SetFlag(wx.ALL) # XXX
|
|
193
|
+
|
|
194
|
+
weight = child.layout_weight
|
|
195
|
+
if self.container_x and child.expand_x:
|
|
196
|
+
si.SetProportion(weight if weight else 1 if child.expand_x else 0)
|
|
197
|
+
elif self.container_y and child.expand_y:
|
|
198
|
+
si.SetProportion(weight if weight else 1 if child.expand_y else 0)
|
|
199
|
+
|
|
200
|
+
p = 0
|
|
201
|
+
if child.layout_padding:
|
|
202
|
+
p = max(child.layout_padding)
|
|
203
|
+
si.SetBorder(p)
|
|
204
|
+
|
|
164
205
|
def addChild(self, idx, child):
|
|
165
206
|
from .layout import Spacer
|
|
207
|
+
self.relayout = True
|
|
208
|
+
|
|
166
209
|
weight = child.layout_weight
|
|
167
210
|
if weight is None:
|
|
168
211
|
weight = 0
|
|
@@ -170,33 +213,34 @@ class WxBaseLayout(WXBase):
|
|
|
170
213
|
weight = 1
|
|
171
214
|
if not weight and self.container_y and child.expand_y:
|
|
172
215
|
weight = 1
|
|
173
|
-
flag = wx.ALL
|
|
174
216
|
|
|
175
|
-
p = 0
|
|
176
|
-
if child.layout_padding:
|
|
177
|
-
p = max(child.layout_padding)
|
|
178
217
|
if isinstance(child, WxBaseLayout):
|
|
179
|
-
self.ui.Insert(idx, child.outer
|
|
218
|
+
si = self.ui.Insert(idx, child.outer)
|
|
219
|
+
self.sizerItems.insert(idx, (child, si))
|
|
180
220
|
elif isinstance(child, WxBaseWidget):
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
else:
|
|
184
|
-
flag |= wx.ALIGN_CENTER
|
|
185
|
-
self.ui.Insert(idx, child.outer, proportion=weight, flag=flag, border=p)
|
|
221
|
+
si = self.ui.Insert(idx, child.outer)
|
|
222
|
+
self.sizerItems.insert(idx, (child, si))
|
|
186
223
|
elif isinstance(child, Spacer):
|
|
187
|
-
self.ui.InsertStretchSpacer(idx
|
|
224
|
+
si = self.ui.InsertStretchSpacer(idx)
|
|
225
|
+
self.sizerItems.insert(idx, (child, si))
|
|
188
226
|
|
|
189
227
|
def removeChild(self, idx, child):
|
|
228
|
+
self.relayout = True
|
|
229
|
+
|
|
190
230
|
from .layout import Spacer
|
|
191
231
|
if isinstance(child, WxBaseLayout):
|
|
192
232
|
self.ui.Detach(idx)
|
|
233
|
+
self.sizerItems.pop(idx)
|
|
193
234
|
elif isinstance(child, WxBaseWidget):
|
|
194
235
|
self.ui.Detach(idx)
|
|
236
|
+
self.sizerItems.pop(idx)
|
|
195
237
|
elif isinstance(child, Spacer):
|
|
196
238
|
self.ui.Detach(idx)
|
|
239
|
+
self.sizerItems.pop(idx)
|
|
197
240
|
|
|
198
241
|
def postSync(self):
|
|
199
|
-
if self.ui:
|
|
242
|
+
if self.relayout and self.ui:
|
|
243
|
+
self.relayout = False
|
|
200
244
|
self.ui.Layout()
|
|
201
|
-
self.ui.Fit(getWindow(self.parent))
|
|
245
|
+
# self.ui.Fit(getWindow(self.parent))
|
|
202
246
|
super().postSync()
|
PUI/wx/canvas.py
CHANGED
PUI/wx/combobox.py
CHANGED
|
@@ -17,20 +17,23 @@ class ComboBox(WxBaseWidget):
|
|
|
17
17
|
else:
|
|
18
18
|
self.curr_index = Prop()
|
|
19
19
|
self.curr_text = Prop()
|
|
20
|
-
self.ui = wx.ComboBox(getWindow(self.parent), choices=[])
|
|
20
|
+
self.ui = wx.ComboBox(getWindow(self.parent), choices=[], style=0 if self.editable else wx.CB_READONLY)
|
|
21
21
|
self.ui.Bind(wx.EVT_COMBOBOX, self._combobox)
|
|
22
22
|
self.ui.Bind(wx.EVT_TEXT, self._text)
|
|
23
23
|
|
|
24
24
|
super().update(prev)
|
|
25
25
|
|
|
26
26
|
def postSync(self):
|
|
27
|
+
index = 0
|
|
28
|
+
text = ""
|
|
29
|
+
|
|
27
30
|
if self.index_model:
|
|
28
31
|
index = self.index_model.value
|
|
29
32
|
text = self.children[index].text
|
|
30
33
|
elif self.text_model:
|
|
31
34
|
text = str(self.text_model.value)
|
|
32
35
|
try:
|
|
33
|
-
index = [c.
|
|
36
|
+
index = [c.value for c in self.children].index(text)
|
|
34
37
|
except:
|
|
35
38
|
index = 0
|
|
36
39
|
|
|
@@ -45,11 +48,15 @@ class ComboBox(WxBaseWidget):
|
|
|
45
48
|
idx = self.ui.GetSelection()
|
|
46
49
|
if node.index_model:
|
|
47
50
|
node.index_model.value = idx
|
|
51
|
+
if node.text_model:
|
|
52
|
+
node.text_model.value = self.children[idx].value
|
|
48
53
|
e = PUIEvent()
|
|
49
54
|
e.value = idx
|
|
50
55
|
node._change(e)
|
|
51
56
|
|
|
52
57
|
def _text(self, *args, **kwargs):
|
|
58
|
+
if not self.editable:
|
|
59
|
+
return
|
|
53
60
|
node = self.get_node()
|
|
54
61
|
text = self.ui.GetValue()
|
|
55
62
|
if node.text_model:
|
|
@@ -64,9 +71,11 @@ class ComboBox(WxBaseWidget):
|
|
|
64
71
|
def removeChild(self, idx, child):
|
|
65
72
|
self.ui.Delete(idx)
|
|
66
73
|
|
|
67
|
-
|
|
68
74
|
class ComboBoxItem(PUINode):
|
|
69
|
-
def __init__(self, text):
|
|
75
|
+
def __init__(self, text, value=None):
|
|
70
76
|
super().__init__()
|
|
71
77
|
self.id(text)
|
|
72
78
|
self.text = text
|
|
79
|
+
if value is None:
|
|
80
|
+
value = text
|
|
81
|
+
self.value = value
|
PUI/wx/layout.py
CHANGED
|
@@ -3,6 +3,9 @@ from .base import *
|
|
|
3
3
|
|
|
4
4
|
class HBox(WxBaseLayout):
|
|
5
5
|
container_x = True
|
|
6
|
+
expand_x_prio = 2
|
|
7
|
+
expand_y_prio = 1
|
|
8
|
+
|
|
6
9
|
def update(self, prev):
|
|
7
10
|
if prev and prev.ui:
|
|
8
11
|
self.ui = prev.ui
|
|
@@ -12,6 +15,9 @@ class HBox(WxBaseLayout):
|
|
|
12
15
|
|
|
13
16
|
class VBox(WxBaseLayout):
|
|
14
17
|
container_y = True
|
|
18
|
+
expand_x_prio = 1
|
|
19
|
+
expand_y_prio = 2
|
|
20
|
+
|
|
15
21
|
def update(self, prev):
|
|
16
22
|
if prev and prev.ui:
|
|
17
23
|
self.ui = prev.ui
|
PUI/wx/scroll.py
CHANGED
|
@@ -4,8 +4,6 @@ import wx.lib.scrolledpanel as scrolled
|
|
|
4
4
|
|
|
5
5
|
class Scroll(WxBaseWidget):
|
|
6
6
|
pui_terminal = False
|
|
7
|
-
weak_expand_x = True
|
|
8
|
-
weak_expand_y = True
|
|
9
7
|
scroll = True
|
|
10
8
|
|
|
11
9
|
END = -0.0
|
|
@@ -20,6 +18,19 @@ class Scroll(WxBaseWidget):
|
|
|
20
18
|
self.ui = prev.ui
|
|
21
19
|
else:
|
|
22
20
|
self.ui = scrolled.ScrolledPanel(getWindow(self.parent))
|
|
21
|
+
|
|
22
|
+
self.container_y = True
|
|
23
|
+
self.expand_y_prio = 3
|
|
24
|
+
if self.vertical is False:
|
|
25
|
+
self.container_y = False
|
|
26
|
+
self.expand_y_prio = 1
|
|
27
|
+
|
|
28
|
+
self.container_x = True
|
|
29
|
+
self.expand_x_prio = 3
|
|
30
|
+
if self.horizontal is False:
|
|
31
|
+
self.container_x = False
|
|
32
|
+
self.expand_x_prio = 1
|
|
33
|
+
|
|
23
34
|
super().update(prev)
|
|
24
35
|
|
|
25
36
|
def addChild(self, idx, child):
|
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: qpuiq
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.14
|
|
4
4
|
Summary: "PUI" Python Declarative UI Framework
|
|
5
5
|
Home-page: https://github.com/buganini/PUI
|
|
6
6
|
Author: Buganini Chiu
|
|
7
7
|
Author-email: buganini@b612.tw
|
|
8
8
|
Description-Content-Type: text/markdown
|
|
9
9
|
License-File: LICENSE.txt
|
|
10
|
+
Dynamic: author
|
|
11
|
+
Dynamic: author-email
|
|
12
|
+
Dynamic: description
|
|
13
|
+
Dynamic: description-content-type
|
|
14
|
+
Dynamic: home-page
|
|
15
|
+
Dynamic: license-file
|
|
16
|
+
Dynamic: summary
|
|
10
17
|
|
|
11
18
|
# What is PUI
|
|
12
19
|
PUI is a reactive/declarative UI framework with two-way data binding.
|
|
@@ -205,8 +212,9 @@ Then PUI will take care of view update [(code)](https://github.com/buganini/PUI/
|
|
|
205
212
|
* textual (Text Mode)
|
|
206
213
|
* no canvas
|
|
207
214
|
|
|
208
|
-
#
|
|
209
|
-
[Reference](REFERENCE.md)
|
|
215
|
+
# Documents
|
|
216
|
+
* [Components Reference](REFERENCE.md)
|
|
217
|
+
* [Sizing Strategy](https://html-preview.github.io/?url=https://github.com/buganini/PUI/blob/main/doc/Sizing.html)
|
|
210
218
|
|
|
211
219
|
# Used by
|
|
212
220
|
* https://github.com/buganini/kikit-ui
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
PUI/__init__.py,sha256=
|
|
2
|
-
PUI/common.py,sha256=
|
|
1
|
+
PUI/__init__.py,sha256=1cYRM8ouBVNa_BIQAMNzSyQJ5Ym-NMT-IL5Zp5mctfk,966
|
|
2
|
+
PUI/common.py,sha256=fUJmHOu5lSCeiOhFDF6YqulJxFqWmsneqnDZ2kZFFmM,581
|
|
3
3
|
PUI/decorator.py,sha256=BN3POYv69QCDomoHENN-UA-d4wY_vfARIb5RJ2qEnS8,483
|
|
4
4
|
PUI/dom.py,sha256=RgdDyv6vSFgkCoj9G2cjzQQOiymG8DwmmSoAZfxYvJM,10141
|
|
5
5
|
PUI/interfaces.py,sha256=rGUciM3S6ICEVgVoahkva8yXUGpweqy1kAzhUQut40E,2182
|
|
@@ -10,16 +10,16 @@ PUI/utils.py,sha256=canb7_Uz0sQ1UZDzyDuIsfAVXzEfZCkc9F81sMY4rTE,505
|
|
|
10
10
|
PUI/view.py,sha256=Oe6sXLHD554GnlLlO5QpY7kegngkzrmMEYRHrdzGZUQ,4623
|
|
11
11
|
PUI/PySide6/__init__.py,sha256=z895ldBVUaEqfGQW4CvYhWh2F6L0qGQA1MXUHVMf9Ms,1110
|
|
12
12
|
PUI/PySide6/application.py,sha256=OsIE47efST4I13txD-7rS1cTWAGhynckl45Wdb1bafk,1471
|
|
13
|
-
PUI/PySide6/base.py,sha256=
|
|
13
|
+
PUI/PySide6/base.py,sha256=bhIxbw16l78lgkSpN4_s2cV33pObj3O3yGhtiNIJ10w,7916
|
|
14
14
|
PUI/PySide6/button.py,sha256=mHfcH98dABYgksuT58fK0amSwtCM9aaYwr7Y2EArEJA,561
|
|
15
|
-
PUI/PySide6/canvas.py,sha256=
|
|
15
|
+
PUI/PySide6/canvas.py,sha256=Qad87bLpQJoh8U5hjqH3g3mSbodPwweT0TOqnB5LPyI,10416
|
|
16
16
|
PUI/PySide6/checkbox.py,sha256=Rsns0BleE4g9yTDdlsD8IADU3qcQkVO2VsFVvYlNL88,900
|
|
17
|
-
PUI/PySide6/combobox.py,sha256=
|
|
17
|
+
PUI/PySide6/combobox.py,sha256=mAfJ_7m-jTWBAh2Sng-BslY-_7EjIwRLbrx5IHik13I,2501
|
|
18
18
|
PUI/PySide6/dialog.py,sha256=4rAyLMqd47ALDxrBGLFHS5FD75SP1I8tkMSKBdaPkv0,2364
|
|
19
19
|
PUI/PySide6/divider.py,sha256=jRR8Qtdil-8JTxj8SyJydzRB_MGTKa_TxegsqkYKcXc,733
|
|
20
|
-
PUI/PySide6/image.py,sha256=
|
|
20
|
+
PUI/PySide6/image.py,sha256=uORM63K6v-1Ug4KpRJW3YHc-PpICqmRxmAzcEL6MaME,1969
|
|
21
21
|
PUI/PySide6/label.py,sha256=_G8bckRPPQdzZTS3j9JaOmfRAnLragBXnyJUG9_kblU,1038
|
|
22
|
-
PUI/PySide6/layout.py,sha256=
|
|
22
|
+
PUI/PySide6/layout.py,sha256=lEr37sxpYWHSo_d-8asPRVjnJsiePP4g9SaKFGLCpJs,2637
|
|
23
23
|
PUI/PySide6/matplotlib.py,sha256=fzVfwgmEX7s_WDtc_JULRdBOfZgcBewiH79f4ahZHQ4,825
|
|
24
24
|
PUI/PySide6/mdi.py,sha256=OGE2-5--Cy-srAzM-ZexnJ1efeORQvlsH2UA7qp18iE,805
|
|
25
25
|
PUI/PySide6/menu.py,sha256=Qbw_0WX56vzC2vkvn-4DXzYX0vZ-4Rq6tW1Kj_M-Qb8,2806
|
|
@@ -33,7 +33,7 @@ PUI/PySide6/table.py,sha256=TTCMf_YNKmkFiqs_qLqw3qbvFsxoBNnz9VMObx_2l3s,4800
|
|
|
33
33
|
PUI/PySide6/text.py,sha256=4kRRZiuH-bLLJMNZ6hK9zAWOorsG-l4uujHbG6I5S20,1069
|
|
34
34
|
PUI/PySide6/textfield.py,sha256=Us-UZMDCwrREwFLjPKKa3e3c_1U4WWD2kzFCe3xiY0k,2140
|
|
35
35
|
PUI/PySide6/toolbar.py,sha256=NPkn99D5xK4RLBA0vxLD7EqYu5eh9ucCL2y1vSJWQl4,1800
|
|
36
|
-
PUI/PySide6/tree.py,sha256=
|
|
36
|
+
PUI/PySide6/tree.py,sha256=skMsCykh8kWXFTg4Yv--PevJ58fqEeZV566ICjBVO4E,9324
|
|
37
37
|
PUI/PySide6/window.py,sha256=CpkIFpleVr3oXOM6vdukahWtX5SV6cWNc1TUW84JPM4,2694
|
|
38
38
|
PUI/flet/__init__.py,sha256=3YzGA0oPfu9eW8DtKQSoAsa8o6ZTGKWakYBTxGaaH8Y,438
|
|
39
39
|
PUI/flet/application.py,sha256=3ZGZrAngSEkVK-WseOV-n_6ljhd86ZKBgO6Jp2PmsJA,937
|
|
@@ -50,16 +50,16 @@ PUI/flet/tab.py,sha256=T26PZ-Ma_LPUx7u9qbxEnYqxuR1-qlytWiB9TDpu7G8,997
|
|
|
50
50
|
PUI/flet/text.py,sha256=HGnhOTDwG5pqceK8x_C6wCZj1AKuqZ9vEZB_NFwXZo4,1465
|
|
51
51
|
PUI/flet/textfield.py,sha256=7BPRrdf4pv8rDM5BpZzMQ9b456kZpXm81y7sVW3K4XM,1802
|
|
52
52
|
PUI/flet/window.py,sha256=NqUnGYvhk2Mpo_G2WthZOEvlU6VMx6AM-jWMKcUqGDM,650
|
|
53
|
-
PUI/textual/__init__.py,sha256=
|
|
53
|
+
PUI/textual/__init__.py,sha256=cPf0_BXd2Q-6w-0UHyxFQ6QLfTVDaoo7XmSCW_1kpyc,732
|
|
54
54
|
PUI/textual/application.py,sha256=FNpZ1j05EbE3XNxqMBDfsU_IPQ1k2Y7xw-5KLtwuFnI,2514
|
|
55
|
-
PUI/textual/base.py,sha256=
|
|
55
|
+
PUI/textual/base.py,sha256=W0tfxGlZErrsCoLb9IuFjgmNa93vZFCYNgZr1V6VEjE,4821
|
|
56
56
|
PUI/textual/button.py,sha256=VF7fmgi5mHeOzptZzy4oBfcuCeUURq5eFrLvN4Fgg30,436
|
|
57
57
|
PUI/textual/checkbox.py,sha256=pkBxZz0qXl2KUz2-Lqap-r2Y3DBI0CET3wQgEpYKb7U,518
|
|
58
|
-
PUI/textual/label.py,sha256=
|
|
59
|
-
PUI/textual/layout.py,sha256=
|
|
58
|
+
PUI/textual/label.py,sha256=3kwUerDSbyUPPEkLsjs0qDcyyhgOvUws2wtjovyf0_k,1220
|
|
59
|
+
PUI/textual/layout.py,sha256=xS3xa7UHyfKT93zW2592lV7iu6POuRJKLGyvRvtHIlQ,1302
|
|
60
60
|
PUI/textual/progressbar.py,sha256=aeLiXzLOj3VWR-KUEBmmEOxJR0LACr1_-MDMOYDHx9c,501
|
|
61
61
|
PUI/textual/radiobutton.py,sha256=zFKG2LeUnPXnxpxeW3cYqPwd91DQZWFUctundau-4b0,621
|
|
62
|
-
PUI/textual/scroll.py,sha256=
|
|
62
|
+
PUI/textual/scroll.py,sha256=u6-tFygXZR_giVsCaePahKxTb0xTbdBHCNisQA9jpWc,1974
|
|
63
63
|
PUI/textual/tab.py,sha256=wcvyH1MZZNwwout8iJDifty_lqe6YuhfRpE3F0lUTBM,2158
|
|
64
64
|
PUI/textual/text.py,sha256=BHvgK3JqBU_LrnWbaaKBFxQ_50Z9lFhcdEJoVJqbcSc,782
|
|
65
65
|
PUI/textual/textfield.py,sha256=u01i-fhtSEMi_6F_bPWgf5TvRUQvuudaxi58Yp6WTbg,1412
|
|
@@ -68,7 +68,7 @@ PUI/tkinter/__init__.py,sha256=VQjdak9UO-zI7n9Kr4q_B-kgCXgag2DVoWWP_QdH2uk,982
|
|
|
68
68
|
PUI/tkinter/application.py,sha256=NxWfU9NHJuceKMdLiGeklUKU5WjYVUomGL_hJpRtrbs,1141
|
|
69
69
|
PUI/tkinter/base.py,sha256=jSOKxd2uMOhVvDjBOloxdiHeNvKwEoWJo0fyVH49ttI,2663
|
|
70
70
|
PUI/tkinter/button.py,sha256=zRGt_jVY6q74Jer5jm4q4H-_LznrXUzfEQwiMWtQboI,467
|
|
71
|
-
PUI/tkinter/canvas.py,sha256=
|
|
71
|
+
PUI/tkinter/canvas.py,sha256=nLi46ZhgEvpZz8_aUy1DwfKct4zdABjqL-9ObS1CCMM,1654
|
|
72
72
|
PUI/tkinter/checkbox.py,sha256=TOYOCKx9ux58YdYWXLkjguFG3NsgVaYlFOIrZ9ukcwI,741
|
|
73
73
|
PUI/tkinter/label.py,sha256=o6hj-8qX0ZwDDbYaNsTz5oUIXKJFr-HctTeZW2NfhHE,555
|
|
74
74
|
PUI/tkinter/layout.py,sha256=q1NgGlPd_dn1avIzJBeO_46NyBPCQyh3VcQ56YmUUKE,3576
|
|
@@ -81,23 +81,23 @@ PUI/tkinter/textfield.py,sha256=-jab7t5-wpIejINRftXczv0685cze-H7pm3lWigOT5w,1788
|
|
|
81
81
|
PUI/tkinter/window.py,sha256=IIieSxxanhGIvPy0krQuLrStsL_jTUdx6TKbEf64nyQ,1606
|
|
82
82
|
PUI/wx/__init__.py,sha256=j8L1kzL4CK_xeF0x5_NZekGETYP_1Dhq3-BuV1LtXoY,391
|
|
83
83
|
PUI/wx/application.py,sha256=Ku_mloCyiw-KTl8a09uTIhV7uupG_7urqw8jXIwQMLc,965
|
|
84
|
-
PUI/wx/base.py,sha256=
|
|
84
|
+
PUI/wx/base.py,sha256=3NKfMbfuH9qClFBP5bVIQtJyhnGRqsNuXwY0vvlyFnU,7596
|
|
85
85
|
PUI/wx/button.py,sha256=ww3Iyn16zomP4zkQhvXTirmHBvlVMJxmiV1pfXtgrSo,447
|
|
86
|
-
PUI/wx/canvas.py,sha256=
|
|
86
|
+
PUI/wx/canvas.py,sha256=uL4z0ghM15IWNlvmDyV3lVw8Li4RNMJWXHvwd7jZSiw,8487
|
|
87
87
|
PUI/wx/checkbox.py,sha256=XgLxsi-tk2f9bnlEvhvEZV4boBGFB3u62ZE1cs8X9tU,674
|
|
88
|
-
PUI/wx/combobox.py,sha256=
|
|
88
|
+
PUI/wx/combobox.py,sha256=FoYn6AkPpxH2jHcZEp20a_peC7MbTx4MUPtbGzOskcI,2363
|
|
89
89
|
PUI/wx/dialog.py,sha256=HVLVdzRkZhRndkHTYl0RgNfzIQBdtik7DIDg93Dp9JA,2572
|
|
90
90
|
PUI/wx/divider.py,sha256=qnaUVpspAOND6YhZyQsZeos1LC02L-ljfdAtVp1vdzw,516
|
|
91
91
|
PUI/wx/label.py,sha256=qr3hGfHtjvYjeXJSB2cD5u30LYodEzix4Q0FYw8p6p0,509
|
|
92
|
-
PUI/wx/layout.py,sha256=
|
|
92
|
+
PUI/wx/layout.py,sha256=nVO31_Xu4aDcTLxlz66DJ5PK2RPHk0yq6qdzyWuGVz8,1460
|
|
93
93
|
PUI/wx/progressbar.py,sha256=gj5j6f-zG78XW1mEIRqiOEYMoYjG16jzS44Vnh4i148,472
|
|
94
94
|
PUI/wx/radiobutton.py,sha256=x7WnCGXuNPV98MqF-tRLzMOOExim22rayNL8jAYVZWk,769
|
|
95
|
-
PUI/wx/scroll.py,sha256=
|
|
95
|
+
PUI/wx/scroll.py,sha256=pvRmt04XEgObpIgwl9i52Kf1wI9ubUfZM77fPHGW9zU,1494
|
|
96
96
|
PUI/wx/text.py,sha256=YeIyDyHH0xBcD_iXbYSTtvL25YDtug1QJNVPvCSAqEk,544
|
|
97
97
|
PUI/wx/textfield.py,sha256=BmMebfqlDJqacaKdh2SON88xF73l0csC7L7hoNjz-qs,1778
|
|
98
98
|
PUI/wx/window.py,sha256=juAsn3W4SzmH8f5LDGvjwppvPD8fDObRUJ_MkQFKCIE,1847
|
|
99
|
-
qpuiq-0.
|
|
100
|
-
qpuiq-0.
|
|
101
|
-
qpuiq-0.
|
|
102
|
-
qpuiq-0.
|
|
103
|
-
qpuiq-0.
|
|
99
|
+
qpuiq-0.14.dist-info/licenses/LICENSE.txt,sha256=1Xwik2AmLNGoIYhAPzvNC28M08Q3EvkOe4TtlQuSd_E,1072
|
|
100
|
+
qpuiq-0.14.dist-info/METADATA,sha256=EkKi_IUa4vM9PyZY2A8n5vTgZLXCnDnR8QGX1cZQR1s,5994
|
|
101
|
+
qpuiq-0.14.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
|
|
102
|
+
qpuiq-0.14.dist-info/top_level.txt,sha256=zMudhifPite0CEVGYvdi-5W3P_dpum71xjU7_g-ZHS0,4
|
|
103
|
+
qpuiq-0.14.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|