diff --git a/NOTE.md b/NOTE.md index 2acd8e7..284ba4a 100644 --- a/NOTE.md +++ b/NOTE.md @@ -1,10 +1,10 @@ A faire : -- Faire marcher le tchat - Sauvegarde / Quitter - Historique / Replay - Police d'écriture - Gérer les erreurs (quitter en cours de connexion, ...) - Documenter +- Rendre le texte de status plus visible - Changer les images, rajouter les fonds, ... diff --git a/assets/image/input/active.png b/assets/image/input/active.png index 8a09917..2f3c320 100644 Binary files a/assets/image/input/active.png and b/assets/image/input/active.png differ diff --git a/source/gui/scene/Game.py b/source/gui/scene/Game.py index 72765e0..b603bd0 100644 --- a/source/gui/scene/Game.py +++ b/source/gui/scene/Game.py @@ -1,8 +1,6 @@ import socket from typing import TYPE_CHECKING -import pyglet - from source.core.enums import BombState from source.core.error import InvalidBombPosition, PositionAlreadyShot from source.gui.scene import Result @@ -127,10 +125,10 @@ class Game(Scene): self.chat_log = self.add_widget( widget.Text, - x=10, y=35, width=0.5, + x=10, y=45, width=0.4, text="", - anchor_x="left", + anchor_x="left", anchor_y="bottom", multiline=True ) @@ -139,16 +137,16 @@ class Game(Scene): x=10, y=10, width=0.5, height=30, + type_regex=".{0,60}", + style=texture.Button.Style1 ) def send_chat(widget): - text = widget.text + text: str = widget.text widget.text = "" - self.chat_log.text += "\n" + text - self.chat_log.label.y = self.chat_log.y + self.chat_log.label.content_height - + self.chat_new_message(self.name_ally, text) PacketChat(message=text).send_connection(connection) self.chat_input.add_listener("on_enter", send_chat) @@ -196,6 +194,15 @@ class Game(Scene): # function + def _refresh_chat_box(self): + # supprime des messages jusqu'à ce que la boite soit plus petite que un quart de la fenêtre + while self.chat_log.label.content_height > (self.window.height / 4): + chat_logs: list[str] = self.chat_log.text.split("\n") + self.chat_log.text = "\n".join(chat_logs[1:]) + + # ajuste la boite de message pour être collé en bas + self.chat_log.label.y = self.chat_log.y + self.chat_log.label.content_height + def _refresh_turn_text(self): self.label_state.text = ( "Placer vos bateaux" if not self.boat_ready_ally else @@ -207,6 +214,12 @@ class Game(Scene): def game_end(self, won: bool): self.window.add_scene(Result, won=won) + def chat_new_message(self, author: str, content: str): + message: str = f"[{author}] - {content}" + self.chat_log.text += "\n" + message + + self._refresh_chat_box() + # property @property @@ -257,7 +270,7 @@ class Game(Scene): # network def network_on_chat(self, connection: socket.socket, packet: PacketChat): - print(packet.message) + self.chat_new_message(self.name_enemy, packet.message) def network_on_boat_placed(self, connection: socket.socket, packet: PacketBoatPlaced): self.boat_ready_enemy = True @@ -309,3 +322,8 @@ class Game(Scene): # si cette bombe a touché le dernier bateau, alors l'on a gagné self.game_end(won=True) return True # coupe la connexion + + # event + + def on_resize_after(self, width: int, height: int): + self._refresh_chat_box() diff --git a/source/gui/scene/RoomCreate.py b/source/gui/scene/RoomCreate.py index 26b9afd..967a5e5 100644 --- a/source/gui/scene/RoomCreate.py +++ b/source/gui/scene/RoomCreate.py @@ -44,7 +44,8 @@ class RoomCreate(Scene): style=texture.Input.Style1, - regex=r"\d{1,5}", + type_regex=r"\d{0,5}", + check_regex=r"\d{1,5}", label_text="52321" ) @@ -66,6 +67,8 @@ class RoomCreate(Scene): x=0.2, y=0.45, width=0.15, height=0.1, + type_regex=r".{0,16}", + style=texture.Input.Style1, label_text="Host" @@ -86,7 +89,8 @@ class RoomCreate(Scene): x=0.2, y=0.86, width=0.1, height=0.08, - regex=r"\d+", + type_regex=r"\d{0,4}", + check_regex=r"\d+", style=texture.Input.Style1, @@ -106,7 +110,8 @@ class RoomCreate(Scene): x=0.2, y=0.76, width=0.1, height=0.08, - regex=r"\d+", + type_regex=r"\d{0,4}", + check_regex=r"\d+", style=texture.Input.Style1, @@ -196,7 +201,8 @@ class RoomCreate(Scene): x=0.7, y=0.68, width=0.2, height=0.08, - regex=r"\d+", + type_regex=r"\d{0,4}", + check_regex=r"\d+", style=texture.Input.Style1, diff --git a/source/gui/scene/RoomJoin.py b/source/gui/scene/RoomJoin.py index 375db2f..97d2646 100644 --- a/source/gui/scene/RoomJoin.py +++ b/source/gui/scene/RoomJoin.py @@ -29,6 +29,8 @@ class RoomJoin(Scene): widget.Input, x=0.4, y=0.55, width=0.2, height=0.1, + type_regex=r".{0,16}", + style=texture.Input.Style1, label_text="Client" @@ -40,7 +42,8 @@ class RoomJoin(Scene): widget.Input, x=0.4, y=0.45, width=0.13, height=0.1, - regex=r"\d{1,3}(\.\d{1,3}){3}", + type_regex=r"[\d\.]{0,15}", + check_regex=r"\d{1,3}(\.\d{1,3}){3}", style=texture.Input.Style1, @@ -51,7 +54,8 @@ class RoomJoin(Scene): widget.Input, x=0.53, y=0.45, width=0.07, height=0.1, - regex=r"\d{1,5}", + type_regex=r"\d{0,5}", + check_regex=r"\d{1,5}", label_text="52321", diff --git a/source/gui/widget/Input.py b/source/gui/widget/Input.py index e20ccfe..517bdce 100644 --- a/source/gui/widget/Input.py +++ b/source/gui/widget/Input.py @@ -22,7 +22,8 @@ class Input(BoxWidget): style: Type[Style], - regex: Optional[str | re.Pattern] = None, + type_regex: Optional[str | re.Pattern] = None, + check_regex: Optional[str | re.Pattern] = None, x: Distance = 0, y: Distance = 0, @@ -36,7 +37,8 @@ class Input(BoxWidget): self._invalid = False - self.regex = re.compile(regex) if isinstance(regex, str) else regex + self.type_regex = re.compile(type_regex) if type_regex is not None else None + self.check_regex = re.compile(check_regex) if check_regex is not None else None self.background = Sprite( img=self.style.get("normal"), @@ -65,10 +67,9 @@ class Input(BoxWidget): and if click the clicking texture (if it exists) :return: the corresponding texture """ - return ( texture if self.activated and (texture := self.style.get("active")) is not None else # NOQA - texture if self.invalid and (texture := self.style.get("signal")) is not None else + texture if self.invalid and (texture := self.style.get("error")) is not None else self.style.get("normal") ) @@ -84,6 +85,10 @@ class Input(BoxWidget): # center the label self.label.x, self.label.y = self.center + def check(self): + if self.check_regex is not None: # si il y a un regex de validation, applique le pour vérifier le texte + self.invalid = self.check_regex.fullmatch(self.text) is None + # property @property @@ -110,18 +115,26 @@ class Input(BoxWidget): if symbol == pyglet.window.key.BACKSPACE: # si la touche "supprimé" est enfoncé self.text = self.text[0:-1] # retire le dernier caractère du texte + self.check() if symbol == pyglet.window.key.ENTER: self.trigger_event("on_enter") def on_text(self, char: str): + print("on_text") + if not self.activated: return # ignore si ce widget est désactivé / non sélectionné if not self.label.multiline and char in "\r\n": return # si le texte est sur une ligne, ignore les retours - self.text += char # ajoute le caractère au label + new_text: str = self.text + char - if self.regex is not None: # si il y a un regex de validation, applique le pour vérifier le texte - self.invalid = self.regex.fullmatch(self.text) is None + if self.type_regex is not None: + # s'il y a un regex d'écriture, vérifie qu'il est respecté, sinon ignore le nouveau caractère + if self.type_regex.fullmatch(new_text) is None: return + + self.text = new_text # ajoute le caractère au label + + self.check() # rafraichi le fait que le texte est considéré comme valide ou non if not self.invalid: self.trigger_event("on_valid_text")