From a25997992efaceafca792e5428adc07e3b99571f Mon Sep 17 00:00:00 2001 From: Vladimir Date: Thu, 6 Aug 2026 03:27:08 +0300 Subject: [PATCH] =?UTF-8?q?feat(ui):=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BB=D0=BE=D0=B1=D0=B1=D0=B8?= =?UTF-8?q?=20=D0=B8=20=D0=B2=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=B8=20=D0=B2=D1=8B=D0=B1=D0=BE=D1=80=D0=B0=20?= =?UTF-8?q?=D1=80=D0=BE=D0=BB=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mind_reader/ui/views/__init__.py | 5 ++ src/mind_reader/ui/views/lobby_view.py | 106 +++++++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 src/mind_reader/ui/views/__init__.py create mode 100644 src/mind_reader/ui/views/lobby_view.py diff --git a/src/mind_reader/ui/views/__init__.py b/src/mind_reader/ui/views/__init__.py new file mode 100644 index 0000000..3afe467 --- /dev/null +++ b/src/mind_reader/ui/views/__init__.py @@ -0,0 +1,5 @@ +from mind_reader.ui.views.lobby_view import LobbyPanel + +__all__ = [ + "LobbyPanel", +] diff --git a/src/mind_reader/ui/views/lobby_view.py b/src/mind_reader/ui/views/lobby_view.py new file mode 100644 index 0000000..12b92d6 --- /dev/null +++ b/src/mind_reader/ui/views/lobby_view.py @@ -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())