Lev
3 years ago
3 changed files with 113 additions and 4 deletions
@ -0,0 +1,99 @@
|
||||
import pygame |
||||
import typing |
||||
|
||||
from config import font, WHITE, BLUE, BLACK |
||||
from dataclasses import dataclass |
||||
|
||||
|
||||
@dataclass |
||||
class Button: |
||||
""" |
||||
Just a button element for pygame |
||||
Attributes: |
||||
:param text (str): Text on the button |
||||
:param top_left ((int, int)): the coordinates of the top-left point of the button |
||||
:param width (int): the width of the button |
||||
:param height (int): the height of the button |
||||
:param padding (int): padding - the distance between rectangle border and button content |
||||
:param bg_color (Color): the background color |
||||
:param text_color (Color): color of the text |
||||
:param hovered_color (Color): the background color when the button is hovered |
||||
:param hovered_text_color (Color): the text color when the button is hovered |
||||
:param pressed_color (Color): the background color when the button is pressed |
||||
:param pressed_text_color (Color): the text color when the button is pressed |
||||
""" |
||||
text: str |
||||
top_left: typing.Tuple[int, int] |
||||
width: int |
||||
height: int |
||||
padding: int = 5 |
||||
bg_color: pygame.Color = BLUE |
||||
text_color: pygame.Color = WHITE |
||||
hovered_color: pygame.Color = (BLUE * 3 + WHITE) // 4 |
||||
hovered_text_color: pygame.Color = BLACK |
||||
pressed_color: pygame.Color = (BLUE + WHITE * 3) // 4 |
||||
pressed_text_color: pygame.Color = BLACK |
||||
is_hovered: bool = False |
||||
is_pressed: bool = False |
||||
|
||||
@property |
||||
def bottom(self) -> int: |
||||
""" |
||||
Return the y coordinate of the bottom of the button |
||||
:return: y_bottom |
||||
""" |
||||
return self.top_left[1] + self.height |
||||
|
||||
@property |
||||
def right(self) -> int: |
||||
""" |
||||
Return the x coordinate of the right edge of the button |
||||
:return: x_right |
||||
""" |
||||
return self.top_left[0] + self.width |
||||
|
||||
def get_colors(self) -> typing.Tuple[pygame.Color, pygame.Color]: |
||||
""" |
||||
Get background and text color considering hovered and pressed states |
||||
:return: the button's background color and the button's text color |
||||
""" |
||||
if self.is_pressed: |
||||
return self.pressed_color, self.pressed_text_color |
||||
if self.is_hovered: |
||||
return self.hovered_color, self.hovered_text_color |
||||
return self.bg_color, self.text_color |
||||
|
||||
def render(self) -> pygame.Surface: |
||||
""" |
||||
Draw the button |
||||
:return: a pygame surface with the button |
||||
""" |
||||
surface: pygame.Surface = pygame.Surface((self.width, self.height)) |
||||
bg_color, text_color = self.get_colors() |
||||
surface.fill(bg_color) |
||||
text_surface: pygame.Surface = font.render(self.text, True, text_color) |
||||
text_height: int = self.height - 2 * self.padding |
||||
text_width: int = round(text_surface.get_width() * text_height / text_surface.get_height()) |
||||
text_surface: pygame.Surface = pygame.transform.scale(text_surface, (text_width, text_height)) |
||||
surface.blit(text_surface, ((self.width - text_width) // 2, self.padding)) |
||||
return surface |
||||
|
||||
def process_event(self, event: pygame.event.Event) -> bool: |
||||
""" |
||||
Process a pygame event. If it's a click on this button, return true |
||||
:param event: a pygame event |
||||
:return: True if there was a click on the button |
||||
""" |
||||
# if this is a mouse event |
||||
if event.type in [pygame.MOUSEBUTTONUP, pygame.MOUSEMOTION, pygame.MOUSEBUTTONDOWN]: |
||||
# if the mouse event is inside the button |
||||
if self.top_left[0] <= event.pos[0] < self.bottom and self.top_left[1] <= event.pos[1] < self.right: |
||||
if event.type == pygame.MOUSEBUTTONUP: |
||||
self.is_pressed = False |
||||
return True |
||||
elif event.type == pygame.MOUSEBUTTONDOWN: |
||||
self.is_hovered = False |
||||
self.is_pressed = True |
||||
elif event.type == pygame.MOUSEMOTION: |
||||
self.is_hovered = True |
||||
return False |
Loading…
Reference in new issue