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()) {