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