8e5e74172d19f62e3a0761ced84d912d04502178
[smdp.git] / viewer.c
1 #include <ncurses.h>
2 #include <stdlib.h>
3
4 #include "include/parser.h"
5 #include "include/viewer.h"
6
7 int ncurses_display(deck_t *deck, int notrans, int nofade) {
8
9     int c = 0;          // char
10     int colors = 0;     // amount of colors supported
11     int fade = 0;       // disable color fading by default
12     int trans = -1;     // enable transparency if term supports it
13     int max_lines = 0;  // max lines per slide
14     int max_cols = 0;   // max columns per line
15
16     // header line 1 is displayed at the top
17     int bar_top = (deck->headers > 0) ? 1 : 0;
18     // header line 2 and 3 are displayed at the bottom
19     int bar_bottom = (deck->headers > 1) ? 1 : 0;
20
21     slide_t *slide = deck->slide;
22     line_t *line;
23
24     while(slide) {
25         // set max_lines if line count exceeded
26         max_lines = (slide->lines > max_lines) ? slide->lines : max_lines;
27         line = slide->line;
28         while(line) {
29             // set max_cols if length exceeded
30             max_cols = (line->length > max_cols) ? line->length : max_cols;
31             line = line->next;
32         }
33         slide = slide->next;
34     }
35
36     if((max_cols > COLS) ||
37        (max_lines + bar_top + bar_bottom + 2 > LINES)) {
38
39         fprintf(stderr, "Error: Terminal size %ix%i to small. Need at least %ix%i.\n",
40             COLS, LINES, max_cols, max_lines + bar_top + bar_bottom + 2);
41         return(1);
42     }
43
44     // replace stdin with current tty if markdown input was piped
45     freopen("/dev/tty", "rw", stdin);
46
47     // init ncurses
48     initscr();
49
50     // disable cursor
51     curs_set(0);
52
53     // disable output of keyboard typing
54     noecho();
55
56     // make getch() process one char at a time
57     cbreak();
58
59     // enable arrow keys
60     keypad(stdscr,TRUE);
61
62     // set colors
63     if(has_colors() == TRUE) {
64         start_color();
65         use_default_colors();
66
67         if(!notrans) trans = 0; // 0 is black
68
69         if(COLORS == 256) {
70             // 256 color mode
71             init_pair(CP_WHITE, 255, trans);
72             init_pair(CP_BLUE, 123, trans);
73             init_pair(CP_RED, 213, trans);
74             init_pair(CP_YELLOW, 208, trans);
75
76             // enable color fading
77             if(!nofade) fade = 1;
78         } else {
79
80             // 8 color mode
81             init_pair(CP_WHITE, 7, trans);
82             init_pair(CP_BLUE, 4, trans);
83             init_pair(CP_RED, 1, trans);
84             init_pair(CP_YELLOW, 3, trans);
85         }
86
87         colors = 1;
88     }
89
90     // set background color of main window
91     if(colors)
92         wbkgd(stdscr, COLOR_PAIR(CP_YELLOW));
93
94     // setup header
95     if(bar_top) {
96         //TODO move cursor to calculated indentation
97         wmove(stdscr, 0, 1);
98         //TODO add text to header
99         wprintw(stdscr, "header");
100     }
101
102     // setup footer
103     if(bar_bottom) {
104         //TODO move cursor to calculated indentation
105         wmove(stdscr, LINES - 1, 1);
106         //TODO add text to footer
107         wprintw(stdscr, "footer");
108     }
109
110     // setup main window
111     WINDOW *content = newwin(LINES - bar_top - bar_bottom, COLS, 0, 0 + bar_top);
112     if(colors)
113         wbkgd(content, COLOR_PAIR(CP_WHITE));
114
115     slide = deck->slide;
116     while(slide) {
117         // fade out
118         // print header / footer
119         // print lines
120         // fade in
121
122         // wait for user input
123         c = getch();
124
125         // evaluate user input
126         switch(c) {
127
128             // show previous slide
129             case KEY_UP:
130             case KEY_LEFT:
131             case KEY_BACKSPACE:
132             case 'h':
133             case 'k':
134                 if(slide->prev)
135                     slide = slide->prev;
136                 break;
137
138             // show next slide
139             case KEY_DOWN:
140             case KEY_RIGHT:
141             case KEY_ENTER:
142             case 'j':
143             case 'l':
144                 if(slide->next)
145                     slide = slide->next;
146                 break;
147
148             // quit
149             case 'q':
150                 slide = (void*)0;
151                 break;
152         }
153     }
154
155     endwin();
156
157     return(0);
158 }
159