129 lines
4.0 KiB
Python
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())
|