AmendHub

Download

jcs

/

amend

/

focusable.c

 

(View History)

jcs   *: Bring in util from Subtext with malloc debugging, integrate it Latest amendment: 92 on 2022-08-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;
51
52 nfocusables++;
53 focusables = xreallocarray(focusables, sizeof(struct focusable *),
54 nfocusables);
55
56 if (nfocusables > 1)
57 for (n = nfocusables - 1; n > 0; n--)
58 focusables[n] = focusables[n - 1];
59
60 focusables[0] = focusable;
61
62 focusable_show(focusable);
63 }
64
65 bool
66 focusable_show(struct focusable *focusable)
67 {
68 struct focusable *last, *tmp;
69 short n;
70
71 if (nfocusables > 1 && focusables[0] != focusable) {
72 last = focusables[0];
73
74 if (last->modal)
75 /* other focusables cannot steal focus from modals */
76 return false;
77
78 focusables[0] = focusable;
79 for (n = 1; n < nfocusables; n++) {
80 tmp = focusables[n];
81 focusables[n] = last;
82 last = tmp;
83 if (last == focusable)
84 break;
85 }
86 }
87
88 if (!focusable->visible) {
89 focusable->visible = true;
90 ShowWindow(focusable->win);
91 }
92
93 SelectWindow(focusable->win);
94 SetPort(focusable->win);
95
96 return true;
97 }
98
99 bool
100 focusable_close(struct focusable *focusable)
101 {
102 short n;
103
104 if (focusable->close) {
105 if (!focusable->close(focusable))
106 return false;
107 } else
108 DisposeWindow(focusable->win);
109
110 for (n = 0; n < nfocusables; n++) {
111 if (focusables[n] == focusable) {
112 for (; n < nfocusables - 1; n++)
113 focusables[n] = focusables[n + 1];
114 break;
115 }
116 }
117
118 nfocusables--;
119 if (nfocusables)
120 focusables = xreallocarray(focusables, sizeof(Ptr), nfocusables);
121 else
122 xfree(&focusables);
123
124 if (nfocusables && focusables[0]->visible)
125 focusable_show(focusables[0]);
126
127 return true;
128 }
129
130 void
131 focusable_hide(struct focusable *focusable)
132 {
133 short n;
134
135 HideWindow(focusable->win);
136 focusable->visible = false;
137
138 for (n = 0; n < nfocusables; n++) {
139 if (focusables[n] == focusable) {
140 for (; n < nfocusables - 1; n++)
141 focusables[n] = focusables[n + 1];
142 break;
143 }
144 }
145 focusables[nfocusables - 1] = focusable;
146 }
147
148 bool
149 focusables_quit(void)
150 {
151 short tnfocusables = nfocusables;
152 short n;
153 struct focusable **tfocusables;
154 bool quit = true;
155
156 if (nfocusables) {
157 /*
158 * nfocusables and focusables array will probably be
159 * modified as each focusable quits
160 */
161 tfocusables = xcalloc(sizeof(Ptr), tnfocusables, "tfocusables");
162 memcpy(tfocusables, focusables, sizeof(Ptr) * tnfocusables);
163
164 for (n = 0; n < tnfocusables; n++) {
165 if (tfocusables[n] && !focusable_close(tfocusables[n])) {
166 quit = false;
167 break;
168 }
169 }
170
171 xfree(&tfocusables);
172 }
173
174 return quit;
175 }