batframework 1.0.9a11__py3-none-any.whl → 1.0.9a12__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.
Files changed (73) hide show
  1. batFramework/__init__.py +2 -0
  2. batFramework/action.py +280 -279
  3. batFramework/actionContainer.py +105 -82
  4. batFramework/animatedSprite.py +80 -58
  5. batFramework/animation.py +91 -77
  6. batFramework/audioManager.py +156 -131
  7. batFramework/baseScene.py +249 -240
  8. batFramework/camera.py +245 -317
  9. batFramework/constants.py +57 -51
  10. batFramework/cutscene.py +239 -253
  11. batFramework/cutsceneManager.py +34 -34
  12. batFramework/drawable.py +107 -77
  13. batFramework/dynamicEntity.py +30 -30
  14. batFramework/easingController.py +58 -58
  15. batFramework/entity.py +130 -130
  16. batFramework/enums.py +171 -135
  17. batFramework/fontManager.py +65 -65
  18. batFramework/gui/__init__.py +28 -25
  19. batFramework/gui/animatedLabel.py +90 -89
  20. batFramework/gui/button.py +17 -17
  21. batFramework/gui/clickableWidget.py +244 -244
  22. batFramework/gui/collapseContainer.py +98 -0
  23. batFramework/gui/constraints/__init__.py +1 -1
  24. batFramework/gui/constraints/constraints.py +1066 -980
  25. batFramework/gui/container.py +220 -206
  26. batFramework/gui/debugger.py +140 -130
  27. batFramework/gui/draggableWidget.py +63 -44
  28. batFramework/gui/image.py +61 -58
  29. batFramework/gui/indicator.py +116 -113
  30. batFramework/gui/interactiveWidget.py +243 -239
  31. batFramework/gui/label.py +147 -344
  32. batFramework/gui/layout.py +442 -429
  33. batFramework/gui/meter.py +155 -96
  34. batFramework/gui/radioButton.py +43 -35
  35. batFramework/gui/root.py +228 -228
  36. batFramework/gui/scrollingContainer.py +282 -0
  37. batFramework/gui/selector.py +232 -250
  38. batFramework/gui/shape.py +286 -276
  39. batFramework/gui/slider.py +353 -397
  40. batFramework/gui/style.py +10 -10
  41. batFramework/gui/styleManager.py +49 -54
  42. batFramework/gui/syncedVar.py +43 -49
  43. batFramework/gui/textInput.py +331 -306
  44. batFramework/gui/textWidget.py +308 -0
  45. batFramework/gui/toggle.py +140 -128
  46. batFramework/gui/tooltip.py +35 -30
  47. batFramework/gui/widget.py +546 -521
  48. batFramework/manager.py +131 -134
  49. batFramework/particle.py +118 -118
  50. batFramework/propertyEaser.py +79 -79
  51. batFramework/renderGroup.py +34 -34
  52. batFramework/resourceManager.py +130 -130
  53. batFramework/scene.py +31 -31
  54. batFramework/sceneLayer.py +134 -138
  55. batFramework/sceneManager.py +200 -197
  56. batFramework/scrollingSprite.py +115 -115
  57. batFramework/sprite.py +46 -51
  58. batFramework/stateMachine.py +49 -54
  59. batFramework/templates/__init__.py +2 -1
  60. batFramework/templates/character.py +15 -0
  61. batFramework/templates/controller.py +158 -97
  62. batFramework/templates/stateMachine.py +39 -0
  63. batFramework/tileset.py +46 -46
  64. batFramework/timeManager.py +213 -213
  65. batFramework/transition.py +162 -162
  66. batFramework/triggerZone.py +22 -22
  67. batFramework/utils.py +306 -306
  68. {batframework-1.0.9a11.dist-info → batframework-1.0.9a12.dist-info}/LICENSE +20 -20
  69. {batframework-1.0.9a11.dist-info → batframework-1.0.9a12.dist-info}/METADATA +24 -17
  70. batframework-1.0.9a12.dist-info/RECORD +72 -0
  71. batframework-1.0.9a11.dist-info/RECORD +0 -67
  72. {batframework-1.0.9a11.dist-info → batframework-1.0.9a12.dist-info}/WHEEL +0 -0
  73. {batframework-1.0.9a11.dist-info → batframework-1.0.9a12.dist-info}/top_level.txt +0 -0
batFramework/gui/label.py CHANGED
@@ -1,344 +1,147 @@
1
- import batFramework as bf
2
- import pygame
3
- from .shape import Shape
4
- from typing import Literal, Self,Union
5
- from math import ceil
6
-
7
- class Label(Shape):
8
- _text_cache = {}
9
-
10
- def __init__(self, text: str = "") -> None:
11
- self.text = text
12
-
13
- # Allows scrolling the text
14
- self.allow_scroll : bool = True
15
-
16
- # Scroll variable
17
- self.scroll :pygame.Vector2 = pygame.Vector2(0,0)
18
-
19
- self.resized_flag: bool = False
20
-
21
- # Enable/Disable antialiasing
22
- self.antialias: bool = bf.FontManager().DEFAULT_ANTIALIAS
23
-
24
- self.text_size = bf.FontManager().DEFAULT_FONT_SIZE
25
-
26
- self.auto_wraplength: bool = False
27
-
28
- self.alignment: bf.alignment = bf.alignment.CENTER
29
-
30
- self.text_color: tuple[int, int, int] | str = "black"
31
-
32
- self.text_outline_color: tuple[int, int, int] | str = "gray50"
33
-
34
- self.text_outline_surface: pygame.Surface = None
35
-
36
- self._text_outline_mask = pygame.Mask((3, 3), fill=True)
37
-
38
- self.line_alignment = pygame.FONT_LEFT
39
- # font name (given when loaded by utils) to use for the text
40
- self.font_name = None
41
- # reference to the font object
42
- self.font_object = None
43
- # Rect containing the text of the label
44
- self.text_rect = pygame.FRect(0, 0, 0, 0)
45
- # text surface (result of font.render)
46
- self.text_surface: pygame.Surface = pygame.Surface((0, 0))
47
-
48
- self.show_text_outline: bool = False
49
-
50
- self.is_italic: bool = False
51
-
52
- self.is_bold: bool = False
53
-
54
- self.is_underlined: bool = False
55
-
56
- super().__init__((0, 0))
57
- self.set_padding((10, 4))
58
- self.set_debug_color("blue")
59
- self.set_color("gray50")
60
- self.set_autoresize(True)
61
- self.set_font(force=True)
62
-
63
-
64
- def __str__(self) -> str:
65
- return f"Label({repr(self.text)})"
66
-
67
-
68
- def set_allow_scroll(self, value:bool)->Self:
69
- if self.allow_scroll == value: return self
70
- self.allow_scroll = value
71
- self.dirty_shape = True
72
- return self
73
-
74
- def set_text_color(self, color) -> Self:
75
- self.text_color = color
76
- self.dirty_surface = True
77
- return self
78
-
79
- def set_line_alignment(self, alignment: Union[Literal["left"], Literal["right"], Literal["center"]]) -> Self:
80
- self.line_alignment = alignment
81
- self.dirty_surface = True
82
- return self
83
-
84
- def set_italic(self, value: bool) -> Self:
85
- if value == self.is_italic:
86
- return self
87
- self.is_italic = value
88
- if self.autoresize_h or self.autoresize_w:
89
- self.dirty_shape = True
90
- else:
91
- self.dirty_surface = True
92
- return self
93
-
94
- def set_bold(self, value: bool) -> Self:
95
- if value == self.is_bold:
96
- return self
97
- self.is_bold = value
98
- if self.autoresize_h or self.autoresize_w:
99
- self.dirty_shape = True
100
- else:
101
- self.dirty_surface = True
102
- return self
103
-
104
- def set_underlined(self, value: bool) -> Self:
105
- if value == self.is_underlined:
106
- return self
107
- self.is_underlined = value
108
- self.dirty_surface = True
109
- return self
110
-
111
- def set_text_outline_mask_size(self,size:tuple[int,int])->Self:
112
- old_size = self._text_outline_mask.get_size()
113
- m = [[self._text_outline_mask.get_at((x,y)) for x in range(min(old_size[0],size[0]))] for y in range(min(old_size[1],size[1]))]
114
- self._text_outline_mask = pygame.Mask(size, fill=True)
115
- self.set_text_outline_matrix(m)
116
- return self
117
-
118
- def set_text_outline_matrix(self, matrix: list[list[0 | 1]]) -> Self:
119
- if matrix is None:
120
- matrix = [[0 for _ in range(3)] for _ in range(3)]
121
- for y in range(3):
122
- for x in range(3):
123
- self._text_outline_mask.set_at((x, y), matrix[2 - y][2 - x])
124
- self.dirty_shape = True
125
- return self
126
-
127
- def set_text_outline_color(self, color) -> Self:
128
- self.text_outline_color = color
129
- self.dirty_surface = True
130
- return self
131
-
132
- def enable_text_outline(self) -> Self:
133
- self.show_text_outline = True
134
- self.dirty_shape = True
135
- return self
136
-
137
- def disable_text_outline(self) -> Self:
138
- self.show_text_outline = False
139
- self.dirty_shape = True
140
- return self
141
-
142
- def set_alignment(self, alignment: bf.alignment) -> Self:
143
- self.alignment = alignment
144
- self.dirty_surface = True
145
- return self
146
-
147
- def set_auto_wraplength(self, val: bool) -> Self:
148
- self.auto_wraplength = val
149
- if self.autoresize_h or self.autoresize_w:
150
- self.dirty_shape = True
151
- else:
152
- self.dirty_surface = True
153
- return self
154
-
155
- def get_debug_outlines(self):
156
- yield from super().get_debug_outlines()
157
- if self.visible:
158
- yield (self.text_rect.move(self.rect.x - self.scroll.x,self.rect.y - self.scroll.y), "purple")
159
-
160
- # offset = self._get_outline_offset() if self.show_text_outline else (0,0)
161
- # yield (self.text_rect.move(self.rect.x - offset[0] - self.scroll.x,self.rect.y - offset[1] - self.scroll.y), "purple")
162
-
163
- def set_font(self, font_name: str = None, force: bool = False) -> Self:
164
- if font_name == self.font_name and not force:
165
- return self
166
- self.font_name = font_name
167
- self.font_object = bf.FontManager().get_font(self.font_name, self.text_size)
168
- if self.autoresize_h or self.autoresize_w:
169
- self.dirty_shape = True
170
- else:
171
- self.dirty_surface = True
172
- return self
173
-
174
- def set_text_size(self, text_size: int) -> Self:
175
- text_size = (text_size // 2) * 2
176
- if text_size == self.text_size:
177
- return self
178
- self.text_size = text_size
179
- self.font_object = bf.FontManager().get_font(self.font_name, self.text_size)
180
- self.dirty_shape = True
181
- return self
182
-
183
- def get_text_size(self) -> int:
184
- return self.text_size
185
-
186
- def is_antialias(self) -> bool:
187
- return self.antialias
188
-
189
- def set_antialias(self, value: bool) -> Self:
190
- self.antialias = value
191
- self.dirty_surface = True
192
- return self
193
-
194
- def set_text(self, text: str) -> Self:
195
- if text == self.text:
196
- return self
197
- self.text = text
198
- self.dirty_shape = True
199
- return self
200
-
201
- def get_min_required_size(self) -> tuple[float, float]:
202
- return self.expand_rect_with_padding(
203
- (0, 0, *self._get_text_rect_required_size())
204
- ).size
205
-
206
- def get_text(self) -> str:
207
- return self.text
208
-
209
- def _render_font(self, params: dict) -> pygame.Surface:
210
-
211
- if self.draw_mode == bf.drawMode.SOLID:
212
- params.pop("font_name")
213
-
214
- # save old settings
215
- old_italic = self.font_object.get_italic()
216
- old_bold = self.font_object.get_bold()
217
- old_underline = self.font_object.get_underline()
218
- old_align = self.font_object.align
219
- # setup font
220
- self.font_object.set_italic(self.is_italic)
221
- self.font_object.set_bold(self.is_bold)
222
- self.font_object.set_underline(self.is_underlined)
223
- self.font_object.align = self.line_alignment
224
- surf = self.font_object.render(**params)
225
-
226
- # reset font
227
- self.font_object.set_italic(old_italic)
228
- self.font_object.set_bold(old_bold)
229
- self.font_object.set_underline(old_underline)
230
- self.font_object.align = old_align
231
- else:
232
- params.pop("font_name")
233
- surf = self.font_object.render(**params)
234
-
235
- return surf
236
-
237
- def _get_outline_offset(self)->tuple[int,int]:
238
- mask_size = self._text_outline_mask.get_size()
239
- return mask_size[0]//2,mask_size[1]//2
240
-
241
- def _get_text_rect_required_size(self):
242
- font_height = self.font_object.get_ascent() - self.font_object.get_descent()
243
- if not self.text:
244
- size = (0,font_height)
245
- else:
246
- tmp_text = self.text
247
- if self.text.endswith('\n'):
248
- tmp_text+=" "
249
- params = {
250
- "font_name": self.font_object.name,
251
- "text": tmp_text,
252
- "antialias": self.antialias,
253
- "color": self.text_color,
254
- "bgcolor": None, # if (self.has_alpha_color() or self.draw_mode == bf.drawMode.TEXTURED) else self.color,
255
- "wraplength": int(self.get_inner_width()) if self.auto_wraplength and not self.autoresize_w else 0,
256
- }
257
-
258
- size = self._render_font(params).get_size()
259
- size = size[0],max(font_height,size[1])
260
-
261
- # print(self.text,size)
262
- s = self._get_outline_offset() if self.show_text_outline else (0,0)
263
- return size[0] + s[0]*2, size[1] + s[1]*2
264
-
265
- def _build_layout(self) -> bool:
266
- ret = False
267
- target_size = self.resolve_size(self.get_min_required_size())
268
-
269
- if self.rect.size != target_size :
270
- self.set_size(target_size)
271
- ret = True
272
- # self.apply_post_updates(skip_draw=True)
273
- # return True
274
-
275
- self.text_rect.size = self._get_text_rect_required_size()
276
- padded = self.get_local_inner_rect()
277
- self.align_text(self.text_rect, padded, self.alignment)
278
- return ret
279
-
280
- def _paint_text(self) -> None:
281
- if self.font_object is None:
282
- print(f"No font for widget with text : '{self}' :(")
283
- return
284
- wrap = int(self.get_inner_width()) if self.auto_wraplength and not self.autoresize_w else 0
285
- params = {
286
- "font_name": self.font_object.name,
287
- "text": self.text,
288
- "antialias": self.antialias,
289
- "color": self.text_color,
290
- "bgcolor": None,
291
- "wraplength": wrap,
292
- }
293
-
294
- self.text_surface = self._render_font(params)
295
- if self.show_text_outline:
296
- self.text_outline_surface = (
297
- pygame.mask.from_surface(self.text_surface)
298
- .convolve(self._text_outline_mask)
299
- .to_surface(setcolor=self.text_outline_color, unsetcolor=(0, 0, 0, 0))
300
- )
301
-
302
- outline_offset = list(self._get_outline_offset())
303
- outline_offset[0]-=self.scroll.x
304
- outline_offset[1]-=self.scroll.y
305
- l = [
306
- (self.text_outline_surface,(self.text_rect.x - self.scroll.x,self.text_rect.y - self.scroll.y)),
307
- (self.text_surface, self.text_rect.move(*outline_offset))
308
- ]
309
- else:
310
- l = [(self.text_surface, self.text_rect.move(-self.scroll))]
311
-
312
- # clip surface
313
-
314
- old = self.surface.get_clip()
315
- self.surface.set_clip(self.get_local_inner_rect())
316
- self.surface.fblits(l)
317
- self.surface.set_clip(old)
318
-
319
- def align_text(
320
- self, text_rect: pygame.FRect, area: pygame.FRect, alignment: bf.alignment
321
- ):
322
- if alignment == bf.alignment.LEFT:
323
- alignment = bf.alignment.MIDLEFT
324
- elif alignment == bf.alignment.MIDRIGHT:
325
- alignment = bf.alignment.MIDRIGHT
326
-
327
- pos = area.__getattribute__(alignment.value)
328
- text_rect.__setattr__(alignment.value, pos)
329
- text_rect.y = ceil(text_rect.y)
330
-
331
- def build(self) -> bool:
332
- """
333
- return True if size changed
334
- """
335
-
336
- size_changed = self._build_layout()
337
- super().build()
338
- return size_changed
339
-
340
-
341
- def paint(self) -> None:
342
- super().paint()
343
- if self.font_object:
344
- self._paint_text()
1
+ import batFramework as bf
2
+ import pygame
3
+ from .shape import Shape
4
+ from .textWidget import TextWidget
5
+ from typing import Literal, Self,Union
6
+ from math import ceil
7
+
8
+ class Label(Shape):
9
+
10
+ def __init__(self, text: str = "") -> None:
11
+ super().__init__((0, 0))
12
+ self.alignment: bf.alignment = bf.alignment.CENTER
13
+ self.text_widget = TextWidget(text)
14
+ self.set_padding((10, 4))
15
+ self.set_debug_color("blue")
16
+ self.set_color("gray50")
17
+ self.set_autoresize(True)
18
+ self.set_font(force=True)
19
+ self.add(self.text_widget)
20
+
21
+ def __str__(self) -> str:
22
+ return f"Label({repr(self.text_widget.text)})"
23
+
24
+ def set_visible(self, value):
25
+ self.text_widget.set_visible(value)
26
+ return super().set_visible(value)
27
+
28
+ def set_allow_scroll(self, value:bool)->Self:
29
+ self.text_widget.set_allow_scroll(value)
30
+ return self
31
+
32
+ def set_text_color(self, color) -> Self:
33
+ self.text_widget.set_text_color(color)
34
+ return self
35
+
36
+ def set_line_alignment(self, alignment: int) -> Self:
37
+ """
38
+ alignment: One of pygame.FONT_CENTER, pygame.FONT_LEFT, pygame.FONT_RIGHT
39
+ """
40
+ self.text_widget.set_line_alignment(alignment)
41
+ return self
42
+
43
+ def set_italic(self, value: bool) -> Self:
44
+ self.text_widget.set_italic(value)
45
+ return self
46
+
47
+ def set_bold(self, value: bool) -> Self:
48
+ self.text_widget.set_bold(value)
49
+ return self
50
+
51
+ def set_underlined(self, value: bool) -> Self:
52
+ self.text_widget.set_underlined(value)
53
+ return self
54
+
55
+ def set_text_outline_mask_size(self,size:tuple[int,int])->Self:
56
+ self.text_widget.set_text_outline_mask_size(size)
57
+ return self
58
+
59
+ def set_text_outline_matrix(self, matrix: list[list[0 | 1]]) -> Self:
60
+ self.text_widget.set_text_outline_matrix(matrix)
61
+ return self
62
+
63
+ def set_text_outline_color(self, color) -> Self:
64
+ self.text_widget.set_text_outline_color(color)
65
+ return self
66
+
67
+ def set_text_bg_color(self, color) -> Self:
68
+ self.text_widget.set_text_bg_color(color)
69
+ return self
70
+
71
+ def set_show_text_outline(self,value:bool) -> Self:
72
+ self.text_widget.set_show_text_outline(value)
73
+ return self
74
+
75
+ def set_alignment(self, alignment: bf.alignment) -> Self:
76
+ self.alignment = alignment
77
+ self.dirty_shape = True
78
+ return self
79
+
80
+ def set_auto_wraplength(self, val: bool) -> Self:
81
+ self.text_widget.set_auto_wraplength(val)
82
+ return self
83
+
84
+ def get_debug_outlines(self):
85
+ if self.visible:
86
+ yield from super().get_debug_outlines()
87
+ yield from self.text_widget.get_debug_outlines()
88
+
89
+ def set_font(self, font_name: str = None, force: bool = False) -> Self:
90
+ self.text_widget.set_font(font_name,force)
91
+ return self
92
+
93
+ def set_text_size(self, text_size: int) -> Self:
94
+ self.text_widget.set_text_size(text_size)
95
+ return self
96
+
97
+ def get_text_size(self) -> int:
98
+ return self.text_widget.text_size
99
+
100
+ def is_antialias(self) -> bool:
101
+ return self.text_widget.antialias
102
+
103
+ def set_antialias(self, value: bool) -> Self:
104
+ self.text_widget.set_antialias(value)
105
+ return self
106
+
107
+ def set_text(self, text: str) -> Self:
108
+ self.text_widget.set_text(text)
109
+ return self
110
+
111
+ def get_min_required_size(self) -> tuple[float, float]:
112
+ return self.expand_rect_with_padding(
113
+ (0, 0, *self.text_widget.get_min_required_size())
114
+ ).size
115
+
116
+ def get_text(self) -> str:
117
+ return self.text_widget.text
118
+
119
+ def align_text(
120
+ self, text_rect: pygame.FRect, area: pygame.FRect, alignment: bf.alignment
121
+ ):
122
+ if alignment == bf.alignment.LEFT:
123
+ alignment = bf.alignment.MIDLEFT
124
+ elif alignment == bf.alignment.MIDRIGHT:
125
+ alignment = bf.alignment.MIDRIGHT
126
+
127
+ pos = area.__getattribute__(alignment.value)
128
+ text_rect.__setattr__(alignment.value, pos)
129
+ text_rect.y = ceil(text_rect.y)
130
+
131
+ def build(self):
132
+ ret = False
133
+ target_size = self.resolve_size(self.get_min_required_size())
134
+ if self.rect.size != target_size :
135
+ self.set_size(target_size)
136
+ self.text_widget.set_size(self.get_inner_rect().size)
137
+ ret = True
138
+
139
+ padded = self.get_inner_rect()
140
+ self.align_text(self.text_widget.rect, padded, self.alignment)
141
+ return ret
142
+
143
+ def apply_pre_updates(self):
144
+ if self.text_widget.dirty_shape:
145
+ self.dirty_shape =True
146
+ return super().apply_pre_updates()
147
+