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.
Files changed (63) hide show
  1. batFramework/__init__.py +50 -53
  2. batFramework/action.py +105 -116
  3. batFramework/actionContainer.py +11 -53
  4. batFramework/animatedSprite.py +65 -115
  5. batFramework/audioManager.py +26 -70
  6. batFramework/camera.py +68 -253
  7. batFramework/constants.py +54 -16
  8. batFramework/cutscene.py +25 -34
  9. batFramework/cutsceneBlocks.py +42 -37
  10. batFramework/debugger.py +48 -0
  11. batFramework/dynamicEntity.py +7 -9
  12. batFramework/easing.py +71 -0
  13. batFramework/entity.py +98 -42
  14. batFramework/gui/__init__.py +2 -8
  15. batFramework/gui/button.py +79 -7
  16. batFramework/gui/constraints.py +204 -0
  17. batFramework/gui/container.py +31 -155
  18. batFramework/gui/debugger.py +43 -124
  19. batFramework/gui/frame.py +19 -0
  20. batFramework/gui/image.py +17 -41
  21. batFramework/gui/indicator.py +21 -41
  22. batFramework/gui/interactiveWidget.py +13 -116
  23. batFramework/gui/label.py +73 -278
  24. batFramework/gui/layout.py +61 -148
  25. batFramework/gui/root.py +37 -102
  26. batFramework/gui/shape.py +57 -258
  27. batFramework/gui/toggle.py +46 -97
  28. batFramework/gui/widget.py +254 -268
  29. batFramework/manager.py +19 -40
  30. batFramework/particles.py +77 -0
  31. batFramework/scene.py +107 -214
  32. batFramework/sceneManager.py +107 -150
  33. batFramework/stateMachine.py +0 -1
  34. batFramework/time.py +57 -117
  35. batFramework/transition.py +126 -184
  36. batFramework/transitionManager.py +0 -0
  37. batFramework/utils.py +161 -34
  38. batframework-1.0.8a2.dist-info/METADATA +58 -0
  39. batframework-1.0.8a2.dist-info/RECORD +42 -0
  40. {batframework-1.0.8a1.dist-info → batframework-1.0.8a2.dist-info}/WHEEL +1 -1
  41. batFramework/easingController.py +0 -58
  42. batFramework/enums.py +0 -104
  43. batFramework/fontManager.py +0 -65
  44. batFramework/gui/clickableWidget.py +0 -206
  45. batFramework/gui/constraints/__init__.py +0 -1
  46. batFramework/gui/constraints/constraints.py +0 -378
  47. batFramework/gui/dialogueBox.py +0 -96
  48. batFramework/gui/draggableWidget.py +0 -38
  49. batFramework/gui/meter.py +0 -76
  50. batFramework/gui/radioButton.py +0 -62
  51. batFramework/gui/slider.py +0 -220
  52. batFramework/gui/textInput.py +0 -134
  53. batFramework/object.py +0 -115
  54. batFramework/particle.py +0 -101
  55. batFramework/renderGroup.py +0 -62
  56. batFramework/resourceManager.py +0 -84
  57. batFramework/scrollingSprite.py +0 -113
  58. batFramework/sprite.py +0 -45
  59. batFramework/tileset.py +0 -46
  60. batframework-1.0.8a1.dist-info/LICENCE +0 -21
  61. batframework-1.0.8a1.dist-info/METADATA +0 -55
  62. batframework-1.0.8a1.dist-info/RECORD +0 -56
  63. {batframework-1.0.8a1.dist-info → batframework-1.0.8a2.dist-info}/top_level.txt +0 -0
@@ -1,60 +1,40 @@
1
1
  from .shape import Shape
2
- from typing import Any, Self
2
+ from typing import Any
3
3
  import pygame
4
- from .widget import Widget
5
- from .interactiveWidget import InteractiveWidget
6
- from .draggableWidget import DraggableWidget
7
- import batFramework as bf
8
-
4
+ # from .constraints import ConstraintAspectRatio
9
5
 
10
6
  class Indicator(Shape):
11
- def __init__(self, size: tuple[int | float] = (10, 10)) -> None:
12
- super().__init__(size)
13
- self.debug_color = "magenta"
14
- self.set_outline_width(1)
15
- self.set_outline_color("black")
7
+ def __init__(self,width:int|float= 10,height:int|float=10)->None:
8
+ super().__init__(width,height)
16
9
 
17
- def to_string_id(self) -> str:
10
+ def to_string_id(self)->str:
18
11
  return "Indicator"
19
12
 
20
- def set_value(self, value: Any) -> None:
13
+ def set_value(self,value:Any)->None:
21
14
  pass
22
15
 
23
- def get_value(self) -> Any:
16
+ def get_value(self)->Any:
24
17
  pass
25
18
 
26
-
27
- def top_at(self, x, y):
28
- return None
19
+ def _build_indicator(self)->None:
20
+ pass
21
+
22
+ def build(self)->None:
23
+ super().build()
24
+ self._build_indicator()
29
25
 
30
26
 
31
27
  class ToggleIndicator(Indicator):
32
- def __init__(self, default_value: bool) -> None:
33
- self.value: bool = default_value
34
- self.callback = lambda val : self.set_color("green" if val else "red")
35
- super().__init__((20, 20))
36
- self.set_value(default_value)
37
-
38
- # TODO aspect ratio would be good right about here
28
+ def __init__(self,default_value:bool)->None:
29
+ self.value:bool = default_value
30
+ super().__init__(20,20)
39
31
  # self.add_constraint(ConstraintAspectRatio(1))
40
32
 
41
- def set_callback(self, callback) -> Self:
42
- self.callback = callback
43
- return self
44
-
45
- def set_value(self, value: bool) -> None:
33
+ def set_value(self,value)->None:
46
34
  self.value = value
47
- if self.callback:
48
- self.callback(value)
49
- self.dirty_surface = True
35
+ self.set_color("green" if value else "red")
36
+ self.build()
50
37
 
51
- def get_value(self) -> bool:
38
+ def get_value(self)->bool:
52
39
  return self.value
53
-
54
- def top_at(self, x: float, y: float) -> "None|Widget":
55
- r = super().top_at(x, y)
56
- if r is self:
57
- return None
58
- return r
59
-
60
-
40
+ #
@@ -1,125 +1,22 @@
1
1
  from .widget import Widget
2
- from typing import Self
3
- from typing import TYPE_CHECKING
4
- import pygame
5
- from math import cos
6
-
7
- if TYPE_CHECKING:
8
- from .container import Container
9
- import batFramework as bf
10
-
11
2
 
12
3
  class InteractiveWidget(Widget):
13
- def __init__(self, *args, **kwargs) -> None:
14
- self.is_focused: bool = False
15
- self.is_hovered: bool = False
16
- self.is_clicked_down: bool = False
17
- self.focused_index = 0
4
+ def __init__(self,*args,**kwargs):
5
+ super().__init__(convert_alpha = True)
18
6
  self.focusable = True
19
- super().__init__(*args, **kwargs)
20
-
21
- def set_focusable(self, value: bool) -> Self:
22
- self.focusable = value
23
- return self
24
-
25
- def allow_focus_to_self(self) -> bool:
26
- return True
7
+ self.is_focused : bool = False
27
8
 
28
- def get_focus(self) -> bool:
29
- if self.focusable and ((r := self.get_root()) is not None):
30
- r.focus_on(self)
31
- if self.parent and isinstance(self.parent, InteractiveWidget):
32
- self.parent.set_focused_child(self)
33
- return True
34
- return False
9
+ def get_focus(self)->bool:
10
+ if self.parent is None or not self.focusable: return False
11
+ self.get_root().focus_on(self)
35
12
 
36
- def lose_focus(self) -> bool:
37
- if self.is_focused and ((r := self.get_root()) is not None):
38
- r.focus_on(None)
39
- return True
40
- return False
41
-
42
- def on_get_focus(self) -> None:
13
+ def on_get_focus(self)->None:
43
14
  self.is_focused = True
44
- self.do_on_get_focus()
45
15
 
46
- def on_lose_focus(self) -> None:
16
+ def on_lose_focus(self)->None:
47
17
  self.is_focused = False
48
- self.do_on_lose_focus()
49
-
50
- def on_key_down(self,key):
51
- if key == pygame.K_DOWN:
52
- self.focus_next_sibling()
53
- elif key == pygame.K_UP:
54
- self.focus_prev_sibling()
55
- else:
56
- self.do_on_key_down(key)
57
-
58
- def on_key_up(self, key):
59
- self.do_on_key_up(key)
60
-
61
- def do_on_key_down(self, key):
62
- pass
63
-
64
- def do_on_key_up(self, key):
65
- pass
66
-
67
- def do_on_get_focus(self) -> None:
68
- pass
69
-
70
- def do_on_lose_focus(self) -> None:
71
- pass
72
-
73
- def focus_next_sibling(self) -> None:
74
- if isinstance(self.parent, bf.Container):
75
- self.parent.focus_next_child()
76
-
77
- def focus_prev_sibling(self) -> None:
78
- if isinstance(self.parent, bf.Container):
79
- self.parent.focus_prev_child()
80
-
81
- def on_click_down(self, button: int) -> None:
82
- self.is_clicked_down = True
83
- self.do_on_click_down(button)
84
-
85
- def on_click_up(self, button: int) -> None:
86
- self.is_clicked_down = False
87
- self.do_on_click_up(button)
88
-
89
- def do_on_click_down(self, button: int) -> None:
90
- pass
91
-
92
- def do_on_click_up(self, button: int) -> None:
93
- pass
94
-
95
- def on_enter(self) -> None:
96
- self.is_hovered = True
97
- self.do_on_enter()
98
-
99
- def on_exit(self) -> None:
100
- self.is_hovered = False
101
- self.is_clicked_down = False
102
- self.do_on_exit()
103
-
104
- def do_on_enter(self) -> None:
105
- pass
106
-
107
- def do_on_exit(self) -> None:
108
- pass
109
-
110
- def on_mouse_motion(self, x, y) -> None:
111
- self.do_on_mouse_motion(x,y)
112
-
113
- def do_on_mouse_motion(self,x,y)->None:
114
- pass
115
-
116
- def set_focused_child(self, child: "InteractiveWidget"):
117
- pass
118
-
119
- def draw_focused(self, camera: bf.Camera) -> None:
120
- delta = 4 + ((2*cos(pygame.time.get_ticks()/100)) //2) * 2
121
- pygame.draw.rect(
122
- camera.surface,
123
- "white",
124
- self.rect.move(-camera.rect.x,-camera.rect.y).inflate(delta,delta),1
125
- )
18
+
19
+ def lose_focus(self)->bool:
20
+ if self.is_focused and self.parent is not None:
21
+ self.get_root().focus_on(None)
22
+
batFramework/gui/label.py CHANGED
@@ -3,313 +3,108 @@ import pygame
3
3
  from .shape import Shape
4
4
  from typing import Self
5
5
 
6
-
7
6
  class Label(Shape):
8
- _text_cache = {}
9
-
10
- def __init__(self, text: str) -> None:
11
- self.text = ""
12
-
13
- self.resized_flag: bool = False
14
-
7
+ def __init__(self,text:str) -> None:
8
+ self._text = ""
15
9
  # Enable/Disable antialiasing
16
- self.antialias: bool = bf.FontManager().DEFAULT_ANTIALIAS
17
-
18
- self.text_size = bf.FontManager().DEFAULT_TEXT_SIZE
19
-
20
- self.auto_wraplength: bool = False
21
-
22
- self.alignment: bf.alignment = bf.alignment.CENTER
23
-
24
- self.text_color: tuple[int, int, int] | str = "black"
25
-
26
- self.text_outline_color: tuple[int, int, int] | str = "gray50"
27
-
28
- self.text_outline_surface: pygame.Surface = None
29
-
30
- self._text_outline_mask = pygame.Mask((3, 3), fill=True)
31
-
10
+ self._antialias : bool = True
11
+
12
+ self._text_size = bf.const.DEFAULT_TEXT_SIZE
13
+
14
+ self._text_color : tuple[int,int,int]|str = "black"
32
15
  # font name (given when loaded by utils) to use for the text
33
- self.font_name = None
16
+ self._font_name = None
34
17
  # reference to the font object
35
- self.font_object = None
18
+ self._font_object = None
36
19
  # Rect containing the text of the label
37
- self.text_rect = pygame.FRect(0,0,0,0)
20
+ self._text_rect = None
38
21
  # text surface (result of font.render)
39
- self.text_surface: pygame.Surface = pygame.Surface((0, 0))
40
- self.do_caching: bool = False
41
-
42
- self.show_text_outline: bool = False
43
-
44
- self.is_italic: bool = False
45
-
46
- self.is_bold: bool = False
47
-
48
- self.is_underlined: bool = False
49
-
50
- super().__init__((0, 0))
51
- self.set_padding((10, 4))
22
+ self._text_surface : pygame.Surface | None= None
23
+ super().__init__(width=0,height=0)
24
+ self.set_padding((10,4))
52
25
  self.set_debug_color("blue")
53
- self.set_color("gray50")
26
+ self.set_color("white")
54
27
  self.set_autoresize(True)
55
28
  self.set_font(force=True)
56
29
  self.set_text(text)
57
30
 
58
- @staticmethod
59
- def clear_cache():
60
- Label._text_cache = {}
61
-
62
- def enable_caching(self) -> Self:
63
- self.do_caching = True
31
+ def set_text_color(self,color)->Self:
32
+ self._text_color = color
33
+ self.build()
64
34
  return self
65
35
 
66
- def disable_caching(self) -> Self:
67
- self.do_caching = False
68
- return self
36
+ def to_string_id(self)->str:
37
+ return f"Label({self._text})"
69
38
 
70
- def set_text_color(self, color) -> Self:
71
- self.text_color = color
72
- self.dirty_surface = True
73
- return self
74
39
 
75
- def set_italic(self, value: bool) -> Self:
76
- if value == self.is_italic:
77
- return self
78
- self.is_italic = value
79
- if self.autoresize_h or self.autoresize_w:
80
- self.dirty_shape = True
81
- else:
82
- self.dirty_surface = True
83
- return self
40
+ def get_bounding_box(self):
41
+ yield from super().get_bounding_box()
42
+ if self._text_rect : yield self._text_rect.move(*self.rect.topleft)
84
43
 
85
- def set_bold(self, value: bool) -> Self:
86
- if value == self.is_bold:
87
- return self
88
- self.is_bold = value
89
- if self.autoresize_h or self.autoresize_w:
90
- self.dirty_shape = True
91
- else:
92
- self.dirty_surface = True
44
+ def set_font(self,font_name:str=None,force:bool = False)-> "Label":
45
+ if font_name == self._font_name and not force: return self
46
+ self._font_name = font_name
47
+ self._font_object = bf.utils.get_font(self._font_name,self._text_size)
48
+ self.build()
93
49
  return self
94
50
 
95
- def set_underlined(self, value: bool) -> Self:
96
- if value == self.is_underlined:
97
- return self
98
- self.is_underlined = value
99
- self.dirty_surface = True
51
+ def set_text_size(self,text_size:int) -> "Label":
52
+ text_size = round(text_size/2) * 2
53
+ if text_size == self._text_size : return self
54
+ self._text_size = text_size
55
+ self._font_object = bf.utils.get_font(self._font_name,self._text_size)
56
+ self.build()
100
57
  return self
101
58
 
102
- def set_text_outline_matrix(self, matrix: list[list[0 | 1]]) -> Self:
103
- if matrix is None:
104
- matrix = [[0 for _ in range(3)] for _ in range(3)]
105
- for y in range(3):
106
- for x in range(3):
107
- self._text_outline_mask.set_at((x, y), matrix[2 - y][2 - x])
108
- self.dirty_surface = True
109
- return self
59
+ def get_text_size(self)-> int:
60
+ return self._text_size
110
61
 
111
- def set_text_outline_color(self, color) -> Self:
112
- self.text_outline_color = color
113
- self.dirty_surface = True
114
- return self
62
+ def is_antialias(self)->bool:
63
+ return self._antialias
115
64
 
116
- def enable_text_outline(self) -> Self:
117
- self.show_text_outline = True
118
- self.dirty_surface = True
65
+ def set_antialias(self,value:bool)->"Label":
66
+ self._antialias = value
67
+ self.build()
119
68
  return self
120
69
 
121
- def disable_text_outline(self) -> Self:
122
- self.show_text_outline = False
123
- self.dirty_surface = True
70
+ def set_text(self,text:str) -> "Label":
71
+ if text == self._text : return self
72
+ self._text = text
73
+ self.build()
124
74
  return self
75
+
76
+ def get_text(self)->str:
77
+ return self._text
125
78
 
126
- def __str__(self) -> str:
127
- return f"Label({self.text})"
128
-
129
- def set_alignment(self, alignment: bf.alignment) -> "Label":
130
- self.alignment = alignment
131
- self.dirty_surface = True
132
- return self
133
-
134
- def set_auto_wraplength(self, val: bool) -> "Label":
135
- self.auto_wraplength = val
136
- if self.autoresize_h or self.autoresize_w:
137
- self.dirty_shape = True
138
- else:
139
- self.dirty_surface = True
140
- return self
141
-
142
- def get_debug_outlines(self):
143
- yield from super().get_debug_outlines()
144
- yield (self.text_rect.move(*self.rect.topleft),"purple")
145
-
146
- def set_font(self, font_name: str = None, force: bool = False) -> Self:
147
- if font_name == self.font_name and not force:
148
- return self
149
- self.font_name = font_name
150
- self.font_object = bf.FontManager().get_font(self.font_name, self.text_size)
151
- if self.autoresize_h or self.autoresize_w:
152
- self.dirty_shape = True
153
- else:
154
- self.dirty_surface = True
155
- return self
156
-
157
- def set_text_size(self, text_size: int) -> Self:
158
- text_size = round(text_size / 2) * 2
159
- if text_size == self.text_size:
160
- return self
161
- self.text_size = text_size
162
- self.font_object = bf.FontManager().get_font(self.font_name, self.text_size)
163
- if self.autoresize_h or self.autoresize_w:
164
- self.dirty_shape = True
165
- return self
166
79
 
167
- def get_text_size(self) -> int:
168
- return self.text_size
169
-
170
- def is_antialias(self) -> bool:
171
- return self.antialias
172
-
173
- def set_antialias(self, value: bool) -> Self:
174
- self.antialias = value
175
- self.dirty_surface = True
176
- return self
177
-
178
- def set_text(self, text: str) -> Self:
179
- if text == self.text:
180
- return self
181
- self.text = text
182
- self.dirty_shape = True
183
- return self
184
-
185
- def get_min_required_size(self)->tuple[float,float]:
186
- if not (self.autoresize_w or self.autoresize_h) :
187
- return self.rect.size
188
- if not self.text_rect:
189
- params = {
190
- "font_name": self.font_object.name,
191
- "text": self.text,
192
- "antialias": False,
193
- "color": "white",
194
- "bgcolor": "black", # if (self.has_alpha_color() or self.draw_mode == bf.drawMode.TEXTURED) else self.color,
195
- "wraplength": int(self.get_padded_width()) if self.auto_wraplength else 0,
196
- }
197
-
198
- self.text_rect.size = self._render_font(params).get_size()
199
- res = self.inflate_rect_by_padding((0,0,*self.text_rect.size)).size
200
- # return res
201
- return res[0] if self.autoresize_w else self.rect.w, res[1] if self.autoresize_h else self.rect.h
202
-
203
- def get_text(self) -> str:
204
- return self.text
205
-
206
- def _render_font(self, params: dict) -> pygame.Surface:
207
- key = tuple(params.values())
208
-
209
- cached_value = Label._text_cache.get(key, None)
210
-
211
- if self.draw_mode == bf.drawMode.SOLID:
212
- if cached_value is None:
213
- params.pop("font_name")
214
-
215
- #save old settings
216
- old_italic = self.font_object.get_italic()
217
- old_bold = self.font_object.get_bold()
218
- old_underline = self.font_object.get_underline()
219
-
220
- #setup font
221
- self.font_object.set_italic(self.is_italic)
222
- self.font_object.set_bold(self.is_bold)
223
- self.font_object.set_underline(self.is_underlined)
224
-
225
- surf = self.font_object.render(**params)
226
-
227
- # reset font
228
- self.font_object.set_italic(old_italic)
229
- self.font_object.set_bold(old_bold)
230
- self.font_object.set_underline(old_underline)
231
-
232
- if self.do_caching:
233
- Label._text_cache[key] = surf
234
- else:
235
- surf = cached_value
236
- else:
237
- params.pop("font_name")
238
- surf = self.font_object.render(**params)
239
-
240
- return surf
241
-
242
- def _build_layout(self) -> None:
243
-
244
- params = {
245
- "font_name": self.font_object.name,
246
- "text": self.text,
247
- "antialias": False,
248
- "color": "white",
249
- "bgcolor": "black", # if (self.has_alpha_color() or self.draw_mode == bf.drawMode.TEXTURED) else self.color,
250
- "wraplength": int(self.get_padded_width()) if self.auto_wraplength else 0,
251
- }
252
-
253
- self.text_rect.size = self._render_font(params).get_size()
254
- if self.autoresize_h or self.autoresize_w:
255
- target_rect = self.inflate_rect_by_padding((0,0,*self.text_rect.size))
256
- if not self.autoresize_w : target_rect.w = self.rect.w
257
- if not self.autoresize_h : target_rect.h = self.rect.h
258
- if self.rect.size != target_rect.size:
259
- self.set_size(target_rect.size)
260
- self.build()
261
- return
262
- padded = self.get_padded_rect().move(-self.rect.x,-self.rect.y)
263
- self.align_text(self.text_rect,padded,self.alignment)
264
-
265
- def _paint_text(self) -> None:
266
- if self.font_object is None:
267
- print(f"No font for widget with text : '{self}' :(")
80
+ def _build_text(self)-> None:
81
+ if self._font_object is None:
82
+ print("No font :(")
268
83
  return
269
-
270
- params = {
271
- "font_name": self.font_object.name,
272
- "text": self.text,
273
- "antialias": self.antialias,
274
- "color": self.text_color,
275
- "bgcolor": None, # if (self.has_alpha_color() or self.draw_mode == bf.drawMode.TEXTURED) else self.color,
276
- "wraplength": int(self.get_padded_width()) if self.auto_wraplength else 0,
277
- }
278
- self.text_surface = self._render_font(params)
279
-
280
- if self.show_text_outline:
281
- self.text_outline_surface = (
282
- pygame.mask.from_surface(self.text_surface)
283
- .convolve(self._text_outline_mask)
284
- .to_surface(setcolor=self.text_outline_color, unsetcolor=(0, 0, 0, 0))
285
- )
286
-
287
-
288
- l = []
289
- if self.show_text_outline:
290
- l.append(
291
- (
292
- self.text_outline_surface,
293
- self.text_rect.move(-1, self.relief - self.get_relief() - 1),
294
- )
295
- )
296
- l.append(
297
- (self.text_surface, self.text_rect.move(0, self.relief - self.get_relief()))
84
+ # render(text, antialias, color, bgcolor=None, wraplength=0) -> Surface
85
+ self._text_surface = self._font_object.render(
86
+ text = self._text,
87
+ antialias = self._antialias,
88
+ color = self._text_color,
89
+ bgcolor = self._color,
90
+ wraplength = 0
298
91
  )
299
- self.surface.fblits(l)
300
-
301
- def align_text(self,text_rect:pygame.FRect,area:pygame.FRect,alignment: bf.alignment):
302
- if alignment == bf.alignment.LEFT : alignment = bf.alignment.MIDLEFT
303
- elif alignment == bf.alignment.MIDRIGHT : alignment = bf.alignment.MIDRIGHT
304
-
305
- pos = area.__getattribute__(alignment.value)
306
- text_rect.__setattr__(alignment.value,pos)
307
-
308
- def build(self) -> None:
92
+ self._text_rect = self._text_surface.get_frect()
93
+
94
+ def _build_layout(self)->None:
95
+ if self.autoresize:
96
+ if self.rect.size != self.inflate_rect_by_padding(self._text_rect).size :
97
+ self.set_size(
98
+ self._text_rect.w + self.padding[0]+self.padding[2],
99
+ self._text_rect.h + self.padding[1]+self.padding[3]
100
+ )
101
+ return
102
+ self._text_rect.center = self.get_content_rect_rel().center
103
+ self.surface.blit(self._text_surface,self._text_rect)
104
+
105
+ def build(self)->None:
309
106
  super().build()
107
+ if not self._font_object:return
108
+ self._build_text()
310
109
  self._build_layout()
311
110
 
312
- def paint(self)->None:
313
- super().paint()
314
- if self.font_object:
315
- self._paint_text()