feat(game): add disabled button colors

This commit is contained in:
Kristofers Solo 2024-01-06 16:13:28 +02:00
parent 6fb7fee090
commit 786ecb3536
4 changed files with 133 additions and 115 deletions

View File

@ -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."""

View File

@ -1,20 +1,113 @@
from abc import ABC, ABCMeta, abstractmethod
from typing import Callable, Optional from typing import Callable, Optional
import pygame import pygame
from utils import CONFIG
from .base import BaseScreen, SceenElement, TextScreen
from .base_button import BaseButton
class Button(ABC, metaclass=ABCMeta): class Button(BaseButton, BaseScreen, SceenElement, TextScreen):
"""Base button class."""
def __init__(self, text: str, action: Optional[Callable[[], None]]) -> None: def __init__(self, text: str, action: Optional[Callable[[], None]]) -> None:
self.action = action super().__init__(text, action)
self.text = text self._initialize_surface()
self._initialize_font()
self._set_default_background_color()
self._set_default_text_color()
@abstractmethod
def on_click(self) -> None: def on_click(self) -> None:
"""Handle click event.""" """Handle click event."""
if self.action:
self.action()
@abstractmethod def on_hover(self, event: pygame.Event) -> None:
def on_hover(self) -> None:
"""Handle hover event.""" """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

View File

@ -6,8 +6,8 @@ from utils import CONFIG, GameMode
from game.log import log from game.log import log
from .base import BaseScreen, SceenElement, TextScreen from .base import BaseScreen, SceenElement, TextScreen
from .button import Button
from .game import Game from .game import Game
from .menu_button import MenuButton
class Main(BaseScreen, SceenElement, TextScreen): class Main(BaseScreen, SceenElement, TextScreen):
@ -43,12 +43,8 @@ class Main(BaseScreen, SceenElement, TextScreen):
if button.rect.collidepoint(mouse_pos): if button.rect.collidepoint(mouse_pos):
button.on_click() button.on_click()
elif event.type == pygame.MOUSEMOTION: elif event.type == pygame.MOUSEMOTION:
mouse_pos = pygame.mouse.get_pos()
for button in self.buttons: for button in self.buttons:
if button.rect.collidepoint(mouse_pos): button.on_hover(event)
button.update(True)
else:
button.update(False)
def run(self) -> None: def run(self) -> None:
while True: while True:
@ -57,15 +53,19 @@ class Main(BaseScreen, SceenElement, TextScreen):
def exit(self) -> None: def exit(self) -> None:
"""Exit the game.""" """Exit the game."""
log.info("Exiting the game")
pygame.quit() pygame.quit()
sys.exit() sys.exit()
def play(self) -> None:
pass
def _set_buttons(self) -> None: def _set_buttons(self) -> None:
self.buttons: list[MenuButton] = [ self.buttons: list[Button] = [
MenuButton("Play", None), Button("Play", self.play),
MenuButton("AI", None), Button("AI", None),
MenuButton("Settings", None), Button("Settings", None),
MenuButton("Quit", self.exit), Button("Quit", self.exit),
] ]
def _initialize_pygame(self) -> None: def _initialize_pygame(self) -> None:

View File

@ -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)