mirror of
https://github.com/kristoferssolo/Tetris.git
synced 2025-10-21 20:00:35 +00:00
feat(game): add disabled button colors
This commit is contained in:
parent
6fb7fee090
commit
786ecb3536
20
src/game/screens/base_button.py
Normal file
20
src/game/screens/base_button.py
Normal 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."""
|
||||||
@ -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
|
||||||
|
|||||||
@ -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:
|
||||||
|
|||||||
@ -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)
|
|
||||||
Loading…
Reference in New Issue
Block a user