]> git.armaanb.net Git - lightcards.git/blob - lightcards/display.py
Add proper text wrapping and truncation
[lightcards.git] / lightcards / display.py
1 # Display card output and retreive input
2 # Armaan Bhojwani 2021
3
4 import curses
5 from random import shuffle
6 import sys
7 import textwrap
8
9
10 def disp_bar(stdscr, stack, headers, obj):
11     (mlines, mcols) = stdscr.getmaxyx()
12     if len(stack) <= 1:
13         percent = "100"
14     else:
15         percent = str(round(obj.getIdx() / (len(stack) - 1) * 100)).zfill(3)
16
17     curses.init_pair(1, curses.COLOR_CYAN, 0)
18     stdscr.insstr(mlines - 1, 0,
19                   "[" +
20                   stack[obj.getIdx()].printStar() +
21                   "] [" +
22                   percent +
23                   "% (" +
24                   str(obj.getIdx() + 1) +
25                   "/" +
26                   str(len(stack)) +
27                   ")]" +
28                   " [" +
29                   headers[obj.getSide()] +
30                   "]", curses.color_pair(1))
31
32
33 def disp_menu(stdscr, stack, headers, idx):
34     stdscr.clear()
35     curses.init_pair(1, curses.COLOR_CYAN, 0)
36     curses.init_pair(2, curses.COLOR_RED, 0)
37     stdscr.addstr("Good job, you've completed a round!\n\n",
38                   curses.color_pair(1))
39     stdscr.addstr("Choose one of the following options:\n" +
40                   "[r]: restart\n" +
41                   "[s]: restart with starred only\n" +
42                   "[u]: restart and unstar all\n" +
43                   "[z]: restart and shuffle cards\n" +
44                   "[q]: quit")
45     while True:
46         key = stdscr.getkey()
47         if key == "q":
48             sys.exit(0)
49         elif key == "r":
50             idx.setIdx(0)
51             get_key(stdscr, stack, headers, idx)
52         elif key == "u":
53             idx.setIdx(0)
54             for x in stack:
55                 x.unStar()
56             get_key(stdscr, stack, headers, idx)
57         elif key == "s":
58             cont = False
59             for x in stack:
60                 if x.getStar():
61                     cont = True
62
63             if cont:
64                 idx.setIdx(0)
65                 stack = [x for x in stack if x.getStar()]
66                 get_key(stdscr, stack, headers, idx)
67             else:
68                 stdscr.clear()
69                 stdscr.addstr("ERR: Stack empty. Choose another option\n\n",
70                               curses.color_pair(2))
71                 disp_menu(stdscr, stack, headers, idx)
72         elif key == "z":
73             idx.setIdx(0)
74             shuffle(stack)
75             get_key(stdscr, stack, headers, idx)
76
77
78 def disp_card(stdscr, stack, headers, obj):
79     stdscr.clear()
80     (mlines, mcols) = stdscr.getmaxyx()
81     if obj.getIdx() == len(stack):
82         disp_menu(stdscr, stack, headers, obj)
83     else:
84         if obj.getSide() == 0:
85             top = headers[obj.getSide()] + "; " + str(obj.getIdx() + 1)
86         else:
87             top = headers[obj.getSide()] + "; " + str(obj.getIdx() + 1) + \
88                 "; " + str(stack[obj.getIdx()][0])
89
90         header_width = mcols
91         if mcols > 80:
92             header_width = 80
93
94         stdscr.addstr(textwrap.shorten(top, width=header_width,
95                                        placeholder="…"), curses.A_BOLD)
96
97         # Add horizontal line
98         lin_width = mcols
99         if len(top) < mcols:
100             lin_width = len(top)
101         stdscr.hline(1, 0, curses.ACS_HLINE, lin_width)
102
103         # Show current side
104         wrap_width = mcols
105         if mcols > 80:
106             wrap_width = 80
107         stdscr.hline(curses.ACS_HLINE, lin_width)
108         stdscr.addstr(2, 0, textwrap.fill(stack[obj.getIdx()][obj.getSide()],
109                                           width=wrap_width))
110     disp_bar(stdscr, stack, headers, obj)
111
112
113 def get_key(stdscr, stack, headers, idx):
114     curses.curs_set(0)
115     disp_card(stdscr, stack, headers, idx)
116
117     while True:
118         key = stdscr.getkey()
119         if key == "q":
120             sys.exit(0)
121         elif key in ["l", "KEY_LEFT"]:
122             idx.forward(stack)
123             idx.setSide(0)
124             disp_card(stdscr, stack, headers, idx)
125         elif key in ["h", "KEY_RIGHT"]:
126             idx.back()
127             idx.setSide(0)
128             disp_card(stdscr, stack, headers,  idx)
129         elif key in ["j", "k", "KEY_UP", "KEY_DOWN"]:
130             idx.flip()
131             disp_card(stdscr, stack, headers, idx)
132         elif key in ["i", "/"]:
133             stack[idx.getIdx()].toggleStar()
134             disp_card(stdscr, stack, headers, idx)
135         elif key in ["0", "^", "KEY_HOME"]:
136             idx.setIdx(0)
137             disp_card(stdscr, stack, headers, idx)
138         elif key in ["$", "KEY_END"]:
139             idx.setIdx(len(stack) - 1)
140             disp_card(stdscr, stack, headers, idx)