From 786ecb3536b8d3f002fd7dc5de36ba5a646ecba1 Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Sat, 6 Jan 2024 16:13:28 +0200 Subject: [PATCH] feat(game): add disabled button colors --- src/game/screens/base_button.py | 20 ++++++ src/game/screens/button.py | 111 +++++++++++++++++++++++++++++--- src/game/screens/main.py | 22 +++---- src/game/screens/menu_button.py | 95 --------------------------- 4 files changed, 133 insertions(+), 115 deletions(-) create mode 100644 src/game/screens/base_button.py delete mode 100644 src/game/screens/menu_button.py diff --git a/src/game/screens/base_button.py b/src/game/screens/base_button.py new file mode 100644 index 0000000..9a11249 --- /dev/null +++ b/src/game/screens/base_button.py @@ -0,0 +1,20 @@ +from abc import ABC, ABCMeta, abstractmethod +from typing import Callable, Optional + +import pygame + + +class BaseButton(ABC, metaclass=ABCMeta): + """Base button class.""" + + def __init__(self, text: str, action: Optional[Callable[[], None]]) -> None: + self.action = action + self.text = text + + @abstractmethod + def on_click(self) -> None: + """Handle click event.""" + + @abstractmethod + def on_hover(self, event: pygame.Event) -> None: + """Handle hover event.""" diff --git a/src/game/screens/button.py b/src/game/screens/button.py index 197ac3e..b5d87c9 100644 --- a/src/game/screens/button.py +++ b/src/game/screens/button.py @@ -1,20 +1,113 @@ -from abc import ABC, ABCMeta, abstractmethod from typing import Callable, Optional import pygame +from utils import CONFIG + +from .base import BaseScreen, SceenElement, TextScreen +from .base_button import BaseButton -class Button(ABC, metaclass=ABCMeta): - """Base button class.""" - +class Button(BaseButton, BaseScreen, SceenElement, TextScreen): def __init__(self, text: str, action: Optional[Callable[[], None]]) -> None: - self.action = action - self.text = text + super().__init__(text, action) + self._initialize_surface() + self._initialize_font() + self._set_default_background_color() + self._set_default_text_color() - @abstractmethod def on_click(self) -> None: """Handle click event.""" + if self.action: + self.action() - @abstractmethod - def on_hover(self) -> None: + def on_hover(self, event: pygame.Event) -> None: """Handle hover event.""" + if self.rect.collidepoint(event.pos): + self._set_background_color(CONFIG.colors.bg_visual) + else: + self._set_default_background_color() + + def run(self) -> None: + pass + + def update(self) -> None: + """Update the button.""" + + def draw(self, surface: pygame.Surface, pos: tuple[float, float]) -> None: + """Draw the button on the button surface.""" + self._initialize_rect(pos) + self._update_display_surface() + self._draw_background() + self._draw_text() + self._draw_border() + + def _initialize_surface(self) -> None: + """Initialize the button surface.""" + self.surface = pygame.Surface(CONFIG.window.button.size) + self.display_surface = pygame.display.get_surface() + + def _initialize_rect(self, pos: tuple[float, float]) -> None: + """Initialize the button rectangle.""" + self.rect = self.surface.get_rect(center=pos) + + def _draw_text(self) -> None: + """Draw the text on the text surface.""" + x = self.surface.get_width() / 2 + y = self.surface.get_height() / 2 + self._display_text(self.text, (x, y)) + + def _display_text(self, text: str, pos: tuple[float, float]) -> None: + """ + Display a single text element on the button surface. + + Args: + text: The text to be displayed. + pos: The position (x, y) where the text should be displayed. + """ + text_surface = self.font.render(text, True, self.text_color) + text_rect = text_surface.get_rect(center=pos) + self.surface.blit(text_surface, text_rect) + + def _initialize_font(self) -> None: + """Initialize the font used to display the score.""" + self.font = pygame.font.Font(CONFIG.font.family, CONFIG.font.size) + + def _draw_background(self) -> None: + """Fill the background of the button.""" + self.surface.fill(self.color) + + def _draw_border(self) -> None: + """Draw the border of the button.""" + pygame.draw.rect( + self.display_surface, + CONFIG.colors.border_highlight, + self.rect, + CONFIG.game.line_width * 2, + CONFIG.game.border_radius, + ) + + def _update_display_surface(self) -> None: + """Update the display surface.""" + self.display_surface.blit(self.surface, self.rect) + + def _set_default_background_color(self) -> None: + """Set the default background color of the button.""" + self._set_background_color(CONFIG.colors.bg_sidebar) + + def _set_default_text_color(self) -> None: + """Set the default text color of the button.""" + self._set_text_color(CONFIG.colors.fg_float) + + def _set_text_color(self, color: str = CONFIG.colors.fg_float) -> None: + """Set the text color of the button.""" + if self.action is None: + self.text_color = CONFIG.colors.fg_dark + return + self.text_color = color + + def _set_background_color(self, color: str) -> None: + """Set the background color of the button.""" + if self.action is None: + self.color = CONFIG.colors.comment + return + self.color = color diff --git a/src/game/screens/main.py b/src/game/screens/main.py index 6a45fd4..70e99a8 100644 --- a/src/game/screens/main.py +++ b/src/game/screens/main.py @@ -6,8 +6,8 @@ from utils import CONFIG, GameMode from game.log import log from .base import BaseScreen, SceenElement, TextScreen +from .button import Button from .game import Game -from .menu_button import MenuButton class Main(BaseScreen, SceenElement, TextScreen): @@ -43,12 +43,8 @@ class Main(BaseScreen, SceenElement, TextScreen): if button.rect.collidepoint(mouse_pos): button.on_click() elif event.type == pygame.MOUSEMOTION: - mouse_pos = pygame.mouse.get_pos() for button in self.buttons: - if button.rect.collidepoint(mouse_pos): - button.update(True) - else: - button.update(False) + button.on_hover(event) def run(self) -> None: while True: @@ -57,15 +53,19 @@ class Main(BaseScreen, SceenElement, TextScreen): def exit(self) -> None: """Exit the game.""" + log.info("Exiting the game") pygame.quit() sys.exit() + def play(self) -> None: + pass + def _set_buttons(self) -> None: - self.buttons: list[MenuButton] = [ - MenuButton("Play", None), - MenuButton("AI", None), - MenuButton("Settings", None), - MenuButton("Quit", self.exit), + self.buttons: list[Button] = [ + Button("Play", self.play), + Button("AI", None), + Button("Settings", None), + Button("Quit", self.exit), ] def _initialize_pygame(self) -> None: diff --git a/src/game/screens/menu_button.py b/src/game/screens/menu_button.py deleted file mode 100644 index e658630..0000000 --- a/src/game/screens/menu_button.py +++ /dev/null @@ -1,95 +0,0 @@ -from typing import Callable, Optional - -import pygame -from utils import CONFIG - -from .base import BaseScreen, SceenElement, TextScreen -from .button import Button - - -class MenuButton(Button, BaseScreen, SceenElement, TextScreen): - def __init__(self, text: str, action: Optional[Callable[[], None]]) -> None: - super().__init__(text, action) - self._initialize_surface() - self._initialize_font() - self.hover = False - - def on_click(self) -> None: - """Handle click event.""" - if self.action: - self.action() - - def on_hover(self) -> None: - """Handle hover event.""" - self._draw_hover_background() - - def run(self) -> None: - pass - - def update(self, hover: bool = False) -> None: - """Update the button.""" - self.hover = hover - - def draw(self, surface: pygame.Surface, pos: tuple[float, float]) -> None: - """Draw the button on the button surface.""" - self._initialize_rect(pos) - self._update_display_surface() - if self.hover: - self.on_hover() - else: - self._draw_background() - self._draw_text() - self._draw_border() - - def _initialize_surface(self) -> None: - """Initialize the button surface.""" - self.surface = pygame.Surface(CONFIG.window.button.size) - self.display_surface = pygame.display.get_surface() - - def _initialize_rect(self, pos: tuple[float, float]) -> None: - """Initialize the button rectangle.""" - self.rect = self.surface.get_rect(center=pos) - - def _draw_text(self) -> None: - """Draw the text on the text surface.""" - x = self.surface.get_width() / 2 - y = self.surface.get_height() / 2 - self._display_text(self.text, (x, y)) - - def _display_text(self, text: str, pos: tuple[float, float]) -> None: - """ - Display a single text element on the button surface. - - Args: - text: The text to be displayed. - pos: The position (x, y) where the text should be displayed. - """ - text_surface = self.font.render(text, True, CONFIG.colors.fg_sidebar) - text_rect = text_surface.get_rect(center=pos) - self.surface.blit(text_surface, text_rect) - - def _initialize_font(self) -> None: - """Initialize the font used to display the score.""" - self.font = pygame.font.Font(CONFIG.font.family, CONFIG.font.size) - - def _draw_background(self) -> None: - """Fill the background of the button.""" - self.surface.fill(CONFIG.colors.bg_sidebar) - - def _draw_hover_background(self) -> None: - """Fill the background of the button.""" - self.surface.fill(CONFIG.colors.bg_visual) - - def _draw_border(self) -> None: - """Draw the border of the button.""" - pygame.draw.rect( - self.display_surface, - CONFIG.colors.border_highlight, - self.rect, - CONFIG.game.line_width * 2, - CONFIG.game.border_radius, - ) - - def _update_display_surface(self) -> None: - """Update the display surface.""" - self.display_surface.blit(self.surface, self.rect)