AmendHub

Download:

jcs

/

wallops

/

amendments

/

53

chatter: Improve re-drawing


jcs made amendment 53 3 months ago
--- chatter.c Tue Jan 17 23:18:38 2023 +++ chatter.c Fri Aug 30 16:38:16 2024 @@ -31,6 +31,8 @@ static Pattern tab_bar_pattern; void chatter_layout(struct chatter *chatter, bool init, Rect *init_bounds); void chatter_draw_tab_bar(struct chatter *chatter); +void chatter_layout_tab(struct chatter *chatter, struct chatter_tab *tab, + Rect *win_bounds, bool init); void chatter_focus_tab(struct chatter *chatter, struct chatter_tab *tab); void chatter_draw_grow_icon(struct chatter *chatter); void chatter_autoscroll(struct chatter *chatter, TEHandle te, @@ -52,7 +54,7 @@ struct chatter_tab * chatter_find_tab_for_conn_and_cha struct chatter * chatter_init(const char *server, const unsigned short port, const char *password, const char *nick, const char *ident, - const char *realname, const char *channel) + const char *realname, bool hide_motd, const char *channel) { struct focusable *focusable; struct chatter *chatter; @@ -63,14 +65,23 @@ chatter_init(const char *server, const unsigned short GetIndPattern(&tab_bar_pattern, sysPatListID, 23); - chatter = xmalloczero(sizeof(struct chatter), "chatter"); + chatter = xmalloczero(sizeof(struct chatter)); + if (chatter == NULL) + return NULL; SLIST_INIT(&chatter->tabs_list); + focusable = xmalloczero(sizeof(struct focusable)); + if (focusable == NULL) { + xfree(&chatter); + return NULL; + } + bounds.left = padding; bounds.top = screenBits.bounds.top + padding + (GetMBarHeight() * 2) - 1; bounds.right = screenBits.bounds.right - padding - 1; - bounds.bottom = screenBits.bounds.bottom - padding - 1; +// bounds.bottom = screenBits.bounds.bottom - padding - 1; + bounds.bottom = (screenBits.bounds.bottom / 2) - padding - 1; snprintf(title, sizeof(title), "%s: Disconnected", PROGRAM_NAME); chatter->win = NewWindow(0L, &bounds, CtoPstr(title), false, @@ -87,7 +98,6 @@ chatter_init(const char *server, const unsigned short bounds.top = bounds.left = 0; chatter_layout(chatter, true, &bounds); - focusable = xmalloczero(sizeof(struct focusable), "focusable"); focusable->win = chatter->win; focusable->cookie = chatter; focusable->wait_type = chatter_wait_type; @@ -111,9 +121,10 @@ chatter_init(const char *server, const unsigned short tab = SLIST_FIRST(&chatter->tabs_list); tab->conn = irc_connect(chatter, server, port, password, nick, ident, - realname, channel); + realname, hide_motd, channel); DrawControls(chatter->win); chatter_update_titlebar(chatter); + chatter_draw_tab_bar(chatter); ValidRect(&bounds); @@ -171,7 +182,9 @@ chatter_layout(struct chatter *chatter, bool init, Rec if (init) { chatter_add_tab(chatter, win_bounds, NULL, NULL); } else { - /* TODO: move tabs around */ + SLIST_FOREACH(tab, &chatter->tabs_list, list) { + chatter_layout_tab(chatter, tab, win_bounds, false); + } } } @@ -188,12 +201,31 @@ chatter_add_tab(struct chatter *chatter, Rect *win_bou if (win_bounds == NULL) win_bounds = &chatter->win->portRect; - tab = xmalloczero(sizeof(struct chatter_tab), "tab"); + tab = xmalloczero(sizeof(struct chatter_tab)); SLIST_APPEND(&chatter->tabs_list, tab, chatter_tab, list); tab->index = chatter->ntabs++; tab->conn = conn; tab->channel = channel; + + chatter_layout_tab(chatter, tab, win_bounds, true); + chatter_focus_tab(chatter, tab); + + return tab; +} + +void +chatter_layout_tab(struct chatter *chatter, struct chatter_tab *tab, + Rect *win_bounds, bool init) +{ + Rect bounds, inset_bounds; + Rect data_bounds = { 0, 0, 0, 1 }; /* tlbr */ + Point cell_size = { 0 }; + Cell cell = { 0, 0 }; + + if (win_bounds == NULL) + win_bounds = &chatter->win->portRect; + bounds.bottom = (*(chatter->input_te))->viewRect.top - 15; if (tab->channel) { @@ -201,12 +233,18 @@ chatter_add_tab(struct chatter *chatter, Rect *win_bou bounds.top = 0; bounds.right = win_bounds->right - SCROLLBAR_WIDTH + 1; bounds.left = bounds.right - NICK_LIST_WIDTH; - tab->nick_list = LNew(&bounds, &data_bounds, cell_size, 0, - chatter->win, true, true, false, true); - if (!tab->nick_list) - panic("Can't create nick list"); - LAddColumn(1, 0, tab->nick_list); - (*(tab->nick_list))->selFlags = lOnlyOne | lNoNilHilite; + if (init) { + tab->nick_list = LNew(&bounds, &data_bounds, cell_size, 0, + chatter->win, true, true, false, true); + if (!tab->nick_list) + panic("Can't create nick list"); + LAddColumn(1, 0, tab->nick_list); + (*(tab->nick_list))->selFlags = lOnlyOne | lNoNilHilite; + } else { + (*(tab->nick_list))->rView = bounds; + LSize(bounds.right - bounds.left, bounds.bottom - bounds.top, + tab->nick_list); + } } /* messages scrollbar */ @@ -217,9 +255,15 @@ chatter_add_tab(struct chatter *chatter, Rect *win_bou bounds.right = win_bounds->right + 1; bounds.left = bounds.right - SCROLLBAR_WIDTH; bounds.bottom += 1; - tab->messages_scroller = NewControl(chatter->win, &bounds, "\p", true, - 1, 1, 1, scrollBarProc, 0L); - + if (init) + tab->messages_scroller = NewControl(chatter->win, &bounds, + "\p", true, 1, 1, 1, scrollBarProc, 0L); + else { + MoveControl(tab->messages_scroller, bounds.left, bounds.top); + SizeControl(tab->messages_scroller, bounds.right - bounds.left, + bounds.bottom - bounds.top); + } + /* messages */ bounds.right = (*(tab->messages_scroller))->contrlRect.left; bounds.left = 0; @@ -227,21 +271,24 @@ chatter_add_tab(struct chatter *chatter, Rect *win_bou bounds.bottom -= 1; inset_bounds = bounds; InsetRect(&inset_bounds, 4, 4); - tab->messages_te = TEStylNew(&inset_bounds, &bounds); - (*(tab->messages_te))->caretHook = NullCaretHook; - TEActivate(tab->messages_te); - chatter_autoscroll(chatter, tab->messages_te, tab->messages_scroller); - - chatter_focus_tab(chatter, tab); - - return tab; + if (init) { + tab->messages_te = TEStylNew(&inset_bounds, &bounds); + (*(tab->messages_te))->caretHook = NullCaretHook; + TEActivate(tab->messages_te); + chatter_autoscroll(chatter, tab->messages_te, + tab->messages_scroller); + } else { + (*(tab->messages_te))->viewRect = bounds; + (*(tab->messages_te))->destRect = inset_bounds; + TECalText(tab->messages_te); + } } void chatter_focus_tab(struct chatter *chatter, struct chatter_tab *tab) { RgnHandle clip; - Rect zerorect = { 0, 0, 0, 0 }, r; + Rect r; if (chatter->current_tab) { if (chatter->current_tab == tab) @@ -254,19 +301,26 @@ chatter_focus_tab(struct chatter *chatter, struct chat GetClip(clip = NewRgn()); r.left = 0; r.top = 0; - r.right = - (*(chatter->current_tab->messages_scroller))->contrlRect.right; - r.bottom = - (*(chatter->current_tab->messages_scroller))->contrlRect.bottom + r.bottom = (*(chatter->current_tab->messages_scroller))->contrlRect.bottom - 1; + if (chatter->current_tab->nick_list) + r.right = (*(chatter->current_tab->nick_list))->rView.right; + else + r.right = (*(chatter->current_tab->messages_scroller))->contrlRect.right; ClipRect(&r); + FillRect(&r, white); TEDeactivate(chatter->current_tab->messages_te); if (chatter->current_tab->nick_list) LDoDraw(false, chatter->current_tab->nick_list); + + /* HideControl will flash, clip it out */ + r.right = 0; + ClipRect(&r); HideControl(chatter->current_tab->messages_scroller); SetClip(clip); + DisposeRgn(clip); } chatter->current_tab = tab; @@ -372,13 +426,22 @@ chatter_idle(struct focusable *focusable, EventRecord { struct chatter *chatter = (struct chatter *)(focusable->cookie); struct chatter_tab *tab; - short n; + short n, was_state; + bool redraw = false; TEIdle(chatter->input_te); SLIST_FOREACH(tab, &chatter->tabs_list, list) { + was_state = tab->conn->state; + irc_process(tab->conn); + + if (tab->conn->state != was_state) + redraw = true; } + + if (redraw) + chatter_draw_tab_bar(chatter); } void @@ -457,7 +520,7 @@ chatter_draw_tab_bar(struct chatter *chatter) width = chatter->win->portRect.right - chatter->win->portRect.left; chatter->tab_bar.rowBytes = (((width - 1) / 16) + 1) * 2; chatter->tab_bar.baseAddr = xmalloczero( - chatter->tab_bar.rowBytes * TAB_BAR_HEIGHT, "tab_bar"); + chatter->tab_bar.rowBytes * TAB_BAR_HEIGHT); SetRect(&chatter->tab_bar.bounds, 0, 0, width, TAB_BAR_HEIGHT); } @@ -704,12 +767,15 @@ chatter_resize(struct focusable *focusable, EventRecor width = LoWord(newsize); SizeWindow(focusable->win, width, height, true); EraseRect(&chatter->win->portRect); + InvalRect(&chatter->win->portRect); /* chatter_draw_tab_bar will recreate this to the new size */ if (chatter->tab_bar.baseAddr) xfree(&chatter->tab_bar.baseAddr); chatter_layout(chatter, false, NULL); + chatter_update(focusable, NULL); + ValidRect(&chatter->win->portRect); } bool @@ -759,8 +825,9 @@ chatter_key_down(struct focusable *focusable, EventRec te = *(chatter->input_te); HLock(te->hText); (*(te->hText))[te->teLength] = '\0'; - input = xstrdup(*(te->hText), "input"); + input = xstrdup(*(te->hText)); TESetText(&k, 0, chatter->input_te); + TEScroll(0, 0, chatter->input_te); EraseRect(&te->viewRect); ValidRect(&te->viewRect); TEIdle(chatter->input_te); @@ -988,7 +1055,9 @@ void chatter_remove_channel(struct chatter *chatter, struct irc_channel *channel) { + RgnHandle clip; struct chatter_tab *tab = NULL, *ttab = NULL, *next_tab = NULL; + Rect r; short n; SLIST_FOREACH(ttab, &chatter->tabs_list, list) { @@ -1001,10 +1070,26 @@ chatter_remove_channel(struct chatter *chatter, } if (tab != NULL) { + GetClip(clip = NewRgn()); + + r.left = 0; + r.top = 0; + r.bottom = (*(tab->messages_scroller))->contrlRect.bottom - 1; + if (tab->nick_list) + r.right = (*(tab->nick_list))->rView.right; + else + r.right = (*(tab->messages_scroller))->contrlRect.right; + + ClipRect(&r); + + FillRect(&r, white); LDispose(tab->nick_list); DisposeControl(tab->messages_scroller); TEDispose(tab->messages_te); SLIST_REMOVE(&chatter->tabs_list, tab, chatter_tab, list); + + SetClip(clip); + DisposeRgn(clip); if (chatter->current_tab == tab) chatter->current_tab = NULL; @@ -1102,4 +1187,22 @@ chatter_insert_to_nick_list(struct chatter *chatter, j += strlcpy(tnick.nick + j, nick->nick, sizeof(tnick.nick) - j); LAddRow(1, cell.v, tab->nick_list); LSetCell(&tnick.nick, j, cell, tab->nick_list); -} +} + +void +chatter_remove_from_nick_list(struct chatter *chatter, + struct irc_channel *channel, struct irc_channel_nick *nick, short pos) +{ + struct chatter_tab *tab; + + tab = chatter_find_tab_for_conn_and_channel(chatter, + channel->connection, channel); + if (!tab) + return; + + if (pos == -1) { + /* TODO: find nick in list */ + } + + LDelRow(1, pos, tab->nick_list); +} \ No newline at end of file