-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathbtn.py
More file actions
132 lines (103 loc) · 4.12 KB
/
Copy pathbtn.py
File metadata and controls
132 lines (103 loc) · 4.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
from typing import Callable, List, Tuple, Union
from pygame import BUTTON_LEFT, MOUSEBUTTONDOWN, MOUSEBUTTONUP, MOUSEMOTION, Rect, Surface, draw
from pygame.event import Event
from pygame.font import Font
from pacman.data_core import FontCfg, IDrawable, IEventful
from pacman.data_core.enums import BtnStateEnum, SoundCh
from pacman.misc import RectObj
from pacman.sound import SoundController, Sounds
from .utils import BTN_DEF_COLORS, BtnColor
class Btn(RectObj, IDrawable, IEventful):
def __init__(
self,
text: str,
rect: Rect,
function: Callable = None,
select_function: Callable = None,
colors: BtnColor = BTN_DEF_COLORS,
text_size: int = 60,
font: str = FontCfg.DEFAULT,
):
super().__init__(rect)
self.__function = function
self.__select_function = select_function
self.__text = text
self.__font = Font(font, text_size)
self._color: BtnColor = colors
self.__state = BtnStateEnum.INITIAL
self.__surfaces = self.__prepare_surfaces()
# region Public
@property
def text(self) -> str:
return self.__text
@text.setter
def text(self, text: str) -> None:
self.__text = text
self.__surfaces = self.__prepare_surfaces()
def _set_color(self, colors: BtnColor) -> None:
self._color = colors
self.__surfaces = self.__prepare_surfaces()
def select(self) -> None:
self.__state = BtnStateEnum.HOVER
if isinstance(self.__select_function, Callable):
self.__select_function()
def deselect(self) -> None:
self.__state = BtnStateEnum.INITIAL
def activate(self) -> None:
self.__state = BtnStateEnum.CLICK
def click(self) -> None:
if isinstance(self.__function, Callable):
self.__function()
SoundController.play(SoundCh.SYSTEM, Sounds.CLICK)
def is_state(self, state: BtnStateEnum) -> bool:
return self.__state is state
def draw(self, screen: Surface) -> None:
screen.blit(self.__surfaces[self.__state.value], self.rect.topleft)
def event_handler(self, event: Event) -> None:
self.__check_mouse_button_down(event)
self.__check_mouse_button_up(event)
self.__check_mouse_click(event)
self.__check_mouse_motion(event)
# endregion
# region Private
def __mouse_hover(self, pos: Tuple[Union[int, float], Union[int, float]]) -> bool:
return self.rect.collidepoint(pos)
def __check_mouse_motion(self, event: Event) -> None:
if event.type != MOUSEMOTION:
return
if self.__mouse_hover(event.pos):
self.select()
elif self.__state != BtnStateEnum.INITIAL:
self.deselect()
def __check_mouse_button_down(self, event: Event) -> None:
if event.type != MOUSEBUTTONDOWN:
return
if self.__mouse_hover(event.pos):
self.activate()
def __check_mouse_button_up(self, event: Event) -> None:
if event.type != MOUSEBUTTONUP:
return
if self.__mouse_hover(event.pos) and event.button == BUTTON_LEFT and self.__state != BtnStateEnum.INITIAL:
self.deselect()
def __check_mouse_click(self, event: Event) -> None:
if not event.type == MOUSEBUTTONUP:
return
if self.rect.collidepoint(event.pos):
self.select()
self.click()
def __prepare_surfaces(self) -> List[Surface]:
surfaces = []
for index in range(len(self._color)):
surfaces.append(self.__prepare_surface(index))
return surfaces
def __prepare_surface(self, state_index: int) -> Surface:
surface = Surface(self.rect.size)
surface = surface.convert_alpha()
zero_rect = surface.get_rect()
text_surface = self.__font.render(self.text, False, self._color[state_index].text)
zero_text_rect = text_surface.get_rect()
zero_text_rect.center = zero_rect.center
draw.rect(surface, self._color[state_index].background, zero_rect, 0)
surface.blit(text_surface, zero_text_rect)
return surface
# endregion