From 42210e079bcdea26261af577d0802fdc4c3d03b6 Mon Sep 17 00:00:00 2001 From: "C. McEnroe" Date: Wed, 5 Feb 2020 02:03:21 -0500 Subject: Reflow text on window resize --- ui.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 17 deletions(-) (limited to 'ui.c') diff --git a/ui.c b/ui.c index b764f84..12205cc 100644 --- a/ui.c +++ b/ui.c @@ -35,6 +35,9 @@ #include "chat.h" +// Annoying stuff from : +#undef lines + #ifndef A_ITALIC #define A_ITALIC A_UNDERLINE #endif @@ -43,16 +46,28 @@ #define RIGHT (COLS - 1) #define WINDOW_LINES (LINES - 2) -enum { - InputCols = 512, - PadLines = 512, -}; - static WINDOW *status; static WINDOW *input; +enum { BufferCap = 512 }; +struct Buffer { + time_t times[BufferCap]; + char *lines[BufferCap]; + size_t len; +}; +static_assert(!(BufferCap & (BufferCap - 1)), "BufferCap is power of two"); + +static void bufferPush(struct Buffer *buffer, time_t time, const char *line) { + size_t i = buffer->len++ % BufferCap; + free(buffer->lines[i]); + buffer->times[i] = time; + buffer->lines[i] = strdup(line); + if (!buffer->lines[i]) err(EX_OSERR, "strdup"); +} + struct Window { size_t id; + struct Buffer buffer; WINDOW *pad; enum Heat heat; int unread; @@ -89,17 +104,15 @@ static struct Window *windowFor(size_t id) { for (window = windows.head; window; window = window->next) { if (window->id == id) return window; } - window = malloc(sizeof(*window)); + window = calloc(1, sizeof(*window)); if (!window) err(EX_OSERR, "malloc"); window->id = id; - window->pad = newpad(PadLines, COLS); - window->heat = Cold; - window->unread = 0; - window->scroll = PadLines; - window->mark = true; + window->pad = newpad(BufferCap, COLS); scrollok(window->pad, true); - wmove(window->pad, PadLines - 1, 0); + wmove(window->pad, BufferCap - 1, 0); + window->scroll = BufferCap; + window->mark = true; windowAdd(window); return window; @@ -190,7 +203,7 @@ void uiInit(void) { colorInit(); status = newwin(1, COLS, 0, 0); - input = newpad(1, InputCols); + input = newpad(1, 512); keypad(input, true); nodelay(input, true); windows.active = windowFor(Network); @@ -380,9 +393,11 @@ static void wordWrap(WINDOW *win, const char *str) { } } -void uiWrite(size_t id, enum Heat heat, const time_t *time, const char *str) { - (void)time; +void uiWrite(size_t id, enum Heat heat, const time_t *src, const char *str) { struct Window *window = windowFor(id); + time_t clock = (src ? *src : time(NULL)); + bufferPush(&window->buffer, clock, str); + waddch(window->pad, '\n'); if (window->mark && heat > Cold) { if (!window->unread++) { @@ -406,6 +421,25 @@ void uiFormat( uiWrite(id, heat, time, buf); } +static void reflow(struct Window *window) { + werase(window->pad); + wmove(window->pad, BufferCap - 1, 0); + size_t len = window->buffer.len; + for (size_t i = (len > BufferCap ? len - BufferCap : 0); i < len; ++i) { + waddch(window->pad, '\n'); + wordWrap(window->pad, window->buffer.lines[i % BufferCap]); + } +} + +static void resize(void) { + // FIXME: Only reflow when COLS changes. + for (struct Window *window = windows.head; window; window = window->next) { + wresize(window->pad, BufferCap, COLS); + reflow(window); + } + statusUpdate(); +} + static void inputAdd(struct Style *style, const char *str) { size_t len; while (*str) { @@ -480,7 +514,7 @@ void uiShowNum(size_t num) { static void keyCode(int code) { switch (code) { - break; case KEY_RESIZE:; // TODO + break; case KEY_RESIZE: resize(); break; case KeyFocusIn: unmark(); break; case KeyFocusOut: windows.active->mark = true; break; case KeyPasteOn:; // TODO @@ -490,7 +524,7 @@ static void keyCode(int code) { static void keyMeta(wchar_t ch) { switch (ch) { - break; case L'm': uiWrite(windows.active->id, Cold, NULL, ""); + break; case L'm': waddch(windows.active->pad, '\n'); break; default: { if (ch >= L'0' && ch <= L'9') uiShowNum(ch - L'0'); } -- cgit 1.4.1 tgirl/commit/README?h=2.0&id=eb035896bd600c40723c31522212be5bd21bb79e&follow=1'>Add Homebrew LibreSSL paths to MakefileJune McEnroe 2018-08-08Distinguish self with square bracketsJune McEnroe 2018-08-08Add markers as lines to the logJune McEnroe 2018-08-08Factor out line editing to edit.cJune McEnroe 2018-08-08Set log marker on FocusOut eventJune McEnroe 2018-08-08Color own messages 15June McEnroe 2018-08-08Use BLACK LEFT-POINTING TRIANGLE for markerJune McEnroe 2018-08-07Reset attrs after addIRCJune McEnroe 2018-08-07Add tab complete UIJune McEnroe 2018-08-07Implement cycling tab completeJune McEnroe 2018-08-07Mark log when scrolling upJune McEnroe 2018-08-07Remove extraneous slash from unrecognized commandJune McEnroe 2018-08-07Highlight and beep pingsJune McEnroe 2018-08-07Factor out allocating conversion between wcs and mbsJune McEnroe 2018-08-07Match commands case-insensitivelyJune McEnroe 2018-08-07Convert input to multibyte before handlingJune McEnroe 2018-08-07Populate tab-complete listJune McEnroe 2018-08-07Fix /me formatting side-effectsJune McEnroe 2018-08-07Define ui.c BUF_LEN with enumJune McEnroe 2018-08-07Hack clang into checking uiFmt format stringsJune McEnroe 2018-08-07Handle PART and QUIT without messagesJune McEnroe 2018-08-07Make safe filling the who bufferJune McEnroe 2018-08-07Add reverse and reset IRC formatting codesJune McEnroe 2018-08-06Rewrite line editing again, add formattingJune McEnroe 2018-08-06Fix allocation size in vaswprintfJune McEnroe 2018-08-06Implement word wrappingJune McEnroe 2018-08-06Use wchar_t strings for all of UIJune McEnroe 2018-08-06Rename line editing functionsJune McEnroe 2018-08-05Initialize all possible color pairsJune McEnroe 2018-08-05Refactor color initializationJune McEnroe 2018-08-05Add ^L redrawJune McEnroe 2018-08-05Use 16 colors if availableJune McEnroe 2018-08-05Limit parsed colors to number of mIRC colorsJune McEnroe 2018-08-04Show source link on exitJune McEnroe 2018-08-04Implement line editing, scrollingJune McEnroe 2018-08-04Handle /topicJune McEnroe