batframework 1.0.6__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.
Files changed (59) hide show
  1. batFramework/__init__.py +23 -14
  2. batFramework/action.py +95 -106
  3. batFramework/actionContainer.py +11 -8
  4. batFramework/animatedSprite.py +60 -43
  5. batFramework/audioManager.py +52 -22
  6. batFramework/camera.py +87 -72
  7. batFramework/constants.py +19 -41
  8. batFramework/cutscene.py +12 -11
  9. batFramework/cutsceneBlocks.py +12 -14
  10. batFramework/dynamicEntity.py +5 -4
  11. batFramework/easingController.py +58 -0
  12. batFramework/entity.py +37 -130
  13. batFramework/enums.py +93 -3
  14. batFramework/fontManager.py +15 -7
  15. batFramework/gui/__init__.py +5 -1
  16. batFramework/gui/button.py +6 -144
  17. batFramework/gui/clickableWidget.py +206 -0
  18. batFramework/gui/constraints/__init__.py +1 -0
  19. batFramework/gui/constraints/constraints.py +378 -0
  20. batFramework/gui/container.py +147 -34
  21. batFramework/gui/debugger.py +39 -22
  22. batFramework/gui/dialogueBox.py +69 -43
  23. batFramework/gui/draggableWidget.py +38 -0
  24. batFramework/gui/image.py +33 -28
  25. batFramework/gui/indicator.py +30 -16
  26. batFramework/gui/interactiveWidget.py +72 -20
  27. batFramework/gui/label.py +240 -98
  28. batFramework/gui/layout.py +125 -53
  29. batFramework/gui/meter.py +76 -0
  30. batFramework/gui/radioButton.py +62 -0
  31. batFramework/gui/root.py +72 -48
  32. batFramework/gui/shape.py +257 -49
  33. batFramework/gui/slider.py +217 -2
  34. batFramework/gui/textInput.py +106 -60
  35. batFramework/gui/toggle.py +85 -42
  36. batFramework/gui/widget.py +259 -288
  37. batFramework/manager.py +30 -16
  38. batFramework/object.py +115 -0
  39. batFramework/{particles.py → particle.py} +37 -34
  40. batFramework/renderGroup.py +62 -0
  41. batFramework/resourceManager.py +36 -24
  42. batFramework/scene.py +94 -88
  43. batFramework/sceneManager.py +140 -57
  44. batFramework/scrollingSprite.py +113 -0
  45. batFramework/sprite.py +35 -23
  46. batFramework/tileset.py +34 -52
  47. batFramework/time.py +105 -56
  48. batFramework/transition.py +213 -1
  49. batFramework/utils.py +38 -18
  50. {batframework-1.0.6.dist-info → batframework-1.0.8a1.dist-info}/METADATA +1 -1
  51. batframework-1.0.8a1.dist-info/RECORD +56 -0
  52. {batframework-1.0.6.dist-info → batframework-1.0.8a1.dist-info}/WHEEL +1 -1
  53. batFramework/easing.py +0 -76
  54. batFramework/gui/constraints.py +0 -277
  55. batFramework/gui/frame.py +0 -25
  56. batFramework/transitionManager.py +0 -0
  57. batframework-1.0.6.dist-info/RECORD +0 -50
  58. {batframework-1.0.6.dist-info → batframework-1.0.8a1.dist-info}/LICENCE +0 -0
  59. {batframework-1.0.6.dist-info → batframework-1.0.8a1.dist-info}/top_level.txt +0 -0
@@ -7,11 +7,10 @@ class DynamicEntity(bf.Entity):
7
7
  def __init__(
8
8
  self,
9
9
  size: None | tuple[int, int] = None,
10
- no_surface: bool = False,
11
10
  surface_flags: int = 0,
12
11
  convert_alpha: bool = False,
13
12
  ) -> None:
14
- super().__init__(size, no_surface, surface_flags, convert_alpha)
13
+ super().__init__(size, surface_flags, convert_alpha)
15
14
  self.velocity = pygame.math.Vector2(0, 0)
16
15
 
17
16
  def on_collideX(self, collider: Self):
@@ -20,5 +19,7 @@ class DynamicEntity(bf.Entity):
20
19
  def on_collideY(self, collider: Self):
21
20
  return False
22
21
 
23
- def move_by_velocity(self,dt) -> None:
24
- self.set_position(self.rect.x + self.velocity.x * dt, self.rect.y + self.velocity.y * dt)
22
+ def move_by_velocity(self, dt) -> None:
23
+ self.set_position(
24
+ self.rect.x + self.velocity.x * dt, self.rect.y + self.velocity.y * dt
25
+ )
@@ -0,0 +1,58 @@
1
+ import pygame
2
+ import batFramework as bf
3
+ from functools import lru_cache
4
+ from .enums import easing
5
+
6
+
7
+ @lru_cache(maxsize=None)
8
+ def process_value(progress: float, p0: float, p1: float, p2: float, p3: float) -> float:
9
+ if p0 == 0 and p1 == 0 and p2 == 1 and p3 == 1: # Linear easing control points
10
+ return progress
11
+ t = progress
12
+ t_inv = 1.0 - t
13
+ t2 = t * t
14
+ t3 = t * t2
15
+ t_inv2 = t_inv * t_inv
16
+ return 3 * t_inv2 * t * p1 + 3 * t_inv * t2 * p3 + t3
17
+
18
+
19
+ class EasingController(bf.Timer):
20
+ def __init__(
21
+ self,
22
+ easing_function: easing = easing.LINEAR,
23
+ duration: float = 1,
24
+ update_callback=None,
25
+ end_callback=None,
26
+ loop: bool = False,
27
+ ) -> None:
28
+ self.easing_function = easing_function
29
+ self.update_callback = update_callback
30
+ self.value: float = 0.0
31
+ super().__init__(duration, end_callback, loop)
32
+
33
+ def get_value(self) -> float:
34
+ return self.value
35
+
36
+ def start(self, force: bool = False):
37
+ super().start(force)
38
+ self.value = 0
39
+
40
+ def update(self, dt: float) -> None:
41
+ if self.get_progression() == 1:
42
+ return
43
+ super().update(dt)
44
+ if self.get_progression() == 0:
45
+ return
46
+ if self.easing_function == easing.LINEAR:
47
+ self.value = self.get_progression()
48
+ else:
49
+ self.value = process_value(
50
+ self.get_progression(), *self.easing_function.control_points
51
+ )
52
+ if self.update_callback:
53
+ self.update_callback(self.value)
54
+
55
+ def end(self):
56
+ if self.update_callback:
57
+ self.update_callback(1)
58
+ super().end()
batFramework/entity.py CHANGED
@@ -1,160 +1,67 @@
1
1
  from typing import Any, Self
2
2
  import pygame
3
3
  import batFramework as bf
4
+ from .object import Object
4
5
 
5
- class Entity:
6
+ class Entity(Object):
6
7
  """
7
- Basic entity class
8
+ Basic entity class
8
9
  """
9
- __instance_count = 0
10
-
11
10
  def __init__(
12
11
  self,
13
12
  size: None | tuple[int, int] = None,
14
- no_surface: bool = False,
15
13
  surface_flags: int = 0,
16
14
  convert_alpha: bool = False,
15
+ *args,
16
+ **kwargs,
17
17
  ) -> None:
18
- self.convert_alpha = convert_alpha
19
- if size is None:
20
- size = (10, 10)
21
- if no_surface:
22
- self.surface = None
23
- else:
24
- self.surface = pygame.Surface(size, surface_flags)
25
-
26
- if convert_alpha and self.surface is not None:
18
+ super().__init__()
19
+ self.visible: bool = True
20
+ self.rect.size = (10, 10) if size is None else size
21
+ self.convert_alpha: bool = convert_alpha
22
+ self.surface_flags: int = surface_flags
23
+ self.blit_flags: int = 0
24
+ self.surface: pygame.Surface = pygame.Surface(self.rect.size, surface_flags)
25
+ if convert_alpha:
27
26
  self.surface = self.surface.convert_alpha()
28
27
  self.surface.fill((0, 0, 0, 0))
29
28
 
30
- self.rect = pygame.FRect(0, 0, *size)
31
- self.tags: list[str] = []
32
- self.parent_scene: bf.Scene | None = None
33
- self.visible: bool = True
34
- self.debug_color: tuple = bf.color.DARK_RED
35
- self.render_order: int = 0
36
- self.uid: Any = Entity.__instance_count
37
- Entity.__instance_count += 1
38
-
39
- def set_render_order(self, render_order: int) -> Self:
40
- self.render_order = render_order
41
- return self
42
-
43
- def get_bounding_box(self):
44
- yield (self.rect, self.debug_color)
45
-
46
- def set_debug_color(self, color) -> Self:
47
- self.debug_color = color
48
- return self
49
-
50
- def set_visible(self, value: bool) -> Self:
51
- self.visible = value
52
- return self
53
-
54
- def set_parent_scene(self, scene) -> Self:
55
- self.parent_scene = scene
29
+ def set_alpha(self, alpha: int) -> Self:
30
+ self.surface.set_alpha(min(max(0, alpha), 255))
56
31
  return self
57
32
 
58
- def do_when_added(self):
59
- pass
60
-
61
- def do_when_removed(self):
62
- pass
63
-
64
- def set_position(self, x, y) -> Self:
65
- self.rect.topleft = (x, y)
66
- return self
67
-
68
- def get_position(self) -> tuple:
69
- return self.rect.topleft
70
-
71
- def get_center(self) -> tuple:
72
- return self.rect.center
33
+ def get_alpha(self)->int:
34
+ return self.surface.get_alpha()
73
35
 
74
- def set_x(self, x) -> Self:
75
- self.rect.x = x
36
+ def set_surface_flags(self, surface_flags: int) -> Self:
37
+ self.surface_flags = surface_flags
76
38
  return self
77
39
 
78
- def set_y(self, y) -> Self:
79
- self.rect.y = y
40
+ def set_convert_alpha(self, value: bool) -> Self:
41
+ self.convert_alpha = value
80
42
  return self
81
43
 
82
- def set_center(self, x, y) -> Self:
83
- self.rect.center = (x, y)
44
+ def set_blit_flags(self, blit_flags: int) -> Self:
45
+ self.blit_flags = blit_flags
84
46
  return self
85
47
 
86
- def set_uid(self, uid) -> Self:
87
- self.uid = uid
48
+ def set_render_order(self, render_order: int) -> Self:
49
+ self.render_order = render_order
50
+ if self.parent_scene:
51
+ self.parent_scene.sort_entities()
88
52
  return self
89
53
 
90
- def add_tags(self, *tags) -> Self:
91
- for tag in tags:
92
- if tag not in self.tags:
93
- self.tags.append(tag)
94
- self.tags.sort()
54
+ def set_visible(self, value: bool) -> Self:
55
+ self.visible = value
95
56
  return self
96
57
 
97
- def remove_tags(self, *tags):
98
- self.tags = [tag for tag in self.tags if tag not in tags]
99
-
100
- def has_tags(self, *tags) -> bool:
101
- return all(tag in self.tags for tag in tags)
102
-
103
- def get_tags(self) -> list[str]:
104
- return self.tags
105
-
106
- def process_event(self, event: pygame.Event) -> bool:
107
- """
108
- Returns bool : True if the method is blocking (no propagation to next children of the scene)
109
- """
110
- self.do_process_actions(event)
111
- res = self.do_handle_actions()
112
- res = res or self.do_handle_event(event)
113
- self.do_reset_actions()
114
- return res
115
-
116
-
117
-
118
- def do_process_actions(self, event: pygame.Event) -> None:
119
- """
120
- Process entity actions you may have set
121
- """
122
-
123
- def do_reset_actions(self) -> None:
124
- """
125
- Reset entity actions you may have set
126
- """
127
-
128
- def do_handle_actions(self) ->None:
129
- """
130
- Handle entity actions
58
+ def draw(self, camera: bf.Camera) -> None:
131
59
  """
132
-
133
- def do_handle_event(self, event: pygame.Event) -> bool:
134
- """
135
- Handle specific
60
+ Draw the entity onto the camera surface
136
61
  """
137
-
138
- return False
139
-
140
- def update(self, dt: float):
141
- """
142
- Update method to be overriden by subclasses of widget
143
- """
144
- self.do_update(dt)
145
-
146
- def do_update(self, dt: float):
147
- """
148
- Update method to be overriden for specific behavior by the end user
149
- """
150
-
151
- def draw(self, camera: bf.Camera) -> int:
152
- """
153
- Draw the entity onto the camera with coordinate transposing
154
- """
155
- should_not_draw = not self.visible or not self.surface or not camera.intersects(self.rect)
156
- if should_not_draw:
157
- return 0
158
- camera.surface.blit(self.surface, camera.transpose(self.rect))
159
-
160
- return 1
62
+ if not self.visible or not camera.rect.colliderect(self.rect): return
63
+ camera.surface.blit(
64
+ self.surface,
65
+ camera.world_to_screen(self.rect),
66
+ special_flags=self.blit_flags,
67
+ )
batFramework/enums.py CHANGED
@@ -1,14 +1,104 @@
1
1
  from enum import Enum
2
2
 
3
- class Direction(Enum):
3
+
4
+ class color:
5
+ WHITE = (255, 255, 255)
6
+ LIGHTER_GRAY = (236, 240, 241)
7
+ LIGHT_GRAY = (189, 195, 199)
8
+ DARK_GRAY = (66, 66, 66)
9
+ DARKER_GRAY = (23, 23, 23)
10
+ BLACK = (0, 0, 0)
11
+
12
+ TURQUOISE = (26, 188, 156)
13
+ TURQUOISE_SHADE = (22, 160, 133)
14
+
15
+ GREEN = (46, 204, 113)
16
+ GREEN_SHADE = (39, 174, 96)
17
+
18
+ BLUE = (52, 152, 219)
19
+ BLUE_SHADE = (41, 128, 185)
20
+
21
+ PURPLE = (155, 89, 182)
22
+ PURPLE_SHADE = (142, 68, 173)
23
+
24
+ CHARCOAL = (52, 73, 94)
25
+ CHARCOAL_SHADE = (44, 62, 80)
26
+
27
+ GOLD = (241, 196, 15)
28
+ GOLD_SHADE = (243, 156, 18)
29
+
30
+ ORANGE = (230, 126, 34)
31
+ ORANGE_SHADE = (211, 84, 0)
32
+
33
+ RED = (231, 76, 60)
34
+ RED_SHADE = (192, 57, 43)
35
+
36
+ CLOUD = (236, 240, 241)
37
+ CLOUD_SHADE = (189, 195, 199)
38
+
39
+ CONCRETE = (149, 165, 166)
40
+ CONCRETE_SHADE = (127, 140, 141)
41
+
42
+ # GB
43
+ DARKER_GB = (27, 42, 9)
44
+ DARK_GB = (14, 69, 11)
45
+ LIGHT_GB = (73, 107, 34)
46
+ LIGHTER_GB = (154, 158, 63)
47
+
48
+ class easing(Enum):
49
+ LINEAR = (0, 0, 1, 1)
50
+ EASE_IN = (0.95, 0, 1, 0.55)
51
+ EASE_OUT = (0.5, 1, 0.5, 1)
52
+ EASE_IN_OUT = (0.55, 0, 0.45, 1)
53
+ EASE_IN_OUT_ELASTIC = (0.39, -0.55, 0.3, 1.3)
54
+
55
+ def __init__(self, *control_points):
56
+ self.control_points = control_points
57
+
58
+ class axis(Enum):
4
59
  HORIZONTAL = "horizontal"
5
60
  VERTICAL = "vertical"
6
61
 
7
-
8
- class Alignment(Enum):
62
+ class spacing(Enum):
63
+ MIN = "min"
64
+ HALF = "half"
65
+ MAX = "max"
66
+ MANUAL = "manual"
67
+ class alignment(Enum):
9
68
  LEFT = "left"
10
69
  RIGHT = "right"
11
70
  CENTER = "center"
12
71
  TOP = "top"
13
72
  BOTTOM = "bottom"
73
+ TOPLEFT = "topleft"
74
+ TOPRIGHT = "topright"
75
+ MIDLEFT = "midleft"
76
+ MIDRIGHT = "midright"
77
+ BOTTOMLEFT = "bottomleft"
78
+ BOTTOMRIGHT = "bottomright"
79
+
80
+ class direction(Enum):
81
+ LEFT = 0
82
+ UP = 1
83
+ RIGHT = 2
84
+ DOWN = 3
85
+
86
+ class drawMode(Enum):
87
+ SOLID = 0
88
+ TEXTURED = 1
89
+
90
+ class debugMode(Enum):
91
+ HIDDEN = 0
92
+ DEBUGGER = 1
93
+ OUTLINES = 2
94
+
95
+ class actionType(Enum):
96
+ INSTANTANEOUS = 0
97
+ CONTINUOUS = 1
98
+ HOLDING = 2
99
+
14
100
 
101
+ class textMode(Enum):
102
+ ALPHABETICAL = 0
103
+ NUMERICAL = 1
104
+ ALPHANUMERIC = 3
@@ -1,8 +1,11 @@
1
1
  from .utils import Singleton
2
+
2
3
  # put font stuff here later
3
4
  import pygame
4
5
  import os
5
6
  import batFramework as bf
7
+
8
+
6
9
  class FontManager(metaclass=Singleton):
7
10
  def __init__(self):
8
11
  pygame.font.init()
@@ -12,10 +15,13 @@ class FontManager(metaclass=Singleton):
12
15
  self.DEFAULT_ANTIALIAS = False
13
16
  self.FONTS = {}
14
17
 
15
- def set_default_text_size(self,size: int):
18
+ def set_antialias(self,value:bool):
19
+ self.DEFAULT_ANTIALIAS = value
20
+
21
+ def set_default_text_size(self, size: int):
16
22
  self.DEFAULT_TEXT_SIZE = size
17
23
 
18
- def init_font(self,raw_path: str|None):
24
+ def init_font(self, raw_path: str | None):
19
25
  try:
20
26
  if raw_path is not None:
21
27
  self.load_font(raw_path if raw_path else None, None)
@@ -24,14 +30,14 @@ class FontManager(metaclass=Singleton):
24
30
  self.load_sysfont(raw_path)
25
31
  self.load_sysfont(raw_path, None)
26
32
 
27
- def load_font(self,path: str|None, name: str|None = ""):
33
+ def load_font(self, path: str | None, name: str | None = ""):
28
34
  if path is not None:
29
35
  path = bf.ResourceManager().get_path(path) # convert path if given
30
36
  filename = None
31
37
  if path is not None:
32
38
  filename = os.path.basename(path).split(".")[0]
33
-
34
- # get filename if path is given, else None
39
+
40
+ # get filename if path is given, else None
35
41
  if name != "":
36
42
  filename = name # if name is not given, name is the filename
37
43
  self.FONTS[filename] = {}
@@ -39,7 +45,7 @@ class FontManager(metaclass=Singleton):
39
45
  for size in range(self.MIN_FONT_SIZE, self.MAX_FONT_SIZE, 2):
40
46
  self.FONTS[filename][size] = pygame.font.Font(path, size=size)
41
47
 
42
- def load_sysfont(self,font_name: str|None, key: str |None= ""):
48
+ def load_sysfont(self, font_name: str | None, key: str | None = ""):
43
49
  if key == "":
44
50
  key = font_name
45
51
  if font_name is None or pygame.font.match_font(font_name) is None:
@@ -49,7 +55,9 @@ class FontManager(metaclass=Singleton):
49
55
  for size in range(self.MIN_FONT_SIZE, self.MAX_FONT_SIZE, 2):
50
56
  self.FONTS[key][size] = pygame.font.SysFont(font_name, size=size)
51
57
 
52
- def get_font(self,name: str | None = None, text_size: int = 12) -> pygame.Font|None:
58
+ def get_font(
59
+ self, name: str | None = None, text_size: int = 12
60
+ ) -> pygame.Font | None:
53
61
  if not name in self.FONTS:
54
62
  return None
55
63
  if not text_size in self.FONTS[name]:
@@ -2,9 +2,11 @@ from .constraints import *
2
2
  from .widget import Widget
3
3
  from .image import Image
4
4
  from .interactiveWidget import InteractiveWidget
5
+ from .draggableWidget import DraggableWidget
6
+ from .clickableWidget import ClickableWidget
5
7
  from .root import Root
6
8
  from .shape import Shape
7
- from .frame import Frame
9
+ from .meter import Meter
8
10
  from .label import Label
9
11
  from .dialogueBox import DialogueBox
10
12
  from .textInput import TextInput
@@ -14,3 +16,5 @@ from .layout import *
14
16
  from .container import Container
15
17
  from .indicator import *
16
18
  from .toggle import Toggle
19
+ from .radioButton import RadioButton,RadioVariable
20
+ from .slider import Slider
@@ -1,150 +1,12 @@
1
1
  from .label import Label
2
2
  import batFramework as bf
3
- from typing import Self,Callable
4
- from .interactiveWidget import InteractiveWidget
3
+ from typing import Self, Callable
4
+ from .clickableWidget import ClickableWidget
5
5
  import pygame
6
+ from math import ceil
6
7
 
7
8
 
8
- class Button(Label, InteractiveWidget):
9
- _cache :dict = {}
10
-
11
- def __init__(self, text: str, callback: None| Callable = None) -> None:
12
- # Label.__init__(self,text)
13
- self.callback = callback
14
- self.is_hovered: bool = False
15
- self.effect_max :float= 20
16
- self.effect_speed :float= 1.8
17
- self.is_clicking : bool = False
18
- self.effect :float = 0
19
- self.enabled :bool = True
9
+ class Button(Label, ClickableWidget):
10
+ def __init__(self, text: str, callback: None | Callable = None) -> None:
20
11
  super().__init__(text=text)
21
- self.set_debug_color("cyan")
22
- self.focusable = True
23
-
24
- def get_surface_filter(self) -> pygame.Surface | None:
25
- if not self.surface:
26
- return None
27
-
28
- size = self.surface.get_size()
29
- surface_filter = Button._cache.get(size, None)
30
-
31
- if surface_filter is None:
32
- # Create a mask from the original surface
33
- mask = pygame.mask.from_surface(self.surface,threshold=0)
34
-
35
- # Get the bounding box of the mask
36
- silhouette_surface = mask.to_surface(
37
- setcolor = (30,30,30),unsetcolor= (255,255,255)
38
- ).convert_alpha()
39
-
40
-
41
- Button._cache[size] = silhouette_surface
42
- surface_filter = silhouette_surface
43
-
44
- return surface_filter
45
- def enable(self)->Self:
46
- self.enabled = True
47
- self.build()
48
- return self
49
-
50
- def disable(self)->Self:
51
- self.enabled = False
52
- self.build()
53
- return self
54
-
55
- def is_enabled(self)->bool:
56
- return self.enabled
57
-
58
- def set_callback(self, callback: Callable) -> Self:
59
- self.callback = callback
60
- return self
61
-
62
- def on_get_focus(self):
63
- super().on_get_focus()
64
- self.build()
65
-
66
- def on_lose_focus(self):
67
- super().on_lose_focus()
68
- self.build()
69
-
70
- def to_string_id(self) -> str:
71
- return f"Button({self._text}){'' if self.enabled else '[disabled]'}"
72
-
73
- def click(self) -> None:
74
- if self.callback is not None:
75
- self.callback()
76
- bf.Timer(duration=0.3,end_callback=self._safety_effect_end).start()
77
-
78
- def _safety_effect_end(self)->None:
79
- if self.effect > 0:
80
- self.effect = 0
81
- self.build()
82
-
83
- def start_effect(self):
84
- if self.effect <= 0 : self.effect = self.effect_max
85
-
86
-
87
- def do_on_click_down(self,button)->None:
88
- if self.enabled and button == 1 and self.effect == 0:
89
- if not self.get_focus():return
90
- self.is_clicking = True
91
- self.start_effect()
92
-
93
- def do_on_click_up(self,button)->None:
94
- if self.enabled and button == 1 and self.is_clicking:
95
- # self.effect = 0
96
- self.is_clicking = False
97
- self.build()
98
- self.click()
99
-
100
- def on_enter(self)->None:
101
- if not self.enabled : return
102
- super().on_enter()
103
- self.effect = 0
104
- self.build()
105
- pygame.mouse.set_cursor(*pygame.cursors.tri_left)
106
-
107
- def on_exit(self)->None:
108
- super().on_exit()
109
- # self.effect = 0
110
- self.is_clicking = False
111
- self.build()
112
- pygame.mouse.set_cursor(pygame.cursors.arrow)
113
-
114
-
115
-
116
- def update(self,dt):
117
- super().update(dt)
118
- if self.effect <= 0: return
119
- self.effect -= dt*60*self.effect_speed
120
- if self.is_clicking:
121
- if self.effect < 1 : self.effect = 1
122
- else:
123
- if self.effect < 0 : self.effect = 0
124
- self.build()
125
-
126
- def _build_effect(self)->None:
127
- if self.effect < 1 : return
128
- e = int(min(self.rect.w //3, self.rect.h//3,self.effect))
129
- pygame.draw.rect(
130
- self.surface,
131
- bf.color.CLOUD_WHITE,
132
- (0,0,*self.surface.get_size()),
133
- #int(self.effect),
134
- e,
135
- *self._border_radius
136
- )
137
- def _build_disabled(self)->None:
138
- self.surface.blit(self.get_surface_filter(), (0, 0), special_flags=pygame.BLEND_SUB)
139
-
140
- def _build_hovered(self)->None:
141
- self.surface.blit(self.get_surface_filter(), (0, 0), special_flags=pygame.BLEND_ADD)
142
-
143
- def build(self) -> None:
144
- super().build()
145
- if not self.enabled:
146
- self._build_disabled()
147
- elif self.is_hovered:
148
- self._build_hovered()
149
- if self.effect:
150
- self._build_effect()
12
+ self.set_callback(callback)