Ajout de la redimension automatique des boutons et hover

This commit is contained in:
Yannis 2024-01-07 17:58:24 +01:00
parent 745a182ec8
commit 21aa1c9768
Signed by: yannis
SSH key fingerprint: SHA256:Bz8K8QiTYUudf8MlthTM9MCLfgiYf/U1md3V9g9Wo14
5 changed files with 51 additions and 15 deletions

View file

@ -36,7 +36,7 @@ class Engine:
self.boss_fight_manager = BossFightManager(self) self.boss_fight_manager = BossFightManager(self)
self.event_sheduler = EventSheduler(self) self.event_sheduler = EventSheduler(self)
self.dialogs_manager = DialogsManager(self.event_handler) self.dialogs_manager = DialogsManager(self.event_handler)
self.menu_manager = MenuManager() self.menu_manager = MenuManager(self)
def loop(self): def loop(self):
"""Fonction à lancer au début du programme et qui va lancer les updates dans une boucle. """Fonction à lancer au début du programme et qui va lancer les updates dans une boucle.

View file

@ -14,6 +14,7 @@ class EventHandler:
self.engine = core self.engine = core
self.key_pressed = [] self.key_pressed = []
self.buttons_area = [] self.buttons_area = []
self.hovered_area = []
@staticmethod @staticmethod
def get_click_collision(rect: tuple[float | int, float | int, float | int, float | int], point: tuple[int, int], def get_click_collision(rect: tuple[float | int, float | int, float | int, float | int], point: tuple[int, int],
@ -37,11 +38,12 @@ class EventHandler:
def register_button_area(self, rect: tuple[float | int, float | int, float | int, float | int], def register_button_area(self, rect: tuple[float | int, float | int, float | int, float | int],
callback: FunctionType | classmethod | staticmethod, name: str, callback: FunctionType | classmethod | staticmethod, name: str,
is_window_relative: int = -1): is_window_relative: int = -1,
hover_callback: FunctionType | classmethod | staticmethod = None):
"""Enregistre une zone comme bouton. La fonction donnée sera donc executé lorsque la zone sur la fenêtre """Enregistre une zone comme bouton. La fonction donnée sera donc executé lorsque la zone sur la fenêtre
sera cliqué. is_window_relative doit être 0 pour que le rect soit multipliée par la largeur de la fenêtre et 1 sera cliqué. is_window_relative doit être 0 pour que le rect soit multipliée par la largeur de la fenêtre et 1
pour qu'elle soit multipliée par la hauteur""" pour qu'elle soit multipliée par la hauteur"""
self.buttons_area.append((rect, callback, is_window_relative, name)) self.buttons_area.append((rect, callback, is_window_relative, name, hover_callback))
def remove_button_area(self, name: str): def remove_button_area(self, name: str):
"""Supprime les boutons aux noms donnés.""" """Supprime les boutons aux noms donnés."""
@ -72,6 +74,10 @@ class EventHandler:
for area in self.buttons_area: for area in self.buttons_area:
if self.get_click_collision(area[0], e.pos, area[2]): if self.get_click_collision(area[0], e.pos, area[2]):
area[1]() area[1]()
elif e.type == MOUSEMOTION:
for area in self.buttons_area:
if area[4] is not None and self.get_click_collision(area[0], e.pos, area[2]):
area[4]()
if self.engine.entity_manager.player_entity_name: if self.engine.entity_manager.player_entity_name:
if K_RIGHT in self.key_pressed: if K_RIGHT in self.key_pressed:

View file

@ -1,9 +1,9 @@
import threading
import tkinter
from types import FunctionType from types import FunctionType
import pygame import pygame
import src.engine.engine
class Widget: class Widget:
"""Classe parente des widgets de menu.""" """Classe parente des widgets de menu."""
@ -28,7 +28,8 @@ class Button(Widget):
"""Un widget de bouton.""" """Un widget de bouton."""
def __init__(self, x: int | float, y: int | float, text: str, size: int | float, color: tuple[int, int, int], def __init__(self, x: int | float, y: int | float, text: str, size: int | float, color: tuple[int, int, int],
callback: FunctionType | classmethod | staticmethod, base_image: pygame.Surface, callback: FunctionType | classmethod | staticmethod, base_image: pygame.Surface,
hover_image: pygame.Surface, centered: bool = False, is_window_relative: int = -1): hover_image: pygame.Surface, centered: bool = False, is_window_relative: int = -1,
area_name: str = "menu_button"):
super().__init__(x, y, is_window_relative) super().__init__(x, y, is_window_relative)
self.text = text self.text = text
self.size = size self.size = size
@ -37,6 +38,11 @@ class Button(Widget):
self.base_image = base_image self.base_image = base_image
self.hover_image = hover_image self.hover_image = hover_image
self.centered = centered self.centered = centered
self.area_name = area_name
self.hovered = False
def set_hover_state(self, state: bool):
self.hovered = state
class Menu: class Menu:
@ -52,14 +58,29 @@ class Menu:
class MenuManager: class MenuManager:
"""Classe qui gère les menus.""" """Classe qui gère les menus."""
def __init__(self): def __init__(self, engine: 'src.engine.engine.Engine'):
self.menus = {} self.menus = {}
self.active_menu: Menu | None = None self.active_menu: Menu | None = None
self.engine = engine
def register_menu(self, menu: Menu, name: str): def register_menu(self, menu: Menu, name: str):
"""Ajoute le menu donné au manager de menu avec le nom donné.""" """Ajoute le menu donné au manager de menu avec le nom donné."""
self.menus[name] = menu self.menus[name] = menu
# On itère dans tous les bouttons pour leur ajouter une interaction
for btn in menu.widgets:
if isinstance(btn, Button):
width = btn.base_image.get_width()/self.engine.renderer.window_size[0]
height = btn.base_image.get_height()/self.engine.renderer.window_size[1]
area_x = btn.x
area_y = btn.y
if btn.centered:
area_x -= width/2
area_y -= height/2
self.engine.event_handler.register_button_area((area_x, area_y, width, height), btn.callback, btn.area_name,
btn.is_window_relative, lambda: print("hover"))
print(btn.is_window_relative)
def show(self, name: str): def show(self, name: str):
"""Affiche le menu au nom donné.""" """Affiche le menu au nom donné."""
self.active_menu = self.menus[name] self.active_menu = self.menus[name]

View file

@ -191,7 +191,6 @@ class Renderer:
else: else:
self.window.blit(rendered_text, (x, y)) self.window.blit(rendered_text, (x, y))
elif isinstance(widget, Button): elif isinstance(widget, Button):
print("a")
# On multiplie la taille du texte si besoin # On multiplie la taille du texte si besoin
if widget.is_window_relative == 0: if widget.is_window_relative == 0:
size = widget.size*window_size[0] size = widget.size*window_size[0]
@ -204,14 +203,24 @@ class Renderer:
text_font = font.SysFont("Arial", round(size)) text_font = font.SysFont("Arial", round(size))
# On affiche l'image du boutton
self.window.blit(widget.base_image, (x-widget.base_image.get_width()//2,
y-widget.base_image.get_height()//2))
rendered_text = text_font.render(widget.text, True, widget.color) rendered_text = text_font.render(widget.text, True, widget.color)
self.window.blit(rendered_text, (x-rendered_text.get_width()//2,
y-rendered_text.get_height()//2))
btn_image = widget.base_image
btn_image = transform.scale(btn_image, (btn_image.get_width()*window_size[0]/self.window_size[0],
btn_image.get_height()*window_size[0]/self.window_size[0]))
# On affiche l'image du boutton
if widget.centered:
self.window.blit(btn_image, (x-btn_image.get_width()//2,
y-btn_image.get_height()//2))
self.window.blit(rendered_text, (x-rendered_text.get_width()//2,
y-rendered_text.get_height()//2))
else:
self.window.blit(btn_image, (x, y))
self.window.blit(rendered_text, (x, y))
def render_dialogs_box(self): def render_dialogs_box(self):
"""Rend la boite de dialogue lorsqu'un dialogue est lancé.""" """Rend la boite de dialogue lorsqu'un dialogue est lancé."""

View file

@ -38,7 +38,7 @@ class Game(Engine):
base_image = pygame.image.load("assets/textures/GUI/button_1.png").convert_alpha() base_image = pygame.image.load("assets/textures/GUI/button_1.png").convert_alpha()
menu.add_widget(Button(0.5, 0.3, "boutton", 0.1, (0, 255, 0), lambda : print("play"), base_image, base_image, True, 2)) menu.add_widget(Button(0.5, 0.3, "boutton", 0.1, (0, 255, 0), lambda : print("play"), base_image, base_image, True, 0))
self.menu_manager.register_menu(menu, "main") self.menu_manager.register_menu(menu, "main")
self.menu_manager.show("main") self.menu_manager.show("main")