qpuiq 0.23__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.
- PUI/PySide6/__init__.py +49 -0
- PUI/PySide6/application.py +58 -0
- PUI/PySide6/base.py +285 -0
- PUI/PySide6/button.py +21 -0
- PUI/PySide6/canvas.py +345 -0
- PUI/PySide6/checkbox.py +32 -0
- PUI/PySide6/combobox.py +85 -0
- PUI/PySide6/dialog.py +72 -0
- PUI/PySide6/divider.py +23 -0
- PUI/PySide6/image.py +48 -0
- PUI/PySide6/label.py +33 -0
- PUI/PySide6/layout.py +141 -0
- PUI/PySide6/matplotlib.py +23 -0
- PUI/PySide6/mdi.py +33 -0
- PUI/PySide6/menu.py +85 -0
- PUI/PySide6/modal.py +132 -0
- PUI/PySide6/progressbar.py +17 -0
- PUI/PySide6/radiobutton.py +29 -0
- PUI/PySide6/scroll.py +155 -0
- PUI/PySide6/splitter.py +25 -0
- PUI/PySide6/tab.py +39 -0
- PUI/PySide6/table.py +147 -0
- PUI/PySide6/text.py +35 -0
- PUI/PySide6/textfield.py +62 -0
- PUI/PySide6/toolbar.py +57 -0
- PUI/PySide6/tree.py +290 -0
- PUI/PySide6/window.py +82 -0
- PUI/__init__.py +46 -0
- PUI/common.py +26 -0
- PUI/decorator.py +20 -0
- PUI/dom.py +263 -0
- PUI/flet/__init__.py +22 -0
- PUI/flet/application.py +42 -0
- PUI/flet/base.py +37 -0
- PUI/flet/button.py +20 -0
- PUI/flet/canvas.py +86 -0
- PUI/flet/checkbox.py +23 -0
- PUI/flet/divider.py +14 -0
- PUI/flet/label.py +27 -0
- PUI/flet/layout.py +50 -0
- PUI/flet/progressbar.py +21 -0
- PUI/flet/radiobutton.py +27 -0
- PUI/flet/scroll.py +83 -0
- PUI/flet/tab.py +42 -0
- PUI/flet/text.py +55 -0
- PUI/flet/textfield.py +58 -0
- PUI/flet/window.py +25 -0
- PUI/interfaces.py +97 -0
- PUI/node.py +432 -0
- PUI/state.py +711 -0
- PUI/textual/__init__.py +35 -0
- PUI/textual/application.py +82 -0
- PUI/textual/base.py +148 -0
- PUI/textual/button.py +17 -0
- PUI/textual/checkbox.py +21 -0
- PUI/textual/label.py +36 -0
- PUI/textual/layout.py +52 -0
- PUI/textual/progressbar.py +17 -0
- PUI/textual/radiobutton.py +24 -0
- PUI/textual/scroll.py +74 -0
- PUI/textual/tab.py +75 -0
- PUI/textual/text.py +32 -0
- PUI/textual/textfield.py +55 -0
- PUI/textual/window.py +7 -0
- PUI/timeline.py +36 -0
- PUI/tkinter/__init__.py +43 -0
- PUI/tkinter/application.py +49 -0
- PUI/tkinter/base.py +68 -0
- PUI/tkinter/button.py +15 -0
- PUI/tkinter/canvas.py +52 -0
- PUI/tkinter/checkbox.py +27 -0
- PUI/tkinter/label.py +17 -0
- PUI/tkinter/layout.py +114 -0
- PUI/tkinter/progressbar.py +17 -0
- PUI/tkinter/radiobutton.py +26 -0
- PUI/tkinter/scroll.py +201 -0
- PUI/tkinter/tab.py +52 -0
- PUI/tkinter/text.py +20 -0
- PUI/tkinter/textfield.py +53 -0
- PUI/tkinter/window.py +51 -0
- PUI/utils.py +15 -0
- PUI/view.py +161 -0
- PUI/wx/__init__.py +19 -0
- PUI/wx/application.py +44 -0
- PUI/wx/base.py +246 -0
- PUI/wx/button.py +16 -0
- PUI/wx/canvas.py +255 -0
- PUI/wx/checkbox.py +25 -0
- PUI/wx/combobox.py +81 -0
- PUI/wx/dialog.py +66 -0
- PUI/wx/divider.py +19 -0
- PUI/wx/label.py +18 -0
- PUI/wx/layout.py +52 -0
- PUI/wx/progressbar.py +19 -0
- PUI/wx/radiobutton.py +27 -0
- PUI/wx/scroll.py +55 -0
- PUI/wx/text.py +23 -0
- PUI/wx/textfield.py +66 -0
- PUI/wx/window.py +64 -0
- qpuiq-0.23.dist-info/LICENSE.txt +21 -0
- qpuiq-0.23.dist-info/METADATA +234 -0
- qpuiq-0.23.dist-info/RECORD +104 -0
- qpuiq-0.23.dist-info/WHEEL +5 -0
- qpuiq-0.23.dist-info/top_level.txt +1 -0
PUI/wx/canvas.py
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
from .. import *
|
|
2
|
+
from .base import *
|
|
3
|
+
import math
|
|
4
|
+
|
|
5
|
+
class Canvas(WxBaseWidget):
|
|
6
|
+
expand_x_prio = 3
|
|
7
|
+
expand_y_prio = 3
|
|
8
|
+
|
|
9
|
+
def __init__(self, painter, *args):
|
|
10
|
+
super().__init__()
|
|
11
|
+
self.ui = None
|
|
12
|
+
self.painter = painter
|
|
13
|
+
self.args = args
|
|
14
|
+
|
|
15
|
+
def update(self, prev):
|
|
16
|
+
if prev and prev.ui:
|
|
17
|
+
self.ui = prev.ui
|
|
18
|
+
self.ui.Refresh()
|
|
19
|
+
else:
|
|
20
|
+
self.ui = wx.Panel(getWindow(self.parent))
|
|
21
|
+
self.ui.Bind(wx.EVT_PAINT, self._paint)
|
|
22
|
+
self.ui.Bind(wx.EVT_LEFT_DCLICK, self._LeftDblClick)
|
|
23
|
+
self.ui.Bind(wx.EVT_LEFT_DOWN, self._LeftDown)
|
|
24
|
+
self.ui.Bind(wx.EVT_LEFT_UP, self._LeftUp)
|
|
25
|
+
self.ui.Bind(wx.EVT_MOTION, self._Motion)
|
|
26
|
+
self.ui.Bind(wx.EVT_MOUSEWHEEL, self._MouseWheel)
|
|
27
|
+
self.ui.SetMinSize((self.layout_width, self.layout_height))
|
|
28
|
+
|
|
29
|
+
super().update(prev)
|
|
30
|
+
|
|
31
|
+
def _MouseWheel(self, event):
|
|
32
|
+
e = PUIEvent()
|
|
33
|
+
e.x, e.y = event.GetPosition()
|
|
34
|
+
if event.GetWheelAxis() == wx.MOUSE_WHEEL_VERTICAL:
|
|
35
|
+
e.h_delta = 0
|
|
36
|
+
e.v_delta = event.GetWheelRotation()
|
|
37
|
+
e.x_delta = 0
|
|
38
|
+
e.y_delta = event.GetWheelDelta()
|
|
39
|
+
else:
|
|
40
|
+
e.h_delta = event.GetWheelRotation()
|
|
41
|
+
e.v_delta = 0
|
|
42
|
+
e.x_delta = event.GetWheelDelta()
|
|
43
|
+
e.y_delta = 0
|
|
44
|
+
self.get_node()._wheel(e)
|
|
45
|
+
|
|
46
|
+
def _LeftDblClick(self, event):
|
|
47
|
+
e = PUIEvent()
|
|
48
|
+
e.x, e.y = event.GetPosition()
|
|
49
|
+
self.get_node()._dblclicked(e)
|
|
50
|
+
|
|
51
|
+
def _LeftDown(self, event):
|
|
52
|
+
e = PUIEvent()
|
|
53
|
+
e.x, e.y = event.GetPosition()
|
|
54
|
+
self.get_node()._mousedown(e)
|
|
55
|
+
|
|
56
|
+
def _LeftUp(self, event):
|
|
57
|
+
e = PUIEvent()
|
|
58
|
+
e.x, e.y = event.GetPosition()
|
|
59
|
+
self.get_node()._mouseup(e)
|
|
60
|
+
|
|
61
|
+
def _Motion(self, event):
|
|
62
|
+
e = PUIEvent()
|
|
63
|
+
e.x, e.y = event.GetPosition()
|
|
64
|
+
self.get_node()._mousemove(e)
|
|
65
|
+
|
|
66
|
+
def _paint(self, event):
|
|
67
|
+
node = self.get_node()
|
|
68
|
+
|
|
69
|
+
node.dc = wx.PaintDC(node.ui)
|
|
70
|
+
if not node.style_bgcolor is None:
|
|
71
|
+
original_brush = node.dc.GetBrush()
|
|
72
|
+
node.dc.SetBrush(wx.Brush(int_to_wx_colour(node.style_bgcolor)))
|
|
73
|
+
node.dc.DrawRectangle(self.ui.GetClientRect())
|
|
74
|
+
node.dc.SetBrush(original_brush)
|
|
75
|
+
|
|
76
|
+
node.painter(node, *node.args)
|
|
77
|
+
node.dc = None
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def drawText(self, x, y, text, w=None, h=None, size=12, color=None, rotate=0, anchor=Anchor.LEFT_TOP):
|
|
81
|
+
original_pen = self.dc.GetPen()
|
|
82
|
+
original_brush = self.dc.GetBrush()
|
|
83
|
+
|
|
84
|
+
lines = text.split("\n")
|
|
85
|
+
extents = [self.dc.GetTextExtent(l) for l in lines]
|
|
86
|
+
width = max([e[0] for e in extents])
|
|
87
|
+
height = sum([e[1] for e in extents])
|
|
88
|
+
|
|
89
|
+
dx = 0
|
|
90
|
+
dy = 0
|
|
91
|
+
if anchor.value[0]=="center":
|
|
92
|
+
dx = width/2
|
|
93
|
+
elif anchor.value[0]=="right":
|
|
94
|
+
dx = width
|
|
95
|
+
|
|
96
|
+
if anchor.value[1]=="center":
|
|
97
|
+
dy = height/2
|
|
98
|
+
elif anchor.value[1]=="bottom":
|
|
99
|
+
dy = height
|
|
100
|
+
|
|
101
|
+
gc = wx.GraphicsContext.Create(self.dc)
|
|
102
|
+
|
|
103
|
+
gc.PushState()
|
|
104
|
+
|
|
105
|
+
gc.Translate(x+dx, y+dy)
|
|
106
|
+
gc.Rotate(math.radians(rotate))
|
|
107
|
+
gc.Translate(-dx, -dy)
|
|
108
|
+
|
|
109
|
+
if color is None:
|
|
110
|
+
color = self.ui.GetForegroundColour()
|
|
111
|
+
else:
|
|
112
|
+
color = int_to_wx_colour(color)
|
|
113
|
+
|
|
114
|
+
gc.SetFont(wx.Font(size, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL), color)
|
|
115
|
+
y_off = 0
|
|
116
|
+
for i,line in enumerate(lines):
|
|
117
|
+
gc.PushState()
|
|
118
|
+
gc.DrawText(line, 0, y_off)
|
|
119
|
+
gc.PopState()
|
|
120
|
+
y_off += extents[i][1]
|
|
121
|
+
|
|
122
|
+
gc.PopState()
|
|
123
|
+
|
|
124
|
+
self.dc.SetPen(original_pen)
|
|
125
|
+
self.dc.SetBrush(original_brush)
|
|
126
|
+
|
|
127
|
+
def drawLine(self, x1, y1, x2, y2, color=0, width=1):
|
|
128
|
+
original_pen = self.dc.GetPen()
|
|
129
|
+
original_brush = self.dc.GetBrush()
|
|
130
|
+
|
|
131
|
+
self.dc.SetPen(wx.Pen(int_to_wx_colour(color), width))
|
|
132
|
+
self.dc.DrawLine(int(x1), int(y1), int(x2), int(y2))
|
|
133
|
+
self.dc.SetPen(original_pen)
|
|
134
|
+
self.dc.SetBrush(original_brush)
|
|
135
|
+
|
|
136
|
+
def drawPolyline(self, coords, color=0, width=1):
|
|
137
|
+
original_pen = self.dc.GetPen()
|
|
138
|
+
original_brush = self.dc.GetBrush()
|
|
139
|
+
|
|
140
|
+
if color is not None:
|
|
141
|
+
self.dc.SetPen(wx.Pen(int_to_wx_colour(color), width))
|
|
142
|
+
|
|
143
|
+
coords = [(int(c[0]), int(c[1])) for c in coords]
|
|
144
|
+
self.dc.DrawLines(coords)
|
|
145
|
+
|
|
146
|
+
self.dc.SetPen(original_pen)
|
|
147
|
+
self.dc.SetBrush(original_brush)
|
|
148
|
+
|
|
149
|
+
def drawPolygon(self, coords, fill=None, stroke=None, width=1):
|
|
150
|
+
original_pen = self.dc.GetPen()
|
|
151
|
+
original_brush = self.dc.GetBrush()
|
|
152
|
+
|
|
153
|
+
if fill is None:
|
|
154
|
+
self.dc.SetBrush(wx.TRANSPARENT_BRUSH)
|
|
155
|
+
else:
|
|
156
|
+
self.dc.SetBrush(wx.Brush(int_to_wx_colour(fill)))
|
|
157
|
+
if stroke is None:
|
|
158
|
+
self.dc.SetPen(wx.NullPen)
|
|
159
|
+
else:
|
|
160
|
+
self.dc.SetPen(wx.Pen(int_to_wx_colour(stroke), width))
|
|
161
|
+
|
|
162
|
+
coords = [(int(c[0]), int(c[1])) for c in coords]
|
|
163
|
+
self.dc.DrawPolygon(coords)
|
|
164
|
+
self.dc.SetPen(original_pen)
|
|
165
|
+
self.dc.SetBrush(original_brush)
|
|
166
|
+
|
|
167
|
+
def drawRect(self, x1, y1, x2, y2, fill=None, stroke=None, width=1):
|
|
168
|
+
original_pen = self.dc.GetPen()
|
|
169
|
+
original_brush = self.dc.GetBrush()
|
|
170
|
+
|
|
171
|
+
if fill is None:
|
|
172
|
+
self.dc.SetBrush(wx.TRANSPARENT_BRUSH)
|
|
173
|
+
else:
|
|
174
|
+
self.dc.SetBrush(wx.Brush(int_to_wx_colour(fill)))
|
|
175
|
+
if stroke is None:
|
|
176
|
+
self.dc.SetPen(wx.NullPen)
|
|
177
|
+
else:
|
|
178
|
+
self.dc.SetPen(wx.Pen(int_to_wx_colour(stroke), width))
|
|
179
|
+
|
|
180
|
+
x = min(x1, x1)
|
|
181
|
+
y = min(y1, y2)
|
|
182
|
+
w = abs(x2 - x1)
|
|
183
|
+
h = abs(y2 - y1)
|
|
184
|
+
|
|
185
|
+
self.dc.DrawRectangle(int(x), int(y), int(w), int(h))
|
|
186
|
+
self.dc.SetPen(original_pen)
|
|
187
|
+
self.dc.SetBrush(original_brush)
|
|
188
|
+
|
|
189
|
+
def drawEllipse(self, x, y, rx, ry, fill=None, stroke=None, width=1):
|
|
190
|
+
original_pen = self.dc.GetPen()
|
|
191
|
+
original_brush = self.dc.GetBrush()
|
|
192
|
+
|
|
193
|
+
if fill is None:
|
|
194
|
+
self.dc.SetBrush(wx.TRANSPARENT_BRUSH)
|
|
195
|
+
else:
|
|
196
|
+
self.dc.SetBrush(wx.Brush(int_to_wx_colour(fill)))
|
|
197
|
+
if stroke is None:
|
|
198
|
+
self.dc.SetPen(wx.NullPen)
|
|
199
|
+
else:
|
|
200
|
+
self.dc.SetPen(wx.Pen(int_to_wx_colour(stroke), width))
|
|
201
|
+
|
|
202
|
+
self.dc.DrawEllipse(int(x-rx), int(y-ry), int(rx*2), int(ry*2))
|
|
203
|
+
self.dc.SetPen(original_pen)
|
|
204
|
+
self.dc.SetBrush(original_brush)
|
|
205
|
+
|
|
206
|
+
def drawShapely(self, shape, fill=None, stroke=None, width=1):
|
|
207
|
+
original_pen = self.dc.GetPen()
|
|
208
|
+
original_brush = self.dc.GetBrush()
|
|
209
|
+
|
|
210
|
+
if fill is None:
|
|
211
|
+
self.dc.SetBrush(wx.TRANSPARENT_BRUSH)
|
|
212
|
+
else:
|
|
213
|
+
self.dc.SetBrush(wx.Brush(int_to_wx_colour(fill)))
|
|
214
|
+
if stroke is None:
|
|
215
|
+
self.dc.SetPen(wx.NullPen)
|
|
216
|
+
else:
|
|
217
|
+
self.dc.SetPen(wx.Pen(int_to_wx_colour(stroke), width))
|
|
218
|
+
|
|
219
|
+
self._drawShapely(shape, fill, stroke, width)
|
|
220
|
+
|
|
221
|
+
def _drawShapely(self, shape, fill=None, stroke=None, width=1):
|
|
222
|
+
if hasattr(shape, "geoms"):
|
|
223
|
+
for g in shape.geoms:
|
|
224
|
+
self.drawShapely(g, fill, stroke, width)
|
|
225
|
+
elif hasattr(shape, "exterior"): # polygon
|
|
226
|
+
gc = wx.GraphicsContext.Create(self.dc)
|
|
227
|
+
if gc:
|
|
228
|
+
path = gc.CreatePath()
|
|
229
|
+
|
|
230
|
+
exterior = shape.exterior.coords
|
|
231
|
+
path.MoveToPoint(* exterior[0])
|
|
232
|
+
for point in exterior[1:]:
|
|
233
|
+
path.AddLineToPoint(*point)
|
|
234
|
+
path.CloseSubpath()
|
|
235
|
+
|
|
236
|
+
for hole in shape.interiors:
|
|
237
|
+
hole = hole.coords
|
|
238
|
+
path.MoveToPoint(*hole[0])
|
|
239
|
+
# Draw holes in reverse order
|
|
240
|
+
for point in hole[1:]:
|
|
241
|
+
path.AddLineToPoint(*point)
|
|
242
|
+
path.CloseSubpath()
|
|
243
|
+
|
|
244
|
+
if fill is not None:
|
|
245
|
+
gc.SetBrush(wx.Brush(int_to_wx_colour(fill)))
|
|
246
|
+
if stroke is not None:
|
|
247
|
+
gc.SetPen(wx.Pen(int_to_wx_colour(stroke), width))
|
|
248
|
+
|
|
249
|
+
gc.DrawPath(path)
|
|
250
|
+
elif hasattr(shape, "x") and hasattr(shape, "y"): # point
|
|
251
|
+
self.drawEllipse(shape.x, shape.y, width/2, width/2, fill=stroke)
|
|
252
|
+
elif hasattr(shape, "coords"): # linestring, linearring
|
|
253
|
+
self.drawPolyline(shape.coords, color=stroke, width=width)
|
|
254
|
+
else:
|
|
255
|
+
raise RuntimeError(f"Not implemented: drawShapely({type(shape).__name__}) {dir(shape)}")
|
PUI/wx/checkbox.py
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from .. import *
|
|
2
|
+
from .base import *
|
|
3
|
+
|
|
4
|
+
class Checkbox(WxBaseWidget):
|
|
5
|
+
def __init__(self, text, model):
|
|
6
|
+
super().__init__()
|
|
7
|
+
self.text = text
|
|
8
|
+
self.model = model
|
|
9
|
+
|
|
10
|
+
def update(self, prev):
|
|
11
|
+
if prev and prev.ui:
|
|
12
|
+
self.ui = prev.ui
|
|
13
|
+
self.ui.SetLabel(self.text)
|
|
14
|
+
else:
|
|
15
|
+
self.ui = wx.CheckBox(getWindow(self.parent), label=self.text)
|
|
16
|
+
self.ui.Bind(wx.EVT_CHECKBOX, self._checked)
|
|
17
|
+
|
|
18
|
+
self.ui.SetValue(self.model.value)
|
|
19
|
+
|
|
20
|
+
super().update(prev)
|
|
21
|
+
|
|
22
|
+
def _checked(self, *args, **kwargs):
|
|
23
|
+
node = self.get_node()
|
|
24
|
+
node.model.value = node.ui.GetValue()
|
|
25
|
+
node._clicked()
|
PUI/wx/combobox.py
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
from .. import *
|
|
2
|
+
from .base import *
|
|
3
|
+
|
|
4
|
+
class ComboBox(WxBaseWidget):
|
|
5
|
+
pui_terminal = False
|
|
6
|
+
def __init__(self, editable=False, index_model=None, text_model=None):
|
|
7
|
+
super().__init__()
|
|
8
|
+
self.editable = editable
|
|
9
|
+
self.index_model = index_model
|
|
10
|
+
self.text_model = text_model
|
|
11
|
+
|
|
12
|
+
def update(self, prev):
|
|
13
|
+
if prev and prev.ui:
|
|
14
|
+
self.curr_index = prev.curr_index
|
|
15
|
+
self.curr_text = prev.curr_text
|
|
16
|
+
self.ui = prev.ui
|
|
17
|
+
else:
|
|
18
|
+
self.curr_index = Prop()
|
|
19
|
+
self.curr_text = Prop()
|
|
20
|
+
self.ui = wx.ComboBox(getWindow(self.parent), choices=[], style=0 if self.editable else wx.CB_READONLY)
|
|
21
|
+
self.ui.Bind(wx.EVT_COMBOBOX, self._combobox)
|
|
22
|
+
self.ui.Bind(wx.EVT_TEXT, self._text)
|
|
23
|
+
|
|
24
|
+
super().update(prev)
|
|
25
|
+
|
|
26
|
+
def postSync(self):
|
|
27
|
+
index = -1
|
|
28
|
+
text = ""
|
|
29
|
+
|
|
30
|
+
if self.index_model:
|
|
31
|
+
index = self.index_model.value
|
|
32
|
+
text = self.children[index].text
|
|
33
|
+
elif self.text_model:
|
|
34
|
+
text = str(self.text_model.value)
|
|
35
|
+
try:
|
|
36
|
+
index = [c.value for c in self.children].index(text)
|
|
37
|
+
except:
|
|
38
|
+
index = -1
|
|
39
|
+
|
|
40
|
+
if self.curr_index.set(index):
|
|
41
|
+
self.ui.SetSelection(index)
|
|
42
|
+
|
|
43
|
+
if self.curr_text.set(text):
|
|
44
|
+
self.ui.SetValue(text)
|
|
45
|
+
|
|
46
|
+
def _combobox(self, *args, **kwargs):
|
|
47
|
+
node = self.get_node()
|
|
48
|
+
idx = self.ui.GetSelection()
|
|
49
|
+
if node.index_model:
|
|
50
|
+
node.index_model.value = idx
|
|
51
|
+
if node.text_model:
|
|
52
|
+
node.text_model.value = self.children[idx].value
|
|
53
|
+
e = PUIEvent()
|
|
54
|
+
e.value = idx
|
|
55
|
+
node._change(e)
|
|
56
|
+
|
|
57
|
+
def _text(self, *args, **kwargs):
|
|
58
|
+
if not self.editable:
|
|
59
|
+
return
|
|
60
|
+
node = self.get_node()
|
|
61
|
+
text = self.ui.GetValue()
|
|
62
|
+
if node.text_model:
|
|
63
|
+
node.text_model.value = text
|
|
64
|
+
e = PUIEvent()
|
|
65
|
+
e.value = text
|
|
66
|
+
node._change(e)
|
|
67
|
+
|
|
68
|
+
def addChild(self, idx, child):
|
|
69
|
+
self.ui.Insert(child.text, idx)
|
|
70
|
+
|
|
71
|
+
def removeChild(self, idx, child):
|
|
72
|
+
self.ui.Delete(idx)
|
|
73
|
+
|
|
74
|
+
class ComboBoxItem(PUINode):
|
|
75
|
+
def __init__(self, text, value=None):
|
|
76
|
+
super().__init__()
|
|
77
|
+
self.id(text)
|
|
78
|
+
self.text = text
|
|
79
|
+
if value is None:
|
|
80
|
+
value = text
|
|
81
|
+
self.value = value
|
PUI/wx/dialog.py
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from .base import wx
|
|
2
|
+
|
|
3
|
+
def OpenDirectory(title="Open Directory", directory=""):
|
|
4
|
+
with wx.DirDialog(None, title, directory, wx.DD_DEFAULT_STYLE | wx.DD_DIR_MUST_EXIST) as dir_dialog:
|
|
5
|
+
if dir_dialog.ShowModal() == wx.ID_CANCEL:
|
|
6
|
+
return None
|
|
7
|
+
return dir_dialog.GetPath()
|
|
8
|
+
|
|
9
|
+
def OpenFile(title="Open File", directory="", types=None):
|
|
10
|
+
if types:
|
|
11
|
+
types = types.replace(";;", "|")
|
|
12
|
+
if types is None:
|
|
13
|
+
types = wx.FileSelectorDefaultWildcardStr
|
|
14
|
+
with wx.FileDialog(None, title, directory, wildcard=types,
|
|
15
|
+
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as file_dialog:
|
|
16
|
+
if file_dialog.ShowModal() == wx.ID_CANCEL:
|
|
17
|
+
return None
|
|
18
|
+
return file_dialog.GetPath()
|
|
19
|
+
|
|
20
|
+
def OpenFiles(title="Open Files", directory="", types=None):
|
|
21
|
+
if types:
|
|
22
|
+
types = types.replace(";;", "|")
|
|
23
|
+
if types is None:
|
|
24
|
+
types = wx.FileSelectorDefaultWildcardStr
|
|
25
|
+
with wx.FileDialog(None, title, directory, wildcard=types,
|
|
26
|
+
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE) as file_dialog:
|
|
27
|
+
if file_dialog.ShowModal() == wx.ID_CANCEL:
|
|
28
|
+
return None
|
|
29
|
+
return file_dialog.GetPaths()
|
|
30
|
+
|
|
31
|
+
def SaveFile(default, title="Save File", directory="", types=None):
|
|
32
|
+
if types:
|
|
33
|
+
types = types.replace(";;", "|")
|
|
34
|
+
if types is None:
|
|
35
|
+
types = wx.FileSelectorDefaultWildcardStr
|
|
36
|
+
if not directory and isinstance(default, str):
|
|
37
|
+
directory = default
|
|
38
|
+
with wx.FileDialog(None, title, directory, wildcard=types,
|
|
39
|
+
style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) as file_dialog:
|
|
40
|
+
if file_dialog.ShowModal() == wx.ID_CANCEL:
|
|
41
|
+
return None
|
|
42
|
+
return file_dialog.GetPath()
|
|
43
|
+
|
|
44
|
+
def Information(message="Information", title="Information Dialog"):
|
|
45
|
+
wx.MessageBox(message, title, wx.OK | wx.ICON_INFORMATION)
|
|
46
|
+
|
|
47
|
+
def Warning(message="Warning", title="Warning Dialog"):
|
|
48
|
+
wx.MessageBox(message, title, wx.OK | wx.ICON_WARNING)
|
|
49
|
+
|
|
50
|
+
def Critical(message="Critical", title="Critical Dialog"):
|
|
51
|
+
wx.MessageBox(message, title, wx.OK | wx.ICON_ERROR)
|
|
52
|
+
|
|
53
|
+
def Confirm(message="Confirm", title="Confirm Dialog"):
|
|
54
|
+
dlg = wx.MessageDialog(None, message, title, wx.YES_NO | wx.ICON_QUESTION)
|
|
55
|
+
result = dlg.ShowModal()
|
|
56
|
+
dlg.Destroy()
|
|
57
|
+
return result == wx.ID_YES
|
|
58
|
+
|
|
59
|
+
def Prompt(prompt="Input", title="Input Dialog", default=""):
|
|
60
|
+
dlg = wx.TextEntryDialog(None, prompt, title, default)
|
|
61
|
+
if dlg.ShowModal() == wx.ID_OK:
|
|
62
|
+
result = dlg.GetValue()
|
|
63
|
+
else:
|
|
64
|
+
result = None
|
|
65
|
+
dlg.Destroy()
|
|
66
|
+
return result
|
PUI/wx/divider.py
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from .. import *
|
|
2
|
+
from .base import *
|
|
3
|
+
from .layout import *
|
|
4
|
+
|
|
5
|
+
class Divider(WxBaseWidget):
|
|
6
|
+
def __init__(self):
|
|
7
|
+
super().__init__()
|
|
8
|
+
|
|
9
|
+
def update(self, prev):
|
|
10
|
+
if prev and prev.ui:
|
|
11
|
+
self.ui = prev.ui
|
|
12
|
+
else:
|
|
13
|
+
if isinstance(self.non_virtual_parent, VBox):
|
|
14
|
+
style = wx.LI_HORIZONTAL
|
|
15
|
+
else:
|
|
16
|
+
style = wx.LI_VERTICAL
|
|
17
|
+
self.ui = wx.StaticLine(getWindow(self.parent), style=style, size=(15, 15))
|
|
18
|
+
|
|
19
|
+
super().update(prev)
|
PUI/wx/label.py
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from .. import *
|
|
2
|
+
from .base import *
|
|
3
|
+
|
|
4
|
+
class Label(WxBaseWidget):
|
|
5
|
+
def __init__(self, text, selectable=False):
|
|
6
|
+
super().__init__()
|
|
7
|
+
self.text = text
|
|
8
|
+
self.selectable = selectable
|
|
9
|
+
|
|
10
|
+
def update(self, prev):
|
|
11
|
+
if prev and prev.ui:
|
|
12
|
+
self.ui = prev.ui
|
|
13
|
+
self.ui.SetLabel(self.text)
|
|
14
|
+
else:
|
|
15
|
+
self.ui = wx.StaticText(getWindow(self.parent), label=self.text)
|
|
16
|
+
self.ui.Bind(wx.EVT_LEFT_DOWN, self._clicked)
|
|
17
|
+
|
|
18
|
+
super().update(prev)
|
PUI/wx/layout.py
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from .. import *
|
|
2
|
+
from .base import *
|
|
3
|
+
|
|
4
|
+
class HBox(WxBaseLayout):
|
|
5
|
+
container_x = True
|
|
6
|
+
expand_x_prio = 2
|
|
7
|
+
expand_y_prio = 1
|
|
8
|
+
|
|
9
|
+
def update(self, prev):
|
|
10
|
+
if prev and prev.ui:
|
|
11
|
+
self.ui = prev.ui
|
|
12
|
+
else:
|
|
13
|
+
self.ui = wx.BoxSizer(wx.HORIZONTAL)
|
|
14
|
+
super().update(prev)
|
|
15
|
+
|
|
16
|
+
class VBox(WxBaseLayout):
|
|
17
|
+
container_y = True
|
|
18
|
+
expand_x_prio = 1
|
|
19
|
+
expand_y_prio = 2
|
|
20
|
+
|
|
21
|
+
def update(self, prev):
|
|
22
|
+
if prev and prev.ui:
|
|
23
|
+
self.ui = prev.ui
|
|
24
|
+
else:
|
|
25
|
+
self.ui = wx.BoxSizer(wx.VERTICAL)
|
|
26
|
+
super().update(prev)
|
|
27
|
+
|
|
28
|
+
class Spacer(WXBase):
|
|
29
|
+
pui_terminal = True
|
|
30
|
+
def __init__(self):
|
|
31
|
+
super().__init__()
|
|
32
|
+
self.layout_weight = 1
|
|
33
|
+
|
|
34
|
+
class Grid(WxBaseLayout):
|
|
35
|
+
pui_grid_layout = True
|
|
36
|
+
def update(self, prev):
|
|
37
|
+
if prev and prev.ui:
|
|
38
|
+
self.ui = prev.ui
|
|
39
|
+
else:
|
|
40
|
+
self.ui = wx.GridBagSizer()
|
|
41
|
+
super().update(prev)
|
|
42
|
+
|
|
43
|
+
def addChild(self, idx, child):
|
|
44
|
+
if isinstance(child, WxBaseLayout) or isinstance(child, WxBaseWidget):
|
|
45
|
+
p = 0
|
|
46
|
+
if child.layout_padding:
|
|
47
|
+
p = max(child.layout_padding)
|
|
48
|
+
self.ui.Add(child.outer, pos=(child.grid_row, child.grid_column), span=(child.grid_rowspan or 1, child.grid_columnspan or 1), flag=wx.ALL|wx.EXPAND, border=p)
|
|
49
|
+
|
|
50
|
+
def removeChild(self, idx, child):
|
|
51
|
+
if isinstance(child, WxBaseLayout) or isinstance(child, WxBaseWidget):
|
|
52
|
+
pass
|
PUI/wx/progressbar.py
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from .. import *
|
|
2
|
+
from .base import *
|
|
3
|
+
|
|
4
|
+
class ProgressBar(WxBaseWidget):
|
|
5
|
+
expand_x_prio = 1
|
|
6
|
+
|
|
7
|
+
def __init__(self, progress, maximum=1):
|
|
8
|
+
super().__init__()
|
|
9
|
+
self.progress = progress
|
|
10
|
+
self.maximum = maximum
|
|
11
|
+
|
|
12
|
+
def update(self, prev):
|
|
13
|
+
if prev and prev.ui:
|
|
14
|
+
self.ui = prev.ui
|
|
15
|
+
else:
|
|
16
|
+
self.ui = wx.Gauge(getWindow(self.parent))
|
|
17
|
+
self.ui.SetRange(self.maximum)
|
|
18
|
+
self.ui.SetValue(self.progress)
|
|
19
|
+
super().update(prev)
|
PUI/wx/radiobutton.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from .. import *
|
|
2
|
+
from .base import *
|
|
3
|
+
|
|
4
|
+
class RadioButton(WxBaseWidget):
|
|
5
|
+
def __init__(self, text, value, model):
|
|
6
|
+
super().__init__()
|
|
7
|
+
self.var = None
|
|
8
|
+
self.text = text
|
|
9
|
+
self.value = value
|
|
10
|
+
self.model = model
|
|
11
|
+
|
|
12
|
+
def update(self, prev):
|
|
13
|
+
if prev and prev.ui:
|
|
14
|
+
self.ui = prev.ui
|
|
15
|
+
self.ui.SetLabel(self.text)
|
|
16
|
+
else:
|
|
17
|
+
self.ui = wx.RadioButton(getWindow(self.parent), label=self.text, style=wx.RB_SINGLE)
|
|
18
|
+
self.ui.Bind(wx.EVT_RADIOBUTTON, self._selected)
|
|
19
|
+
|
|
20
|
+
self.ui.SetValue(self.model.value == self.value)
|
|
21
|
+
|
|
22
|
+
super().update(prev)
|
|
23
|
+
|
|
24
|
+
def _selected(self, *args, **kwargs):
|
|
25
|
+
node = self.get_node()
|
|
26
|
+
node.model.value = node.value
|
|
27
|
+
node._clicked()
|
PUI/wx/scroll.py
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from .. import *
|
|
2
|
+
from .base import *
|
|
3
|
+
import wx.lib.scrolledpanel as scrolled
|
|
4
|
+
|
|
5
|
+
class Scroll(WxBaseWidget):
|
|
6
|
+
pui_terminal = False
|
|
7
|
+
scroll = True
|
|
8
|
+
|
|
9
|
+
END = -0.0
|
|
10
|
+
|
|
11
|
+
def __init__(self, vertical=None, horizontal=False):
|
|
12
|
+
self.vertical = vertical
|
|
13
|
+
self.horizontal = horizontal
|
|
14
|
+
super().__init__()
|
|
15
|
+
|
|
16
|
+
def update(self, prev):
|
|
17
|
+
if prev and prev.ui:
|
|
18
|
+
self.ui = prev.ui
|
|
19
|
+
else:
|
|
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
|
+
|
|
34
|
+
super().update(prev)
|
|
35
|
+
|
|
36
|
+
def addChild(self, idx, child):
|
|
37
|
+
if isinstance(child, WxBaseLayout):
|
|
38
|
+
self.ui.SetSizer(child.outer)
|
|
39
|
+
elif isinstance(child, WxBaseWidget):
|
|
40
|
+
pass
|
|
41
|
+
|
|
42
|
+
def removeChild(self, idx, child):
|
|
43
|
+
if isinstance(child, WxBaseLayout):
|
|
44
|
+
pass
|
|
45
|
+
elif isinstance(child, WxBaseWidget):
|
|
46
|
+
pass
|
|
47
|
+
|
|
48
|
+
def scrollX(self, pos=0):
|
|
49
|
+
return self
|
|
50
|
+
|
|
51
|
+
def scrollY(self, pos=0):
|
|
52
|
+
return self
|
|
53
|
+
|
|
54
|
+
def postSync(self):
|
|
55
|
+
self.ui.SetupScrolling(scroll_x=self.horizontal or self.horizontal is None, scroll_y=self.vertical or self.vertical is None, scrollToTop=False)
|
PUI/wx/text.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from .. import *
|
|
2
|
+
from .base import *
|
|
3
|
+
|
|
4
|
+
class Text(WxBaseWidget):
|
|
5
|
+
def __init__(self, text, selectable=False):
|
|
6
|
+
super().__init__()
|
|
7
|
+
self.text = text
|
|
8
|
+
self.selectable = selectable
|
|
9
|
+
|
|
10
|
+
def update(self, prev):
|
|
11
|
+
if prev and prev.ui:
|
|
12
|
+
self.ui = prev.ui
|
|
13
|
+
self.ui.SetLabel(self.text)
|
|
14
|
+
else:
|
|
15
|
+
self.ui = wx.StaticText(getWindow(self.parent), label=self.text)
|
|
16
|
+
|
|
17
|
+
super().update(prev)
|
|
18
|
+
|
|
19
|
+
class Html(Text):
|
|
20
|
+
pui_supported = False
|
|
21
|
+
|
|
22
|
+
class MarkDown(Text):
|
|
23
|
+
pui_supported = False
|