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/meter.py CHANGED
@@ -1,96 +1,155 @@
1
- import math
2
- import batFramework as bf
3
- from .shape import Shape
4
- from typing import Self
5
-
6
-
7
- def custom_top_at(self, x, y):
8
- if Shape.top_at(self, x, y) == self:
9
- return self.parent
10
- return None
11
-
12
- class Meter(Shape):
13
- def __init__(self, min_value: float = 0, max_value: float = 1, step: float = 0.1):
14
- super().__init__()
15
- self.min_value, self.max_value = min_value, max_value
16
- self.step = step
17
- self.snap: bool = False
18
- self.value = self.max_value
19
- self.set_debug_color("pink")
20
-
21
- def __str__(self) -> str:
22
- return "Meter"
23
-
24
- def set_step(self, step: float) -> Self:
25
- self.step = step
26
- self.set_value(self.value)
27
- return self
28
-
29
- def set_range(self, range_min: float, range_max: float) -> Self:
30
- if range_min >= range_max:
31
- return self
32
- self.min_value = range_min
33
- self.max_value = range_max
34
- self.dirty_shape = True
35
-
36
- def set_value(self, value: float) -> Self:
37
- value = max(self.min_value, min(self.max_value, value))
38
- value = round(value / self.step) * self.step
39
- self.value = round(value,10)
40
- self.dirty_shape = True
41
- return self
42
-
43
- def get_value(self) -> float:
44
- return self.value
45
-
46
- def get_range(self) -> float:
47
- return self.max_value - self.min_value
48
-
49
- def get_ratio(self) -> float:
50
- return (self.value-self.min_value) / (self.max_value - self.min_value)
51
-
52
-
53
- class BarMeter(Meter):
54
- def __init__(self, min_value: float = 0, max_value: float = 1, step: float = 0.1):
55
- super().__init__(min_value, max_value, step)
56
- self.axis: bf.axis = bf.axis.HORIZONTAL
57
- self.content = Shape((0, 0)).set_color(bf.color.BLUE)
58
- self.content.set_debug_color("cyan")
59
- self.content.top_at = lambda x, y: custom_top_at(self.content, x, y)
60
- self.add(self.content)
61
- self.set_padding(4)
62
- self.set_color("gray20")
63
- self.set_outline_width(1)
64
- self.set_outline_color(bf.color.BLACK)
65
- self.set_debug_color("pink")
66
-
67
- def __str__(self) -> str:
68
- return "BarMeter"
69
-
70
- def set_axis(self,axis:bf.axis)->Self:
71
- self.axis = axis
72
- self.dirty_shape = True
73
- return self
74
-
75
- def _build_content(self) -> None:
76
- padded = self.get_inner_rect()
77
- ratio = self.get_ratio()
78
-
79
- self.content.set_border_radius(*[round(b/2) for b in self.border_radius])
80
-
81
- if self.axis == bf.axis.HORIZONTAL:
82
- width = (padded.width- self.outline_width *2) * ratio
83
- self.content.set_size((width, padded.height - self.outline_width*2))
84
- self.content.rect.topleft = padded.move(self.outline_width, self.outline_width).topleft
85
-
86
- else: # vertical
87
- height = (padded.height - self.outline_width * 2) * ratio
88
- self.content.set_size((padded.width - self.outline_width * 2, height))
89
- self.content.rect.bottomleft = (
90
- padded.move(self.outline_width,-self.outline_width).bottomleft
91
- )
92
- self.content.rect.height = math.ceil(self.content.rect.height)
93
-
94
- def build(self) -> None:
95
- self._build_content()
96
- super().build()
1
+ import math
2
+ import batFramework as bf
3
+ from .shape import Shape
4
+ from typing import Self
5
+ from .syncedVar import SyncedVar
6
+
7
+ def custom_top_at(self, x, y):
8
+ if Shape.top_at(self, x, y) == self:
9
+ return self.parent
10
+ return None
11
+
12
+ class Meter(Shape):
13
+ def __init__(self, min_value: float = 0, max_value: float = None, step: float = 0.1, synced_var: SyncedVar = None):
14
+ super().__init__()
15
+ self.min_value, self.max_value = min_value, max_value
16
+ self.step = step
17
+ self.snap: bool = False
18
+ self.synced_var = synced_var or SyncedVar(min_value)
19
+ if self.max_value is None:
20
+ self.max_value = self.synced_var.value
21
+ self.synced_var.bind(self, self._on_synced_var_update)
22
+ self.set_debug_color("pink")
23
+
24
+ def __str__(self) -> str:
25
+ return "Meter"
26
+
27
+ def set_snap(self,snap:bool)->Self:
28
+ self.snap = snap
29
+ self.set_value(self.get_value())
30
+ return self
31
+
32
+ def set_step(self, step: float) -> Self:
33
+ self.step = step
34
+ self.set_value(self.get_value())
35
+ return self
36
+
37
+ def set_range(self, range_min: float, range_max: float) -> Self:
38
+ if range_min >= range_max:
39
+ return self
40
+ self.min_value = range_min
41
+ self.max_value = range_max
42
+ self.dirty_shape = True
43
+ return self
44
+
45
+ def set_value(self, value: float) -> Self:
46
+ """
47
+ Sets the value of the meter and updates the synced variable.
48
+ """
49
+ value = max(self.min_value, min(self.max_value, value))
50
+ value = round(value / self.step) * self.step
51
+ value = round(value, 10)
52
+ self.synced_var.value = value # Update the synced variable
53
+ return self
54
+
55
+ def get_value(self) -> float:
56
+ """
57
+ Gets the current value from the synced variable.
58
+ """
59
+ return self.synced_var.value
60
+
61
+ def get_range(self) -> float:
62
+ return self.max_value - self.min_value
63
+
64
+ def get_ratio(self) -> float:
65
+ if self.max_value <= self.min_value:
66
+ return 0
67
+ return (self.get_value() - self.min_value) / (self.max_value - self.min_value)
68
+
69
+ def _on_synced_var_update(self, value: float) -> None:
70
+ """
71
+ Updates the meter's internal state when the synced variable changes.
72
+ """
73
+ self.dirty_shape = True
74
+
75
+ def set_synced_var(self, synced_var: SyncedVar) -> Self:
76
+ """
77
+ Rebinds the meter to a new SyncedVar.
78
+ """
79
+ if self.synced_var:
80
+ self.synced_var.unbind(self)
81
+ self.synced_var = synced_var
82
+ self.synced_var.bind(self, self._on_synced_var_update)
83
+ return self
84
+
85
+ class BarMeter(Meter):
86
+ def __init__(self, min_value = 0, max_value = None, step = 0.1, synced_var = None):
87
+ super().__init__(min_value, max_value, step, synced_var)
88
+ self.axis: bf.axis = bf.axis.HORIZONTAL
89
+ self.direction = bf.direction.RIGHT # Direction determines which side is the max range
90
+ self.content = Shape((4, 4)).set_color(bf.color.BLUE)
91
+ self.content.set_debug_color("cyan")
92
+ self.content.top_at = lambda x, y: custom_top_at(self.content, x, y)
93
+ self.add(self.content)
94
+ self.set_padding(4)
95
+ self.set_color("gray20")
96
+ self.set_outline_width(1)
97
+ self.set_outline_color(bf.color.BLACK)
98
+ self.set_debug_color("pink")
99
+
100
+ def __str__(self) -> str:
101
+ return "BarMeter"
102
+
103
+ def set_direction(self, direction: bf.direction) -> Self:
104
+ """
105
+ Sets the direction of the BarMeter.
106
+ """
107
+ self.direction = direction
108
+ if self.axis == bf.axis.HORIZONTAL and self.direction in [bf.direction.UP, bf.direction.DOWN]:
109
+ self.set_axis(bf.axis.VERTICAL)
110
+ elif self.axis == bf.axis.VERTICAL and self.direction in [bf.direction.LEFT, bf.direction.RIGHT]:
111
+ self.set_axis(bf.axis.HORIZONTAL)
112
+ self.dirty_shape = True
113
+ return self
114
+
115
+ def set_axis(self,axis:bf.axis)->Self:
116
+ self.axis = axis
117
+ if axis==bf.axis.HORIZONTAL and self.direction not in [bf.direction.LEFT,bf.direction.RIGHT]:
118
+ self.direction = bf.direction.RIGHT
119
+ elif axis == bf.axis.VERTICAL and self.direction not in [bf.direction.UP, bf.direction.DOWN]:
120
+ self.direction = bf.direction.UP
121
+
122
+ self.dirty_shape = True
123
+ return self
124
+
125
+ def _build_content(self) -> None:
126
+ padded = self.get_inner_rect()
127
+ ratio = self.get_ratio()
128
+
129
+ self.content.set_border_radius(*[round(b / 2) for b in self.border_radius])
130
+
131
+ if self.axis == bf.axis.HORIZONTAL:
132
+ width = (padded.width - self.outline_width * 2) * ratio
133
+ width = max(width,0)
134
+ self.content.set_size((width, padded.height - self.outline_width * 2))
135
+ if self.direction == bf.direction.RIGHT:
136
+ self.content.rect.topleft = padded.move(self.outline_width, self.outline_width).topleft
137
+ else: # bf.direction.LEFT
138
+ self.content.rect.topright = padded.move(-self.outline_width, self.outline_width).topright
139
+
140
+ else: # vertical
141
+ height = (padded.height - self.outline_width * 2) * ratio
142
+ height = round(height)
143
+ height = max(height,0)
144
+
145
+ self.content.set_size((padded.width - self.outline_width * 2, height))
146
+ if self.direction == bf.direction.UP:
147
+
148
+
149
+ self.content.rect.bottomleft = (padded.left + self.outline_width, padded.bottom - self.outline_width)
150
+ else: # bf.direction.DOWN
151
+ self.content.rect.topleft = padded.move(self.outline_width, self.outline_width).topleft
152
+
153
+ def build(self) -> None:
154
+ self._build_content()
155
+ super().build()
@@ -1,35 +1,43 @@
1
- import batFramework as bf
2
- from typing import Self, Any, Callable
3
- from .toggle import Toggle
4
- from .syncedVar import SyncedVar
5
-
6
-
7
- class RadioButton(Toggle):
8
- def __init__(self, text: str = "", radio_value: Any = None, synced_var: SyncedVar = None) -> None:
9
- super().__init__(text, None, False)
10
- self.radio_value: Any = radio_value if radio_value is not None else text if text else None
11
- self.synced_var : SyncedVar = None
12
- if synced_var:
13
- self.link(synced_var)
14
-
15
- def link(self,synced_var:SyncedVar)->Self:
16
- self.synced_var = synced_var
17
- synced_var.bind_widget(self,self._update_state)
18
- return self
19
-
20
- def __str__(self) -> str:
21
- return f"RadioButton({self.radio_value}|{'Active' if self.value else 'Inactive'})"
22
-
23
- def set_radio_value(self, value: Any) -> Self:
24
- self.radio_value = value
25
- return self
26
-
27
- def set_value(self, value : bool, do_callback=False):
28
- super().set_value(value, do_callback)
29
- if value : self.synced_var.value = self.radio_value
30
-
31
- def _update_state(self, synced_value: Any) -> None:
32
- """
33
- Updates the state of the RadioButton based on the synced variable's value.
34
- """
35
- self.set_value(self.radio_value == synced_value, False)
1
+ import batFramework as bf
2
+ from typing import Self, Any, Callable
3
+ from .toggle import Toggle
4
+ from .syncedVar import SyncedVar
5
+
6
+
7
+ # TODO : RadioButton with no synced var ? click crashes
8
+
9
+ class RadioButton(Toggle):
10
+ def __init__(self, text: str, synced_var: SyncedVar, radio_value: Any = None) -> None:
11
+ super().__init__(text, None, False)
12
+ self.radio_value: Any = radio_value if radio_value is not None else text if text else None
13
+ self.synced_var : SyncedVar = synced_var
14
+ self.synced_var.bind(self,self._update_state)
15
+
16
+ def __str__(self) -> str:
17
+ return f"RadioButton({self.radio_value}|{'Active' if self.value else 'Inactive'})"
18
+
19
+ def set_radio_value(self, value: Any) -> Self:
20
+ self.radio_value = value
21
+ return self
22
+
23
+ def set_value(self, value : bool, do_callback=False):
24
+ if self.value == value:
25
+ return self # No change
26
+ self.value = value
27
+ self.indicator.set_value(value)
28
+ self.dirty_surface = True
29
+
30
+ # Update SyncedVar only if different (avoid recursion)
31
+ if value and self.synced_var.value != self.radio_value:
32
+ self.synced_var.value = self.radio_value
33
+
34
+ if do_callback and self.callback:
35
+ self.callback(self.value)
36
+ return self
37
+ # if value : self.synced_var.value = self.radio_value
38
+
39
+ def _update_state(self, synced_value: Any) -> None:
40
+ """
41
+ Updates the state of the RadioButton based on the synced variable's value.
42
+ """
43
+ self.set_value(self.radio_value == synced_value, False)