1 # Display card output and retreive input
5 from random import shuffle
9 from . import lightcards
13 def __init__(self, stack, headers, obj):
15 self.headers = headers
18 def run(self, stdscr):
20 curses.curs_set(0) # Hide cursor
21 curses.init_pair(1, curses.COLOR_CYAN, 0)
22 curses.init_pair(2, curses.COLOR_RED, 0)
23 curses.init_pair(3, curses.COLOR_YELLOW, 0)
28 Display the statusbar at the bottom of the screen with progress, star
29 status, and card side.
31 (mlines, mcols) = self.win.getmaxyx()
33 # Calculate percent done
34 if len(self.stack) <= 1:
37 percent = str(round(self.obj.getIdx() /
38 len(self.stack) * 100)).zfill(2)
40 # Print yellow if starred
41 if self.stack[self.obj.getIdx()].getStar():
42 star_color = curses.color_pair(3)
44 star_color = curses.color_pair(1)
46 # Create bar component
48 bar_middle = self.stack[self.obj.getIdx()].printStar()
49 bar_end = "] [" + percent + "% (" + \
50 str(self.obj.getIdx() + 1).zfill(len(str(len(self.stack)))) + \
51 "/" + str(len(self.stack)) + ")] [" + \
52 self.headers[self.obj.getSide()] + " (" + \
53 str(self.obj.getSide() + 1) + ")]"
56 self.win.addstr(mlines - 1, 0, bar_start, curses.color_pair(1))
57 self.win.addstr(bar_middle, star_color)
58 self.win.insstr(bar_end, curses.color_pair(1))
60 def menu_print(self, string, err=False):
61 (mlines, mcols) = self.win.getmaxyx()
64 color = curses.color_pair(2)
66 color = curses.color_pair(1)
67 self.disp_menu(keygrab=False)
68 self.win.addstr("\n\n" + string, color)
73 key = self.win.getkey()
75 if len(self.stack) == self.obj.getIdx():
77 elif len(self.stack) < self.obj.getIdx():
81 self.stack = lightcards.get_orig()[1]
82 self.menu_print("Stack reset!")
84 [x.unStar() for x in self.stack]
85 self.menu_print("All unstarred!")
87 [x.star() for x in self.stack]
88 self.menu_print("All starred!")
92 "self.stack reversed!")
95 self.menu_print("Stack shuffled!")
98 x[0], x[1] = x[1], x[0]
99 (self.headers[0], self.headers[1]) = (self.headers[1],
101 self.menu_print("Cards flipped!")
103 # Check if there are any starred cards before proceeding, and
104 # if not, don't allow to proceed and show an error message
112 self.stack = [x for x in self.stack if x.getStar()]
113 self.menu_print("Stars only!")
115 self.menu_print("ERR: None are starred!", err=True)
116 elif key in ["h", "KEY_LEFT"]:
117 self.obj.setIdx(len(self.stack) - 1)
123 def disp_menu(self, keygrab=True):
125 Display a menu once the end of the deck has been reached, offering
126 multiple options on how to continue.
129 self.win.addstr("LIGHTCARDS MENU", curses.color_pair(1) +
131 self.win.hline(1, 0, curses.ACS_HLINE, 15)
132 self.win.addstr(2, 0, "[y]: reset stack to original state\n" +
133 "[z]: shuffle stack\n" +
134 "[f]: flip all cards in stack\n" +
135 "[t]: reverse stack order\n" +
136 "[u]: unstar all\n" +
138 "[s]: update stack to include starred only\n\n" +
145 def wrap_width(self):
146 (mlines, mcols) = self.win.getmaxyx()
154 Display the contents of the card
155 Shows a header, a horizontal line, and the contents of the current
159 (mlines, mcols) = self.win.getmaxyx()
160 if self.obj.getIdx() == len(self.stack):
163 # If on the back of the card, show the content of the front side in
165 num_done = str(self.obj.getIdx() +
166 1).zfill(len(str(len(self.stack))))
167 if self.obj.getSide() == 0:
168 top = num_done + " | " + self.headers[self.obj.getSide()]
170 top = num_done + " | " + self.headers[self.obj.getSide()] + \
171 " | \"" + str(self.stack[self.obj.getIdx()][0]) + "\""
176 self.win.addstr(textwrap.shorten(top, width=header_width,
177 placeholder="…"), curses.A_BOLD)
179 # Add horizontal line
180 lin_width = header_width
181 if len(top) < header_width:
183 self.win.hline(1, 0, curses.ACS_HLINE, lin_width)
186 self.win.addstr(2, 0, textwrap.fill(
187 self.stack[self.obj.getIdx()][self.obj.getSide()],
188 width=self.wrap_width()))
192 """Display help screen"""
194 self.win.addstr("LIGHTCARDS HELP", curses.color_pair(1) +
196 self.win.hline(1, 0, curses.ACS_HLINE, 15)
197 self.win.addstr(2, 0, textwrap.fill(
198 "Welcome to lightcards. Here are some keybindings to get you " +
199 "started:", width=self.wrap_width()) +
200 "\n\nh, left previous card\n" +
201 "l, right next card\n" +
202 "j, k, up, down flip card\n" +
204 "0, ^, home go to the start of the deck\n" +
205 "$, end go to the end of the deck\n" +
206 "H, ? open this screen\n" +
207 "e open the input file in $EDITOR\n" +
208 "m open the control menu\n\n" +
210 "More information can be found in the man page, " +
211 "or by running `lightcards --help`.",
212 width=self.wrap_width()) +
213 "\n\nPress [q], [H], or [?] to go back.")
215 key = self.win.getkey()
216 if key in ["q", "H", "?"]:
221 Display a card and wait for the input.
222 Used as a general way of getting back into the card flow from a menu
227 key = self.win.getkey()
230 elif key in ["l", "KEY_RIGHT"]:
231 self.obj.forward(self.stack)
234 elif key in ["h", "KEY_LEFT"]:
238 elif key in ["j", "k", "KEY_UP", "KEY_DOWN"]:
241 elif key in ["i", "/"]:
242 self.stack[self.obj.getIdx()].toggleStar()
244 elif key in ["0", "^", "KEY_HOME"]:
248 elif key in ["$", "KEY_END"]:
249 self.obj.setIdx(len(self.stack) - 1)
252 elif key in ["H", "?"]:
258 (self.headers, self.stack) = lightcards.reparse()