discover/grub2: Allow to separate the --id argument using a space char
[petitboot] / ui / ncurses / nc-textscreen.c
index 3b0d01d9910d1a60d809d6a77607112dee251b78..0be201644fac26a6ec57f301f719858e0d4a4624 100644 (file)
@@ -24,7 +24,9 @@
 #include <talloc/talloc.h>
 #include <types/types.h>
 #include <log/log.h>
+#include <fold/fold.h>
 #include <util/util.h>
+#include <i18n/i18n.h>
 
 #include "nc-cui.h"
 #include "nc-textscreen.h"
@@ -39,14 +41,17 @@ struct text_screen *text_screen_from_scr(struct nc_scr *scr)
 
 void text_screen_draw(struct text_screen *screen)
 {
-       int max_y, i;
+       int max_y, max_x, i, len;
 
        max_y = getmaxy(screen->scr.sub_ncw);
+       max_x = getmaxx(screen->scr.sub_ncw) - 1;
 
        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]);
+       for (i = screen->scroll_y; i < max_y; i++) {
+               len = strncols(screen->lines[i]) > max_x ? max_x : -1;
+               mvwaddnstr(screen->scr.sub_ncw, i, 1, screen->lines[i], len);
+       }
 
        wrefresh(screen->scr.sub_ncw);
 }
@@ -54,7 +59,8 @@ void text_screen_draw(struct text_screen *screen)
 static void text_screen_scroll(struct text_screen *screen, int key)
 {
        int win_lines = getmaxy(screen->scr.sub_ncw);
-       int delta;
+       int win_cols = getmaxx(screen->scr.sub_ncw) - 1;
+       int delta, len, i;
 
        if (key == KEY_UP)
                delta = -1;
@@ -71,12 +77,16 @@ static void text_screen_scroll(struct text_screen *screen, int key)
        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]);
+               i = screen->scroll_y + win_lines - 1;
+               len = strncols(screen->lines[i]) > win_cols ? win_cols : -1;
+               mvwaddnstr(screen->scr.sub_ncw, win_lines - 1, 1,
+                               screen->lines[i], len);
        } else if (delta < 0) {
-               mvwaddstr(screen->scr.sub_ncw, 0, 1,
-                               screen->lines[screen->scroll_y]);
+               i = screen->scroll_y;
+               len = strncols(screen->lines[i]) > win_cols ? win_cols : -1;
+               mvwaddnstr(screen->scr.sub_ncw, 0, 1, screen->lines[i], len);
        }
 
        wrefresh(screen->scr.sub_ncw);
@@ -87,7 +97,22 @@ 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);
+       screen->lines = talloc_array(screen, const char *,
+                       screen->n_alloc_lines);
+}
+
+static void __text_screen_append_line(struct text_screen *screen,
+               const char *line)
+{
+       if (screen->n_lines == screen->n_alloc_lines) {
+               screen->n_alloc_lines *= 2;
+               screen->lines = talloc_realloc(screen, screen->lines,
+                                               const char *,
+                                               screen->n_alloc_lines);
+       }
+
+       screen->lines[screen->n_lines] = line;
+       screen->n_lines++;
 }
 
 void text_screen_append_line(struct text_screen *screen, const char *fmt, ...)
@@ -103,16 +128,24 @@ void text_screen_append_line(struct text_screen *screen, const char *fmt, ...)
                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);
-       }
+       __text_screen_append_line(screen, line);
+}
 
-       screen->lines[screen->n_lines] = line;
-       screen->n_lines++;
+static int text_screen_fold_cb(void *arg, const char *buf, int len)
+{
+       struct text_screen *screen = arg;
+
+       buf = len ? talloc_strndup(screen->lines, buf, len) : "";
+       __text_screen_append_line(screen, buf);
+
+       return 0;
 }
 
+void text_screen_set_text(struct text_screen *screen, const char *text)
+{
+       fold_text(text, getmaxx(screen->scr.sub_ncw) - 1, text_screen_fold_cb,
+                       screen);
+}
 
 void text_screen_process_key(struct nc_scr *scr, int key)
 {
@@ -120,12 +153,18 @@ void text_screen_process_key(struct nc_scr *scr, int key)
 
        switch (key) {
        case 'x':
+       case 27: /* esc */
                screen->on_exit(screen->cui);
                break;
        case KEY_DOWN:
        case KEY_UP:
                text_screen_scroll(screen, key);
                break;
+       case 'h':
+               if (screen->help_text)
+                       cui_show_help(screen->cui, screen->help_title,
+                                       screen->help_text);
+               break;
        default:
                break;
        }
@@ -142,8 +181,23 @@ struct nc_scr *text_screen_scr(struct text_screen *screen)
        return &screen->scr;
 }
 
+void text_screen_set_help(struct text_screen *screen, const char *title,
+               const struct help_text *text)
+{
+       screen->help_title = title;
+       screen->help_text = text;
+       screen->scr.frame.help = _("x=exit, h=help");
+}
+
 static int text_screen_post(struct nc_scr *scr)
 {
+       struct text_screen *screen = text_screen_from_scr(scr);
+
+       if (screen->need_update) {
+               text_screen_draw(screen);
+               screen->need_update = false;
+       }
+
        nc_scr_frame_draw(scr);
        redrawwin(scr->main_ncw);
        wrefresh(scr->main_ncw);
@@ -157,11 +211,16 @@ void text_screen_init(struct text_screen *screen, struct cui *cui,
                        cui, text_screen_process_key,
                        text_screen_post, NULL, text_screen_resize);
 
+       /* this will establish our array of lines */
+       screen->lines = NULL;
+       text_screen_clear(screen);
+
        screen->cui = cui;
        screen->on_exit = on_exit;
+       screen->need_update = false;
 
        screen->scr.frame.ltitle = talloc_strdup(screen, title);
        screen->scr.frame.rtitle = NULL;
-       screen->scr.frame.help = "x=exit";
+       screen->scr.frame.help = _("x=exit");
        scrollok(screen->scr.sub_ncw, true);
 }