batframework 1.0.8a6__py3-none-any.whl → 1.0.8a8__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 (70) hide show
  1. batFramework/__init__.py +51 -68
  2. batFramework/action.py +99 -126
  3. batFramework/actionContainer.py +9 -53
  4. batFramework/animatedSprite.py +82 -141
  5. batFramework/audioManager.py +26 -69
  6. batFramework/camera.py +69 -259
  7. batFramework/constants.py +54 -16
  8. batFramework/cutscene.py +29 -39
  9. batFramework/cutsceneBlocks.py +43 -36
  10. batFramework/debugger.py +48 -0
  11. batFramework/dynamicEntity.py +9 -18
  12. batFramework/easing.py +71 -0
  13. batFramework/entity.py +97 -48
  14. batFramework/gui/__init__.py +2 -10
  15. batFramework/gui/button.py +78 -9
  16. batFramework/gui/constraints.py +204 -0
  17. batFramework/gui/container.py +32 -174
  18. batFramework/gui/debugger.py +43 -131
  19. batFramework/gui/frame.py +19 -0
  20. batFramework/gui/image.py +20 -56
  21. batFramework/gui/indicator.py +21 -38
  22. batFramework/gui/interactiveWidget.py +13 -192
  23. batFramework/gui/label.py +74 -309
  24. batFramework/gui/layout.py +63 -231
  25. batFramework/gui/root.py +38 -134
  26. batFramework/gui/shape.py +57 -237
  27. batFramework/gui/toggle.py +51 -101
  28. batFramework/gui/widget.py +250 -358
  29. batFramework/manager.py +19 -52
  30. batFramework/particles.py +77 -0
  31. batFramework/scene.py +123 -281
  32. batFramework/sceneManager.py +116 -178
  33. batFramework/stateMachine.py +8 -11
  34. batFramework/time.py +58 -144
  35. batFramework/transition.py +124 -195
  36. batFramework/transitionManager.py +0 -0
  37. batFramework/triggerZone.py +1 -1
  38. batFramework/utils.py +147 -112
  39. batframework-1.0.8a8.dist-info/METADATA +53 -0
  40. batframework-1.0.8a8.dist-info/RECORD +42 -0
  41. {batframework-1.0.8a6.dist-info → batframework-1.0.8a8.dist-info}/WHEEL +1 -1
  42. batFramework/character.py +0 -27
  43. batFramework/easingController.py +0 -58
  44. batFramework/enums.py +0 -113
  45. batFramework/fontManager.py +0 -65
  46. batFramework/gui/clickableWidget.py +0 -220
  47. batFramework/gui/constraints/__init__.py +0 -1
  48. batFramework/gui/constraints/constraints.py +0 -815
  49. batFramework/gui/dialogueBox.py +0 -99
  50. batFramework/gui/draggableWidget.py +0 -40
  51. batFramework/gui/meter.py +0 -74
  52. batFramework/gui/radioButton.py +0 -84
  53. batFramework/gui/slider.py +0 -240
  54. batFramework/gui/style.py +0 -10
  55. batFramework/gui/styleManager.py +0 -48
  56. batFramework/gui/textInput.py +0 -247
  57. batFramework/object.py +0 -123
  58. batFramework/particle.py +0 -115
  59. batFramework/renderGroup.py +0 -67
  60. batFramework/resourceManager.py +0 -100
  61. batFramework/scrollingSprite.py +0 -114
  62. batFramework/sprite.py +0 -51
  63. batFramework/templates/__init__.py +0 -2
  64. batFramework/templates/character.py +0 -44
  65. batFramework/templates/states.py +0 -166
  66. batFramework/tileset.py +0 -46
  67. batframework-1.0.8a6.dist-info/LICENCE +0 -21
  68. batframework-1.0.8a6.dist-info/METADATA +0 -43
  69. batframework-1.0.8a6.dist-info/RECORD +0 -62
  70. {batframework-1.0.8a6.dist-info → batframework-1.0.8a8.dist-info}/top_level.txt +0 -0
@@ -1,249 +1,81 @@
1
1
  import batFramework as bf
2
2
  from .widget import Widget
3
- from .constraints.constraints import *
4
- from typing import Self, TYPE_CHECKING,override
5
- from abc import ABC,abstractmethod
6
- import pygame
3
+ from .constraints import *
4
+ from typing import Self
7
5
 
8
- if TYPE_CHECKING:
9
- from .container import Container
10
-
11
-
12
- class Layout(ABC):
13
- def __init__(self, parent: "Container" = None):
6
+ class Layout:
7
+ def __init__(self, parent: Widget=None):
14
8
  self.parent = parent
15
- self.child_constraints: list[Constraint] = []
16
- self.children_rect = pygame.FRect(0, 0, 0, 0)
17
-
18
- def set_child_constraints(self, *constraints) -> Self:
19
- self.child_constraints = list(constraints)
20
- self.notify_parent()
9
+ self.child_constraints : list[Constraint] = []
10
+
11
+ def set_child_constraints(self,*constraints)->Self:
12
+ self.child_constraints = constraints
13
+ self.arrange()
21
14
  return self
22
-
23
- def set_parent(self, parent: Widget):
15
+
16
+ def set_parent(self,parent:Widget):
24
17
  self.parent = parent
25
- self.notify_parent()
26
-
27
- def notify_parent(self) -> None:
28
- if self.parent:
29
- self.parent.dirty_children = True
30
-
31
- def arrange(self) -> None:
32
- return
33
-
34
- def get_raw_size(self) -> tuple[float, float]:
35
- """
36
- Returns the supposed size the container should have to encapsulate perfectly all of its widgets
37
- """
38
- return self.parent.rect.size if self.parent else (0, 0)
39
-
40
- def get_auto_size(self) -> tuple[float, float]:
41
- """
42
- Returns the final size the container should have (while keeping the the width and height if they are non-resizable)
43
- """
44
- target_size = list(self.get_raw_size())
45
- if not self.parent.autoresize_w:
46
- target_size[0] = self.parent.rect.w
47
- if not self.parent.autoresize_h:
48
- target_size[1] = self.parent.rect.h
49
- return target_size
50
-
51
- def focus_next_child(self) -> None:
52
- pass
53
-
54
- def focus_prev_child(self) -> None:
55
- pass
56
-
57
- def scroll_to_widget(self, widget: Widget) -> None:
58
- padded = self.parent.get_padded_rect()
59
- r = widget.rect
60
- if padded.contains(r):
61
- return
62
- clamped = r.clamp(padded)
63
- dx, dy = clamped.move(-r.x, -r.y).topleft
64
- self.parent.scroll_by((-dx, -dy))
65
-
66
- def handle_event(self, event):
67
- pass
68
-
18
+ self.arrange()
69
19
 
70
- class SingleAxisLayout(Layout):
71
- def focus_next_child(self) -> None:
72
- l = self.parent.get_interactive_children()
73
- self.parent.focused_index = min(self.parent.focused_index + 1, len(l) - 1)
74
- focused = l[self.parent.focused_index]
75
- focused.get_focus()
76
- self.scroll_to_widget(focused)
20
+ def arrange(self)->None:
21
+ raise NotImplementedError("Subclasses must implement arrange method")
77
22
 
78
- def focus_prev_child(self) -> None:
79
- l = self.parent.get_interactive_children()
80
- self.parent.focused_index = max(self.parent.focused_index - 1, 0)
81
- focused = l[self.parent.focused_index]
82
- focused.get_focus()
83
- self.scroll_to_widget(focused)
84
-
85
-
86
- class Column(SingleAxisLayout):
87
- def __init__(self, gap: int = 0, spacing: bf.spacing = bf.spacing.MANUAL):
23
+ class Column(Layout):
24
+ def __init__(self,gap:int=0,shrink:bool=False):
88
25
  super().__init__()
89
26
  self.gap = gap
90
- self.spacing = spacing
91
-
92
- def set_gap(self, value: float) -> Self:
93
- self.gap = value
94
- self.notify_parent()
95
- return self
96
-
97
- def set_spacing(self, spacing: bf.spacing) -> Self:
98
- self.spacing = spacing
99
- self.notify_parent()
100
- return self
27
+ self.shrink :bool = shrink
28
+
29
+ def arrange(self)->None:
30
+ if not self.parent or not self.parent.children : return
31
+ if self.shrink:
32
+ len_children = len(self.parent.children)
33
+ parent_height = sum(c.rect.h for c in self.parent.children)
34
+ parent_width = max(c.rect.w for c in self.parent.children)
35
+ if self.gap : parent_height += (len_children-1) * self.gap
36
+ # print(self.parent.to_string(),len_children,parent_height)
37
+ c = self.parent.get_constraint("height")
38
+ if not c or c.height != parent_height :
39
+ self.parent.add_constraint(ConstraintHeight(parent_height))
40
+ c = self.parent.get_constraint("width")
41
+ if not c or c.width != parent_width :
42
+ self.parent.add_constraint(ConstraintWidth(parent_width))
43
+ current_y = self.parent.rect.top
101
44
 
102
- def get_raw_size(self) -> tuple[float, float]:
103
- len_children = len(self.parent.children)
104
- if not len_children:
105
- return self.parent.rect.size
106
- parent_height = sum(c.get_min_required_size()[1] for c in self.parent.children)
107
- parent_width = max(c.get_min_required_size()[0] for c in self.parent.children)
108
- if self.gap:
109
- parent_height += (len_children - 1) * self.gap
110
- target_rect = self.parent.inflate_rect_by_padding(
111
- (0, 0, parent_width, parent_height)
112
- )
113
- return target_rect.size
114
-
115
- def get_auto_size(self) -> tuple[float, float]:
116
- target_size = list(self.get_raw_size())
117
- if not self.parent.autoresize_w:
118
- target_size[0] = self.parent.rect.w
119
- if not self.parent.autoresize_h:
120
- target_size[1] = self.parent.rect.h
121
- return target_size
122
-
123
- def arrange(self) -> None:
124
- if not self.parent or not self.parent.children:
125
- return
126
- if self.child_constraints:
127
- for child in self.parent.children:
128
- child.add_constraints(*self.child_constraints)
129
- self.child_rect = self.parent.get_padded_rect()
130
-
131
- if self.parent.autoresize_w or self.parent.autoresize_h:
132
- width, height = self.get_auto_size()
133
- if self.parent.rect.size != (width, height):
134
- self.parent.set_size((width, height))
135
- self.parent.build()
136
- self.arrange()
137
- return
138
- self.child_rect.move_ip(-self.parent.scroll.x, -self.parent.scroll.y)
139
- y = self.child_rect.top
140
45
  for child in self.parent.children:
141
- child.set_position(self.child_rect.x, y)
142
- y += child.get_min_required_size()[1] + self.gap
143
-
144
- def handle_event(self, event):
145
- if self.parent.autoresize_h or not self.parent.visible:
146
- return
147
-
148
- if not self.parent.children:
149
- return
150
-
151
- if event.type == pygame.MOUSEBUTTONDOWN:
152
- r = self.parent.get_root()
153
- if not r:
154
- return
155
-
156
- if self.parent.rect.collidepoint(
157
- r.drawing_camera.screen_to_world(pygame.mouse.get_pos())
158
- ):
159
- if event.button == 4:
160
- self.parent.scroll_by((0, -10))
161
- elif event.button == 5:
162
- self.parent.scroll_by((0, 10))
163
- else:
164
- return
165
- event.consumed = True
166
- self.parent.clamp_scroll()
167
-
168
-
169
- class Row(SingleAxisLayout):
170
- def __init__(self, gap: int = 0, spacing: bf.spacing = bf.spacing.MANUAL):
46
+ child.set_position(self.parent.rect.x,current_y)
47
+ current_y += child.rect.h + self.gap
48
+ for c in self.child_constraints:
49
+ if not child.has_constraint(c.name):
50
+ child.add_constraint(c)
51
+
52
+ class Row(Layout):
53
+ def __init__(self, gap: int = 0, shrink: bool = False):
171
54
  super().__init__()
172
55
  self.gap = gap
173
- self.spacing = spacing
174
-
175
- def set_gap(self, value: float) -> Self:
176
- self.gap = value
177
- self.notify_parent()
178
- return self
179
-
180
- def set_spacing(self, spacing: bf.spacing) -> Self:
181
- self.spacing = spacing
182
- self.notify_parent()
183
- return self
184
-
185
- def get_raw_size(self) -> tuple[float, float]:
186
- len_children = len(self.parent.children)
187
- if not len_children:
188
- return self.parent.rect.size
189
- parent_width = sum(c.get_min_required_size()[0] for c in self.parent.children)
190
- parent_height = max(c.get_min_required_size()[1] for c in self.parent.children)
191
- if self.gap:
192
- parent_width += (len_children - 1) * self.gap
193
- target_rect = self.parent.inflate_rect_by_padding(
194
- (0, 0, parent_width, parent_height)
195
- )
196
-
197
- return target_rect.size
198
-
199
- def get_auto_size(self) -> tuple[float, float]:
200
- target_size = list(self.get_raw_size())
201
- if not self.parent.autoresize_w:
202
- target_size[0] = self.parent.rect.w
203
- if not self.parent.autoresize_h:
204
- target_size[1] = self.parent.rect.h
205
- return target_size
56
+ self.shrink = shrink
206
57
 
207
58
  def arrange(self) -> None:
208
- if not self.parent or not self.parent.children:
59
+ if not self.parent:
209
60
  return
210
- if self.child_constraints:
211
- for child in self.parent.children:
212
- child.add_constraints(*self.child_constraints)
213
- self.child_rect = self.parent.get_padded_rect()
214
-
215
- if self.parent.autoresize_w or self.parent.autoresize_h:
216
- width, height = self.get_auto_size()
217
- if self.parent.rect.size != (width, height):
218
- self.parent.set_size((width, height))
219
- self.parent.build()
220
- self.arrange()
221
- return
222
- self.child_rect.move_ip(-self.parent.scroll.x, -self.parent.scroll.y)
223
- x = self.child_rect.left
61
+ if self.shrink and self.parent.children:
62
+ len_children = len(self.parent.children)
63
+ parent_width = sum(c.rect.w for c in self.parent.children)
64
+ parent_height = max(c.rect.h for c in self.parent.children)
65
+ if self.gap:
66
+ parent_width += (len_children - 1) * self.gap
67
+
68
+ c = self.parent.get_constraint("width")
69
+ if not c or c.width != parent_width:
70
+ self.parent.add_constraint(ConstraintWidth(parent_width))
71
+ c = self.parent.get_constraint("height")
72
+ if not c or c.height != parent_height:
73
+ self.parent.add_constraint(ConstraintHeight(parent_height))
74
+
75
+ current_x = self.parent.rect.left
224
76
  for child in self.parent.children:
225
- child.set_position(x, self.child_rect.y)
226
- x += child.get_min_required_size()[0] + self.gap
227
-
228
- def handle_event(self, event):
229
- if self.parent.autoresize_w or not self.parent.visible:
230
- return
231
-
232
- if not self.parent.children:
233
- return
234
-
235
- if event.type == pygame.MOUSEBUTTONDOWN:
236
- r = self.parent.get_root()
237
- if not r:
238
- return
239
- if self.parent.rect.collidepoint(
240
- r.drawing_camera.screen_to_world(pygame.mouse.get_pos())
241
- ):
242
- if event.button == 4:
243
- self.parent.scroll_by((-10, 0))
244
- elif event.button == 5:
245
- self.parent.scroll_by((10, 0))
246
- else:
247
- return
248
- event.consumed = True
249
- self.parent.clamp_scroll()
77
+ child.set_position(current_x,self.parent.rect.y)
78
+ current_x += child.rect.w + self.gap
79
+ for c in self.child_constraints:
80
+ if not child.has_constraint(c.name):
81
+ child.add_constraint(c)
batFramework/gui/root.py CHANGED
@@ -2,155 +2,59 @@ import batFramework as bf
2
2
  from .interactiveWidget import InteractiveWidget
3
3
  from .widget import Widget
4
4
  import pygame
5
- from typing import Self
6
- import sys
7
-
8
5
 
9
6
  class Root(InteractiveWidget):
10
- def __init__(self, camera) -> None:
7
+ def __init__(self):
11
8
  super().__init__()
12
- self.is_root = True
13
- self.drawing_camera: bf.Camera = camera
14
- self.visible = False
9
+ self.surface = None
10
+ self.set_root()
15
11
  self.rect.size = pygame.display.get_surface().get_size()
16
- self.focused: InteractiveWidget | None = self
17
- self.hovered: Widget | None = self
18
- self.set_debug_color("yellow")
19
- self.set_render_order(sys.maxsize)
20
- self.clip_children = False
21
-
22
- def __str__(self) -> str:
23
- return "Root"
12
+ self.focused : InteractiveWidget = self
13
+ self.hovered : Widget|None = self
14
+ self.set_debug_color("purple")
24
15
 
25
- def set_parent_scene(self, parent_scene: bf.Scene) -> Self:
26
- bf.StyleManager().register_widget(self)
27
- return super().set_parent_scene(parent_scene)
16
+ def to_string(self)->str:
17
+ return "ROOT"
28
18
 
29
- def get_focused(self) -> Widget | None:
19
+ def get_focused(self)->Widget|None:
30
20
  return self.focused
31
21
 
32
- def get_hovered(self) -> Widget | None:
22
+ def get_hovered(self)->Widget|None:
33
23
  return self.hovered
24
+
25
+ def to_string_id(self)->str:
26
+ return "ROOT"
34
27
 
35
- def clear_focused(self) -> None:
36
- self.focus_on(None)
37
-
38
- def clear_hovered(self) -> None:
39
- if isinstance(self.hovered, InteractiveWidget):
40
- self.hovered.on_exit()
41
- self.hovered = None
42
-
43
- def get_debug_outlines(self):
44
- yield (self.rect, self.debug_color)
45
- for child in self.children:
46
- yield from child.get_debug_outlines()
47
-
48
- def focus_on(self, widget: InteractiveWidget | None) -> None:
49
- if widget == self.focused:
50
- return
51
- if widget and not widget.allow_focus_to_self():
52
- return
53
- if self.focused is not None:
28
+ def focus_on(self,widget:InteractiveWidget)->None:
29
+ if self.focused is not None:
54
30
  self.focused.on_lose_focus()
55
- if widget is None:
31
+ if widget is None :
56
32
  self.focused = self
57
33
  return
58
- self.focused = widget
34
+ self.focused= widget
59
35
  self.focused.on_get_focus()
60
36
 
61
- def get_by_tags(self, *tags) -> list[Widget]:
62
- res = []
63
-
64
- def getter(w: Widget):
65
- nonlocal res
66
- if any(t in w.tags for t in tags):
67
- res.append(w)
68
-
69
- self.visit(getter)
70
- return res
71
-
72
- def focus_next_tab(self, widget):
73
- return True
74
-
75
- def focus_prev_tab(self, widget):
76
- return True
77
-
78
- def get_by_uid(self, uid: int) -> "Widget":
79
- def helper(w: "Widget", uid: int) -> "Widget":
80
- if w.uid == uid:
81
- return w
82
- for child in w.children:
83
- res = helper(child, uid)
84
- if res is not None:
85
- return res
86
- return None
87
-
88
- return helper(self, uid)
89
-
90
- def set_size(self, size: tuple[float, float], force: bool = False) -> "Root":
91
- if not force:
92
- return self
93
- self.rect.size = size
94
- # self.build(resolve_constraints=True)
37
+ def set_size(self,width:float,height:float,force:bool=False)->"Root":
38
+ if not force : return self
39
+ self.rect.size = width,height
40
+ self.build(apply_constraints=True)
95
41
  return self
96
-
97
- def do_handle_event(self, event):
98
- if not self.parent_scene.get_sharedVar("player_has_control"):
99
- return
100
- if self.focused:
101
- if event.type == pygame.KEYDOWN:
102
- if self.focused.on_key_down(event.key):
103
- event.consumed = True
104
- elif event.type == pygame.KEYUP:
105
- if self.focused.on_key_up(event.key):
106
- event.consumed = True
107
-
108
- if not self.hovered or (not isinstance(self.hovered, InteractiveWidget)):
109
- return
110
-
111
- if event.type == pygame.MOUSEBUTTONDOWN:
112
- if self.hovered.on_click_down(event.button):
113
- event.consumed = True
114
-
115
- elif event.type == pygame.MOUSEBUTTONUP:
116
- if self.hovered.on_click_up(event.button):
117
- event.consumed = True
118
-
119
- def do_on_click_down(self, button: int) -> None:
120
- if button == 1:
121
- self.clear_focused()
122
-
123
- def top_at(self, x: float | int, y: float | int) -> "None|Widget":
124
- if self.children:
125
- for child in reversed(self.children):
126
- r = child.top_at(x, y)
127
- if r is not None:
128
- return r
129
- return self if self.rect.collidepoint(x, y) else None
130
-
131
- def update(self, dt: float) -> None:
42
+
43
+ def build(self,apply_constraints:bool=False)->None:
44
+ if apply_constraints : self.apply_all_constraints()
45
+ for child in self.children :
46
+ child.build()
47
+
48
+ def do_handle_event(self,event):
49
+ if event.type == pygame.VIDEORESIZE:
50
+ self.set_size(event.w,event.h,force=True)
51
+ return True
52
+ return False
53
+
54
+ def update(self,dt:float)->None:
132
55
  super().update(dt)
133
- if not self.parent_scene.get_sharedVar("player_has_control",True):
134
- return
135
- old = self.hovered
136
- transposed = self.drawing_camera.screen_to_world(pygame.mouse.get_pos())
137
- self.hovered = self.top_at(*transposed) if self.top_at(*transposed) else None
138
- if old == self.hovered and isinstance(self.hovered, InteractiveWidget):
139
- self.hovered.on_mouse_motion(*transposed)
140
- return
141
- if old and isinstance(old, InteractiveWidget):
142
- old.on_exit()
143
- if self.hovered and isinstance(self.hovered, InteractiveWidget):
144
- self.hovered.on_enter()
56
+ self.hovered = self.top_at(*pygame.mouse.get_pos()) if self.top_at(*pygame.mouse.get_pos()) else None
57
+
145
58
 
146
- def draw(self, camera: bf.Camera) -> None:
147
- super().draw(camera)
148
- if not self.parent_scene.get_sharedVar("player_has_control"):
149
- return
150
- if (
151
- self.parent_scene
152
- and self.parent_scene.active
153
- and self.focused
154
- and self.focused != self
155
- ):
156
- self.focused.draw_focused(camera)
59
+
60
+