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
@@ -0,0 +1,204 @@
1
+ from .widget import Widget
2
+ import batFramework as bf
3
+
4
+
5
+ class Constraint:
6
+ def __init__(self,name="Constraint", priority=0):
7
+ self.priority = priority
8
+ self.name = name
9
+ def set_priority(self, priority)->"Constraint":
10
+ self.priority = priority
11
+ return self
12
+ def to_string(self)->str:
13
+ return f"{self.name.upper()}"
14
+
15
+ def evaluate(self, parent_widget:Widget, child_widget:Widget) -> bool:
16
+ raise NotImplementedError("Subclasses must implement evaluate method")
17
+
18
+ def apply(self, parent_widget:Widget, child_widget:Widget=None) -> bool:
19
+ if not self.evaluate(parent_widget, child_widget):
20
+ self.apply_constraint(parent_widget, child_widget)
21
+ return False
22
+ return True
23
+
24
+ def apply_constraint(self, parent_widget:Widget, child_widget:Widget):
25
+ raise NotImplementedError("Subclasses must implement apply_constraint method")
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+
38
+
39
+
40
+
41
+
42
+ class ConstraintMinWidth(Constraint):
43
+ def __init__(self, width):
44
+ super().__init__(name="min_width")
45
+ self.min_width = width
46
+
47
+ def evaluate(self, parent_widget, child_widget):
48
+ return child_widget.rect.width >= self.min_width
49
+
50
+ def apply_constraint(self, parent_widget, child_widget):
51
+ if not self.evaluate(parent_widget, child_widget):
52
+ child_widget.set_size(self.min_width,child_widget.rect.h)
53
+
54
+
55
+
56
+
57
+ class ConstraintCenterX(Constraint):
58
+ def __init__(self):
59
+ super().__init__(name="centerx")
60
+
61
+ def evaluate(self, parent_widget, child_widget):
62
+ return child_widget.rect.centerx == parent_widget.get_content_center()[0]
63
+
64
+ def apply_constraint(self,parent_widget,child_widget):
65
+ if not self.evaluate(parent_widget,child_widget):
66
+ child_widget.set_center(parent_widget.get_content_center()[0],child_widget.rect.centery)
67
+
68
+ class ConstraintCenterY(Constraint):
69
+ def __init__(self):
70
+ super().__init__(name="centery")
71
+
72
+ def evaluate(self, parent_widget, child_widget):
73
+ return child_widget.rect.centery == parent_widget.get_content_center()[1]
74
+
75
+ def apply_constraint(self,parent_widget,child_widget):
76
+ if not self.evaluate(parent_widget,child_widget):
77
+ child_widget.set_center(child_widget.rect.centerx,parent_widget.get_content_center()[1])
78
+
79
+ class ConstraintCenter(Constraint):
80
+ def __init__(self):
81
+ super().__init__(name="center")
82
+
83
+ def evaluate(self, parent_widget, child_widget):
84
+ return child_widget.rect.center == parent_widget.get_content_center()
85
+
86
+ def apply_constraint(self,parent_widget,child_widget):
87
+ if not self.evaluate(parent_widget,child_widget):
88
+ child_widget.set_center(*parent_widget.get_content_center())
89
+
90
+ class ConstraintPercentageWidth(Constraint):
91
+ def __init__(self,percentage:float,keep_autoresize:bool=True):
92
+ super().__init__(name="percentage_width")
93
+ self.percentage:float = percentage
94
+ self.keep_autoresize: bool = keep_autoresize
95
+ def to_string(self)->str:
96
+ return f"{super().to_string()}.[{self.percentage},{self.keep_autoresize}]"
97
+ def evaluate(self, parent_widget, child_widget):
98
+ return child_widget.rect.width == round(parent_widget.get_content_width() * self.percentage)
99
+
100
+ def apply_constraint(self,parent_widget,child_widget):
101
+ if not self.evaluate(parent_widget,child_widget):
102
+ if child_widget.autoresize:
103
+ if self.keep_autoresize:
104
+ print(f"Warning: Constraint on {child_widget.to_string()} can't resize, autoresize set to True")
105
+ return
106
+ child_widget.set_autoresize(False)
107
+ child_widget.set_size(round(parent_widget.get_content_width() * self.percentage) ,child_widget.rect.h)
108
+
109
+
110
+ class ConstraintPercentageHeight(Constraint):
111
+ def __init__(self,percentage:float,keep_autoresize:bool=True):
112
+ super().__init__(name="percentage_height")
113
+ self.percentage:float = percentage
114
+ self.keep_autoresize: bool = keep_autoresize
115
+
116
+ def evaluate(self, parent_widget, child_widget):
117
+ return child_widget.rect.height == round(parent_widget.get_content_height() * self.percentage)
118
+
119
+ def apply_constraint(self,parent_widget,child_widget):
120
+ if not self.evaluate(parent_widget,child_widget):
121
+ if child_widget.autoresize:
122
+ if self.keep_autoresize:
123
+ print(f"Warning: Constraint on {child_widget.to_string()} can't resize, autoresize set to True")
124
+ return
125
+ child_widget.set_autoresize(False)
126
+ child_widget.set_size(child_widget.rect.w,round(parent_widget.get_content_height() * self.percentage))
127
+
128
+ class ConstraintHeight(Constraint):
129
+ def __init__(self,height:float):
130
+ if height < 0 :
131
+ raise ValueError("height can't be negative")
132
+ super().__init__(name="height")
133
+ self.height = height
134
+
135
+ def to_string(self)->str:
136
+ return f"{super().to_string()}.({self.height})"
137
+
138
+ def evaluate(self, parent_widget, child_widget):
139
+ return child_widget.rect.height == self.height
140
+
141
+ def apply_constraint(self,parent_widget,child_widget):
142
+ if not self.evaluate(parent_widget,child_widget):
143
+ child_widget.set_size(child_widget.rect.w,self.height)
144
+
145
+ class ConstraintWidth(Constraint):
146
+ def __init__(self,width:float):
147
+ if width < 0 :
148
+ raise ValueError("width can't be negative")
149
+ super().__init__(name="width")
150
+ self.width = width
151
+
152
+ def to_string(self)->str:
153
+ return f"{super().to_string()}.({self.width})"
154
+
155
+ def evaluate(self, parent_widget, child_widget):
156
+ return child_widget.rect.width == self.width
157
+
158
+ def apply_constraint(self,parent_widget,child_widget):
159
+ if not self.evaluate(parent_widget,child_widget):
160
+ child_widget.set_size(self.width,child_widget.rect.h)
161
+
162
+
163
+ class ConstraintAspectRatio(Constraint):
164
+ def __init__(self,ratio:int|float=1):
165
+ super().__init__(name="aspect_ratio")
166
+ if isinstance(ratio, float|int):
167
+ self.ratio = ratio
168
+ elif isinstance(ratio,Widget):
169
+ self.ratio = ratio.rect.w / ratio.rect.h
170
+ else:
171
+ raise TypeError(f"Ratio must be float or Widget")
172
+ def evaluate(self, parent_widget,child_widget):
173
+ return self.ratio == child_widget.rect.w / child_widget.rect.h
174
+
175
+ def apply_constraint(self,parent_widget,child_widget):
176
+ if not self.evaluate(parent_widget,child_widget):
177
+ return # TODO
178
+
179
+ class ConstraintAnchorBottom(Constraint):
180
+ def __init__(self):
181
+ super().__init__(name="anchor_bottom")
182
+
183
+ def evaluate(self, parent_widget,child_widget):
184
+ return child_widget.rect.bottom == parent_widget.rect.bottom
185
+
186
+ def apply_constraint(self,parent_widget,child_widget):
187
+ if not self.evaluate(parent_widget,child_widget):
188
+ child_widget.set_y(parent_widget.get_content_bottom() - child_widget.rect.h)
189
+
190
+
191
+ class ConstraintAnchorTopRight(Constraint):
192
+ def __init__(self):
193
+ super().__init__(name="anchor_topright")
194
+
195
+ def evaluate(self, parent_widget,child_widget):
196
+ return child_widget.rect.topright == parent_widget.rect.topright
197
+
198
+ def apply_constraint(self,parent_widget,child_widget):
199
+ if not self.evaluate(parent_widget,child_widget):
200
+ child_widget.set_position(parent_widget.get_content_right()-child_widget.rect.w, parent_widget.get_content_top())
201
+
202
+
203
+
204
+
@@ -1,191 +1,49 @@
1
1
  import batFramework as bf
2
2
  from .widget import Widget
3
- from .shape import Shape
4
- from .interactiveWidget import InteractiveWidget
5
- from .layout import Layout, Column
3
+ from .layout import Layout
4
+ from .constraints import Constraint
6
5
  from typing import Self
7
- import pygame
8
- from pygame.math import Vector2
9
6
 
10
-
11
- class Container(Shape, InteractiveWidget):
12
- def __init__(self, layout: Layout = None, *children: Widget) -> None:
7
+ class Container(Widget):
8
+ def __init__(self, layout:Layout=None, *children:Widget):
13
9
  super().__init__()
14
- self.dirty_children = False
15
10
  self.set_debug_color("green")
16
- self.layout: Layout = layout
17
- self.scroll = Vector2(0, 0)
18
- if not self.layout:
19
- self.layout = Column()
20
- self.layout.set_parent(self)
21
- self.add(*children)
22
-
23
- def __str__(self) -> str:
24
- return f"Container({self.uid},{len(self.children)})"
25
-
26
- def get_min_required_size(self):
27
- if self.layout:
28
- return self.layout.get_auto_size()
29
- return self.rect.size
30
-
31
- def reset_scroll(self) -> Self:
32
- self.scroll.update(0, 0)
33
- self.dirty_children = True
34
- return self
35
-
36
- def set_scroll(self, value: tuple) -> Self:
37
- self.scroll.update(value)
38
- self.dirty_children = True
39
- return self
40
-
41
- def scrollX_by(self, x: float | int) -> Self:
42
- self.scroll.x += x
43
- self.dirty_children = True
44
- return self
45
-
46
- def scrollY_by(self, y: float | int) -> Self:
47
- self.scroll.y += y
48
- self.dirty_children = True
49
- return self
50
-
51
- def scroll_by(self, value: tuple[float | int, float | int]) -> Self:
52
- self.scroll += value
53
- self.dirty_children = True
54
- return self
55
-
56
- def clamp_scroll(self) -> Self:
57
- if not self.children:
58
- return Self
59
- r = self.get_padded_rect()
60
- size = self.children[0].rect.unionall(self.children[1:]).size
61
-
62
- # Calculate the maximum scroll values
63
- max_scroll_x = max(0, size[0] - r.width)
64
- max_scroll_y = max(0, size[1] - r.height)
65
-
66
- # Clamp the scroll values
67
- self.scroll.x = max(0, min(self.scroll.x, max_scroll_x))
68
- self.scroll.y = max(0, min(self.scroll.y, max_scroll_y))
11
+ self.surface = None
12
+ self.layout :Layout = layout
13
+ if self.layout : self.layout.set_parent(self)
14
+ for child in children:
15
+ self.add_child(child)
69
16
 
70
- self.dirty_children = True
71
- return self
72
-
73
- def set_layout(self, layout: Layout) -> Self:
74
- tmp = self.layout
17
+ def set_layout(self,layout:Layout)->Self:
75
18
  self.layout = layout
76
- if self.layout != tmp:
77
- self.dirty_children = True
19
+ self.apply_constraints()
78
20
  return self
79
21
 
80
- def get_interactive_children(self) -> list[InteractiveWidget]:
81
- return [
82
- child
83
- for child in self.children
84
- if isinstance(child, InteractiveWidget) and child.allow_focus_to_self()
85
- ]
86
-
87
- def focus_next_child(self) -> None:
88
- self.layout.focus_next_child()
89
-
90
- def focus_prev_child(self) -> None:
91
- self.layout.focus_prev_child()
22
+ def get_bounding_box(self):
23
+ yield (self.rect,self._debug_color)
24
+ for child in self.children:
25
+ yield from child.get_bounding_box()
92
26
 
93
- def clear_children(self) -> None:
27
+ def clear_children(self)->None:
94
28
  self.children.clear()
95
- self.dirty_children = True
96
-
97
- def add(self, *child: Widget) -> Self:
98
- super().add(*child)
99
- self.dirty_children = True
100
- return self
101
-
102
- def remove(self, *child: Widget) -> Self:
103
- super().remove(*child)
104
- self.dirty_children = True
105
- return self
106
-
107
- def resolve_constraints(self) -> None:
108
- super().resolve_constraints()
109
-
110
- def top_at(self, x: float | int, y: float | int) -> "None|Widget":
111
- if self.visible and self.rect.collidepoint(x, y):
112
- if self.children:
113
- for child in reversed(self.children):
114
- r = child.top_at(x, y)
115
- if r is not None:
116
- return r
117
- return self
118
- return None
119
-
120
- def get_focus(self) -> bool:
121
- res = super().get_focus()
122
- if not res:
123
- return False
124
- l = l = self.get_interactive_children()
125
- if not l:
126
- return True
127
- self.focused_index = min(self.focused_index, len(l))
128
- return l[self.focused_index].get_focus()
129
-
130
- def do_handle_event(self, event):
131
- self.layout.handle_event(event)
132
-
133
- def set_focused_child(self, child: InteractiveWidget) -> bool:
134
- l = self.get_interactive_children()
135
- try:
136
- i = l.index(child)
137
- except ValueError:
138
- return False
139
- if i >= 0:
140
- self.focused_index = i
141
- return True
142
- return False
143
-
144
- def allow_focus_to_self(self) -> bool:
145
- return len(self.get_interactive_children()) != 0 and self.visible
146
-
147
- def draw(self, camera: bf.Camera) -> None:
148
- constraints_down = False
149
- if self.dirty_shape:
150
- self.dirty_constraints = True
151
- self.dirty_children = True
152
- self.dirty_surface = True
153
- self.build()
154
- for child in self.children:
155
- child.dirty_constraints = True
156
- self.dirty_shape = False
157
-
158
- if self.dirty_constraints:
159
- if self.parent and self.parent.dirty_constraints:
160
- self.parent.visit_up(self.selective_up)
161
- else:
162
- constraints_down = True
163
- if not self.dirty_children:
164
- self.dirty_children = any(c.dirty_shape for c in self.children)
165
- if self.dirty_children:
166
- if self.layout:
167
- self.layout.arrange()
168
- self.dirty_children = False
29
+ self.apply_constraints()
169
30
 
170
- if constraints_down:
171
- self.visit(lambda c: c.resolve_constraints())
31
+ def add_child(self,*child:Widget)->None:
32
+ super().add_child(*child)
33
+ if self.layout : self.layout.arrange()
172
34
 
173
- if self.dirty_surface:
174
- self.paint()
175
- self.dirty_surface = False
35
+ def remove_child(self,child:Widget)->None:
36
+ super().remove_child(child)
37
+ if self.layout : self.layout.arrange()
176
38
 
177
- bf.Entity.draw(self, camera)
39
+ def build(self)->None:
40
+ super().build()
41
+ if self.layout : self.layout.arrange()
178
42
 
179
- if self.clip_children:
180
- new_clip = camera.world_to_screen(self.get_padded_rect())
181
- old_clip = camera.surface.get_clip()
182
- new_clip = new_clip.clip(old_clip)
183
- camera.surface.set_clip(new_clip)
184
- # Draw children with adjusted positions
185
- _ = [
186
- child.draw(camera)
187
- for child in sorted(self.children, key=lambda c: c.render_order)
188
- ]
43
+ def apply_constraints(self)->None:
44
+ super().apply_constraints()
45
+ if self.layout : self.layout.arrange()
189
46
 
190
- if self.clip_children:
191
- camera.surface.set_clip(old_clip)
47
+ def to_string_id(self)->str:
48
+ return f"Container({len(self.children)},{[c.to_string() for c in self.constraints]})"
49
+
@@ -1,135 +1,47 @@
1
1
  from .label import Label
2
2
  from typing import Self
3
- import batFramework as bf
4
- import pygame
5
-
6
-
7
- def convert_to_int(*args):
8
- return [int(arg) for arg in args]
9
-
10
3
 
11
4
  class Debugger(Label):
12
- def __init__(self) -> None:
13
- super().__init__("")
14
- self.static_data: dict = {}
15
- self.dynamic_data: dict = {}
16
- self.refresh_rate = 10
17
- self.refresh_counter: float = 0
18
- self.add_tags("debugger")
19
- self.set_visible(False)
20
-
21
- def set_refresh_rate(self, value: int) -> Self:
22
- self.refresh_rate = value
23
- return self
24
-
25
- def add_static(self, key: str, data):
26
- self.static_data[key] = str(data)
27
- self.update_text()
28
-
29
- def add_dynamic(self, key: str, func) -> None:
30
- self.dynamic_data[key] = func
31
- self.update_text()
32
-
33
- def remove_static(self, key) -> bool:
34
- try:
35
- self.static_data.pop(key)
36
- return True
37
- except KeyError:
38
- return False
39
-
40
- def remove_dynamic(self, key) -> bool:
41
- try:
42
- self.dynamic_data.pop(key)
43
- return True
44
- except KeyError:
45
- return False
46
-
47
- def set_parent_scene(self, scene) -> Self:
48
- super().set_parent_scene(scene)
49
- self.set_render_order(99)
50
- self.update_text()
51
- return self
52
-
53
- def set_text(self, text: str) -> Self:
54
- return super().set_text(text)
55
-
56
- def update_text(self) -> None:
57
- if not self.parent_scene:
58
- return
59
-
60
- d = "\n".join(
61
- key + ":" + data if key != "" else data
62
- for key, data in self.static_data.items()
63
- )
64
-
65
- d2 = "\n".join(
66
- key + ":" + str(data()) if key != "" else str(data())
67
- for key, data in self.dynamic_data.items()
68
- )
69
-
70
- self.set_text("\n".join((d, d2)).strip())
71
-
72
- def update(self, dt: float) -> None:
73
- if not self.parent_scene:
74
- return
75
- if self.parent_scene.get_sharedVar("debug_mode") != bf.debugMode.DEBUGGER:
76
- self.set_visible(False)
77
- return
78
- self.set_visible(True)
79
- self.refresh_counter = self.refresh_counter + (dt * 60)
80
- if self.refresh_counter > self.refresh_rate:
81
- self.refresh_counter = 0
82
- self.update_text()
83
-
84
- def __str__(self) -> str:
85
- return "Debugger"
86
-
87
- def top_at(self, x, y):
88
- return None
89
-
90
-
91
- class FPSDebugger(Debugger):
92
- def __init__(self):
93
- super().__init__()
94
-
95
- def do_when_added(self):
96
- if not self.parent_scene or not self.parent_scene.manager:
97
- print("Debugger could not link to the manager")
98
- return
99
- manager_link = self.parent_scene.manager
100
- self.add_dynamic("FPS", lambda: str(round(manager_link.get_fps())))
101
-
102
-
103
- class BasicDebugger(FPSDebugger):
104
- def do_when_added(self):
105
- if not self.parent_scene or not self.parent_scene.manager:
106
- print("Debugger could not link to the manager")
107
- return
108
- self.add_dynamic(
109
- "Resolution", lambda: "x".join(str(i) for i in bf.const.RESOLUTION)
110
- )
111
- super().do_when_added()
112
- parent_scene = self.parent_scene
113
-
114
- self.add_dynamic("Mouse", pygame.mouse.get_pos)
115
- self.add_dynamic(
116
- "World",
117
- lambda: convert_to_int(
118
- *parent_scene.camera.screen_to_world(pygame.mouse.get_pos())
119
- ),
120
- )
121
- self.add_dynamic(
122
- "Hud",
123
- lambda: convert_to_int(
124
- *parent_scene.hud_camera.screen_to_world(pygame.mouse.get_pos())
125
- ),
126
- )
127
- self.add_dynamic("W. Ent.", lambda: parent_scene.get_world_entity_count())
128
- self.add_dynamic("H. Ent.", lambda: parent_scene.get_hud_entity_count())
129
-
130
- self.add_dynamic(
131
- "Hover",
132
- lambda: (
133
- str(parent_scene.root.hovered) if parent_scene.root.hovered else None
134
- ),
135
- )
5
+ def __init__(self)->None:
6
+ super().__init__("")
7
+ self.static_data : dict = {}
8
+ self.dynamic_data : dict = {}
9
+ self.refresh_rate = 10
10
+ self.refresh_counter = 0
11
+ self.render_order = 99
12
+
13
+ def to_string_id(self)->str:
14
+ return "Debugger"
15
+
16
+ def set_refresh_rate(self, value:int)-> Self:
17
+ self.refresh_rate = value
18
+ return self
19
+
20
+ def add_data(self,key:str,data):
21
+ self.static_data[key] = str(data)
22
+ self.update_text()
23
+
24
+ def add_dynamic_data(self,key:str,func)->None:
25
+ self.dynamic_data[key] = func
26
+ self.update_text()
27
+
28
+ def set_parent_scene(self,scene)->None:
29
+ super().set_parent_scene(scene)
30
+ self.update_text()
31
+
32
+ def update_text(self)->None:
33
+ if not self.parent_scene:return
34
+ d = '\n'.join(key+':'+data if key!='' else data for key,data in self.static_data.items())
35
+ d2 = '\n'.join(key+':'+str(data()) if key!='' else str(data()) for key,data in self.dynamic_data.items())
36
+ self.set_text('\n'.join((d,d2)).strip())
37
+
38
+ def update(self,dt:float)->None:
39
+ if not self.parent_scene:return
40
+ if self.parent_scene.get_sharedVar("is_debugging_func")() != 1:
41
+ self.set_visible(False)
42
+ return
43
+ self.set_visible(True)
44
+ self.refresh_counter = self.refresh_counter + (dt * 60)
45
+ if self.refresh_counter > self.refresh_rate:
46
+ self.refresh_counter = 0
47
+ self.update_text()
@@ -0,0 +1,19 @@
1
+ import batFramework as bf
2
+ from .shape import Shape
3
+ import pygame
4
+
5
+
6
+ class Frame(Shape):
7
+ def __init__(self,width:float,height:float):
8
+ super().__init__(width,height)
9
+ self.set_debug_color("magenta")
10
+
11
+ def to_string_id(self)->str:
12
+ return "Frame"
13
+
14
+ def children_modified(self)->None:
15
+ print(self.children)
16
+ self.set_size(
17
+ *self.inflate_rect_by_padding(self.rect.unionall(list(c.rect for c in self.children))).size
18
+ )
19
+ super().children_modified()