]> git.armaanb.net Git - lightcards.git/blobdiff - lightcards/display.py
Modify mvwin() positioning
[lightcards.git] / lightcards / display.py
index d0c42fa6d04f45fc0503e9245af93c5e73cb722e..d0c24208b5fb11b19b73be81f15e9ede6fb776e6 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])
@@ -60,8 +63,7 @@ class Help:
     def disp(self):
         """Display help screen"""
         (mlines, mcols) = self.outer.win.getmaxyx()
-        self.win.mvwin(int(mlines / 2) - 10, int(mcols / 2) - 26)
-        self.outer.update_panels()
+        self.win.mvwin(int(mlines / 2) - 10, int(mcols / 2) - 25)
         self.panel.show()
 
         while True:
@@ -74,17 +76,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",
@@ -103,7 +108,6 @@ class Menu:
             self.win.addstr(t[0] + 3, 1, t[1])
 
         self.win.box()
-        self.outer.update_panels()
 
     def menu_print(self, string, err=False):
         """Print messages on the menu screen"""
@@ -116,7 +120,6 @@ class Menu:
             self.win.addch(15, i + 1, " ")
 
         self.win.addstr(15, 1, string, color)
-        self.outer.update_panels()
         self.menu_grab()
 
     def menu_grab(self):
@@ -125,7 +128,6 @@ class Menu:
             key = self.win.getkey()
             if key in ["r", "m"]:
                 self.panel.hide()
-                self.outer.update_panels()
                 self.outer.get_key()
             elif key == "q":
                 self.outer.leave()
@@ -133,7 +135,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]
@@ -160,22 +162,19 @@ class Menu:
                 # if not, don't allow to proceed and show an error message
                 cont = False
                 for x in self.outer.stack:
-                    if x.getStar():
+                    if x.starred:
                         cont = True
                         break
 
                 if cont:
                     self.outer.stack = [
-                        x for x in self.outer.stack if x.getStar()
+                        x for x in self.outer.stack if x.starred
                     ]
                     self.menu_print("Stars only!")
                 else:
                     self.menu_print("ERR: None are starred!", err=True)
-            elif key in ["h", "KEY_LEFT"]:
-                self.outer.obj.setIdx(len(self.outer.stack) - 1)
-                self.outer.get_key()
             elif key == "r":
-                self.outer.obj.setIdx(0)
+                self.outer.obj.index = 0
                 self.outer.get_key()
 
     def disp(self):
@@ -184,9 +183,8 @@ class Menu:
         and to continue
         """
         (mlines, mcols) = self.outer.win.getmaxyx()
-        self.win.mvwin(int(mlines / 2) - 9, int(mcols / 2) - 22)
+        self.win.mvwin(int(mlines / 2) - 9, int(mcols / 2) - 21)
         self.panel.show()
-        self.outer.update_panels()
 
         self.menu_grab()
 
@@ -200,53 +198,66 @@ 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 update_panels(self):
-        """Update panel and window contents"""
-        curses.panel.update_panels()
-        self.win.refresh()
+    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 leave(self):
         """Pickle stack before quitting"""
-        if self.obj.getIdx() + 1 == len(self.stack):
-            self.obj.setIdx(0)
+        if self.obj.index + 1 == len(self.stack):
+            self.obj.index = 0
 
         progress.dump(self.stack, runner.get_orig()[1])
         sys.exit(0)
 
     def nstarred(self):
         """Get total number of starred cards"""
-        return [card for card in self.stack if card.getStar()]
+        return [card for card in self.stack if card.starred]
 
     def disp_bar(self):
         """
         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:
             percent = "100"
         else:
             percent = str(
-                round(self.obj.getIdx() / (len(self.stack) - 1) * 100)
+                round(self.obj.index / (len(self.stack) - 1) * 100)
             ).zfill(2)
 
         # Print yellow if starred
-        if self.current_card().getStar():
+        if self.current_card().starred:
             star_color = curses.color_pair(3)
         else:
             star_color = curses.color_pair(1)
@@ -257,10 +268,10 @@ class Display:
         bar_end = (
             f"] [{len(self.nstarred())}/{str(len(self.stack))} starred] "
             f"[{percent}% ("
-            f"{str(self.obj.getIdx()).zfill(len(str(len(self.stack))))}"
+            f"{str(self.obj.index).zfill(len(str(len(self.stack))))}"
             f"/{str(len(self.stack))})] ["
-            f"{self.headers[self.current_card().getSide()]} ("
-            f"{str(int(self.current_card().getSide()) + 1)})]"
+            f"{self.headers[self.current_card().side]} ("
+            f"{str(int(self.current_card().side) + 1)})]"
         )
 
         # Put it all togethor
@@ -269,7 +280,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,30 +298,30 @@ 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.getIdx() + 1).zfill(len(str(len(self.stack))))
-        if self.current_card().getSide() == 0:
-            top = (
-                num_done + " | " + self.headers[self.current_card().getSide()]
-            )
+        num_done = str(self.obj.index + 1).zfill(len(str(len(self.stack))))
+        if self.current_card().side == 0:
+            top = num_done + " | " + self.headers[self.current_card().side]
         else:
             top = (
                 num_done
                 + " | "
-                + self.headers[self.current_card().getSide()]
+                + self.headers[self.current_card().side]
                 + ' | "'
-                + str(self.current_card().getFront())
+                + 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="…"),
@@ -318,13 +329,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(
@@ -332,35 +340,34 @@ class Display:
                 width=self.wrap_width(),
             ),
         )
-        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"""
-        return self.stack[self.obj.getIdx()]
+        return self.stack[self.obj.index]
 
     def get_key(self):
         """
         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()
             elif key in ["h", "KEY_LEFT"]:
                 self.obj.back()
-                self.current_card().setSide(0)
+                self.current_card().side = 0
                 self.disp_card()
             elif key in ["l", "KEY_RIGHT"]:
-                if self.obj.getIdx() + 1 == len(self.stack):
+                if self.obj.index + 1 == len(self.stack):
                     self.menu_obj.disp()
                 else:
                     self.obj.forward(self.stack)
-                    self.current_card().setSide(0)
+                    self.current_card().side = 0
                     self.disp_card()
             elif key in ["j", "k", "KEY_UP", "KEY_DOWN"]:
                 self.current_card().flip()
@@ -369,12 +376,12 @@ class Display:
                 self.current_card().toggleStar()
                 self.disp_card()
             elif key in ["0", "^", "KEY_HOME"]:
-                self.obj.setIdx(0)
-                self.current_card().setSide(0)
+                self.obj.index = 0
+                self.current_card().side = 0
                 self.disp_card()
             elif key in ["$", "KEY_END"]:
-                self.obj.setIdx(len(self.stack) - 1)
-                self.current_card().setSide(0)
+                self.obj.index = len(self.stack) - 1
+                self.current_card().side = 0
                 self.disp_card()
             elif key in ["H", "?"]:
                 self.help_obj.disp()
@@ -396,7 +403,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()):
@@ -406,7 +412,7 @@ class Display:
 
         for _ in nstarred:
             for i, card in enumerate(nstarred):
-                term = card.getFront()
+                term = card.front
                 if len(term) > 18:
                     term = term + "…"
                 self.win.addstr(2 + i, left, term)