Reflow text on window resize
parent
7414a8a11c
commit
42210e079b
2
chat.c
2
chat.c
|
@ -122,6 +122,8 @@ int main(int argc, char *argv[]) {
|
||||||
if (signals[SIGHUP] || signals[SIGINT] || signals[SIGTERM]) {
|
if (signals[SIGHUP] || signals[SIGINT] || signals[SIGTERM]) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// FIXME: Display doesn't update properly when receiving many of these
|
||||||
|
// until some input?
|
||||||
if (signals[SIGWINCH]) {
|
if (signals[SIGWINCH]) {
|
||||||
signals[SIGWINCH] = 0;
|
signals[SIGWINCH] = 0;
|
||||||
cursesWinch(SIGWINCH);
|
cursesWinch(SIGWINCH);
|
||||||
|
|
68
ui.c
68
ui.c
|
@ -35,6 +35,9 @@
|
||||||
|
|
||||||
#include "chat.h"
|
#include "chat.h"
|
||||||
|
|
||||||
|
// Annoying stuff from <term.h>:
|
||||||
|
#undef lines
|
||||||
|
|
||||||
#ifndef A_ITALIC
|
#ifndef A_ITALIC
|
||||||
#define A_ITALIC A_UNDERLINE
|
#define A_ITALIC A_UNDERLINE
|
||||||
#endif
|
#endif
|
||||||
|
@ -43,16 +46,28 @@
|
||||||
#define RIGHT (COLS - 1)
|
#define RIGHT (COLS - 1)
|
||||||
#define WINDOW_LINES (LINES - 2)
|
#define WINDOW_LINES (LINES - 2)
|
||||||
|
|
||||||
enum {
|
|
||||||
InputCols = 512,
|
|
||||||
PadLines = 512,
|
|
||||||
};
|
|
||||||
|
|
||||||
static WINDOW *status;
|
static WINDOW *status;
|
||||||
static WINDOW *input;
|
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 {
|
struct Window {
|
||||||
size_t id;
|
size_t id;
|
||||||
|
struct Buffer buffer;
|
||||||
WINDOW *pad;
|
WINDOW *pad;
|
||||||
enum Heat heat;
|
enum Heat heat;
|
||||||
int unread;
|
int unread;
|
||||||
|
@ -89,17 +104,15 @@ static struct Window *windowFor(size_t id) {
|
||||||
for (window = windows.head; window; window = window->next) {
|
for (window = windows.head; window; window = window->next) {
|
||||||
if (window->id == id) return window;
|
if (window->id == id) return window;
|
||||||
}
|
}
|
||||||
window = malloc(sizeof(*window));
|
window = calloc(1, sizeof(*window));
|
||||||
if (!window) err(EX_OSERR, "malloc");
|
if (!window) err(EX_OSERR, "malloc");
|
||||||
|
|
||||||
window->id = id;
|
window->id = id;
|
||||||
window->pad = newpad(PadLines, COLS);
|
window->pad = newpad(BufferCap, COLS);
|
||||||
window->heat = Cold;
|
|
||||||
window->unread = 0;
|
|
||||||
window->scroll = PadLines;
|
|
||||||
window->mark = true;
|
|
||||||
scrollok(window->pad, true);
|
scrollok(window->pad, true);
|
||||||
wmove(window->pad, PadLines - 1, 0);
|
wmove(window->pad, BufferCap - 1, 0);
|
||||||
|
window->scroll = BufferCap;
|
||||||
|
window->mark = true;
|
||||||
|
|
||||||
windowAdd(window);
|
windowAdd(window);
|
||||||
return window;
|
return window;
|
||||||
|
@ -190,7 +203,7 @@ void uiInit(void) {
|
||||||
|
|
||||||
colorInit();
|
colorInit();
|
||||||
status = newwin(1, COLS, 0, 0);
|
status = newwin(1, COLS, 0, 0);
|
||||||
input = newpad(1, InputCols);
|
input = newpad(1, 512);
|
||||||
keypad(input, true);
|
keypad(input, true);
|
||||||
nodelay(input, true);
|
nodelay(input, true);
|
||||||
windows.active = windowFor(Network);
|
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 uiWrite(size_t id, enum Heat heat, const time_t *src, const char *str) {
|
||||||
(void)time;
|
|
||||||
struct Window *window = windowFor(id);
|
struct Window *window = windowFor(id);
|
||||||
|
time_t clock = (src ? *src : time(NULL));
|
||||||
|
bufferPush(&window->buffer, clock, str);
|
||||||
|
|
||||||
waddch(window->pad, '\n');
|
waddch(window->pad, '\n');
|
||||||
if (window->mark && heat > Cold) {
|
if (window->mark && heat > Cold) {
|
||||||
if (!window->unread++) {
|
if (!window->unread++) {
|
||||||
|
@ -406,6 +421,25 @@ void uiFormat(
|
||||||
uiWrite(id, heat, time, buf);
|
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) {
|
static void inputAdd(struct Style *style, const char *str) {
|
||||||
size_t len;
|
size_t len;
|
||||||
while (*str) {
|
while (*str) {
|
||||||
|
@ -480,7 +514,7 @@ void uiShowNum(size_t num) {
|
||||||
|
|
||||||
static void keyCode(int code) {
|
static void keyCode(int code) {
|
||||||
switch (code) {
|
switch (code) {
|
||||||
break; case KEY_RESIZE:; // TODO
|
break; case KEY_RESIZE: resize();
|
||||||
break; case KeyFocusIn: unmark();
|
break; case KeyFocusIn: unmark();
|
||||||
break; case KeyFocusOut: windows.active->mark = true;
|
break; case KeyFocusOut: windows.active->mark = true;
|
||||||
break; case KeyPasteOn:; // TODO
|
break; case KeyPasteOn:; // TODO
|
||||||
|
@ -490,7 +524,7 @@ static void keyCode(int code) {
|
||||||
|
|
||||||
static void keyMeta(wchar_t ch) {
|
static void keyMeta(wchar_t ch) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
break; case L'm': uiWrite(windows.active->id, Cold, NULL, "");
|
break; case L'm': waddch(windows.active->pad, '\n');
|
||||||
break; default: {
|
break; default: {
|
||||||
if (ch >= L'0' && ch <= L'9') uiShowNum(ch - L'0');
|
if (ch >= L'0' && ch <= L'9') uiShowNum(ch - L'0');
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue