AmendHub

Download

jcs

/

wallops

/

focusable.c

 

(View History)

jcs   *: Cleanup panic messages Latest amendment: 121 on 2024-09-18

1 /*
2 * Copyright (c) 2021-2022 joshua stein <jcs@jcs.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17 #include <string.h>
18
19 #include "focusable.h"
20 #include "util.h"
21
22 struct focusable **focusables = NULL;
23 short nfocusables = 0;
24
25 struct focusable *
26 focusable_find(GrafPtr win)
27 {
28 short n;
29
30 for (n = 0; n < nfocusables; n++) {
31 if (focusables[n]->win == win)
32 return focusables[n];
33 }
34
35 return NULL;
36 }
37
38 struct focusable *
39 focusable_focused(void)
40 {
41 if (nfocusables && focusables[0]->visible)
42 return focusables[0];
43
44 return NULL;
45 }
46
47 void
48 focusable_add(struct focusable *focusable)
49 {
50 short n, id;
51 bool found;
52
53 nfocusables++;
54 focusables = xreallocarray(focusables, sizeof(struct focusable *),
55 nfocusables);
56
57 if (nfocusables > 1)
58 for (n = nfocusables - 1; n > 0; n--)
59 focusables[n] = focusables[n - 1];
60
61 focusables[0] = focusable;
62
63 focusable->id = -1;
64 for (id = 0; id < nfocusables; id++) {
65 found = false;
66 for (n = 0; n < nfocusables; n++) {
67 if (focusables[n]->id == id) {
68 found = true;
69 break;
70 }
71 }
72 if (!found) {
73 focusable->id = id;
74 break;
75 }
76 }
77 if (focusable->id == -1)
78 panic("No focusable id");
79
80 focusable_show(focusable);
81 }
82
83 bool
84 focusable_show(struct focusable *focusable)
85 {
86 struct focusable *last, *tmp;
87 short n;
88
89 if (nfocusables > 1 && focusables[0] != focusable) {
90 last = focusables[0];
91
92 if (last->modal)
93 /* other focusables cannot steal focus from modals */
94 return false;
95
96 focusables[0] = focusable;
97 for (n = 1; n < nfocusables; n++) {
98 tmp = focusables[n];
99 focusables[n] = last;
100 last = tmp;
101 if (last == focusable)
102 break;
103 }
104 }
105
106 focusable->visible = true;
107 ShowWindow(focusable->win);
108 SelectWindow(focusable->win);
109 SetPort(focusable->win);
110
111 return true;
112 }
113
114 bool
115 focusable_close(struct focusable *focusable)
116 {
117 short n;
118
119 if (focusable->close) {
120 if (!focusable->close(focusable))
121 return false;
122 } else
123 DisposeWindow(focusable->win);
124
125 for (n = 0; n < nfocusables; n++) {
126 if (focusables[n] == focusable) {
127 for (; n < nfocusables - 1; n++)
128 focusables[n] = focusables[n + 1];
129 break;
130 }
131 }
132
133 nfocusables--;
134 if (nfocusables)
135 focusables = xreallocarray(focusables, sizeof(Ptr), nfocusables);
136 else
137 xfree(&focusables);
138
139 if (nfocusables && focusables[0]->visible)
140 focusable_show(focusables[0]);
141
142 return true;
143 }
144
145 void
146 focusable_hide(struct focusable *focusable)
147 {
148 short n;
149
150 HideWindow(focusable->win);
151 focusable->visible = false;
152
153 for (n = 0; n < nfocusables; n++) {
154 if (focusables[n] == focusable) {
155 for (; n < nfocusables - 1; n++)
156 focusables[n] = focusables[n + 1];
157 break;
158 }
159 }
160 focusables[nfocusables - 1] = focusable;
161 }
162
163 bool
164 focusables_quit(void)
165 {
166 short tnfocusables = nfocusables;
167 short n;
168 struct focusable **tfocusables;
169 bool quit = true;
170
171 if (nfocusables) {
172 /*
173 * nfocusables and focusables array will probably be
174 * modified as each focusable quits
175 */
176 tfocusables = xcalloc(sizeof(Ptr), tnfocusables);
177 memcpy(tfocusables, focusables, sizeof(Ptr) * tnfocusables);
178
179 for (n = 0; n < tnfocusables; n++) {
180 if (tfocusables[n] && tfocusables[n]->quit &&
181 !tfocusables[n]->quit(tfocusables[n])) {
182 quit = false;
183 break;
184 }
185 }
186
187 xfree(&tfocusables);
188 }
189
190 return quit;
191 }