feat(ui): добавление лобби и возможности выбора роли

This commit is contained in:
2026-08-06 03:27:08 +03:00
parent c993e80a71
commit a25997992e
2 changed files with 111 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
from mind_reader.ui.views.lobby_view import LobbyPanel
__all__ = [
"LobbyPanel",
]
+106
View File
@@ -0,0 +1,106 @@
import wx
from mind_reader.core import GameState
class RoleColumn(wx.Panel):
def __init__(self, parent, role_key: str, button_label: str):
super().__init__(parent)
self.role_key = role_key
sizer = wx.BoxSizer(wx.VERTICAL)
self.button_select = wx.Button(self, label=button_label)
sizer.Add(self.button_select, 0, wx.EXPAND | wx.ALL, 5)
self.list_players = wx.ListBox(self)
sizer.Add(self.list_players, 1, wx.EXPAND | wx.ALL, 5)
self.SetSizer(sizer)
def set_players(self, players: list[str]):
self.list_players.Clear()
if players:
self.list_players.AppendItems(players)
def disable_on_role_match(self, role: str):
self.button_select.Enable(self.role_key != role)
class LobbyPanel(wx.Panel):
def __init__(self, parent, state: GameState):
super().__init__(parent)
self.state = state
self._init_ui()
def _init_ui(self):
main_sizer = wx.BoxSizer(wx.VERTICAL)
columns_sizer = wx.BoxSizer(wx.HORIZONTAL)
self.column_none = RoleColumn(self, "NONE", "👤 Без роли")
self.column_setter = RoleColumn(self, "SETTER", "🧠 Загадывает")
self.column_guesser = RoleColumn(self, "GUESSER", "🕵️ Угадывает")
columns_sizer.Add(self.column_none, 1, wx.EXPAND | wx.ALL, 5)
columns_sizer.Add(self.column_setter, 1, wx.EXPAND | wx.ALL, 5)
columns_sizer.Add(self.column_guesser, 1, wx.EXPAND | wx.ALL, 5)
self.column_none.button_select.Bind(
wx.EVT_BUTTON, lambda evt: self._on_role_click("NONE")
)
self.column_setter.button_select.Bind(
wx.EVT_BUTTON, lambda evt: self._on_role_click("SETTER")
)
self.column_guesser.button_select.Bind(
wx.EVT_BUTTON, lambda evt: self._on_role_click("GUESSER")
)
self.button_start = wx.Button(self, label="➔ Начать сессию")
self.button_start.Bind(wx.EVT_BUTTON, self._on_start_click)
main_sizer.Add(columns_sizer, 1, wx.EXPAND | wx.ALL, 5)
main_sizer.Add(
self.button_start, 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10
)
self.SetSizer(main_sizer)
self.refresh_from_state()
def _on_role_click(self, target_role: str):
success = self.state.set_player_role(
self.state.local_player_name, target_role
)
if not success:
wx.MessageBox(
f"Не удалось занять роль «{target_role}».",
"Внимание",
wx.OK | wx.ICON_WARNING,
)
return
self.refresh_from_state()
def _on_start_click(self, event):
wx.MessageBox("Сессия запущена!", "Старт", wx.OK | wx.ICON_INFORMATION)
def refresh_from_state(self):
players_by_role = {"NONE": [], "SETTER": [], "GUESSER": []}
for player, role in self.state.lobby_players.items():
if role in players_by_role:
players_by_role[role].append(player)
self.column_none.set_players(players_by_role["NONE"])
self.column_setter.set_players(players_by_role["SETTER"])
self.column_guesser.set_players(players_by_role["GUESSER"])
local_player_role = self.state.local_player_role
self.column_none.disable_on_role_match(local_player_role)
self.column_setter.disable_on_role_match(local_player_role)
self.column_guesser.disable_on_role_match(local_player_role)
self.button_start.Enable(self.state.is_session_ready())