batframework 1.0.8a1__py3-none-any.whl → 1.0.8a2__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 +50 -53
- batFramework/action.py +105 -116
- batFramework/actionContainer.py +11 -53
- batFramework/animatedSprite.py +65 -115
- batFramework/audioManager.py +26 -70
- batFramework/camera.py +68 -253
- batFramework/constants.py +54 -16
- batFramework/cutscene.py +25 -34
- batFramework/cutsceneBlocks.py +42 -37
- batFramework/debugger.py +48 -0
- batFramework/dynamicEntity.py +7 -9
- batFramework/easing.py +71 -0
- batFramework/entity.py +98 -42
- batFramework/gui/__init__.py +2 -8
- batFramework/gui/button.py +79 -7
- batFramework/gui/constraints.py +204 -0
- batFramework/gui/container.py +31 -155
- batFramework/gui/debugger.py +43 -124
- batFramework/gui/frame.py +19 -0
- batFramework/gui/image.py +17 -41
- batFramework/gui/indicator.py +21 -41
- batFramework/gui/interactiveWidget.py +13 -116
- batFramework/gui/label.py +73 -278
- batFramework/gui/layout.py +61 -148
- batFramework/gui/root.py +37 -102
- batFramework/gui/shape.py +57 -258
- batFramework/gui/toggle.py +46 -97
- batFramework/gui/widget.py +254 -268
- batFramework/manager.py +19 -40
- batFramework/particles.py +77 -0
- batFramework/scene.py +107 -214
- batFramework/sceneManager.py +107 -150
- batFramework/stateMachine.py +0 -1
- batFramework/time.py +57 -117
- batFramework/transition.py +126 -184
- batFramework/transitionManager.py +0 -0
- batFramework/utils.py +161 -34
- batframework-1.0.8a2.dist-info/METADATA +58 -0
- batframework-1.0.8a2.dist-info/RECORD +42 -0
- {batframework-1.0.8a1.dist-info → batframework-1.0.8a2.dist-info}/WHEEL +1 -1
- batFramework/easingController.py +0 -58
- batFramework/enums.py +0 -104
- batFramework/fontManager.py +0 -65
- batFramework/gui/clickableWidget.py +0 -206
- batFramework/gui/constraints/__init__.py +0 -1
- batFramework/gui/constraints/constraints.py +0 -378
- batFramework/gui/dialogueBox.py +0 -96
- batFramework/gui/draggableWidget.py +0 -38
- batFramework/gui/meter.py +0 -76
- batFramework/gui/radioButton.py +0 -62
- batFramework/gui/slider.py +0 -220
- batFramework/gui/textInput.py +0 -134
- batFramework/object.py +0 -115
- batFramework/particle.py +0 -101
- batFramework/renderGroup.py +0 -62
- batFramework/resourceManager.py +0 -84
- batFramework/scrollingSprite.py +0 -113
- batFramework/sprite.py +0 -45
- batFramework/tileset.py +0 -46
- batframework-1.0.8a1.dist-info/LICENCE +0 -21
- batframework-1.0.8a1.dist-info/METADATA +0 -55
- batframework-1.0.8a1.dist-info/RECORD +0 -56
- {batframework-1.0.8a1.dist-info → batframework-1.0.8a2.dist-info}/top_level.txt +0 -0
batFramework/gui/widget.py
CHANGED
@@ -1,321 +1,307 @@
|
|
1
|
-
from
|
2
|
-
from
|
1
|
+
from __future__ import annotations
|
2
|
+
from typing import TYPE_CHECKING
|
3
|
+
if TYPE_CHECKING:
|
4
|
+
from .constraints import Constraint
|
5
|
+
from .root import Root
|
6
|
+
from typing import Self
|
7
|
+
|
3
8
|
import batFramework as bf
|
4
9
|
import pygame
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
10
|
+
from math import ceil
|
11
|
+
|
12
|
+
|
13
|
+
|
9
14
|
class Widget(bf.Entity):
|
10
|
-
def __init__(self
|
11
|
-
super().__init__(
|
12
|
-
self.
|
15
|
+
def __init__(self,convert_alpha=True)->None:
|
16
|
+
super().__init__(convert_alpha=convert_alpha)
|
17
|
+
self.autoresize = False
|
18
|
+
self.parent : None|Self = None
|
19
|
+
self.is_root :bool = False
|
20
|
+
self.children : list["Widget"] = []
|
21
|
+
self.focusable :bool= False
|
13
22
|
self.constraints : list[Constraint] = []
|
14
|
-
self.
|
15
|
-
self.
|
16
|
-
self.
|
17
|
-
self.padding = (0,
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
23
|
+
self.gui_depth : int = 0
|
24
|
+
if self.surface : self.surface.fill("white")
|
25
|
+
self.set_debug_color("red")
|
26
|
+
self.padding :tuple[float|int,...]= (0,0,0,0)
|
27
|
+
|
28
|
+
def set_padding(self,value : float|int|tuple|list)->Self:
|
29
|
+
old_raw_size = (
|
30
|
+
self.rect.w - self.padding[0] - self.padding[2],
|
31
|
+
self.rect.h - self.padding[1] - self.padding[3]
|
32
|
+
)
|
33
|
+
if isinstance(value,list) or isinstance(value,tuple):
|
34
|
+
if len(value) > 4 : return self
|
35
|
+
if any(v<0 for v in value) : return self
|
36
|
+
if len(value) == 2:
|
37
|
+
self.padding = (value[0],value[1],value[0],value[1])
|
38
|
+
else:
|
39
|
+
self.padding = (*value, *self.padding[len(value):])
|
40
|
+
else:
|
41
|
+
self.padding = (value,)*4
|
32
42
|
|
33
|
-
|
34
|
-
|
35
|
-
|
43
|
+
self.set_size(
|
44
|
+
old_raw_size[0] + self.padding[0] + self.padding[2],
|
45
|
+
old_raw_size[1] + self.padding[1] + self.padding[3],
|
46
|
+
)
|
36
47
|
return self
|
48
|
+
|
49
|
+
def inflate_rect_by_padding(self,rect:pygame.FRect)->pygame.FRect:
|
50
|
+
return pygame.FRect(
|
51
|
+
rect[0] - self.padding[0],
|
52
|
+
rect[1] - self.padding[1],
|
53
|
+
rect[2] + self.padding[0]+self.padding[2],
|
54
|
+
rect[3] + self.padding[1]+self.padding[3]
|
55
|
+
)
|
56
|
+
def get_content_left(self)->float:
|
57
|
+
return self.rect.left + self.padding[0]
|
37
58
|
|
38
|
-
def
|
39
|
-
self.
|
40
|
-
self.dirty_shape = True
|
41
|
-
return self
|
59
|
+
def get_content_top(self)->float:
|
60
|
+
return self.rect.top + self.padding[1]
|
42
61
|
|
43
|
-
def
|
44
|
-
self.
|
45
|
-
self.dirty_shape = True
|
46
|
-
return self
|
62
|
+
def get_content_right(self)->float:
|
63
|
+
return self.rect.right - self.padding[2]
|
47
64
|
|
48
|
-
def
|
49
|
-
|
50
|
-
|
51
|
-
|
65
|
+
def get_content_bottom(self)->float:
|
66
|
+
return self.rect.bottom - self.padding[3]
|
67
|
+
|
68
|
+
def get_content_width(self)->float:
|
69
|
+
return self.rect.w - self.padding[0] - self.padding[2]
|
52
70
|
|
71
|
+
def get_content_height(self)->float:
|
72
|
+
return self.rect.h - self.padding[1] - self.padding[3]
|
53
73
|
|
54
|
-
def
|
74
|
+
def get_content_rect(self)->pygame.FRect:
|
55
75
|
return pygame.FRect(
|
56
|
-
rect
|
57
|
-
rect
|
58
|
-
|
59
|
-
|
76
|
+
self.rect.left + self.padding[0],
|
77
|
+
self.rect.top + self.padding[1],
|
78
|
+
self.get_content_width(),
|
79
|
+
self.get_content_height()
|
60
80
|
)
|
61
|
-
|
62
|
-
def set_position(self, x, y) -> Self:
|
63
|
-
if x is None: x = self.rect.x
|
64
|
-
if y is None: y = self.rect.y
|
65
|
-
if (x,y) == self.rect.topleft : return self
|
66
|
-
dx,dy = x-self.rect.x,y-self.rect.y
|
67
|
-
self.rect.topleft = x,y
|
68
|
-
_ = [c.set_position(c.rect.x+dx,c.rect.y+dy) for c in self.children]
|
69
|
-
return self
|
70
81
|
|
71
|
-
def
|
72
|
-
|
73
|
-
if y is None : y = self.rect.centery
|
74
|
-
if (x,y) == self.rect.center : return self
|
75
|
-
dx,dy = x-self.rect.centerx,y-self.rect.centery
|
76
|
-
self.rect.center = x,y
|
77
|
-
_ = [c.set_center(c.rect.centerx+dx,c.rect.centery+dy) for c in self.children]
|
78
|
-
return self
|
82
|
+
def get_content_rect_rel(self)->pygame.FRect:
|
83
|
+
return self.get_content_rect().move(-self.rect.left,-self.rect.top)
|
79
84
|
|
80
|
-
def
|
81
|
-
|
82
|
-
for c in self.children :
|
83
|
-
c.set_parent_scene(parent_scene)
|
84
|
-
return self
|
85
|
-
|
86
|
-
def set_parent(self,parent:"Widget")->Self:
|
87
|
-
self.parent = parent
|
88
|
-
return self
|
85
|
+
def get_content_center(self)->tuple[float,float]:
|
86
|
+
return self.get_content_rect().center
|
89
87
|
|
90
|
-
def
|
91
|
-
if
|
92
|
-
|
93
|
-
pass
|
94
|
-
elif any(v < 0 for v in value):
|
95
|
-
pass
|
96
|
-
elif len(value) == 2:
|
97
|
-
self.padding = (value[0], value[1], value[0], value[1])
|
98
|
-
else:
|
99
|
-
self.padding = (*value, *self.padding[len(value) :])
|
88
|
+
def get_depth(self)->int:
|
89
|
+
if self.is_root or self.parent is None :
|
90
|
+
self.gui_depth = 0
|
100
91
|
else:
|
101
|
-
self.
|
92
|
+
self.gui_depth = self.parent.get_depth() + 1
|
93
|
+
return self.gui_depth
|
102
94
|
|
103
|
-
|
104
|
-
|
95
|
+
def top_at(self, x: float, y: float) -> "None|Widget":
|
96
|
+
if self.children:
|
97
|
+
for child in reversed(self.children):
|
98
|
+
r = child.top_at(x,y)
|
99
|
+
if r is not None:
|
100
|
+
return r
|
101
|
+
if self.rect.collidepoint(x,y) and self.visible:
|
102
|
+
return self
|
103
|
+
return None
|
104
|
+
|
105
|
+
def get_constraint(self,name:str)->Constraint|None:
|
106
|
+
return next((c for c in self.constraints if c.name == name), None)
|
105
107
|
|
106
|
-
def
|
107
|
-
|
108
|
-
|
109
|
-
|
108
|
+
def add_constraints(self,*constraints:Constraint)->Self:
|
109
|
+
for c in constraints:
|
110
|
+
self.add_constraint(c,False)
|
111
|
+
self.apply_constraints()
|
112
|
+
return self
|
113
|
+
|
114
|
+
def add_constraint(self,constraint:Constraint,apply:bool=True)->Self:
|
115
|
+
c = self.get_constraint(constraint.name)
|
116
|
+
if c is not None:
|
117
|
+
self.constraints.remove(c)
|
118
|
+
self.constraints.append(constraint)
|
119
|
+
self.apply_constraints()
|
120
|
+
return self
|
110
121
|
|
111
|
-
def
|
112
|
-
return self.
|
122
|
+
def has_constraint(self,name:str)->bool:
|
123
|
+
return any(c.name == name for c in self.constraints)
|
113
124
|
|
114
|
-
def
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
return self.rect.h - self.padding[1] - self.padding[3]
|
125
|
+
def apply_all_constraints(self)->None:
|
126
|
+
# print("APPLY ALL CONSTRAINTS IN ",self.to_string())
|
127
|
+
self.apply_constraints()
|
128
|
+
for child in self.children : child.apply_all_constraints()
|
119
129
|
|
120
|
-
def
|
121
|
-
|
130
|
+
def apply_constraints(self, max_iterations: int = 10) -> None:
|
131
|
+
if not self.parent:
|
132
|
+
# print(f"Warning : can't apply constraints on {self.to_string()} without parent widget")
|
133
|
+
return
|
134
|
+
if not self.constraints:
|
135
|
+
return
|
136
|
+
# Sort constraints based on priority
|
137
|
+
self.constraints.sort(key=lambda c: c.priority)
|
122
138
|
|
123
|
-
|
124
|
-
|
139
|
+
for iteration in range(max_iterations):
|
140
|
+
unsatisfied = [] # Initialize a flag
|
125
141
|
|
126
|
-
|
127
|
-
|
142
|
+
for constraint in self.constraints:
|
143
|
+
if not constraint.evaluate(self.parent, self):
|
144
|
+
unsatisfied.append(constraint)
|
145
|
+
constraint.apply(self.parent, self)
|
146
|
+
if not unsatisfied:
|
147
|
+
# data = ''.join(f"\n\t->{c.to_string()}" for c in self.constraints)
|
148
|
+
# print(self.get_depth()*'\t'+f"Following constraints of {self.to_string()} were all satisfied :{data}")
|
149
|
+
break
|
150
|
+
# print(f"pass {iteration}/{max_iterations} : unsatisfied = {';'.join(c.to_string() for c in unsatisfied)}")
|
151
|
+
if iteration == max_iterations - 1:
|
152
|
+
raise ValueError(f"[WARNING] Following constraints for {self.to_string()} were not satisfied : \n\t{';'.join([c.to_string() for c in unsatisfied])}")
|
153
|
+
|
154
|
+
# GETTERS
|
155
|
+
def get_root(self)-> Self|Root|None:
|
156
|
+
if self.is_root: return self
|
157
|
+
if self.parent_scene is not None : return self.parent_scene.root
|
158
|
+
return None if self.parent is None else self.parent.get_root()
|
159
|
+
|
160
|
+
def get_size_int(self)->tuple[int,int]:
|
161
|
+
return (ceil(self.rect.width),ceil(self.rect.height))
|
162
|
+
|
163
|
+
|
164
|
+
def get_center(self)->tuple[float,float]:
|
165
|
+
return self.rect.center
|
166
|
+
|
167
|
+
|
168
|
+
def get_bounding_box(self):
|
169
|
+
yield (self.rect,self._debug_color)
|
170
|
+
yield (self.get_content_rect(),"yellow")
|
171
|
+
for child in self.children:
|
172
|
+
yield from child.get_bounding_box()
|
128
173
|
|
129
|
-
def
|
130
|
-
|
174
|
+
def set_autoresize(self,value:bool)-> Self:
|
175
|
+
self.autoresize = value
|
176
|
+
self.build()
|
177
|
+
return self
|
178
|
+
|
179
|
+
def set_parent(self,parent:Self|None)->None:
|
180
|
+
if self.parent:
|
181
|
+
self.parent.remove_child(self)
|
182
|
+
self.parent = parent
|
183
|
+
self.apply_all_constraints()
|
184
|
+
# SETTERS
|
185
|
+
|
186
|
+
def set_root(self) -> Self:
|
187
|
+
self.is_root = True
|
188
|
+
return self
|
131
189
|
|
132
|
-
def
|
133
|
-
|
190
|
+
def set_parent_scene(self,scene)->None:
|
191
|
+
super().set_parent_scene(scene)
|
192
|
+
for child in self.children :
|
193
|
+
child.set_parent_scene(scene)
|
134
194
|
|
135
|
-
def
|
136
|
-
|
137
|
-
|
195
|
+
def set_x(self,x:float)->Self:
|
196
|
+
delta = x - self.rect.x
|
197
|
+
self.rect.x = x
|
138
198
|
for child in self.children:
|
139
|
-
|
140
|
-
|
141
|
-
def add_constraints(self,*constraints:"Constraint")->Self:
|
142
|
-
self.constraints.extend(constraints)
|
143
|
-
seen = set()
|
144
|
-
result = []
|
145
|
-
for c in self.constraints:
|
146
|
-
if c.name not in seen:
|
147
|
-
result.append(c)
|
148
|
-
seen.add(c.name)
|
149
|
-
self.constraints = result
|
150
|
-
self.constraints.sort(key=lambda c : c.priority)
|
151
|
-
self.dirty_constraints = True
|
199
|
+
child.set_x(child.rect.x + delta)
|
200
|
+
self.apply_constraints()
|
152
201
|
return self
|
153
202
|
|
154
|
-
def
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
while not all_good:
|
161
|
-
for constraint in self.constraints:
|
162
|
-
if not constraint.evaluate(self.parent,self):
|
163
|
-
constraint.apply(self.parent,self)
|
164
|
-
# print(constraint.name,"Applied")
|
165
|
-
constraint_iteration += 1
|
166
|
-
if all(c.evaluate(self.parent,self) for c in self.constraints):
|
167
|
-
all_good = True
|
168
|
-
break
|
169
|
-
elif self.__constraint_iteration > MAX_CONSTRAINTS:
|
170
|
-
print(self,"CONSTRAINTS ERROR",list(c.name for c in self.constraints if not c.evaluate(self.parent,self)))
|
171
|
-
self.dirty_constraints = False
|
172
|
-
return
|
173
|
-
# print("DONE")
|
174
|
-
self.dirty_constraints = False
|
175
|
-
|
176
|
-
def remove_constraints(self,*names:str)->Self:
|
177
|
-
self.constraints = [c for c in self.constraints if c.name not in names]
|
178
|
-
return self
|
203
|
+
def set_y(self,y:float)->Self:
|
204
|
+
delta = y - self.rect.y
|
205
|
+
self.rect.y = y
|
206
|
+
for child in self.children:
|
207
|
+
child.set_y(child.rect.y + delta)
|
208
|
+
self.apply_constraints()
|
179
209
|
|
180
|
-
|
181
|
-
return any(c.name == name for c in self.constraints )
|
210
|
+
return self
|
182
211
|
|
183
|
-
def
|
184
|
-
|
212
|
+
def set_position(self,x:float,y:float)->Self:
|
213
|
+
delta_x = x - self.rect.x
|
214
|
+
delta_y = y - self.rect.y
|
215
|
+
self.rect.topleft = x,y
|
185
216
|
for child in self.children:
|
186
|
-
child.
|
187
|
-
|
217
|
+
child.set_position(child.rect.x + delta_x,child.rect.y+delta_y)
|
218
|
+
self.apply_constraints()
|
219
|
+
return self
|
220
|
+
|
221
|
+
def set_center(self,x:float,y:float)->Self:
|
222
|
+
delta_x = x - self.rect.centerx
|
223
|
+
delta_y = y - self.rect.centery
|
224
|
+
self.rect.center = x,y
|
225
|
+
for child in self.children:
|
226
|
+
child.set_position(child.rect.x + delta_x,child.rect.y+delta_y)
|
227
|
+
self.apply_constraints()
|
228
|
+
return self
|
188
229
|
|
189
|
-
def get_root(self)->"Root":
|
190
|
-
if self.is_root:
|
191
|
-
return self
|
192
|
-
return self.parent.get_root()
|
193
230
|
|
194
|
-
def
|
195
|
-
|
196
|
-
|
197
|
-
if child.visible:
|
198
|
-
r = child.top_at(x, y)
|
199
|
-
if r is not None:
|
200
|
-
return r
|
201
|
-
return self if self.visible and self.rect.collidepoint(x, y) else None
|
202
|
-
|
203
|
-
def add(self,*children:"Widget")->Self:
|
204
|
-
self.children.extend(children)
|
205
|
-
i = len(self.children)
|
206
|
-
for child in children:
|
207
|
-
child.set_render_order(i).set_parent(self).set_parent_scene(self.parent_scene)
|
208
|
-
i += 1
|
209
|
-
if self.parent:
|
210
|
-
self.parent.do_sort_children = True
|
231
|
+
def set_size(self, width : float, height: float) -> Self:
|
232
|
+
self.rect.size = (width,height)
|
233
|
+
self.build()
|
211
234
|
return self
|
235
|
+
|
212
236
|
|
213
|
-
|
214
|
-
for child in self.children[:]:
|
215
|
-
if child in children:
|
216
|
-
child.set_parent(None).set_parent_scene(None)
|
217
|
-
self.children.remove(child)
|
218
|
-
if self.parent:
|
219
|
-
self.parent.do_sort_children = True
|
237
|
+
# Other Methods
|
220
238
|
|
221
|
-
def
|
222
|
-
|
223
|
-
|
224
|
-
|
239
|
+
def print_tree(self,ident:int=0)->None:
|
240
|
+
print('\t'*ident+self.to_string()+(':' if self.children else ''))
|
241
|
+
for child in self.children :
|
242
|
+
child.print_tree(ident+1)
|
225
243
|
|
226
|
-
|
244
|
+
def to_string(self)->str:
|
245
|
+
|
246
|
+
return f"{self.to_string_id()}@{*self.rect.topleft,* self.rect.size}"
|
227
247
|
|
228
|
-
return self
|
229
248
|
|
230
|
-
def
|
231
|
-
|
232
|
-
if size[0] is None : size[0] = self.rect.w
|
233
|
-
if size[1] is None : size[1] = self.rect.h
|
234
|
-
if size == self.rect.size : return self
|
235
|
-
self.rect.size = size
|
236
|
-
self.dirty_shape = True
|
237
|
-
return self
|
238
|
-
|
249
|
+
def to_string_id(self)->str:
|
250
|
+
return "Widget"
|
239
251
|
|
240
|
-
def process_event(self, event: pygame.Event) -> bool:
|
241
|
-
# First propagate to children
|
242
|
-
for child in self.children:
|
243
|
-
child.process_event(event)
|
244
|
-
# return True if the method is blocking (no propagation to next children of the scene)
|
245
|
-
super().process_event(event)
|
246
252
|
|
253
|
+
def do_when_removed(self)->None:
|
254
|
+
if self.parent_scene and self.parent == self.parent_scene.root:
|
255
|
+
self.set_parent(None)
|
247
256
|
|
248
|
-
|
249
|
-
if self.do_sort_children:
|
250
|
-
self.children.sort(key = lambda c : c.render_order)
|
251
|
-
self.do_sort_children = False
|
252
|
-
_ = [c.update(dt) for c in self.children]
|
253
|
-
super().update(dt)
|
257
|
+
# Methods on children
|
254
258
|
|
259
|
+
def add_child(self,*child:"Widget")->None:
|
260
|
+
for c in child :
|
261
|
+
self.children.append(c)
|
262
|
+
c.set_parent(self)
|
263
|
+
c.set_parent_scene(self.parent_scene)
|
264
|
+
c.apply_constraints()
|
265
|
+
self.children_modified()
|
255
266
|
|
256
|
-
def
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
if self.convert_alpha : self.surface = self.surface.convert_alpha()
|
262
|
-
|
263
|
-
def paint(self)->None:
|
264
|
-
self.surface.fill((0,0,0,0))
|
265
|
-
return self
|
267
|
+
def remove_child(self,child:Self)->None:
|
268
|
+
self.children.remove(child)
|
269
|
+
child.set_parent(None)
|
270
|
+
child.set_parent_scene(None)
|
271
|
+
self.children_modified()
|
266
272
|
|
267
|
-
def visit_up(self,func)->None:
|
268
|
-
if func(self) : return
|
269
|
-
if self.parent:
|
270
|
-
self.parent.visit_up(func)
|
271
|
-
|
272
|
-
def selective_up(self,widget:"Widget"):
|
273
|
-
# if returns True then stop climbing widget tree
|
274
|
-
if widget.parent and widget.parent.dirty_constraints:
|
275
|
-
return False
|
276
|
-
widget.visit(self.selective_down)
|
277
|
-
return True
|
278
|
-
|
279
|
-
def selective_down(self,widget: "Widget"):
|
280
|
-
if widget.constraints :
|
281
|
-
widget.resolve_constraints()
|
282
|
-
else:
|
283
|
-
widget.dirty_constraints = False
|
284
|
-
if widget.dirty_shape:
|
285
|
-
widget.build()
|
286
|
-
widget.dirty_shape = False
|
287
|
-
self.dirty_surface = True
|
288
|
-
|
289
|
-
|
290
|
-
def draw(self, camera: bf.Camera) -> None:
|
291
|
-
if self.dirty_shape:
|
292
|
-
self.dirty_constraints = True
|
293
|
-
self.dirty_surface = True
|
294
|
-
self.build()
|
295
|
-
self.dirty_shape = False
|
296
|
-
for child in self.children :
|
297
|
-
child.dirty_constraints = True
|
298
|
-
|
299
|
-
if self.dirty_constraints:
|
300
|
-
if self.parent and self.parent.dirty_constraints:
|
301
|
-
self.parent.visit_up(self.selective_up)
|
302
|
-
else:
|
303
|
-
self.visit(lambda c : c.resolve_constraints())
|
304
273
|
|
305
|
-
if self.dirty_surface :
|
306
|
-
self.paint()
|
307
|
-
self.dirty_surface = False
|
308
274
|
|
309
275
|
|
276
|
+
# if return True -> don't propagate to siblings or parents
|
277
|
+
def process_event(self, event: pygame.Event)->bool:
|
278
|
+
# First propagate to children
|
279
|
+
for child in self.children:
|
280
|
+
if child.process_event(event):
|
281
|
+
return True
|
282
|
+
#return True if the method is blocking (no propagation to next children of the scene)
|
283
|
+
return super().process_event(event)
|
310
284
|
|
311
|
-
super().draw(camera)
|
312
|
-
if self.clip_children:
|
313
285
|
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
camera.surface.set_clip(new_clip)
|
286
|
+
def update(self,dt:float):
|
287
|
+
for child in self.children:
|
288
|
+
child.update(dt)
|
318
289
|
|
319
|
-
|
320
|
-
|
321
|
-
|
290
|
+
def draw(self, camera: bf.Camera) -> int:
|
291
|
+
self.children.sort(key=lambda e: (e.z_depth,e.render_order))
|
292
|
+
return super().draw(camera) + sum([child.draw(camera) for child in self.children])
|
293
|
+
|
294
|
+
def build(self)->None:
|
295
|
+
"""
|
296
|
+
This function is called each time the widget's surface has to be updated
|
297
|
+
It usually has to be overriden if inherited to suit the needs of the new class
|
298
|
+
"""
|
299
|
+
if not self.surface: return
|
300
|
+
if self.surface.get_size() != self.get_size_int():
|
301
|
+
self.surface = pygame.Surface(self.get_size_int())
|
302
|
+
if self.parent : self.parent.children_modified()
|
303
|
+
|
304
|
+
def children_modified(self)->None:
|
305
|
+
self.apply_constraints()
|
306
|
+
if self.parent and not self.is_root:
|
307
|
+
self.parent.children_modified()
|
batFramework/manager.py
CHANGED
@@ -2,70 +2,49 @@ import batFramework as bf
|
|
2
2
|
import pygame
|
3
3
|
import random
|
4
4
|
|
5
|
-
|
6
5
|
class Manager(bf.SceneManager):
|
7
6
|
def __init__(self, *initial_scene_list) -> None:
|
8
|
-
|
9
|
-
|
10
|
-
self.
|
11
|
-
self.
|
12
|
-
self._cutsceneManager = bf.CutsceneManager()
|
13
|
-
self._cutsceneManager.set_manager(self)
|
7
|
+
random.seed("random")
|
8
|
+
self._screen: pygame.Surface = bf.const.SCREEN
|
9
|
+
self._timeManager = bf.Time()
|
10
|
+
self._cutsceneManager = bf.CutsceneManager(self)
|
14
11
|
self._clock: pygame.Clock = pygame.Clock()
|
15
|
-
|
16
|
-
self.do_pre_init()
|
17
|
-
self.init_scenes(*initial_scene_list)
|
12
|
+
super().__init__(*initial_scene_list)
|
18
13
|
self.set_sharedVar("clock", self._clock)
|
19
14
|
self.do_init()
|
20
15
|
|
21
16
|
@staticmethod
|
22
|
-
def set_icon(path: str)
|
23
|
-
surf = pygame.image.load(bf.
|
17
|
+
def set_icon(path: str):
|
18
|
+
surf = pygame.image.load(bf.utils.get_path(path)).convert_alpha()
|
24
19
|
pygame.display.set_icon(surf)
|
25
20
|
|
26
|
-
def
|
27
|
-
super().print_status()
|
28
|
-
print("TIMERS : ")
|
29
|
-
for r in self._timeManager.get_active_registers():
|
30
|
-
# print(r["timers"])
|
31
|
-
print("\n".join(str(t) for t in r))
|
32
|
-
print("-" * 40)
|
33
|
-
|
34
|
-
def get_fps(self) -> float:
|
21
|
+
def get_fps(self):
|
35
22
|
return self._clock.get_fps()
|
36
23
|
|
37
|
-
def do_init(self)
|
38
|
-
pass
|
39
|
-
|
40
|
-
def do_pre_init(self) -> None:
|
24
|
+
def do_init(self):
|
41
25
|
pass
|
42
26
|
|
43
|
-
def stop(self)
|
27
|
+
def stop(self)->None:
|
44
28
|
self._running = False
|
45
29
|
|
46
|
-
def run(self)
|
30
|
+
def run(self):
|
47
31
|
self._running = True
|
48
32
|
dt: float = 0
|
49
33
|
while self._running:
|
50
34
|
for event in pygame.event.get():
|
51
|
-
event.
|
35
|
+
if event.type == pygame.QUIT:
|
36
|
+
self._running = False
|
37
|
+
break
|
38
|
+
if event.type == pygame.VIDEORESIZE:
|
39
|
+
bf.const.set_resolution((event.w,event.h))
|
52
40
|
self.process_event(event)
|
53
|
-
if not event.consumed:
|
54
|
-
if event.type == pygame.QUIT:
|
55
|
-
self._running = False
|
56
|
-
break
|
57
|
-
if event.type == pygame.VIDEORESIZE and not (
|
58
|
-
bf.const.FLAGS & pygame.SCALED
|
59
|
-
):
|
60
|
-
bf.const.set_resolution((event.w, event.h))
|
61
41
|
# update
|
62
|
-
dt = self._clock.tick(bf.const.FPS) / 1000
|
63
|
-
|
64
|
-
self._timeManager.update(dt)
|
42
|
+
dt = self._clock.tick(bf.const.FPS if not bf.const.VSYNC else 0) / 1000
|
43
|
+
dt = min(dt, 0.02)
|
65
44
|
self._cutsceneManager.update(dt)
|
45
|
+
self._timeManager.update()
|
66
46
|
self.update(dt)
|
67
47
|
# render
|
68
|
-
self._screen.fill((0, 0, 0))
|
69
48
|
self.draw(self._screen)
|
70
49
|
pygame.display.flip()
|
71
50
|
pygame.quit()
|