def _render_impl(self, h: int, w: int) -> None: assert self._pad if self._align_right: for y, row in enumerate(self._items): if y == self._selected and has_colors(): self._pad.attron(curses.color_pair(COLOR_HIGHLIGHT)) self._pad.move(y, 0) self._pad.addnstr(row[0], min(len(row[0]), w)) col2_x = max(0, w - len(row[1])) if col2_x < w: self._pad.move(y, col2_x) self._pad.addstr(row[1]) if y == self._selected and has_colors(): self._pad.attroff(curses.color_pair(COLOR_HIGHLIGHT)) else: col2_x = self._get_col_width(0) for y, row in enumerate(self._items): if y == self._selected and has_colors(): self._pad.attron(curses.color_pair(COLOR_HIGHLIGHT)) self._pad.addnstr(y, 0, row[0], min(len(row[0]), w)) if col2_x < w: self._pad.addnstr(y, col2_x, row[1], min(len(row[1]), w - col2_x)) if y == self._selected and has_colors(): self._pad.attroff(curses.color_pair(COLOR_HIGHLIGHT))
def _render_impl(self, h: int, w: int) -> None: assert self._pad for y, item in enumerate(self._items): if y == self._selected and has_colors(): self._pad.attron(curses.color_pair(COLOR_HIGHLIGHT)) self._pad.addnstr(y, 0, item, min(len(item), w)) if y == self._selected and has_colors(): self._pad.attroff(curses.color_pair(COLOR_HIGHLIGHT))
def focus_standout(focused: bool, win: T.Any) -> T.Generator: if focused: if has_colors(): win.attron(curses.color_pair(COLOR_FOCUSED)) else: win.standout() yield if focused: if has_colors(): win.attroff(curses.color_pair(COLOR_FOCUSED)) else: win.standend()
def render(self) -> None: if not self._pad or not self._win: return if self._items: self._pad.resize(max(1, len(self._items)), max(1, self.getmaxyx()[1] + 1)) else: self._pad.resize(1, 1) self._win.erase() self._win.noutrefresh() self._pad.erase() h, w = self.getmaxyx() y, x = self.getbegyx() try: if self._scroll_pos > 0 or self._scroll_pos + h < len(self._items): y1 = self._scroll_pos y2 = self._scroll_pos + h thumb_y1 = int(y1 * h // len(self._items)) thumb_y2 = int(y2 * h // len(self._items)) attr_thumb = (curses.color_pair(COLOR_SCROLLBAR_THUMB) if has_colors() else curses.A_REVERSE) attr_track = (curses.color_pair(COLOR_SCROLLBAR_TRACK) if has_colors() else curses.A_NORMAL) for win_y in range(h): self._win.chgat( win_y, w - 1, attr_thumb if thumb_y1 <= win_y <= thumb_y2 else attr_track, ) self._win.noutrefresh() self._render_impl(h, w - 1) self._pad.noutrefresh(self._scroll_pos, 0, y, x, y + h - 1, x + w - 2) else: self._render_impl(h, w) self._pad.noutrefresh(self._scroll_pos, 0, y, x, y + h - 1, x + w - 1) except curses.error: pass
def __init__(self, roster: Roster, args: argparse.Namespace) -> None: super().__init__(roster, args) os.environ.setdefault("ESCDELAY", "25") self._screen = curses.initscr() self._screen.nodelay(True) self._screen.keypad(True) curses.noecho() curses.curs_set(0) set_colors(args.colors) if has_colors(): curses.start_color() curses.use_default_colors() curses.init_pair(COLOR_LOGO, -1, -1) curses.init_pair(COLOR_LOGO_ALT, -1, 9) curses.init_pair(COLOR_FOCUSED, -1, 8) curses.init_pair(COLOR_SCROLLBAR_THUMB, -1, 7) curses.init_pair(COLOR_SCROLLBAR_TRACK, -1, 0) curses.init_pair(COLOR_PROGRESSBAR, 0, 9) curses.init_pair(COLOR_HIGHLIGHT, 3, -1) def signal_handler(sig: T.Any, frame: T.Any) -> None: if self.args.use_saves: self.roster.save() exit(0) signal.signal(signal.SIGINT, signal_handler) self._roster_view = RosterView(self._screen) self._roster_view.on_create += self._switch_to_create_char_name_view self._roster_view.on_delete += self._switch_to_delete_char_view self._roster_view.on_play += self._switch_to_play_view self._roster_view.on_quit += self._quit self._view: BaseView = self._roster_view self._view.start()
def set_position(self, cur_pos: float, max_pos: float) -> None: if not self._win: return self._win.erase() if self._last_tick is None or cur_pos == 0 or max_pos != self._max_pos: self._last_tick = (datetime.datetime.now(), cur_pos) self._cur_pos = cur_pos self._max_pos = max_pos text = f"{cur_pos / max_pos:.02%}" if self.time_left and self._show_time: text += f" ({format_timespan(self.time_left)})" x = max(0, (self.getmaxyx()[1] - len(text)) // 2) self._win.addnstr(0, x, text, min(len(text), self.getmaxyx()[1] - 1)) x = int(cur_pos * self.getmaxyx()[1] // max_pos) if x > 0: self._win.chgat( 0, 0, curses.color_pair(COLOR_PROGRESSBAR) if has_colors() else curses.A_REVERSE, ) if x < self.getmaxyx()[1]: self._win.chgat(0, x, curses.A_NORMAL) self._win.noutrefresh()
def __init__( self, choices: T.List[Choice], scr_height: int, scr_width: int ) -> None: super().__init__( header=LOGO, choices=choices, active_choice=0, scr_height=scr_height, scr_width=scr_width, ) if has_colors(): for y in range(len(self._header_lines)): self._pad.chgat(y, 0, curses.color_pair(COLOR_LOGO)) self._pad.chgat(3, 29, 5, curses.color_pair(COLOR_LOGO_ALT)) self._pad.chgat(4, 29, 5, curses.color_pair(COLOR_LOGO_ALT)) self._pad.chgat(5, 32, 4, curses.color_pair(COLOR_LOGO_ALT)) self._pad.chgat(5, 27, 4, curses.color_pair(COLOR_LOGO_ALT)) self._pad.chgat(6, 34, 2, curses.color_pair(COLOR_LOGO_ALT)) self._pad.chgat(6, 27, 2, curses.color_pair(COLOR_LOGO_ALT))