AmendHub

Download:

jcs

/

wallops

/

amendments

/

63

*: Add View menu with hide/show options, fix dropped update events

updateEvt puts the window in .message not .where, so found_focusable
was being null, resulting in no update function called. Defer
finding event_in/found_focusable until we know what type of message
it is.

jcs made amendment 63 2 months ago
--- chatter.c Wed Sep 4 14:18:22 2024 +++ chatter.c Thu Sep 5 10:12:05 2024 @@ -19,6 +19,7 @@ #include <string.h> #include "chatter.h" #include "irc.h" +#include "settings.h" #include "util.h" #define NICK_LIST_WIDTH 75 @@ -28,6 +29,7 @@ static Handle scrp_rec_h = NULL; static Pattern tab_bar_pattern; +static Rect zerorect = { 0, 0, 0, 0 }; void chatter_layout(struct chatter *chatter, bool init, Rect *init_bounds); void chatter_draw_tab_bar(struct chatter *chatter); @@ -86,7 +88,7 @@ chatter_init(const char *server, const unsigned short padding - (GetMBarHeight() * 2); height = MIN(height, 350); center_in_screen(width, height, true, &bounds); - + width = screenBits.bounds.right - screenBits.bounds.left; height = screenBits.bounds.bottom - screenBits.bounds.top; chatter->shadow.rowBytes = (((width - 1) / 16) + 1) * 2; @@ -128,16 +130,19 @@ chatter_init(const char *server, const unsigned short focusable->resume = chatter_resume; focusable_add(focusable); chatter->focusable = focusable; + + chatter_update_menu(focusable); chatter_draw_tab_bar(chatter); chatter_printf(chatter, NULL, NULL, - "$B***$0 Welcome to %s", - PROGRAM_NAME); + "$B***$0 Welcome to %s %s", + PROGRAM_NAME, get_version(false)); tab = SLIST_FIRST(&chatter->tabs_list); tab->conn = irc_connect(chatter, server, port, password, nick, ident, realname, hide_motd, channel); + DrawControls(chatter->win); chatter_update_titlebar(chatter); chatter_draw_tab_bar(chatter); @@ -227,7 +232,6 @@ chatter_add_tab(struct chatter *chatter, Rect *win_bou tab->channel = channel; chatter_layout_tab(chatter, tab, win_bounds, true); - chatter_focus_tab(chatter, tab); if (conn) @@ -293,6 +297,7 @@ chatter_layout_tab(struct chatter *chatter, struct cha bounds.bottom -= 1; inset_bounds = bounds; InsetRect(&inset_bounds, 4, 4); + EraseRect(&bounds); if (init) { tab->messages_te = TEStylNew(&inset_bounds, &bounds); (*(tab->messages_te))->caretHook = NullCaretHook; @@ -331,7 +336,7 @@ chatter_focus_tab(struct chatter *chatter, struct chat r.right = (*(chatter->current_tab->messages_scroller))->contrlRect.right; ClipRect(&r); - FillRect(&r, white); + EraseRect(&r); TEDeactivate(chatter->current_tab->messages_te); if (chatter->current_tab->nick_list) LDoDraw(false, chatter->current_tab->nick_list); @@ -347,17 +352,18 @@ chatter_focus_tab(struct chatter *chatter, struct chat chatter->current_tab = tab; - FillRect(&(*(tab->messages_te))->viewRect, white); + EraseRect(&(*(tab->messages_te))->viewRect); TEActivate(tab->messages_te); TEUpdate(&(*(tab->messages_te))->viewRect, tab->messages_te); ShowControl(tab->messages_scroller); if (tab->nick_list) { - FillRect(&(*(tab->nick_list))->rView, white); + EraseRect(&(*(tab->nick_list))->rView); LDoDraw(true, tab->nick_list); LUpdate(chatter->win->visRgn, tab->nick_list); } DrawControls(chatter->win); + chatter_draw_tab_bar(chatter); } @@ -507,6 +513,7 @@ chatter_update(struct focusable *focusable, EventRecor TEUpdate(&(*(chatter->input_te))->viewRect, chatter->input_te); DrawControls(chatter->win); + chatter_draw_tab_bar(chatter); chatter_reveal_shadow(chatter); break; @@ -554,7 +561,6 @@ chatter_draw_tab_bar(struct chatter *chatter) TextSize(9); tab_offset = 5; - tab_width = (chatter->win->portRect.right - chatter->win->portRect.left - tab_offset - tab_offset) / chatter->ntabs; @@ -587,11 +593,11 @@ chatter_draw_tab_bar(struct chatter *chatter) SLIST_FOREACH(tab, &chatter->tabs_list, list) { tab->label_rect = r; - FillRect(&r, white); + EraseRect(&r); FrameRect(&r); if (tab == chatter->current_tab) { FrameRect(&r2); - FillRect(&r2, white); + EraseRect(&r2); tab->have_activity = false; } @@ -678,7 +684,7 @@ chatter_draw_grow_icon(struct chatter *chatter) r.left -= 2; r.bottom -= 4; r.right -= 4; - FillRect(&r, white); + EraseRect(&r); FrameRect(&r); HUnlock(*(chatter->input_te)); @@ -779,6 +785,7 @@ void chatter_resize(struct focusable *focusable, EventRecord *event) { struct chatter *chatter = (struct chatter *)(focusable->cookie); + struct chatter_tab *ttab; RgnHandle savergn; Rect bounds; long newsize, width, height; @@ -807,9 +814,10 @@ chatter_resize(struct focusable *focusable, EventRecor ClipRect(&zerorect); SLIST_FOREACH(ttab, &chatter->tabs_list, list) { - if (tab == chatter->current_tab) + if (ttab == chatter->current_tab) continue; + TEPinScroll(0, -INT_MAX, ttab->messages_te); chatter_autoscroll(chatter, ttab->messages_te, ttab->messages_scroller); } @@ -867,6 +875,8 @@ chatter_update_menu(struct focusable *focusable) HLock(chatter->input_te); HLock(tab->messages_te); + EnableItem(view_menu, VIEW_MENU_HIDE_ID); + EnableItem(edit_menu, EDIT_MENU_PASTE_ID); if ((*(chatter->input_te))->selStart != (*(chatter->input_te))->selEnd) { @@ -946,7 +956,6 @@ chatter_printf(struct chatter *chatter, struct irc_con StScrpRec *scrp_rec; ScrpSTElement *scrp_ele, *prev_scrp_ele; RgnHandle savergn; - Rect zerorect = { 0, 0, 0, 0 }; va_list argptr; size_t len, n, buf_out_len, in_this_style; time_t now = Time; @@ -1074,7 +1083,7 @@ te_overflow: GetClip(savergn); /* create an empty clip region so all TE updates are hidden */ ClipRect(&zerorect); - + /* select some lines at the start, delete them */ TESetSelect(0, (*(tab->messages_te))->lineStarts[5], tab->messages_te); TEDelete(tab->messages_te); @@ -1096,7 +1105,7 @@ no_overflow: /* create an empty clip region so all TE updates are hidden */ ClipRect(&zerorect); } - + TESetSelect(SHRT_MAX, SHRT_MAX, tab->messages_te); TEStylInsert(buf_out, buf_out_len, scrp_rec_h, tab->messages_te); HUnlock(scrp_rec_h); --- chatter.h Tue Sep 3 16:17:49 2024 +++ chatter.h Thu Sep 5 09:19:25 2024 @@ -44,6 +44,9 @@ #define EDIT_MENU_COPY_ID 2 #define EDIT_MENU_PASTE_ID 3 +#define VIEW_MENU_ID 131 +#define VIEW_MENU_HIDE_ID 1 + #define WAIT_TYPE_NONE (1 << 0) #define WAIT_TYPE_BACKGROUND (1 << 1) #define WAIT_TYPE_FOREGROUND (1 << 2) @@ -75,7 +78,7 @@ struct chatter { struct chatter_tab *current_tab; }; -extern MenuHandle apple_menu, file_menu, edit_menu; +extern MenuHandle apple_menu, file_menu, edit_menu, view_menu; void notify(void); void cancel_notification(void); --- focusable.c Wed Aug 28 13:55:46 2024 +++ focusable.c Thu Sep 5 10:08:39 2024 @@ -85,12 +85,13 @@ focusable_show(struct focusable *focusable) } } - if (!focusable->visible) { + if (focusable->visible) + SelectWindow(focusable->win); + else { focusable->visible = true; ShowWindow(focusable->win); } - SelectWindow(focusable->win); SetPort(focusable->win); return true; --- main.c Tue Sep 3 14:56:14 2024 +++ main.c Thu Sep 5 10:08:25 2024 @@ -23,7 +23,7 @@ NMRec notification = { 0 }; struct settings settings; -MenuHandle apple_menu, file_menu, edit_menu; +MenuHandle apple_menu, file_menu, edit_menu, view_menu; void update_menu(void); void handle_exit(void); @@ -69,6 +69,8 @@ main(void) panic("no file menu"); if (!(edit_menu = GetMHandle(EDIT_MENU_ID))) panic("no edit menu"); + if (!(view_menu = GetMHandle(VIEW_MENU_ID))) + panic("no view menu"); update_menu(); DrawMenuBar(); @@ -92,11 +94,6 @@ main(void) WaitNextEvent(everyEvent, &event, wait_ticks, 0L); - if (event.what != nullEvent) { - event_in = FindWindow(event.where, &event_win); - found_focusable = focusable_find(event_win); - } - switch (event.what) { case nullEvent: for (n = 0; n < nfocusables; n++) { @@ -115,6 +112,9 @@ main(void) focusables[0]->key_down(focusables[0], &event); break; case mouseDown: + event_in = FindWindow(event.where, &event_win); + found_focusable = focusable_find(event_win); + switch (event_in) { case inMenuBar: handle_menu(MenuSelect(event.where)); @@ -154,6 +154,7 @@ main(void) case updateEvt: case activateEvt: event_win = (WindowPtr)event.message; + found_focusable = focusable_find(event_win); GetPort(&old_port); SetPort(event_win); @@ -203,7 +204,10 @@ show_connect_dialog(void) { bool valid; - if (!settings_edit(!settings_load())) + valid = settings_edit(!settings_load()); + update_menu(); + + if (!valid) return; chatter_init(settings.server, settings.port, settings.password, @@ -252,6 +256,37 @@ handle_menu(long menu_id) break; } break; + case VIEW_MENU_ID: + switch (LoWord(menu_id)) { + case VIEW_MENU_HIDE_ID: { + Str255 text; + struct focusable **tfocusables = NULL; + + /* hiding and showing adjusts order, so duplicate order */ + tfocusables = xmalloc(sizeof(struct focusable *) * nfocusables); + memcpy(tfocusables, focusables, sizeof(struct focusable *) * + nfocusables); + + GetItem(view_menu, VIEW_MENU_HIDE_ID, &text); + if (memcmp((char *)text + 1, "Hide", 4) == 0) { + for (n = 0; n < nfocusables; n++) { + if (tfocusables[n]->visible) + focusable_hide(tfocusables[n]); + } + } else { + for (n = 0; n < nfocusables; n++) { + if (!tfocusables[n]->visible) + focusable_show(tfocusables[n]); + } + } + + xfree(&tfocusables); + update_menu(); + ret = true; + break; + } + } + break; default: if (nfocusables && focusables[0]->visible && focusables[0]->menu) ret = focusables[0]->menu(focusables[0], HiWord(menu_id), @@ -265,17 +300,30 @@ handle_menu(long menu_id) void update_menu(void) { - if (nfocusables) { - if (focusables[0]->visible) { - EnableItem(edit_menu, 0); - if (focusables[0]->update_menu) - focusables[0]->update_menu(focusables[0]); - } else { - DisableItem(edit_menu, 0); + short n; + bool hidden = false; + + for (n = 0; n < nfocusables; n++) { + if (!focusables[n]->visible) { + hidden = true; + break; } - } else { - DisableItem(edit_menu, 0); } + + if (hidden) + SetItem(view_menu, VIEW_MENU_HIDE_ID, "\pShow Windows"); + else + SetItem(view_menu, VIEW_MENU_HIDE_ID, "\pHide Windows"); + + if (nfocusables && focusables[0]->visible && + focusables[0]->update_menu) { + focusables[0]->update_menu(focusables[0]); + return; + } + + DisableItem(edit_menu, EDIT_MENU_CUT_ID); + DisableItem(edit_menu, EDIT_MENU_COPY_ID); + DisableItem(edit_menu, EDIT_MENU_PASTE_ID); } void @@ -309,4 +357,4 @@ cancel_notification(void) if (notification.qType) NMRemove(&notification); memset(&notification, 0, sizeof(notification)); -} \ No newline at end of file +}