Files
mind-reader/src/mind_reader/ui/views/lobby_view.py
T

129 lines
4.0 KiB
Python

from typing import Callable, Optional
import wx
from wx.lib.pubsub import pub
from ...core import LobbyState
class RoleColumn(wx.Panel):
def __init__(
self,
parent,
role_key: str,
button_label: str,
on_role_selected: Optional[Callable[[str], None]] = None,
):
super().__init__(parent)
self.role_key = role_key
self.on_role_selected = on_role_selected
self.is_active = False
sizer = wx.BoxSizer(wx.VERTICAL)
self.button_select = wx.ToggleButton(self, label=button_label)
self.button_select.Bind(wx.EVT_TOGGLEBUTTON, self._on_button_click)
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 _on_button_click(self, event):
if self.is_active:
self.button_select.SetValue(True)
return
if self.on_role_selected:
self.on_role_selected(self.role_key)
def set_players(self, players: list[str]):
self.list_players.Clear()
if players:
self.list_players.AppendItems(players)
def set_role_state(self, role: str):
self.is_active = self.role_key == role
self.button_select.SetValue(self.is_active)
class LobbyPanel(wx.Panel):
def __init__(self, parent, state: LobbyState):
super().__init__(parent)
self.state = state
self._init_ui()
self.Bind(wx.EVT_WINDOW_DESTROY, self._on_destroy)
def _init_ui(self):
main_sizer = wx.BoxSizer(wx.VERTICAL)
columns_sizer = wx.BoxSizer(wx.HORIZONTAL)
self.column_none = RoleColumn(
self, "NONE", "👤 Без роли", self._on_role_click
)
self.column_setter = RoleColumn(
self, "SETTER", "🧠 Загадывает", self._on_role_click
)
self.column_guesser = RoleColumn(
self, "GUESSER", "🕵️ Угадывает", self._on_role_click
)
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.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)
pub.subscribe(self.refresh, "lobby.refresh")
self.refresh(self.state)
def _on_role_click(self, target_role: str):
success = self.state.set_player_role(target_role)
if not success:
wx.MessageBox(
f"Не удалось занять роль «{target_role}».",
"Внимание",
wx.OK | wx.ICON_WARNING,
)
return
self.refresh(self.state)
def _on_start_click(self, event):
wx.MessageBox("Сессия запущена!", "Старт", wx.OK | wx.ICON_INFORMATION)
def _on_destroy(self, event):
pub.unsubscribe(self.refresh, "lobby.refresh")
event.Skip()
def refresh(self, state: LobbyState):
players_by_role = {"NONE": [], "SETTER": [], "GUESSER": []}
for player, role in state.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 = state.local_player_role
self.column_none.set_role_state(local_player_role)
self.column_setter.set_role_state(local_player_role)
self.column_guesser.set_role_state(local_player_role)
self.button_start.Enable(state.is_ready())