2048/src/py2048/objects/button.py

72 lines
2.4 KiB
Python

import sys
import pygame
from attrs import define, field
from py2048.color import ColorScheme
from py2048.config import Config
@define
class Button(pygame.sprite.Sprite):
def __init__(self, text: str, x: int, y: int, group: pygame.sprite.Group):
super().__init__()
self.text = text
self.image = self._create_button_surface()
# text: str = field(kw_only=True)
# font_family: str = field(kw_only=True)
# font_size: int = field(kw_only=True)
# font_color: ColorScheme = field(kw_only=True)
# position: tuple[int, int] = field(kw_only=True)
# width: int = field(kw_only=True)
# height: int = field(kw_only=True)
# action = field(kw_only=True)
# bg_color: ColorScheme = field(kw_only=True)
# hover_color: ColorScheme = field(kw_only=True)
# font: pygame.Font = field(init=False)
# rendered_text: pygame.Surface = field(init=False)
# rect: pygame.Rect = field(init=False)
# is_hovered: bool = field(init=False, default=False)
def __attrs_post_init__(self) -> None:
"""Initialize the button."""
self.font = pygame.font.SysFont(self.font_family, self.font_size)
self._draw_text()
def _draw_text(self) -> None:
"""Draw the text on the button."""
self.rendered_text = self.font.render(
self.text, True, self.font_color, self.bg_color
)
self.rect = pygame.Rect(
self.position[0], self.position[1], self.width, self.height
)
def check_hover(self, mouse_pos: tuple[int, int]) -> None:
"""Check if the mouse is hovering over the button."""
self.is_hovered = self.rect.collidepoint(mouse_pos)
def check_click(self, mouse_pos: tuple[int, int]) -> None:
"""Check if the button is clicked."""
if self.rect.collidepoint(mouse_pos) and self.action:
self.action()
def draw(self, surface: pygame.Surface) -> None:
"""Draw the button on the given surface."""
if self.is_hovered:
self._draw_rect(surface, self.hover_color)
else:
self._draw_rect(surface, self.bg_color)
surface.blit(self.rendered_text, self.position)
def _draw_rect(self, surface: pygame.Surface, color: ColorScheme) -> None:
"""Draw the button rectangle."""
pygame.draw.rect(
surface,
self.bg_color,
self.rect,
border_radius=Config.TILE_BORDER_RADIUS,
)