AmendHub

Download:

jcs

/

wallops

/

amendments

/

47

*: Smoother screen/tab updates, fix close/quit/dealloc sequences


jcs made amendment 47 about 1 year ago
--- chatter.c Tue Jan 10 15:22:50 2023 +++ chatter.c Tue Jan 17 23:14:56 2023 @@ -24,6 +24,7 @@ #define NICK_LIST_WIDTH 75 #define CHATTER_SCRAP_ELEMENTS 20 #define MAX_TAB_WIDTH 100 +#define TAB_BAR_HEIGHT 15 static Handle scrp_rec_h = NULL; static Pattern tab_bar_pattern; @@ -101,6 +102,8 @@ chatter_init(const char *server, const unsigned short focusable->resume = chatter_resume; focusable_add(focusable); chatter->focusable = focusable; + + chatter_draw_tab_bar(chatter); chatter_printf(chatter, NULL, NULL, "$B***$0 Welcome to %s", @@ -109,10 +112,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); - InvalRect(&bounds); DrawControls(chatter->win); - chatter_draw_tab_bar(chatter); chatter_update_titlebar(chatter); + + ValidRect(&bounds); return chatter; } @@ -237,14 +240,33 @@ chatter_add_tab(struct chatter *chatter, Rect *win_bou void chatter_focus_tab(struct chatter *chatter, struct chatter_tab *tab) { + RgnHandle clip; + Rect zerorect = { 0, 0, 0, 0 }, r; + if (chatter->current_tab) { if (chatter->current_tab == tab) return; + /* + * Doing the HideControl takes out the top line of our tab bar, + * so clip to just above it + */ + 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 + - 1; + ClipRect(&r); + TEDeactivate(chatter->current_tab->messages_te); if (chatter->current_tab->nick_list) LDoDraw(false, chatter->current_tab->nick_list); HideControl(chatter->current_tab->messages_scroller); + + SetClip(clip); } chatter->current_tab = tab; @@ -277,14 +299,9 @@ chatter_close(struct focusable *focusable) { struct chatter *chatter = (struct chatter *)(focusable->cookie); struct chatter_tab *tab; - struct irc_connection *conn; + struct irc_connection *conn, *tconn; bool connected = false; - if (chatter->quitting) { - DisposeWindow(focusable->win); - return true; - } - SLIST_FOREACH(tab, &chatter->tabs_list, list) { if (tab->conn->state == IRC_STATE_CONNECTED) { connected = true; @@ -292,13 +309,24 @@ chatter_close(struct focusable *focusable) } } - if (connected) { + if (connected && !chatter->quitting) { focusable_hide(focusable); return false; } + + SLIST_FOREACH_SAFE(conn, &irc_connections_list, list, tconn) { + if (conn->chatter == chatter) { + irc_close_connection(conn); + /* this will kill any channels as well */ + irc_dealloc_connection(conn); + } + } - /* TODO: maybe ask the user whether they want to hide or close? */ - chatter_quit(focusable); + if (chatter->tab_port.baseAddr) + xfree(&chatter->tab_port.baseAddr); + + DisposeWindow(focusable->win); + return true; } @@ -306,16 +334,10 @@ bool chatter_quit(struct focusable *focusable) { struct chatter *chatter = (struct chatter *)(focusable->cookie); - struct chatter_tab *tab; - short n; - SLIST_FOREACH(tab, &chatter->tabs_list, list) { - /* TODO: quit with a proper quit message */ - irc_close_connection(tab->conn); - } - chatter->quitting = true; focusable_close(focusable); + return true; } @@ -422,12 +444,25 @@ chatter_draw_tab_bar(struct chatter *chatter) { Rect r, r2; RgnHandle clip; + BitMap cur_bits; short tab_width, tab_offset, n, width; size_t len; static const char no_connection[] = "Disconnected"; struct chatter_tab *tab; char *label; + + cur_bits = chatter->win->portBits; + if (chatter->tab_port.baseAddr == 0) { + width = chatter->win->portRect.right - chatter->win->portRect.left; + chatter->tab_port.rowBytes = (((width - 1) / 16) + 1) * 2; + chatter->tab_port.baseAddr = xmalloczero( + chatter->tab_port.rowBytes * TAB_BAR_HEIGHT, "tab_port"); + SetRect(&chatter->tab_port.bounds, 0, 0, width, TAB_BAR_HEIGHT); + } + + SetPortBits(&chatter->tab_port); + TextFont(geneva); TextSize(9); @@ -439,15 +474,20 @@ chatter_draw_tab_bar(struct chatter *chatter) if (tab_width > MAX_TAB_WIDTH) tab_width = MAX_TAB_WIDTH; - r = (*(chatter->input_te))->viewRect; - r.bottom = r.top - 1; - r.right = chatter->win->portRect.right; - r.top -= 14; + r.top = 0; + r.bottom = TAB_BAR_HEIGHT; + r.left = 0; + r.right = chatter->win->portRect.right - chatter->win->portRect.left; FillRect(&r, tab_bar_pattern); + + r.left--; + r.right++; + FrameRect(&r); + r.left++; + r.right--; - r.left = chatter->win->portRect.left + tab_offset; - r.top -= 1; - r.bottom -= 1; + r.left = tab_offset; + r.bottom -= 2; r.right = r.left + tab_width; r2.left = r.left + 1; @@ -503,6 +543,20 @@ chatter_draw_tab_bar(struct chatter *chatter) TextSize(10); TextFace(0); + SetPortBits(&cur_bits); + + r = chatter->tab_port.bounds; + r.bottom = (*(chatter->input_te))->viewRect.top; + r.top += r.bottom - TAB_BAR_HEIGHT; + + SLIST_FOREACH(tab, &chatter->tabs_list, list) { + tab->label_rect.top += r.top; + tab->label_rect.bottom += r.top; + } + + CopyBits(&chatter->tab_port, &chatter->win->portBits, + &chatter->tab_port.bounds, &r, srcCopy, nil); + chatter_draw_grow_icon(chatter); } @@ -650,6 +704,11 @@ chatter_resize(struct focusable *focusable, EventRecor width = LoWord(newsize); SizeWindow(focusable->win, width, height, true); EraseRect(&chatter->win->portRect); + + /* chatter_draw_tab_bar will recreate this to the new size */ + if (chatter->tab_port.baseAddr) + xfree(&chatter->tab_port.baseAddr); + chatter_layout(chatter, false, NULL); } --- chatter.h Tue Jan 10 10:22:54 2023 +++ chatter.h Mon Jan 16 14:41:22 2023 @@ -90,6 +90,7 @@ struct chatter { WindowPtr win; TEHandle input_te; bool quitting; + BitMap tab_port; short ntabs; struct chatter_tabs_head tabs_list; struct chatter_tab *current_tab; --- irc.c Tue Jan 10 10:15:56 2023 +++ irc.c Tue Jan 17 14:23:25 2023 @@ -995,7 +995,6 @@ irc_dealloc_channel(struct irc_channel *channel) struct irc_connection *conn = channel->connection; struct irc_channel *tchannel; struct chatter *chatter = channel->chatter; - short n; chatter_remove_channel(chatter, channel); --- main.c Mon Jan 9 16:42:00 2023 +++ main.c Tue Jan 17 13:48:47 2023 @@ -168,9 +168,8 @@ main(void) found_focusable->resize(found_focusable, &event); break; case inGoAway: - if (TrackGoAway(event_win, event.where) && - found_focusable && found_focusable->close) - found_focusable->close(found_focusable); + if (TrackGoAway(event_win, event.where) && found_focusable) + focusable_close(found_focusable); break; case inContent: if (event_win != FrontWindow()) {