from typing import Optional import wx from wx.lib.pubsub import pub from ..core import AppState from ..ui.dialogs import ClientConnectDialog, ServerStartDialog from ..ui.menu_bar import AppMenuBar from ..ui.views import LobbyPanel class MainFrame(wx.Frame): def __init__(self): super().__init__( parent=None, id=wx.ID_ANY, title="Mind Reader", size=wx.Size(700, 500), style=wx.DEFAULT_FRAME_STYLE, ) self.state: AppState = AppState() self.lobby_panel: Optional[LobbyPanel] = None self.Center() self.main_sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(self.main_sizer) self.menu_bar = AppMenuBar(self) self.SetMenuBar(self.menu_bar) self.CreateStatusBar(1) pub.subscribe(self.set_statusbar_text, "mainframe.statusbar") pub.subscribe(self.remote_server_stop, "mainframe.remote_server_stop") self._bind_menu_events() def _bind_menu_events(self): self.Bind( wx.EVT_MENU, self.on_client_connect, self.menu_bar.item_client ) self.Bind(wx.EVT_MENU, self.on_server_start, self.menu_bar.item_server) self.Bind( wx.EVT_MENU, self.on_disconnect, self.menu_bar.item_disconnect ) def set_statusbar_text(self, notice: str): self.SetStatusText(notice) def remote_server_stop(self, state: AppState): self.on_disconnect(None) def _show_lobby(self): self._destroy_lobby() if self.state.lobby: self.lobby_panel = LobbyPanel(self, self.state.lobby) self.main_sizer.Add(self.lobby_panel, 1, wx.EXPAND) self.Layout() def _destroy_lobby(self): if self.lobby_panel: self.main_sizer.Detach(self.lobby_panel) self.lobby_panel.Destroy() self.lobby_panel = None self.Layout() def on_client_connect(self, event): d = ClientConnectDialog(self) if d.ShowModal() == wx.ID_OK: player_name, ip = d.get_data() if self.state.connect(player_name, ip): self.menu_bar.set_connected_state(True) self._show_lobby() d.Destroy() def on_server_start(self, event): d = ServerStartDialog(self) if d.ShowModal() == wx.ID_OK: player_name, ip = d.get_data() self.state.serve(player_name, ip) self.menu_bar.set_connected_state(True) self._show_lobby() d.Destroy() def on_disconnect(self, event): self._destroy_lobby() self.state.disconnect() self.menu_bar.set_connected_state(False)