batframework 1.1.0__py3-none-any.whl → 2.0.0__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.
- batFramework/__init__.py +84 -51
- batFramework/action.py +280 -252
- batFramework/actionContainer.py +105 -38
- batFramework/animatedSprite.py +81 -117
- batFramework/animation.py +91 -0
- batFramework/audioManager.py +156 -85
- batFramework/baseScene.py +249 -0
- batFramework/camera.py +245 -123
- batFramework/constants.py +57 -75
- batFramework/cutscene.py +239 -119
- batFramework/cutsceneManager.py +34 -0
- batFramework/drawable.py +107 -0
- batFramework/dynamicEntity.py +30 -23
- batFramework/easingController.py +58 -0
- batFramework/entity.py +130 -123
- batFramework/enums.py +171 -0
- batFramework/fontManager.py +65 -0
- batFramework/gui/__init__.py +28 -14
- batFramework/gui/animatedLabel.py +90 -0
- batFramework/gui/button.py +18 -84
- batFramework/gui/clickableWidget.py +244 -0
- batFramework/gui/collapseContainer.py +98 -0
- batFramework/gui/constraints/__init__.py +1 -0
- batFramework/gui/constraints/constraints.py +1066 -0
- batFramework/gui/container.py +220 -49
- batFramework/gui/debugger.py +140 -47
- batFramework/gui/draggableWidget.py +63 -0
- batFramework/gui/image.py +61 -23
- batFramework/gui/indicator.py +116 -40
- batFramework/gui/interactiveWidget.py +243 -22
- batFramework/gui/label.py +147 -110
- batFramework/gui/layout.py +442 -81
- batFramework/gui/meter.py +155 -0
- batFramework/gui/radioButton.py +43 -0
- batFramework/gui/root.py +228 -60
- batFramework/gui/scrollingContainer.py +282 -0
- batFramework/gui/selector.py +232 -0
- batFramework/gui/shape.py +286 -86
- batFramework/gui/slider.py +353 -0
- batFramework/gui/style.py +10 -0
- batFramework/gui/styleManager.py +49 -0
- batFramework/gui/syncedVar.py +43 -0
- batFramework/gui/textInput.py +331 -0
- batFramework/gui/textWidget.py +308 -0
- batFramework/gui/toggle.py +140 -62
- batFramework/gui/tooltip.py +35 -0
- batFramework/gui/widget.py +546 -307
- batFramework/manager.py +131 -50
- batFramework/particle.py +118 -0
- batFramework/propertyEaser.py +79 -0
- batFramework/renderGroup.py +34 -0
- batFramework/resourceManager.py +130 -0
- batFramework/scene.py +31 -226
- batFramework/sceneLayer.py +134 -0
- batFramework/sceneManager.py +200 -165
- batFramework/scrollingSprite.py +115 -0
- batFramework/sprite.py +46 -0
- batFramework/stateMachine.py +49 -51
- batFramework/templates/__init__.py +2 -0
- batFramework/templates/character.py +15 -0
- batFramework/templates/controller.py +158 -0
- batFramework/templates/stateMachine.py +39 -0
- batFramework/tileset.py +46 -0
- batFramework/timeManager.py +213 -0
- batFramework/transition.py +162 -157
- batFramework/triggerZone.py +22 -22
- batFramework/utils.py +306 -184
- {batframework-1.1.0.dist-info → batframework-2.0.0.dist-info}/LICENSE +1 -1
- {batframework-1.1.0.dist-info → batframework-2.0.0.dist-info}/METADATA +8 -4
- batframework-2.0.0.dist-info/RECORD +72 -0
- batFramework/cutsceneBlocks.py +0 -176
- batFramework/debugger.py +0 -48
- batFramework/easing.py +0 -71
- batFramework/gui/constraints.py +0 -204
- batFramework/gui/frame.py +0 -19
- batFramework/particles.py +0 -77
- batFramework/time.py +0 -75
- batFramework/transitionManager.py +0 -0
- batframework-1.1.0.dist-info/RECORD +0 -43
- {batframework-1.1.0.dist-info → batframework-2.0.0.dist-info}/WHEEL +0 -0
- {batframework-1.1.0.dist-info → batframework-2.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,1066 @@
|
|
1
|
+
from abc import ABC, abstractmethod
|
2
|
+
from ..widget import Widget
|
3
|
+
import batFramework as bf
|
4
|
+
import pygame
|
5
|
+
|
6
|
+
|
7
|
+
class Constraint:
|
8
|
+
def __init__(self, name:str|None=None, priority=0):
|
9
|
+
self.priority = priority
|
10
|
+
self.name = name if name is not None else self.__class__.__name__
|
11
|
+
self.old_autoresize_w = None
|
12
|
+
self.old_autoresize_h = None
|
13
|
+
self.affects_size : bool = False
|
14
|
+
self.affects_position : bool = False
|
15
|
+
|
16
|
+
|
17
|
+
def on_removal(self,child_widget: Widget)->None:
|
18
|
+
child_widget.set_autoresize_h(self.old_autoresize_h)
|
19
|
+
child_widget.set_autoresize_w(self.old_autoresize_w)
|
20
|
+
|
21
|
+
|
22
|
+
def set_priority(self, priority) -> "Constraint":
|
23
|
+
"""
|
24
|
+
Highest priority is used if 2 constraints are in conflict
|
25
|
+
Default is 0
|
26
|
+
"""
|
27
|
+
self.priority = priority
|
28
|
+
return self
|
29
|
+
|
30
|
+
def __str__(self) -> str:
|
31
|
+
return f"{self.name.upper()}"
|
32
|
+
|
33
|
+
def evaluate(self, parent_widget: Widget, child_widget: Widget) -> bool:
|
34
|
+
raise NotImplementedError("Subclasses must implement evaluate method")
|
35
|
+
|
36
|
+
def apply(self, parent_widget: Widget, child_widget: Widget = None) -> bool:
|
37
|
+
if self.old_autoresize_h is None:
|
38
|
+
self.old_autoresize_h = child_widget.autoresize_h
|
39
|
+
if self.old_autoresize_w is None:
|
40
|
+
self.old_autoresize_w = child_widget.autoresize_w
|
41
|
+
|
42
|
+
if not self.evaluate(parent_widget, child_widget):
|
43
|
+
self.apply_constraint(parent_widget, child_widget)
|
44
|
+
return False
|
45
|
+
return True
|
46
|
+
|
47
|
+
def apply_constraint(self, parent_widget: Widget, child_widget: Widget):
|
48
|
+
raise NotImplementedError("Subclasses must implement apply_constraint method")
|
49
|
+
|
50
|
+
def __eq__(self,other:"Constraint")->bool:
|
51
|
+
if not isinstance(other,self.__class__):
|
52
|
+
return False
|
53
|
+
return other.name == self.name
|
54
|
+
|
55
|
+
class MinWidth(Constraint):
|
56
|
+
def __init__(self, width: float):
|
57
|
+
super().__init__()
|
58
|
+
self.min_width = width
|
59
|
+
self.affects_size = True
|
60
|
+
|
61
|
+
|
62
|
+
def evaluate(self, parent_widget, child_widget):
|
63
|
+
return child_widget.rect.width >= self.min_width
|
64
|
+
|
65
|
+
def apply_constraint(self, parent_widget, child_widget):
|
66
|
+
child_widget.set_autoresize_w(False)
|
67
|
+
child_widget.set_size((self.min_width, None))
|
68
|
+
|
69
|
+
def __eq__(self,other:"Constraint")->bool:
|
70
|
+
if not isinstance(other,self.__class__):
|
71
|
+
return False
|
72
|
+
return (
|
73
|
+
other.name == self.name and
|
74
|
+
other.min_width == self.min_width
|
75
|
+
)
|
76
|
+
|
77
|
+
class MinHeight(Constraint):
|
78
|
+
def __init__(self, height: float):
|
79
|
+
super().__init__()
|
80
|
+
self.min_height = height
|
81
|
+
self.affects_size = True
|
82
|
+
|
83
|
+
|
84
|
+
def evaluate(self, parent_widget, child_widget):
|
85
|
+
return child_widget.rect.h >= self.min_height
|
86
|
+
|
87
|
+
|
88
|
+
def apply_constraint(self, parent_widget, child_widget):
|
89
|
+
child_widget.set_autoresize_h(False)
|
90
|
+
child_widget.set_size((None, self.min_height))
|
91
|
+
|
92
|
+
def __eq__(self,other:"Constraint")->bool:
|
93
|
+
if not isinstance(other,self.__class__):
|
94
|
+
return False
|
95
|
+
return (
|
96
|
+
other.name == self.name and
|
97
|
+
other.min_height == self.min_height
|
98
|
+
)
|
99
|
+
|
100
|
+
class MaxWidth(Constraint):
|
101
|
+
def __init__(self, width: float):
|
102
|
+
super().__init__()
|
103
|
+
self.max_width = width
|
104
|
+
self.affects_size = True
|
105
|
+
|
106
|
+
def on_removal(self, child_widget: Widget) -> None:
|
107
|
+
child_widget.set_autoresize_w(False)
|
108
|
+
|
109
|
+
def evaluate(self, parent_widget, child_widget):
|
110
|
+
res = child_widget.rect.width <= self.max_width
|
111
|
+
if not res:
|
112
|
+
child_widget.set_autoresize_w(False)
|
113
|
+
return res
|
114
|
+
|
115
|
+
def apply_constraint(self, parent_widget, child_widget):
|
116
|
+
child_widget.set_autoresize_w(True)
|
117
|
+
current_height = child_widget.rect.height
|
118
|
+
child_widget.set_size((self.max_width, current_height))
|
119
|
+
|
120
|
+
def __eq__(self, other: "Constraint") -> bool:
|
121
|
+
if not isinstance(other, self.__class__):
|
122
|
+
return False
|
123
|
+
return other.max_width == self.max_width
|
124
|
+
|
125
|
+
|
126
|
+
class MaxHeight(Constraint):
|
127
|
+
def __init__(self, height: float):
|
128
|
+
super().__init__()
|
129
|
+
self.max_height = height
|
130
|
+
self.affects_size = True
|
131
|
+
|
132
|
+
def on_removal(self, child_widget: Widget) -> None:
|
133
|
+
child_widget.set_autoresize_h(False)
|
134
|
+
|
135
|
+
def evaluate(self, parent_widget, child_widget):
|
136
|
+
res = child_widget.rect.height <= self.max_height
|
137
|
+
if not res:
|
138
|
+
child_widget.set_autoresize_h(False)
|
139
|
+
return res
|
140
|
+
|
141
|
+
def apply_constraint(self, parent_widget, child_widget):
|
142
|
+
child_widget.set_autoresize_h(True)
|
143
|
+
current_width = child_widget.rect.width
|
144
|
+
child_widget.set_size((current_width, self.max_height))
|
145
|
+
|
146
|
+
def __eq__(self, other: "Constraint") -> bool:
|
147
|
+
if not isinstance(other, self.__class__):
|
148
|
+
return False
|
149
|
+
return other.max_height == self.max_height
|
150
|
+
|
151
|
+
|
152
|
+
|
153
|
+
class CenterX(Constraint):
|
154
|
+
def __init__(self):
|
155
|
+
super().__init__()
|
156
|
+
self.affects_position = True
|
157
|
+
|
158
|
+
def evaluate(self, parent_widget, child_widget):
|
159
|
+
return (
|
160
|
+
child_widget.rect.centerx - parent_widget.get_inner_center()[0] == 0
|
161
|
+
)
|
162
|
+
|
163
|
+
def apply_constraint(self, parent_widget, child_widget):
|
164
|
+
child_widget.set_center(
|
165
|
+
parent_widget.get_inner_center()[0], child_widget.rect.centery
|
166
|
+
)
|
167
|
+
|
168
|
+
|
169
|
+
class CenterY(Constraint):
|
170
|
+
def __init__(self):
|
171
|
+
super().__init__()
|
172
|
+
self.affects_position = True
|
173
|
+
|
174
|
+
def evaluate(self, parent_widget, child_widget):
|
175
|
+
return (
|
176
|
+
child_widget.rect.centery - parent_widget.get_inner_center()[1] == 0
|
177
|
+
)
|
178
|
+
|
179
|
+
def apply_constraint(self, parent_widget, child_widget):
|
180
|
+
child_widget.set_center(
|
181
|
+
child_widget.rect.centerx, parent_widget.get_inner_center()[1]
|
182
|
+
)
|
183
|
+
|
184
|
+
|
185
|
+
class Center(Constraint):
|
186
|
+
def __init__(self):
|
187
|
+
super().__init__()
|
188
|
+
self.affects_position = True
|
189
|
+
|
190
|
+
def evaluate(self, parent_widget, child_widget):
|
191
|
+
return (
|
192
|
+
child_widget.rect.centerx - parent_widget.get_inner_center()[0] == 0
|
193
|
+
and child_widget.rect.centery - parent_widget.get_inner_center()[1] == 0
|
194
|
+
)
|
195
|
+
|
196
|
+
def apply_constraint(self, parent_widget, child_widget):
|
197
|
+
child_widget.set_center(*parent_widget.get_inner_center())
|
198
|
+
|
199
|
+
|
200
|
+
class PercentageWidth(Constraint):
|
201
|
+
def __init__(self, percentage: float):
|
202
|
+
super().__init__()
|
203
|
+
self.percentage: float = percentage
|
204
|
+
self.affects_size = True
|
205
|
+
|
206
|
+
def on_removal(self, child_widget):
|
207
|
+
child_widget.set_autoresize_w(True)
|
208
|
+
|
209
|
+
def __str__(self) -> str:
|
210
|
+
return f"{super().__str__()}.[{self.percentage*100}%]"
|
211
|
+
|
212
|
+
def evaluate(self, parent_widget, child_widget):
|
213
|
+
return child_widget.rect.width == round(
|
214
|
+
parent_widget.get_inner_width() * self.percentage
|
215
|
+
)
|
216
|
+
|
217
|
+
def apply_constraint(self, parent_widget, child_widget):
|
218
|
+
if child_widget.autoresize_w:
|
219
|
+
child_widget.set_autoresize_w(False)
|
220
|
+
child_widget.set_size(
|
221
|
+
(round(parent_widget.get_inner_width() * self.percentage), None)
|
222
|
+
)
|
223
|
+
|
224
|
+
def __eq__(self,other:"Constraint")->bool:
|
225
|
+
if not isinstance(other,self.__class__):
|
226
|
+
return False
|
227
|
+
return (
|
228
|
+
other.name == self.name and
|
229
|
+
other.percentage == self.percentage
|
230
|
+
)
|
231
|
+
|
232
|
+
|
233
|
+
class PercentageHeight(Constraint):
|
234
|
+
def __init__(self, percentage: float):
|
235
|
+
super().__init__()
|
236
|
+
self.percentage: float = percentage
|
237
|
+
self.affects_size = True
|
238
|
+
|
239
|
+
def on_removal(self, child_widget):
|
240
|
+
child_widget.set_autoresize_h(True)
|
241
|
+
|
242
|
+
|
243
|
+
def evaluate(self, parent_widget, child_widget):
|
244
|
+
return child_widget.rect.height == round(
|
245
|
+
parent_widget.get_inner_height() * self.percentage
|
246
|
+
)
|
247
|
+
|
248
|
+
def __str__(self) -> str:
|
249
|
+
return f"{super().__str__()}.[{self.percentage*100}%]"
|
250
|
+
|
251
|
+
def apply_constraint(self, parent_widget, child_widget):
|
252
|
+
if child_widget.autoresize_h:
|
253
|
+
child_widget.set_autoresize_h(False)
|
254
|
+
child_widget.set_size(
|
255
|
+
(None, round(parent_widget.get_inner_height() * self.percentage))
|
256
|
+
)
|
257
|
+
|
258
|
+
def __eq__(self,other:"Constraint")->bool:
|
259
|
+
if not isinstance(other,self.__class__):
|
260
|
+
return False
|
261
|
+
return (
|
262
|
+
other.name == self.name and
|
263
|
+
other.percentage == self.percentage
|
264
|
+
)
|
265
|
+
|
266
|
+
class FillX(PercentageWidth):
|
267
|
+
def __init__(self):
|
268
|
+
super().__init__(1)
|
269
|
+
self.name = "FillX"
|
270
|
+
|
271
|
+
def __eq__(self, other: Constraint) -> bool:
|
272
|
+
return Constraint.__eq__(self,other)
|
273
|
+
|
274
|
+
class FillY(PercentageHeight):
|
275
|
+
def __init__(self):
|
276
|
+
super().__init__(1)
|
277
|
+
self.name = "FillY"
|
278
|
+
|
279
|
+
def __eq__(self, other: Constraint) -> bool:
|
280
|
+
return Constraint.__eq__(self,other)
|
281
|
+
|
282
|
+
class Fill(Constraint):
|
283
|
+
def __init__(self):
|
284
|
+
super().__init__()
|
285
|
+
self.affects_size = True
|
286
|
+
|
287
|
+
def on_removal(self, child_widget):
|
288
|
+
child_widget.set_autoresize(True)
|
289
|
+
|
290
|
+
def __str__(self) -> str:
|
291
|
+
return f"{super().__str__()}"
|
292
|
+
|
293
|
+
def evaluate(self, parent_widget, child_widget):
|
294
|
+
return child_widget.rect.width == round(parent_widget.get_inner_width()) and \
|
295
|
+
child_widget.rect.height == round(parent_widget.get_inner_height())
|
296
|
+
|
297
|
+
def apply_constraint(self, parent_widget, child_widget):
|
298
|
+
if child_widget.autoresize_w:
|
299
|
+
child_widget.set_autoresize(False)
|
300
|
+
child_widget.set_size(parent_widget.get_inner_rect().size)
|
301
|
+
|
302
|
+
def __eq__(self,other:"Constraint")->bool:
|
303
|
+
if not isinstance(other,self.__class__):
|
304
|
+
return False
|
305
|
+
return other.name == self.name
|
306
|
+
|
307
|
+
|
308
|
+
|
309
|
+
class PercentageRectHeight(Constraint):
|
310
|
+
def __init__(self, percentage: float):
|
311
|
+
super().__init__()
|
312
|
+
self.percentage: float = percentage
|
313
|
+
self.affects_size = True
|
314
|
+
|
315
|
+
def on_removal(self, child_widget):
|
316
|
+
child_widget.set_autoresize_h(True)
|
317
|
+
|
318
|
+
def evaluate(self, parent_widget, child_widget):
|
319
|
+
return child_widget.rect.height == round(
|
320
|
+
parent_widget.rect.height * self.percentage
|
321
|
+
)
|
322
|
+
|
323
|
+
def __str__(self) -> str:
|
324
|
+
return f"{super().__str__()}.[{self.percentage*100}%]"
|
325
|
+
|
326
|
+
def apply_constraint(self, parent_widget, child_widget):
|
327
|
+
if child_widget.autoresize_h:
|
328
|
+
child_widget.set_autoresize_h(False)
|
329
|
+
child_widget.set_size(
|
330
|
+
(None, round(parent_widget.rect.height * self.percentage))
|
331
|
+
)
|
332
|
+
|
333
|
+
def __eq__(self,other:"Constraint")->bool:
|
334
|
+
if not isinstance(other,self.__class__):
|
335
|
+
return False
|
336
|
+
return (
|
337
|
+
other.name == self.name and
|
338
|
+
other.percentage == self.percentage
|
339
|
+
)
|
340
|
+
|
341
|
+
class PercentageRectWidth(Constraint):
|
342
|
+
def __init__(self, percentage: float):
|
343
|
+
super().__init__()
|
344
|
+
self.percentage: float = percentage
|
345
|
+
self.affects_size = True
|
346
|
+
|
347
|
+
def on_removal(self, child_widget: Widget) -> None:
|
348
|
+
child_widget.set_autoresize_w(True)
|
349
|
+
|
350
|
+
def evaluate(self, parent_widget, child_widget):
|
351
|
+
return child_widget.rect.width == round(
|
352
|
+
parent_widget.rect.width * self.percentage
|
353
|
+
)
|
354
|
+
|
355
|
+
def __str__(self) -> str:
|
356
|
+
return f"{super().__str__()}.[{self.percentage*100}%]"
|
357
|
+
|
358
|
+
def apply_constraint(self, parent_widget, child_widget):
|
359
|
+
if child_widget.autoresize_w:
|
360
|
+
child_widget.set_autoresize_w(False)
|
361
|
+
child_widget.set_size((round(parent_widget.rect.width * self.percentage), None))
|
362
|
+
|
363
|
+
def __eq__(self,other:"Constraint")->bool:
|
364
|
+
if not isinstance(other,self.__class__):
|
365
|
+
return False
|
366
|
+
return (
|
367
|
+
other.name == self.name and
|
368
|
+
other.percentage == self.percentage
|
369
|
+
)
|
370
|
+
|
371
|
+
class FillRectX(PercentageRectWidth):
|
372
|
+
def __init__(self):
|
373
|
+
super().__init__(1)
|
374
|
+
self.name = "fill_rect_x"
|
375
|
+
self.affects_size = True
|
376
|
+
|
377
|
+
|
378
|
+
class FillRectY(PercentageRectHeight):
|
379
|
+
def __init__(self):
|
380
|
+
super().__init__(1)
|
381
|
+
self.name = "fill_rect_y"
|
382
|
+
self.affects_size = True
|
383
|
+
|
384
|
+
|
385
|
+
class AspectRatio(Constraint):
|
386
|
+
def __init__(
|
387
|
+
self,
|
388
|
+
ratio: int | float | pygame.rect.FRectType = 1,
|
389
|
+
reference_axis: bf.axis = bf.axis.HORIZONTAL,
|
390
|
+
):
|
391
|
+
super().__init__()
|
392
|
+
self.ref_axis: bf.axis = reference_axis
|
393
|
+
self.affects_size = True
|
394
|
+
|
395
|
+
if isinstance(ratio, float | int):
|
396
|
+
self.ratio = ratio
|
397
|
+
elif isinstance(ratio, pygame.rect.FRect):
|
398
|
+
self.ratio = (
|
399
|
+
round(ratio.w / ratio.h,2)
|
400
|
+
if reference_axis == bf.axis.HORIZONTAL
|
401
|
+
else round(ratio.h / ratio.w,2)
|
402
|
+
)
|
403
|
+
else:
|
404
|
+
raise TypeError(f"Ratio must be float or FRect")
|
405
|
+
|
406
|
+
def on_removal(self, child_widget):
|
407
|
+
child_widget.set_autoresize(True)
|
408
|
+
|
409
|
+
|
410
|
+
def evaluate(self, parent_widget, child_widget):
|
411
|
+
if self.ref_axis == bf.axis.HORIZONTAL:
|
412
|
+
return self.ratio == round(child_widget.rect.h / child_widget.rect.w,2)
|
413
|
+
if self.ref_axis == bf.axis.VERTICAL:
|
414
|
+
return self.ratio == round(child_widget.rect.w / child_widget.rect.h,2)
|
415
|
+
|
416
|
+
|
417
|
+
def apply_constraint(self, parent_widget, child_widget):
|
418
|
+
|
419
|
+
if self.ref_axis == bf.axis.VERTICAL:
|
420
|
+
if child_widget.autoresize_w:
|
421
|
+
child_widget.set_autoresize_w(False)
|
422
|
+
child_widget.set_size((child_widget.rect.h * self.ratio, None))
|
423
|
+
|
424
|
+
if self.ref_axis == bf.axis.HORIZONTAL:
|
425
|
+
if child_widget.autoresize_h:
|
426
|
+
child_widget.set_autoresize_h(False)
|
427
|
+
|
428
|
+
child_widget.set_size((None, child_widget.rect.w * self.ratio))
|
429
|
+
|
430
|
+
def __str__(self) -> str:
|
431
|
+
return f"{self.name.upper()}[ratio = {self.ratio}, ref = {'Vertical' if self.ref_axis == bf.axis.VERTICAL else 'Horizontal'}]"
|
432
|
+
|
433
|
+
|
434
|
+
def __eq__(self,other:"Constraint")->bool:
|
435
|
+
if not isinstance(other,self.__class__):
|
436
|
+
return False
|
437
|
+
return (
|
438
|
+
other.name == self.name and
|
439
|
+
other.ratio == self.ratio and
|
440
|
+
other.ref_axis == self.ref_axis
|
441
|
+
)
|
442
|
+
|
443
|
+
class AnchorBottom(Constraint):
|
444
|
+
def __init__(self):
|
445
|
+
super().__init__()
|
446
|
+
self.affects_position = True
|
447
|
+
|
448
|
+
def evaluate(self, parent_widget, child_widget):
|
449
|
+
return (
|
450
|
+
child_widget.rect.bottom
|
451
|
+
== parent_widget.get_inner_bottom()
|
452
|
+
)
|
453
|
+
|
454
|
+
def apply_constraint(self, parent_widget, child_widget):
|
455
|
+
child_widget.set_position(
|
456
|
+
child_widget.rect.x, parent_widget.get_inner_bottom() - child_widget.rect.h
|
457
|
+
)
|
458
|
+
|
459
|
+
class AnchorTop(Constraint):
|
460
|
+
def __init__(self):
|
461
|
+
super().__init__()
|
462
|
+
self.affects_position = True
|
463
|
+
|
464
|
+
def evaluate(self, parent_widget, child_widget):
|
465
|
+
return (child_widget.rect.top == parent_widget.get_inner_top())
|
466
|
+
|
467
|
+
def apply_constraint(self, parent_widget, child_widget):
|
468
|
+
child_widget.set_position(child_widget.rect.x, parent_widget.get_inner_top())
|
469
|
+
|
470
|
+
|
471
|
+
class AnchorTopRight(Constraint):
|
472
|
+
def __init__(self):
|
473
|
+
super().__init__()
|
474
|
+
self.affects_position = True
|
475
|
+
|
476
|
+
def evaluate(self, parent_widget, child_widget):
|
477
|
+
return child_widget.rect.topright == parent_widget.get_inner_rect().topright
|
478
|
+
|
479
|
+
def apply_constraint(self, parent_widget, child_widget):
|
480
|
+
# print("before",child_widget.rect.topright, parent_widget.get_inner_rect().topright)
|
481
|
+
topright = parent_widget.get_inner_rect().topright
|
482
|
+
child_widget.set_position(topright[0] - child_widget.rect.w,topright[1])
|
483
|
+
# print("after",child_widget.rect.topright, parent_widget.get_inner_rect().topright)
|
484
|
+
|
485
|
+
class AnchorTopLeft(Constraint):
|
486
|
+
def __init__(self):
|
487
|
+
super().__init__()
|
488
|
+
self.affects_position = True
|
489
|
+
|
490
|
+
def evaluate(self, parent_widget, child_widget):
|
491
|
+
return child_widget.rect.topleft == parent_widget.get_inner_rect().topleft
|
492
|
+
|
493
|
+
def apply_constraint(self, parent_widget, child_widget):
|
494
|
+
child_widget.set_position(*parent_widget.get_inner_rect().topleft)
|
495
|
+
|
496
|
+
|
497
|
+
class AnchorBottomRight(Constraint):
|
498
|
+
def __init__(self):
|
499
|
+
super().__init__()
|
500
|
+
self.affects_position = True
|
501
|
+
|
502
|
+
def evaluate(self, parent_widget, child_widget):
|
503
|
+
return (
|
504
|
+
child_widget.rect.bottomright == parent_widget.get_inner_rect().bottomright
|
505
|
+
)
|
506
|
+
|
507
|
+
def apply_constraint(self, parent_widget, child_widget):
|
508
|
+
bottomright = parent_widget.get_inner_rect().bottomright
|
509
|
+
|
510
|
+
child_widget.set_position(
|
511
|
+
bottomright[0] - child_widget.rect.w,
|
512
|
+
bottomright[1] - child_widget.rect.h,
|
513
|
+
)
|
514
|
+
|
515
|
+
|
516
|
+
class AnchorRight(Constraint):
|
517
|
+
def __init__(self):
|
518
|
+
super().__init__()
|
519
|
+
self.affects_position = True
|
520
|
+
|
521
|
+
def evaluate(self, parent_widget, child_widget):
|
522
|
+
return child_widget.rect.right == parent_widget.get_inner_right()
|
523
|
+
|
524
|
+
def apply_constraint(self, parent_widget, child_widget):
|
525
|
+
child_widget.set_position(
|
526
|
+
parent_widget.get_inner_right() - child_widget.rect.w,
|
527
|
+
None,
|
528
|
+
)
|
529
|
+
|
530
|
+
|
531
|
+
class AnchorLeft(Constraint):
|
532
|
+
def __init__(self):
|
533
|
+
super().__init__()
|
534
|
+
self.affects_position = True
|
535
|
+
|
536
|
+
def evaluate(self, parent_widget, child_widget):
|
537
|
+
return child_widget.rect.left == parent_widget.get_inner_left()
|
538
|
+
|
539
|
+
def apply_constraint(self, parent_widget, child_widget):
|
540
|
+
child_widget.set_position(
|
541
|
+
parent_widget.get_inner_left(), None
|
542
|
+
)
|
543
|
+
|
544
|
+
|
545
|
+
class Margin(Constraint):
|
546
|
+
def __init__(self, margin_top: float = None, margin_right: float = None, margin_bottom: float = None, margin_left: float = None):
|
547
|
+
"""
|
548
|
+
Applies margins in the order: top, right, bottom, left.
|
549
|
+
Only non-None values are applied.
|
550
|
+
"""
|
551
|
+
super().__init__()
|
552
|
+
self.margins = (margin_top, margin_right, margin_bottom, margin_left)
|
553
|
+
self.affects_position = True
|
554
|
+
|
555
|
+
def evaluate(self, parent_widget, child_widget):
|
556
|
+
# Check each margin if set, and compare the corresponding edge
|
557
|
+
mt, mr, mb, ml = self.margins
|
558
|
+
ok = True
|
559
|
+
inner = parent_widget.get_inner_rect()
|
560
|
+
if mt is not None:
|
561
|
+
ok = ok and (child_widget.rect.top == inner.top + mt)
|
562
|
+
if mr is not None:
|
563
|
+
ok = ok and (child_widget.rect.right == inner.right - mr)
|
564
|
+
if mb is not None:
|
565
|
+
ok = ok and (child_widget.rect.bottom == inner.bottom - mb)
|
566
|
+
if ml is not None:
|
567
|
+
ok = ok and (child_widget.rect.left == inner.left + ml)
|
568
|
+
return ok
|
569
|
+
|
570
|
+
def apply_constraint(self, parent_widget, child_widget):
|
571
|
+
# Get current position
|
572
|
+
x, y = child_widget.rect.x, child_widget.rect.y
|
573
|
+
w, h = child_widget.rect.w, child_widget.rect.h
|
574
|
+
mt, mr, mb, ml = self.margins
|
575
|
+
inner = parent_widget.get_inner_rect()
|
576
|
+
# Calculate new x
|
577
|
+
if ml is not None:
|
578
|
+
x = inner.left + ml
|
579
|
+
elif mr is not None:
|
580
|
+
x = inner.right - w - mr
|
581
|
+
|
582
|
+
# Calculate new y
|
583
|
+
if mt is not None:
|
584
|
+
y = inner.top + mt
|
585
|
+
elif mb is not None:
|
586
|
+
y = inner.bottom - h - mb
|
587
|
+
|
588
|
+
child_widget.set_position(x, y)
|
589
|
+
|
590
|
+
def __eq__(self, other: "Constraint") -> bool:
|
591
|
+
if not isinstance(other, self.__class__):
|
592
|
+
return False
|
593
|
+
return other.margins == self.margins
|
594
|
+
|
595
|
+
|
596
|
+
class MarginBottom(Constraint):
|
597
|
+
def __init__(self, margin: float):
|
598
|
+
super().__init__()
|
599
|
+
self.margin = margin
|
600
|
+
self.affects_position = True
|
601
|
+
|
602
|
+
def evaluate(self, parent_widget, child_widget):
|
603
|
+
return (
|
604
|
+
child_widget.rect.bottom == parent_widget.get_inner_bottom() - self.margin
|
605
|
+
)
|
606
|
+
|
607
|
+
def apply_constraint(self, parent_widget, child_widget):
|
608
|
+
child_widget.set_position(
|
609
|
+
child_widget.rect.x,
|
610
|
+
parent_widget.get_inner_bottom() - child_widget.rect.h - self.margin,
|
611
|
+
)
|
612
|
+
|
613
|
+
def __eq__(self,other:"Constraint")->bool:
|
614
|
+
if not isinstance(other,self.__class__):
|
615
|
+
return False
|
616
|
+
return (
|
617
|
+
other.name == self.name and
|
618
|
+
other.margin == self.margin
|
619
|
+
)
|
620
|
+
|
621
|
+
class MarginTop(Constraint):
|
622
|
+
def __init__(self, margin: float):
|
623
|
+
super().__init__()
|
624
|
+
self.margin = margin
|
625
|
+
self.affects_position = True
|
626
|
+
|
627
|
+
def evaluate(self, parent_widget, child_widget):
|
628
|
+
return child_widget.rect.top == parent_widget.get_inner_top() + self.margin
|
629
|
+
|
630
|
+
def apply_constraint(self, parent_widget, child_widget):
|
631
|
+
child_widget.set_position(
|
632
|
+
child_widget.rect.x, parent_widget.get_inner_top() + self.margin
|
633
|
+
)
|
634
|
+
|
635
|
+
def __eq__(self,other:"Constraint")->bool:
|
636
|
+
if not isinstance(other,self.__class__):
|
637
|
+
return False
|
638
|
+
return (
|
639
|
+
other.name == self.name and
|
640
|
+
other.margin == self.margin
|
641
|
+
)
|
642
|
+
|
643
|
+
class MarginLeft(Constraint):
|
644
|
+
def __init__(self, margin: float):
|
645
|
+
super().__init__()
|
646
|
+
self.margin = margin
|
647
|
+
self.affects_position = True
|
648
|
+
|
649
|
+
def evaluate(self, parent_widget, child_widget):
|
650
|
+
return child_widget.rect.left == parent_widget.get_inner_left() + self.margin
|
651
|
+
|
652
|
+
def apply_constraint(self, parent_widget, child_widget):
|
653
|
+
if not self.evaluate(parent_widget, child_widget):
|
654
|
+
child_widget.set_position(
|
655
|
+
parent_widget.get_inner_left() + self.margin, child_widget.rect.y
|
656
|
+
)
|
657
|
+
|
658
|
+
def __eq__(self,other:"Constraint")->bool:
|
659
|
+
if not isinstance(other,self.__class__):
|
660
|
+
return False
|
661
|
+
return (
|
662
|
+
other.name == self.name and
|
663
|
+
other.margin == self.margin
|
664
|
+
)
|
665
|
+
|
666
|
+
class MarginRight(Constraint):
|
667
|
+
def __init__(self, margin: float):
|
668
|
+
super().__init__()
|
669
|
+
self.margin = margin
|
670
|
+
self.affects_position = True
|
671
|
+
|
672
|
+
def evaluate(self, parent_widget, child_widget):
|
673
|
+
return child_widget.rect.right == parent_widget.get_inner_right() - self.margin
|
674
|
+
|
675
|
+
def apply_constraint(self, parent_widget, child_widget):
|
676
|
+
child_widget.set_position(
|
677
|
+
parent_widget.get_inner_right() - child_widget.rect.w - self.margin,
|
678
|
+
child_widget.rect.y,
|
679
|
+
)
|
680
|
+
|
681
|
+
def __eq__(self,other:"Constraint")->bool:
|
682
|
+
if not isinstance(other,self.__class__):
|
683
|
+
return False
|
684
|
+
return (
|
685
|
+
other.name == self.name and
|
686
|
+
other.margin == self.margin
|
687
|
+
)
|
688
|
+
|
689
|
+
class RectMarginBottom(Constraint):
|
690
|
+
def __init__(self, margin: float):
|
691
|
+
super().__init__()
|
692
|
+
self.margin = margin
|
693
|
+
self.affects_position = True
|
694
|
+
|
695
|
+
def evaluate(self, parent_widget, child_widget):
|
696
|
+
return (
|
697
|
+
child_widget.rect.bottom == parent_widget.rect.bottom - self.margin
|
698
|
+
)
|
699
|
+
|
700
|
+
def apply_constraint(self, parent_widget, child_widget):
|
701
|
+
child_widget.set_position(
|
702
|
+
child_widget.rect.x,
|
703
|
+
parent_widget.rect.bottom- child_widget.rect.h - self.margin,
|
704
|
+
)
|
705
|
+
|
706
|
+
def __eq__(self,other:"Constraint")->bool:
|
707
|
+
if not isinstance(other,self.__class__):
|
708
|
+
return False
|
709
|
+
return (
|
710
|
+
other.name == self.name and
|
711
|
+
other.margin == self.margin
|
712
|
+
)
|
713
|
+
|
714
|
+
class RectMarginTop(Constraint):
|
715
|
+
def __init__(self, margin: float):
|
716
|
+
super().__init__()
|
717
|
+
self.margin = margin
|
718
|
+
self.affects_position = True
|
719
|
+
|
720
|
+
def evaluate(self, parent_widget, child_widget):
|
721
|
+
return child_widget.rect.top == parent_widget.rect.top + self.margin
|
722
|
+
|
723
|
+
def apply_constraint(self, parent_widget, child_widget):
|
724
|
+
child_widget.set_position(
|
725
|
+
child_widget.rect.x, parent_widget.rect.top + self.margin
|
726
|
+
)
|
727
|
+
|
728
|
+
def __eq__(self,other:"Constraint")->bool:
|
729
|
+
if not isinstance(other,self.__class__):
|
730
|
+
return False
|
731
|
+
return (
|
732
|
+
other.name == self.name and
|
733
|
+
other.margin == self.margin
|
734
|
+
)
|
735
|
+
|
736
|
+
class RectMarginLeft(Constraint):
|
737
|
+
def __init__(self, margin: float):
|
738
|
+
super().__init__()
|
739
|
+
self.margin = margin
|
740
|
+
self.affects_position = True
|
741
|
+
|
742
|
+
def evaluate(self, parent_widget, child_widget):
|
743
|
+
return child_widget.rect.left == parent_widget.rect.left + self.margin
|
744
|
+
|
745
|
+
def apply_constraint(self, parent_widget, child_widget):
|
746
|
+
if not self.evaluate(parent_widget, child_widget):
|
747
|
+
child_widget.set_position(
|
748
|
+
parent_widget.rect.left + self.margin, child_widget.rect.y
|
749
|
+
)
|
750
|
+
|
751
|
+
def __eq__(self,other:"Constraint")->bool:
|
752
|
+
if not isinstance(other,self.__class__):
|
753
|
+
return False
|
754
|
+
return (
|
755
|
+
other.name == self.name and
|
756
|
+
other.margin == self.margin
|
757
|
+
)
|
758
|
+
|
759
|
+
class RectMarginRight(Constraint):
|
760
|
+
def __init__(self, margin: float):
|
761
|
+
super().__init__()
|
762
|
+
self.margin = margin
|
763
|
+
self.affects_position = True
|
764
|
+
|
765
|
+
def evaluate(self, parent_widget, child_widget):
|
766
|
+
return child_widget.rect.right == parent_widget.rect.right - self.margin
|
767
|
+
|
768
|
+
def apply_constraint(self, parent_widget, child_widget):
|
769
|
+
child_widget.set_position(
|
770
|
+
parent_widget.rect.right - child_widget.rect.w - self.margin,
|
771
|
+
child_widget.rect.y,
|
772
|
+
)
|
773
|
+
|
774
|
+
def __eq__(self,other:"Constraint")->bool:
|
775
|
+
if not isinstance(other,self.__class__):
|
776
|
+
return False
|
777
|
+
return (
|
778
|
+
other.name == self.name and
|
779
|
+
other.margin == self.margin
|
780
|
+
)
|
781
|
+
|
782
|
+
class PercentageMarginBottom(Constraint):
|
783
|
+
def __init__(self, margin: float):
|
784
|
+
super().__init__()
|
785
|
+
self.margin = margin
|
786
|
+
self.affects_position = True
|
787
|
+
|
788
|
+
def evaluate(self, parent_widget, child_widget):
|
789
|
+
return abs(
|
790
|
+
child_widget.rect.bottom
|
791
|
+
- (
|
792
|
+
parent_widget.get_inner_bottom()-
|
793
|
+
parent_widget.get_inner_height() * self.margin)
|
794
|
+
) < 0.01
|
795
|
+
|
796
|
+
def apply_constraint(self, parent_widget, child_widget):
|
797
|
+
child_widget.set_position(
|
798
|
+
child_widget.rect.x,
|
799
|
+
parent_widget.get_inner_bottom()
|
800
|
+
- child_widget.rect.h
|
801
|
+
- parent_widget.get_inner_height() * self.margin,
|
802
|
+
)
|
803
|
+
|
804
|
+
def __eq__(self,other:"Constraint")->bool:
|
805
|
+
if not isinstance(other,self.__class__):
|
806
|
+
return False
|
807
|
+
return (
|
808
|
+
other.name == self.name and
|
809
|
+
other.margin == self.margin
|
810
|
+
)
|
811
|
+
|
812
|
+
class PercentageMarginTop(Constraint):
|
813
|
+
def __init__(self, margin: float):
|
814
|
+
super().__init__()
|
815
|
+
self.margin = margin
|
816
|
+
self.affects_position = True
|
817
|
+
|
818
|
+
def evaluate(self, parent_widget, child_widget):
|
819
|
+
return abs(
|
820
|
+
child_widget.rect.top
|
821
|
+
- (
|
822
|
+
parent_widget.get_inner_top()+
|
823
|
+
parent_widget.get_inner_height() * self.margin)
|
824
|
+
) < 0.01
|
825
|
+
|
826
|
+
def apply_constraint(self, parent_widget, child_widget):
|
827
|
+
child_widget.set_position(
|
828
|
+
child_widget.rect.x,
|
829
|
+
parent_widget.get_inner_top()
|
830
|
+
+ parent_widget.get_inner_height() * self.margin,
|
831
|
+
)
|
832
|
+
|
833
|
+
def __eq__(self,other:"Constraint")->bool:
|
834
|
+
if not isinstance(other,self.__class__):
|
835
|
+
return False
|
836
|
+
return (
|
837
|
+
other.name == self.name and
|
838
|
+
other.margin == self.margin
|
839
|
+
)
|
840
|
+
|
841
|
+
class PercentageMarginLeft(Constraint):
|
842
|
+
def __init__(self, margin: float):
|
843
|
+
super().__init__()
|
844
|
+
self.margin = margin
|
845
|
+
self.affects_position = True
|
846
|
+
|
847
|
+
def evaluate(self, parent_widget, child_widget):
|
848
|
+
return (
|
849
|
+
child_widget.rect.left
|
850
|
+
== parent_widget.get_inner_left()
|
851
|
+
+ parent_widget.get_inner_width() * self.margin
|
852
|
+
)
|
853
|
+
|
854
|
+
def apply_constraint(self, parent_widget, child_widget):
|
855
|
+
if not self.evaluate(parent_widget, child_widget):
|
856
|
+
child_widget.set_position(
|
857
|
+
parent_widget.get_inner_left()
|
858
|
+
+ parent_widget.get_inner_width() * self.margin,
|
859
|
+
child_widget.rect.y,
|
860
|
+
)
|
861
|
+
|
862
|
+
def __eq__(self,other:"Constraint")->bool:
|
863
|
+
if not isinstance(other,self.__class__):
|
864
|
+
return False
|
865
|
+
return (
|
866
|
+
other.name == self.name and
|
867
|
+
other.margin == self.margin
|
868
|
+
)
|
869
|
+
|
870
|
+
class PercentageMarginRight(Constraint):
|
871
|
+
def __init__(self, margin: float):
|
872
|
+
super().__init__()
|
873
|
+
self.margin = margin
|
874
|
+
self.affects_position = True
|
875
|
+
|
876
|
+
def evaluate(self, parent_widget, child_widget):
|
877
|
+
return (
|
878
|
+
child_widget.rect.right
|
879
|
+
== parent_widget.get_inner_right()
|
880
|
+
- parent_widget.get_inner_width() * self.margin
|
881
|
+
)
|
882
|
+
|
883
|
+
def apply_constraint(self, parent_widget, child_widget):
|
884
|
+
child_widget.set_position(
|
885
|
+
parent_widget.get_inner_right()
|
886
|
+
- child_widget.rect.w
|
887
|
+
- parent_widget.get_inner_width() * self.margin,
|
888
|
+
child_widget.rect.y,
|
889
|
+
)
|
890
|
+
|
891
|
+
def __eq__(self,other:"Constraint")->bool:
|
892
|
+
if not isinstance(other,self.__class__):
|
893
|
+
return False
|
894
|
+
return (
|
895
|
+
other.name == self.name and
|
896
|
+
other.margin == self.margin
|
897
|
+
)
|
898
|
+
|
899
|
+
class PercentageRectMarginBottom(Constraint):
|
900
|
+
def __init__(self, margin: float):
|
901
|
+
super().__init__()
|
902
|
+
self.margin = margin
|
903
|
+
self.affects_position = True
|
904
|
+
|
905
|
+
def evaluate(self, parent_widget, child_widget):
|
906
|
+
return (
|
907
|
+
child_widget.rect.bottom
|
908
|
+
== parent_widget.rect.top + parent_widget.rect.height * self.margin
|
909
|
+
)
|
910
|
+
|
911
|
+
def apply_constraint(self, parent_widget, child_widget):
|
912
|
+
child_widget.set_position(
|
913
|
+
child_widget.rect.x,
|
914
|
+
parent_widget.rect.bottom
|
915
|
+
- child_widget.rect.height
|
916
|
+
- parent_widget.rect.height * self.margin,
|
917
|
+
)
|
918
|
+
|
919
|
+
def __eq__(self,other:"Constraint")->bool:
|
920
|
+
if not isinstance(other,self.__class__):
|
921
|
+
return False
|
922
|
+
return (
|
923
|
+
other.name == self.name and
|
924
|
+
other.margin == self.margin
|
925
|
+
)
|
926
|
+
|
927
|
+
class PercentageRectMarginTop(Constraint):
|
928
|
+
def __init__(self, margin: float):
|
929
|
+
super().__init__()
|
930
|
+
self.margin = margin
|
931
|
+
self.affects_position = True
|
932
|
+
|
933
|
+
def evaluate(self, parent_widget, child_widget):
|
934
|
+
return (
|
935
|
+
child_widget.rect.top
|
936
|
+
== parent_widget.rect.top + parent_widget.rect.height * self.margin
|
937
|
+
)
|
938
|
+
|
939
|
+
def apply_constraint(self, parent_widget, child_widget):
|
940
|
+
child_widget.set_position(
|
941
|
+
child_widget.rect.x,
|
942
|
+
parent_widget.rect.top + parent_widget.rect.height * self.margin,
|
943
|
+
)
|
944
|
+
|
945
|
+
def __eq__(self,other:"Constraint")->bool:
|
946
|
+
if not isinstance(other,self.__class__):
|
947
|
+
return False
|
948
|
+
return (
|
949
|
+
other.name == self.name and
|
950
|
+
other.margin == self.margin
|
951
|
+
)
|
952
|
+
|
953
|
+
class PercentageRectMarginLeft(Constraint):
|
954
|
+
def __init__(self, margin: float):
|
955
|
+
super().__init__()
|
956
|
+
self.margin = margin
|
957
|
+
self.affects_position = True
|
958
|
+
|
959
|
+
def evaluate(self, parent_widget, child_widget):
|
960
|
+
return (
|
961
|
+
child_widget.rect.left
|
962
|
+
== parent_widget.rect.left + parent_widget.rect.width * self.margin
|
963
|
+
)
|
964
|
+
|
965
|
+
def apply_constraint(self, parent_widget, child_widget):
|
966
|
+
if not self.evaluate(parent_widget, child_widget):
|
967
|
+
child_widget.set_position(
|
968
|
+
parent_widget.rect.left + parent_widget.rect.width * self.margin,
|
969
|
+
child_widget.rect.y,
|
970
|
+
)
|
971
|
+
|
972
|
+
def __eq__(self,other:"Constraint")->bool:
|
973
|
+
if not isinstance(other,self.__class__):
|
974
|
+
return False
|
975
|
+
return (
|
976
|
+
other.name == self.name and
|
977
|
+
other.margin == self.margin
|
978
|
+
)
|
979
|
+
|
980
|
+
class PercentageRectMarginRight(Constraint):
|
981
|
+
def __init__(self, margin: float):
|
982
|
+
super().__init__()
|
983
|
+
self.margin = margin
|
984
|
+
self.affects_position = True
|
985
|
+
|
986
|
+
def evaluate(self, parent_widget, child_widget):
|
987
|
+
return (
|
988
|
+
child_widget.rect.right
|
989
|
+
== parent_widget.rect.right - parent_widget.rect.width * self.margin
|
990
|
+
)
|
991
|
+
|
992
|
+
def apply_constraint(self, parent_widget, child_widget):
|
993
|
+
child_widget.set_position(
|
994
|
+
parent_widget.rect.right
|
995
|
+
- child_widget.rect.width
|
996
|
+
- parent_widget.rect.width * self.margin,
|
997
|
+
child_widget.rect.y,
|
998
|
+
)
|
999
|
+
|
1000
|
+
def __eq__(self,other:"Constraint")->bool:
|
1001
|
+
if not isinstance(other,self.__class__):
|
1002
|
+
return False
|
1003
|
+
return (
|
1004
|
+
other.name == self.name and
|
1005
|
+
other.margin == self.margin
|
1006
|
+
)
|
1007
|
+
|
1008
|
+
|
1009
|
+
|
1010
|
+
|
1011
|
+
class Grow(Constraint, ABC):
|
1012
|
+
|
1013
|
+
@abstractmethod
|
1014
|
+
def evaluate(self, parent_widget, child_widget):
|
1015
|
+
pass
|
1016
|
+
|
1017
|
+
@abstractmethod
|
1018
|
+
def apply_constraint(self, parent_widget, child_widget):
|
1019
|
+
pass
|
1020
|
+
|
1021
|
+
def __eq__(self, other: "Constraint") -> bool:
|
1022
|
+
return isinstance(other, self.__class__)
|
1023
|
+
|
1024
|
+
|
1025
|
+
class GrowH(Grow):
|
1026
|
+
def __init__(self):
|
1027
|
+
super().__init__()
|
1028
|
+
self.affects_size = True
|
1029
|
+
|
1030
|
+
def evaluate(self, parent_widget, child_widget):
|
1031
|
+
siblings = [s for s in parent_widget.children if s != child_widget]
|
1032
|
+
sibling_width = sum(s.rect.w for s in siblings)
|
1033
|
+
return abs(parent_widget.get_inner_width() - (child_widget.rect.w + sibling_width)) == 0
|
1034
|
+
|
1035
|
+
def apply_constraint(self, parent_widget, child_widget):
|
1036
|
+
child_widget.set_autoresize_w(False)
|
1037
|
+
siblings = [s for s in parent_widget.children if s != child_widget]
|
1038
|
+
sibling_width = sum(s.rect.w for s in siblings)
|
1039
|
+
# print(parent_widget.get_inner_width() - sibling_width," is new size")
|
1040
|
+
if hasattr(parent_widget,"layout"):
|
1041
|
+
w = parent_widget.layout.get_free_space()[0]
|
1042
|
+
else:
|
1043
|
+
w = parent_widget.get_inner_width()
|
1044
|
+
child_widget.set_size((w - sibling_width, None))
|
1045
|
+
|
1046
|
+
|
1047
|
+
class GrowV(Grow):
|
1048
|
+
def __init__(self):
|
1049
|
+
super().__init__()
|
1050
|
+
self.affects_size = True
|
1051
|
+
|
1052
|
+
def evaluate(self, parent_widget, child_widget):
|
1053
|
+
siblings = [s for s in parent_widget.children if s != child_widget]
|
1054
|
+
sibling_height = sum(s.rect.h for s in siblings)
|
1055
|
+
return abs(parent_widget.get_inner_height() - (child_widget.rect.h + sibling_height)) == 0
|
1056
|
+
|
1057
|
+
def apply_constraint(self, parent_widget, child_widget):
|
1058
|
+
child_widget.set_autoresize_h(False)
|
1059
|
+
siblings = [s for s in parent_widget.children if s != child_widget]
|
1060
|
+
sibling_height = sum(s.rect.h for s in siblings)
|
1061
|
+
if hasattr(parent_widget,"layou"):
|
1062
|
+
h = parent_widget.layout.get_free_space()[1]
|
1063
|
+
else:
|
1064
|
+
h = parent_widget.get_inner_height()
|
1065
|
+
|
1066
|
+
child_widget.set_size((None, h- sibling_height))
|