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