commented widgets
This commit is contained in:
parent
89c6b81ba9
commit
51eb35c43c
16 changed files with 206 additions and 132 deletions
|
@ -6,5 +6,9 @@ path = path_sound / "ambient"
|
|||
|
||||
|
||||
class SoundAmbient(MediaGroup):
|
||||
"""
|
||||
Groupe contenant les sons ambient du jeu.
|
||||
"""
|
||||
|
||||
menu = Sound(path / "menu.wav")
|
||||
sea = Sound(path / "sea.wav")
|
||||
|
|
|
@ -6,6 +6,10 @@ path = path_sound / "effect"
|
|||
|
||||
|
||||
class SoundEffect(MediaGroup):
|
||||
"""
|
||||
Groupe contenant les effets sonores du jeu.
|
||||
"""
|
||||
|
||||
placed = Sound(path / "placed.wav")
|
||||
touched = Sound(path / "touched.wav")
|
||||
missed = Sound(path / "missed.wav")
|
||||
|
|
|
@ -5,7 +5,7 @@ import pyglet
|
|||
|
||||
class MediaGroup(ABC):
|
||||
"""
|
||||
This class represent a music group that can be played.
|
||||
Cette classe représente un groupe de musique pouvant être joué.
|
||||
"""
|
||||
|
||||
player: pyglet.media.Player
|
||||
|
|
|
@ -11,6 +11,10 @@ if TYPE_CHECKING:
|
|||
|
||||
|
||||
class Sound(Media):
|
||||
"""
|
||||
Représente un son pouvant être joué par le lecteur.
|
||||
"""
|
||||
|
||||
def __init__(self, path: Path):
|
||||
self.path = path
|
||||
|
||||
|
|
|
@ -10,10 +10,21 @@ if TYPE_CHECKING:
|
|||
|
||||
|
||||
class Media(ABC):
|
||||
loaded_media: dict[Path, pyglet.media.Source] = {}
|
||||
"""
|
||||
Représente un type de média
|
||||
"""
|
||||
|
||||
loaded_media: dict[Path, pyglet.media.Source] = {} # cache des médias chargés
|
||||
|
||||
@classmethod
|
||||
def get_media(cls, path: Path, owner: "MediaGroup") -> pyglet.media.Source:
|
||||
"""
|
||||
Renvoie le média correspondant au chemin donné
|
||||
:param path: le chemin du media
|
||||
:param owner: la classe qui a appelé la fonction
|
||||
:return: le média
|
||||
"""
|
||||
|
||||
if (media := cls.loaded_media.get(path)) is None:
|
||||
# charge le son
|
||||
media = pyglet.media.load(path)
|
||||
|
@ -38,4 +49,10 @@ class Media(ABC):
|
|||
|
||||
@abstractmethod
|
||||
def __get__(self, instance, owner) -> pyglet.media.Source:
|
||||
"""
|
||||
Renvoie le média correspondant à l'instance donnée
|
||||
:param instance: instance de la classe qui a appelé la fonction
|
||||
:param owner: classe ayant appelé la fonction
|
||||
:return: le media
|
||||
"""
|
||||
pass
|
||||
|
|
|
@ -14,8 +14,9 @@ if TYPE_CHECKING:
|
|||
|
||||
class Button(BoxWidget):
|
||||
"""
|
||||
A button widget with a background texture that change depending on if it is clicked or hovered, and a label.
|
||||
You can pass parameter to the background and label by adding "background_" and "label_" before the parameter.
|
||||
Un bouton avec une texture de fond qui change en fonction de s'il est cliqué ou survolé et un label.
|
||||
Vous pouvez passer des paramètres pour le background et au label en ajoutant "background_" et "label_"
|
||||
devant le paramètre.
|
||||
"""
|
||||
|
||||
def __init__(self, scene: "Scene",
|
||||
|
@ -48,17 +49,17 @@ class Button(BoxWidget):
|
|||
self.add_listener("on_hover_change", lambda *_: self._refresh_background())
|
||||
self.add_listener("on_click_change", lambda *_: self._refresh_background())
|
||||
|
||||
self._refresh_size() # refresh the size and position for the background and label
|
||||
self._refresh_size() # rafraîchit la taille et la position du background et du label
|
||||
|
||||
# background
|
||||
|
||||
@property
|
||||
def background_texture(self) -> pyglet.image.AbstractImage:
|
||||
"""
|
||||
Return the correct texture for the background.
|
||||
The clicking texture per default, if hover the hovered texture (if it exists)
|
||||
and if click the clicking texture (if it exists)
|
||||
:return: the corresponding texture
|
||||
Renvoie la bonne texture pour le fond.
|
||||
Utilise la texture normale par défaut, si survolé la texture de survol (si elle existe)
|
||||
et la texture de clic (si elle existe) si cliqué
|
||||
:return: la texture correspondante
|
||||
"""
|
||||
|
||||
return (
|
||||
|
|
|
@ -12,7 +12,7 @@ if TYPE_CHECKING:
|
|||
|
||||
class Checkbox(BoxWidget):
|
||||
"""
|
||||
A checkbox widget with a background texture that change depending on if it is checked or unchecked.
|
||||
Un widget de checkbox avec une texture d'arrière-plan qui change en fonction de si elle est cochée ou non.
|
||||
"""
|
||||
|
||||
def __init__(self, scene: "Scene",
|
||||
|
@ -43,7 +43,7 @@ class Checkbox(BoxWidget):
|
|||
|
||||
self._refresh_size()
|
||||
|
||||
# refreshing
|
||||
# rafraichissement
|
||||
|
||||
@property
|
||||
def tick_texture(self):
|
||||
|
@ -56,7 +56,7 @@ class Checkbox(BoxWidget):
|
|||
self.tick.x, self.tick.y = self.xy
|
||||
self.tick.width, self.tick.height = self.size
|
||||
|
||||
# property
|
||||
# propriétés
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
|
|
|
@ -19,7 +19,7 @@ if TYPE_CHECKING:
|
|||
|
||||
class GameGrid(BoxWidget):
|
||||
"""
|
||||
A widget that represent a game grid.
|
||||
Un widget représentant la grille du jeu
|
||||
"""
|
||||
|
||||
def __init__(self, scene: "Scene",
|
||||
|
@ -49,7 +49,7 @@ class GameGrid(BoxWidget):
|
|||
self.group_cursor = pyglet.graphics.Group(order=1)
|
||||
self.group_line = pyglet.graphics.Group(order=2)
|
||||
|
||||
# the list of the size of the boats to place
|
||||
# la liste des tailles des bateaux a placé sur la grille
|
||||
self.boats_length = [] if boats_length is None else sorted(boats_length, reverse=True)
|
||||
|
||||
# créer la planche du jeu
|
||||
|
@ -104,13 +104,13 @@ class GameGrid(BoxWidget):
|
|||
int((rel_y-1) / self.cell_height)
|
||||
)
|
||||
|
||||
# refresh
|
||||
# rafraichissement
|
||||
|
||||
def _refresh_size(self):
|
||||
self.background.x, self.background.y = self.xy
|
||||
self.background.width, self.background.height = self.size
|
||||
|
||||
# lines
|
||||
# lignes
|
||||
|
||||
for column, line in enumerate(self.lines[:self.columns - 1], start=1):
|
||||
line.x = self.x + self.cell_width * column
|
||||
|
@ -149,7 +149,7 @@ class GameGrid(BoxWidget):
|
|||
self.cursor.y = self.y + cell_y * self.height / self.rows
|
||||
self.cursor.width, self.cursor.height = self.cell_size
|
||||
|
||||
self.preview_boat((cell_x, cell_y)) # display the preview of the boat on this cell
|
||||
self.preview_boat((cell_x, cell_y)) # affiche la grille du jeu en prévisualisant cette cellule
|
||||
|
||||
# function
|
||||
|
||||
|
@ -161,7 +161,11 @@ class GameGrid(BoxWidget):
|
|||
self.display_board(self.board)
|
||||
|
||||
def display_board(self, board: Board, preview: bool = False):
|
||||
# remplacer par l'utilisation de board.boats ?
|
||||
"""
|
||||
Affiche la grille du jeu.
|
||||
:param board: la grille du jeu à afficher
|
||||
:param preview: la prévisualisation du dernier bateau est-elle activée ?
|
||||
"""
|
||||
|
||||
matrice = board.boats
|
||||
max_boat: int = np.max(matrice)
|
||||
|
@ -220,12 +224,21 @@ class GameGrid(BoxWidget):
|
|||
self._refresh_size()
|
||||
|
||||
def swap_orientation(self):
|
||||
"""
|
||||
Inverse l'orientation du bateau en cours de placement.
|
||||
"""
|
||||
|
||||
self.orientation = (
|
||||
Orientation.HORIZONTAL if self.orientation is Orientation.VERTICAL else
|
||||
Orientation.VERTICAL
|
||||
)
|
||||
|
||||
def place_boat(self, cell: Point2D):
|
||||
"""
|
||||
Place un bateau sur la grille du jeu.
|
||||
:param cell: position sur laquelle placer le bateau
|
||||
"""
|
||||
|
||||
if len(self.boats_length) == 0: return
|
||||
|
||||
try:
|
||||
|
@ -234,10 +247,10 @@ class GameGrid(BoxWidget):
|
|||
cell
|
||||
)
|
||||
except InvalidBoatPosition:
|
||||
pass # if the boat can't be placed, ignore
|
||||
pass # si le bateau n'a pas pu être placé, ignore
|
||||
|
||||
else: # if the boat have been placed
|
||||
self.boats_length.pop(0) # remove the boat from the list of boat to place
|
||||
else: # si le bateau a bien été placé
|
||||
self.boats_length.pop(0) # retire la taille du bateau de la liste des bateaux à placer
|
||||
|
||||
self.trigger_event("on_boat_placed")
|
||||
if len(self.boats_length) == 0:
|
||||
|
@ -246,6 +259,11 @@ class GameGrid(BoxWidget):
|
|||
self.refresh_board() # rafraichi l'affichage
|
||||
|
||||
def preview_boat(self, cell: Point2D):
|
||||
"""
|
||||
Prévisualise le prochain bateau à placer.
|
||||
:param cell: position où visualiser le bateau
|
||||
"""
|
||||
|
||||
if len(self.boats_length) == 0: return
|
||||
|
||||
try:
|
||||
|
@ -260,6 +278,13 @@ class GameGrid(BoxWidget):
|
|||
else: self.display_board(preview_board, preview=True)
|
||||
|
||||
def place_bomb(self, cell: Point2D, force_touched: bool = None) -> BombState:
|
||||
"""
|
||||
Place une bombe sur la grille du jeu.
|
||||
:param cell: cellule sur laquelle placer la bombe
|
||||
:param force_touched: la cellule doit-elle forcer l'affichage comment étant manqué ou touché ?
|
||||
:return: l'état de la bombe
|
||||
"""
|
||||
|
||||
bomb_state = self.board.bomb(cell)
|
||||
|
||||
if force_touched is not None:
|
||||
|
@ -270,7 +295,10 @@ class GameGrid(BoxWidget):
|
|||
return bomb_state
|
||||
|
||||
def remove_bomb(self, cell: Point2D):
|
||||
# retire une bombe de la planche
|
||||
"""
|
||||
Retire une bombe de la grille du jeu.
|
||||
:param cell: cellule de la bombe à retirer
|
||||
"""
|
||||
self.board.remove_bomb(cell)
|
||||
self.refresh_board()
|
||||
|
||||
|
@ -278,29 +306,27 @@ class GameGrid(BoxWidget):
|
|||
cell = self.get_cell_from_rel(rel_x, rel_y)
|
||||
|
||||
match button:
|
||||
# si le joueur fait un clic droit, inverse l'orientation du bateau en cours de placement
|
||||
case pyglet.window.mouse.RIGHT:
|
||||
self.swap_orientation()
|
||||
self.preview_boat(cell)
|
||||
|
||||
# si le joueur fait un clic gauche, place un bateau ou une bombe
|
||||
case pyglet.window.mouse.LEFT:
|
||||
self.place_boat(cell)
|
||||
self.trigger_event("on_request_place_bomb", cell)
|
||||
|
||||
# property
|
||||
# propriétés
|
||||
|
||||
@property
|
||||
def cell_width(self) -> float:
|
||||
return self.width / self.columns
|
||||
def cell_width(self) -> float: return self.width / self.columns
|
||||
|
||||
@property
|
||||
def cell_height(self) -> float:
|
||||
return self.height / self.rows
|
||||
def cell_height(self) -> float: return self.height / self.rows
|
||||
|
||||
@property
|
||||
def cell_size(self) -> tuple[float, float]:
|
||||
return self.cell_width, self.cell_height
|
||||
def cell_size(self) -> tuple[float, float]: return self.cell_width, self.cell_height
|
||||
|
||||
# event
|
||||
# événements
|
||||
|
||||
def on_resize(self, width: int, height: int):
|
||||
self._refresh_size()
|
||||
def on_resize(self, width: int, height: int): self._refresh_size()
|
||||
|
|
|
@ -12,7 +12,7 @@ if TYPE_CHECKING:
|
|||
|
||||
class Image(BoxWidget):
|
||||
"""
|
||||
An image widget with a texture.
|
||||
Un widget d'image avec une texture.
|
||||
"""
|
||||
|
||||
def __init__(self, scene: "Scene",
|
||||
|
|
|
@ -15,7 +15,7 @@ if TYPE_CHECKING:
|
|||
|
||||
class Input(BoxWidget):
|
||||
"""
|
||||
An input widget with a background texture and a label. A regex pattern can be added to validate the input.
|
||||
Un widget d'entrée avec une texture de fond et un label. Des paternes regex peut être ajouté pour valider l'entrée.
|
||||
"""
|
||||
|
||||
def __init__(self, scene: "Scene",
|
||||
|
@ -64,18 +64,19 @@ class Input(BoxWidget):
|
|||
@property
|
||||
def background_texture(self) -> pyglet.image.AbstractImage:
|
||||
"""
|
||||
Return the correct texture for the background.
|
||||
The clicking texture per default, if hover the hovered texture (if it exists)
|
||||
and if click the clicking texture (if it exists)
|
||||
:return: the corresponding texture
|
||||
Renvoie la texture de fond correspondante.
|
||||
Si le widget est activé, renvoie la texture active (si elle existe),
|
||||
la texture de clic (si elle existe) sinon la texture normale
|
||||
:return: la texture de fond correspondante
|
||||
"""
|
||||
|
||||
return (
|
||||
texture if self.activated and (texture := self.style.get("active")) is not None else # NOQA
|
||||
texture if not self.valid and (texture := self.style.get("error")) is not None else
|
||||
self.style.get("normal")
|
||||
)
|
||||
|
||||
# refresh
|
||||
# rafraichissement
|
||||
|
||||
def _refresh_background(self) -> None:
|
||||
self.background.image = self.background_texture
|
||||
|
@ -94,8 +95,7 @@ class Input(BoxWidget):
|
|||
# property
|
||||
|
||||
@property
|
||||
def valid(self):
|
||||
return self._valid
|
||||
def valid(self): return self._valid
|
||||
|
||||
@valid.setter
|
||||
def valid(self, valid: bool):
|
||||
|
@ -103,14 +103,12 @@ class Input(BoxWidget):
|
|||
self._refresh_background()
|
||||
|
||||
@property
|
||||
def text(self):
|
||||
return self.label.text
|
||||
def text(self): return self.label.text
|
||||
|
||||
@text.setter
|
||||
def text(self, text: str):
|
||||
self.label.text = text
|
||||
def text(self, text: str): self.label.text = text
|
||||
|
||||
# event
|
||||
# événements
|
||||
|
||||
def on_key_press(self, symbol: int, modifiers: int):
|
||||
if not self.activated: return # ignore si ce widget est désactivé / non sélectionné
|
||||
|
|
|
@ -12,8 +12,7 @@ if TYPE_CHECKING:
|
|||
|
||||
class Scroller(BoxWidget):
|
||||
"""
|
||||
A scroller widget with a background texture, a scroller and a label.
|
||||
The cursor can be moved between the "from" and the "to" value
|
||||
Un widget qui affiche un curseur qui peut être déplacé entre deux valeurs.
|
||||
"""
|
||||
|
||||
def __init__(self, scene: "Scene",
|
||||
|
@ -64,7 +63,7 @@ class Scroller(BoxWidget):
|
|||
self._to = to
|
||||
self.value = value
|
||||
|
||||
# refresh
|
||||
# rafraichissement
|
||||
|
||||
def _refresh(self):
|
||||
# background
|
||||
|
@ -91,7 +90,7 @@ class Scroller(BoxWidget):
|
|||
def _refresh_cursor(self, rel_x: int):
|
||||
self.value = (rel_x / self.width) * (self.to - self.from_) + self.from_
|
||||
|
||||
# property
|
||||
# propriétés
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
|
@ -122,7 +121,7 @@ class Scroller(BoxWidget):
|
|||
self._to = to
|
||||
self._refresh()
|
||||
|
||||
# event
|
||||
# événements
|
||||
|
||||
def on_resize(self, width: int, height: int):
|
||||
self._refresh()
|
||||
|
|
|
@ -11,7 +11,7 @@ if TYPE_CHECKING:
|
|||
|
||||
class Text(BoxWidget):
|
||||
"""
|
||||
A widget that display a text
|
||||
Un widget qui affiche du texte
|
||||
"""
|
||||
|
||||
def __init__(self, scene: "Scene",
|
||||
|
|
|
@ -11,7 +11,7 @@ if TYPE_CHECKING:
|
|||
|
||||
class BoxWidget(Widget, ABC):
|
||||
"""
|
||||
Same as a basic widget, but inside a box
|
||||
Pareil qu'un Widget, mais dans une boîte de collision (bbox)
|
||||
"""
|
||||
|
||||
def __init__(self, scene: "Scene",
|
||||
|
@ -21,23 +21,23 @@ class BoxWidget(Widget, ABC):
|
|||
height: Distance = None):
|
||||
super().__init__(scene)
|
||||
|
||||
# memorize the value with a percent value
|
||||
# Défini les bordures de la boîte de collision. Peut utiliser des nombres ou des unités de distance
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.width = width
|
||||
self.height = height
|
||||
|
||||
self.hovering = False # is the button currently hovered ?
|
||||
self.clicking = False # is the button currently clicked ?
|
||||
self.activated = False # is the button activated ? (the last click was inside this widget)
|
||||
self.hovering = False # La bbox est-elle actuellement survolée ?
|
||||
self.clicking = False # La bbox est-elle actuellement cliqué ?
|
||||
self.activated = False # La bbox est-il actuellement activé ? (le dernier clic a été à l'intérieur)
|
||||
|
||||
# property
|
||||
# propriétés
|
||||
|
||||
def _getter_distance(self, raw_distance: Distance) -> int:
|
||||
"""
|
||||
Return the true distance in pixel from a more abstract distance
|
||||
:param raw_distance: the distance object to convert to pixel
|
||||
:return: the true distance in pixel
|
||||
Renvoie la distance en pixel d'une distance abstraite
|
||||
:param raw_distance: la distance à convertir en pixel
|
||||
:return: la vrai distance en pixel
|
||||
"""
|
||||
|
||||
if isinstance(raw_distance, int): return raw_distance
|
||||
|
@ -47,88 +47,71 @@ class BoxWidget(Widget, ABC):
|
|||
raise TypeError(f"Invalid type for the distance : {type(raw_distance)}")
|
||||
|
||||
@property
|
||||
def x(self) -> int:
|
||||
return self._getter_distance(self._x)
|
||||
def x(self) -> int: return self._getter_distance(self._x)
|
||||
|
||||
@x.setter
|
||||
def x(self, x: Distance):
|
||||
self._x = x
|
||||
def x(self, x: Distance): self._x = x
|
||||
|
||||
@property
|
||||
def y(self) -> int:
|
||||
return self._getter_distance(self._y)
|
||||
def y(self) -> int: return self._getter_distance(self._y)
|
||||
|
||||
@y.setter
|
||||
def y(self, y: Distance):
|
||||
self._y = y
|
||||
def y(self, y: Distance): self._y = y
|
||||
|
||||
@property
|
||||
def xy(self) -> tuple[int, int]:
|
||||
return self.x, self.y
|
||||
def xy(self) -> tuple[int, int]: return self.x, self.y
|
||||
|
||||
@property
|
||||
def x2(self) -> int:
|
||||
return self.x + self.width
|
||||
def x2(self) -> int: return self.x + self.width
|
||||
|
||||
@property
|
||||
def y2(self) -> int:
|
||||
return self.y + self.height
|
||||
def y2(self) -> int: return self.y + self.height
|
||||
|
||||
@property
|
||||
def xy2(self) -> tuple[int, int]:
|
||||
return self.x2, self.y2
|
||||
def xy2(self) -> tuple[int, int]: return self.x2, self.y2
|
||||
|
||||
@property
|
||||
def width(self) -> int:
|
||||
return self._getter_distance(self._width)
|
||||
def width(self) -> int: return self._getter_distance(self._width)
|
||||
|
||||
@width.setter
|
||||
def width(self, width: Optional[Distance]):
|
||||
self._width = width
|
||||
def width(self, width: Optional[Distance]): self._width = width
|
||||
|
||||
@property
|
||||
def height(self) -> int:
|
||||
return self._getter_distance(self._height)
|
||||
def height(self) -> int: return self._getter_distance(self._height)
|
||||
|
||||
@height.setter
|
||||
def height(self, height: Optional[Distance]):
|
||||
self._height = height
|
||||
def height(self, height: Optional[Distance]): self._height = height
|
||||
|
||||
@property
|
||||
def size(self) -> tuple[int, int]:
|
||||
return self.width, self.height
|
||||
def size(self) -> tuple[int, int]: return self.width, self.height
|
||||
|
||||
@property
|
||||
def bbox(self) -> tuple[int, int, int, int]:
|
||||
return self.x, self.y, self.x2, self.y2
|
||||
def bbox(self) -> tuple[int, int, int, int]: return self.x, self.y, self.x2, self.y2
|
||||
|
||||
@property
|
||||
def center_x(self) -> float:
|
||||
return self.x + (self.width / 2)
|
||||
def center_x(self) -> float: return self.x + (self.width / 2)
|
||||
|
||||
@property
|
||||
def center_y(self) -> float:
|
||||
return self.y + (self.height / 2)
|
||||
def center_y(self) -> float: return self.y + (self.height / 2)
|
||||
|
||||
@property
|
||||
def center(self) -> tuple[float, float]:
|
||||
return self.center_x, self.center_y
|
||||
def center(self) -> tuple[float, float]: return self.center_x, self.center_y
|
||||
|
||||
# function
|
||||
# fonctions
|
||||
|
||||
def in_bbox(self, point: Point2D) -> bool:
|
||||
return in_bbox(point, self.bbox)
|
||||
|
||||
# event
|
||||
# événements
|
||||
|
||||
def on_mouse_motion(self, x: int, y: int, dx: int, dy: int):
|
||||
"""
|
||||
When the mouse is moved, this event is triggered.
|
||||
Allow the implementation of the on_hover_enter and on_hover_leave events
|
||||
:x: the x position of the mouse
|
||||
:y: the y position of the mouse
|
||||
:dx: the difference of the x mouse axis
|
||||
:dy: the difference of the y mouse axis
|
||||
Lorsque la souris est déplacée, cet événement est déclenché.
|
||||
Permet d'implémenter les événements on_hover, on_hover_enter et on_hover_leave
|
||||
:param x: la position x de la souris
|
||||
:param y: la position y de la souris
|
||||
:param dx: la différence de la position x de la souris
|
||||
:param dy: la différence de la position y de la souris
|
||||
"""
|
||||
|
||||
rel_x, rel_y = x - self.x, y - self.y
|
||||
|
@ -136,39 +119,59 @@ class BoxWidget(Widget, ABC):
|
|||
old_hovering = self.hovering
|
||||
self.hovering = self.in_bbox((x, y))
|
||||
|
||||
if old_hovering != self.hovering: # if the hover changed
|
||||
# call the hover changed event
|
||||
if old_hovering != self.hovering: # si le survole a changé d'état
|
||||
# appelle d'événement on_hover_change
|
||||
self.trigger_event("on_hover_change", rel_x, rel_y)
|
||||
# call the hover enter / leave event
|
||||
# appelle l'événement on_hover_enter ou on_hover_leave selon la valeur
|
||||
self.trigger_event("on_hover_enter" if self.hovering else "on_hover_leave", rel_x, rel_y)
|
||||
|
||||
if self.hovering: # if the mouse motion is inside the collision
|
||||
self.trigger_event("on_hover", rel_x, rel_y) # call the hover event
|
||||
if self.hovering: # si la souris est dans la bbox actuellement
|
||||
self.trigger_event("on_hover", rel_x, rel_y) # appelle l'événement on_hover
|
||||
|
||||
def on_mouse_press(self, x: int, y: int, button: int, modifiers: int):
|
||||
"""
|
||||
Lorsque la souris est cliqué, cet événement est déclenché.
|
||||
:param x: la position x de la souris
|
||||
:param y: la position y de la souris
|
||||
:param button: button de la souris cliqué
|
||||
:param modifiers: modificateur du bouton de la souris
|
||||
"""
|
||||
|
||||
rel_x, rel_y = x - self.x, y - self.y
|
||||
|
||||
self.activated = self.in_bbox((x, y))
|
||||
self.trigger_event("on_activate_change", rel_x, rel_y, button, modifiers)
|
||||
|
||||
if self.activated: # if the click was inside the widget
|
||||
if self.activated: # si le clic s'est produit dans la bbox
|
||||
# appel des événements on_activate_enter
|
||||
self.trigger_event("on_activate_enter", rel_x, rel_y, button, modifiers)
|
||||
|
||||
self.clicking = True # the widget is also now clicked
|
||||
self.clicking = True # défini le widget comme étant à présent cliqué
|
||||
# appel des événements on_click_change et on_click_press
|
||||
self.trigger_event("on_click_change", rel_x, rel_y, button, modifiers)
|
||||
self.trigger_event("on_click_press", rel_x, rel_y, button, modifiers)
|
||||
|
||||
else:
|
||||
# si le clic n'était pas dans la bbox, appel de l'événement on_activate_leave
|
||||
self.trigger_event("on_activate_leave", rel_x, rel_y, button, modifiers)
|
||||
|
||||
def on_mouse_release(self, x: int, y: int, button: int, modifiers: int):
|
||||
"""
|
||||
Lorsque le clic de la souris est relâché, cet événement est déclenché.
|
||||
:param x: la position x de la souris
|
||||
:param y: la position y de la souris
|
||||
:param button: button de la souris cliqué
|
||||
:param modifiers: modificateur du bouton de la souris
|
||||
"""
|
||||
|
||||
rel_x, rel_y = x - self.x, y - self.y
|
||||
|
||||
old_click: bool = self.clicking
|
||||
self.clicking = False # the widget is no longer clicked
|
||||
self.clicking = False # le widget n'est plus cliqué
|
||||
|
||||
if not self.in_bbox((x, y)): return # if the release was not in the collision, ignore
|
||||
if not self.in_bbox((x, y)): return # si le clic n'a pas été relâché dans la bbox, ignore
|
||||
|
||||
if old_click: # if this button was the one hovered when the click was pressed
|
||||
if old_click: # si ce bouton était celui qui était survolé lorsque le bouton a été cliqué
|
||||
# déclenche les événements on_click_change et on_click_release
|
||||
self.trigger_event("on_click_change", rel_x, rel_y, button, modifiers)
|
||||
self.trigger_event("on_click_release", rel_x, rel_y, button, modifiers)
|
||||
|
|
|
@ -9,9 +9,9 @@ if TYPE_CHECKING:
|
|||
|
||||
class Widget(Listener, ABC):
|
||||
"""
|
||||
A Widget that can be attached to a scene.
|
||||
Un widget pouvant être attaché à une scène.
|
||||
|
||||
It can react to any "on_" event from the scene.
|
||||
Il peut réagir à n'importe quel événement "on_" de la scène.
|
||||
"""
|
||||
|
||||
def __init__(self, scene: "Scene", **kwargs):
|
||||
|
|
|
@ -9,7 +9,7 @@ from source.type import ColorRGBA
|
|||
|
||||
class GameWindow(Window): # NOQA
|
||||
"""
|
||||
Similar to the normal Window, but add small feature useful for a game like a fps counter.
|
||||
Similaire à la classe Window, mais ajoute quelque fonctionnalités pratique pour un jeu. (Option, FPS, etc.)
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
|
@ -34,6 +34,10 @@ class GameWindow(Window): # NOQA
|
|||
pyglet.clock.schedule_once(lambda *_: self.load_option(), 0)
|
||||
|
||||
def load_option(self):
|
||||
"""
|
||||
Charge les options depuis le fichier self.option_path.
|
||||
"""
|
||||
|
||||
try:
|
||||
if self.option_path.exists():
|
||||
self.option = Option.load(self, self.option_path)
|
||||
|
@ -43,4 +47,5 @@ class GameWindow(Window): # NOQA
|
|||
if self.option is None: self.option = Option(window=self)
|
||||
|
||||
def on_draw_after(self):
|
||||
# après que tous les éléments ont été dessinés, dessiner le compteur de FPS s'il est activé.
|
||||
if self.fps_enable: self._fps_counter.draw()
|
||||
|
|
|
@ -12,8 +12,8 @@ if TYPE_CHECKING:
|
|||
|
||||
class Window(pyglet.window.Window, EventPropagationMixin): # NOQA
|
||||
"""
|
||||
A window. Based on the pyglet window object.
|
||||
Scene can be added to the window
|
||||
Une fenêtre basée sur l'objet Window de pyglet.
|
||||
Des scènes peuvent y être placé.
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
@ -24,12 +24,21 @@ class Window(pyglet.window.Window, EventPropagationMixin): # NOQA
|
|||
|
||||
@property
|
||||
def childs(self):
|
||||
"""
|
||||
Renvoie les scènes de la fenêtre. Utilisé pour la propagation d'événements.
|
||||
:return: les scènes de la fenêtre.
|
||||
"""
|
||||
return self._scenes
|
||||
|
||||
# FPS
|
||||
|
||||
@staticmethod
|
||||
def get_fps() -> float:
|
||||
"""
|
||||
Renvoie le nombre de FPS actuel de la fenêtre.
|
||||
:return: le nombre de FPS actuel de la fenêtre.
|
||||
"""
|
||||
|
||||
# on récupère la fonction responsable du rafraichissement de la fenêtre
|
||||
refresh_func = pyglet.app.event_loop._redraw_windows # NOQA
|
||||
|
||||
|
@ -47,6 +56,11 @@ class Window(pyglet.window.Window, EventPropagationMixin): # NOQA
|
|||
|
||||
@staticmethod
|
||||
def set_fps(value: float):
|
||||
"""
|
||||
Définit le nombre de FPS de la fenêtre.
|
||||
:param value: nombre de FPS souhaité
|
||||
"""
|
||||
|
||||
# on récupère la fonction responsable du rafraichissement de la fenêtre
|
||||
refresh_func = pyglet.app.event_loop._redraw_windows # NOQA
|
||||
|
||||
|
@ -62,24 +76,23 @@ class Window(pyglet.window.Window, EventPropagationMixin): # NOQA
|
|||
|
||||
# Scene Managing
|
||||
|
||||
def set_scene(self, scene_class: Type["Scene"], *scene_args, **scene_kwargs) -> "Scene":
|
||||
def set_scene(self, scene_class: Type["Scene"], **scene_kwargs) -> "Scene":
|
||||
"""
|
||||
Set the scene of the window.
|
||||
:scene_class: the class of the scene to add.
|
||||
:scene_args: args for the creation of the scene object.
|
||||
:scene_kwargs: kwargs for the creation of the scene object.
|
||||
:return: the new created scene.
|
||||
Défini la scène actuelle pour la fenêtre.
|
||||
:scene_class: la classe de la scène à ajouter
|
||||
:scene_kwargs: les arguments clés de la scène
|
||||
:return: la nouvelle scène créée
|
||||
"""
|
||||
|
||||
self.clear_scene()
|
||||
return self.add_scene(scene_class, *scene_args, **scene_kwargs)
|
||||
return self.add_scene(scene_class, **scene_kwargs)
|
||||
|
||||
def add_scene(self, scene_class: Type["Scene"], priority: int = 0, **scene_kwargs) -> "Scene":
|
||||
"""
|
||||
Add a scene of the window.
|
||||
:scene_class: the class of the scene to add.
|
||||
:scene_kwargs: kwargs for the creation of the scene object.
|
||||
:return: the new created scene.
|
||||
Ajoute une scène à la fenêtre.
|
||||
:scene_class: la classe de la scène à ajouter
|
||||
:scene_kwargs: les arguments clés de la scène
|
||||
:return: la nouvelle scène créée
|
||||
"""
|
||||
|
||||
scene: "Scene" = scene_class(window=self, **scene_kwargs)
|
||||
|
@ -88,15 +101,15 @@ class Window(pyglet.window.Window, EventPropagationMixin): # NOQA
|
|||
|
||||
def remove_scene(self, scene: "Scene") -> None:
|
||||
"""
|
||||
Remove a scene from the window.
|
||||
:scene: the scene to remove.
|
||||
Retire une scène spécifique de la fenêtre
|
||||
:scene: la scène à retirer
|
||||
"""
|
||||
|
||||
self._scenes.remove(scene)
|
||||
|
||||
def clear_scene(self) -> None:
|
||||
"""
|
||||
Clear the window from all the scenes.
|
||||
Retire toutes les scènes de la fenêtre.
|
||||
"""
|
||||
|
||||
self._scenes.clear()
|
||||
|
|
Loading…
Reference in a new issue