batframework 1.0.9a11__py3-none-any.whl → 1.0.10__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.
- batFramework/__init__.py +53 -76
- batFramework/action.py +99 -126
- batFramework/actionContainer.py +9 -53
- batFramework/animatedSprite.py +114 -56
- batFramework/audioManager.py +36 -82
- batFramework/camera.py +69 -263
- batFramework/constants.py +53 -29
- batFramework/cutscene.py +109 -243
- batFramework/cutsceneBlocks.py +176 -0
- batFramework/debugger.py +48 -0
- batFramework/dynamicEntity.py +9 -16
- batFramework/easing.py +71 -0
- batFramework/entity.py +85 -92
- batFramework/gui/__init__.py +3 -14
- batFramework/gui/button.py +78 -12
- batFramework/gui/constraints.py +204 -0
- batFramework/gui/container.py +31 -188
- batFramework/gui/debugger.py +43 -126
- batFramework/gui/frame.py +19 -0
- batFramework/gui/image.py +20 -55
- batFramework/gui/indicator.py +22 -95
- batFramework/gui/interactiveWidget.py +12 -229
- batFramework/gui/label.py +77 -311
- batFramework/gui/layout.py +66 -414
- batFramework/gui/root.py +35 -203
- batFramework/gui/shape.py +57 -247
- batFramework/gui/toggle.py +48 -114
- batFramework/gui/widget.py +243 -457
- batFramework/manager.py +29 -113
- batFramework/particles.py +77 -0
- batFramework/scene.py +217 -22
- batFramework/sceneManager.py +129 -161
- batFramework/stateMachine.py +8 -11
- batFramework/time.py +75 -0
- batFramework/transition.py +124 -129
- batFramework/transitionManager.py +0 -0
- batFramework/triggerZone.py +4 -4
- batFramework/utils.py +144 -266
- {batframework-1.0.9a11.dist-info → batframework-1.0.10.dist-info}/METADATA +24 -17
- batframework-1.0.10.dist-info/RECORD +43 -0
- batFramework/animation.py +0 -77
- batFramework/baseScene.py +0 -240
- batFramework/cutsceneManager.py +0 -34
- batFramework/drawable.py +0 -77
- batFramework/easingController.py +0 -58
- batFramework/enums.py +0 -135
- batFramework/fontManager.py +0 -65
- batFramework/gui/animatedLabel.py +0 -89
- batFramework/gui/clickableWidget.py +0 -244
- batFramework/gui/constraints/__init__.py +0 -1
- batFramework/gui/constraints/constraints.py +0 -980
- batFramework/gui/draggableWidget.py +0 -44
- batFramework/gui/meter.py +0 -96
- batFramework/gui/radioButton.py +0 -35
- batFramework/gui/selector.py +0 -250
- batFramework/gui/slider.py +0 -397
- batFramework/gui/style.py +0 -10
- batFramework/gui/styleManager.py +0 -54
- batFramework/gui/syncedVar.py +0 -49
- batFramework/gui/textInput.py +0 -306
- batFramework/gui/tooltip.py +0 -30
- batFramework/particle.py +0 -118
- batFramework/propertyEaser.py +0 -79
- batFramework/renderGroup.py +0 -34
- batFramework/resourceManager.py +0 -130
- batFramework/sceneLayer.py +0 -138
- batFramework/scrollingSprite.py +0 -115
- batFramework/sprite.py +0 -51
- batFramework/templates/__init__.py +0 -1
- batFramework/templates/controller.py +0 -97
- batFramework/tileset.py +0 -46
- batFramework/timeManager.py +0 -213
- batframework-1.0.9a11.dist-info/RECORD +0 -67
- {batframework-1.0.9a11.dist-info → batframework-1.0.10.dist-info}/LICENSE +0 -0
- {batframework-1.0.9a11.dist-info → batframework-1.0.10.dist-info}/WHEEL +0 -0
- {batframework-1.0.9a11.dist-info → batframework-1.0.10.dist-info}/top_level.txt +0 -0
@@ -1,44 +0,0 @@
|
|
1
|
-
from .interactiveWidget import InteractiveWidget
|
2
|
-
import batFramework as bf
|
3
|
-
import pygame
|
4
|
-
|
5
|
-
|
6
|
-
class DraggableWidget(InteractiveWidget):
|
7
|
-
def __init__(self, *args, **kwargs) -> None:
|
8
|
-
self.drag_start = None
|
9
|
-
self.offset = None
|
10
|
-
self.click_mask = [True,False,False,False,False]
|
11
|
-
self.is_dragged : bool = False # the widget is following the mouse AND the mouse is in the widget
|
12
|
-
self.is_dragged_outside : bool = False # the widget is following the mouse BUT the mouse is NOT in the widget
|
13
|
-
super().__init__(*args, **kwargs)
|
14
|
-
|
15
|
-
def set_click_mask(self,b1=0,b2=0,b3=0,b4=0,b5=0):
|
16
|
-
self.click_mask = [b1,b2,b3,b4,b5]
|
17
|
-
|
18
|
-
def on_click_down(self, button):
|
19
|
-
super().on_click_down(button)
|
20
|
-
return any(i==j and i== True for i,j in zip(self.is_clicked_down,self.click_mask))
|
21
|
-
|
22
|
-
def do_on_drag(
|
23
|
-
self, drag_start_pos: tuple[float, float], drag_end_pos: tuple[float, float]
|
24
|
-
) -> None:
|
25
|
-
new_pos = drag_end_pos[0] - self.offset[0], drag_end_pos[1] - self.offset[1]
|
26
|
-
if self.rect.topleft != new_pos:
|
27
|
-
self.set_position(*new_pos)
|
28
|
-
|
29
|
-
def update(self, dt: float):
|
30
|
-
self.is_dragged_outside = any(i==j and i== True for i,j in zip(pygame.mouse.get_pressed(5),self.click_mask))
|
31
|
-
self.is_dragged = any(i==j and i== True for i,j in zip(self.is_clicked_down,self.click_mask))
|
32
|
-
|
33
|
-
if self.is_dragged and self.is_dragged_outside:
|
34
|
-
x, y = self.parent_layer.camera.screen_to_world(pygame.mouse.get_pos())
|
35
|
-
if self.drag_start == None:
|
36
|
-
self.offset = x - self.rect.x, y - self.rect.y
|
37
|
-
self.drag_start = x, y
|
38
|
-
else:
|
39
|
-
self.do_on_drag(self.drag_start, (x, y))
|
40
|
-
else:
|
41
|
-
self.drag_start = None
|
42
|
-
self.offset = None
|
43
|
-
self.is_clicked_down = [False]*5
|
44
|
-
super().update(dt)
|
batFramework/gui/meter.py
DELETED
@@ -1,96 +0,0 @@
|
|
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()
|
batFramework/gui/radioButton.py
DELETED
@@ -1,35 +0,0 @@
|
|
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)
|
batFramework/gui/selector.py
DELETED
@@ -1,250 +0,0 @@
|
|
1
|
-
import batFramework as bf
|
2
|
-
import pygame
|
3
|
-
from typing import Self,Callable,Any
|
4
|
-
from .button import Button
|
5
|
-
from .indicator import ArrowIndicator
|
6
|
-
from .clickableWidget import ClickableWidget
|
7
|
-
from .widget import Widget
|
8
|
-
|
9
|
-
class MyArrow(ArrowIndicator,ClickableWidget):
|
10
|
-
def top_at(self,x,y):
|
11
|
-
return Widget.top_at(self,x,y)
|
12
|
-
|
13
|
-
def get_focus(self):
|
14
|
-
return self.parent.get_focus()
|
15
|
-
|
16
|
-
class Selector(Button):
|
17
|
-
def __init__(self,options:list[str]=None,default_value:str=None,allow_cycle:bool=False):
|
18
|
-
super().__init__('')
|
19
|
-
self.allow_cycle = allow_cycle
|
20
|
-
self.current_index = 0
|
21
|
-
self.on_modify_callback : Callable[[str,int],Any] = None
|
22
|
-
self.options = options if options else []
|
23
|
-
self.gap : int = 2
|
24
|
-
text_value = ""
|
25
|
-
|
26
|
-
|
27
|
-
if not (default_value is not None and default_value in self.options):
|
28
|
-
default_value = options[0]
|
29
|
-
|
30
|
-
text_value = default_value
|
31
|
-
self.current_index = self.options.index(default_value)
|
32
|
-
|
33
|
-
self.left_indicator : MyArrow = (MyArrow(bf.direction.LEFT)
|
34
|
-
.set_color((0,0,0,0)).set_arrow_color(self.text_color)
|
35
|
-
.set_callback(lambda : self.set_by_index(self.get_current_index()-1))
|
36
|
-
)
|
37
|
-
|
38
|
-
self.right_indicator:MyArrow =(MyArrow(bf.direction.RIGHT)
|
39
|
-
.set_color((0,0,0,0)).set_arrow_color(self.text_color)
|
40
|
-
.set_callback(lambda : self.set_by_index(self.get_current_index()+1))
|
41
|
-
)
|
42
|
-
|
43
|
-
self.add(self.left_indicator,self.right_indicator)
|
44
|
-
self.set_clip_children(False)
|
45
|
-
self.set_text(text_value)
|
46
|
-
|
47
|
-
def __str__(self):
|
48
|
-
return f"Selector[{self.options[self.current_index]}]"
|
49
|
-
|
50
|
-
def set_gap(self,value:int)->Self:
|
51
|
-
self.gap = value
|
52
|
-
self.dirty_shape = True
|
53
|
-
return self
|
54
|
-
|
55
|
-
def set_arrow_color(self,color)->Self:
|
56
|
-
self.left_indicator.set_arrow_color(color)
|
57
|
-
self.right_indicator.set_arrow_color(color)
|
58
|
-
return self
|
59
|
-
|
60
|
-
def disable(self):
|
61
|
-
super().disable()
|
62
|
-
self.left_indicator.disable()
|
63
|
-
self.right_indicator.disable()
|
64
|
-
return self
|
65
|
-
|
66
|
-
def enable(self):
|
67
|
-
super().enable()
|
68
|
-
self.right_indicator.enable()
|
69
|
-
self.left_indicator.enable()
|
70
|
-
index = self.current_index
|
71
|
-
if not self.allow_cycle:
|
72
|
-
if index == 0:
|
73
|
-
self.left_indicator.disable()
|
74
|
-
else:
|
75
|
-
self.left_indicator.enable()
|
76
|
-
if index == len(self.options)-1:
|
77
|
-
self.right_indicator.disable()
|
78
|
-
else:
|
79
|
-
self.right_indicator.enable()
|
80
|
-
|
81
|
-
|
82
|
-
return self
|
83
|
-
|
84
|
-
def set_tooltip_text(self, text):
|
85
|
-
self.left_indicator.set_tooltip_text(text)
|
86
|
-
self.right_indicator.set_tooltip_text(text)
|
87
|
-
return super().set_tooltip_text(text)
|
88
|
-
|
89
|
-
def get_min_required_size(self) -> tuple[float, float]:
|
90
|
-
"""
|
91
|
-
Calculates the minimum size required for the selector, including text and indicators.
|
92
|
-
"""
|
93
|
-
|
94
|
-
# Calculate the maximum size needed for the text
|
95
|
-
old_text = self.text
|
96
|
-
max_text_size = (0, 0)
|
97
|
-
for option in self.options:
|
98
|
-
self.text = option
|
99
|
-
text_size = self._get_text_rect_required_size()
|
100
|
-
max_text_size = max(max_text_size[0], text_size[0]), max(max_text_size[1], text_size[1])
|
101
|
-
self.text = old_text
|
102
|
-
|
103
|
-
# Ensure total_height is always an odd integer
|
104
|
-
total_height = max(self.font_object.get_height()+1, max_text_size[1] * 1.5)
|
105
|
-
total_height += self.unpressed_relief
|
106
|
-
total_height += max(self.right_indicator.outline_width,self.left_indicator.outline_width)
|
107
|
-
|
108
|
-
# Calculate total width and height
|
109
|
-
total_width = (
|
110
|
-
total_height*2+
|
111
|
-
max_text_size[0] + # Text width
|
112
|
-
self.gap * 2 # Gaps between text and indicators
|
113
|
-
)
|
114
|
-
# Inflate by padding at the very end
|
115
|
-
final_size = self.expand_rect_with_padding((0, 0, total_width, total_height)).size
|
116
|
-
|
117
|
-
return final_size
|
118
|
-
|
119
|
-
def _align_content(self):
|
120
|
-
"""
|
121
|
-
Builds the selector layout (places and resizes the indicators)
|
122
|
-
"""
|
123
|
-
|
124
|
-
# return
|
125
|
-
# Step 1: Calculate the padded area for positioning
|
126
|
-
padded = self.get_inner_rect()
|
127
|
-
|
128
|
-
|
129
|
-
# left_size = self.left_indicator.rect.size
|
130
|
-
right_size = self.right_indicator.rect.size
|
131
|
-
|
132
|
-
indicator_height = padded.h
|
133
|
-
|
134
|
-
self.left_indicator.set_size((indicator_height,indicator_height))
|
135
|
-
self.right_indicator.set_size((indicator_height,indicator_height))
|
136
|
-
|
137
|
-
|
138
|
-
# Step 3: Position indicators
|
139
|
-
self.left_indicator.set_position(padded.left, None)
|
140
|
-
self.left_indicator.set_center(None, padded.centery)
|
141
|
-
|
142
|
-
self.right_indicator.set_position(padded.right - right_size[0], None)
|
143
|
-
self.right_indicator.set_center(None, padded.centery)
|
144
|
-
|
145
|
-
def apply_post_updates(self, skip_draw = False):
|
146
|
-
super().apply_post_updates(skip_draw)
|
147
|
-
self._align_content()
|
148
|
-
|
149
|
-
def get_current_index(self)->int:
|
150
|
-
return self.current_index
|
151
|
-
|
152
|
-
def set_allow_cycle(self,value:bool)->Self:
|
153
|
-
if value == self.allow_cycle: return self
|
154
|
-
self.allow_cycle = value
|
155
|
-
self.dirty_surface = True
|
156
|
-
return self
|
157
|
-
|
158
|
-
def set_text_color(self,color)->Self:
|
159
|
-
super().set_text_color(color)
|
160
|
-
self.left_indicator.set_arrow_color(color)
|
161
|
-
self.right_indicator.set_arrow_color(color)
|
162
|
-
return self
|
163
|
-
|
164
|
-
def set_modify_callback(self,function:Callable[[str,int],Any]):
|
165
|
-
"""
|
166
|
-
the function will receive the value and the index
|
167
|
-
"""
|
168
|
-
self.on_modify_callback = function
|
169
|
-
return self
|
170
|
-
|
171
|
-
def set_by_index(self,index:int)->Self:
|
172
|
-
if self.allow_cycle:
|
173
|
-
index = index%len(self.options)
|
174
|
-
else:
|
175
|
-
index = max(min(len(self.options)-1,index),0)
|
176
|
-
|
177
|
-
if index == self.current_index:
|
178
|
-
return self
|
179
|
-
|
180
|
-
self.current_index = index
|
181
|
-
self.set_text(self.options[self.current_index])
|
182
|
-
if self.on_modify_callback:
|
183
|
-
self.on_modify_callback(self.options[self.current_index],self.current_index)
|
184
|
-
if not self.allow_cycle:
|
185
|
-
if index == 0:
|
186
|
-
self.left_indicator.disable()
|
187
|
-
else:
|
188
|
-
self.left_indicator.enable()
|
189
|
-
if index == len(self.options)-1:
|
190
|
-
self.right_indicator.disable()
|
191
|
-
else:
|
192
|
-
self.right_indicator.enable()
|
193
|
-
return self
|
194
|
-
|
195
|
-
def paint(self):
|
196
|
-
super().paint()
|
197
|
-
self.left_indicator.show()
|
198
|
-
self.right_indicator.show()
|
199
|
-
if not self.allow_cycle and self.current_index == 0:
|
200
|
-
self.left_indicator.hide()
|
201
|
-
elif not self.allow_cycle and self.current_index== len(self.options)-1:
|
202
|
-
self.right_indicator.hide()
|
203
|
-
|
204
|
-
def set_by_value(self,value:str)->Self:
|
205
|
-
if not self.is_enabled : return
|
206
|
-
if value not in self.options : return self
|
207
|
-
index = self.options.index(value)
|
208
|
-
self.set_by_index(index)
|
209
|
-
return self
|
210
|
-
|
211
|
-
def on_key_down(self, key: int) -> bool:
|
212
|
-
if not self.is_enabled:
|
213
|
-
return False
|
214
|
-
|
215
|
-
key_actions = {
|
216
|
-
pygame.K_RIGHT: self.right_indicator,
|
217
|
-
pygame.K_SPACE: self.right_indicator,
|
218
|
-
pygame.K_LEFT: self.left_indicator
|
219
|
-
}
|
220
|
-
|
221
|
-
indicator = key_actions.get(key)
|
222
|
-
if indicator and indicator.visible and indicator.is_enabled:
|
223
|
-
indicator.on_click_down(1)
|
224
|
-
return True
|
225
|
-
|
226
|
-
return False
|
227
|
-
|
228
|
-
def on_key_up(self, key: int) -> bool:
|
229
|
-
if not self.is_enabled:
|
230
|
-
return False
|
231
|
-
|
232
|
-
key_actions = {
|
233
|
-
pygame.K_RIGHT: self.right_indicator,
|
234
|
-
pygame.K_SPACE: self.right_indicator,
|
235
|
-
pygame.K_LEFT: self.left_indicator
|
236
|
-
}
|
237
|
-
|
238
|
-
indicator = key_actions.get(key)
|
239
|
-
if indicator and indicator.visible and indicator.is_enabled:
|
240
|
-
indicator.on_click_up(1)
|
241
|
-
return True
|
242
|
-
|
243
|
-
return False
|
244
|
-
|
245
|
-
def do_on_click_down(self, button) -> None:
|
246
|
-
if self.is_enabled and button == 1:
|
247
|
-
if not self.get_focus():
|
248
|
-
return True
|
249
|
-
return False
|
250
|
-
|