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