X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=viewer.c;h=6db88b95319a7e2edf0b93b3056bfb1effa74a64;hb=a3d9a0cc14a6c55cb62e808b1c43d3b7a487faf1;hp=82d8d9928dc7722fc9b048587f02b8c724702b15;hpb=338e24c049fcf14fd1d2e8ac3807177f049eec2e;p=smdp.git diff --git a/viewer.c b/viewer.c index 82d8d99..6db88b9 100644 --- a/viewer.c +++ b/viewer.c @@ -4,7 +4,7 @@ * faded in 256 color mode. * Copyright (C) 2014 Michael Goehler * - * This file is part of mpd. + * This file is part of mdp. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,14 +29,15 @@ #include "include/viewer.h" +// color ramp for fading from black to color 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, + 19, 20, 20, 21, 27, 33, + 32, 39, 38, 45, 44, 44, 81, 81, 51, 51, 123, 123 }; static short red_ramp[24] = { 16, 52, 52, 53, 53, 89, @@ -44,10 +45,28 @@ static short red_ramp[24] = { 16, 52, 52, 53, 53, 89, 163, 163, 164, 164, 200, 200, 201, 201, 207, 207, 213, 213 }; -int ncurses_display(deck_t *deck, int notrans, int nofade) { +// color ramp for fading from white to color +static short white_ramp_invert[24] = { 15, 255, 254, 254, 252, 251, + 250, 249, 248, 247, 246, 245, + 243, 242, 241, 240, 239, 238, + 237, 236, 235, 234, 233, 232}; + +static short blue_ramp_invert[24] = { 15, 231, 231, 195, 195, 159, + 159, 123, 123, 87, 51, 44, + 45, 38, 39, 32, 33, 33, + 26, 26, 27, 27, 21, 21}; + +static short red_ramp_invert[24] = { 15, 231, 231, 224, 224, 225, + 225, 218, 218, 219, 212, 213, + 206, 207, 201, 200, 199, 199, + 198, 198, 197, 197, 196, 196}; + +int ncurses_display(deck_t *deck, int notrans, int nofade, int invert) { int c = 0; // char + int i = 0; // iterate int l = 0; // line number + int sc = 1; // slide count int colors = 0; // amount of colors supported int fade = 0; // disable color fading by default int trans = -1; // enable transparency if term supports it @@ -57,8 +76,9 @@ int ncurses_display(deck_t *deck, int notrans, int nofade) { // 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; + // header line 2 is displayed at the bottom + // anyway we display the slide number at the bottom + int bar_bottom = 1; slide_t *slide = deck->slide; line_t *line; @@ -78,24 +98,18 @@ int ncurses_display(deck_t *deck, int notrans, int nofade) { // set locale to display UTF-8 correctly in ncurses setlocale(LC_CTYPE, ""); - // replace stdin with current tty if markdown input was piped - freopen("/dev/tty", "rw", stdin); - // init ncurses initscr(); 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", + fprintf(stderr, "Error: Terminal size %ix%i too small. Need at least %ix%i.\n", COLS, LINES, max_cols, max_lines + bar_top + bar_bottom + 2); endwin(); return(1); } - // replace stdin with current tty if markdown input was piped - freopen("/dev/tty", "rw", stdin); - // disable cursor curs_set(0); @@ -113,21 +127,47 @@ int ncurses_display(deck_t *deck, int notrans, int nofade) { start_color(); use_default_colors(); - if(notrans) trans = 0; // 0 is black - + // 256 color mode if(COLORS == 256) { - // 256 color mode - init_pair(CP_WHITE, 255, trans); - init_pair(CP_BLUE, 123, trans); - init_pair(CP_RED, 213, trans); + + if(notrans) { + if(invert) { + trans = 15; // white in 256 color mode + } else { + trans = 16; // black in 256 color mode + } + } + + if(invert) { + init_pair(CP_WHITE, 232, trans); + init_pair(CP_BLUE, 21, trans); + init_pair(CP_RED, 196, trans); + } else { + 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; + + // 8 color mode } else { - // 8 color mode - init_pair(CP_WHITE, 7, trans); + if(notrans) { + if(invert) { + trans = 7; // white in 8 color mode + } else { + trans = 0; // black in 8 color mode + } + } + + if(invert) { + init_pair(CP_WHITE, 0, trans); + } else { + init_pair(CP_WHITE, 7, trans); + } init_pair(CP_BLUE, 4, trans); init_pair(CP_RED, 1, trans); init_pair(CP_YELLOW, 3, trans); @@ -140,39 +180,6 @@ int ncurses_display(deck_t *deck, int notrans, int nofade) { if(colors) wbkgd(stdscr, COLOR_PAIR(CP_YELLOW)); - // setup header - if(bar_top) { - 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 - //TODO display slide number in footer - if(bar_bottom) { - 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 - wrefresh(stdscr); - // setup main window WINDOW *content = newwin(LINES - bar_top - bar_bottom, COLS, 0 + bar_top, 0); if(colors) @@ -180,15 +187,46 @@ int ncurses_display(deck_t *deck, int notrans, int nofade) { slide = deck->slide; while(slide) { - // clear main window + // clear windows werase(content); + werase(stdscr); + + // always resize window in case terminal geometry has changed + wresize(content, LINES - bar_top - bar_bottom, COLS); + + // setup header + if(bar_top) { + 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(deck->headers > 1) { + 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]); + } + // add slide number to right footer + mvwprintw(stdscr, + LINES - 1, COLS - int_length(deck->slides) - int_length(sc) - 6, + "%d / %d", sc, deck->slides); + + // make header + fooder visible + wrefresh(stdscr); line = slide->line; l = 0; // print lines while(line) { - add_line(content, l, (COLS - max_cols) / 2, line, max_cols); + add_line(content, l, (COLS - max_cols) / 2, line, max_cols, colors); line = line->next; l++; } @@ -198,7 +236,7 @@ int ncurses_display(deck_t *deck, int notrans, int nofade) { // fade in if(fade) - fade_in(content, trans, colors); + fade_in(content, trans, colors, invert); // re-enable fading after any undefined key press if(COLORS == 256 && !nofade) fade = 1; @@ -207,6 +245,7 @@ int ncurses_display(deck_t *deck, int notrans, int nofade) { c = getch(); // evaluate user input + i = 0; switch(c) { // show previous slide @@ -217,8 +256,12 @@ int ncurses_display(deck_t *deck, int notrans, int nofade) { case 263: // BACKSPACE (getty) case 'h': case 'k': - if(slide->prev) + if(slide->prev) { slide = slide->prev; + sc--; + } else { + fade = 0; + } break; // show next slide @@ -228,8 +271,60 @@ int ncurses_display(deck_t *deck, int notrans, int nofade) { case ' ': // SPACE case 'j': case 'l': - if(slide->next) + if(slide->next) { slide = slide->next; + sc++; + } else { + fade = 0; + } + break; + + // show slide n + case '9': i++; + case '8': i++; + case '7': i++; + case '6': i++; + case '5': i++; + case '4': i++; + case '3': i++; + case '2': i++; + case '1': i++; + if(i <= deck->slides) { + while(sc != i) { + // search forward + if(sc < i) { + if(slide->next) { + slide = slide->next; + sc++; + } + // search backward + } else { + if(slide->prev) { + slide = slide->prev; + sc--; + } + } + } + } else { + // disable fading if slide n doesn't exist + fade = 0; + } + break; + + // show first slide + case KEY_HOME: + slide = deck->slide; + sc = 1; + break; + + // show last slide + case KEY_END: + for(i = sc; i <= deck->slides; i++) { + if(slide->next) { + slide = slide->next; + sc++; + } + } break; // quit @@ -247,7 +342,7 @@ int ncurses_display(deck_t *deck, int notrans, int nofade) { // fade out if(fade) - fade_out(content, trans, colors); + fade_out(content, trans, colors, invert); } endwin(); @@ -255,7 +350,7 @@ 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) { +void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols, int colors) { int i = 0; // increment char *c; // char pointer for iteration char *special = "\\*_"; // list of interpreted chars @@ -263,7 +358,6 @@ void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols) { if(line->text->text) { int offset = 0; // text offset - offset = next_nonblank(line->text, 0); // IS_CODE if(CHECK_BIT(line->bits, IS_CODE)) { @@ -285,7 +379,8 @@ void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols) { if(CHECK_BIT(line->bits, IS_H1) || CHECK_BIT(line->bits, IS_H2)) { // set headline color - wattron(window, COLOR_PAIR(CP_BLUE)); + if(colors) + wattron(window, COLOR_PAIR(CP_BLUE)); // enable underline for H1 if(CHECK_BIT(line->bits, IS_H1)) @@ -308,12 +403,17 @@ void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols) { // IS_QUOTE if(CHECK_BIT(line->bits, IS_QUOTE)) { - // print a reverse color block - wattron(window, A_REVERSE); - wprintw(window, "%s", " "); - wattroff(window, A_REVERSE); - wprintw(window, "%s", " "); - offset += 2; + while(line->text->text[offset] == '>') { + // print a reverse color block + wattron(window, A_REVERSE); + wprintw(window, "%s", " "); + wattroff(window, A_REVERSE); + wprintw(window, "%s", " "); + // find next quote or break + offset++; + if(line->text->text[offset] == ' ') + offset = next_word(line->text, offset); + } } // for each char in line @@ -333,7 +433,8 @@ void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols) { break; // disable highlight case '*': - wattron(window, COLOR_PAIR(CP_WHITE)); + if(colors) + wattron(window, COLOR_PAIR(CP_WHITE)); break; // disable underline case '_': @@ -356,7 +457,8 @@ void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols) { switch(*c) { // enable highlight case '*': - wattron(window, COLOR_PAIR(CP_RED)); + if(colors) + wattron(window, COLOR_PAIR(CP_RED)); break; // enable underline case '_': @@ -370,6 +472,10 @@ void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols) { } } else { + // remove backslash from stack + if((stack->top)(stack, '\\')) + (stack->pop)(stack); + // print regular char wprintw(window, "%c", *c); } @@ -380,17 +486,16 @@ void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols) { // pop stack until empty to prevent formated trailing spaces while(!(stack->empty)(stack)) { switch((stack->pop)(stack)) { - case '\\': - wprintw(window, "%c", '\\'); - break; // disable highlight case '*': - wattron(window, COLOR_PAIR(CP_WHITE)); + if(colors) + wattron(window, COLOR_PAIR(CP_WHITE)); break; // disable underline case '_': wattroff(window, A_UNDERLINE); break; + // do nothing for backslashes } } } @@ -401,7 +506,8 @@ void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols) { wprintw(window, "%s", " "); // reset to default color - wattron(window, COLOR_PAIR(CP_WHITE)); + if(colors) + wattron(window, COLOR_PAIR(CP_WHITE)); wattroff(window, A_UNDERLINE); wattroff(window, A_REVERSE); } @@ -409,35 +515,61 @@ void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols) { (stack->delete)(stack); } -void fade_out(WINDOW *window, int trans, int colors) { +void fade_out(WINDOW *window, int trans, int colors, int invert) { int i; // increment if(colors) { for(i = 22; i >= 0; i--) { - // darken color pairs - init_pair(CP_WHITE, white_ramp[i], trans); - init_pair(CP_BLUE, blue_ramp[i], trans); - init_pair(CP_RED, red_ramp[i], trans); + + // dim color pairs + if(invert) { + init_pair(CP_WHITE, white_ramp_invert[i], trans); + init_pair(CP_BLUE, blue_ramp_invert[i], trans); + init_pair(CP_RED, red_ramp_invert[i], trans); + } else { + init_pair(CP_WHITE, white_ramp[i], trans); + init_pair(CP_BLUE, blue_ramp[i], trans); + init_pair(CP_RED, red_ramp[i], trans); + } + // refresh window with new color wrefresh(window); + // delay for our eyes to recognize the change usleep(FADE_DELAY); } } } -void fade_in(WINDOW *window, int trans, int colors) { +void fade_in(WINDOW *window, int trans, int colors, int invert) { int i; // increment if(colors) { for(i = 0; i <= 23; i++) { - // lighten color pairs - init_pair(CP_WHITE, white_ramp[i], trans); - init_pair(CP_BLUE, blue_ramp[i], trans); - init_pair(CP_RED, red_ramp[i], trans); + + // brighten color pairs + if(invert) { + init_pair(CP_WHITE, white_ramp_invert[i], trans); + init_pair(CP_BLUE, blue_ramp_invert[i], trans); + init_pair(CP_RED, red_ramp_invert[i], trans); + } else { + init_pair(CP_WHITE, white_ramp[i], trans); + init_pair(CP_BLUE, blue_ramp[i], trans); + init_pair(CP_RED, red_ramp[i], trans); + } + // refresh window with new color wrefresh(window); + // delay for our eyes to recognize the change usleep(FADE_DELAY); } } } +int int_length (int val) { + int l = 1; + while(val > 9) { + l++; + val /= 10; + } + return l; +}