X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=viewer.c;h=2d64b4eb43d4c81c89fdec22af4950363fe43045;hb=31eb213da6e050f77ccaf59626484a03f1b95af6;hp=d6b5c8539bbb80ff4b6fbf641d69a57d22dea743;hpb=70ce4d7eba90b5da6f9187eb217794db6f153888;p=smdp.git diff --git a/viewer.c b/viewer.c index d6b5c85..2d64b4e 100644 --- a/viewer.c +++ b/viewer.c @@ -1,5 +1,6 @@ #include #include +#include // strchr #include #include "include/parser.h" @@ -23,11 +24,13 @@ static short red_ramp[24] = { 16, 52, 52, 53, 53, 89, int ncurses_display(deck_t *deck, int notrans, int nofade) { int c = 0; // char + int l = 0; // line number 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 + int offset; // text offset // header line 1 is displayed at the top int bar_top = (deck->headers > 0) ? 1 : 0; @@ -113,18 +116,31 @@ int ncurses_display(deck_t *deck, int notrans, int nofade) { // setup header if(bar_top) { - //TODO move cursor to calculated indentation - wmove(stdscr, 0, 1); - //TODO add text to header - wprintw(stdscr, "header"); + line = deck->header; + offset = next_blank(line->text, 0) + 1; + // add text to header + mvwprintw(stdscr, + 0, (COLS - line->length + offset) / 2, + "%s", &line->text->text[offset]); } // setup footer if(bar_bottom) { - //TODO move cursor to calculated indentation - wmove(stdscr, LINES - 1, 1); - //TODO add text to footer - wprintw(stdscr, "footer"); + line = deck->header->next; + offset = next_blank(line->text, 0) + 1; + // add text to left footer + mvwprintw(stdscr, + LINES - 1, 3, + "%s", &line->text->text[offset]); + + if(deck->headers > 2) { + line = deck->header->next->next; + offset = next_blank(line->text, 0) + 1; + // add text to right footer + mvwprintw(stdscr, + LINES - 1, COLS - line->length + offset - 3, + "%s", &line->text->text[offset]); + } } // make header + fooder visible @@ -140,8 +156,15 @@ int ncurses_display(deck_t *deck, int notrans, int nofade) { // clear main window werase(content); - //TODO print lines - wprintw(content, "content"); + line = slide->line; + l = 0; + + // print lines + while(line) { + add_line(content, l, (COLS - max_cols) / 2, line, max_cols); + line = line->next; + l++; + } // make content visible wrefresh(content); @@ -150,6 +173,9 @@ int ncurses_display(deck_t *deck, int notrans, int nofade) { if(fade) fade_in(content, trans, colors); + // re-enable fading after any undefined key press + if(COLORS == 256 && !nofade) fade = 1; + // wait for user input c = getch(); @@ -159,7 +185,9 @@ int ncurses_display(deck_t *deck, int notrans, int nofade) { // show previous slide case KEY_UP: case KEY_LEFT: - case KEY_BACKSPACE: + case 8: // BACKSPACE (ascii) + case 127: // BACKSPACE (xterm) + case 263: // BACKSPACE (getty) case 'h': case 'k': if(slide->prev) @@ -169,7 +197,8 @@ int ncurses_display(deck_t *deck, int notrans, int nofade) { // show next slide case KEY_DOWN: case KEY_RIGHT: - case KEY_ENTER: + case '\n': // ENTER + case ' ': // SPACE case 'j': case 'l': if(slide->next) @@ -182,6 +211,11 @@ int ncurses_display(deck_t *deck, int notrans, int nofade) { fade = 0; slide = (void*)0; break; + + default: + // disable fading on undefined key press + fade = 0; + break; } // fade out @@ -194,6 +228,154 @@ int ncurses_display(deck_t *deck, int notrans, int nofade) { return(0); } +void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols) { + int i = 0; // increment + char *c; // char pointer for iteration + char *special = "\\*_"; // list of interpreted chars + cstack_t *stack = cstack_init(); + + if(line->text->text) { + int offset = 0; // text offset + offset = next_nonblank(line->text, 0); + + // IS_CODE + if(CHECK_BIT(line->bits, IS_CODE)) { + + // set static offset for code + offset = CODE_INDENT; + + // reverse color for code blocks + wattron(window, A_REVERSE); + + // print whole lines + mvwprintw(window, + y, x, + "%s", &line->text->text[offset]); + + // IS_QUOTE + } else if(CHECK_BIT(line->bits, IS_QUOTE)) { + //TODO replace greater sign with color block + + //FIXME remove dummy print code + mvwprintw(window, + y, x, + "%s", &line->text->text[offset]); + + } else { + + // IF_H1 || IF_H2 + if(CHECK_BIT(line->bits, IS_H1) || CHECK_BIT(line->bits, IS_H2)) { + + // set headline color + wattron(window, COLOR_PAIR(CP_BLUE)); + + // enable underline for H1 + if(CHECK_BIT(line->bits, IS_H1)) + wattron(window, A_UNDERLINE); + + // skip hashes + while(line->text->text[offset] == '#') + offset = next_word(line->text, offset); + + // print whole lines + mvwprintw(window, + y, x, + "%s", &line->text->text[offset]); + + wattroff(window, A_UNDERLINE); + + } else { + // move the cursor in position + wmove(window, y, x); + + // for each char in line + c = line->text->text; + while(*c) { + + // if char is in special char list + if(strchr(special, *c)) { + + // closing special char (or second backslash) + if(is_attron(stack, *c)) { + + switch(*c) { + // print escaped backslash + case '\\': + wprintw(window, "%c", *c); + break; + // disable highlight + case '*': + wattron(window, COLOR_PAIR(CP_WHITE)); + break; + // disable underline + case '_': + wattroff(window, A_UNDERLINE); + break; + } + + // remove top special char from stack + (stack->pop)(stack); + + // treat special as regular char + } else if(is_attron(stack, '\\')) { + wprintw(window, "%c", *c); + + // remove backslash from stack + (stack->pop)(stack); + + // opening special char + } else { + switch(*c) { + // enable highlight + case '*': + wattron(window, COLOR_PAIR(CP_RED)); + break; + // enable underline + case '_': + wattron(window, A_UNDERLINE); + break; + // do nothing for backslashes + } + + // push special char to stack + (stack->push)(stack, *c); + } + + } else { + // print regular char + wprintw(window, "%c", *c); + } + + c++; + } + + //TODO pop stack until empty + } + } + + // fill rest off line with spaces + for(i = getcurx(window) - x; i < max_cols; i++) + wprintw(window, "%s", " "); + + // reset to default color + wattron(window, COLOR_PAIR(CP_WHITE)); + wattroff(window, A_UNDERLINE); + wattroff(window, A_REVERSE); + } + + (stack->delete)(stack); +} + +int is_attron(cstack_t *stack, char c) { + // test if char is on top of stack + if(stack->head >= 0) { + if((stack->top)(stack) == c) { + return 1; + } + } + return 0; +} + void fade_out(WINDOW *window, int trans, int colors) { int i; // increment if(colors) {