batframework 1.0.9a10__py3-none-any.whl → 1.0.10__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 (76) hide show
  1. batFramework/__init__.py +53 -76
  2. batFramework/action.py +99 -126
  3. batFramework/actionContainer.py +9 -53
  4. batFramework/animatedSprite.py +114 -56
  5. batFramework/audioManager.py +36 -82
  6. batFramework/camera.py +69 -263
  7. batFramework/constants.py +53 -29
  8. batFramework/cutscene.py +109 -243
  9. batFramework/cutsceneBlocks.py +176 -0
  10. batFramework/debugger.py +48 -0
  11. batFramework/dynamicEntity.py +9 -16
  12. batFramework/easing.py +71 -0
  13. batFramework/entity.py +85 -92
  14. batFramework/gui/__init__.py +3 -14
  15. batFramework/gui/button.py +78 -12
  16. batFramework/gui/constraints.py +204 -0
  17. batFramework/gui/container.py +31 -183
  18. batFramework/gui/debugger.py +43 -126
  19. batFramework/gui/frame.py +19 -0
  20. batFramework/gui/image.py +20 -55
  21. batFramework/gui/indicator.py +22 -95
  22. batFramework/gui/interactiveWidget.py +12 -229
  23. batFramework/gui/label.py +77 -311
  24. batFramework/gui/layout.py +66 -411
  25. batFramework/gui/root.py +35 -203
  26. batFramework/gui/shape.py +57 -247
  27. batFramework/gui/toggle.py +48 -114
  28. batFramework/gui/widget.py +243 -457
  29. batFramework/manager.py +29 -113
  30. batFramework/particles.py +77 -0
  31. batFramework/scene.py +217 -22
  32. batFramework/sceneManager.py +129 -161
  33. batFramework/stateMachine.py +8 -11
  34. batFramework/time.py +75 -0
  35. batFramework/transition.py +124 -129
  36. batFramework/transitionManager.py +0 -0
  37. batFramework/triggerZone.py +4 -4
  38. batFramework/utils.py +144 -266
  39. {batframework-1.0.9a10.dist-info → batframework-1.0.10.dist-info}/METADATA +24 -17
  40. batframework-1.0.10.dist-info/RECORD +43 -0
  41. batFramework/animation.py +0 -77
  42. batFramework/baseScene.py +0 -240
  43. batFramework/cutsceneManager.py +0 -34
  44. batFramework/drawable.py +0 -77
  45. batFramework/easingController.py +0 -58
  46. batFramework/enums.py +0 -135
  47. batFramework/fontManager.py +0 -65
  48. batFramework/gui/animatedLabel.py +0 -89
  49. batFramework/gui/clickableWidget.py +0 -245
  50. batFramework/gui/constraints/__init__.py +0 -1
  51. batFramework/gui/constraints/constraints.py +0 -980
  52. batFramework/gui/draggableWidget.py +0 -44
  53. batFramework/gui/meter.py +0 -96
  54. batFramework/gui/radioButton.py +0 -35
  55. batFramework/gui/selector.py +0 -250
  56. batFramework/gui/slider.py +0 -397
  57. batFramework/gui/style.py +0 -10
  58. batFramework/gui/styleManager.py +0 -54
  59. batFramework/gui/syncedVar.py +0 -49
  60. batFramework/gui/textInput.py +0 -306
  61. batFramework/gui/tooltip.py +0 -30
  62. batFramework/particle.py +0 -118
  63. batFramework/propertyEaser.py +0 -79
  64. batFramework/renderGroup.py +0 -34
  65. batFramework/resourceManager.py +0 -130
  66. batFramework/sceneLayer.py +0 -138
  67. batFramework/scrollingSprite.py +0 -115
  68. batFramework/sprite.py +0 -51
  69. batFramework/templates/__init__.py +0 -1
  70. batFramework/templates/controller.py +0 -97
  71. batFramework/tileset.py +0 -46
  72. batFramework/timeManager.py +0 -213
  73. batframework-1.0.9a10.dist-info/RECORD +0 -67
  74. {batframework-1.0.9a10.dist-info → batframework-1.0.10.dist-info}/LICENSE +0 -0
  75. {batframework-1.0.9a10.dist-info → batframework-1.0.10.dist-info}/WHEEL +0 -0
  76. {batframework-1.0.9a10.dist-info → batframework-1.0.10.dist-info}/top_level.txt +0 -0
@@ -1,44 +0,0 @@
1
- from .interactiveWidget import InteractiveWidget
2
- import batFramework as bf
3
- import pygame
4
-
5
-
6
- class DraggableWidget(InteractiveWidget):
7
- def __init__(self, *args, **kwargs) -> None:
8
- self.drag_start = None
9
- self.offset = None
10
- self.click_mask = [True,False,False,False,False]
11
- self.is_dragged : bool = False # the widget is following the mouse AND the mouse is in the widget
12
- self.is_dragged_outside : bool = False # the widget is following the mouse BUT the mouse is NOT in the widget
13
- super().__init__(*args, **kwargs)
14
-
15
- def set_click_mask(self,b1=0,b2=0,b3=0,b4=0,b5=0):
16
- self.click_mask = [b1,b2,b3,b4,b5]
17
-
18
- def on_click_down(self, button):
19
- super().on_click_down(button)
20
- return any(i==j and i== True for i,j in zip(self.is_clicked_down,self.click_mask))
21
-
22
- def do_on_drag(
23
- self, drag_start_pos: tuple[float, float], drag_end_pos: tuple[float, float]
24
- ) -> None:
25
- new_pos = drag_end_pos[0] - self.offset[0], drag_end_pos[1] - self.offset[1]
26
- if self.rect.topleft != new_pos:
27
- self.set_position(*new_pos)
28
-
29
- def update(self, dt: float):
30
- self.is_dragged_outside = any(i==j and i== True for i,j in zip(pygame.mouse.get_pressed(5),self.click_mask))
31
- self.is_dragged = any(i==j and i== True for i,j in zip(self.is_clicked_down,self.click_mask))
32
-
33
- if self.is_dragged and self.is_dragged_outside:
34
- x, y = self.parent_layer.camera.screen_to_world(pygame.mouse.get_pos())
35
- if self.drag_start == None:
36
- self.offset = x - self.rect.x, y - self.rect.y
37
- self.drag_start = x, y
38
- else:
39
- self.do_on_drag(self.drag_start, (x, y))
40
- else:
41
- self.drag_start = None
42
- self.offset = None
43
- self.is_clicked_down = [False]*5
44
- super().update(dt)
batFramework/gui/meter.py DELETED
@@ -1,96 +0,0 @@
1
- import math
2
- import batFramework as bf
3
- from .shape import Shape
4
- from typing import Self
5
-
6
-
7
- def custom_top_at(self, x, y):
8
- if Shape.top_at(self, x, y) == self:
9
- return self.parent
10
- return None
11
-
12
- class Meter(Shape):
13
- def __init__(self, min_value: float = 0, max_value: float = 1, step: float = 0.1):
14
- super().__init__()
15
- self.min_value, self.max_value = min_value, max_value
16
- self.step = step
17
- self.snap: bool = False
18
- self.value = self.max_value
19
- self.set_debug_color("pink")
20
-
21
- def __str__(self) -> str:
22
- return "Meter"
23
-
24
- def set_step(self, step: float) -> Self:
25
- self.step = step
26
- self.set_value(self.value)
27
- return self
28
-
29
- def set_range(self, range_min: float, range_max: float) -> Self:
30
- if range_min >= range_max:
31
- return self
32
- self.min_value = range_min
33
- self.max_value = range_max
34
- self.dirty_shape = True
35
-
36
- def set_value(self, value: float) -> Self:
37
- value = max(self.min_value, min(self.max_value, value))
38
- value = round(value / self.step) * self.step
39
- self.value = round(value,10)
40
- self.dirty_shape = True
41
- return self
42
-
43
- def get_value(self) -> float:
44
- return self.value
45
-
46
- def get_range(self) -> float:
47
- return self.max_value - self.min_value
48
-
49
- def get_ratio(self) -> float:
50
- return (self.value-self.min_value) / (self.max_value - self.min_value)
51
-
52
-
53
- class BarMeter(Meter):
54
- def __init__(self, min_value: float = 0, max_value: float = 1, step: float = 0.1):
55
- super().__init__(min_value, max_value, step)
56
- self.axis: bf.axis = bf.axis.HORIZONTAL
57
- self.content = Shape((0, 0)).set_color(bf.color.BLUE)
58
- self.content.set_debug_color("cyan")
59
- self.content.top_at = lambda x, y: custom_top_at(self.content, x, y)
60
- self.add(self.content)
61
- self.set_padding(4)
62
- self.set_color("gray20")
63
- self.set_outline_width(1)
64
- self.set_outline_color(bf.color.BLACK)
65
- self.set_debug_color("pink")
66
-
67
- def __str__(self) -> str:
68
- return "BarMeter"
69
-
70
- def set_axis(self,axis:bf.axis)->Self:
71
- self.axis = axis
72
- self.dirty_shape = True
73
- return self
74
-
75
- def _build_content(self) -> None:
76
- padded = self.get_inner_rect()
77
- ratio = self.get_ratio()
78
-
79
- self.content.set_border_radius(*[round(b/2) for b in self.border_radius])
80
-
81
- if self.axis == bf.axis.HORIZONTAL:
82
- width = (padded.width- self.outline_width *2) * ratio
83
- self.content.set_size((width, padded.height - self.outline_width*2))
84
- self.content.rect.topleft = padded.move(self.outline_width, self.outline_width).topleft
85
-
86
- else: # vertical
87
- height = (padded.height - self.outline_width * 2) * ratio
88
- self.content.set_size((padded.width - self.outline_width * 2, height))
89
- self.content.rect.bottomleft = (
90
- padded.move(self.outline_width,-self.outline_width).bottomleft
91
- )
92
- self.content.rect.height = math.ceil(self.content.rect.height)
93
-
94
- def build(self) -> None:
95
- self._build_content()
96
- super().build()
@@ -1,35 +0,0 @@
1
- import batFramework as bf
2
- from typing import Self, Any, Callable
3
- from .toggle import Toggle
4
- from .syncedVar import SyncedVar
5
-
6
-
7
- class RadioButton(Toggle):
8
- def __init__(self, text: str = "", radio_value: Any = None, synced_var: SyncedVar = None) -> None:
9
- super().__init__(text, None, False)
10
- self.radio_value: Any = radio_value if radio_value is not None else text if text else None
11
- self.synced_var : SyncedVar = None
12
- if synced_var:
13
- self.link(synced_var)
14
-
15
- def link(self,synced_var:SyncedVar)->Self:
16
- self.synced_var = synced_var
17
- synced_var.bind_widget(self,self._update_state)
18
- return self
19
-
20
- def __str__(self) -> str:
21
- return f"RadioButton({self.radio_value}|{'Active' if self.value else 'Inactive'})"
22
-
23
- def set_radio_value(self, value: Any) -> Self:
24
- self.radio_value = value
25
- return self
26
-
27
- def set_value(self, value : bool, do_callback=False):
28
- super().set_value(value, do_callback)
29
- if value : self.synced_var.value = self.radio_value
30
-
31
- def _update_state(self, synced_value: Any) -> None:
32
- """
33
- Updates the state of the RadioButton based on the synced variable's value.
34
- """
35
- self.set_value(self.radio_value == synced_value, False)
@@ -1,250 +0,0 @@
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
-