batframework 1.0.9a11__py3-none-any.whl → 1.0.9a13__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 +3 -11
  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.9a13.dist-info}/LICENSE +20 -20
  69. {batframework-1.0.9a11.dist-info → batframework-1.0.9a13.dist-info}/METADATA +24 -17
  70. batframework-1.0.9a13.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.9a13.dist-info}/WHEEL +0 -0
  73. {batframework-1.0.9a11.dist-info → batframework-1.0.9a13.dist-info}/top_level.txt +0 -0
batFramework/gui/root.py CHANGED
@@ -1,228 +1,228 @@
1
- import batFramework as bf
2
- from .interactiveWidget import InteractiveWidget
3
- from .widget import Widget
4
- import pygame
5
- from typing import Self
6
- import sys
7
-
8
-
9
- class Root(InteractiveWidget):
10
- def __init__(self, camera) -> None:
11
- super().__init__()
12
- self.is_root = True
13
- self.drawing_camera: bf.Camera = camera
14
- self.visible = False
15
- self.rect.size = pygame.display.get_surface().get_size()
16
- self.focused: InteractiveWidget | None = self
17
- self.hovered: Widget | None = self
18
- self.clip_children = False
19
- self.set_debug_color("yellow")
20
-
21
- self.show_tooltip : bool = True
22
- self.tooltip = bf.gui.ToolTip("").set_visible(False)
23
- self.add(self.tooltip)
24
-
25
- def toggle_tooltip(self,value:bool)->Self:
26
- self.show_tooltip = value
27
- return self
28
-
29
- def __str__(self) -> str:
30
- return "Root"
31
-
32
- def to_ascii_tree(self) -> str:
33
- def f(w, depth):
34
- prefix = " " * (depth * 4) + ("└── " if depth > 0 else "")
35
- children = "\n".join(f(c, depth + 1) for c in w.children) if w.children else ""
36
- return f"{prefix}{str(w)}\n{children}"
37
- return f(self, 0)
38
-
39
- def set_parent_scene(self, parent_scene: bf.Scene) -> Self:
40
- return super().set_parent_scene(parent_scene)
41
-
42
- def get_focused(self) -> Widget | None:
43
- return self.focused
44
-
45
- def get_hovered(self) -> Widget | None:
46
- return self.hovered
47
-
48
- def clear_focused(self) -> None:
49
- self.focus_on(None)
50
-
51
- def clear_hovered(self) -> None:
52
- if isinstance(self.hovered, InteractiveWidget):
53
- self.hovered.on_exit()
54
- self.hovered = None
55
-
56
- def get_debug_outlines(self):
57
- yield (self.rect, self.debug_color)
58
- for child in self.children:
59
- yield from child.get_debug_outlines()
60
-
61
- def focus_on(self, widget: InteractiveWidget | None) -> None:
62
- if widget == self.focused:
63
- return
64
- if widget and not widget.allow_focus_to_self():
65
- return
66
- if self.focused is not None:
67
- self.focused.on_lose_focus()
68
- if widget is None:
69
- self.focused = self
70
- return
71
- self.focused = widget
72
- self.focused.on_get_focus()
73
-
74
- def get_by_tags(self, *tags) -> list[Widget]:
75
- res = []
76
-
77
- def getter(w: Widget):
78
- nonlocal res
79
- if any(t in w.tags for t in tags):
80
- res.append(w)
81
-
82
- self.visit(getter)
83
- return res
84
-
85
- def focus_next_tab(self, widget):
86
- return
87
-
88
- def focus_prev_tab(self, widget):
89
- return
90
-
91
- def get_by_uid(self, uid: int) -> "Widget":
92
- def helper(w: "Widget", uid: int) -> "Widget":
93
- if w.uid == uid:
94
- return w
95
- for child in w.children:
96
- res = helper(child, uid)
97
- if res is not None:
98
- return res
99
- return None
100
-
101
- return helper(self, uid)
102
-
103
- def set_size(self, size: tuple[float, float], force: bool = False) -> "Root":
104
- if not force:
105
- return self
106
- self.rect.size = size
107
- self.dirty_shape = True
108
- self.dirty_size_constraints = True
109
- return self
110
-
111
- def process_event(self,event):
112
- if not event.consumed : self.do_handle_event_early(event)
113
- if not event.consumed : super().process_event(event)
114
-
115
- def do_handle_event_early(self, event):
116
- if event.type == pygame.VIDEORESIZE and not pygame.SCALED & bf.const.FLAGS:
117
- self.set_size((event.w,event.h),force=True)
118
- if self.focused:
119
- if event.type == pygame.KEYDOWN:
120
- event.consumed = self.focused.on_key_down(event.key)
121
- if not event.consumed :
122
- event.consumed = self._handle_alt_tab(event.key)
123
- elif event.type == pygame.KEYUP:
124
- event.consumed = self.focused.on_key_up(event.key)
125
-
126
- if not self.hovered or (not isinstance(self.hovered, InteractiveWidget)):
127
- event.consumed = True
128
- return
129
-
130
- if event.type == pygame.MOUSEBUTTONDOWN:
131
- event.consumed = self.hovered.on_click_down(event.button)
132
-
133
- elif event.type == pygame.MOUSEBUTTONUP:
134
- event.consumed = self.hovered.on_click_up(event.button)
135
-
136
- def do_on_click_down(self, button: int) -> None:
137
- if button == 1:
138
- self.clear_focused()
139
-
140
- def top_at(self, x: float | int, y: float | int) -> "None|Widget":
141
- if self.children:
142
- for child in reversed(self.children):
143
- r = child.top_at(x, y)
144
- if r is not None:
145
- return r
146
- return self if self.rect.collidepoint(x, y) else None
147
-
148
- def update(self, dt: float) -> None:
149
- super().update(dt)
150
- self.update_tree()
151
-
152
- mouse_screen = pygame.mouse.get_pos()
153
- mouse_world = self.drawing_camera.screen_to_world(mouse_screen)
154
- prev_hovered = self.hovered
155
- self.hovered = self.top_at(*mouse_world) or None
156
-
157
- # Tooltip logic
158
- if self.hovered and self.hovered.tooltip_text:
159
- self.tooltip.set_text(self.hovered.tooltip_text)
160
-
161
- tooltip_size = self.tooltip.get_min_required_size()
162
- screen_w, screen_h = self.drawing_camera.rect.size
163
- tooltip_x, tooltip_y = self.drawing_camera.world_to_screen_point(mouse_world)
164
-
165
- tooltip_x = min(tooltip_x, screen_w - tooltip_size[0])
166
- tooltip_y = min(tooltip_y, screen_h - tooltip_size[1])
167
- tooltip_x = max(0, tooltip_x)
168
- tooltip_y = max(0, tooltip_y)
169
-
170
- self.tooltip.set_position(tooltip_x, tooltip_y)
171
- self.tooltip.fade_in()
172
- else:
173
- self.tooltip.fade_out()
174
-
175
- if self.hovered == prev_hovered:
176
- if isinstance(self.hovered, InteractiveWidget):
177
- self.hovered.on_mouse_motion(*mouse_world)
178
- return
179
-
180
- if isinstance(prev_hovered, InteractiveWidget):
181
- prev_hovered.on_exit()
182
- if isinstance(self.hovered, InteractiveWidget):
183
- self.hovered.on_enter()
184
-
185
-
186
- def _handle_alt_tab(self,key):
187
- if self.focused is None:
188
- return False
189
- if key != pygame.K_TAB:
190
- return False
191
- keys = pygame.key.get_pressed()
192
- if keys[pygame.K_LSHIFT] or keys[pygame.K_RSHIFT]:
193
- self.focused.focus_prev_tab(self.focused)
194
- else:
195
- self.focused.focus_next_tab(self.focused)
196
- return True
197
-
198
- def update_tree(self):
199
- # print("START updating tree")
200
- self.apply_updates("pre")
201
- self.apply_updates("post")
202
-
203
- self.apply_updates("pre")
204
- self.apply_updates("post")
205
-
206
- # print("END updating tree")
207
-
208
- def apply_pre_updates(self):
209
- return
210
-
211
- def apply_post_updates(self, skip_draw = False):
212
- return
213
-
214
- def draw(self, camera: bf.Camera) -> None:
215
- super().draw(camera)
216
- if (
217
- self.parent_scene
218
- and self.parent_scene.active
219
- and self.focused
220
- and self.focused != self
221
- ):
222
- clip:bool =self.focused.parent and self.focused.parent.clip_children
223
- if clip:
224
- old_clip = camera.surface.get_clip()
225
- camera.surface.set_clip(camera.world_to_screen(self.focused.parent.rect))
226
- if clip:
227
- camera.surface.set_clip(old_clip)
228
- self.focused.draw_focused(camera)
1
+ import batFramework as bf
2
+ from .interactiveWidget import InteractiveWidget
3
+ from .widget import Widget
4
+ import pygame
5
+ from typing import Self
6
+ import sys
7
+
8
+
9
+ class Root(InteractiveWidget):
10
+ def __init__(self, camera) -> None:
11
+ super().__init__()
12
+ self.is_root = True
13
+ self.drawing_camera: bf.Camera = camera
14
+ self.visible = False
15
+ self.rect.size = pygame.display.get_surface().get_size()
16
+ self.focused: InteractiveWidget | None = self
17
+ self.hovered: Widget | None = self
18
+ self.clip_children = False
19
+ self.set_debug_color("yellow")
20
+
21
+ self.show_tooltip : bool = True
22
+ self.tooltip = bf.gui.ToolTip("").set_visible(False)
23
+ self.add(self.tooltip)
24
+ self.set_click_pass_through(True)
25
+
26
+ def set_show_tooltip(self,value:bool)->Self:
27
+ self.show_tooltip = value
28
+ return self
29
+
30
+ def __str__(self) -> str:
31
+ return "Root"
32
+
33
+ def to_ascii_tree(self) -> str:
34
+ def f(w:Widget, depth):
35
+ prefix = " " * (depth * 4) + ("L__ " if depth > 0 else "")
36
+ children = "\n".join(f(c, depth + 1) for c in w.children) if w.children else ""
37
+ return f"{prefix}{str(w)}\n{children}"
38
+ return f(self, 0)
39
+
40
+ def set_parent_scene(self, parent_scene: bf.Scene) -> Self:
41
+ return super().set_parent_scene(parent_scene)
42
+
43
+ def get_focused(self) -> Widget | None:
44
+ return self.focused
45
+
46
+ def get_hovered(self) -> Widget | None:
47
+ return self.hovered
48
+
49
+ def clear_focused(self) -> None:
50
+ self.focus_on(None)
51
+
52
+ def clear_hovered(self) -> None:
53
+ if isinstance(self.hovered, InteractiveWidget):
54
+ self.hovered.on_exit()
55
+ self.hovered = None
56
+
57
+ def get_debug_outlines(self):
58
+ yield (self.rect, self.debug_color)
59
+ for child in self.children:
60
+ yield from child.get_debug_outlines()
61
+
62
+ def focus_on(self, widget: InteractiveWidget | None) -> None:
63
+ if widget == self.focused:
64
+ return
65
+ if widget and not widget.allow_focus_to_self():
66
+ return
67
+ if self.focused is not None:
68
+ self.focused.on_lose_focus()
69
+ if widget is None:
70
+ self.focused = self
71
+ return
72
+ self.focused = widget
73
+ self.focused.on_get_focus()
74
+
75
+ def get_by_tags(self, *tags) -> list[Widget]:
76
+ res = []
77
+
78
+ def getter(w: Widget):
79
+ nonlocal res
80
+ if any(t in w.tags for t in tags):
81
+ res.append(w)
82
+
83
+ self.visit(getter)
84
+ return res
85
+
86
+ def focus_next_tab(self, widget):
87
+ return
88
+
89
+ def focus_prev_tab(self, widget):
90
+ return
91
+
92
+ def get_by_uid(self, uid: int) -> "Widget":
93
+ def helper(w: "Widget", uid: int) -> "Widget":
94
+ if w.uid == uid:
95
+ return w
96
+ for child in w.children:
97
+ res = helper(child, uid)
98
+ if res is not None:
99
+ return res
100
+ return None
101
+
102
+ return helper(self, uid)
103
+
104
+ def set_size(self, size: tuple[float, float], force: bool = False) -> "Root":
105
+ if not force:
106
+ return self
107
+ self.rect.size = size
108
+ self.dirty_shape = True
109
+ self.dirty_size_constraints = True
110
+ return self
111
+
112
+ def process_event(self,event):
113
+ if not event.consumed : self.handle_event_early(event)
114
+ super().process_event(event)
115
+
116
+ def handle_event_early(self, event):
117
+ if event.type == pygame.VIDEORESIZE and not pygame.SCALED & bf.const.FLAGS:
118
+ self.set_size((event.w,event.h),force=True)
119
+ return
120
+
121
+ def handle_event(self, event):
122
+ super().handle_event(event)
123
+ if not event.consumed :
124
+ if event.type == pygame.KEYDOWN and event.key==pygame.K_TAB:
125
+ self.tab_focus(event)
126
+
127
+ def tab_focus(self,event=None):
128
+ if self.focused is None:
129
+ return
130
+ keys = pygame.key.get_pressed()
131
+ if keys[pygame.K_LSHIFT] or keys[pygame.K_RSHIFT]:
132
+ self.focused.focus_prev_tab(self.focused)
133
+ else:
134
+ self.focused.focus_next_tab(self.focused)
135
+ if event :event.consumed = True
136
+
137
+
138
+ def on_click_down(self, button: int,event) -> None:
139
+ if button == 1:
140
+ self.clear_focused()
141
+ super().on_click_down(button,event)
142
+
143
+ def top_at(self, x: float | int, y: float | int) -> "None|Widget":
144
+ for child in reversed(self.children):
145
+ r = child.top_at(x, y)
146
+ if r is not None:
147
+ return r
148
+ return self if self.rect.collidepoint(x, y) else None
149
+
150
+ def update(self, dt: float) -> None:
151
+ super().update(dt)
152
+ self.update_tree()
153
+
154
+ mouse_world = self.drawing_camera.get_mouse_pos()
155
+ prev_hovered = self.hovered
156
+ self.hovered = self.top_at(*mouse_world)
157
+
158
+ if (self.hovered and self.hovered.tooltip_text and self.show_tooltip):
159
+ self.tooltip.set_text(self.hovered.tooltip_text)
160
+ self.tooltip.fade_in()
161
+ else:
162
+ self.tooltip.fade_out()
163
+
164
+ # Tooltip logic
165
+ if self.tooltip.visible:
166
+
167
+ tooltip_size = self.tooltip.get_min_required_size()
168
+ # screen_w, screen_h = self.drawing_camera.rect.size
169
+ screen_w, screen_h = bf.const.RESOLUTION
170
+
171
+ tooltip_x, tooltip_y = mouse_world
172
+ tooltip_x+=4
173
+ tooltip_y+=4
174
+ tooltip_x = min(tooltip_x, screen_w - tooltip_size[0])
175
+ tooltip_y = min(tooltip_y, screen_h - tooltip_size[1])
176
+ tooltip_x = max(0, tooltip_x)
177
+ tooltip_y = max(0, tooltip_y)
178
+
179
+ self.tooltip.set_position(tooltip_x, tooltip_y)
180
+
181
+ if self.hovered == prev_hovered:
182
+ if isinstance(self.hovered, InteractiveWidget):
183
+ self.hovered.on_mouse_motion(*mouse_world)
184
+ return
185
+
186
+ if isinstance(prev_hovered, InteractiveWidget):
187
+ prev_hovered.on_exit()
188
+ if isinstance(self.hovered, InteractiveWidget):
189
+ self.hovered.on_enter()
190
+
191
+
192
+
193
+
194
+ def update_tree(self):
195
+ # 1st pass
196
+ self.apply_updates("pre")
197
+ self.apply_updates("post")
198
+ # 2nd pass
199
+ # self.apply_updates("pre")
200
+ # self.apply_updates("post")
201
+
202
+
203
+ def apply_pre_updates(self):
204
+ return
205
+
206
+ def apply_post_updates(self, skip_draw = False):
207
+ return
208
+
209
+ def draw(self, camera: bf.Camera) -> None:
210
+ if self.clip_children:
211
+ new_clip = camera.world_to_screen(self.get_inner_rect())
212
+ old_clip = camera.surface.get_clip()
213
+ camera.surface.set_clip(new_clip)
214
+
215
+ # Draw each child widget, sorted by render order
216
+ for child in [c for c in self.children if c != self.tooltip]:
217
+ if (not self.clip_children) or (child.rect.colliderect(self.rect) or not child.rect):
218
+ child.draw(camera)
219
+ if self.clip_children:
220
+ camera.surface.set_clip(old_clip)
221
+
222
+ if self.focused != self and (not self.focused is None) :
223
+ old_clip = camera.surface.get_clip()
224
+ camera.surface.set_clip(self.focused.parent.get_inner_rect())
225
+ self.focused.draw_focused(camera)
226
+ camera.surface.set_clip(old_clip)
227
+
228
+ self.tooltip.draw(camera)