AmendHub

Download:

jcs

/

wallops

/

amendments

/

40

chatter: Implement window resizing

Since our input field is taller than a scrollbar, we have to draw our
own grow icon that is a little taller.

jcs made amendment 40 about 1 year ago
--- chatter.c Wed Nov 30 23:20:30 2022 +++ chatter.c Thu Dec 1 21:49:35 2022 @@ -27,9 +27,12 @@ static Handle scrp_rec_h = NULL; void chatter_layout(struct chatter *chatter, bool init, Rect *init_bounds); +void chatter_draw_grow_icon(struct chatter *chatter); +void chatter_autoscroll(struct chatter *chatter); short chatter_wait_type(struct focusable *focusable); void chatter_key_down(struct focusable *focusable, EventRecord *event); void chatter_mouse_down(struct focusable *focusable, EventRecord *event); +void chatter_resize(struct focusable *focusable, EventRecord *event); bool chatter_menu(struct focusable *focusable, short menu, short item); void chatter_idle(struct focusable *focusable, EventRecord *event); void chatter_update(struct focusable *focusable, EventRecord *event); @@ -96,6 +99,7 @@ chatter_init(const char *server, const unsigned short focusable->close = chatter_close; focusable->atexit = chatter_atexit; focusable->quit = chatter_quit; + focusable->resize = chatter_resize; focusable->menu = chatter_menu; focusable->resume = chatter_resume; add_focusable(focusable); @@ -131,7 +135,7 @@ chatter_layout(struct chatter *chatter, bool init, Rec /* input */ bounds.left = win_bounds.left; - bounds.right = win_bounds.right - 3; + bounds.right = win_bounds.right - SCROLLBAR_WIDTH - 3; bounds.top = win_bounds.bottom - SCROLLBAR_WIDTH; bounds.bottom = win_bounds.bottom; if (init) { @@ -163,7 +167,7 @@ chatter_layout(struct chatter *chatter, bool init, Rec (*(chatter->nick_list))->selFlags = lOnlyOne | lNoNilHilite; } else { (*(chatter->nick_list))->rView = bounds; - LSize(bounds.right - bounds.left, bounds.bottom - bounds.top - 10, + LSize(bounds.right - bounds.left, bounds.bottom - bounds.top, chatter->nick_list); } @@ -194,9 +198,13 @@ chatter_layout(struct chatter *chatter, bool init, Rec InsetRect(&bounds, 4, 4); (*(chatter->messages_te))->destRect = bounds; TECalText(chatter->messages_te); + + chatter_autoscroll(chatter); } - InvalRect(chatter->win->visRgn); + InvalRect(&win_bounds); + DrawControls(chatter->win); + chatter_draw_grow_icon(chatter); } void @@ -299,7 +307,6 @@ chatter_update(struct focusable *focusable, EventRecor EraseRect(&chatter->win->portRect); r = (*(chatter->nick_list))->rView; - EraseRect(&r); LUpdate(chatter->win->visRgn, chatter->nick_list); InsetRect(&r, -1, -1); FrameRect(&r); @@ -313,6 +320,7 @@ chatter_update(struct focusable *focusable, EventRecor TEUpdate(&(*(chatter->input_te))->viewRect, chatter->input_te); DrawControls(chatter->win); + chatter_draw_grow_icon(chatter); break; case activateEvt: if (event->modifiers & activeFlag) { @@ -329,6 +337,43 @@ chatter_update(struct focusable *focusable, EventRecor } void +chatter_draw_grow_icon(struct chatter *chatter) +{ + Rect r, *te; + RgnHandle tmp; + WindowPtr win = chatter->win; + + /* + * Our input bar is taller than a scrollbar, so we can't use the + * normal DrawGrowIcon or our DrawGrowIconOnly + */ + HLock(*(chatter->input_te)); + te = &(*(chatter->input_te))->viewRect; + + r = win->portRect; + r.top = r.bottom - (te->bottom - te->top + 1) - 1; + r.left = r.right - SCROLLBAR_WIDTH + 1; + r.right += 1; + r.bottom += 1; + FrameRect(&r); + + r.bottom -= 2; + r.right -= 2; + r.top = r.bottom - 9; + r.left = r.right - 9; + FrameRect(&r); + + r.top -= 5; + r.left -= 2; + r.bottom -= 5; + r.right -= 3; + FillRect(&r, white); + FrameRect(&r); + + HUnlock(*(chatter->input_te)); +} + +void chatter_mouse_down(struct focusable *focusable, EventRecord *event) { struct chatter *chatter = (struct chatter *)(focusable->cookie); @@ -409,6 +454,27 @@ chatter_mouse_down(struct focusable *focusable, EventR } } +void +chatter_resize(struct focusable *focusable, EventRecord *event) +{ + struct chatter *chatter = (struct chatter *)(focusable->cookie); + Rect bounds; + long newsize, width, height; + + bounds.left = 100; + bounds.top = 100; + bounds.right = screenBits.bounds.right; + bounds.bottom = screenBits.bounds.bottom; + + newsize = GrowWindow(focusable->win, event->where, &bounds); + + height = HiWord(newsize); + width = LoWord(newsize); + SizeWindow(focusable->win, width, height, true); + EraseRect(&chatter->win->portRect); + chatter_layout(chatter, false, NULL); +} + bool chatter_menu(struct focusable *focusable, short menu, short item) { @@ -441,30 +507,7 @@ chatter_menu(struct focusable *focusable, short menu, return false; } -#if 0 void -chatter_grow(Point p) -{ - GrafPtr old_port; - long res; - Rect r; - - GetPort(&old_port); - - SetPort(chatter_win); - SetRect(&r, 80, 80, screenBits.bounds.right, screenBits.bounds.bottom); - res = GrowWindow(chatter_win, p, &r); - if (res != 0) { - SizeWindow(chatter_win, LoWord(res), HiWord(res), false); - InvalRect(&chatter_win->portRect); - chatter_layout(); - } - - SetPort(old_port); -} -#endif - -void chatter_key_down(struct focusable *focusable, EventRecord *event) { struct chatter *chatter = (struct chatter *)(focusable->cookie); @@ -633,15 +676,21 @@ no_overflow: TESetSelect(SHRT_MAX, SHRT_MAX, chatter->messages_te); TEStylInsert(buf_out, buf_out_len, scrp_rec_h, chatter->messages_te); HUnlock(scrp_rec_h); - + HUnlock(chatter->messages_te); + + chatter_autoscroll(chatter); + + return buf_out_len; +} + +void +chatter_autoscroll(struct chatter *chatter) +{ TEPinScroll(0, -INT_MAX, chatter->messages_te); SetCtlValue(chatter->messages_scroller, GetCtlMax(chatter->messages_scroller)); UpdateScrollbarForTE(chatter->win, chatter->messages_scroller, chatter->messages_te, false); - HUnlock(chatter->messages_te); - - return buf_out_len; } void --- main.c Wed Nov 30 23:22:52 2022 +++ main.c Thu Dec 1 13:53:21 2022 @@ -159,6 +159,14 @@ main(void) case inDrag: DragWindow(event_win, event.where, &screenBits.bounds); break; + case inGrow: + if (event_win != FrontWindow() && found_focusable) { + cancel_notification(); + show_focusable(found_focusable); + } + if (found_focusable && found_focusable->resize) + found_focusable->resize(found_focusable, &event); + break; case inGoAway: if (TrackGoAway(event_win, event.where) && found_focusable && found_focusable->close)