a first draft of the ncurses viewer
authorMichael Göhler <somebody.here@gmx.de>
Thu, 28 Aug 2014 23:41:42 +0000 (01:41 +0200)
committerMichael Göhler <somebody.here@gmx.de>
Fri, 29 Aug 2014 08:53:14 +0000 (10:53 +0200)
include/viewer.h [new file with mode: 0644]
viewer.c [new file with mode: 0644]

diff --git a/include/viewer.h b/include/viewer.h
new file mode 100644 (file)
index 0000000..89837ec
--- /dev/null
@@ -0,0 +1,24 @@
+#if !defined( VIEWER_H )
+#define VIEWER_H
+
+#define CP_WHITE  1 // 255
+#define CP_BLUE   2 // 123
+#define CP_RED    3 // 213
+#define CP_YELLOW 4 // 208
+
+static short white_ramp[24] = { 16, 232, 233, 234, 235, 236,
+                               237, 238, 239, 240, 241, 242,
+                               244, 245, 246, 247, 248, 249,
+                               250, 251, 252, 253, 254, 255 };
+
+static short blue_ramp[24]  = { 16,  17,  17,  18,  18,  19,
+                                19,  20,  20,  21,  27,  32,
+                                33,  38,  39,  44,  45,  45,
+                                81,  81,  51,  51, 123, 123 };
+
+static short red_ramp[24]   = { 16,  52,  52,  53,  53,  89,
+                                89,  90,  90, 126, 127, 127,
+                               163, 163, 164, 164, 200, 200,
+                               201, 201, 207, 207, 213, 213 };
+
+#endif // !defined( VIEWER_H )
diff --git a/viewer.c b/viewer.c
new file mode 100644 (file)
index 0000000..8e5e741
--- /dev/null
+++ b/viewer.c
@@ -0,0 +1,159 @@
+#include <ncurses.h>
+#include <stdlib.h>
+
+#include "include/parser.h"
+#include "include/viewer.h"
+
+int ncurses_display(deck_t *deck, int notrans, int nofade) {
+
+    int c = 0;          // char
+    int colors = 0;     // amount of colors supported
+    int fade = 0;       // disable color fading by default
+    int trans = -1;     // enable transparency if term supports it
+    int max_lines = 0;  // max lines per slide
+    int max_cols = 0;   // max columns per line
+
+    // header line 1 is displayed at the top
+    int bar_top = (deck->headers > 0) ? 1 : 0;
+    // header line 2 and 3 are displayed at the bottom
+    int bar_bottom = (deck->headers > 1) ? 1 : 0;
+
+    slide_t *slide = deck->slide;
+    line_t *line;
+
+    while(slide) {
+        // set max_lines if line count exceeded
+        max_lines = (slide->lines > max_lines) ? slide->lines : max_lines;
+        line = slide->line;
+        while(line) {
+            // set max_cols if length exceeded
+            max_cols = (line->length > max_cols) ? line->length : max_cols;
+            line = line->next;
+        }
+        slide = slide->next;
+    }
+
+    if((max_cols > COLS) ||
+       (max_lines + bar_top + bar_bottom + 2 > LINES)) {
+
+        fprintf(stderr, "Error: Terminal size %ix%i to small. Need at least %ix%i.\n",
+            COLS, LINES, max_cols, max_lines + bar_top + bar_bottom + 2);
+        return(1);
+    }
+
+    // replace stdin with current tty if markdown input was piped
+    freopen("/dev/tty", "rw", stdin);
+
+    // init ncurses
+    initscr();
+
+    // disable cursor
+    curs_set(0);
+
+    // disable output of keyboard typing
+    noecho();
+
+    // make getch() process one char at a time
+    cbreak();
+
+    // enable arrow keys
+    keypad(stdscr,TRUE);
+
+    // set colors
+    if(has_colors() == TRUE) {
+        start_color();
+        use_default_colors();
+
+        if(!notrans) trans = 0; // 0 is black
+
+        if(COLORS == 256) {
+            // 256 color mode
+            init_pair(CP_WHITE, 255, trans);
+            init_pair(CP_BLUE, 123, trans);
+            init_pair(CP_RED, 213, trans);
+            init_pair(CP_YELLOW, 208, trans);
+
+            // enable color fading
+            if(!nofade) fade = 1;
+        } else {
+
+            // 8 color mode
+            init_pair(CP_WHITE, 7, trans);
+            init_pair(CP_BLUE, 4, trans);
+            init_pair(CP_RED, 1, trans);
+            init_pair(CP_YELLOW, 3, trans);
+        }
+
+        colors = 1;
+    }
+
+    // set background color of main window
+    if(colors)
+        wbkgd(stdscr, COLOR_PAIR(CP_YELLOW));
+
+    // setup header
+    if(bar_top) {
+        //TODO move cursor to calculated indentation
+        wmove(stdscr, 0, 1);
+        //TODO add text to header
+        wprintw(stdscr, "header");
+    }
+
+    // setup footer
+    if(bar_bottom) {
+        //TODO move cursor to calculated indentation
+        wmove(stdscr, LINES - 1, 1);
+        //TODO add text to footer
+        wprintw(stdscr, "footer");
+    }
+
+    // setup main window
+    WINDOW *content = newwin(LINES - bar_top - bar_bottom, COLS, 0, 0 + bar_top);
+    if(colors)
+        wbkgd(content, COLOR_PAIR(CP_WHITE));
+
+    slide = deck->slide;
+    while(slide) {
+        // fade out
+        // print header / footer
+        // print lines
+        // fade in
+
+        // wait for user input
+        c = getch();
+
+        // evaluate user input
+        switch(c) {
+
+            // show previous slide
+            case KEY_UP:
+            case KEY_LEFT:
+            case KEY_BACKSPACE:
+            case 'h':
+            case 'k':
+                if(slide->prev)
+                    slide = slide->prev;
+                break;
+
+            // show next slide
+            case KEY_DOWN:
+            case KEY_RIGHT:
+            case KEY_ENTER:
+            case 'j':
+            case 'l':
+                if(slide->next)
+                    slide = slide->next;
+                break;
+
+            // quit
+            case 'q':
+                slide = (void*)0;
+                break;
+        }
+    }
+
+    endwin();
+
+    return(0);
+}
+