batframework 1.0.8a1__py3-none-any.whl → 1.0.8a2__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 (63) hide show
  1. batFramework/__init__.py +50 -53
  2. batFramework/action.py +105 -116
  3. batFramework/actionContainer.py +11 -53
  4. batFramework/animatedSprite.py +65 -115
  5. batFramework/audioManager.py +26 -70
  6. batFramework/camera.py +68 -253
  7. batFramework/constants.py +54 -16
  8. batFramework/cutscene.py +25 -34
  9. batFramework/cutsceneBlocks.py +42 -37
  10. batFramework/debugger.py +48 -0
  11. batFramework/dynamicEntity.py +7 -9
  12. batFramework/easing.py +71 -0
  13. batFramework/entity.py +98 -42
  14. batFramework/gui/__init__.py +2 -8
  15. batFramework/gui/button.py +79 -7
  16. batFramework/gui/constraints.py +204 -0
  17. batFramework/gui/container.py +31 -155
  18. batFramework/gui/debugger.py +43 -124
  19. batFramework/gui/frame.py +19 -0
  20. batFramework/gui/image.py +17 -41
  21. batFramework/gui/indicator.py +21 -41
  22. batFramework/gui/interactiveWidget.py +13 -116
  23. batFramework/gui/label.py +73 -278
  24. batFramework/gui/layout.py +61 -148
  25. batFramework/gui/root.py +37 -102
  26. batFramework/gui/shape.py +57 -258
  27. batFramework/gui/toggle.py +46 -97
  28. batFramework/gui/widget.py +254 -268
  29. batFramework/manager.py +19 -40
  30. batFramework/particles.py +77 -0
  31. batFramework/scene.py +107 -214
  32. batFramework/sceneManager.py +107 -150
  33. batFramework/stateMachine.py +0 -1
  34. batFramework/time.py +57 -117
  35. batFramework/transition.py +126 -184
  36. batFramework/transitionManager.py +0 -0
  37. batFramework/utils.py +161 -34
  38. batframework-1.0.8a2.dist-info/METADATA +58 -0
  39. batframework-1.0.8a2.dist-info/RECORD +42 -0
  40. {batframework-1.0.8a1.dist-info → batframework-1.0.8a2.dist-info}/WHEEL +1 -1
  41. batFramework/easingController.py +0 -58
  42. batFramework/enums.py +0 -104
  43. batFramework/fontManager.py +0 -65
  44. batFramework/gui/clickableWidget.py +0 -206
  45. batFramework/gui/constraints/__init__.py +0 -1
  46. batFramework/gui/constraints/constraints.py +0 -378
  47. batFramework/gui/dialogueBox.py +0 -96
  48. batFramework/gui/draggableWidget.py +0 -38
  49. batFramework/gui/meter.py +0 -76
  50. batFramework/gui/radioButton.py +0 -62
  51. batFramework/gui/slider.py +0 -220
  52. batFramework/gui/textInput.py +0 -134
  53. batFramework/object.py +0 -115
  54. batFramework/particle.py +0 -101
  55. batFramework/renderGroup.py +0 -62
  56. batFramework/resourceManager.py +0 -84
  57. batFramework/scrollingSprite.py +0 -113
  58. batFramework/sprite.py +0 -45
  59. batFramework/tileset.py +0 -46
  60. batframework-1.0.8a1.dist-info/LICENCE +0 -21
  61. batframework-1.0.8a1.dist-info/METADATA +0 -55
  62. batframework-1.0.8a1.dist-info/RECORD +0 -56
  63. {batframework-1.0.8a1.dist-info → batframework-1.0.8a2.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,173 +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 get_min_required_size(self):
24
- if self.layout:
25
- return self.layout.get_auto_size()
26
- return self.rect.size
27
-
28
- def reset_scroll(self) -> Self:
29
- self.scroll.update(0, 0)
30
- self.dirty_children = True
31
- return self
32
-
33
- def set_scroll(self, value: tuple) -> Self:
34
- self.scroll.update(value)
35
- self.dirty_children = True
36
- return self
37
-
38
- def scrollX_by(self, x: float | int) -> Self:
39
- self.scroll.x += x
40
- self.dirty_children = True
41
- return self
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)
42
16
 
43
- def scrollY_by(self, y: float | int) -> Self:
44
- self.scroll.y += y
45
- self.dirty_children = True
46
- return self
47
-
48
- def scroll_by(self, value: tuple[float | int, float | int]) -> Self:
49
- self.scroll += value
50
- self.dirty_children = True
51
- return self
52
-
53
- def set_layout(self, layout: Layout) -> Self:
54
- tmp = self.layout
17
+ def set_layout(self,layout:Layout)->Self:
55
18
  self.layout = layout
56
- if self.layout != tmp:
57
- self.dirty_children = True
19
+ self.apply_constraints()
58
20
  return self
59
21
 
60
-
61
- def get_debug_outlines(self):
62
- yield (self.rect, self.debug_color)
63
- yield (self.get_padded_rect(), self.debug_color)
64
-
22
+ def get_bounding_box(self):
23
+ yield (self.rect,self._debug_color)
65
24
  for child in self.children:
66
- yield from child.get_debug_outlines()
67
- # for data in child.get_debug_outlines():
68
-
69
- def get_interactive_children(self) -> list[InteractiveWidget]:
70
- return [
71
- child for child in self.children if isinstance(child, InteractiveWidget) and child.allow_focus_to_self()
72
- ]
73
-
74
- def focus_next_child(self) -> None:
75
- self.layout.focus_next_child()
76
-
77
- def focus_prev_child(self) -> None:
78
- self.layout.focus_prev_child()
25
+ yield from child.get_bounding_box()
79
26
 
80
- def clear_children(self) -> None:
27
+ def clear_children(self)->None:
81
28
  self.children.clear()
82
- self.dirty_children = True
83
-
84
- def add(self, *child: Widget) -> Self:
85
- super().add(*child)
86
- self.dirty_children = True
87
- return self
88
-
89
- def remove(self, *child: Widget) -> Self:
90
- super().remove(*child)
91
- self.dirty_children = True
92
- return self
93
-
94
- def resolve_constraints(self) -> None:
95
- super().resolve_constraints()
96
-
97
- def __str__(self) -> str:
98
- return f"Container({self.uid},{len(self.children)})"
99
-
100
- def top_at(self, x: float | int, y: float | int) -> "None|Widget":
101
- if self.visible and self.rect.collidepoint(x, y):
102
- if self.children:
103
- for child in reversed(self.children):
104
- r = child.top_at(x,y)
105
- if r is not None:
106
- return r
107
- return self
108
- return None
109
-
110
- def get_focus(self) -> bool:
111
- res = super().get_focus()
112
- if not res:
113
- return False
114
- l = l = self.get_interactive_children()
115
- if not l:
116
- return True
117
- self.focused_index = min(self.focused_index, len(l))
118
- return l[self.focused_index].get_focus()
119
-
120
- def set_focused_child(self, child: InteractiveWidget) -> bool:
121
- l = self.get_interactive_children()
122
- i = l.index(child)
123
- if i >= 0:
124
- self.focused_index = i
125
- return True
126
- return False
127
-
128
- def allow_focus_to_self(self) -> bool:
129
- return len(self.get_interactive_children()) != 0
130
-
131
- def draw(self, camera: bf.Camera) -> None:
132
- constraints_down = False
133
- if self.dirty_shape:
134
- self.dirty_constraints = True
135
- self.dirty_children = True
136
- self.dirty_surface = True
137
- self.build()
138
- for child in self.children:
139
- child.dirty_constraints = True
140
- self.dirty_shape = False
141
-
142
- if self.dirty_constraints:
143
- if self.parent and self.parent.dirty_constraints:
144
- self.parent.visit_up(self.selective_up)
145
- else:
146
- constraints_down = True
147
-
148
- if self.dirty_children:
149
- if self.layout:
150
- self.layout.arrange()
151
- self.dirty_children = False
152
-
153
- if constraints_down:
154
- self.visit(lambda c: c.resolve_constraints())
155
-
156
- if self.dirty_surface:
157
- self.paint()
158
- self.dirty_surface = False
29
+ self.apply_constraints()
159
30
 
31
+ def add_child(self,*child:Widget)->None:
32
+ super().add_child(*child)
33
+ if self.layout : self.layout.arrange()
160
34
 
161
- bf.Entity.draw(self, camera)
35
+ def remove_child(self,child:Widget)->None:
36
+ super().remove_child(child)
37
+ if self.layout : self.layout.arrange()
162
38
 
163
- if self.clip_children:
164
- new_clip = camera.world_to_screen(self.get_padded_rect())
165
- old_clip = camera.surface.get_clip()
166
- new_clip = new_clip.clip(old_clip)
167
- camera.surface.set_clip(new_clip)
168
- # Draw children with adjusted positions
169
- _ = [child.draw(camera) for child in sorted(self.children, key=lambda c: c.render_order)]
39
+ def build(self)->None:
40
+ super().build()
41
+ if self.layout : self.layout.arrange()
170
42
 
171
- if self.clip_children:
172
- camera.surface.set_clip(old_clip)
43
+ def apply_constraints(self)->None:
44
+ super().apply_constraints()
45
+ if self.layout : self.layout.arrange()
173
46
 
47
+ def to_string_id(self)->str:
48
+ return f"Container({len(self.children)},{[c.to_string() for c in self.constraints]})"
49
+
@@ -1,128 +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
3
 
10
4
  class Debugger(Label):
11
- def __init__(self) -> None:
12
- super().__init__("")
13
- self.static_data: dict = {}
14
- self.dynamic_data: dict = {}
15
- self.refresh_rate = 10
16
- self.refresh_counter: float = 0
17
- self.add_tags("debugger")
18
- self.set_visible(False)
19
-
20
- # def get_debug_outlines(self):
21
- # yield None
22
-
23
- def to_string_id(self) -> str:
24
- return "Debugger"
25
-
26
- def set_refresh_rate(self, value: int) -> Self:
27
- self.refresh_rate = value
28
- return self
29
-
30
- def add_static(self, key: str, data):
31
- self.static_data[key] = str(data)
32
- self.update_text()
33
-
34
- def add_dynamic(self, key: str, func) -> None:
35
- self.dynamic_data[key] = func
36
- self.update_text()
37
-
38
- def remove_static(self, key) -> bool:
39
- try:
40
- self.static_data.pop(key)
41
- return True
42
- except KeyError:
43
- return False
44
-
45
- def remove_dynamic(self, key) -> bool:
46
- try:
47
- self.dynamic_data.pop(key)
48
- return True
49
- except KeyError:
50
- return False
51
-
52
- def set_parent_scene(self, scene) -> Self:
53
- super().set_parent_scene(scene)
54
- self.set_render_order(99)
55
- self.update_text()
56
- return self
57
-
58
- def set_text(self, text: str) -> Self:
59
- return super().set_text(text)
60
-
61
- def update_text(self) -> None:
62
- if not self.parent_scene:
63
- return
64
- d = "\n".join(
65
- key + ":" + data if key != "" else data
66
- for key, data in self.static_data.items()
67
- )
68
- d2 = "\n".join(
69
- key + ":" + str(data()) if key != "" else str(data())
70
- for key, data in self.dynamic_data.items()
71
- )
72
- self.set_text("\n".join((d, d2)).strip())
73
-
74
- def update(self, dt: float) -> None:
75
- if not self.parent_scene:
76
- return
77
- if self.parent_scene.get_sharedVar("debug_mode") != bf.debugMode.DEBUGGER:
78
- self.set_visible(False)
79
- return
80
- self.set_visible(True)
81
- self.refresh_counter = self.refresh_counter + (dt * 60)
82
- if self.refresh_counter > self.refresh_rate:
83
- self.refresh_counter = 0
84
- self.update_text()
85
-
86
-
87
- def __str__(self)->str:
88
- return "Debugger"
89
- # def top_at(self,x,y):
90
- # return None
91
-
92
- class FPSDebugger(Debugger):
93
- def do_when_added(self):
94
- if not self.parent_scene or not self.parent_scene.manager:
95
- print("Debugger could not link to the manager")
96
- return
97
- manager_link = self.parent_scene.manager
98
- self.add_dynamic("FPS", lambda: str(round(manager_link.get_fps())))
99
-
100
-
101
- class BasicDebugger(FPSDebugger):
102
- def do_when_added(self):
103
- if not self.parent_scene or not self.parent_scene.manager:
104
- print("Debugger could not link to the manager")
105
- return
106
- self.add_dynamic(
107
- "Resolution", lambda: "x".join(str(i) for i in bf.const.RESOLUTION)
108
- )
109
- super().do_when_added()
110
- parent_scene = self.parent_scene
111
-
112
- self.add_dynamic("Mouse", pygame.mouse.get_pos)
113
- self.add_dynamic(
114
- "World",
115
- lambda: convert_to_int(
116
- *parent_scene.camera.screen_to_world(pygame.mouse.get_pos())
117
- ),
118
- )
119
- self.add_dynamic(
120
- "Hud",
121
- lambda: convert_to_int(
122
- *parent_scene.hud_camera.screen_to_world(pygame.mouse.get_pos())
123
- ),
124
- )
125
- self.add_dynamic("W. Ent.", lambda: parent_scene.get_world_entity_count())
126
- self.add_dynamic("H. Ent.", lambda: parent_scene.get_hud_entity_count())
127
-
128
- self.add_dynamic("Hover",lambda : str(parent_scene.root.hovered) if parent_scene.root.hovered else None)
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()
batFramework/gui/image.py CHANGED
@@ -1,47 +1,23 @@
1
1
  import batFramework as bf
2
2
  from .widget import Widget
3
3
  import pygame
4
- from typing import Self
5
-
6
-
7
4
  class Image(Widget):
8
- def __init__(
9
- self,
10
- path: str = None,
11
- convert_alpha=True,
12
- ):
13
- self.original_surface = None
14
- super().__init__(convert_alpha = convert_alpha)
15
- if path is not None:
16
- self.from_path(path)
17
-
18
- def paint(self) -> None:
19
- super().paint()
20
- self.surface.fill((0,0,0,0 if self.convert_alpha else 255))
21
- if self.rect.size != self.original_surface.get_size():
22
- self.surface.blit(pygame.transform.scale(self.original_surface,self.rect.size),(0,0))
23
- else:
24
- self.surface.blit(self.original_surface,(0,0))
25
-
5
+ def __init__(self,data:pygame.Surface|str,size:None|tuple[int,int]=None,convert_alpha=True):
6
+ super().__init__(False)
7
+ self.surface = None
8
+ if isinstance(data,str):
9
+ path = bf.utils.get_path(data)
10
+ self.original_surface=pygame.image.load(path)
11
+ elif isinstance(data,pygame.Surface):
12
+ self.original_surface = data
13
+
14
+ if convert_alpha: self.original_surface = self.original_surface.convert_alpha()
15
+ if not size : size = self.original_surface.get_size()
16
+ self.set_size(*size)
26
17
 
27
- def from_path(self,path:str)->Self:
28
- tmp = bf.ResourceManager().get_image(path,self.convert_alpha)
29
- if tmp is None:
30
- return self
31
- self.original_surface = tmp
32
- size = self.original_surface.get_size()
33
- if not self.autoresize_h : size[0] = None
34
- if not self.autoresize_h : size[1] = None
35
- self.set_size(size)
36
- self.dirty_surface = True
37
- return self
38
18
 
39
- def from_surface(self,surface: pygame.Surface)->Self:
40
- if surface is None : return self
41
- self.original_surface = surface
42
- size = self.original_surface.get_size()
43
- if not self.autoresize_h : size[0] = None
44
- if not self.autoresize_h : size[1] = None
45
- self.set_size(size)
46
- self.dirty_surface = True
47
- return self
19
+ def build(self)->None:
20
+ if not self.surface or self.surface.get_size() != self.get_size_int():
21
+ self.surface = pygame.transform.scale(self.original_surface,self.get_size_int())
22
+
23
+