""" Key constants and key-binding registry for the console UI. Key provides named constants matching curses key codes so that screens and renderers never need to import curses directly. KeyBindings maps key codes to callable actions and tracks the footer labels displayed at the bottom of the screen. """ import curses class Key: """Key constants matching curses key codes.""" ESCAPE = 27 ENTER = 10 TAB = 9 BACKSPACE = 127 UP = curses.KEY_UP DOWN = curses.KEY_DOWN LEFT = curses.KEY_LEFT RIGHT = curses.KEY_RIGHT PGUP = curses.KEY_PPAGE PGDN = curses.KEY_NPAGE HOME = curses.KEY_HOME END = curses.KEY_END F1 = curses.KEY_F1 F2 = curses.KEY_F2 F3 = curses.KEY_F3 F4 = curses.KEY_F4 F5 = curses.KEY_F5 F6 = curses.KEY_F6 F7 = curses.KEY_F7 F8 = curses.KEY_F8 F9 = curses.KEY_F9 F10 = curses.KEY_F10 class KeyBindings: """Registry that maps key codes to callable actions. Usage:: kb = KeyBindings() kb.bind(Key.ENTER, lambda: do_something()) handled = kb.handle(Key.ENTER) # True, callback was invoked """ def __init__(self): self._bindings: dict[int, callable] = {} self._footer_labels: list[tuple[str, str]] = [] def bind(self, key: int, action: callable) -> None: """Register *action* as the callback for *key*. If *key* already has a binding it is replaced. """ self._bindings[key] = action def handle(self, key: int) -> bool: """Look up *key* and invoke its callback if one exists. Returns ``True`` if a callback was found and executed, ``False`` otherwise. """ action = self._bindings.get(key) if action is not None: action() return True return False def set_footer(self, labels: list[tuple[str, str]]) -> None: """Set the footer bar labels. *labels* is a list of ``(key_label, description)`` tuples, e.g. ``[("F1", "Help"), ("F10", "Quit")]``. """ self._footer_labels = list(labels) def get_footer_labels(self) -> list[tuple[str, str]]: """Return the current footer labels list.""" return list(self._footer_labels)