From 755d1dda2a1eb1c26fa7bc12328e2bca25256257 Mon Sep 17 00:00:00 2001 From: Ben Connors Date: Fri, 18 Oct 2019 23:02:12 -0400 Subject: Get a decent start on the actual interface - Can edit, create, delete scenes - Basic saving --- interface/pager.py | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100755 interface/pager.py (limited to 'interface/pager.py') diff --git a/interface/pager.py b/interface/pager.py new file mode 100755 index 0000000..2203e52 --- /dev/null +++ b/interface/pager.py @@ -0,0 +1,149 @@ +#!/usr/bin/env python3 + +import curses +import threading + +from .globals import CURSES_LOCK + +class Pager: + def set_dim(self, height, width): + if height < 4 or width < 10: + raise ValueError("Size too small") + + with self._lock: + if (height, width) != (self._height, self._width): + self.win.erase() + self.win.noutrefresh() + + self.win.resize(height, width) + self.win.redrawwin() + + self._height = height + self._width = width + self._regen_actual() + self._redraw() + + def set_pos(self, y, x): + with self._lock: + if (y, x) != (self._y, self._x): + self.win.mvwin(y, x) + self._y = y + self._x = x + self.win.noutrefresh() + + def _redraw(self): + with self._lock, CURSES_LOCK: + start = max(0, self._bottom_a - self._height + 2) + end = self._bottom_a + todisp = self._actual[start:end] + if len(todisp) < self._height-2 and len(todisp) < len(self._actual): + end = self._bottom_a+self._height-2-len(todisp) + todisp += self._actual[self._bottom_a:end] + self.win.erase() + self.win.border() + if start > 0: + self.win.addch(0, self._width//2, '⯅') + for n, l in enumerate(todisp, 1): + self.win.addstr(n, 1, l) + if end < len(self._actual): + self.win.addch(self._height-1, self._width//2, '⯆') + self.win.refresh() + + def _split_line(self, l): + with self._lock: + lines = [] + + while len(l) >= self._width-2: + lines.append(l[:self._width-3] + '…') + l = "⮡ "+l[self._width-3:] + lines.append(l) + + return lines + + def _regen_actual(self): + with self._lock: + self._actual = [] + for n, l in enumerate(self._lines): + self._actual += self._split_line(l) + if n == self._bottom: + self._bottom_a = len(self._actual) + self._bottom_a = max(self._bottom_a, self._height-2) + + def display_many(self, s, split=False): + with self._lock: + if split: + self._lines.append("") + self._actual.append("") + for l in s: + self._lines.append(l) + self._actual += self._split_line(l) + self._bottom = len(self._lines) - 1 + self._bottom_a = len(self._actual) + self._redraw() + + def display(self, s): + self.display_many((s, )) + + def user_page(self, refresh=None): + curses.curs_set(0) + + while True: + l = self.win.getch() + + with self._lock: + if l == curses.KEY_RESIZE: + if refresh is not None: + refresh() + elif l == ord('q'): + break + elif l in (ord('k'), curses.KEY_UP): + if self._bottom_a > self._height-2: + self._bottom_a -= 1 + self._redraw() + elif l in (ord('j'), curses.KEY_DOWN): + if self._bottom_a < len(self._actual): + self._bottom_a += 1 + self._redraw() + elif l == curses.KEY_NPAGE: + if self._bottom_a < len(self._actual): + self._bottom_a = min(len(self._actual), self._bottom_a + self._height - 2) + self._redraw() + elif l == curses.KEY_PPAGE: + if self._bottom_a > 0: + self._bottom_a = max(self._height - 2, self._bottom_a - self._height + 2) + self._redraw() + elif l == curses.KEY_HOME: + if self._bottom_a > self._height - 2: + self._bottom_a = self._height - 2 + self._redraw() + elif l == curses.KEY_END: + if self._bottom_a < len(self._actual): + self._bottom_a = len(self._actual) + self._redraw() + + curses.curs_set(1) + + def clear(self): + with self._lock: + self._lines = [] + self._actual = [] + self._bottom_a = 0 + self._bottom = -1 + self._redraw() + + def __init__(self, y, x, height, width): + with CURSES_LOCK: + self.win = curses.newwin(height, width, y, x) + self.win.keypad(True) + self._lock = threading.RLock() + self._height = height + self._width = width + self._y = -1 + self._x = -1 + self._lines = [] + self._actual = [] + self._bottom = -1 + self._bottom_a = 0 + + self.set_pos(y, x) + self.set_dim(height, width) -- cgit v1.2.3