From 6ed915f431e41ea93771a970edaa6ab1b438b582 Mon Sep 17 00:00:00 2001
From: Ben Connors <benconnors@outlook.com>
Date: Tue, 1 Oct 2019 22:05:12 -0400
Subject: Add initial work on curses interface

---
 interface/__init__.py    |   0
 interface/channelbank.py | 166 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 166 insertions(+)
 create mode 100644 interface/__init__.py
 create mode 100755 interface/channelbank.py

(limited to 'interface')

diff --git a/interface/__init__.py b/interface/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/interface/channelbank.py b/interface/channelbank.py
new file mode 100755
index 0000000..c9d971f
--- /dev/null
+++ b/interface/channelbank.py
@@ -0,0 +1,166 @@
+import curses
+
+_progress = ["    "]
+for i in range(8):
+    pos = i // 2
+    s = _progress[-1]
+    _progress.append(s[:pos] + ('\u2588' if i%2 else '\u258c') + s[pos+1:])
+
+def get_progress(v):
+    if v == 0:
+        return _progress[0]
+    elif v <= 36:
+        return _progress[1]
+    elif v <= 73:
+        return _progress[2]
+    elif v <= 109:
+        return _progress[3]
+    elif v <= 145:
+        return _progress[4]
+    elif v <= 181:
+        return _progress[5]
+    elif v <= 218:
+        return _progress[6]
+    elif v <= 254:
+        return _progress[7]
+    return _progress[8]
+
+class ChannelView:
+    width = 9
+    height = 3
+
+    def _refresh_channel(self):
+        self.win.addstr(0, 0, "%03d.%03d" % (self.c.f.id, self.c.id), curses.A_UNDERLINE if self._active else 0)
+        self.win.noutrefresh()
+
+    def _refresh_value(self):
+        self.win.addstr(1, 0, get_progress(self._value))
+        self.win.addstr(1, 4, "%03d" % self._value, (curses.A_ITALIC|curses.A_BOLD if self._held else 0))
+        self.win.noutrefresh()
+
+    def refresh(self):
+        self._refresh_value()
+        self._refresh_channel()
+
+    @property
+    def active(self):
+        return self._active
+
+    @active.setter
+    def active(self, v):
+        if v != self._active:
+            self._active = v
+            self._refresh_channel()
+
+    @property
+    def value(self):
+        return self._value
+
+    @value.setter
+    def value(self, v):
+        if v != self._value:
+            self._value = v
+            self._refresh_value()
+
+    @property
+    def held(self):
+        return self._held
+
+    @held.setter
+    def held(self, v):
+        if v != self._held:
+            self._held = v
+            self._refresh_value()
+
+    def set_pos(self, y, x):
+        self.y = self.y
+        self.x = self.x
+        self.win.noutrefresh()
+        self.win.mvwin(y, x)
+        self.refresh()
+
+    def __init__(self, root, c, y, x, value=0, held=False, active=False):
+        self._active = active
+        self._held = held
+        self._value = value
+        self.c = c
+        
+        self.y = y
+        self.x = x
+
+        self.root = root
+        self.win = root.subpad(self.height, self.width, self.y, self.x)
+
+        self._refresh_value()
+        self._refresh_channel()
+
+class ChannelBank:
+    def set_dim(self, height, width):
+        if ((height-2)//ChannelView.height) * ((width-4)//ChannelView.width) < len(self.scope):
+            raise NotImplementedError("Screen size to small")
+
+
+        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._refresh_scope()
+        self.win.border()
+        self.win.noutrefresh()
+
+    def _refresh_scope(self):
+        self.win.erase()
+        ncv = {}
+        cols = (self._width-4)//ChannelView.width
+        with open("out.txt", 'w+') as f:
+            f.write(str(cols)+'\n')
+        self._sscope = sorted(self.scope, key=lambda a: (a.f.id, a.id))
+        for n, c in enumerate(self._sscope):
+            row = (n // cols)*ChannelView.height + 1
+            col = (n % cols)*ChannelView.width + 2
+            if c in self._cv:
+                active = self._cv[c].active
+                held = self._cv[c].held
+                value = self._cv[c].value
+            else:
+                active = False
+                held = False
+                value = 0
+            ncv[c] = ChannelView(self.win, c, row, col, value=value, active=active, held=held)
+        self._cv = ncv
+
+    def set_pos(self, y, x):
+        if (y, x) != (self._y, self._x):
+            self.win.mvwin(y, x)
+            self.win.border()
+            self.win.noutrefresh()
+
+    def set_active(self, channels, v=True):
+        for c in channels:
+            self._cv[c].active = v
+
+    def set_held(self, channels, v=True):
+        for c in channels:
+            self._cv[c].held = v
+
+    def set_values(self, cv):
+        for c, v in cv:
+            self._cv[c].value = v
+            
+    def __init__(self, y, x, height, width, scope=frozenset()):
+        self.win = curses.newwin(height, width, y, x)
+        self.win.keypad(True)
+        self.scope = frozenset(scope)
+        self._sscope = []
+        self._cv = {}
+        self._height = height
+        self._width = width
+        self._y = -1
+        self._x = -1
+        self.set_pos(y, x)
+        self.set_dim(height, width)
-- 
cgit v1.2.3