batframework 1.0.7__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 (51) hide show
  1. batFramework/__init__.py +47 -41
  2. batFramework/action.py +20 -42
  3. batFramework/actionContainer.py +4 -43
  4. batFramework/animatedSprite.py +65 -98
  5. batFramework/audioManager.py +25 -39
  6. batFramework/camera.py +56 -226
  7. batFramework/constants.py +48 -32
  8. batFramework/cutscene.py +24 -32
  9. batFramework/cutsceneBlocks.py +33 -30
  10. batFramework/debugger.py +48 -0
  11. batFramework/dynamicEntity.py +7 -8
  12. batFramework/easing.py +23 -28
  13. batFramework/entity.py +52 -89
  14. batFramework/gui/__init__.py +1 -3
  15. batFramework/gui/button.py +58 -124
  16. batFramework/gui/constraints.py +90 -163
  17. batFramework/gui/container.py +18 -29
  18. batFramework/gui/debugger.py +42 -106
  19. batFramework/gui/frame.py +9 -15
  20. batFramework/gui/image.py +17 -36
  21. batFramework/gui/indicator.py +14 -20
  22. batFramework/gui/interactiveWidget.py +12 -63
  23. batFramework/gui/label.py +50 -113
  24. batFramework/gui/layout.py +51 -66
  25. batFramework/gui/root.py +29 -70
  26. batFramework/gui/shape.py +41 -34
  27. batFramework/gui/toggle.py +29 -37
  28. batFramework/gui/widget.py +131 -174
  29. batFramework/manager.py +14 -21
  30. batFramework/particles.py +20 -41
  31. batFramework/scene.py +72 -173
  32. batFramework/sceneManager.py +80 -40
  33. batFramework/stateMachine.py +0 -1
  34. batFramework/time.py +51 -62
  35. batFramework/transition.py +154 -0
  36. batFramework/utils.py +150 -3
  37. batframework-1.0.8a2.dist-info/METADATA +58 -0
  38. batframework-1.0.8a2.dist-info/RECORD +42 -0
  39. {batframework-1.0.7.dist-info → batframework-1.0.8a2.dist-info}/WHEEL +1 -1
  40. batFramework/enums.py +0 -14
  41. batFramework/fontManager.py +0 -57
  42. batFramework/gui/dialogueBox.py +0 -70
  43. batFramework/gui/slider.py +0 -5
  44. batFramework/gui/textInput.py +0 -88
  45. batFramework/resourceManager.py +0 -72
  46. batFramework/sprite.py +0 -33
  47. batFramework/tileset.py +0 -64
  48. batframework-1.0.7.dist-info/LICENCE +0 -21
  49. batframework-1.0.7.dist-info/METADATA +0 -55
  50. batframework-1.0.7.dist-info/RECORD +0 -50
  51. {batframework-1.0.7.dist-info → batframework-1.0.8a2.dist-info}/top_level.txt +0 -0
batFramework/gui/image.py CHANGED
@@ -1,42 +1,23 @@
1
1
  import batFramework as bf
2
2
  from .widget import Widget
3
3
  import pygame
4
-
5
-
6
4
  class Image(Widget):
7
- def __init__(
8
- self,
9
- data: pygame.Surface | str | None = None,
10
- size: None | tuple[int, int] = None,
11
- convert_alpha=True,
12
- ):
13
- self.dirty : bool = False
14
- self.original_surface = None
15
- self.surface = None
16
- super().__init__(convert_alpha)
17
- if data:
18
- self.set_image(data,size)
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)
19
17
 
20
- def build(self) -> None:
21
- if self.original_surface and (
22
- (not self.surface or self.surface.get_size() != self.get_size_int())
23
- or self.dirty
24
- ) :
25
- self.surface = pygame.transform.scale(
26
- self.original_surface, self.get_size_int()
27
- )
28
18
 
29
- def set_image(
30
- self, data: pygame.Surface | str, size: None | tuple[int, int] = None
31
- ):
32
- if isinstance(data, str):
33
- tmp = bf.ResourceManager().get_image(data,self.convert_alpha)
34
- elif isinstance(data, pygame.Surface):
35
- tmp= data
36
- if self.convert_alpha:
37
- tmp = tmp.convert_alpha()
38
- if tmp != self.original_surface: self.dirty = True
39
- self.original_surface = tmp
40
- if not size and self.original_surface:
41
- size = self.original_surface.get_size()
42
- self.set_size(*size)
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
+
@@ -1,46 +1,40 @@
1
1
  from .shape import Shape
2
2
  from typing import Any
3
3
  import pygame
4
-
5
4
  # from .constraints import ConstraintAspectRatio
6
5
 
7
-
8
6
  class Indicator(Shape):
9
- def __init__(self, width: int | float = 10, height: int | float = 10) -> None:
10
- super().__init__(width, height)
7
+ def __init__(self,width:int|float= 10,height:int|float=10)->None:
8
+ super().__init__(width,height)
11
9
 
12
- def to_string_id(self) -> str:
10
+ def to_string_id(self)->str:
13
11
  return "Indicator"
14
12
 
15
- def set_value(self, value: Any) -> None:
13
+ def set_value(self,value:Any)->None:
16
14
  pass
17
15
 
18
- def get_value(self) -> Any:
16
+ def get_value(self)->Any:
19
17
  pass
20
18
 
21
- def _build_indicator(self) -> None:
19
+ def _build_indicator(self)->None:
22
20
  pass
23
-
24
- def build(self) -> None:
21
+
22
+ def build(self)->None:
25
23
  super().build()
26
24
  self._build_indicator()
27
25
 
28
26
 
29
27
  class ToggleIndicator(Indicator):
30
- def __init__(self, default_value: bool) -> None:
31
- self.value: bool = default_value
32
- super().__init__(20, 20)
33
-
34
- #TODO aspect ratio would be good right about here
28
+ def __init__(self,default_value:bool)->None:
29
+ self.value:bool = default_value
30
+ super().__init__(20,20)
35
31
  # self.add_constraint(ConstraintAspectRatio(1))
36
32
 
37
- def set_value(self, value) -> None:
33
+ def set_value(self,value)->None:
38
34
  self.value = value
39
35
  self.set_color("green" if value else "red")
40
36
  self.build()
41
37
 
42
- def get_value(self) -> bool:
38
+ def get_value(self)->bool:
43
39
  return self.value
44
-
45
- def top_at(self, x: float, y: float) -> "None|Widget":
46
- return None
40
+ #
@@ -1,73 +1,22 @@
1
1
  from .widget import Widget
2
- from typing import Self
3
2
 
4
3
  class InteractiveWidget(Widget):
5
- def __init__(self, *args, **kwargs)->None:
4
+ def __init__(self,*args,**kwargs):
5
+ super().__init__(convert_alpha = True)
6
6
  self.focusable = True
7
- self.is_focused: bool = False
8
- self.is_hovered: bool = False
9
- self.is_clicked_down:bool = False
10
- super().__init__(convert_alpha=True)
7
+ self.is_focused : bool = False
11
8
 
12
- def set_focusable(self,value:bool)->Self:
13
- self.focusable = value
14
- return self
9
+ def get_focus(self)->bool:
10
+ if self.parent is None or not self.focusable: return False
11
+ self.get_root().focus_on(self)
15
12
 
16
- def get_focus(self) -> bool:
17
- if self.focusable and (r:=self.get_root()) is not None:
18
- r.focus_on(self)
19
- return True
20
- return False
21
-
22
- def lose_focus(self) -> bool:
23
- if self.is_focused and (r:=self.get_root()) is not None:
24
- r.focus_on(None)
25
- return True
26
- return False
27
-
28
-
29
- def on_get_focus(self) -> None:
13
+ def on_get_focus(self)->None:
30
14
  self.is_focused = True
31
- self.do_on_get_focus()
32
15
 
33
-
34
- def on_lose_focus(self) -> None:
16
+ def on_lose_focus(self)->None:
35
17
  self.is_focused = False
36
- self.do_on_lose_focus()
37
-
38
-
39
- def do_on_get_focus(self)->None:
40
- pass
41
18
 
42
- def do_on_lose_focus(self)->None:
43
- pass
44
-
45
-
46
- def on_click_down(self,button:int)->None:
47
- self.do_on_click_down(button)
48
-
49
- def on_click_up(self,button:int)->None:
50
- self.do_on_click_up(button)
51
-
52
- def do_on_click_down(self,button:int)->None:
53
- pass
54
-
55
- def do_on_click_up(self,button:int)->None:
56
- pass
57
-
58
- def on_enter(self)->None:
59
- self.is_hovered = True
60
- self.do_on_enter()
61
-
62
- def on_exit(self)->None:
63
- self.is_hovered = False
64
- self.do_on_exit()
65
-
66
-
67
- def do_on_enter(self)->None:
68
- pass
69
-
70
- def do_on_exit(self)->None:
71
- pass
72
-
73
-
19
+ def lose_focus(self)->bool:
20
+ if self.is_focused and self.parent is not None:
21
+ self.get_root().focus_on(None)
22
+
batFramework/gui/label.py CHANGED
@@ -4,22 +4,14 @@ from .shape import Shape
4
4
  from typing import Self
5
5
 
6
6
  class Label(Shape):
7
- _text_cache = {}
8
- def __init__(self, text: str) -> None:
7
+ def __init__(self,text:str) -> None:
9
8
  self._text = ""
10
-
11
- self._resized_flag: bool = False
12
-
13
9
  # Enable/Disable antialiasing
14
- self._antialias: bool = True
15
-
16
- self._text_size = bf.FontManager().DEFAULT_TEXT_SIZE
17
-
18
- self.auto_wraplength: bool = False
19
-
20
- self._alignment: bf.Alignment = bf.Alignment.CENTER
21
-
22
- self._text_color: tuple[int, int, int] | str = "black"
10
+ self._antialias : bool = True
11
+
12
+ self._text_size = bf.const.DEFAULT_TEXT_SIZE
13
+
14
+ self._text_color : tuple[int,int,int]|str = "black"
23
15
  # font name (given when loaded by utils) to use for the text
24
16
  self._font_name = None
25
17
  # reference to the font object
@@ -27,147 +19,92 @@ class Label(Shape):
27
19
  # Rect containing the text of the label
28
20
  self._text_rect = None
29
21
  # text surface (result of font.render)
30
- self._text_surface: pygame.Surface | None = None
31
-
32
- self._do_caching : bool = False
33
- super().__init__(width=0, height=0)
34
- self.set_padding((10, 4))
22
+ self._text_surface : pygame.Surface | None= None
23
+ super().__init__(width=0,height=0)
24
+ self.set_padding((10,4))
35
25
  self.set_debug_color("blue")
36
- self.set_color(bf.color.CLOUD_WHITE)
26
+ self.set_color("white")
37
27
  self.set_autoresize(True)
38
28
  self.set_font(force=True)
39
29
  self.set_text(text)
40
30
 
41
-
42
- @staticmethod
43
- def clear_cache():
44
- Label._text_cache = {}
45
-
46
- def enable_caching(self)->Self:
47
- self._do_caching = True
48
- return self
49
-
50
- def disable_caching(self)->Self:
51
- self._do_caching = False
52
- return self
53
-
54
- def set_text_color(self, color) -> Self:
31
+ def set_text_color(self,color)->Self:
55
32
  self._text_color = color
56
33
  self.build()
57
34
  return self
58
35
 
59
- def to_string_id(self) -> str:
36
+ def to_string_id(self)->str:
60
37
  return f"Label({self._text})"
61
38
 
62
- def set_alignment(self, alignment: bf.Alignment) -> "Label":
63
- self._alignment = alignment
64
- self.build()
65
- return self
66
-
67
- def set_auto_wraplength(self, val: bool) -> "Label":
68
- self.auto_wraplength = val
69
- self.build()
70
- return self
71
39
 
72
40
  def get_bounding_box(self):
73
41
  yield from super().get_bounding_box()
74
- if self._text_rect:
75
- yield self._text_rect.move(*self.rect.topleft)
42
+ if self._text_rect : yield self._text_rect.move(*self.rect.topleft)
76
43
 
77
- def set_font(self, font_name: str = None, force: bool = False) -> "Label":
78
- if font_name == self._font_name and not force:
79
- return self
44
+ def set_font(self,font_name:str=None,force:bool = False)-> "Label":
45
+ if font_name == self._font_name and not force: return self
80
46
  self._font_name = font_name
81
- self._font_object = bf.FontManager().get_font(self._font_name, self._text_size)
47
+ self._font_object = bf.utils.get_font(self._font_name,self._text_size)
82
48
  self.build()
83
49
  return self
84
50
 
85
- def set_text_size(self, text_size: int) -> "Label":
86
- text_size = round(text_size / 2) * 2
87
- if text_size == self._text_size:
88
- return self
51
+ def set_text_size(self,text_size:int) -> "Label":
52
+ text_size = round(text_size/2) * 2
53
+ if text_size == self._text_size : return self
89
54
  self._text_size = text_size
90
- self._font_object = bf.FontManager().get_font(self._font_name, self._text_size)
55
+ self._font_object = bf.utils.get_font(self._font_name,self._text_size)
91
56
  self.build()
92
57
  return self
93
58
 
94
- def get_text_size(self) -> int:
59
+ def get_text_size(self)-> int:
95
60
  return self._text_size
96
61
 
97
- def is_antialias(self) -> bool:
62
+ def is_antialias(self)->bool:
98
63
  return self._antialias
99
64
 
100
- def set_antialias(self, value: bool) -> "Label":
65
+ def set_antialias(self,value:bool)->"Label":
101
66
  self._antialias = value
102
67
  self.build()
103
68
  return self
104
69
 
105
- def set_text(self, text: str) -> "Label":
106
- if text == self._text:
107
- return self
70
+ def set_text(self,text:str) -> "Label":
71
+ if text == self._text : return self
108
72
  self._text = text
109
73
  self.build()
110
74
  return self
111
-
112
- def get_text(self) -> str:
75
+
76
+ def get_text(self)->str:
113
77
  return self._text
114
78
 
115
79
 
116
- def get_min_required_size(self)->tuple[float,float]:
117
- return (0,0) if not self._font_object else self.inflate_rect_by_padding(pygame.FRect(0,0,*self._font_object.size(self._text))).size
118
-
119
- def _build_text(self) -> None:
80
+ def _build_text(self)-> None:
120
81
  if self._font_object is None:
121
- print(f"No font for '{self.to_string_id()}' :(")
82
+ print("No font :(")
122
83
  return
123
84
  # render(text, antialias, color, bgcolor=None, wraplength=0) -> Surface
124
-
125
- params = {
126
- "font_name":self._font_object.name,
127
- "text":self._text,
128
- "antialias":self._antialias,
129
- "color":self._text_color,
130
- "bgcolor":self._color,
131
- "wraplength":int(self.get_content_width()) if self.auto_wraplength else 0
132
- }
133
-
134
- key = tuple(params.values())
135
- cached_value = Label._text_cache.get(key,None)
136
- if cached_value != None:
137
- self._text_surface = cached_value
138
- else:
139
- params.pop("font_name")
140
- self._text_surface = self._font_object.render(**params)
141
- if self._do_caching:
142
- Label._text_cache[key] = self._text_surface
143
- self._text_rect = self._text_surface.get_frect(topleft = self.get_content_rect_rel().topleft)
144
-
145
- def _build_layout(self) -> None:
146
- if self._text_rect is None : return
85
+ self._text_surface = self._font_object.render(
86
+ text = self._text,
87
+ antialias = self._antialias,
88
+ color = self._text_color,
89
+ bgcolor = self._color,
90
+ wraplength = 0
91
+ )
92
+ self._text_rect = self._text_surface.get_frect()
93
+
94
+ def _build_layout(self)->None:
147
95
  if self.autoresize:
148
- target_rect = self.inflate_rect_by_padding(self._text_rect)
149
- if self.rect.size != target_rect.size:
150
- self._resized_flag = True
151
- self.set_size(* target_rect.size)
96
+ if self.rect.size != self.inflate_rect_by_padding(self._text_rect).size :
97
+ self.set_size(
98
+ self._text_rect.w + self.padding[0]+self.padding[2],
99
+ self._text_rect.h + self.padding[1]+self.padding[3]
100
+ )
152
101
  return
153
- if self._alignment == bf.Alignment.CENTER:
154
- self._text_rect.center = self.get_content_rect_rel().center
155
- elif self._alignment == bf.Alignment.LEFT:
156
- self._text_rect.topleft = self.get_content_rect_rel().topleft
157
- elif self._alignment == bf.Alignment.RIGHT:
158
- self._text_rect.topright = self.get_content_rect_rel().topright
159
- if self._resized_flag:
160
- self._resized_flag = False
161
- if self.parent:
162
- # print("Children modified call")
163
- self.parent.children_modified()
164
-
165
- self.surface.fblits([(self._text_surface, self._text_rect)])
166
-
167
- def build(self) -> None:
102
+ self._text_rect.center = self.get_content_rect_rel().center
103
+ self.surface.blit(self._text_surface,self._text_rect)
104
+
105
+ def build(self)->None:
168
106
  super().build()
169
- if not self._font_object:
170
- return
107
+ if not self._font_object:return
171
108
  self._build_text()
172
109
  self._build_layout()
173
- self.apply_constraints()
110
+
@@ -2,95 +2,80 @@ import batFramework as bf
2
2
  from .widget import Widget
3
3
  from .constraints import *
4
4
  from typing import Self
5
- import pygame
6
-
7
5
 
8
6
  class Layout:
9
- def __init__(self, parent: Widget = None):
7
+ def __init__(self, parent: Widget=None):
10
8
  self.parent = parent
11
- self.child_constraints: list[Constraint] = []
12
- self.children_rect = pygame.FRect(0, 0, 0, 0)
13
-
14
- def set_child_constraints(self, *constraints) -> Self:
15
- self.child_constraints = list(constraints)
9
+ self.child_constraints : list[Constraint] = []
10
+
11
+ def set_child_constraints(self,*constraints)->Self:
12
+ self.child_constraints = constraints
16
13
  self.arrange()
17
14
  return self
18
-
19
- def set_parent(self, parent: Widget):
15
+
16
+ def set_parent(self,parent:Widget):
20
17
  self.parent = parent
21
18
  self.arrange()
22
19
 
23
- def arrange(self) -> None:
20
+ def arrange(self)->None:
24
21
  raise NotImplementedError("Subclasses must implement arrange method")
25
22
 
26
-
27
23
  class Column(Layout):
28
- def __init__(self, gap: int = 0, fit_children: bool = True, center: bool = True):
24
+ def __init__(self,gap:int=0,shrink:bool=False):
29
25
  super().__init__()
30
26
  self.gap = gap
31
- self.fit_children: bool = fit_children
32
- self.center = center
33
-
34
- def arrange(self) -> None:
35
- if not self.parent or not self.parent.children:
36
- return
37
- len_children = len(self.parent.children)
38
- parent_height = sum(c.get_min_required_size()[1] for c in self.parent.children)
39
- parent_width = max(c.get_min_required_size()[0] for c in self.parent.children)
40
- if self.gap:
41
- parent_height += (len_children - 1) * self.gap
42
- self.children_rect.update(
43
- self.parent.get_content_left(),
44
- self.parent.get_content_top(),
45
- parent_width,
46
- parent_height,
47
- )
48
- if self.fit_children:
49
- self.parent.set_size(parent_width,parent_height)
50
- if self.center:
51
- self.children_rect.center = self.parent.rect.center
52
-
53
- current_y = self.children_rect.top
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
54
44
 
55
45
  for child in self.parent.children:
56
- child.set_position(self.parent.rect.x, current_y)
46
+ child.set_position(self.parent.rect.x,current_y)
57
47
  current_y += child.rect.h + self.gap
58
48
  for c in self.child_constraints:
59
- child.add_constraints(c)
60
-
61
-
49
+ if not child.has_constraint(c.name):
50
+ child.add_constraint(c)
51
+
62
52
  class Row(Layout):
63
- def __init__(self, gap: int = 0, fit_children: bool = True, center: bool = True):
53
+ def __init__(self, gap: int = 0, shrink: bool = False):
64
54
  super().__init__()
65
55
  self.gap = gap
66
- self.fit_children: bool = fit_children
67
- self.center = center
56
+ self.shrink = shrink
68
57
 
69
58
  def arrange(self) -> None:
70
- if not self.parent or not self.parent.children:
59
+ if not self.parent:
71
60
  return
72
-
73
- len_children = len(self.parent.children)
74
- parent_width = sum(c.get_min_required_size()[0] for c in self.parent.children)
75
- parent_height = max(c.get_min_required_size()[1] for c in self.parent.children)
76
-
77
- if self.gap:
78
- parent_width += (len_children - 1) * self.gap
79
- self.children_rect.update(
80
- self.parent.get_content_left(),
81
- self.parent.get_content_top(),
82
- parent_width,
83
- parent_height,
84
- )
85
- if self.center:
86
- self.children_rect.center = self.parent.get_content_center()
87
- if self.fit_children:
88
- self.parent.set_size(parent_width,parent_height)
89
-
90
- current_x = self.children_rect.left
91
-
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
92
76
  for child in self.parent.children:
93
- child.set_position(current_x, self.parent.rect.y)
77
+ child.set_position(current_x,self.parent.rect.y)
94
78
  current_x += child.rect.w + self.gap
95
79
  for c in self.child_constraints:
96
- child.add_constraints(c)
80
+ if not child.has_constraint(c.name):
81
+ child.add_constraint(c)