batframework 1.0.7__py3-none-any.whl → 1.0.8a1__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 +24 -15
- batFramework/action.py +95 -106
- batFramework/actionContainer.py +11 -8
- batFramework/animatedSprite.py +60 -43
- batFramework/audioManager.py +52 -22
- batFramework/camera.py +87 -72
- batFramework/constants.py +19 -41
- batFramework/cutscene.py +12 -11
- batFramework/cutsceneBlocks.py +12 -14
- batFramework/dynamicEntity.py +5 -4
- batFramework/easingController.py +58 -0
- batFramework/entity.py +37 -130
- batFramework/enums.py +93 -3
- batFramework/fontManager.py +15 -7
- batFramework/gui/__init__.py +5 -1
- batFramework/gui/button.py +6 -144
- batFramework/gui/clickableWidget.py +206 -0
- batFramework/gui/constraints/__init__.py +1 -0
- batFramework/gui/constraints/constraints.py +378 -0
- batFramework/gui/container.py +147 -34
- batFramework/gui/debugger.py +39 -22
- batFramework/gui/dialogueBox.py +69 -43
- batFramework/gui/draggableWidget.py +38 -0
- batFramework/gui/image.py +33 -28
- batFramework/gui/indicator.py +30 -16
- batFramework/gui/interactiveWidget.py +72 -20
- batFramework/gui/label.py +240 -98
- batFramework/gui/layout.py +125 -53
- batFramework/gui/meter.py +76 -0
- batFramework/gui/radioButton.py +62 -0
- batFramework/gui/root.py +72 -48
- batFramework/gui/shape.py +257 -49
- batFramework/gui/slider.py +217 -2
- batFramework/gui/textInput.py +106 -60
- batFramework/gui/toggle.py +85 -42
- batFramework/gui/widget.py +259 -288
- batFramework/manager.py +30 -16
- batFramework/object.py +115 -0
- batFramework/{particles.py → particle.py} +37 -34
- batFramework/renderGroup.py +62 -0
- batFramework/resourceManager.py +36 -24
- batFramework/scene.py +94 -88
- batFramework/sceneManager.py +140 -57
- batFramework/scrollingSprite.py +113 -0
- batFramework/sprite.py +35 -23
- batFramework/tileset.py +34 -52
- batFramework/time.py +105 -56
- batFramework/transition.py +213 -1
- batFramework/utils.py +38 -18
- {batframework-1.0.7.dist-info → batframework-1.0.8a1.dist-info}/METADATA +1 -1
- batframework-1.0.8a1.dist-info/RECORD +56 -0
- {batframework-1.0.7.dist-info → batframework-1.0.8a1.dist-info}/WHEEL +1 -1
- batFramework/easing.py +0 -76
- batFramework/gui/constraints.py +0 -277
- batFramework/gui/frame.py +0 -25
- batFramework/transitionManager.py +0 -0
- batframework-1.0.7.dist-info/RECORD +0 -50
- {batframework-1.0.7.dist-info → batframework-1.0.8a1.dist-info}/LICENCE +0 -0
- {batframework-1.0.7.dist-info → batframework-1.0.8a1.dist-info}/top_level.txt +0 -0
batFramework/gui/textInput.py
CHANGED
@@ -1,88 +1,134 @@
|
|
1
1
|
import batFramework as bf
|
2
|
-
from typing import Self
|
2
|
+
from typing import Self,Callable
|
3
3
|
from .label import Label
|
4
4
|
from .interactiveWidget import InteractiveWidget
|
5
5
|
import pygame
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
|
8
|
+
class TextInput(Label, InteractiveWidget):
|
9
|
+
def __init__(self) -> None:
|
9
10
|
self.cursor_position = 0
|
10
|
-
self.
|
11
|
-
|
12
|
-
self.
|
11
|
+
self.old_key_repeat: tuple = (0, 0)
|
12
|
+
self.cursor_timer = bf.Timer(0.3, self._cursor_toggle, loop=True).start()
|
13
|
+
self.cursor_timer.pause()
|
14
|
+
self.show_cursor: bool = False
|
15
|
+
self.on_modify :Callable[[str],str] = None
|
13
16
|
self.set_focusable(True)
|
14
17
|
self.set_outline_color("black")
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
self.
|
18
|
+
super().__init__("")
|
19
|
+
|
20
|
+
def set_modify_callback(self,callback : Callable[[str],str])->Self:
|
21
|
+
self.on_modify = callback
|
22
|
+
return self
|
19
23
|
|
20
24
|
def to_string_id(self) -> str:
|
21
|
-
return f"TextInput({self.
|
25
|
+
return f"TextInput({self.text})"
|
22
26
|
|
23
|
-
def _cursor_toggle(self):
|
24
|
-
|
25
|
-
self.
|
27
|
+
def _cursor_toggle(self,value:bool = None):
|
28
|
+
if value is None : value = not self.show_cursor
|
29
|
+
self.show_cursor = value
|
30
|
+
self.dirty_surface = True
|
26
31
|
|
27
|
-
def
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
def do_on_click_down(self,button):
|
32
|
-
if button != 1:return
|
32
|
+
def do_on_click_down(self, button):
|
33
|
+
if button != 1:
|
34
|
+
return
|
33
35
|
self.get_focus()
|
36
|
+
|
34
37
|
def do_on_enter(self):
|
35
38
|
pygame.mouse.set_cursor(pygame.SYSTEM_CURSOR_IBEAM)
|
36
39
|
|
37
40
|
def do_on_exit(self):
|
38
|
-
pygame.mouse.set_cursor(
|
41
|
+
pygame.mouse.set_cursor(bf.const.DEFAULT_CURSOR)
|
39
42
|
|
40
43
|
def do_on_get_focus(self):
|
41
|
-
self.set_outline_width(2)
|
42
44
|
self.old_key_repeat = pygame.key.get_repeat()
|
43
|
-
self.
|
44
|
-
|
45
|
+
self.cursor_timer.resume()
|
46
|
+
self._cursor_toggle(True)
|
47
|
+
pygame.key.set_repeat(200, 50)
|
48
|
+
|
45
49
|
def do_on_lose_focus(self):
|
46
|
-
self.
|
47
|
-
self.
|
50
|
+
self.cursor_timer.pause()
|
51
|
+
self._cursor_toggle(False)
|
48
52
|
pygame.key.set_repeat(*self.old_key_repeat)
|
49
53
|
|
50
|
-
def set_cursor_position(self,position:int)->Self:
|
51
|
-
if position < 0
|
52
|
-
|
54
|
+
def set_cursor_position(self, position: int) -> Self:
|
55
|
+
if position < 0:
|
56
|
+
position = 0
|
57
|
+
elif position > len(self.get_text()):
|
58
|
+
position = len(self.get_text())
|
53
59
|
self.cursor_position = position
|
54
|
-
self.
|
60
|
+
self.show_cursor = True
|
61
|
+
self.dirty_surface = True
|
62
|
+
if self.text_rect.w > self.get_padded_width():
|
63
|
+
self.dirty_shape = True
|
55
64
|
return self
|
56
65
|
|
57
|
-
def do_handle_event(self,event)
|
66
|
+
def do_handle_event(self, event):
|
67
|
+
if not self.is_focused:
|
68
|
+
return
|
58
69
|
text = self.get_text()
|
59
|
-
|
70
|
+
cursor_position = self.cursor_position
|
71
|
+
|
60
72
|
if event.type == pygame.TEXTINPUT:
|
61
|
-
self.set_text(text[:
|
62
|
-
self.set_cursor_position(
|
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
|
-
super().
|
88
|
-
|
73
|
+
self.set_text(text[:cursor_position] + event.text + text[cursor_position:])
|
74
|
+
self.set_cursor_position(cursor_position + 1)
|
75
|
+
elif event.type == pygame.KEYDOWN:
|
76
|
+
if event.key == pygame.K_ESCAPE:
|
77
|
+
self.lose_focus()
|
78
|
+
|
79
|
+
elif event.key == pygame.K_BACKSPACE:
|
80
|
+
if cursor_position > 0:
|
81
|
+
self.set_text(text[:cursor_position - 1] + text[cursor_position:])
|
82
|
+
self.set_cursor_position(cursor_position - 1)
|
83
|
+
|
84
|
+
elif event.key == pygame.K_RIGHT:
|
85
|
+
self.set_cursor_position(cursor_position + 1)
|
86
|
+
|
87
|
+
elif event.key == pygame.K_LEFT:
|
88
|
+
self.set_cursor_position(cursor_position - 1)
|
89
|
+
|
90
|
+
else:
|
91
|
+
return
|
92
|
+
else :
|
93
|
+
return
|
94
|
+
|
95
|
+
event.consumed = True
|
96
|
+
|
97
|
+
def set_text(self, text: str) -> Self:
|
98
|
+
if self.on_modify : text = self.on_modify(text)
|
99
|
+
return super().set_text(text)
|
100
|
+
|
101
|
+
def _paint_cursor(self) -> None:
|
102
|
+
if not self.font_object or not self.show_cursor:
|
103
|
+
return
|
104
|
+
partial_text_size = self.font_object.size(
|
105
|
+
self.get_text()[: self.cursor_position]
|
106
|
+
)
|
107
|
+
|
108
|
+
cursor_rect = pygame.Rect(0, 0,1, self.font_object.point_size )
|
109
|
+
if self.cursor_position != 0: # align left properly
|
110
|
+
cursor_rect.midleft = self.text_rect.move(partial_text_size[0], 0).midleft
|
111
|
+
else:
|
112
|
+
cursor_rect.midright = self.text_rect.midleft
|
113
|
+
|
114
|
+
pygame.draw.rect(self.surface, self.text_color, cursor_rect)
|
115
|
+
|
116
|
+
def paint(self) -> None:
|
117
|
+
super().paint()
|
118
|
+
self._paint_cursor()
|
119
|
+
|
120
|
+
|
121
|
+
def align_text(self,text_rect:pygame.FRect,area:pygame.FRect,alignment: bf.alignment):
|
122
|
+
if alignment == bf.alignment.LEFT : alignment = bf.alignment.MIDLEFT
|
123
|
+
elif alignment == bf.alignment.MIDRIGHT : alignment = bf.alignment.MIDRIGHT
|
124
|
+
|
125
|
+
pos = area.__getattribute__(alignment.value)
|
126
|
+
text_rect.__setattr__(alignment.value,pos)
|
127
|
+
w = self.font_object.size(
|
128
|
+
self.get_text()[: self.cursor_position]
|
129
|
+
)[0]
|
130
|
+
if self.text_rect.x + w > area.right:
|
131
|
+
self.text_rect.right = area.right
|
132
|
+
elif self.text_rect.x + w < area.left:
|
133
|
+
self.text_rect.left = area.left - w
|
134
|
+
|
batFramework/gui/toggle.py
CHANGED
@@ -1,70 +1,113 @@
|
|
1
1
|
from .button import Button
|
2
2
|
from .indicator import Indicator, ToggleIndicator
|
3
|
-
import pygame
|
4
3
|
import batFramework as bf
|
5
4
|
from typing import Self
|
6
|
-
|
5
|
+
import pygame
|
7
6
|
|
8
7
|
|
9
8
|
class Toggle(Button):
|
10
|
-
def __init__(self, text: str, default_value: bool = False
|
9
|
+
def __init__(self, text: str, callback=None,default_value: bool = False) -> None:
|
11
10
|
self.value: bool = default_value
|
12
|
-
self.
|
13
|
-
self.indicator: Indicator = ToggleIndicator(default_value)
|
11
|
+
self.indicator: ToggleIndicator = ToggleIndicator(default_value)
|
14
12
|
self.gap: float | int = 0
|
15
|
-
|
16
|
-
|
17
|
-
self.
|
18
|
-
self.
|
13
|
+
self.spacing :bf.spacing = bf.spacing.MANUAL
|
14
|
+
super().__init__(text, callback)
|
15
|
+
self.add(self.indicator)
|
16
|
+
# self.set_gap(int(max(4, self.get_padded_width() / 3)))
|
19
17
|
|
20
|
-
def set_value(self,value:bool,do_callback=False)->Self:
|
18
|
+
def set_value(self, value: bool, do_callback=False) -> Self:
|
21
19
|
self.value = value
|
22
|
-
self.
|
20
|
+
self.indicator.set_value(value)
|
21
|
+
self.dirty_surface = True
|
22
|
+
if do_callback and self.callback:
|
23
|
+
self.callback(self.value)
|
24
|
+
return self
|
23
25
|
|
24
|
-
|
26
|
+
def set_spacing(self,spacing:bf.spacing)->Self:
|
27
|
+
if spacing == self.spacing : return self
|
28
|
+
self.spacing = spacing
|
29
|
+
self.dirty_shape = True
|
25
30
|
return self
|
31
|
+
|
32
|
+
def click(self) -> None:
|
33
|
+
self.set_value(not self.value, True)
|
34
|
+
|
26
35
|
def set_gap(self, value: int | float) -> Self:
|
27
|
-
|
28
|
-
|
36
|
+
value = max(0, value)
|
37
|
+
if value == self.gap : return self
|
29
38
|
self.gap = value
|
30
|
-
self.
|
31
|
-
if self.parent:
|
32
|
-
self.parent.children_modified()
|
39
|
+
self.dirty_shape = True
|
33
40
|
return self
|
34
41
|
|
35
|
-
def
|
42
|
+
def __str__(self) -> str:
|
36
43
|
return f"Toggle({self.value})"
|
37
44
|
|
38
45
|
def toggle(self) -> None:
|
39
|
-
self.set_value(not self.value,do_callback
|
46
|
+
self.set_value(not self.value, do_callback=True)
|
40
47
|
|
48
|
+
def get_min_required_size(self) -> tuple[float, float]:
|
49
|
+
if not self.text_rect:
|
50
|
+
params = {
|
51
|
+
"font_name": self.font_object.name,
|
52
|
+
"text": self.text,
|
53
|
+
"antialias": False,
|
54
|
+
"color": "white",
|
55
|
+
"bgcolor": "black", # if (self.has_alpha_color() or self.draw_mode == bf.drawMode.TEXTURED) else self.color,
|
56
|
+
"wraplength": int(self.get_padded_width()) if self.auto_wraplength else 0,
|
57
|
+
}
|
58
|
+
self.text_rect.size = self._render_font(params).get_size()
|
59
|
+
w,h = self.text_rect.size
|
60
|
+
size = max(self.indicator.rect.w,w + self.font_object.point_size + (self.gap if self.text else 0)), max(h,self.font_object.point_size,self.indicator.rect.h)
|
61
|
+
return self.inflate_rect_by_padding((0,0,*size)).size
|
41
62
|
|
42
|
-
|
43
|
-
self.on_toggle = callback
|
44
|
-
return self
|
45
|
-
|
63
|
+
|
46
64
|
def _build_layout(self) -> None:
|
47
|
-
self.indicator.set_value(self.value)
|
48
|
-
self.indicator.set_size(self._text_rect.h,self._text_rect.h)
|
49
|
-
size = (
|
50
|
-
0,
|
51
|
-
0,
|
52
|
-
self._text_rect.w + self.indicator.rect.w + self.gap,
|
53
|
-
max(self._text_rect.h, self.indicator.rect.h),
|
54
|
-
)
|
55
65
|
|
56
|
-
|
66
|
+
gap = self.gap if self.text else 0
|
67
|
+
|
68
|
+
params = {
|
69
|
+
"font_name": self.font_object.name,
|
70
|
+
"text": self.text,
|
71
|
+
"antialias": False,
|
72
|
+
"color": "white",
|
73
|
+
"bgcolor": "black", # if (self.has_alpha_color() or self.draw_mode == bf.drawMode.TEXTURED) else self.color,
|
74
|
+
"wraplength": int(self.get_padded_width()) if self.auto_wraplength else 0,
|
75
|
+
}
|
76
|
+
self.text_rect.size = self._render_font(params).get_size()
|
77
|
+
|
78
|
+
indicator_height = self.font_object.point_size
|
57
79
|
|
58
|
-
|
59
|
-
self.set_size(*required_rect.size)
|
60
|
-
return
|
80
|
+
self.indicator.set_size((indicator_height,indicator_height))
|
61
81
|
|
62
|
-
|
63
|
-
|
82
|
+
|
83
|
+
tmp_rect = pygame.FRect(0,0,self.text_rect.w + gap + indicator_height , self.text_rect.h)
|
64
84
|
|
65
|
-
self._text_rect.midleft = required_rect_rel.midleft
|
66
|
-
r = self.indicator.rect.copy()
|
67
|
-
r.midleft = required_rect.move(self._text_rect.w + self.gap, 0).midleft
|
68
|
-
self.indicator.set_position(*r.topleft)
|
69
85
|
|
70
|
-
self.
|
86
|
+
if self.autoresize_h or self.autoresize_w:
|
87
|
+
target_rect = self.inflate_rect_by_padding(tmp_rect)
|
88
|
+
if not self.autoresize_w : target_rect.w = self.rect.w
|
89
|
+
if not self.autoresize_h : target_rect.h = self.rect.h
|
90
|
+
if self.rect.size != target_rect.size:
|
91
|
+
self.set_size(target_rect.size)
|
92
|
+
self.build()
|
93
|
+
return
|
94
|
+
|
95
|
+
padded = self.get_padded_rect().move(-self.rect.x,-self.rect.y)
|
96
|
+
|
97
|
+
self.align_text(tmp_rect,padded,self.alignment)
|
98
|
+
self.text_rect.midleft = tmp_rect.midleft
|
99
|
+
if self.text :
|
100
|
+
match self.spacing:
|
101
|
+
case bf.spacing.MAX:
|
102
|
+
gap = padded.w - self.text_rect.w - self.indicator.rect.w
|
103
|
+
case bf.spacing.MIN:
|
104
|
+
gap = 0
|
105
|
+
case bf.spacing.HALF:
|
106
|
+
gap = (padded.w)/2 - self.text_rect.w
|
107
|
+
|
108
|
+
self.indicator.set_position(
|
109
|
+
*self.text_rect.move(
|
110
|
+
self.rect.x+gap,
|
111
|
+
self.rect.y + (self.text_rect.h /2) - self.indicator.rect.h/2
|
112
|
+
).topright
|
113
|
+
)
|