home · contact · privacy
More TUI client refactoring.
[plomrogue2] / plomrogue_client / tui.py
index 7cfc01139c35a8cbb75aa0039640fc353b98a109..758d7f76b036926770acd07c68e71814c6340181 100644 (file)
@@ -3,10 +3,17 @@ import curses
 
 
 
+class AbortOnGetkey(Exception):
+    pass
+
+
+
 class TUI:
 
     def __init__(self):
         self._log = []
+        self.do_refresh = True
+        self.store_widechar = False
         curses.wrapper(self.run_loop)
 
     def addstr(self, y, x, line, attr=0):
@@ -26,19 +33,49 @@ class TUI:
         self.size = self.size - YX(self.size.y % 4, 0)
         self.size = self.size - YX(0, self.size.x % 4)
 
+    def log(self, msg):
+        self._log += [msg]
+        self.do_refresh = True
+
     def init_loop(self):
         curses.curs_set(0)  # hide cursor
         self.stdscr.timeout(10)
         self.reset_size()
 
+    def get_key_and_keycode(self):
+        try:
+            key = self.stdscr.getkey()
+        except curses.error:
+            raise AbortOnGetkey
+        keycode = None
+        if len(key) == 1:
+            keycode = ord(key)
+            # workaround for <https://stackoverflow.com/a/56390915>
+            if self.store_widechar:
+                self.store_widechar = False
+                key = bytes([195, keycode]).decode()
+            if keycode == 195:
+                self.store_widechar = True
+                raise AbortOnGetkey
+        return key, keycode
+
     def run_loop(self, stdscr):
         self.stdscr = stdscr
         self.init_loop()
         while True:
-            self.loop()
-
-    def log(self, msg):
-        self._log += [msg]
+            self.on_each_loop_start()
+            for msg in self.socket.get_message():
+                self.handle_server_message(msg)
+            if self.do_refresh:
+                self.stdscr.clear()
+                self.draw_screen()
+                self.do_refresh = False
+            try:
+                key, keycode = self.get_key_and_keycode()
+            except AbortOnGetkey:
+                continue
+            self.on_key(key, keycode)
+            self.do_refresh = True