From 445f43743b73fbd63cccba7fa7ae890c907fe6dd Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Mon, 9 Dec 2013 11:30:19 +0800 Subject: ui/ncurses: Abstract text-screen code from sysinfo screen We want to implement help screens, which are very similar to the sysinfo screen - show a set of lines, and allow scrolling. This change splits the text-screen rendering code into a new nc-textinfo module. Signed-off-by: Jeremy Kerr --- ui/ncurses/nc-textscreen.c | 167 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 ui/ncurses/nc-textscreen.c (limited to 'ui/ncurses/nc-textscreen.c') diff --git a/ui/ncurses/nc-textscreen.c b/ui/ncurses/nc-textscreen.c new file mode 100644 index 0000000..3b0d01d --- /dev/null +++ b/ui/ncurses/nc-textscreen.c @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2013 IBM Corporation + * + * 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 + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include + +#include +#include +#include +#include + +#include "nc-cui.h" +#include "nc-textscreen.h" + +struct text_screen *text_screen_from_scr(struct nc_scr *scr) +{ + struct text_screen *text_screen; + assert(scr->sig == pb_text_screen_sig); + text_screen = container_of(scr, struct text_screen, scr); + return text_screen; +} + +void text_screen_draw(struct text_screen *screen) +{ + int max_y, i; + + max_y = getmaxy(screen->scr.sub_ncw); + + max_y = min(max_y, screen->scroll_y + screen->n_lines); + + for (i = screen->scroll_y; i < max_y; i++) + mvwaddstr(screen->scr.sub_ncw, i, 1, screen->lines[i]); + + wrefresh(screen->scr.sub_ncw); +} + +static void text_screen_scroll(struct text_screen *screen, int key) +{ + int win_lines = getmaxy(screen->scr.sub_ncw); + int delta; + + if (key == KEY_UP) + delta = -1; + else if (key == KEY_DOWN) + delta = 1; + else + return; + + if (screen->scroll_y + delta < 0) + return; + if (screen->scroll_y + delta + win_lines > screen->n_lines) + return; + + screen->scroll_y += delta; + wscrl(screen->scr.sub_ncw, delta); + + if (delta > 0) { + mvwaddstr(screen->scr.sub_ncw, win_lines - 1, 1, + screen->lines[screen->scroll_y+win_lines-1]); + } else if (delta < 0) { + mvwaddstr(screen->scr.sub_ncw, 0, 1, + screen->lines[screen->scroll_y]); + } + + wrefresh(screen->scr.sub_ncw); +} + +void text_screen_clear(struct text_screen *screen) +{ + talloc_free(screen->lines); + screen->n_lines = 0; + screen->n_alloc_lines = 16; + screen->lines = talloc_array(screen, char *, screen->n_alloc_lines); +} + +void text_screen_append_line(struct text_screen *screen, const char *fmt, ...) +{ + char *line; + va_list ap; + + if (fmt) { + va_start(ap, fmt); + line = talloc_vasprintf(screen->lines, fmt, ap); + va_end(ap); + } else { + line = ""; + } + + if (screen->n_lines == screen->n_alloc_lines) { + screen->n_alloc_lines *= 2; + screen->lines = talloc_realloc(screen, screen->lines, + char *, screen->n_alloc_lines); + } + + screen->lines[screen->n_lines] = line; + screen->n_lines++; +} + + +void text_screen_process_key(struct nc_scr *scr, int key) +{ + struct text_screen *screen = text_screen_from_scr(scr); + + switch (key) { + case 'x': + screen->on_exit(screen->cui); + break; + case KEY_DOWN: + case KEY_UP: + text_screen_scroll(screen, key); + break; + default: + break; + } +} + +static void text_screen_resize(struct nc_scr *scr) +{ + struct text_screen *screen = text_screen_from_scr(scr); + text_screen_draw(screen); +} + +struct nc_scr *text_screen_scr(struct text_screen *screen) +{ + return &screen->scr; +} + +static int text_screen_post(struct nc_scr *scr) +{ + nc_scr_frame_draw(scr); + redrawwin(scr->main_ncw); + wrefresh(scr->main_ncw); + return 0; +} + +void text_screen_init(struct text_screen *screen, struct cui *cui, + const char *title, void (*on_exit)(struct cui *)) +{ + nc_scr_init(&screen->scr, pb_text_screen_sig, 0, + cui, text_screen_process_key, + text_screen_post, NULL, text_screen_resize); + + screen->cui = cui; + screen->on_exit = on_exit; + + screen->scr.frame.ltitle = talloc_strdup(screen, title); + screen->scr.frame.rtitle = NULL; + screen->scr.frame.help = "x=exit"; + scrollok(screen->scr.sub_ncw, true); +} -- cgit v1.2.1