diff --git a/pqcli/ui/__init__.py b/pqcli/ui/__init__.py index bdc6cab..cc3b5e4 100644 --- a/pqcli/ui/__init__.py +++ b/pqcli/ui/__init__.py @@ -59,24 +59,21 @@ class Ui: return False def switch_to_roster_view(self) -> None: - self.loop.widget = RosterView( - self.roster, - on_exit=self.switch_to_exit_view, - on_new_game=self.switch_to_new_game_view, - on_resume_game=self.switch_to_game_view, - ) + self.loop.widget = RosterView(self.roster) + self._connect("load_game", self.switch_to_game_view) + self._connect("new_game", self.switch_to_new_game_view) + self._connect("exit", self.switch_to_exit_view) def switch_to_exit_view(self) -> None: self.old_view = self.loop.widget - self.loop.widget = ExitView( - self.old_view, on_exit=self.exit, on_cancel=self.cancel_exit - ) + self.loop.widget = ExitView(self.old_view) + self._connect("exit", self.exit) + self._connect("cancel", self.cancel_exit) def switch_to_new_game_view(self) -> None: - self.loop.widget = NewGameView( - on_confirm=self.switch_to_game_view, - on_cancel=self.switch_to_roster_view, - ) + self.loop.widget = NewGameView() + self._connect("confirm", self.switch_to_game_view) + self._connect("cancel", self.switch_to_roster_view) def switch_to_game_view(self, player_name: str) -> None: raise NotImplementedError("not implemented") @@ -88,3 +85,10 @@ class Ui: assert self.old_view is not None self.loop.widget = self.old_view self.old_view = None + + def _connect(self, signal_name: str, callback: T.Callable) -> None: + urwid.signals.connect_signal( + self.loop.widget, + signal_name, + lambda _sender, *args: callback(*args), + ) diff --git a/pqcli/ui/exit_view.py b/pqcli/ui/exit_view.py index 55460c0..e4ed925 100644 --- a/pqcli/ui/exit_view.py +++ b/pqcli/ui/exit_view.py @@ -6,15 +6,12 @@ from pqcli.ui.button import MenuButton class ExitView(urwid.Overlay): - def __init__( - self, parent: urwid.Widget, on_exit: T.Callable, on_cancel: T.Callable - ) -> None: - self.on_exit = on_exit - self.on_cancel = on_cancel + signals = ["exit", "cancel"] + def __init__(self, parent: urwid.Widget) -> None: question = urwid.Text(("bold", "Really quit?"), "center") - yes_btn = MenuButton("Yes", lambda _user_data: self.on_exit()) - no_btn = MenuButton("No", lambda _user_data: self.on_cancel()) + yes_btn = MenuButton("Yes", lambda _user_data: self.exit()) + no_btn = MenuButton("No", lambda _user_data: self.cancel()) line_box = urwid.LineBox( urwid.ListBox( @@ -26,9 +23,15 @@ class ExitView(urwid.Overlay): def keypress(self, size: T.Any, key: str) -> T.Optional[str]: if key in {"y", "Y"}: - self.on_exit() + self.exit() return None if key in {"n", "N"}: - self.on_cancel() + self.cancel() return None - return super().keypress(size, key) + return T.cast(T.Optional[str], super().keypress(size, key)) + + def exit(self) -> None: + self._emit("exit") + + def cancel(self) -> None: + self._emit("cancel") diff --git a/pqcli/ui/new_game_view.py b/pqcli/ui/new_game_view.py index 24d840e..15d64cf 100644 --- a/pqcli/ui/new_game_view.py +++ b/pqcli/ui/new_game_view.py @@ -104,10 +104,9 @@ class ClassBox(LineBox): class NewGameView(urwid.Pile): - def __init__(self, on_confirm: T.Callable, on_cancel: T.Callable) -> None: - self.on_confirm = on_confirm - self.on_cancel = on_cancel + signals = ["confirm", "cancel"] + def __init__(self) -> None: race_box = RaceBox() class_box = ClassBox() stats_box = StatsBox() @@ -150,7 +149,7 @@ class NewGameView(urwid.Pile): def unhandled_input(self, key: str) -> bool: if key == "esc": - self.on_cancel() + self._emit("cancel") return True return False diff --git a/pqcli/ui/roster_view.py b/pqcli/ui/roster_view.py index 68b61c3..ae311c4 100644 --- a/pqcli/ui/roster_view.py +++ b/pqcli/ui/roster_view.py @@ -7,17 +7,10 @@ from pqcli.ui.button import MenuButton class RosterView(urwid.Filler): - def __init__( - self, - roster: Roster, - on_new_game: T.Callable, - on_resume_game: T.Callable, - on_exit: T.Callable, - ) -> None: + signals = ["load_game", "new_game", "exit"] + + def __init__(self, roster: Roster) -> None: self.roster = roster - self.on_new_game = on_new_game - self.on_resume_game = on_resume_game - self.on_exit = on_exit logo = urwid.BigText("ProgressQuest", urwid.HalfBlock5x4Font()) @@ -52,17 +45,17 @@ class RosterView(urwid.Filler): def on_resume_game_press(self, user_data: T.Any) -> None: player_name = T.cast(str, user_data) - self.on_resume_game(player_name) + self._emit("load_game", player_data) def on_new_game_press(self, _user_data: T.Any) -> None: - self.on_new_game() + self._emit("new_game") def on_exit_press(self, _user_data: T.Any) -> None: - self.on_exit() + self._emit("exit") def unhandled_input(self, key: str) -> bool: if key == "esc": - self.on_exit() + self._emit("exit") return True return False