commit e8ff69142a73deeb3406ea19cb752cebfc4c7527
parent 03fc2cb2391f4138bed4538bab3ab610045d83bd
Author: hhvn <dev@hhvn.uk>
Date: Sun, 31 Oct 2021 10:54:30 +0000
ui.c hirc.h hist.c: width aware printing
Diffstat:
M | hirc.h | | | 3 | ++- |
M | hist.c | | | 2 | +- |
M | ui.c | | | 97 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------- |
3 files changed, 81 insertions(+), 21 deletions(-)
diff --git a/hirc.h b/hirc.h
@@ -99,7 +99,8 @@ void ui_draw_buflist(void);
int ui_buflist_count(int *ret_servers, int *ret_channels);
void ui_buflist_select(int num);
int ui_get_pair(short fg, short bg);
-int ui_wprintc(WINDOW *window, char *format, ...);
+int ui_wprintc(struct Window *window, int lines, char *format, ...);
+int ui_strlenc(struct Window *window, char *s, int *lines);
void ui_select(struct Server *server, struct Channel *channel);
void ui_error_(char *file, int line, char *format, ...);
#define ui_error(format, ...) ui_error_(__FILE__, __LINE__, format, __VA_ARGS__);
diff --git a/hist.c b/hist.c
@@ -100,7 +100,7 @@ hist_add(struct Server *server, struct HistInfo *histinfo, struct Nick *from,
// XXX
if (options & HIST_SHOW) {
- ui_wprintc(windows[Win_main].window, "!%lld :%s %s\n", (long long)new->timestamp, nick_strprefix(new->from), new->raw);
+ ui_wprintc(&windows[Win_main], 0, "!%lld :%s %s\n", (long long)new->timestamp, nick_strprefix(new->from), new->raw);
windows[Win_main].redraw = 1;
}
diff --git a/ui.c b/ui.c
@@ -387,13 +387,14 @@ ui_draw_buflist(void) {
}
int
-ui_wprintc(WINDOW *window, char *format, ...) {
+ui_wprintc(struct Window *window, int lines, char *format, ...) {
char str[1024], *s;
va_list ap;
int ret;
attr_t curattr;
int temp; /* used only for wattr_get,
because ncurses is dumb */
+ int cc, lc, elc;
char colourbuf[2][3];
int colours[2];
int colour = 0;
@@ -403,18 +404,21 @@ ui_wprintc(WINDOW *window, char *format, ...) {
int italic = 0;
va_start(ap, format);
- if ((ret = vsnprintf(str, sizeof(str), format, ap)) < 0) {
- va_end(ap);
+ ret = vsnprintf(str, sizeof(str), format, ap);
+ va_end(ap);
+ if (ret < 0)
return ret;
- }
- for (s = str; s && *s; s++) {
+ if (lines < 0)
+ ui_strlenc(window, str, &elc);
+
+ for (ret = cc = lc = 0, s = str; s && *s; s++) {
switch (*s) {
case 2: /* ^B */
if (bold)
- wattroff(window, A_BOLD);
+ wattroff(window->window, A_BOLD);
else
- wattron(window, A_BOLD);
+ wattron(window->window, A_BOLD);
bold = bold ? 0 : 1;
break;
case 3: /* ^C */
@@ -449,15 +453,15 @@ ui_wprintc(WINDOW *window, char *format, ...) {
colours[0] = colourbuf[0][0] ? atoi(colourbuf[0]) : 99;
colours[1] = colourbuf[1][0] ? atoi(colourbuf[1]) : 99;
- wattr_get(window, &curattr, &temp, NULL);
- wattr_set(window, curattr, ui_get_pair(colours[0], colours[1]), NULL);
+ wattr_get(window->window, &curattr, &temp, NULL);
+ wattr_set(window->window, curattr, ui_get_pair(colours[0], colours[1]), NULL);
colour = 1;
break;
case 9: /* ^I */
if (italic)
- wattroff(window, A_ITALIC);
+ wattroff(window->window, A_ITALIC);
else
- wattron(window, A_ITALIC);
+ wattron(window->window, A_ITALIC);
italic = italic ? 0 : 1;
break;
case 15: /* ^O */
@@ -468,39 +472,94 @@ ui_wprintc(WINDOW *window, char *format, ...) {
italic = 0;
/* Setting A_NORMAL turns everything off,
* without using 5 different attroffs */
- wattrset(window, A_NORMAL);
+ wattrset(window->window, A_NORMAL);
break;
case 18: /* ^R */
if (reverse)
- wattroff(window, A_REVERSE);
+ wattroff(window->window, A_REVERSE);
else
- wattron(window, A_REVERSE);
+ wattron(window->window, A_REVERSE);
reverse = reverse ? 0 : 1;
break;
case 21: /* ^U */
if (underline)
- wattroff(window, A_UNDERLINE);
+ wattroff(window->window, A_UNDERLINE);
else
- wattron(window, A_UNDERLINE);
+ wattron(window->window, A_UNDERLINE);
underline = underline ? 0 : 1;
break;
default:
- waddch(window, *s);
+ cc++;
+ if (lines > 0 && lc >= lines)
+ goto end;
+ if (!lines || lines > 0 || (lines < 0 && lc >= elc + lines)) {
+ waddch(window->window, *s);
+ ret++;
+ }
+ if (cc == window->w) {
+ lc++;
+ cc = 0;
+ }
break;
}
}
+end:
colour = 0;
bold = 0;
underline =0;
reverse = 0;
italic = 0;
- wattrset(window, A_NORMAL);
+ wattrset(window->window, A_NORMAL);
- va_end(ap);
return ret;
}
+int
+ui_strlenc(struct Window *window, char *s, int *lines) {
+ int ret, cc, lc;
+
+ for (ret = cc = lc = 0; s && *s; s++) {
+ switch (*s) {
+ case 2: /* ^B */
+ case 9: /* ^I */
+ case 15: /* ^O */
+ case 18: /* ^R */
+ case 21: /* ^U */
+ break;
+ case 3: /* ^C */
+ if (*s && isdigit(*(s+1)))
+ s += 1;
+ if (*s && isdigit(*(s+1)))
+ s += 1;
+ if (*s && *(s+1) == ',' && isdigit(*(s+2)))
+ s += 2;
+ if (*s && *(s-1) == ',' && isdigit(*(s+1)))
+ s += 1;
+ break;
+ default:
+ cc++;
+ ret++;
+ if (cc == window->w) {
+ lc++;
+ cc = 0;
+ }
+ break;
+ }
+ }
+
+ if (lines)
+ *lines = lc;
+ return ret;
+}
+
+void
+ui_draw_main(void) {
+ int y;
+
+ y = windows[Win_main].h - 1;
+}
+
void
ui_select(struct Server *server, struct Channel *channel) {
selected.channel = channel;