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 June McEnroe 2018-04-03Add MASSEDUCTIONJune McEnroe 2018-04-03Add Luciferian Towers trackJune McEnroe 2018-04-03Indicate all Tiny Desk ConcertsJune McEnroe 2018-04-03Add FloristJune McEnroe 2018-04-03Add CHVRCHES tiny desk concertJune McEnroe 2018-04-03Add AuroraJune McEnroe 2018-04-03Add AtmosphereJune McEnroe I know I've already put Joy Division in here. But this is also Trainspotting and I managed to miss / not appreciate this one on my first go through JD. 2018-04-03Add Born SlippyJune McEnroe I watched Trainspotting last night. 2018-04-03Add I Can Tell You About PainJune McEnroe 2018-04-03Reverse new music orderJune McEnroe 2018-04-03Add FAUVE, CocoRosieJune McEnroe 2018-04-03Add House of LeavesJune McEnroe 2018-04-03Add ChromaticsJune McEnroe 2018-04-03Add those new Arcade Fire singlesJune McEnroe 2018-04-03Add SermonJune McEnroe 2018-04-03Add Pools of LightJune McEnroe 2018-04-03Add SteroidsJune McEnroe 2018-04-03Add A Common TruthJune McEnroe 2018-04-03Add new Colin Stetson albumJune McEnroe 2018-04-03Add ForgetJune McEnroe 2018-04-03Add ArcaJune McEnroe 2018-04-03Add new DMST and Joni VoidJune McEnroe 2018-04-03Add The Body LoversJune McEnroe 2018-04-03Add some albums from recentlyJune McEnroe 2018-04-03Add Saltland Light of MercyJune McEnroe 2018-04-03Add Jessica Moss GlaciersJune McEnroe 2018-04-03Add BNNY RBBTJune McEnroe 2018-04-03Add DepthsJune McEnroe 2018-04-03Add new Saltland previewJune McEnroe 2018-04-03Add BenjiJune McEnroe 2018-04-03Add Mouth MoodsJune McEnroe 2018-04-03Add Those Who Walk AwayJune McEnroe 2018-04-03Add Some TunesJune McEnroe 2018-04-03Add Pas pire popJune McEnroe 2018-04-03Add I Give You PowerJune McEnroe 2018-04-03Add Jenny GoGoJune McEnroe 2018-04-03Add KKB Fish BowlJune McEnroe 2018-04-03Add new Avec le soleil album previewJune McEnroe 2018-04-03Add Julien Baker as recent new musicJune McEnroe 2018-04-03Add recent new musicJune McEnroe