batframework 1.0.9a10__py3-none-any.whl → 1.0.9a12__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 +2 -0
- batFramework/action.py +280 -279
- batFramework/actionContainer.py +105 -82
- batFramework/animatedSprite.py +80 -58
- batFramework/animation.py +91 -77
- batFramework/audioManager.py +156 -131
- batFramework/baseScene.py +249 -240
- batFramework/camera.py +245 -317
- batFramework/constants.py +57 -51
- batFramework/cutscene.py +239 -253
- batFramework/cutsceneManager.py +34 -34
- batFramework/drawable.py +107 -77
- batFramework/dynamicEntity.py +30 -30
- batFramework/easingController.py +58 -58
- batFramework/entity.py +130 -130
- batFramework/enums.py +171 -135
- batFramework/fontManager.py +65 -65
- batFramework/gui/__init__.py +28 -25
- batFramework/gui/animatedLabel.py +90 -89
- batFramework/gui/button.py +17 -17
- batFramework/gui/clickableWidget.py +244 -245
- batFramework/gui/collapseContainer.py +98 -0
- batFramework/gui/constraints/__init__.py +1 -1
- batFramework/gui/constraints/constraints.py +1066 -980
- batFramework/gui/container.py +220 -201
- batFramework/gui/debugger.py +140 -130
- batFramework/gui/draggableWidget.py +63 -44
- batFramework/gui/image.py +61 -58
- batFramework/gui/indicator.py +116 -113
- batFramework/gui/interactiveWidget.py +243 -239
- batFramework/gui/label.py +147 -344
- batFramework/gui/layout.py +442 -426
- batFramework/gui/meter.py +155 -96
- batFramework/gui/radioButton.py +43 -35
- batFramework/gui/root.py +228 -228
- batFramework/gui/scrollingContainer.py +282 -0
- batFramework/gui/selector.py +232 -250
- batFramework/gui/shape.py +286 -276
- batFramework/gui/slider.py +353 -397
- batFramework/gui/style.py +10 -10
- batFramework/gui/styleManager.py +49 -54
- batFramework/gui/syncedVar.py +43 -49
- batFramework/gui/textInput.py +331 -306
- batFramework/gui/textWidget.py +308 -0
- batFramework/gui/toggle.py +140 -128
- batFramework/gui/tooltip.py +35 -30
- batFramework/gui/widget.py +546 -521
- batFramework/manager.py +131 -134
- batFramework/particle.py +118 -118
- batFramework/propertyEaser.py +79 -79
- batFramework/renderGroup.py +34 -34
- batFramework/resourceManager.py +130 -130
- batFramework/scene.py +31 -31
- batFramework/sceneLayer.py +134 -138
- batFramework/sceneManager.py +200 -197
- batFramework/scrollingSprite.py +115 -115
- batFramework/sprite.py +46 -51
- batFramework/stateMachine.py +49 -54
- batFramework/templates/__init__.py +2 -1
- batFramework/templates/character.py +15 -0
- batFramework/templates/controller.py +158 -97
- batFramework/templates/stateMachine.py +39 -0
- batFramework/tileset.py +46 -46
- batFramework/timeManager.py +213 -213
- batFramework/transition.py +162 -162
- batFramework/triggerZone.py +22 -22
- batFramework/utils.py +306 -306
- {batframework-1.0.9a10.dist-info → batframework-1.0.9a12.dist-info}/LICENSE +20 -20
- {batframework-1.0.9a10.dist-info → batframework-1.0.9a12.dist-info}/METADATA +24 -17
- batframework-1.0.9a12.dist-info/RECORD +72 -0
- batframework-1.0.9a10.dist-info/RECORD +0 -67
- {batframework-1.0.9a10.dist-info → batframework-1.0.9a12.dist-info}/WHEEL +0 -0
- {batframework-1.0.9a10.dist-info → batframework-1.0.9a12.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,308 @@
|
|
1
|
+
from math import ceil
|
2
|
+
import pygame
|
3
|
+
from .widget import Widget
|
4
|
+
import batFramework as bf
|
5
|
+
from typing import Literal, Self,Union
|
6
|
+
|
7
|
+
class TextWidget(Widget):
|
8
|
+
def __init__(self, text:str):
|
9
|
+
super().__init__()
|
10
|
+
self.text = text
|
11
|
+
|
12
|
+
# Allows scrolling the text
|
13
|
+
self.allow_scroll : bool = True
|
14
|
+
|
15
|
+
# Scroll variable
|
16
|
+
# TODO make scroll work
|
17
|
+
self.scroll :pygame.Vector2 = pygame.Vector2(0,0)
|
18
|
+
|
19
|
+
# Enable/Disable antialiasing
|
20
|
+
self.antialias: bool = bf.FontManager().DEFAULT_ANTIALIAS
|
21
|
+
|
22
|
+
self.text_size = bf.FontManager().DEFAULT_FONT_SIZE
|
23
|
+
|
24
|
+
self.auto_wraplength: bool = False
|
25
|
+
|
26
|
+
self.text_color: tuple[int, int, int] | str = "black"
|
27
|
+
|
28
|
+
self.text_bg_color : tuple[int,int,int]| str | None = None
|
29
|
+
|
30
|
+
|
31
|
+
self.text_outline_color: tuple[int, int, int] | str = "gray50"
|
32
|
+
|
33
|
+
self._text_outline_mask = pygame.Mask((3, 3), fill=True)
|
34
|
+
|
35
|
+
self.line_alignment = pygame.FONT_LEFT
|
36
|
+
# font name (given when loaded by utils) to use for the text
|
37
|
+
|
38
|
+
self.font_name = None
|
39
|
+
# reference to the font object
|
40
|
+
self.font_object = None
|
41
|
+
# Rect containing the text of the label
|
42
|
+
self.show_text_outline: bool = False
|
43
|
+
|
44
|
+
self.is_italic: bool = False
|
45
|
+
|
46
|
+
self.is_bold: bool = False
|
47
|
+
|
48
|
+
self.is_underlined: bool = False
|
49
|
+
|
50
|
+
super().__init__()
|
51
|
+
self.set_debug_color("purple")
|
52
|
+
self.set_autoresize(True)
|
53
|
+
self.set_font(force=True)
|
54
|
+
self.set_convert_alpha(True)
|
55
|
+
|
56
|
+
|
57
|
+
def set_padding(self, value): # can't set padding
|
58
|
+
return self
|
59
|
+
|
60
|
+
def __str__(self) -> str:
|
61
|
+
return f"TextWidget({repr(self.text)})"
|
62
|
+
|
63
|
+
def set_allow_scroll(self, value:bool)->Self:
|
64
|
+
if self.allow_scroll == value: return self
|
65
|
+
self.allow_scroll = value
|
66
|
+
self.dirty_surface = True
|
67
|
+
return self
|
68
|
+
|
69
|
+
def set_scroll(self,x=None,y=None)->Self:
|
70
|
+
x = x if x is not None else self.scroll.x
|
71
|
+
y = y if y is not None else self.scroll.y
|
72
|
+
|
73
|
+
self.scroll.update(x,y)
|
74
|
+
self.dirty_surface = True
|
75
|
+
return self
|
76
|
+
|
77
|
+
def scroll_by(self,x=0,y=0)->Self:
|
78
|
+
self.scroll += x,y
|
79
|
+
self.dirty_surface = True
|
80
|
+
return self
|
81
|
+
|
82
|
+
def set_text_color(self, color) -> Self:
|
83
|
+
self.text_color = color
|
84
|
+
self.dirty_surface = True
|
85
|
+
return self
|
86
|
+
|
87
|
+
def set_text_bg_color(self, color) -> Self:
|
88
|
+
self.text_bg_color = color
|
89
|
+
self.set_convert_alpha(color is None)
|
90
|
+
self.dirty_surface = True
|
91
|
+
return self
|
92
|
+
|
93
|
+
|
94
|
+
def top_at(self, x, y):
|
95
|
+
return None
|
96
|
+
|
97
|
+
def set_line_alignment(self, alignment: Union[Literal["left"], Literal["right"], Literal["center"]]) -> Self:
|
98
|
+
self.line_alignment = alignment
|
99
|
+
self.dirty_surface = True
|
100
|
+
return self
|
101
|
+
|
102
|
+
def set_italic(self, value: bool) -> Self:
|
103
|
+
if value == self.is_italic:
|
104
|
+
return self
|
105
|
+
self.is_italic = value
|
106
|
+
if self.autoresize_h or self.autoresize_w:
|
107
|
+
self.dirty_shape = True
|
108
|
+
else:
|
109
|
+
self.dirty_surface = True
|
110
|
+
return self
|
111
|
+
|
112
|
+
def set_bold(self, value: bool) -> Self:
|
113
|
+
if value == self.is_bold:
|
114
|
+
return self
|
115
|
+
self.is_bold = value
|
116
|
+
if self.autoresize_h or self.autoresize_w:
|
117
|
+
self.dirty_shape = True
|
118
|
+
else:
|
119
|
+
self.dirty_surface = True
|
120
|
+
return self
|
121
|
+
|
122
|
+
def set_underlined(self, value: bool) -> Self:
|
123
|
+
if value == self.is_underlined:
|
124
|
+
return self
|
125
|
+
self.is_underlined = value
|
126
|
+
self.dirty_surface = True
|
127
|
+
return self
|
128
|
+
|
129
|
+
def set_text_outline_mask_size(self,size:tuple[int,int])->Self:
|
130
|
+
old_size = self._text_outline_mask.get_size()
|
131
|
+
min_w, min_h = min(old_size[0], size[0]), min(old_size[1], size[1])
|
132
|
+
m = [
|
133
|
+
[self._text_outline_mask.get_at((x, y)) for x in range(min_w)]
|
134
|
+
for y in range(min_h)
|
135
|
+
]
|
136
|
+
self._text_outline_mask = pygame.Mask(size, fill=True)
|
137
|
+
self.set_text_outline_matrix(m)
|
138
|
+
return self
|
139
|
+
|
140
|
+
def set_text_outline_matrix(self, matrix: list[list[0 | 1]]) -> Self:
|
141
|
+
if matrix is None:
|
142
|
+
matrix = [[0 for _ in range(3)] for _ in range(3)]
|
143
|
+
for y in range(3):
|
144
|
+
for x in range(3):
|
145
|
+
self._text_outline_mask.set_at((x, y), matrix[2 - y][2 - x])
|
146
|
+
self.dirty_shape = True
|
147
|
+
return self
|
148
|
+
|
149
|
+
def set_text_outline_color(self, color) -> Self:
|
150
|
+
self.text_outline_color = color
|
151
|
+
self.dirty_surface = True
|
152
|
+
return self
|
153
|
+
|
154
|
+
def set_show_text_outline(self,value:bool) -> Self:
|
155
|
+
self.show_text_outline = value
|
156
|
+
self.dirty_shape = True
|
157
|
+
return self
|
158
|
+
|
159
|
+
def set_auto_wraplength(self, val: bool) -> Self:
|
160
|
+
self.auto_wraplength = val
|
161
|
+
if self.autoresize_h or self.autoresize_w:
|
162
|
+
self.dirty_shape = True
|
163
|
+
else:
|
164
|
+
self.dirty_surface = True
|
165
|
+
return self
|
166
|
+
|
167
|
+
def get_debug_outlines(self):
|
168
|
+
if self.visible:
|
169
|
+
yield from super().get_debug_outlines()
|
170
|
+
|
171
|
+
def set_font(self, font_name: str = None, force: bool = False) -> Self:
|
172
|
+
if font_name == self.font_name and not force:
|
173
|
+
return self
|
174
|
+
self.font_name = font_name
|
175
|
+
self.font_object = bf.FontManager().get_font(self.font_name, self.text_size)
|
176
|
+
if self.autoresize_h or self.autoresize_w:
|
177
|
+
self.dirty_shape = True
|
178
|
+
else:
|
179
|
+
self.dirty_surface = True
|
180
|
+
return self
|
181
|
+
|
182
|
+
def set_text_size(self, text_size: int) -> Self:
|
183
|
+
text_size = (text_size // 2) * 2
|
184
|
+
if text_size == self.text_size:
|
185
|
+
return self
|
186
|
+
self.text_size = text_size
|
187
|
+
self.font_object = bf.FontManager().get_font(self.font_name, self.text_size)
|
188
|
+
self.dirty_shape = True
|
189
|
+
return self
|
190
|
+
|
191
|
+
def get_text_size(self) -> int:
|
192
|
+
return self.text_size
|
193
|
+
|
194
|
+
|
195
|
+
def is_antialias(self) -> bool:
|
196
|
+
return self.antialias
|
197
|
+
|
198
|
+
def set_antialias(self, value: bool) -> Self:
|
199
|
+
self.antialias = value
|
200
|
+
self.dirty_surface = True
|
201
|
+
return self
|
202
|
+
|
203
|
+
def set_text(self, text: str) -> Self:
|
204
|
+
if text == self.text:
|
205
|
+
return self
|
206
|
+
self.text = text
|
207
|
+
self.dirty_shape = True
|
208
|
+
return self
|
209
|
+
|
210
|
+
def get_min_required_size(self) -> tuple[float, float]:
|
211
|
+
if not self.font_object : return 0,0
|
212
|
+
|
213
|
+
tmp_text = self.text
|
214
|
+
if self.text.endswith('\n'):
|
215
|
+
tmp_text+=" " # hack to have correct size if ends with newline
|
216
|
+
params = {
|
217
|
+
"font_name": self.font_object.name,
|
218
|
+
"text": tmp_text,
|
219
|
+
"antialias": self.antialias,
|
220
|
+
"color": self.text_color,
|
221
|
+
"bgcolor": self.text_bg_color,
|
222
|
+
"wraplength": int(self.get_inner_width()) if self.auto_wraplength and not self.autoresize_w else 0,
|
223
|
+
}
|
224
|
+
|
225
|
+
size = list(self._render_font(params).get_size())
|
226
|
+
size[1]= max(size[1],self.font_object.get_ascent() - self.font_object.get_descent())
|
227
|
+
if not self.show_text_outline:
|
228
|
+
return size
|
229
|
+
s = self._get_outline_offset()
|
230
|
+
return size[0] + s[0]*2, size[1] + s[1]*2
|
231
|
+
|
232
|
+
|
233
|
+
def get_text(self) -> str:
|
234
|
+
return self.text
|
235
|
+
|
236
|
+
def _render_font(self, params: dict) -> pygame.Surface:
|
237
|
+
params.pop("font_name")
|
238
|
+
# save old settings
|
239
|
+
old_italic = self.font_object.get_italic()
|
240
|
+
old_bold = self.font_object.get_bold()
|
241
|
+
old_underline = self.font_object.get_underline()
|
242
|
+
old_align = self.font_object.align
|
243
|
+
# setup font
|
244
|
+
self.font_object.set_italic(self.is_italic)
|
245
|
+
self.font_object.set_bold(self.is_bold)
|
246
|
+
self.font_object.set_underline(self.is_underlined)
|
247
|
+
self.font_object.align = self.line_alignment
|
248
|
+
surf = self.font_object.render(**params)
|
249
|
+
# reset font
|
250
|
+
self.font_object.set_italic(old_italic)
|
251
|
+
self.font_object.set_bold(old_bold)
|
252
|
+
self.font_object.set_underline(old_underline)
|
253
|
+
self.font_object.align = old_align
|
254
|
+
return surf
|
255
|
+
|
256
|
+
def _get_outline_offset(self)->tuple[int,int]:
|
257
|
+
mask_size = self._text_outline_mask.get_size()
|
258
|
+
return mask_size[0]//2,mask_size[1]//2
|
259
|
+
|
260
|
+
|
261
|
+
def build(self) -> bool:
|
262
|
+
"""
|
263
|
+
return True if size changed
|
264
|
+
"""
|
265
|
+
target_size = self.resolve_size(self.get_min_required_size())
|
266
|
+
if self.rect.size != target_size:
|
267
|
+
self.set_size(target_size)
|
268
|
+
return True
|
269
|
+
return False
|
270
|
+
|
271
|
+
|
272
|
+
|
273
|
+
def paint(self) -> None:
|
274
|
+
self._resize_surface()
|
275
|
+
if self.font_object is None:
|
276
|
+
print(f"No font for widget with text : '{self}' :(")
|
277
|
+
return
|
278
|
+
|
279
|
+
|
280
|
+
wrap = int(self.get_inner_width()) if self.auto_wraplength and not self.autoresize_w else 0
|
281
|
+
params = {
|
282
|
+
"font_name": self.font_object.name,
|
283
|
+
"text": self.text,
|
284
|
+
"antialias": self.antialias,
|
285
|
+
"color": self.text_color,
|
286
|
+
"bgcolor": self.text_bg_color if not self.show_text_outline else None,
|
287
|
+
"wraplength": wrap,
|
288
|
+
}
|
289
|
+
|
290
|
+
if self.text_bg_color is None :
|
291
|
+
self.surface = self.surface.convert_alpha()
|
292
|
+
|
293
|
+
bg_fill_color = (0, 0, 0, 0) if self.text_bg_color is None else self.text_bg_color
|
294
|
+
self.surface.fill(bg_fill_color)
|
295
|
+
|
296
|
+
text_surf = self._render_font(params)
|
297
|
+
|
298
|
+
if self.show_text_outline:
|
299
|
+
mask = pygame.mask.from_surface(text_surf).convolve(self._text_outline_mask)
|
300
|
+
outline_surf = mask.to_surface(
|
301
|
+
setcolor=self.text_outline_color,
|
302
|
+
unsetcolor=bg_fill_color
|
303
|
+
)
|
304
|
+
|
305
|
+
outline_surf.blit(text_surf,self._get_outline_offset())
|
306
|
+
text_surf = outline_surf
|
307
|
+
|
308
|
+
self.surface.blit(text_surf, -self.scroll)
|
batFramework/gui/toggle.py
CHANGED
@@ -1,128 +1,140 @@
|
|
1
|
-
from .
|
2
|
-
from .
|
3
|
-
from .
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
self
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
self.value = value
|
23
|
-
|
24
|
-
self.
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
self.
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
self.
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
self.
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
bf.
|
107
|
-
bf.
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
1
|
+
from .widget import Widget
|
2
|
+
from .button import Button
|
3
|
+
from .indicator import Indicator, ToggleIndicator
|
4
|
+
from .shape import Shape
|
5
|
+
import batFramework as bf
|
6
|
+
from typing import Self, Callable, Any
|
7
|
+
import pygame
|
8
|
+
from .syncedVar import SyncedVar # Adjust import path
|
9
|
+
|
10
|
+
class Toggle(Button):
|
11
|
+
def __init__(
|
12
|
+
self,
|
13
|
+
text: str = "",
|
14
|
+
callback: Callable[[bool], Any] = None,
|
15
|
+
default_value: bool = False,
|
16
|
+
synced_var: SyncedVar[bool] = None,
|
17
|
+
) -> None:
|
18
|
+
# Use passed SyncedVar or create a new one
|
19
|
+
self.synced_var: SyncedVar[bool] = synced_var or SyncedVar(default_value)
|
20
|
+
|
21
|
+
# Local value synced to SyncedVar.value
|
22
|
+
self.value: bool = self.synced_var.value
|
23
|
+
|
24
|
+
self.indicator: ToggleIndicator = ToggleIndicator(self.value)
|
25
|
+
self.gap: float | int = 0
|
26
|
+
self.spacing: bf.spacing = bf.spacing.MANUAL
|
27
|
+
|
28
|
+
super().__init__(text, callback)
|
29
|
+
|
30
|
+
# Add indicator to widget
|
31
|
+
self.add(self.indicator)
|
32
|
+
self.set_clip_children(False)
|
33
|
+
|
34
|
+
# Bind this toggle’s _on_synced_var_update to synced_var updates
|
35
|
+
self.synced_var.bind(self, self._on_synced_var_update)
|
36
|
+
|
37
|
+
def _on_synced_var_update(self, new_value: bool) -> None:
|
38
|
+
# Called when SyncedVar changes externally
|
39
|
+
if self.value != new_value:
|
40
|
+
self.set_value(new_value, do_callback=False)
|
41
|
+
|
42
|
+
|
43
|
+
def set_indicator(self,indicator:Indicator):
|
44
|
+
self.remove(self.indicator)
|
45
|
+
self.synced_var.unbind(self.indicator)
|
46
|
+
self.indicator = indicator
|
47
|
+
self.add(self.indicator)
|
48
|
+
def set_visible(self, value: bool) -> Self:
|
49
|
+
self.indicator.set_visible(value)
|
50
|
+
return super().set_visible(value)
|
51
|
+
|
52
|
+
def set_value(self, value: bool, do_callback=False) -> Self:
|
53
|
+
if self.value == value:
|
54
|
+
return self # No change
|
55
|
+
|
56
|
+
self.value = value
|
57
|
+
self.indicator.set_value(value)
|
58
|
+
self.dirty_surface = True
|
59
|
+
|
60
|
+
# Update SyncedVar only if different (avoid recursion)
|
61
|
+
if self.synced_var.value != value:
|
62
|
+
self.synced_var.value = value
|
63
|
+
|
64
|
+
if do_callback and self.callback:
|
65
|
+
self.callback(self.value)
|
66
|
+
return self
|
67
|
+
|
68
|
+
def set_spacing(self, spacing: bf.spacing) -> Self:
|
69
|
+
if spacing == self.spacing:
|
70
|
+
return self
|
71
|
+
self.spacing = spacing
|
72
|
+
self.dirty_shape = True
|
73
|
+
return self
|
74
|
+
|
75
|
+
def click(self) -> None:
|
76
|
+
self.set_value(not self.value, do_callback=True)
|
77
|
+
|
78
|
+
def set_gap(self, value: int | float) -> Self:
|
79
|
+
value = max(0, value)
|
80
|
+
if value == self.gap:
|
81
|
+
return self
|
82
|
+
self.gap = value
|
83
|
+
self.dirty_shape = True
|
84
|
+
return self
|
85
|
+
|
86
|
+
def __str__(self) -> str:
|
87
|
+
return f"Toggle({self.value})"
|
88
|
+
|
89
|
+
def toggle(self) -> None:
|
90
|
+
self.set_value(not self.value, do_callback=True)
|
91
|
+
|
92
|
+
def get_min_required_size(self) -> tuple[float, float]:
|
93
|
+
left = self.text_widget.get_min_required_size()
|
94
|
+
gap = self.gap if self.text_widget.text else 0
|
95
|
+
full_rect = pygame.FRect(0, 0, left[0] + left[1] + gap, left[1])
|
96
|
+
full_rect.h += self.unpressed_relief
|
97
|
+
return self.expand_rect_with_padding((0, 0, *full_rect.size)).size
|
98
|
+
|
99
|
+
def _align_composed(self, left: Shape, right: Shape):
|
100
|
+
full_rect = self.get_inner_rect()
|
101
|
+
left_rect = left.rect
|
102
|
+
right_rect = right.rect
|
103
|
+
gap = {
|
104
|
+
bf.spacing.MIN: 0,
|
105
|
+
bf.spacing.HALF: (full_rect.width - left_rect.width - right_rect.width) // 2,
|
106
|
+
bf.spacing.MAX: full_rect.width - left_rect.width - right_rect.width,
|
107
|
+
bf.spacing.MANUAL: self.gap,
|
108
|
+
}.get(self.spacing, 0)
|
109
|
+
|
110
|
+
gap = max(0, gap)
|
111
|
+
combined_width = left_rect.width + right_rect.width + gap
|
112
|
+
|
113
|
+
group_x = {
|
114
|
+
bf.alignment.LEFT: full_rect.left,
|
115
|
+
bf.alignment.MIDLEFT: full_rect.left,
|
116
|
+
bf.alignment.RIGHT: full_rect.right - combined_width,
|
117
|
+
bf.alignment.MIDRIGHT: full_rect.right - combined_width,
|
118
|
+
bf.alignment.CENTER: full_rect.centerx - combined_width // 2,
|
119
|
+
}.get(self.alignment, full_rect.left)
|
120
|
+
|
121
|
+
# Set horizontal positions
|
122
|
+
left.set_position(x=group_x)
|
123
|
+
right.set_position(x=group_x + left_rect.width + gap)
|
124
|
+
|
125
|
+
# Set vertical positions
|
126
|
+
if self.alignment in {bf.alignment.TOP, bf.alignment.TOPLEFT, bf.alignment.TOPRIGHT}:
|
127
|
+
left.set_position(y=full_rect.top)
|
128
|
+
right.set_position(y=full_rect.top)
|
129
|
+
elif self.alignment in {bf.alignment.BOTTOM, bf.alignment.BOTTOMLEFT, bf.alignment.BOTTOMRIGHT}:
|
130
|
+
left.set_position(y=full_rect.bottom - left_rect.height)
|
131
|
+
right.set_position(y=full_rect.bottom - right_rect.height)
|
132
|
+
else:
|
133
|
+
left.set_center(y=full_rect.centery)
|
134
|
+
right.set_center(y=full_rect.centery)
|
135
|
+
|
136
|
+
def build(self) -> None:
|
137
|
+
res = super().build()
|
138
|
+
self.indicator.set_size(self.indicator.resolve_size((self.text_widget.rect.h, self.text_widget.rect.h)))
|
139
|
+
self._align_composed(self.text_widget, self.indicator)
|
140
|
+
return res
|
batFramework/gui/tooltip.py
CHANGED
@@ -1,30 +1,35 @@
|
|
1
|
-
from .label import Label
|
2
|
-
import batFramework as bf
|
3
|
-
import sys
|
4
|
-
|
5
|
-
class ToolTip(Label):
|
6
|
-
def __init__(self, text = ""):
|
7
|
-
super().__init__(text)
|
8
|
-
self.fade_in_duration : float = 0.1
|
9
|
-
self.fade_out_duration : float = 0.1
|
10
|
-
self.set_render_order(sys.maxsize)
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
self.
|
28
|
-
|
29
|
-
|
30
|
-
|
1
|
+
from .label import Label
|
2
|
+
import batFramework as bf
|
3
|
+
import sys
|
4
|
+
|
5
|
+
class ToolTip(Label):
|
6
|
+
def __init__(self, text = ""):
|
7
|
+
super().__init__(text)
|
8
|
+
self.fade_in_duration : float = 0.1
|
9
|
+
self.fade_out_duration : float = 0.1
|
10
|
+
self.set_render_order(sys.maxsize)
|
11
|
+
self.set_padding(2)
|
12
|
+
|
13
|
+
def __str__(self):
|
14
|
+
return f"ToolTip('{self.text_widget.text}')"
|
15
|
+
|
16
|
+
def top_at(self, x, y):
|
17
|
+
return None
|
18
|
+
|
19
|
+
def set_all_alpha(self,value:int):
|
20
|
+
self.text_widget.set_alpha(value)
|
21
|
+
return self.set_alpha(value)
|
22
|
+
|
23
|
+
def fade_in(self):
|
24
|
+
self.set_visible(True)
|
25
|
+
bf.PropertyEaser(
|
26
|
+
self.fade_in_duration,bf.easing.EASE_OUT,
|
27
|
+
0,self.parent_scene.name
|
28
|
+
).add_custom(self.get_alpha,self.set_all_alpha,255).start()
|
29
|
+
|
30
|
+
def fade_out(self):
|
31
|
+
bf.PropertyEaser(
|
32
|
+
self.fade_out_duration,bf.easing.EASE_IN,
|
33
|
+
0,self.parent_scene.name,
|
34
|
+
lambda : self.set_visible(False)
|
35
|
+
).add_custom(self.get_alpha,self.set_all_alpha,0).start()
|