the chat is now fully working, input can now take a type_check regex
This commit is contained in:
parent
3caaa8180d
commit
0872883a5c
6 changed files with 64 additions and 23 deletions
2
NOTE.md
2
NOTE.md
|
@ -1,10 +1,10 @@
|
||||||
A faire :
|
A faire :
|
||||||
- Faire marcher le tchat
|
|
||||||
- Sauvegarde / Quitter
|
- Sauvegarde / Quitter
|
||||||
- Historique / Replay
|
- Historique / Replay
|
||||||
- Police d'écriture
|
- Police d'écriture
|
||||||
- Gérer les erreurs (quitter en cours de connexion, ...)
|
- Gérer les erreurs (quitter en cours de connexion, ...)
|
||||||
- Documenter
|
- Documenter
|
||||||
|
- Rendre le texte de status plus visible
|
||||||
|
|
||||||
|
|
||||||
- Changer les images, rajouter les fonds, ...
|
- Changer les images, rajouter les fonds, ...
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 311 B |
|
@ -1,8 +1,6 @@
|
||||||
import socket
|
import socket
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
import pyglet
|
|
||||||
|
|
||||||
from source.core.enums import BombState
|
from source.core.enums import BombState
|
||||||
from source.core.error import InvalidBombPosition, PositionAlreadyShot
|
from source.core.error import InvalidBombPosition, PositionAlreadyShot
|
||||||
from source.gui.scene import Result
|
from source.gui.scene import Result
|
||||||
|
@ -127,10 +125,10 @@ class Game(Scene):
|
||||||
self.chat_log = self.add_widget(
|
self.chat_log = self.add_widget(
|
||||||
widget.Text,
|
widget.Text,
|
||||||
|
|
||||||
x=10, y=35, width=0.5,
|
x=10, y=45, width=0.4,
|
||||||
|
|
||||||
text="",
|
text="",
|
||||||
anchor_x="left",
|
anchor_x="left", anchor_y="bottom",
|
||||||
multiline=True
|
multiline=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -139,16 +137,16 @@ class Game(Scene):
|
||||||
|
|
||||||
x=10, y=10, width=0.5, height=30,
|
x=10, y=10, width=0.5, height=30,
|
||||||
|
|
||||||
|
type_regex=".{0,60}",
|
||||||
|
|
||||||
style=texture.Button.Style1
|
style=texture.Button.Style1
|
||||||
)
|
)
|
||||||
|
|
||||||
def send_chat(widget):
|
def send_chat(widget):
|
||||||
text = widget.text
|
text: str = widget.text
|
||||||
widget.text = ""
|
widget.text = ""
|
||||||
|
|
||||||
self.chat_log.text += "\n" + text
|
self.chat_new_message(self.name_ally, text)
|
||||||
self.chat_log.label.y = self.chat_log.y + self.chat_log.label.content_height
|
|
||||||
|
|
||||||
PacketChat(message=text).send_connection(connection)
|
PacketChat(message=text).send_connection(connection)
|
||||||
|
|
||||||
self.chat_input.add_listener("on_enter", send_chat)
|
self.chat_input.add_listener("on_enter", send_chat)
|
||||||
|
@ -196,6 +194,15 @@ class Game(Scene):
|
||||||
|
|
||||||
# function
|
# 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):
|
def _refresh_turn_text(self):
|
||||||
self.label_state.text = (
|
self.label_state.text = (
|
||||||
"Placer vos bateaux" if not self.boat_ready_ally else
|
"Placer vos bateaux" if not self.boat_ready_ally else
|
||||||
|
@ -207,6 +214,12 @@ class Game(Scene):
|
||||||
def game_end(self, won: bool):
|
def game_end(self, won: bool):
|
||||||
self.window.add_scene(Result, won=won)
|
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
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -257,7 +270,7 @@ class Game(Scene):
|
||||||
# network
|
# network
|
||||||
|
|
||||||
def network_on_chat(self, connection: socket.socket, packet: PacketChat):
|
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):
|
def network_on_boat_placed(self, connection: socket.socket, packet: PacketBoatPlaced):
|
||||||
self.boat_ready_enemy = True
|
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é
|
# si cette bombe a touché le dernier bateau, alors l'on a gagné
|
||||||
self.game_end(won=True)
|
self.game_end(won=True)
|
||||||
return True # coupe la connexion
|
return True # coupe la connexion
|
||||||
|
|
||||||
|
# event
|
||||||
|
|
||||||
|
def on_resize_after(self, width: int, height: int):
|
||||||
|
self._refresh_chat_box()
|
||||||
|
|
|
@ -44,7 +44,8 @@ class RoomCreate(Scene):
|
||||||
|
|
||||||
style=texture.Input.Style1,
|
style=texture.Input.Style1,
|
||||||
|
|
||||||
regex=r"\d{1,5}",
|
type_regex=r"\d{0,5}",
|
||||||
|
check_regex=r"\d{1,5}",
|
||||||
|
|
||||||
label_text="52321"
|
label_text="52321"
|
||||||
)
|
)
|
||||||
|
@ -66,6 +67,8 @@ class RoomCreate(Scene):
|
||||||
|
|
||||||
x=0.2, y=0.45, width=0.15, height=0.1,
|
x=0.2, y=0.45, width=0.15, height=0.1,
|
||||||
|
|
||||||
|
type_regex=r".{0,16}",
|
||||||
|
|
||||||
style=texture.Input.Style1,
|
style=texture.Input.Style1,
|
||||||
|
|
||||||
label_text="Host"
|
label_text="Host"
|
||||||
|
@ -86,7 +89,8 @@ class RoomCreate(Scene):
|
||||||
|
|
||||||
x=0.2, y=0.86, width=0.1, height=0.08,
|
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,
|
style=texture.Input.Style1,
|
||||||
|
|
||||||
|
@ -106,7 +110,8 @@ class RoomCreate(Scene):
|
||||||
|
|
||||||
x=0.2, y=0.76, width=0.1, height=0.08,
|
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,
|
style=texture.Input.Style1,
|
||||||
|
|
||||||
|
@ -196,7 +201,8 @@ class RoomCreate(Scene):
|
||||||
|
|
||||||
x=0.7, y=0.68, width=0.2, height=0.08,
|
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,
|
style=texture.Input.Style1,
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,8 @@ class RoomJoin(Scene):
|
||||||
widget.Input,
|
widget.Input,
|
||||||
x=0.4, y=0.55, width=0.2, height=0.1,
|
x=0.4, y=0.55, width=0.2, height=0.1,
|
||||||
|
|
||||||
|
type_regex=r".{0,16}",
|
||||||
|
|
||||||
style=texture.Input.Style1,
|
style=texture.Input.Style1,
|
||||||
|
|
||||||
label_text="Client"
|
label_text="Client"
|
||||||
|
@ -40,7 +42,8 @@ class RoomJoin(Scene):
|
||||||
widget.Input,
|
widget.Input,
|
||||||
x=0.4, y=0.45, width=0.13, height=0.1,
|
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,
|
style=texture.Input.Style1,
|
||||||
|
|
||||||
|
@ -51,7 +54,8 @@ class RoomJoin(Scene):
|
||||||
widget.Input,
|
widget.Input,
|
||||||
x=0.53, y=0.45, width=0.07, height=0.1,
|
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",
|
label_text="52321",
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,8 @@ class Input(BoxWidget):
|
||||||
|
|
||||||
style: Type[Style],
|
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,
|
x: Distance = 0,
|
||||||
y: Distance = 0,
|
y: Distance = 0,
|
||||||
|
@ -36,7 +37,8 @@ class Input(BoxWidget):
|
||||||
|
|
||||||
self._invalid = False
|
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(
|
self.background = Sprite(
|
||||||
img=self.style.get("normal"),
|
img=self.style.get("normal"),
|
||||||
|
@ -65,10 +67,9 @@ class Input(BoxWidget):
|
||||||
and if click the clicking texture (if it exists)
|
and if click the clicking texture (if it exists)
|
||||||
:return: the corresponding texture
|
:return: the corresponding texture
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return (
|
return (
|
||||||
texture if self.activated and (texture := self.style.get("active")) is not None else # NOQA
|
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")
|
self.style.get("normal")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -84,6 +85,10 @@ class Input(BoxWidget):
|
||||||
# center the label
|
# center the label
|
||||||
self.label.x, self.label.y = self.center
|
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
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -110,18 +115,26 @@ class Input(BoxWidget):
|
||||||
|
|
||||||
if symbol == pyglet.window.key.BACKSPACE: # si la touche "supprimé" est enfoncé
|
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.text = self.text[0:-1] # retire le dernier caractère du texte
|
||||||
|
self.check()
|
||||||
|
|
||||||
if symbol == pyglet.window.key.ENTER:
|
if symbol == pyglet.window.key.ENTER:
|
||||||
self.trigger_event("on_enter")
|
self.trigger_event("on_enter")
|
||||||
|
|
||||||
def on_text(self, char: str):
|
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.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
|
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
|
if self.type_regex is not None:
|
||||||
self.invalid = self.regex.fullmatch(self.text) is 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:
|
if not self.invalid:
|
||||||
self.trigger_event("on_valid_text")
|
self.trigger_event("on_valid_text")
|
||||||
|
|
Loading…
Reference in a new issue