]> git.armaanb.net Git - lightcards.git/blobdiff - lightcards/display.py
Reduce number of screen refreshes
[lightcards.git] / lightcards / display.py
index f51259396cd04cd2587cbdf92f993267531159aa..6f572ad470ad2b90d8dd36b2b6084db749fd5b1a 100644 (file)
@@ -6,6 +6,7 @@ import curses.panel
 from random import shuffle
 import sys
 import textwrap
+import time
 
 from . import runner, progress
 
@@ -19,13 +20,12 @@ def panel_create(x, y):
 
 
 class Help:
-    def __init__(self, outer):
+    def __init__(self, outer, mlines=20, mcols=52):
         """Initialize help screen"""
         self.outer = outer
-        (self.win, self.panel) = panel_create(20, 52)
+        (self.win, self.panel) = panel_create(mlines, mcols)
         self.panel.top()
         self.panel.hide()
-        self.win.clear()
 
         text = [
             "Welcome to runner. Here are some keybindings",
@@ -48,9 +48,12 @@ class Help:
         ]
 
         self.win.addstr(
-            1, 1, "LIGHTCARDS HELP", curses.color_pair(1) + curses.A_BOLD
+            1,
+            int(mcols / 2) - 8,
+            "LIGHTCARDS HELP",
+            curses.color_pair(1) + curses.A_BOLD,
         )
-        self.win.hline(2, 1, curses.ACS_HLINE, 15)
+        self.win.hline(2, 1, curses.ACS_HLINE, mcols)
 
         for t in enumerate(text):
             self.win.addstr(t[0] + 3, 1, t[1])
@@ -74,17 +77,20 @@ class Help:
 
 
 class Menu:
-    def __init__(self, outer):
+    def __init__(self, outer, mlines=17, mcols=44):
         """Initialize the menu with content"""
         self.outer = outer
-        (self.win, self.panel) = panel_create(17, 44)
+        (self.win, self.panel) = panel_create(mlines, mcols)
         self.panel.top()
         self.panel.hide()
 
         self.win.addstr(
-            1, 1, "LIGHTCARDS MENU", curses.color_pair(1) + curses.A_BOLD
+            1,
+            int(mcols / 2) - 8,
+            "LIGHTCARDS MENU",
+            curses.color_pair(1) + curses.A_BOLD,
         )
-        self.win.hline(2, 1, curses.ACS_HLINE, 15)
+        self.win.hline(2, 1, curses.ACS_HLINE, mcols)
         text = [
             "[y]: reset stack to original state",
             "[a]: alphabetize stack",
@@ -133,7 +139,7 @@ class Menu:
                 self.outer.stack = runner.get_orig()[1]
                 self.menu_print("Stack reset!")
             elif key == "a":
-                self.outer.stack.sort()
+                self.outer.stack.sort(key=lambda x: x.front)
                 self.menu_print("Stack alphabetized!")
             elif key == "u":
                 [x.unStar() for x in self.outer.stack]
@@ -171,9 +177,6 @@ class Menu:
                     self.menu_print("Stars only!")
                 else:
                     self.menu_print("ERR: None are starred!", err=True)
-            elif key in ["h", "KEY_LEFT"]:
-                self.outer.obj.index = len(self.outer.stack) - 1
-                self.outer.get_key()
             elif key == "r":
                 self.outer.obj.index = 0
                 self.outer.get_key()
@@ -200,23 +203,40 @@ class Display:
     def run(self, stdscr):
         """Set important options that require stdscr before starting"""
         self.win = stdscr
-        (mlines, mcols) = self.win.getmaxyx()
         curses.curs_set(0)  # Hide cursor
         curses.use_default_colors()  # Allow transparency
         curses.init_pair(1, curses.COLOR_CYAN, -1)
         curses.init_pair(2, curses.COLOR_RED, -1)
         curses.init_pair(3, curses.COLOR_YELLOW, -1)
 
-        (self.main_win, self.main_panel) = panel_create(mlines, mcols)
+        self.main_panel = curses.panel.new_panel(self.win)
         self.menu_obj = Menu(self)
         self.help_obj = Help(self)
 
         self.get_key()
 
+    def check_size(self):
+        (mlines, mcols) = self.win.getmaxyx()
+
+        while mlines < 24 or mcols < 60:
+            self.win.clear()
+            self.win.addstr(
+                0,
+                0,
+                textwrap.fill(
+                    "Terminal too small! Min size 60x24", width=mcols
+                ),
+            )
+            self.win.refresh()
+            (mlines, mcols) = self.win.getmaxyx()
+            time.sleep(0.1)
+        else:
+            self.disp_card()
+
     def update_panels(self):
         """Update panel and window contents"""
         curses.panel.update_panels()
-        self.win.refresh()
+        curses.doupdate()
 
     def leave(self):
         """Pickle stack before quitting"""
@@ -235,7 +255,8 @@ class Display:
         Display the statusbar at the bottom of the screen with progress, star
         status, and card side.
         """
-        (mlines, _) = self.win.getmaxyx()
+        (mlines, mcols) = self.win.getmaxyx()
+        self.win.hline(mlines - 2, 0, 0, mcols)
 
         # Calculate percent done
         if len(self.stack) <= 1:
@@ -269,7 +290,7 @@ class Display:
         self.win.addstr(
             mlines - 1,
             len(bar_start + bar_middle),
-            bar_end,
+            textwrap.shorten(bar_end, width=mcols - 20, placeholder="…"),
             curses.color_pair(1),
         )
 
@@ -287,9 +308,10 @@ class Display:
         Shows a header, a horizontal line, and the contents of the current
         side.
         """
-        (mlines, mcols) = self.win.getmaxyx()
+        (_, mcols) = self.win.getmaxyx()
         self.main_panel.bottom()
-        self.main_win.clear()
+        self.win.clear()
+
         # If on the back of the card, show the content of the front side in
         # the header
         num_done = str(self.obj.index + 1).zfill(len(str(len(self.stack))))
@@ -304,11 +326,12 @@ class Display:
                 + str(self.current_card().front)
                 + '"'
             )
+
         header_width = mcols
         if mcols > 80:
             header_width = 80
 
-        self.main_win.addstr(
+        self.win.addstr(
             0,
             0,
             textwrap.shorten(top, width=header_width, placeholder="…"),
@@ -316,13 +339,10 @@ class Display:
         )
 
         # Add horizontal line
-        lin_width = header_width
-        if len(top) < header_width:
-            lin_width = len(top)
-        self.main_win.hline(1, 0, curses.ACS_HLINE, lin_width)
+        self.win.hline(1, 0, curses.ACS_HLINE, mcols)
 
         # Show current side
-        self.main_win.addstr(
+        self.win.addstr(
             2,
             0,
             textwrap.fill(
@@ -333,7 +353,6 @@ class Display:
         self.update_panels()
         self.disp_bar()
         self.disp_sidebar()
-        self.win.hline(mlines - 2, 0, 0, mcols)
 
     def current_card(self):
         """Get current card object"""
@@ -344,8 +363,8 @@ class Display:
         Display a card and wait for the input.
         Used as a general way of getting back into the card flow from a menu
         """
-        self.disp_card()
         while True:
+            self.check_size()
             key = self.win.getkey()
             if key == "q":
                 self.leave()
@@ -394,7 +413,6 @@ class Display:
             curses.color_pair(3) + curses.A_BOLD,
         )
         self.win.vline(0, mcols - 20, 0, mlines - 2)
-        self.win.hline(1, left, 0, mlines)
 
         nstarred = self.nstarred()
         if mlines - 5 < len(self.nstarred()):