Preserve scroll position when new lines appear

master
Curtis McEnroe 2018-09-05 17:10:26 -04:00
parent 240f9ebf84
commit 0cf067315d
No known key found for this signature in database
GPG Key ID: CEA2F97ADCFCD77C
1 changed files with 15 additions and 6 deletions

21
ui.c
View File

@ -131,7 +131,7 @@ static struct View *viewTag(struct Tag tag) {
view->log = newpad(LogLines, COLS); view->log = newpad(LogLines, COLS);
wsetscrreg(view->log, 0, lastLogLine()); wsetscrreg(view->log, 0, lastLogLine());
scrollok(view->log, true); scrollok(view->log, true);
wmove(view->log, lastLogLine() - logHeight(view) + 2, 0); wmove(view->log, lastLogLine(), 0);
view->scroll = LogLines; view->scroll = LogLines;
view->mark = true; view->mark = true;
@ -266,7 +266,7 @@ static const wchar_t *parseColor(short *pair, const wchar_t *str) {
return str; return str;
} }
static void wordWrap(WINDOW *win, const wchar_t *str) { static int wordWrap(WINDOW *win, const wchar_t *str) {
size_t len = wcscspn(str, L" "); size_t len = wcscspn(str, L" ");
size_t width = 1; size_t width = 1;
for (size_t i = 0; i < len; ++i) { for (size_t i = 0; i < len; ++i) {
@ -279,8 +279,10 @@ static void wordWrap(WINDOW *win, const wchar_t *str) {
if (width >= (size_t)(xMax - x)) { if (width >= (size_t)(xMax - x)) {
waddch(win, '\n'); waddch(win, '\n');
return 1;
} else { } else {
waddch(win, ' '); waddch(win, ' ');
return 0;
} }
} }
@ -295,9 +297,10 @@ static const wchar_t IRCCodes[] = {
L'\0', L'\0',
}; };
static void addIRC(WINDOW *win, const wchar_t *str) { static int addIRC(WINDOW *win, const wchar_t *str) {
attr_t attr = A_NORMAL; attr_t attr = A_NORMAL;
short pair = -1; short pair = -1;
int lines = 0;
for (;;) { for (;;) {
size_t cc = wcscspn(str, IRCCodes); size_t cc = wcscspn(str, IRCCodes);
wattr_set(win, attr | attr8(pair), 1 + pair8(pair), NULL); wattr_set(win, attr | attr8(pair), 1 + pair8(pair), NULL);
@ -306,7 +309,7 @@ static void addIRC(WINDOW *win, const wchar_t *str) {
str = &str[cc]; str = &str[cc];
switch (*str++) { switch (*str++) {
break; case L' ': wordWrap(win, str); break; case L' ': lines += wordWrap(win, str);
break; case IRCBold: attr ^= A_BOLD; break; case IRCBold: attr ^= A_BOLD;
break; case IRCItalic: attr ^= A_ITALIC; break; case IRCItalic: attr ^= A_ITALIC;
break; case IRCUnderline: attr ^= A_UNDERLINE; break; case IRCUnderline: attr ^= A_UNDERLINE;
@ -315,6 +318,7 @@ static void addIRC(WINDOW *win, const wchar_t *str) {
break; case IRCReset: attr = A_NORMAL; pair = -1; break; case IRCReset: attr = A_NORMAL; pair = -1;
} }
} }
return lines;
} }
static void uiStatus(void) { static void uiStatus(void) {
@ -412,16 +416,21 @@ void uiTopic(struct Tag tag, const char *topic) {
void uiLog(struct Tag tag, enum UIHeat heat, const wchar_t *line) { void uiLog(struct Tag tag, enum UIHeat heat, const wchar_t *line) {
struct View *view = viewTag(tag); struct View *view = viewTag(tag);
int lines = 1;
waddch(view->log, '\n'); waddch(view->log, '\n');
if (view->mark && heat > UICold) { if (view->mark && heat > UICold) {
if (!view->unread++) waddch(view->log, '\n'); if (!view->unread++) {
lines++;
waddch(view->log, '\n');
}
if (heat > UIWarm) { if (heat > UIWarm) {
view->hot = true; view->hot = true;
beep(); // TODO: Notification. beep(); // TODO: Notification.
} }
uiStatus(); uiStatus();
} }
addIRC(view->log, line); lines += addIRC(view->log, line);
if (view->scroll != LogLines) view->scroll -= lines;
} }
void uiFmt(struct Tag tag, enum UIHeat heat, const wchar_t *format, ...) { void uiFmt(struct Tag tag, enum UIHeat heat, const wchar_t *format, ...) {