Source code for runtimepy.tui.mixin
"""
A module for terminal user-interface application mixins.
"""
# built-in
from contextlib import suppress
from typing import Optional
# internal
from runtimepy.tui.cursor import CursesWindow, Cursor
__all__ = ["CursesWindow", "Cursor", "TuiMixin"]
_curses = {} # type: ignore
with suppress(ModuleNotFoundError):
import curses as _curses # type: ignore
[docs]
class TuiMixin:
"""A class mixin for building TUI applications."""
cursor: Cursor
def __init__(self, window: Optional[CursesWindow] = None) -> None:
"""Initialize this instance."""
self._window = None
self.init(window)
[docs]
def init(self, window: Optional[CursesWindow]) -> bool:
"""Initialize this interface's window."""
do_init = window is not None and self._window is None
if do_init:
assert window is not None
self._window = window
self.cursor = Cursor(self._window)
# _curses.use_default_colors()
getattr(_curses, "use_default_colors")()
# _curses.curs_set(0)
getattr(_curses, "curs_set")(0)
# Don't block when getting a character.
window.nodelay(True)
# Initialize the window dimensions.
self.update_dimensions()
return do_init
@property
def window(self) -> CursesWindow:
"""Get the window for this instance."""
assert self._window is not None
return self._window
[docs]
def update_dimensions(self) -> CursesWindow:
"""Handle an update to the window's dimensions."""
window = self.window
self.cursor.poll_max()
return window
[docs]
def tui_update(self) -> None:
"""Re-draw the screen."""
getattr(_curses, "doupdate")()
[docs]
async def handle_char(self, char: int) -> bool:
"""Handle character input."""
handled = False
if char != -1:
if char == getattr(_curses, "KEY_RESIZE"):
self.update_dimensions()
handled = True
return handled