Implement scrolling!
parent
8ce6d4c377
commit
8451543b98
44
ui.c
44
ui.c
|
@ -367,13 +367,22 @@ static void statusUpdate(void) {
|
|||
fflush(stdout);
|
||||
}
|
||||
|
||||
static void unmark(void) {
|
||||
windows.active->heat = Cold;
|
||||
windows.active->unread = 0;
|
||||
windows.active->mark = false;
|
||||
static void unmark(struct Window *window) {
|
||||
if (window->scroll < BufferCap) return;
|
||||
window->heat = Cold;
|
||||
window->unread = 0;
|
||||
window->mark = false;
|
||||
statusUpdate();
|
||||
}
|
||||
|
||||
static void windowScroll(struct Window *window, int n) {
|
||||
if (window->scroll == BufferCap) window->mark = true;
|
||||
window->scroll += n;
|
||||
if (window->scroll < WINDOW_LINES) window->scroll = WINDOW_LINES;
|
||||
if (window->scroll > BufferCap) window->scroll = BufferCap;
|
||||
if (window->scroll == BufferCap) unmark(window);
|
||||
}
|
||||
|
||||
static int wordWidth(const char *str) {
|
||||
size_t len = strcspn(str, " ");
|
||||
int width = 0;
|
||||
|
@ -388,11 +397,12 @@ static int wordWidth(const char *str) {
|
|||
return width;
|
||||
}
|
||||
|
||||
static void wordWrap(WINDOW *win, const char *str) {
|
||||
static int wordWrap(WINDOW *win, const char *str) {
|
||||
int y, x, width;
|
||||
getmaxyx(win, y, width);
|
||||
|
||||
size_t len;
|
||||
int lines = 0;
|
||||
int align = 0;
|
||||
struct Style style = Reset;
|
||||
while (*str) {
|
||||
|
@ -409,6 +419,7 @@ static void wordWrap(WINDOW *win, const char *str) {
|
|||
getyx(win, y, x);
|
||||
const char *word = &str[strspn(str, " ")];
|
||||
if (width - x - 1 <= wordWidth(word)) {
|
||||
lines++;
|
||||
waddch(win, '\n');
|
||||
getyx(win, y, x);
|
||||
wmove(win, y, align);
|
||||
|
@ -432,6 +443,7 @@ static void wordWrap(WINDOW *win, const char *str) {
|
|||
waddnstr(win, str, len);
|
||||
str += len;
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
void uiWrite(size_t id, enum Heat heat, const time_t *src, const char *str) {
|
||||
|
@ -439,15 +451,20 @@ void uiWrite(size_t id, enum Heat heat, const time_t *src, const char *str) {
|
|||
time_t clock = (src ? *src : time(NULL));
|
||||
bufferPush(&window->buffer, clock, str);
|
||||
|
||||
int lines = 1;
|
||||
waddch(window->pad, '\n');
|
||||
if (window->mark && heat > Cold) {
|
||||
if (!window->unread++) {
|
||||
lines++;
|
||||
waddch(window->pad, '\n');
|
||||
}
|
||||
window->heat = heat;
|
||||
statusUpdate();
|
||||
}
|
||||
wordWrap(window->pad, str);
|
||||
lines += wordWrap(window->pad, str);
|
||||
if (window->scroll < BufferCap) {
|
||||
windowScroll(window, -lines);
|
||||
}
|
||||
if (heat > Warm) beep();
|
||||
}
|
||||
|
||||
|
@ -573,7 +590,7 @@ static void windowShow(struct Window *window) {
|
|||
windows.active = window;
|
||||
windows.other->mark = true;
|
||||
inputUpdate();
|
||||
unmark();
|
||||
unmark(windows.active);
|
||||
}
|
||||
|
||||
void uiShowID(size_t id) {
|
||||
|
@ -645,11 +662,12 @@ static void showAuto(void) {
|
|||
}
|
||||
|
||||
static void keyCode(int code) {
|
||||
size_t id = windows.active->id;
|
||||
struct Window *window = windows.active;
|
||||
size_t id = window->id;
|
||||
switch (code) {
|
||||
break; case KEY_RESIZE: resize();
|
||||
break; case KeyFocusIn: unmark();
|
||||
break; case KeyFocusOut: windows.active->mark = true;
|
||||
break; case KeyFocusIn: unmark(window);
|
||||
break; case KeyFocusOut: window->mark = true;
|
||||
break; case KeyPasteOn:; // TODO
|
||||
break; case KeyPasteOff:; // TODO
|
||||
|
||||
|
@ -659,15 +677,19 @@ static void keyCode(int code) {
|
|||
break; case KeyMetaB: edit(id, EditPrevWord, 0);
|
||||
break; case KeyMetaD: edit(id, EditDeleteNextWord, 0);
|
||||
break; case KeyMetaF: edit(id, EditNextWord, 0);
|
||||
break; case KeyMetaM: waddch(windows.active->pad, '\n');
|
||||
break; case KeyMetaM: waddch(window->pad, '\n');
|
||||
|
||||
break; case KEY_BACKSPACE: edit(id, EditDeletePrev, 0);
|
||||
break; case KEY_DC: edit(id, EditDeleteNext, 0);
|
||||
break; case KEY_DOWN: windowScroll(window, +1);
|
||||
break; case KEY_END: edit(id, EditTail, 0);
|
||||
break; case KEY_ENTER: edit(id, EditEnter, 0);
|
||||
break; case KEY_HOME: edit(id, EditHead, 0);
|
||||
break; case KEY_LEFT: edit(id, EditPrev, 0);
|
||||
break; case KEY_NPAGE: windowScroll(window, +(WINDOW_LINES - 2));
|
||||
break; case KEY_PPAGE: windowScroll(window, -(WINDOW_LINES - 2));
|
||||
break; case KEY_RIGHT: edit(id, EditNext, 0);
|
||||
break; case KEY_UP: windowScroll(window, -1);
|
||||
|
||||
break; default: {
|
||||
if (code >= KeyMeta0 && code <= KeyMeta9) {
|
||||
|
|
Loading…
Reference in New Issue