Download
jcs
/subtext
/focusable.c
(View History)
jcs focusable: Allow add_focusable to fail | Latest amendment: 339 on 2023-03-02 |
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 | find_focusable(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 | bool |
39 | add_focusable(struct focusable *focusable) |
40 | { |
41 | short n; |
42 | struct focusable **new_focusables; |
43 | |
44 | new_focusables = xreallocarray(focusables, sizeof(struct focusable *), |
45 | nfocusables + 1); |
46 | if (new_focusables == NULL) |
47 | return false; |
48 | |
49 | focusables = new_focusables; |
50 | nfocusables++; |
51 | |
52 | if (nfocusables > 1) |
53 | for (n = nfocusables - 1; n > 0; n--) |
54 | focusables[n] = focusables[n - 1]; |
55 | |
56 | focusables[0] = focusable; |
57 | |
58 | show_focusable(focusable); |
59 | return true; |
60 | } |
61 | |
62 | void |
63 | show_focusable(struct focusable *focusable) |
64 | { |
65 | struct focusable *last, *tmp; |
66 | short n; |
67 | |
68 | if (nfocusables > 1 && focusables[0] != focusable) { |
69 | last = focusables[0]; |
70 | focusables[0] = focusable; |
71 | for (n = 1; n < nfocusables; n++) { |
72 | tmp = focusables[n]; |
73 | focusables[n] = last; |
74 | last = tmp; |
75 | if (last == focusable) |
76 | break; |
77 | } |
78 | } |
79 | |
80 | focusable->visible = true; |
81 | ShowWindow(focusable->win); |
82 | SelectWindow(focusable->win); |
83 | } |
84 | |
85 | void |
86 | destroy_focusable(struct focusable *focusable) |
87 | { |
88 | short n; |
89 | |
90 | if (focusable->visible) |
91 | CloseWindow(focusable->win); |
92 | |
93 | for (n = 0; n < nfocusables; n++) { |
94 | if (focusables[n] == focusable) { |
95 | for (; n < nfocusables - 1; n++) |
96 | focusables[n] = focusables[n + 1]; |
97 | break; |
98 | } |
99 | } |
100 | |
101 | nfocusables--; |
102 | if (nfocusables) |
103 | focusables = xreallocarray(focusables, sizeof(Ptr), nfocusables); |
104 | else { |
105 | xfree(&focusables); |
106 | focusables = NULL; |
107 | } |
108 | |
109 | if (nfocusables && focusables[0]->visible) |
110 | SelectWindow(focusables[0]->win); |
111 | |
112 | /* focusable is now bogus */ |
113 | } |
114 | |
115 | void |
116 | hide_focusable(struct focusable *focusable) |
117 | { |
118 | short n; |
119 | |
120 | HideWindow(focusable->win); |
121 | focusable->visible = false; |
122 | |
123 | for (n = 0; n < nfocusables; n++) { |
124 | if (focusables[n] == focusable) { |
125 | for (; n < nfocusables - 1; n++) |
126 | focusables[n] = focusables[n + 1]; |
127 | break; |
128 | } |
129 | } |
130 | focusables[nfocusables - 1] = focusable; |
131 | } |