batframework 1.0.8a7__py3-none-any.whl → 1.0.8a9__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 +51 -68
- batFramework/action.py +99 -126
- batFramework/actionContainer.py +9 -53
- batFramework/animatedSprite.py +82 -141
- batFramework/audioManager.py +26 -69
- batFramework/camera.py +69 -259
- batFramework/constants.py +54 -16
- batFramework/cutscene.py +29 -39
- batFramework/cutsceneBlocks.py +43 -36
- batFramework/debugger.py +48 -0
- batFramework/dynamicEntity.py +9 -18
- batFramework/easing.py +71 -0
- batFramework/entity.py +97 -48
- batFramework/gui/__init__.py +2 -10
- batFramework/gui/button.py +78 -9
- batFramework/gui/constraints.py +204 -0
- batFramework/gui/container.py +32 -174
- batFramework/gui/debugger.py +43 -131
- batFramework/gui/frame.py +19 -0
- batFramework/gui/image.py +20 -56
- batFramework/gui/indicator.py +21 -38
- batFramework/gui/interactiveWidget.py +13 -192
- batFramework/gui/label.py +74 -309
- batFramework/gui/layout.py +63 -231
- batFramework/gui/root.py +38 -134
- batFramework/gui/shape.py +57 -237
- batFramework/gui/toggle.py +51 -101
- batFramework/gui/widget.py +250 -358
- batFramework/manager.py +19 -52
- batFramework/particles.py +77 -0
- batFramework/scene.py +123 -281
- batFramework/sceneManager.py +116 -178
- batFramework/stateMachine.py +8 -11
- batFramework/time.py +58 -145
- batFramework/transition.py +124 -195
- batFramework/transitionManager.py +0 -0
- batFramework/triggerZone.py +1 -1
- batFramework/utils.py +147 -112
- batframework-1.0.8a9.dist-info/METADATA +53 -0
- batframework-1.0.8a9.dist-info/RECORD +42 -0
- {batframework-1.0.8a7.dist-info → batframework-1.0.8a9.dist-info}/WHEEL +1 -1
- batFramework/character.py +0 -27
- batFramework/easingController.py +0 -58
- batFramework/enums.py +0 -113
- batFramework/fontManager.py +0 -65
- batFramework/gui/clickableWidget.py +0 -220
- batFramework/gui/constraints/__init__.py +0 -1
- batFramework/gui/constraints/constraints.py +0 -815
- batFramework/gui/dialogueBox.py +0 -99
- batFramework/gui/draggableWidget.py +0 -40
- batFramework/gui/meter.py +0 -74
- batFramework/gui/radioButton.py +0 -84
- batFramework/gui/slider.py +0 -240
- batFramework/gui/style.py +0 -10
- batFramework/gui/styleManager.py +0 -48
- batFramework/gui/textInput.py +0 -247
- batFramework/object.py +0 -123
- batFramework/particle.py +0 -115
- batFramework/renderGroup.py +0 -67
- batFramework/resourceManager.py +0 -100
- batFramework/scrollingSprite.py +0 -114
- batFramework/sprite.py +0 -51
- batFramework/templates/__init__.py +0 -2
- batFramework/templates/character.py +0 -44
- batFramework/templates/states.py +0 -166
- batFramework/tileset.py +0 -46
- batframework-1.0.8a7.dist-info/LICENCE +0 -21
- batframework-1.0.8a7.dist-info/METADATA +0 -43
- batframework-1.0.8a7.dist-info/RECORD +0 -62
- {batframework-1.0.8a7.dist-info → batframework-1.0.8a9.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: batframework
|
3
|
+
Version: 1.0.8a9
|
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.8a9.dist-info/METADATA,sha256=Ztm_Bp5g9CEKmMnsVFYca3HYvrH-yY9QV8fv7Dwc0ZY,1713
|
40
|
+
batframework-1.0.8a9.dist-info/WHEEL,sha256=5Mi1sN9lKoFv_gxcPtisEVrJZihrm_beibeg5R6xb4I,91
|
41
|
+
batframework-1.0.8a9.dist-info/top_level.txt,sha256=vxAKBIk1oparFTxeXGBrgfIO7iq_YR5Fv1JvPVAIwmA,13
|
42
|
+
batframework-1.0.8a9.dist-info/RECORD,,
|
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
|
batFramework/easingController.py
DELETED
@@ -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
|
batFramework/fontManager.py
DELETED
@@ -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
|