]> git.armaanb.net Git - lightcards.git/blobdiff - lightcards/display.py
Restructure menu and help into seperate classes
[lightcards.git] / lightcards / display.py
index 58a9055004760f1c13d640ea85465d3ba84b313a..d0c42fa6d04f45fc0503e9245af93c5e73cb722e 100644 (file)
@@ -10,6 +10,187 @@ import textwrap
 from . import runner, progress
 
 
 from . import runner, progress
 
 
+def panel_create(x, y):
+    """Create popup panels to a certain scale"""
+    win = curses.newwin(x, y)
+    panel = curses.panel.new_panel(win)
+    win.erase()
+    return (win, panel)
+
+
+class Help:
+    def __init__(self, outer):
+        """Initialize help screen"""
+        self.outer = outer
+        (self.win, self.panel) = panel_create(20, 52)
+        self.panel.top()
+        self.panel.hide()
+        self.win.clear()
+
+        text = [
+            "Welcome to runner. Here are some keybindings",
+            "to get you started:",
+            "",
+            "h, left          previous card",
+            "l, right         next card",
+            "j, k, up, down   flip card",
+            "i, /             star card",
+            "0, ^, home       go to the start of the deck",
+            "$, end           go to the end of the deck",
+            "H, ?             open this screen",
+            "e                open the input file in $EDITOR",
+            "m                open the control menu",
+            "",
+            "More information can be found in the man page, or",
+            "by running `lightcards --help`.",
+            "",
+            "Press [H], or [?] to go back.",
+        ]
+
+        self.win.addstr(
+            1, 1, "LIGHTCARDS HELP", curses.color_pair(1) + curses.A_BOLD
+        )
+        self.win.hline(2, 1, curses.ACS_HLINE, 15)
+
+        for t in enumerate(text):
+            self.win.addstr(t[0] + 3, 1, t[1])
+
+        self.win.box()
+
+    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.panel.show()
+
+        while True:
+            key = self.win.getkey()
+            if key == "q":
+                self.outer.leave()
+            elif key in ["H", "?"]:
+                self.panel.hide()
+                self.outer.get_key()
+
+
+class Menu:
+    def __init__(self, outer):
+        """Initialize the menu with content"""
+        self.outer = outer
+        (self.win, self.panel) = panel_create(17, 44)
+        self.panel.top()
+        self.panel.hide()
+
+        self.win.addstr(
+            1, 1, "LIGHTCARDS MENU", curses.color_pair(1) + curses.A_BOLD
+        )
+        self.win.hline(2, 1, curses.ACS_HLINE, 15)
+        text = [
+            "[y]: reset stack to original state",
+            "[a]: alphabetize stack",
+            "[z]: shuffle stack",
+            "[f]: flip all cards in stack",
+            "[t]: reverse stack order",
+            "[u]: unstar all",
+            "[d]: star all",
+            "[s]: update stack to include starred only",
+            "",
+            "[r]: restart",
+            "[m]: close menu",
+        ]
+
+        for t in enumerate(text):
+            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"""
+        if err:
+            color = curses.color_pair(2)
+        else:
+            color = curses.color_pair(1)
+
+        for i in range(42):
+            self.win.addch(15, i + 1, " ")
+
+        self.win.addstr(15, 1, string, color)
+        self.outer.update_panels()
+        self.menu_grab()
+
+    def menu_grab(self):
+        """Grab keypresses on the menu screen"""
+        while True:
+            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()
+            elif key == "y":
+                self.outer.stack = runner.get_orig()[1]
+                self.menu_print("Stack reset!")
+            elif key == "a":
+                self.outer.stack.sort()
+                self.menu_print("Stack alphabetized!")
+            elif key == "u":
+                [x.unStar() for x in self.outer.stack]
+                self.menu_print("All unstarred!")
+            elif key == "d":
+                [x.star() for x in self.outer.stack]
+                self.menu_print("All starred!")
+            elif key == "t":
+                self.outer.stack.reverse()
+                self.menu_print("Stack reversed!")
+            elif key == "z":
+                shuffle(self.outer.stack)
+                self.menu_print("Stack shuffled!")
+            elif key == "f":
+                for x in self.outer.stack:
+                    x.front, x.back = x.back, x.front
+                (self.outer.headers[0], self.outer.headers[1]) = (
+                    self.outer.headers[1],
+                    self.outer.headers[0],
+                )
+                self.menu_print("Cards flipped!")
+            elif key == "s":
+                # Check if there are any starred cards before proceeding, and
+                # if not, don't allow to proceed and show an error message
+                cont = False
+                for x in self.outer.stack:
+                    if x.getStar():
+                        cont = True
+                        break
+
+                if cont:
+                    self.outer.stack = [
+                        x for x in self.outer.stack if x.getStar()
+                    ]
+                    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.get_key()
+
+    def disp(self):
+        """
+        Display a menu offering multiple options on how to manipulate the deck
+        and to continue
+        """
+        (mlines, mcols) = self.outer.win.getmaxyx()
+        self.win.mvwin(int(mlines / 2) - 9, int(mcols / 2) - 22)
+        self.panel.show()
+        self.outer.update_panels()
+
+        self.menu_grab()
+
+
 class Display:
     def __init__(self, stack, headers, obj):
         self.stack = stack
 class Display:
     def __init__(self, stack, headers, obj):
         self.stack = stack
@@ -26,20 +207,13 @@ class Display:
         curses.init_pair(2, curses.COLOR_RED, -1)
         curses.init_pair(3, curses.COLOR_YELLOW, -1)
 
         curses.init_pair(2, curses.COLOR_RED, -1)
         curses.init_pair(3, curses.COLOR_YELLOW, -1)
 
-        (self.main_win, self.main_panel) = self.panel_create(mlines, mcols)
-        self.menu_init()
-        self.help_init()
+        (self.main_win, self.main_panel) = panel_create(mlines, mcols)
+        self.menu_obj = Menu(self)
+        self.help_obj = Help(self)
 
         self.get_key()
 
 
         self.get_key()
 
-    def panel_create(self, x, y):
-        """Create popup panels to a certain scale"""
-        win = curses.newwin(x, y)
-        panel = curses.panel.new_panel(win)
-        win.erase()
-        return (win, panel)
-
-    def panel_up(self):
+    def update_panels(self):
         """Update panel and window contents"""
         curses.panel.update_panels()
         self.win.refresh()
         """Update panel and window contents"""
         curses.panel.update_panels()
         self.win.refresh()
@@ -52,7 +226,7 @@ class Display:
         progress.dump(self.stack, runner.get_orig()[1])
         sys.exit(0)
 
         progress.dump(self.stack, runner.get_orig()[1])
         sys.exit(0)
 
-    def ntotal(self):
+    def nstarred(self):
         """Get total number of starred cards"""
         return [card for card in self.stack if card.getStar()]
 
         """Get total number of starred cards"""
         return [card for card in self.stack if card.getStar()]
 
@@ -61,7 +235,7 @@ class Display:
         Display the statusbar at the bottom of the screen with progress, star
         status, and card side.
         """
         Display the statusbar at the bottom of the screen with progress, star
         status, and card side.
         """
-        (mlines, mcols) = self.win.getmaxyx()
+        (mlines, _) = self.win.getmaxyx()
 
         # Calculate percent done
         if len(self.stack) <= 1:
 
         # Calculate percent done
         if len(self.stack) <= 1:
@@ -81,7 +255,7 @@ class Display:
         bar_start = "["
         bar_middle = self.current_card().printStar()
         bar_end = (
         bar_start = "["
         bar_middle = self.current_card().printStar()
         bar_end = (
-            f"] [{len(self.ntotal())}/{str(len(self.stack))} starred] "
+            f"] [{len(self.nstarred())}/{str(len(self.stack))} starred] "
             f"[{percent}% ("
             f"{str(self.obj.getIdx()).zfill(len(str(len(self.stack))))}"
             f"/{str(len(self.stack))})] ["
             f"[{percent}% ("
             f"{str(self.obj.getIdx()).zfill(len(str(len(self.stack))))}"
             f"/{str(len(self.stack))})] ["
@@ -99,120 +273,6 @@ class Display:
             curses.color_pair(1),
         )
 
             curses.color_pair(1),
         )
 
-    def menu_print(self, string, err=False):
-        """Print messages on the menu screen"""
-        if err:
-            color = curses.color_pair(2)
-        else:
-            color = curses.color_pair(1)
-
-        for i in range(42):
-            self.menu_win.addch(15, i + 1, " ")
-
-        self.menu_win.addstr(15, 1, string, color)
-        self.panel_up()
-        self.menu_grab()
-
-    def menu_grab(self):
-        """Grab keypresses on the menu screen"""
-        while True:
-            key = self.win.getkey()
-            if key in ["r", "m"]:
-                self.menu_panel.hide()
-                self.panel_up()
-                self.get_key()
-            elif key == "q":
-                self.leave()
-            elif key == "y":
-                self.stack = runner.get_orig()[1]
-                self.menu_print("Stack reset!")
-            elif key == "a":
-                self.stack.sort()
-                self.menu_print("Stack alphabetized!")
-            elif key == "u":
-                [x.unStar() for x in self.stack]
-                self.menu_print("All unstarred!")
-            elif key == "d":
-                [x.star() for x in self.stack]
-                self.menu_print("All starred!")
-            elif key == "t":
-                self.stack.reverse()
-                self.menu_print("Stack reversed!")
-            elif key == "z":
-                shuffle(self.stack)
-                self.menu_print("Stack shuffled!")
-            elif key == "f":
-                for x in self.stack:
-                    x[0], x[1] = x[1], x[0]
-                (self.headers[0], self.headers[1]) = (
-                    self.headers[1],
-                    self.headers[0],
-                )
-                self.menu_print("Cards flipped!")
-            elif key == "s":
-                # Check if there are any starred cards before proceeding, and
-                # if not, don't allow to proceed and show an error message
-                cont = False
-                for x in self.stack:
-                    if x.getStar():
-                        cont = True
-                        break
-
-                if cont:
-                    self.stack = [x for x in self.stack if x.getStar()]
-                    self.menu_print("Stars only!")
-                else:
-                    self.menu_print("ERR: None are starred!", err=True)
-            elif key in ["h", "KEY_LEFT"]:
-                self.obj.setIdx(len(self.stack) - 1)
-                self.get_key()
-            elif key == "r":
-                self.obj.setIdx(0)
-                self.get_key()
-
-    def menu_init(self):
-        """Initialize the menu with content"""
-        (self.menu_win, self.menu_panel) = self.panel_create(17, 44)
-        self.menu_panel.top()
-        self.menu_panel.hide()
-
-        self.menu_win.addstr(
-            1, 1, "LIGHTCARDS MENU", curses.color_pair(1) + curses.A_BOLD
-        )
-        self.menu_win.hline(2, 1, curses.ACS_HLINE, 15)
-        text = [
-            "[y]: reset stack to original state",
-            "[a]: alphabetize stack",
-            "[z]: shuffle stack",
-            "[f]: flip all cards in stack",
-            "[t]: reverse stack order",
-            "[u]: unstar all",
-            "[d]: star all",
-            "[s]: update stack to include starred only",
-            "",
-            "[r]: restart",
-            "[m]: close menu",
-        ]
-
-        for t in enumerate(text):
-            self.menu_win.addstr(t[0] + 3, 1, t[1])
-
-        self.menu_win.box()
-        self.panel_up()
-
-    def disp_menu(self, keygrab=True):
-        """
-        Display a menu offering multiple options on how to manipulate the deck
-        and to continue
-        """
-        (mlines, mcols) = self.win.getmaxyx()
-        self.menu_win.mvwin(int(mlines / 2) - 9, int(mcols / 2) - 22)
-        self.menu_panel.show()
-        self.panel_up()
-
-        if keygrab:
-            self.menu_grab()
-
     def wrap_width(self):
         """Calculate the width at which the body text should wrap"""
         (_, mcols) = self.win.getmaxyx()
     def wrap_width(self):
         """Calculate the width at which the body text should wrap"""
         (_, mcols) = self.win.getmaxyx()
@@ -272,60 +332,11 @@ class Display:
                 width=self.wrap_width(),
             ),
         )
                 width=self.wrap_width(),
             ),
         )
-        self.panel_up()
+        self.update_panels()
         self.disp_bar()
         self.disp_sidebar()
         self.win.hline(mlines - 2, 0, 0, mcols)
 
         self.disp_bar()
         self.disp_sidebar()
         self.win.hline(mlines - 2, 0, 0, mcols)
 
-    def help_init(self):
-        """Initialize help screen"""
-        (self.help_win, self.help_panel) = self.panel_create(20, 52)
-        self.help_panel.top()
-        self.help_panel.hide()
-        self.help_win.clear()
-        self.help_win.addstr(
-            1, 1, "LIGHTCARDS HELP", curses.color_pair(1) + curses.A_BOLD
-        )
-        self.help_win.hline(2, 1, curses.ACS_HLINE, 15)
-        text = [
-            "Welcome to runner. Here are some keybindings",
-            "to get you started:",
-            "",
-            "h, left          previous card",
-            "l, right         next card",
-            "j, k, up, down   flip card",
-            "i, /             star card",
-            "0, ^, home       go to the start of the deck",
-            "$, end           go to the end of the deck",
-            "H, ?             open this screen",
-            "e                open the input file in $EDITOR",
-            "m                open the control menu",
-            "",
-            "More information can be found in the man page, or",
-            "by running `lightcards --help`.",
-            "",
-            "Press [H], or [?] to go back.",
-        ]
-
-        for t in enumerate(text):
-            self.help_win.addstr(t[0] + 3, 1, t[1])
-
-        self.help_win.box()
-
-    def disp_help(self):
-        """Display help screen"""
-        (mlines, mcols) = self.win.getmaxyx()
-        self.help_win.mvwin(int(mlines / 2) - 10, int(mcols / 2) - 26)
-        self.panel_up()
-        self.help_panel.show()
-        while True:
-            key = self.help_win.getkey()
-            if key == "q":
-                self.leave()
-            elif key in ["H", "?"]:
-                self.help_panel.hide()
-                self.get_key()
-
     def current_card(self):
         """Get current card object"""
         return self.stack[self.obj.getIdx()]
     def current_card(self):
         """Get current card object"""
         return self.stack[self.obj.getIdx()]
@@ -346,7 +357,7 @@ class Display:
                 self.disp_card()
             elif key in ["l", "KEY_RIGHT"]:
                 if self.obj.getIdx() + 1 == len(self.stack):
                 self.disp_card()
             elif key in ["l", "KEY_RIGHT"]:
                 if self.obj.getIdx() + 1 == len(self.stack):
-                    self.disp_menu()
+                    self.menu_obj.disp()
                 else:
                     self.obj.forward(self.stack)
                     self.current_card().setSide(0)
                 else:
                     self.obj.forward(self.stack)
                     self.current_card().setSide(0)
@@ -366,9 +377,9 @@ class Display:
                 self.current_card().setSide(0)
                 self.disp_card()
             elif key in ["H", "?"]:
                 self.current_card().setSide(0)
                 self.disp_card()
             elif key in ["H", "?"]:
-                self.disp_help()
+                self.help_obj.disp()
             elif key == "m":
             elif key == "m":
-                self.disp_menu()
+                self.menu_obj.disp()
             elif key == "e":
                 (self.headers, self.stack) = runner.reparse()
                 self.get_key()
             elif key == "e":
                 (self.headers, self.stack) = runner.reparse()
                 self.get_key()
@@ -387,27 +398,25 @@ class Display:
         self.win.vline(0, mcols - 20, 0, mlines - 2)
         self.win.hline(1, left, 0, mlines)
 
         self.win.vline(0, mcols - 20, 0, mlines - 2)
         self.win.hline(1, left, 0, mlines)
 
-        i = 0
-        # TODO: Fix this, some off by one error
-        newntotal = self.ntotal()
-        if mlines - 5 < len(self.ntotal()):
-            newntotal = self.ntotal()[: mlines - 4]
-        elif mlines - 5 == len(self.ntotal()):
-            newntotal = self.ntotal()[: mlines - 3]
+        nstarred = self.nstarred()
+        if mlines - 5 < len(self.nstarred()):
+            nstarred = self.nstarred()[: mlines - 4]
+        elif mlines - 5 == len(self.nstarred()):
+            nstarred = self.nstarred()[: mlines - 3]
 
 
-        for _ in newntotal:
-            for i, card in enumerate(newntotal):
+        for _ in nstarred:
+            for i, card in enumerate(nstarred):
                 term = card.getFront()
                 if len(term) > 18:
                     term = term + "…"
                 self.win.addstr(2 + i, left, term)
                 term = card.getFront()
                 if len(term) > 18:
                     term = term + "…"
                 self.win.addstr(2 + i, left, term)
-            if not newntotal == self.ntotal():
+            if not nstarred == self.nstarred():
                 self.win.addstr(
                     mlines - 3,
                     left,
                 self.win.addstr(
                     mlines - 3,
                     left,
-                    f"({len(self.ntotal()) - len(newntotal)} more)",
+                    f"({len(self.nstarred()) - len(nstarred)} more)",
                 )
                 break
 
                 )
                 break
 
-        if len(self.ntotal()) == 0:
+        if len(self.nstarred()) == 0:
             self.win.addstr(2, left, "None starred")
             self.win.addstr(2, left, "None starred")