batframework 1.0.9a10__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 -245
  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 -201
  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 -426
  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.9a10.dist-info → batframework-1.0.9a12.dist-info}/LICENSE +20 -20
  69. {batframework-1.0.9a10.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.9a10.dist-info/RECORD +0 -67
  72. {batframework-1.0.9a10.dist-info → batframework-1.0.9a12.dist-info}/WHEEL +0 -0
  73. {batframework-1.0.9a10.dist-info → batframework-1.0.9a12.dist-info}/top_level.txt +0 -0
@@ -1,250 +1,232 @@
1
- import batFramework as bf
2
- import pygame
3
- from typing import Self,Callable,Any
4
- from .button import Button
5
- from .indicator import ArrowIndicator
6
- from .clickableWidget import ClickableWidget
7
- from .widget import Widget
8
-
9
- class MyArrow(ArrowIndicator,ClickableWidget):
10
- def top_at(self,x,y):
11
- return Widget.top_at(self,x,y)
12
-
13
- def get_focus(self):
14
- return self.parent.get_focus()
15
-
16
- class Selector(Button):
17
- def __init__(self,options:list[str]=None,default_value:str=None,allow_cycle:bool=False):
18
- super().__init__('')
19
- self.allow_cycle = allow_cycle
20
- self.current_index = 0
21
- self.on_modify_callback : Callable[[str,int],Any] = None
22
- self.options = options if options else []
23
- self.gap : int = 2
24
- text_value = ""
25
-
26
-
27
- if not (default_value is not None and default_value in self.options):
28
- default_value = options[0]
29
-
30
- text_value = default_value
31
- self.current_index = self.options.index(default_value)
32
-
33
- self.left_indicator : MyArrow = (MyArrow(bf.direction.LEFT)
34
- .set_color((0,0,0,0)).set_arrow_color(self.text_color)
35
- .set_callback(lambda : self.set_by_index(self.get_current_index()-1))
36
- )
37
-
38
- self.right_indicator:MyArrow =(MyArrow(bf.direction.RIGHT)
39
- .set_color((0,0,0,0)).set_arrow_color(self.text_color)
40
- .set_callback(lambda : self.set_by_index(self.get_current_index()+1))
41
- )
42
-
43
- self.add(self.left_indicator,self.right_indicator)
44
- self.set_clip_children(False)
45
- self.set_text(text_value)
46
-
47
- def __str__(self):
48
- return f"Selector[{self.options[self.current_index]}]"
49
-
50
- def set_gap(self,value:int)->Self:
51
- self.gap = value
52
- self.dirty_shape = True
53
- return self
54
-
55
- def set_arrow_color(self,color)->Self:
56
- self.left_indicator.set_arrow_color(color)
57
- self.right_indicator.set_arrow_color(color)
58
- return self
59
-
60
- def disable(self):
61
- super().disable()
62
- self.left_indicator.disable()
63
- self.right_indicator.disable()
64
- return self
65
-
66
- def enable(self):
67
- super().enable()
68
- self.right_indicator.enable()
69
- self.left_indicator.enable()
70
- index = self.current_index
71
- if not self.allow_cycle:
72
- if index == 0:
73
- self.left_indicator.disable()
74
- else:
75
- self.left_indicator.enable()
76
- if index == len(self.options)-1:
77
- self.right_indicator.disable()
78
- else:
79
- self.right_indicator.enable()
80
-
81
-
82
- return self
83
-
84
- def set_tooltip_text(self, text):
85
- self.left_indicator.set_tooltip_text(text)
86
- self.right_indicator.set_tooltip_text(text)
87
- return super().set_tooltip_text(text)
88
-
89
- def get_min_required_size(self) -> tuple[float, float]:
90
- """
91
- Calculates the minimum size required for the selector, including text and indicators.
92
- """
93
-
94
- # Calculate the maximum size needed for the text
95
- old_text = self.text
96
- max_text_size = (0, 0)
97
- for option in self.options:
98
- self.text = option
99
- text_size = self._get_text_rect_required_size()
100
- max_text_size = max(max_text_size[0], text_size[0]), max(max_text_size[1], text_size[1])
101
- self.text = old_text
102
-
103
- # Ensure total_height is always an odd integer
104
- total_height = max(self.font_object.get_height()+1, max_text_size[1] * 1.5)
105
- total_height += self.unpressed_relief
106
- total_height += max(self.right_indicator.outline_width,self.left_indicator.outline_width)
107
-
108
- # Calculate total width and height
109
- total_width = (
110
- total_height*2+
111
- max_text_size[0] + # Text width
112
- self.gap * 2 # Gaps between text and indicators
113
- )
114
- # Inflate by padding at the very end
115
- final_size = self.expand_rect_with_padding((0, 0, total_width, total_height)).size
116
-
117
- return final_size
118
-
119
- def _align_content(self):
120
- """
121
- Builds the selector layout (places and resizes the indicators)
122
- """
123
-
124
- # return
125
- # Step 1: Calculate the padded area for positioning
126
- padded = self.get_inner_rect()
127
-
128
-
129
- # left_size = self.left_indicator.rect.size
130
- right_size = self.right_indicator.rect.size
131
-
132
- indicator_height = padded.h
133
-
134
- self.left_indicator.set_size((indicator_height,indicator_height))
135
- self.right_indicator.set_size((indicator_height,indicator_height))
136
-
137
-
138
- # Step 3: Position indicators
139
- self.left_indicator.set_position(padded.left, None)
140
- self.left_indicator.set_center(None, padded.centery)
141
-
142
- self.right_indicator.set_position(padded.right - right_size[0], None)
143
- self.right_indicator.set_center(None, padded.centery)
144
-
145
- def apply_post_updates(self, skip_draw = False):
146
- super().apply_post_updates(skip_draw)
147
- self._align_content()
148
-
149
- def get_current_index(self)->int:
150
- return self.current_index
151
-
152
- def set_allow_cycle(self,value:bool)->Self:
153
- if value == self.allow_cycle: return self
154
- self.allow_cycle = value
155
- self.dirty_surface = True
156
- return self
157
-
158
- def set_text_color(self,color)->Self:
159
- super().set_text_color(color)
160
- self.left_indicator.set_arrow_color(color)
161
- self.right_indicator.set_arrow_color(color)
162
- return self
163
-
164
- def set_modify_callback(self,function:Callable[[str,int],Any]):
165
- """
166
- the function will receive the value and the index
167
- """
168
- self.on_modify_callback = function
169
- return self
170
-
171
- def set_by_index(self,index:int)->Self:
172
- if self.allow_cycle:
173
- index = index%len(self.options)
174
- else:
175
- index = max(min(len(self.options)-1,index),0)
176
-
177
- if index == self.current_index:
178
- return self
179
-
180
- self.current_index = index
181
- self.set_text(self.options[self.current_index])
182
- if self.on_modify_callback:
183
- self.on_modify_callback(self.options[self.current_index],self.current_index)
184
- if not self.allow_cycle:
185
- if index == 0:
186
- self.left_indicator.disable()
187
- else:
188
- self.left_indicator.enable()
189
- if index == len(self.options)-1:
190
- self.right_indicator.disable()
191
- else:
192
- self.right_indicator.enable()
193
- return self
194
-
195
- def paint(self):
196
- super().paint()
197
- self.left_indicator.show()
198
- self.right_indicator.show()
199
- if not self.allow_cycle and self.current_index == 0:
200
- self.left_indicator.hide()
201
- elif not self.allow_cycle and self.current_index== len(self.options)-1:
202
- self.right_indicator.hide()
203
-
204
- def set_by_value(self,value:str)->Self:
205
- if not self.is_enabled : return
206
- if value not in self.options : return self
207
- index = self.options.index(value)
208
- self.set_by_index(index)
209
- return self
210
-
211
- def on_key_down(self, key: int) -> bool:
212
- if not self.is_enabled:
213
- return False
214
-
215
- key_actions = {
216
- pygame.K_RIGHT: self.right_indicator,
217
- pygame.K_SPACE: self.right_indicator,
218
- pygame.K_LEFT: self.left_indicator
219
- }
220
-
221
- indicator = key_actions.get(key)
222
- if indicator and indicator.visible and indicator.is_enabled:
223
- indicator.on_click_down(1)
224
- return True
225
-
226
- return False
227
-
228
- def on_key_up(self, key: int) -> bool:
229
- if not self.is_enabled:
230
- return False
231
-
232
- key_actions = {
233
- pygame.K_RIGHT: self.right_indicator,
234
- pygame.K_SPACE: self.right_indicator,
235
- pygame.K_LEFT: self.left_indicator
236
- }
237
-
238
- indicator = key_actions.get(key)
239
- if indicator and indicator.visible and indicator.is_enabled:
240
- indicator.on_click_up(1)
241
- return True
242
-
243
- return False
244
-
245
- def do_on_click_down(self, button) -> None:
246
- if self.is_enabled and button == 1:
247
- if not self.get_focus():
248
- return True
249
- return False
250
-
1
+ import batFramework as bf
2
+ import pygame
3
+ from typing import Self, Callable, Any
4
+ from .button import Button
5
+ from .indicator import ArrowIndicator
6
+ from .clickableWidget import ClickableWidget
7
+ from .widget import Widget
8
+ from .syncedVar import SyncedVar
9
+
10
+ class MyArrow(ArrowIndicator, ClickableWidget):
11
+ def top_at(self, x, y):
12
+ return Widget.top_at(self, x, y)
13
+
14
+ def get_focus(self):
15
+ return self.parent.get_focus()
16
+
17
+ def __str__(self):
18
+ return "SelectorArrow"
19
+
20
+ class Selector(Button):
21
+ def __init__(self, options: list[Any] = None, default_value_index: int = None, display_func: Callable[[Any], str] = None,synced_var: SyncedVar = None):
22
+ self.allow_cycle = False
23
+ self.current_index = default_value_index
24
+ self.on_modify_callback: Callable[[Any, int], Any] = None
25
+ self.options = options if options else []
26
+ self.display_func = display_func or str
27
+ self.gap: int = 2
28
+ self.synced_var = synced_var if synced_var is not None else SyncedVar(None)
29
+ display_text = ""
30
+
31
+ super().__init__("")
32
+
33
+ self.left_indicator: MyArrow = (MyArrow(bf.direction.LEFT)
34
+ .set_color((0, 0, 0, 0)).set_arrow_color(self.text_widget.text_color)
35
+ .set_callback(lambda: self.set_by_index(self.get_current_index() - 1))
36
+ )
37
+
38
+ self.right_indicator: MyArrow = (MyArrow(bf.direction.RIGHT)
39
+ .set_color((0, 0, 0, 0)).set_arrow_color(self.text_widget.text_color)
40
+ .set_callback(lambda: self.set_by_index(self.get_current_index() + 1))
41
+ )
42
+
43
+ self.add(self.left_indicator, self.right_indicator)
44
+ self.set_clip_children(False)
45
+
46
+ if self.options and default_value_index is None and synced_var is not None:
47
+ display_text = display_func(synced_var.value)
48
+ default_value_index = self.options.index(synced_var.value)
49
+ elif self.options:
50
+ if default_value_index is None:
51
+ default_value_index= 0
52
+ display_text = self.display_func(self.options[default_value_index])
53
+ self.current_index = default_value_index
54
+ self.set_text(display_text)
55
+
56
+ def __str__(self):
57
+ return f"Selector[{self.options[self.current_index] if self.options else ''}]"
58
+
59
+ def _update_text_widget(self):
60
+ if self.options:
61
+ display_text = self.display_func(self.options[self.current_index])
62
+ self.text_widget.set_text(display_text)
63
+ else:
64
+ self.text_widget.set_text("")
65
+
66
+ def _on_synced_var_update(self, value: Any):
67
+ if value in self.options:
68
+ self.current_index = self.options.index(value)
69
+ self._update_text_widget()
70
+ self._update_arrow_states()
71
+ if self.on_modify_callback:
72
+ self.on_modify_callback(value, self.current_index)
73
+
74
+ def _update_arrow_states(self):
75
+ if not self.allow_cycle:
76
+ if self.current_index <= 0:
77
+ self.left_indicator.disable()
78
+ else:
79
+ self.left_indicator.enable()
80
+
81
+ if self.current_index >= len(self.options) - 1:
82
+ self.right_indicator.disable()
83
+ else:
84
+ self.right_indicator.enable()
85
+
86
+ def set_gap(self, value: int) -> Self:
87
+ self.gap = value
88
+ self.dirty_shape = True
89
+ return self
90
+
91
+ def set_arrow_color(self, color) -> Self:
92
+ self.left_indicator.set_arrow_color(color)
93
+ self.right_indicator.set_arrow_color(color)
94
+ return self
95
+
96
+ def disable(self):
97
+ super().disable()
98
+ self.left_indicator.disable()
99
+ self.right_indicator.disable()
100
+ return self
101
+
102
+ def enable(self):
103
+ super().enable()
104
+ self.left_indicator.enable()
105
+ self.right_indicator.enable()
106
+ self._update_arrow_states()
107
+ return self
108
+
109
+ def set_tooltip_text(self, text) -> Self:
110
+ self.left_indicator.set_tooltip_text(text)
111
+ self.right_indicator.set_tooltip_text(text)
112
+ return super().set_tooltip_text(text)
113
+
114
+ def get_min_required_size(self) -> tuple[float, float]:
115
+ old_text = self.text_widget.get_text()
116
+ max_size = (0, 0)
117
+ for option in self.options:
118
+ self.text_widget.set_text(self.display_func(option))
119
+ size = self.text_widget.get_min_required_size()
120
+ max_size = (max(max_size[0], size[0]), max(max_size[1], size[1]))
121
+ self.text_widget.set_text(old_text)
122
+
123
+ # total_height = max(self.font_object.get_height() + 1, max_size[1] * 1.5)
124
+ total_height = max_size[1] if max_size[1] > 16 else max_size[1]*1.5
125
+ total_height += self.unpressed_relief
126
+ total_height += max(self.right_indicator.outline_width, self.left_indicator.outline_width)
127
+
128
+ total_width = total_height * 2 + max_size[0] + self.gap * 2
129
+
130
+ return self.expand_rect_with_padding((0, 0, total_width, total_height)).size
131
+
132
+ def _align_content(self):
133
+ padded = self.get_inner_rect()
134
+ indicator_height = padded.h
135
+ self.left_indicator.set_size((indicator_height, indicator_height))
136
+ self.right_indicator.set_size((indicator_height, indicator_height))
137
+
138
+ self.left_indicator.set_position(padded.left, None)
139
+ self.left_indicator.set_center(None, padded.centery)
140
+
141
+ right_size = self.right_indicator.rect.size
142
+ self.right_indicator.set_position(padded.right - right_size[0], None)
143
+ self.right_indicator.set_center(None, padded.centery)
144
+
145
+ def apply_post_updates(self, skip_draw=False):
146
+ super().apply_post_updates(skip_draw)
147
+ self._align_content()
148
+
149
+ def get_current_index(self) -> int:
150
+ return self.current_index
151
+
152
+ def set_allow_cycle(self, value: bool) -> Self:
153
+ if value != self.allow_cycle:
154
+ self.allow_cycle = value
155
+ self.dirty_surface = True
156
+ self._update_arrow_states()
157
+ return self
158
+
159
+ def set_text_color(self, color) -> Self:
160
+ super().set_text_color(color)
161
+ return self
162
+
163
+ def set_modify_callback(self, func: Callable[[Any, int], Any]) -> Self:
164
+ self.on_modify_callback = func
165
+ return self
166
+
167
+ def set_by_index(self, index: int) -> Self:
168
+ if self.allow_cycle:
169
+ index = index % len(self.options)
170
+ else:
171
+ index = max(min(len(self.options) - 1, index), 0)
172
+
173
+ if index == self.current_index:
174
+ return self
175
+
176
+ self.current_index = index
177
+ value = self.options[self.current_index]
178
+ display_text = self.display_func(value)
179
+ self.set_text(display_text)
180
+
181
+ self.synced_var.value = value
182
+
183
+ if self.on_modify_callback:
184
+ self.on_modify_callback(value, self.current_index)
185
+
186
+ if not self.allow_cycle:
187
+ if index == 0:
188
+ self.left_indicator.disable()
189
+ else:
190
+ self.left_indicator.enable()
191
+ if index == len(self.options) - 1:
192
+ self.right_indicator.disable()
193
+ else:
194
+ self.right_indicator.enable()
195
+
196
+ return self
197
+
198
+
199
+ def set_by_value(self, value: str) -> Self:
200
+ if not self.is_enabled:
201
+ return self
202
+ if value not in self.options:
203
+ return self
204
+ index = self.options.index(value)
205
+ self.set_by_index(index)
206
+ return self
207
+
208
+ def on_key_down(self, key: int,event) -> None:
209
+ if not self.is_enabled:
210
+ return
211
+ key_actions = {
212
+ pygame.K_RIGHT: self.right_indicator,
213
+ pygame.K_SPACE: self.right_indicator,
214
+ pygame.K_LEFT: self.left_indicator,
215
+ }
216
+ indicator = key_actions.get(key)
217
+ if indicator and indicator.visible and indicator.is_enabled:
218
+ indicator.on_click_down(1,event)
219
+ event.consumed = True
220
+
221
+ def on_key_up(self, key: int,event) -> None:
222
+ if not self.is_enabled:
223
+ return
224
+ key_actions = {
225
+ pygame.K_RIGHT: self.right_indicator,
226
+ pygame.K_SPACE: self.right_indicator,
227
+ pygame.K_LEFT: self.left_indicator,
228
+ }
229
+ indicator = key_actions.get(key)
230
+ if indicator and indicator.visible and indicator.is_enabled:
231
+ indicator.on_click_up(1,event)
232
+ event.consumed = True