batframework 1.0.8a7__py3-none-any.whl → 1.0.8a8__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 (70) hide show
  1. batFramework/__init__.py +51 -68
  2. batFramework/action.py +99 -126
  3. batFramework/actionContainer.py +9 -53
  4. batFramework/animatedSprite.py +82 -141
  5. batFramework/audioManager.py +26 -69
  6. batFramework/camera.py +69 -259
  7. batFramework/constants.py +54 -16
  8. batFramework/cutscene.py +29 -39
  9. batFramework/cutsceneBlocks.py +43 -36
  10. batFramework/debugger.py +48 -0
  11. batFramework/dynamicEntity.py +9 -18
  12. batFramework/easing.py +71 -0
  13. batFramework/entity.py +97 -48
  14. batFramework/gui/__init__.py +2 -10
  15. batFramework/gui/button.py +78 -9
  16. batFramework/gui/constraints.py +204 -0
  17. batFramework/gui/container.py +32 -174
  18. batFramework/gui/debugger.py +43 -131
  19. batFramework/gui/frame.py +19 -0
  20. batFramework/gui/image.py +20 -56
  21. batFramework/gui/indicator.py +21 -38
  22. batFramework/gui/interactiveWidget.py +13 -192
  23. batFramework/gui/label.py +74 -309
  24. batFramework/gui/layout.py +63 -231
  25. batFramework/gui/root.py +38 -134
  26. batFramework/gui/shape.py +57 -237
  27. batFramework/gui/toggle.py +51 -101
  28. batFramework/gui/widget.py +250 -358
  29. batFramework/manager.py +19 -52
  30. batFramework/particles.py +77 -0
  31. batFramework/scene.py +123 -281
  32. batFramework/sceneManager.py +116 -178
  33. batFramework/stateMachine.py +8 -11
  34. batFramework/time.py +58 -145
  35. batFramework/transition.py +124 -195
  36. batFramework/transitionManager.py +0 -0
  37. batFramework/triggerZone.py +1 -1
  38. batFramework/utils.py +147 -112
  39. batframework-1.0.8a8.dist-info/METADATA +53 -0
  40. batframework-1.0.8a8.dist-info/RECORD +42 -0
  41. {batframework-1.0.8a7.dist-info → batframework-1.0.8a8.dist-info}/WHEEL +1 -1
  42. batFramework/character.py +0 -27
  43. batFramework/easingController.py +0 -58
  44. batFramework/enums.py +0 -113
  45. batFramework/fontManager.py +0 -65
  46. batFramework/gui/clickableWidget.py +0 -220
  47. batFramework/gui/constraints/__init__.py +0 -1
  48. batFramework/gui/constraints/constraints.py +0 -815
  49. batFramework/gui/dialogueBox.py +0 -99
  50. batFramework/gui/draggableWidget.py +0 -40
  51. batFramework/gui/meter.py +0 -74
  52. batFramework/gui/radioButton.py +0 -84
  53. batFramework/gui/slider.py +0 -240
  54. batFramework/gui/style.py +0 -10
  55. batFramework/gui/styleManager.py +0 -48
  56. batFramework/gui/textInput.py +0 -247
  57. batFramework/object.py +0 -123
  58. batFramework/particle.py +0 -115
  59. batFramework/renderGroup.py +0 -67
  60. batFramework/resourceManager.py +0 -100
  61. batFramework/scrollingSprite.py +0 -114
  62. batFramework/sprite.py +0 -51
  63. batFramework/templates/__init__.py +0 -2
  64. batFramework/templates/character.py +0 -44
  65. batFramework/templates/states.py +0 -166
  66. batFramework/tileset.py +0 -46
  67. batframework-1.0.8a7.dist-info/LICENCE +0 -21
  68. batframework-1.0.8a7.dist-info/METADATA +0 -43
  69. batframework-1.0.8a7.dist-info/RECORD +0 -62
  70. {batframework-1.0.8a7.dist-info → batframework-1.0.8a8.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,53 @@
1
+ Metadata-Version: 2.1
2
+ Name: batframework
3
+ Version: 1.0.8a8
4
+ Summary: Pygame framework for making games easier.
5
+ Requires-Python: >=3.11
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: pygame-ce
8
+
9
+ # batFramework
10
+
11
+ batFramework is a Python game framework built using Pygame, designed to simplify game development by providing entities, scenes, a scene manager, and various utilities.
12
+
13
+ ## Purpose and Overview
14
+ The primary objective of batFramework is to streamline game development by utilizing entities and scenes that hold entities. It employs a manager, which inherits from the scene manager, to handle scenes, propagate events, and manage updates and rendering.
15
+
16
+ ## Installation and Setup
17
+ To install batFramework, you can use pip:
18
+ ```pip install batFramework```
19
+
20
+
21
+ The only dependency required is pygame-ce.
22
+
23
+ ## Usage Instructions
24
+ To create a basic app using batFramework, here's an example:
25
+
26
+ ```python
27
+ import batFramework as bf
28
+
29
+ # Initialize the framework
30
+ bf.init((1280, 720), window_title="My Amazing Program")
31
+
32
+ # Create a manager and a scene
33
+ bf.Manager(bf.Scene("main")).run()
34
+ ```
35
+ In practice, users can inherit bf.Scene to create their own scenes, adding specific behaviors, entities, etc.
36
+
37
+ ## Features and Functionalities
38
+
39
+ - Scene management for organizing game components
40
+ - Cutscene support to facilitate storytelling sequences
41
+ - Audio management for music and sound effects with volume control
42
+ - Entity, sprite, and animated sprite support
43
+ - Utility modules such as time management and easingAnimation
44
+
45
+ Users can leverage these functionalities to build games efficiently using batFramework.
46
+
47
+ For more detailed usage and examples, please refer to the documentation or codebase.
48
+
49
+
50
+ # License
51
+ MIT License
52
+
53
+
@@ -0,0 +1,42 @@
1
+ batFramework/__init__.py,sha256=MLVXC2ymkO3k8LdCgB6TbahgJfhxk4GKAbmndmEgZS4,2146
2
+ batFramework/action.py,sha256=Phk6-q2P-XyV2GVlXPpxyje0due4fIrKnhI1_4anfjI,7600
3
+ batFramework/actionContainer.py,sha256=K9dIgG559ckxzRB3t-lpON4dFTcM2mcKZfsf4bhuJ1k,1092
4
+ batFramework/animatedSprite.py,sha256=kJPKrTOfkbQu2uYDziIEop1z6-gjBwZxkC1Rxd_vBwE,3992
5
+ batFramework/audioManager.py,sha256=5UsDPy4zsDO7Va1y1kM4lSpEJXU95o9F01E-Sts3osg,2546
6
+ batFramework/camera.py,sha256=wt4TyWTgQmQElBVeFI7ONzNI75r0FKtB3KmNH00GeFM,4322
7
+ batFramework/constants.py,sha256=FSyEYLxdAb3JaXA11sAwZBfAImedASohpFcd_7qnG0I,2075
8
+ batFramework/cutscene.py,sha256=5aiIQeWGmvHCb-N3vjmwxhE4dCXv3iZRFHiexSNxCXM,3650
9
+ batFramework/cutsceneBlocks.py,sha256=1gmof0jKJ8SqE-RoErm6n1A0JJ4Ang9Q30xEZnW9NaI,5123
10
+ batFramework/debugger.py,sha256=gh5kOUmGr4t-BFXA17tImid4nzxUqrhsUhE_JV9srNg,1671
11
+ batFramework/dynamicEntity.py,sha256=REIqH0jnfX6yUThoQNkQrsG0390TR6C5la1h2MAioYk,665
12
+ batFramework/easing.py,sha256=vGkk7FDPj27X7NCJXALCEyVKDbpXXebWYtMvxkbhOh0,2217
13
+ batFramework/entity.py,sha256=Tw4_PIA_sY8fhbj9TjE6wPcDTrZZX_Tj7l8oKquqe8U,3178
14
+ batFramework/manager.py,sha256=LdiQVyuPQE23jwO4EjR4zqDymxtRmthUJ7VE7RIEDpU,1583
15
+ batFramework/particles.py,sha256=PX8zSqOS1gyDloGAz3fAlrto51lWMUpBXDIM152EYWc,2172
16
+ batFramework/scene.py,sha256=KM1e53ZfPvuJoSGQZaEl_IouWRYCbFq0QOYTuXYCr-E,7324
17
+ batFramework/sceneManager.py,sha256=sFkQbfMuR19M4duvCf0SOxSY7MkMrkmiiKh72-tC1nI,5743
18
+ batFramework/stateMachine.py,sha256=_er9_dcm6MLmlTjXTVm175eqZ9puaKb31PFmNPRhcSU,1338
19
+ batFramework/time.py,sha256=iGV9mxUFrdXsvm4fJ1faX-VYNsOH7DX2N_aXsDRHhmM,2403
20
+ batFramework/transition.py,sha256=wmL1Mgg_xopzeDbEPJyAmllLB2BCRJZtuMOR7Mez480,4873
21
+ batFramework/transitionManager.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ batFramework/triggerZone.py,sha256=ikOOlJT1KIND0MO2xiilCHuKlb1eQhkCMEhZTi1btsI,586
23
+ batFramework/utils.py,sha256=EUB3bMldWTYFVZxcJk5_7XAWcEz080P7PT5ZtkO5TAQ,6164
24
+ batFramework/gui/__init__.py,sha256=azu5HpC8Q9kupythU5GN5blt7K9oH55oXlOeXsIw1Mw,391
25
+ batFramework/gui/button.py,sha256=05RMQ20P5npgU9QmiT8v6abJhnhjqRgYbpZGaQXr6Bg,2703
26
+ batFramework/gui/constraints.py,sha256=pUTNwJqI2Tu57l8ZeQXVXg3b5F5t3aR4Us-CD5qXwnM,7544
27
+ batFramework/gui/container.py,sha256=XAkPZ0BOVXxzxWP5mKDF_MjYPPPAmUBY-J5zIadO0wQ,1480
28
+ batFramework/gui/debugger.py,sha256=JORHcSYQQCZ0tDzjnNQvDSOOjZVwEQLeqlr8e6xk2RI,1379
29
+ batFramework/gui/frame.py,sha256=zjHwbQT1fpRuvNgfBGZhMO_GdMEWqExa5dNlN9kUnUM,514
30
+ batFramework/gui/image.py,sha256=goOcPntsJeTb3LR7avzi4cXfYHwyGb0KXYttbCiE6fA,777
31
+ batFramework/gui/indicator.py,sha256=OgqDFsi2HCfbSzVjHkHO_shmo4q4ro3wfd0LWSLTJeQ,957
32
+ batFramework/gui/interactiveWidget.py,sha256=rRElxI1eFkvOeTfTaA6f8kVTOswOD-DFLAJDUCAI_Yk,641
33
+ batFramework/gui/label.py,sha256=EO1J5zPVe1skHz-KVqXKBZVKug8UVJUCXyHnvdRDuig,3586
34
+ batFramework/gui/layout.py,sha256=HyVhYTy1AQacALg6XMY5aX5lj7WY__HCCh8sTSBXwgI,3210
35
+ batFramework/gui/root.py,sha256=mhlu8ohqq8N-8q__ugv_tGRgPv-1jIHXBFezMFZ4mUM,1763
36
+ batFramework/gui/shape.py,sha256=CYaD0BdCiuGJO_tS2pALfKPlNGaGRNPzvy-Lk08_R8g,2490
37
+ batFramework/gui/toggle.py,sha256=jAeEyQXA893gDBUmjN7aoGgfsVln5RTODpSFB4LxwTY,2020
38
+ batFramework/gui/widget.py,sha256=1PkxThmet8nI5rvSDE6-iPtD_DsZkk-OxriZHbBZaFc,10509
39
+ batframework-1.0.8a8.dist-info/METADATA,sha256=5bEry2ZJ0j3qgR_eOW9-JmYTInWo72i2dQxnnYPV07s,1713
40
+ batframework-1.0.8a8.dist-info/WHEEL,sha256=5Mi1sN9lKoFv_gxcPtisEVrJZihrm_beibeg5R6xb4I,91
41
+ batframework-1.0.8a8.dist-info/top_level.txt,sha256=vxAKBIk1oparFTxeXGBrgfIO7iq_YR5Fv1JvPVAIwmA,13
42
+ batframework-1.0.8a8.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (74.1.2)
2
+ Generator: setuptools (75.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
batFramework/character.py DELETED
@@ -1,27 +0,0 @@
1
- import batFramework as bf
2
- from .stateMachine import State
3
- from .animatedSprite import AnimatedSprite
4
- from .dynamicEntity import DynamicEntity
5
-
6
- class Character(AnimatedSprite,DynamicEntity):
7
- def __init__(self) -> None:
8
- super().__init__()
9
- self.state_machine = bf.StateMachine(self)
10
- self.do_setup_animations()
11
- self.do_setup_states()
12
-
13
- def set_state(self,state_name:str):
14
- self.state_machine.set_state(state_name)
15
-
16
- def get_current_state(self)->State:
17
- return self.state_machine.get_current_state()
18
-
19
- def update(self, dt: float) -> None:
20
- self.state_machine.update(dt)
21
- super().update(dt)
22
-
23
- def do_setup_states(self):
24
- pass
25
-
26
- def do_setup_animations(self):
27
- pass
@@ -1,58 +0,0 @@
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/enums.py DELETED
@@ -1,113 +0,0 @@
1
- from enum import Enum
2
-
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
-
49
- class easing(Enum):
50
- LINEAR = (0, 0, 1, 1)
51
- EASE_IN = (0.95, 0, 1, 0.55)
52
- EASE_OUT = (0.5, 1, 0.5, 1)
53
- EASE_IN_OUT = (0.55, 0, 0.45, 1)
54
- EASE_IN_OUT_ELASTIC = (0.76,-0.36,0.41,1.34)
55
-
56
- def __init__(self, *control_points):
57
- self.control_points = control_points
58
-
59
-
60
- class axis(Enum):
61
- HORIZONTAL = "horizontal"
62
- VERTICAL = "vertical"
63
-
64
-
65
- class spacing(Enum):
66
- MIN = "min"
67
- HALF = "half"
68
- MAX = "max"
69
- MANUAL = "manual"
70
-
71
-
72
- class alignment(Enum):
73
- LEFT = "left"
74
- RIGHT = "right"
75
- CENTER = "center"
76
- TOP = "top"
77
- BOTTOM = "bottom"
78
- TOPLEFT = "topleft"
79
- TOPRIGHT = "topright"
80
- MIDLEFT = "midleft"
81
- MIDRIGHT = "midright"
82
- BOTTOMLEFT = "bottomleft"
83
- BOTTOMRIGHT = "bottomright"
84
-
85
-
86
- class direction(Enum):
87
- LEFT = 0
88
- UP = 1
89
- RIGHT = 2
90
- DOWN = 3
91
-
92
-
93
- class drawMode(Enum):
94
- SOLID = 0
95
- TEXTURED = 1
96
-
97
-
98
- class debugMode(Enum):
99
- HIDDEN = 0
100
- DEBUGGER = 1
101
- OUTLINES = 2
102
-
103
-
104
- class actionType(Enum):
105
- INSTANTANEOUS = 0
106
- CONTINUOUS = 1
107
- HOLDING = 2
108
-
109
-
110
- class textMode(Enum):
111
- ALPHABETICAL = 0
112
- NUMERICAL = 1
113
- ALPHANUMERICAL = 3
@@ -1,65 +0,0 @@
1
- from .utils import Singleton
2
-
3
- # put font stuff here later
4
- import pygame
5
- import os
6
- import batFramework as bf
7
-
8
-
9
- class FontManager(metaclass=Singleton):
10
- def __init__(self):
11
- pygame.font.init()
12
- self.DEFAULT_TEXT_SIZE = 16
13
- self.MIN_FONT_SIZE = 8
14
- self.MAX_FONT_SIZE = 64
15
- self.DEFAULT_ANTIALIAS = False
16
- self.FONTS = {}
17
-
18
- def set_antialias(self, value: bool):
19
- self.DEFAULT_ANTIALIAS = value
20
-
21
- def set_default_text_size(self, size: int):
22
- self.DEFAULT_TEXT_SIZE = size
23
-
24
- def init_font(self, raw_path: str | None):
25
- try:
26
- if raw_path is not None:
27
- self.load_font(raw_path if raw_path else None, None)
28
- self.load_font(raw_path)
29
- except FileNotFoundError:
30
- self.load_sysfont(raw_path)
31
- self.load_sysfont(raw_path, None)
32
-
33
- def load_font(self, path: str | None, name: str | None = ""):
34
- if path is not None:
35
- path = bf.ResourceManager().get_path(path) # convert path if given
36
- filename = None
37
- if path is not None:
38
- filename = os.path.basename(path).split(".")[0]
39
-
40
- # get filename if path is given, else None
41
- if name != "":
42
- filename = name # if name is not given, name is the filename
43
- self.FONTS[filename] = {}
44
- # fill the dict
45
- for size in range(self.MIN_FONT_SIZE, self.MAX_FONT_SIZE+1, 2):
46
- self.FONTS[filename][size] = pygame.font.Font(path, size=size)
47
-
48
- def load_sysfont(self, font_name: str | None, key: str | None = ""):
49
- if key == "":
50
- key = font_name
51
- if font_name is None or pygame.font.match_font(font_name) is None:
52
- raise FileNotFoundError(f"Requested font '{font_name}' was not found")
53
- self.FONTS[font_name] = {}
54
-
55
- for size in range(self.MIN_FONT_SIZE, self.MAX_FONT_SIZE+1, 2):
56
- self.FONTS[key][size] = pygame.font.SysFont(font_name, size=size)
57
-
58
- def get_font(
59
- self, name: str | None = None, text_size: int = 12
60
- ) -> pygame.Font | None:
61
- if not name in self.FONTS:
62
- return None
63
- if not text_size in self.FONTS[name]:
64
- return None
65
- return self.FONTS[name][text_size]
@@ -1,220 +0,0 @@
1
- from .label import Label
2
- import batFramework as bf
3
- from typing import Self, Callable
4
- from .interactiveWidget import InteractiveWidget
5
- from .shape import Shape
6
- import pygame
7
- from math import ceil
8
-
9
-
10
- class ClickableWidget(Shape, InteractiveWidget):
11
- _cache: dict = {}
12
-
13
- def __init__(self, callback: None | Callable = None, *args, **kwargs) -> None:
14
- super().__init__(*args, **kwargs)
15
- self.callback = callback
16
- self.is_pressed: bool = False
17
- self.enabled: bool = True
18
- self.hover_cursor = bf.const.DEFAULT_HOVER_CURSOR
19
- self.click_cursor = bf.const.DEFAULT_CLICK_CURSOR
20
- self.click_down_sound = None
21
- self.click_up_sound = None
22
- self.get_focus_sound = None
23
- self.lose_focus_sound = None
24
- self.pressed_relief: int = 1
25
- self.unpressed_relief: int = 2
26
- self.silent_focus: bool = False
27
- self.set_debug_color("cyan")
28
- self.set_relief(self.unpressed_relief)
29
-
30
- def set_unpressed_relief(self, relief: int) -> Self:
31
- if relief == self.unpressed_relief:
32
- return self
33
- self.unpressed_relief = relief
34
- self.dirty_shape = True
35
- if not self.is_pressed:
36
- self.set_relief(relief)
37
- return self
38
-
39
- def set_pressed_relief(self, relief: int) -> Self:
40
- if relief == self.pressed_relief:
41
- return self
42
- self.pressed_relief = relief
43
- self.dirty_shape = True
44
- if self.is_pressed:
45
- self.set_relief(relief)
46
- return self
47
-
48
- def set_silent_focus(self, value: bool) -> Self:
49
- self.silent_focus = value
50
- return self
51
-
52
- def set_click_down_sound(self, sound_name: str) -> Self:
53
- self.click_down_sound = sound_name
54
- return self
55
-
56
- def set_click_up_sound(self, sound_name: str) -> Self:
57
- self.click_up_sound = sound_name
58
- return self
59
-
60
- def set_get_focus_sound(self, sound_name: str) -> Self:
61
- self.get_focus_sound = sound_name
62
- return self
63
-
64
- def set_lose_focus_sound(self, sound_name: str) -> Self:
65
- self.lose_focus_sound = sound_name
66
- return self
67
-
68
- def set_hover_cursor(self, cursor: pygame.Cursor) -> Self:
69
- self.hover_cursor = cursor
70
- return self
71
-
72
- def set_click_cursor(self, cursor: pygame.Cursor) -> Self:
73
- self.click_cursor = cursor
74
- return self
75
-
76
- def get_surface_filter(self) -> pygame.Surface | None:
77
- size = int(self.rect.w), int(self.rect.h)
78
- surface_filter = ClickableWidget._cache.get((size, *self.border_radius), None)
79
- if surface_filter is None:
80
- # Create a mask from the original surface
81
- mask = pygame.mask.from_surface(self.surface, threshold=0)
82
-
83
- silhouette_surface = mask.to_surface(
84
- setcolor=(30, 30, 30), unsetcolor=(0, 0, 0)
85
- )
86
-
87
- ClickableWidget._cache[(size, *self.border_radius)] = silhouette_surface
88
-
89
- surface_filter = silhouette_surface
90
-
91
- return surface_filter
92
-
93
- def allow_focus_to_self(self) -> bool:
94
- return True
95
-
96
- def enable(self) -> Self:
97
- self.enabled = True
98
- self.dirty_surface = True
99
- return self
100
-
101
- def disable(self) -> Self:
102
- self.enabled = False
103
- self.dirty_surface = True
104
- return self
105
-
106
- def is_enabled(self) -> bool:
107
- return self.enabled
108
-
109
- def set_callback(self, callback: Callable) -> Self:
110
- self.callback = callback
111
- return self
112
-
113
- def on_get_focus(self):
114
- super().on_get_focus()
115
- if self.get_focus_sound and not self.silent_focus:
116
- if self.parent_scene and self.parent_scene.visible:
117
- bf.AudioManager().play_sound(self.get_focus_sound)
118
- if self.silent_focus:
119
- self.silent_focus = False
120
-
121
- def on_lose_focus(self):
122
- super().on_lose_focus()
123
- if self.lose_focus_sound and not self.silent_focus:
124
- if self.parent_scene and self.parent_scene.visible:
125
- bf.AudioManager().play_sound(self.lose_focus_sound)
126
- if self.silent_focus:
127
- self.silent_focus = False
128
-
129
- def __str__(self) -> str:
130
- return f"ClickableWidget"
131
-
132
- def click(self, force=False) -> None:
133
- if not self.enabled and not force:
134
- return
135
- if self.callback is not None:
136
- self.callback()
137
-
138
- def do_on_click_down(self, button) -> None:
139
- if self.enabled and button == 1:
140
- if not self.get_focus():
141
- return
142
- self.is_pressed = True
143
- if self.click_down_sound:
144
- bf.AudioManager().play_sound(self.click_down_sound)
145
- pygame.mouse.set_cursor(self.click_cursor)
146
- self.set_relief(self.pressed_relief)
147
-
148
- def do_on_click_up(self, button) -> None:
149
- if self.enabled and button == 1 and self.is_pressed:
150
- self.is_pressed = False
151
- if self.click_up_sound:
152
- bf.AudioManager().play_sound(self.click_up_sound)
153
- self.set_relief(self.unpressed_relief)
154
- self.click()
155
-
156
- def on_enter(self) -> None:
157
- if not self.enabled:
158
- return
159
- super().on_enter()
160
- self.dirty_surface = True
161
- pygame.mouse.set_cursor(self.hover_cursor)
162
-
163
- def on_exit(self) -> None:
164
- super().on_exit()
165
- if self.is_pressed:
166
- self.set_relief(self.unpressed_relief)
167
- self.is_pressed = False
168
- self.dirty_surface = True
169
-
170
- pygame.mouse.set_cursor(bf.const.DEFAULT_CURSOR)
171
-
172
- def on_lose_focus(self):
173
- super().on_lose_focus()
174
- self.on_exit()
175
-
176
- def on_key_down(self, key):
177
- if key == pygame.K_SPACE:
178
- self.on_click_down(1)
179
- super().on_key_down(key)
180
-
181
- def on_key_up(self, key):
182
- if key == pygame.K_SPACE:
183
- self.on_click_up(1)
184
- super().on_key_up(key)
185
-
186
- def _paint_disabled(self) -> None:
187
- self.surface.blit(
188
- self.get_surface_filter(), (0, 0), special_flags=pygame.BLEND_RGB_SUB
189
- )
190
-
191
- def _paint_hovered(self) -> None:
192
- self.surface.blit(
193
- self.get_surface_filter(), (0, 0), special_flags=pygame.BLEND_RGB_ADD
194
- )
195
-
196
- def get_padded_rect(self) -> pygame.FRect:
197
- return pygame.FRect(
198
- self.rect.x + self.padding[0],
199
- self.rect.y
200
- + self.padding[1]
201
- + (self.unpressed_relief - self.pressed_relief if self.is_pressed else 0),
202
- self.rect.w - self.padding[2] - self.padding[0],
203
- self.rect.h - self.unpressed_relief - self.padding[1] - self.padding[3], #
204
- )
205
-
206
- def _get_elevated_rect(self) -> pygame.FRect:
207
- return pygame.FRect(
208
- 0,
209
- self.unpressed_relief - self.pressed_relief if self.is_pressed else 0,
210
- self.rect.w,
211
- self.rect.h - self.unpressed_relief,
212
- )
213
-
214
- def paint(self) -> None:
215
- super().paint()
216
- if not self.enabled:
217
- self._paint_disabled()
218
- elif self.is_hovered:
219
- self._paint_hovered()
220
-
@@ -1 +0,0 @@
1
- from . import constraints