diff options
author | nicm <nicm> | 2020-05-16 16:02:24 +0000 |
---|---|---|
committer | nicm <nicm> | 2020-05-16 16:02:24 +0000 |
commit | d67245c734c9c600ad6d186570a1230aa21b80c8 (patch) | |
tree | 9e71286a88716251c09d3dd2c2b323074f9f40ff /screen-write.c | |
parent | 472d77fd0f4af8431267473df3cf109030760fa1 (diff) | |
download | rtmux-d67245c734c9c600ad6d186570a1230aa21b80c8.tar.gz rtmux-d67245c734c9c600ad6d186570a1230aa21b80c8.tar.bz2 rtmux-d67245c734c9c600ad6d186570a1230aa21b80c8.zip |
Add a customize mode where keys and options may be browsed and changed,
includes adding a brief description of each option. Bound to "C" by
default.
Diffstat (limited to 'screen-write.c')
-rw-r--r-- | screen-write.c | 92 |
1 files changed, 91 insertions, 1 deletions
diff --git a/screen-write.c b/screen-write.c index 909b8531..9571cbec 100644 --- a/screen-write.c +++ b/screen-write.c @@ -360,7 +360,97 @@ screen_write_strlen(const char *fmt, ...) return (size); } -/* Write simple string (no UTF-8 or maximum length). */ +/* Write string wrapped over lines. */ +int +screen_write_text(struct screen_write_ctx *ctx, u_int cx, u_int width, + u_int lines, int more, const struct grid_cell *gcp, const char *fmt, ...) +{ + struct screen *s = ctx->s; + va_list ap; + char *tmp; + u_int cy = s->cy, i, end, next, idx = 0, at, left; + struct utf8_data *text; + struct grid_cell gc; + + memcpy(&gc, gcp, sizeof gc); + + va_start(ap, fmt); + xvasprintf(&tmp, fmt, ap); + va_end(ap); + + text = utf8_fromcstr(tmp); + free(tmp); + + left = (cx + width) - s->cx; + for (;;) { + /* Find the end of what can fit on the line. */ + at = 0; + for (end = idx; text[end].size != 0; end++) { + if (text[end].size == 1 && text[end].data[0] == '\n') + break; + if (at + text[end].width > left) + break; + at += text[end].width; + } + + /* + * If we're on a space, that's the end. If not, walk back to + * try and find one. + */ + if (text[end].size == 0) + next = end; + else if (text[end].size == 1 && text[end].data[0] == '\n') + next = end + 1; + else if (text[end].size == 1 && text[end].data[0] == ' ') + next = end + 1; + else { + for (i = end; i > idx; i--) { + if (text[i].size == 1 && text[i].data[0] == ' ') + break; + } + if (i != idx) { + next = i + 1; + end = i; + } else + next = end; + } + + /* Print the line. */ + for (i = idx; i < end; i++) { + utf8_copy(&gc.data, &text[i]); + screen_write_cell(ctx, &gc); + } + + /* If at the bottom, stop. */ + idx = next; + if (s->cy == cy + lines - 1 || text[idx].size == 0) + break; + + screen_write_cursormove(ctx, cx, s->cy + 1, 0); + left = width; + } + + /* + * Fail if on the last line and there is more to come or at the end, or + * if the text was not entirely consumed. + */ + if ((s->cy == cy + lines - 1 && (!more || s->cx == cx + width)) || + text[idx].size != 0) { + free(text); + return (0); + } + free(text); + + /* + * If no more to come, move to the next line. Otherwise, leave on + * the same line (except if at the end). + */ + if (!more || s->cx == cx + width) + screen_write_cursormove(ctx, cx, s->cy + 1, 0); + return (1); +} + +/* Write simple string (no maximum length). */ void screen_write_puts(struct screen_write_ctx *ctx, const struct grid_cell *gcp, const char *fmt, ...) |