ui/curses: add focus to character name view

This commit is contained in:
rr-
2019-01-13 21:41:21 +01:00
parent 8d385523ad
commit 8c6b1a2504
@@ -4,8 +4,9 @@ import typing as T
from pqcli.mechanic import generate_name
from pqcli.ui.curses.event_handler import EventHandler
from pqcli.ui.curses.util import KEYS_CANCEL
from pqcli.ui.curses.util import KEYS_CANCEL, KEYS_DOWN, KEYS_UP
from pqcli.ui.curses.views.base_view import BaseView
from pqcli.ui.curses.widgets.focusable import focus_standout
class ChooseCharacterNameView(BaseView):
@@ -17,7 +18,9 @@ class ChooseCharacterNameView(BaseView):
self.on_cancel = EventHandler()
self.on_confirm = EventHandler()
self._active_widget = 0
self._win: T.Optional[T.Any] = None
self._text_win: T.Optional[T.Any] = None
self._text = character_name or generate_name()
def start(self) -> None:
@@ -30,49 +33,85 @@ class ChooseCharacterNameView(BaseView):
w = 30
y = (scr_height - h - 2) // 2
x = (scr_width - w - 2) // 2
self._win = curses.newwin(3, w + 2, y + 2, x - 1)
self._win.box()
self.screen.addstr(y, x, "Choose character name:")
self.screen.addstr(y + 6, x, "[F5 ] generate random name")
self.screen.addstr(y + 7, x, "[Esc ] cancel")
self.screen.addstr(y + 8, x, "[Enter] confirm")
self._win.refresh()
self._text_win = curses.newwin(3, w + 2, y + 2, x - 1)
self._win = curses.newwin(h + 2, w + 2, y, x)
self._render()
def stop(self) -> None:
del self._win
del self._text_win
self._win = None
self._text_win = None
def keypress(self, key: int) -> None:
if key == curses.ascii.ESC:
self.on_cancel()
elif key == curses.KEY_F5:
if key == curses.KEY_F5:
self._text = generate_name()
elif key == curses.KEY_F10:
self._finish()
elif self._active_widget == 0:
if key == curses.ascii.ESC:
self.on_cancel()
elif curses.ascii.isprint(key):
self._text += chr(key)
elif key == curses.KEY_BACKSPACE or key == curses.ascii.DEL:
self._text = self._text[:-1]
elif key == curses.ascii.NL:
self._finish()
elif key == curses.ascii.ETB: # ^w
self._text = ""
elif key == curses.KEY_DOWN:
self._active_widget = 1
else:
if key == curses.ascii.NL:
if self._active_widget == 1:
self._text = generate_name()
elif self._active_widget == 2:
self._finish()
elif self._active_widget == 3:
self.on_cancel()
else:
assert False
elif key in KEYS_CANCEL:
self.on_cancel()
elif key in KEYS_DOWN and self._active_widget < 3:
self._active_widget += 1
elif key in KEYS_UP and self._active_widget > 0:
self._active_widget -= 1
self._render()
def _finish(self) -> None:
self._text = self._text.strip()
if self._text:
self.on_confirm(self._text)
else:
self.on_cancel()
elif key == curses.ascii.ETB: # ^w
self._text = ""
self._render()
def _render(self) -> None:
if not self._win:
if not self._win or not self._text_win:
return
self._win.erase()
self._win.box()
self._win.addnstr(1, 1, self._text, self._win.getmaxyx()[1] - 2)
self._win.addstr(0, 0, "Choose character name:")
with focus_standout(self._active_widget == 1, self._win):
self._win.addstr(6, 0, "[F5 ] generate random name")
with focus_standout(self._active_widget == 2, self._win):
self._win.addstr(7, 0, "[F10 ] continue")
with focus_standout(self._active_widget == 3, self._win):
self._win.addstr(8, 0, "[Esc ] cancel")
self._win.refresh()
self._text_win.erase()
with focus_standout(self._active_widget == 0, self._text_win):
self._text_win.box()
self._text_win.addnstr(
1, 1, self._text, self._text_win.getmaxyx()[1] - 2
)
self._text_win.refresh()