from __future__ import annotations import curses from .colors import UIColors from .views import DigitsView, HeaderView, HelpView class PiDashboard: """Coordinates curses windows for the π streaming UI.""" def __init__(self, stdscr: "curses._CursesWindow") -> None: self.stdscr = stdscr try: curses.curs_set(0) except curses.error: pass self.stdscr.nodelay(True) self.stdscr.timeout(100) UIColors.setup() lines, cols = curses.LINES, curses.COLS header_h = 6 help_h = 1 digits_h = max(1, lines - header_h - help_h - 1) self.header = HeaderView(header_h, cols, 0, 0) self.digits = DigitsView(digits_h, cols, header_h, 0) self.help = HelpView(header_h + digits_h, 0, cols) self.scroll = 0 def render( self, digits_text: str, digits_count: int, elapsed: float, rate: float, last_digit: str | None, computing: bool, iteration: int, ) -> None: self.header.render( iteration, digits_count, elapsed, rate, last_digit, computing, ) self.scroll = self.digits.render(digits_text, self.scroll) self.help.render() curses.doupdate() def handle_input(self, ch: int) -> None: if ch == curses.KEY_UP: self.scroll = max(0, self.scroll - 1) elif ch == curses.KEY_DOWN: self.scroll += 1