Beispiel #1
0
 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))
Beispiel #2
0
 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))
Beispiel #3
0
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()
Beispiel #4
0
    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
Beispiel #5
0
    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()
Beispiel #6
0
    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()
Beispiel #7
0
 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))