mirror of
https://github.com/rr-/pq-cli.git
synced 2026-09-28 22:33:59 -06:00
misc: improve mypy health
This commit is contained in:
+9
-3
@@ -13,7 +13,9 @@ from pqcli.lingo import *
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
_SIGNALS: T.Dict[T.Tuple[str, str], T.List[T.Callable]] = defaultdict(list)
|
_SIGNALS: T.Dict[
|
||||||
|
T.Tuple["SignalMixin", str], T.List[T.Callable[..., T.Any]]
|
||||||
|
] = defaultdict(list)
|
||||||
|
|
||||||
|
|
||||||
class SignalMixin:
|
class SignalMixin:
|
||||||
@@ -21,10 +23,14 @@ class SignalMixin:
|
|||||||
for callback in _SIGNALS[self, signal_name]:
|
for callback in _SIGNALS[self, signal_name]:
|
||||||
callback(*user_data)
|
callback(*user_data)
|
||||||
|
|
||||||
def connect(self, signal_name: str, callback: T.Callable) -> None:
|
def connect(
|
||||||
|
self, signal_name: str, callback: T.Callable[..., T.Any]
|
||||||
|
) -> None:
|
||||||
_SIGNALS[self, signal_name].append(callback)
|
_SIGNALS[self, signal_name].append(callback)
|
||||||
|
|
||||||
def disconnect(self, signal_name: str, callback: T.Callable) -> None:
|
def disconnect(
|
||||||
|
self, signal_name: str, callback: T.Callable[..., T.Any]
|
||||||
|
) -> None:
|
||||||
try:
|
try:
|
||||||
idx = _SIGNALS[self, signal_name].index(callback)
|
idx = _SIGNALS[self, signal_name].index(callback)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
|||||||
+1
-1
@@ -32,7 +32,7 @@ class Roster:
|
|||||||
self.path.rename(old_path)
|
self.path.rename(old_path)
|
||||||
tmp_path.rename(self.path)
|
tmp_path.rename(self.path)
|
||||||
|
|
||||||
def save_periodically(self):
|
def save_periodically(self) -> None:
|
||||||
if (datetime.now() - self._last_save).total_seconds() >= 300:
|
if (datetime.now() - self._last_save).total_seconds() >= 300:
|
||||||
logging.info("Saving...")
|
logging.info("Saving...")
|
||||||
self.save()
|
self.save()
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ class BasicUserInterface(BaseUserInterface):
|
|||||||
def __init__(self, roster: Roster, args: argparse.Namespace) -> None:
|
def __init__(self, roster: Roster, args: argparse.Namespace) -> None:
|
||||||
super().__init__(roster, args)
|
super().__init__(roster, args)
|
||||||
|
|
||||||
def signal_handler(sig, frame):
|
def signal_handler(sig: T.Any, frame: T.Any) -> None:
|
||||||
print("Quitting")
|
logging.info("Quitting")
|
||||||
if self.args.use_saves:
|
if self.args.use_saves:
|
||||||
self.roster.save()
|
self.roster.save()
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
@@ -57,7 +57,7 @@ class BasicUserInterface(BaseUserInterface):
|
|||||||
def logo(self) -> None:
|
def logo(self) -> None:
|
||||||
print(LOGO)
|
print(LOGO)
|
||||||
|
|
||||||
def main_menu(self):
|
def main_menu(self) -> None:
|
||||||
while True:
|
while True:
|
||||||
choice = self.menu(
|
choice = self.menu(
|
||||||
[
|
[
|
||||||
@@ -168,7 +168,9 @@ class BasicUserInterface(BaseUserInterface):
|
|||||||
print("--- Plot ---")
|
print("--- Plot ---")
|
||||||
print(f"Current act: {lingo.to_roman(player.quest_book.act)}")
|
print(f"Current act: {lingo.to_roman(player.quest_book.act)}")
|
||||||
print(f"Current quest: {player.quest_book.current_quest or '?'}")
|
print(f"Current quest: {player.quest_book.current_quest or '?'}")
|
||||||
print(f"Current task: {player.task.description}")
|
print(
|
||||||
|
f"Current task: {player.task.description if player.task else '?'}"
|
||||||
|
)
|
||||||
|
|
||||||
def delete_player(self, player: Player) -> None:
|
def delete_player(self, player: Player) -> None:
|
||||||
if self.confirm(lingo.terminate_message(player.name)):
|
if self.confirm(lingo.terminate_message(player.name)):
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class CursesUserInterface(BaseUserInterface):
|
|||||||
curses.noecho()
|
curses.noecho()
|
||||||
curses.curs_set(0)
|
curses.curs_set(0)
|
||||||
|
|
||||||
def signal_handler(sig, frame):
|
def signal_handler(sig: T.Any, frame: T.Any) -> None:
|
||||||
if self.args.use_saves:
|
if self.args.use_saves:
|
||||||
self.roster.save()
|
self.roster.save()
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ class ChooseCharacterNameView(BaseView):
|
|||||||
self.on_cancel = EventHandler()
|
self.on_cancel = EventHandler()
|
||||||
self.on_confirm = EventHandler()
|
self.on_confirm = EventHandler()
|
||||||
|
|
||||||
|
self._win: T.Optional[T.Any] = None
|
||||||
self._text = character_name or generate_name()
|
self._text = character_name or generate_name()
|
||||||
|
|
||||||
def start(self) -> None:
|
def start(self) -> None:
|
||||||
@@ -143,6 +144,9 @@ class ChooseCharacterStatsView(BaseView):
|
|||||||
self.on_cancel = EventHandler()
|
self.on_cancel = EventHandler()
|
||||||
self.on_confirm = EventHandler()
|
self.on_confirm = EventHandler()
|
||||||
|
|
||||||
|
self._win: T.Optional[T.Any] = None
|
||||||
|
self._stats_win: T.Optional[T.Any] = None
|
||||||
|
|
||||||
self._stats_builder = StatsBuilder()
|
self._stats_builder = StatsBuilder()
|
||||||
self._stats = self._stats_builder.roll()
|
self._stats = self._stats_builder.roll()
|
||||||
|
|
||||||
@@ -184,7 +188,7 @@ class ChooseCharacterStatsView(BaseView):
|
|||||||
self._render()
|
self._render()
|
||||||
|
|
||||||
def _render(self) -> None:
|
def _render(self) -> None:
|
||||||
if not self._win:
|
if not self._win or not self._stats_win:
|
||||||
return
|
return
|
||||||
|
|
||||||
y, x = self._win.getbegyx()
|
y, x = self._win.getbegyx()
|
||||||
|
|||||||
@@ -7,11 +7,12 @@ from pqcli.mechanic import Player, Simulation
|
|||||||
from pqcli.roster import Roster
|
from pqcli.roster import Roster
|
||||||
from pqcli.ui.curses.event_handler import EventHandler
|
from pqcli.ui.curses.event_handler import EventHandler
|
||||||
from pqcli.ui.curses.util import KEYS_DOWN, KEYS_LEFT, KEYS_RIGHT, KEYS_UP
|
from pqcli.ui.curses.util import KEYS_DOWN, KEYS_LEFT, KEYS_RIGHT, KEYS_UP
|
||||||
|
from pqcli.ui.curses.views.base_view import BaseView
|
||||||
from pqcli.ui.curses.widgets import Scrollable, Widget
|
from pqcli.ui.curses.widgets import Scrollable, Widget
|
||||||
|
|
||||||
from ..base_view import BaseView
|
|
||||||
from .character_sheet_window import CharacterSheetWindow
|
from .character_sheet_window import CharacterSheetWindow
|
||||||
from .equipment_window import EquipmentWindow
|
from .equipment_window import EquipmentWindow
|
||||||
|
from .focusable import Focusable
|
||||||
from .inventory_window import InventoryWindow
|
from .inventory_window import InventoryWindow
|
||||||
from .plot_window import PlotWindow
|
from .plot_window import PlotWindow
|
||||||
from .quest_book_window import QuestBookWindow
|
from .quest_book_window import QuestBookWindow
|
||||||
@@ -186,14 +187,16 @@ class GameView(BaseView):
|
|||||||
x=0,
|
x=0,
|
||||||
)
|
)
|
||||||
|
|
||||||
self._children: T.List[Widget] = [
|
self._focusable_children: T.List[Focusable] = [
|
||||||
self._char_sheet_win,
|
self._char_sheet_win,
|
||||||
self._spell_book_win,
|
self._spell_book_win,
|
||||||
self._equipment_win,
|
self._equipment_win,
|
||||||
self._inventory_win,
|
self._inventory_win,
|
||||||
self._plot_win,
|
self._plot_win,
|
||||||
self._quest_book_win,
|
self._quest_book_win,
|
||||||
self._task_win,
|
]
|
||||||
|
self._children: T.List[Widget] = self._focusable_children + [
|
||||||
|
self._task_win
|
||||||
]
|
]
|
||||||
|
|
||||||
def stop(self) -> None:
|
def stop(self) -> None:
|
||||||
@@ -213,12 +216,12 @@ class GameView(BaseView):
|
|||||||
curses.doupdate()
|
curses.doupdate()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def focused(self) -> Widget:
|
def focused(self) -> Focusable:
|
||||||
for widget in self._children:
|
for widget in self._focusable_children:
|
||||||
if widget.focused:
|
if widget.focused:
|
||||||
return widget
|
return widget
|
||||||
return None
|
raise AssertionError
|
||||||
|
|
||||||
def focus(self, widget: Widget):
|
def focus(self, widget: Focusable) -> None:
|
||||||
self.focused.focused = False
|
self.focused.focused = False
|
||||||
widget.focused = True
|
widget.focused = True
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class EquipmentWindow(Focusable, WindowWrapper):
|
|||||||
if not self._win:
|
if not self._win:
|
||||||
return
|
return
|
||||||
|
|
||||||
with self._focus_standout(self._win):
|
with self.focus_standout(self._win):
|
||||||
self._win.box()
|
self._win.box()
|
||||||
text = " Equipment "
|
text = " Equipment "
|
||||||
x = max(0, (self.getmaxyx()[1] - len(text)) // 2)
|
x = max(0, (self.getmaxyx()[1] - len(text)) // 2)
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ class Focusable:
|
|||||||
self._on_focus_change()
|
self._on_focus_change()
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def _focus_standout(self, win: T.Any) -> T.Generator:
|
def focus_standout(self, win: T.Any) -> T.Generator:
|
||||||
if self._focused:
|
if self._focused:
|
||||||
self._win.standout()
|
win.standout()
|
||||||
yield
|
yield
|
||||||
if self._focused:
|
if self._focused:
|
||||||
self._win.standend()
|
win.standend()
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import curses
|
import curses
|
||||||
import typing as T
|
import typing as T
|
||||||
|
|
||||||
|
from pqcli.ui.curses.views.game_view.focusable import Focusable
|
||||||
from pqcli.ui.curses.widgets import (
|
from pqcli.ui.curses.widgets import (
|
||||||
DataTable,
|
DataTable,
|
||||||
ListBox,
|
ListBox,
|
||||||
@@ -8,8 +9,6 @@ from pqcli.ui.curses.widgets import (
|
|||||||
WindowWrapper,
|
WindowWrapper,
|
||||||
)
|
)
|
||||||
|
|
||||||
from .focusable import Focusable
|
|
||||||
|
|
||||||
|
|
||||||
class ProgressBarWindow(WindowWrapper):
|
class ProgressBarWindow(WindowWrapper):
|
||||||
def __init__(
|
def __init__(
|
||||||
@@ -25,8 +24,8 @@ class ProgressBarWindow(WindowWrapper):
|
|||||||
super().__init__(parent, h, w, y, x)
|
super().__init__(parent, h, w, y, x)
|
||||||
|
|
||||||
self._title = title
|
self._title = title
|
||||||
self._cur_pos = 0
|
self._cur_pos = 0.0
|
||||||
self._max_pos = 1
|
self._max_pos = 1.0
|
||||||
self._progress_title = ""
|
self._progress_title = ""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -52,11 +51,7 @@ class ProgressBarWindow(WindowWrapper):
|
|||||||
|
|
||||||
self._progress_bar_win.erase()
|
self._progress_bar_win.erase()
|
||||||
|
|
||||||
if self._focused:
|
with Focusable.focus_standout(self, self._progress_bar_win):
|
||||||
# with self._focus_standout(self._progress_bar_win):
|
|
||||||
self._progress_bar_win.standout()
|
|
||||||
|
|
||||||
if True:
|
|
||||||
self._progress_bar_win.border(
|
self._progress_bar_win.border(
|
||||||
curses.ACS_VLINE,
|
curses.ACS_VLINE,
|
||||||
curses.ACS_VLINE,
|
curses.ACS_VLINE,
|
||||||
@@ -77,9 +72,6 @@ class ProgressBarWindow(WindowWrapper):
|
|||||||
min(len(text), self._progress_bar_win.getmaxyx()[1]),
|
min(len(text), self._progress_bar_win.getmaxyx()[1]),
|
||||||
)
|
)
|
||||||
|
|
||||||
if self._focused:
|
|
||||||
self._progress_bar_win.standend()
|
|
||||||
|
|
||||||
self._progress_bar.set_position(self._cur_pos, self._max_pos)
|
self._progress_bar.set_position(self._cur_pos, self._max_pos)
|
||||||
self._progress_bar_win.noutrefresh()
|
self._progress_bar_win.noutrefresh()
|
||||||
|
|
||||||
@@ -110,7 +102,7 @@ class DataTableProgressBarWindow(ProgressBarWindow):
|
|||||||
if not self._win:
|
if not self._win:
|
||||||
return
|
return
|
||||||
|
|
||||||
with self._focus_standout(self._win):
|
with Focusable.focus_standout(self, self._win):
|
||||||
self._win.box()
|
self._win.box()
|
||||||
x = max(0, (self.getmaxyx()[1] - len(self._title)) // 2)
|
x = max(0, (self.getmaxyx()[1] - len(self._title)) // 2)
|
||||||
self._win.addnstr(
|
self._win.addnstr(
|
||||||
@@ -148,7 +140,7 @@ class ListBoxProgressBarWindow(ProgressBarWindow):
|
|||||||
if not self._win:
|
if not self._win:
|
||||||
return
|
return
|
||||||
|
|
||||||
with self._focus_standout(self._win):
|
with Focusable.focus_standout(self, self._win):
|
||||||
self._win.box()
|
self._win.box()
|
||||||
x = max(0, (self.getmaxyx()[1] - len(self._title)) // 2)
|
x = max(0, (self.getmaxyx()[1] - len(self._title)) // 2)
|
||||||
self._win.addnstr(
|
self._win.addnstr(
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class SpellBookWindow(Focusable, WindowWrapper):
|
|||||||
if not self._win:
|
if not self._win:
|
||||||
return
|
return
|
||||||
|
|
||||||
with self._focus_standout(self._win):
|
with self.focus_standout(self._win):
|
||||||
self._win.box()
|
self._win.box()
|
||||||
text = " Spell Book "
|
text = " Spell Book "
|
||||||
x = max(0, (self.getmaxyx()[1] - len(text)) // 2)
|
x = max(0, (self.getmaxyx()[1] - len(text)) // 2)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import curses
|
import curses
|
||||||
|
import curses.ascii
|
||||||
import typing as T
|
import typing as T
|
||||||
|
|
||||||
from pqcli.ui.curses.util import KEYS_DOWN, KEYS_UP
|
from pqcli.ui.curses.util import KEYS_DOWN, KEYS_UP
|
||||||
|
|||||||
@@ -92,5 +92,5 @@ class Scrollable(WindowWrapper):
|
|||||||
except curses.error:
|
except curses.error:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _render_impl(self) -> None:
|
def _render_impl(self, h: int, w: int) -> None:
|
||||||
raise NotImplementedError("not implemented")
|
raise NotImplementedError("not implemented")
|
||||||
|
|||||||
Reference in New Issue
Block a user