AmendHub

Download:

jcs

/

wallops

/

amendments

/

44

focusable: Import newer version again


jcs made amendment 44 about 1 year ago
--- focusable.c Tue Aug 2 15:34:47 2022 +++ focusable.c Sat Jan 7 20:24:14 2023 @@ -23,7 +23,7 @@ struct focusable **focusables = NULL; short nfocusables = 0; struct focusable * -find_focusable(GrafPtr win) +focusable_find(GrafPtr win) { short n; @@ -35,8 +35,17 @@ find_focusable(GrafPtr win) return NULL; } +struct focusable * +focusable_focused(void) +{ + if (nfocusables && focusables[0]->visible) + return focusables[0]; + + return NULL; +} + void -add_focusable(struct focusable *focusable) +focusable_add(struct focusable *focusable) { short n; @@ -50,17 +59,22 @@ add_focusable(struct focusable *focusable) focusables[0] = focusable; - show_focusable(focusable); + focusable_show(focusable); } -void -show_focusable(struct focusable *focusable) +bool +focusable_show(struct focusable *focusable) { struct focusable *last, *tmp; short n; if (nfocusables > 1 && focusables[0] != focusable) { last = focusables[0]; + + if (last->modal) + /* other focusables cannot steal focus from modals */ + return false; + focusables[0] = focusable; for (n = 1; n < nfocusables; n++) { tmp = focusables[n]; @@ -71,19 +85,28 @@ show_focusable(struct focusable *focusable) } } - focusable->visible = true; - ShowWindow(focusable->win); + if (!focusable->visible) { + focusable->visible = true; + ShowWindow(focusable->win); + } + SelectWindow(focusable->win); + SetPort(focusable->win); + + return true; } -void -destroy_focusable(struct focusable *focusable) +bool +focusable_close(struct focusable *focusable) { short n; - if (focusable->visible) - CloseWindow(focusable->win); - + if (focusable->close) { + if (!focusable->close(focusable)) + return false; + } else + DisposeWindow(focusable->win); + for (n = 0; n < nfocusables; n++) { if (focusables[n] == focusable) { for (; n < nfocusables - 1; n++) @@ -95,19 +118,17 @@ destroy_focusable(struct focusable *focusable) nfocusables--; if (nfocusables) focusables = xreallocarray(focusables, sizeof(Ptr), nfocusables); - else { + else xfree(&focusables); - focusables = NULL; - } if (nfocusables && focusables[0]->visible) - SelectWindow(focusables[0]->win); - - /* focusable is now bogus */ + focusable_show(focusables[0]); + + return true; } void -hide_focusable(struct focusable *focusable) +focusable_hide(struct focusable *focusable) { short n; @@ -122,4 +143,34 @@ hide_focusable(struct focusable *focusable) } } focusables[nfocusables - 1] = focusable; -} +} + +bool +focusables_quit(void) +{ + short tnfocusables = nfocusables; + short n; + struct focusable **tfocusables; + bool quit = true; + + if (nfocusables) { + /* + * nfocusables and focusables array will probably be + * modified as each focusable quits + */ + tfocusables = xcalloc(sizeof(Ptr), tnfocusables, "tfocusables"); + memcpy(tfocusables, focusables, sizeof(Ptr) * tnfocusables); + + for (n = 0; n < tnfocusables; n++) { + if (tfocusables[n] && tfocusables[n]->quit && + !tfocusables[n]->quit(tfocusables[n])) { + quit = false; + break; + } + } + + xfree(&tfocusables); + } + + return quit; +} --- focusable.h Fri Nov 18 13:30:48 2022 +++ focusable.h Sat Jan 7 19:16:17 2023 @@ -23,6 +23,7 @@ struct focusable { WindowPtr win; bool visible; void *cookie; + bool modal; short (*wait_type)(struct focusable *focusable); void (*idle)(struct focusable *focusable, EventRecord *event); void (*update)(struct focusable *focusable, EventRecord *event); @@ -30,19 +31,21 @@ struct focusable { void (*mouse_down)(struct focusable *focusable, EventRecord *event); void (*resize)(struct focusable *focusable, EventRecord *event); bool (*menu)(struct focusable *focusable, short menu, short item); - void (*close)(struct focusable *focusable, EventRecord *event); void (*suspend)(struct focusable *focusable, EventRecord *event); void (*resume)(struct focusable *focusable, EventRecord *event); + bool (*close)(struct focusable *focusable); bool (*quit)(struct focusable *focusable); void (*atexit)(struct focusable *focusable); }; extern struct focusable **focusables; extern short nfocusables; -struct focusable * find_focusable(GrafPtr win); -void add_focusable(struct focusable *focusable); -void show_focusable(struct focusable *focusable); -void destroy_focusable(struct focusable *focusable); -void hide_focusable(struct focusable *focusable); +struct focusable * focusable_find(GrafPtr win); +struct focusable * focusable_focused(void); +void focusable_add(struct focusable *focusable); +bool focusable_show(struct focusable *focusable); +bool focusable_close(struct focusable *focusable); +void focusable_hide(struct focusable *focusable); +bool focusables_quit(void); #endif