Initial revision
[ssr] / StraySrc / Libraries / Steel / c / pane
1 /*
2 * Pane
3 * Handles all those many problems you get with panes
4 *
5 * v. 1.100 (25 July 1993)
6 *
7 * © 1993-1998 Straylight
8 */
9
10 /*----- Licensing note ----------------------------------------------------*
11 *
12 * This file is part of Straylight's Steel library.
13 *
14 * Steel is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2, or (at your option)
17 * any later version.
18 *
19 * Steel is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with Steel. If not, write to the Free Software Foundation,
26 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 */
28
29 #include "wimp.h"
30 #include "wimpt.h"
31 #include "pane.h"
32 #include "werr.h"
33 #include "msgs.h"
34 #include "mem.h"
35 #include "win.h"
36 #include <stdlib.h>
37
38 typedef enum
39 {
40 pane__WINDOW,
41 pane__LISTBOX
42 }
43 pane__paneType;
44
45 typedef union
46 {
47 list l;
48 }
49 pane__handle;
50
51 typedef struct pane__paneItem
52 {
53 struct pane__paneItem *next;
54 wimp_w pane;
55 pane__paneType type;
56 pane__handle handle;
57 wimp_box box;
58 }
59 pane__paneItem;
60
61 typedef struct pane__panestr
62 {
63 wimp_w tool;
64 pane__paneItem *panes;
65 }
66 pane__panestr;
67
68 /*
69 * pane pane_create(wimp_w tool)
70 *
71 * Use
72 * Sets up a structure for a pane, and returns a handle.
73 *
74 * Parameters
75 * wimp_w tool == the window handle of the tool window (the one that isn't
76 * a pane)
77 *
78 * Returns
79 * An abstract handle to the pane.
80 */
81
82 pane pane_create(wimp_w tool)
83 {
84 pane newPane=(pane)mem_alloc(sizeof(pane__panestr));
85 if (newPane)
86 {
87 newPane->tool=tool;
88 newPane->panes=0;
89 }
90 else
91 werr(FALSE,msgs_lookup("paneNEM:Not enough memory to register pane."));
92 return (newPane);
93 }
94
95 /*
96 * void pane_addPane(pane p,wimp_w w)
97 *
98 * Use
99 * Registers a new pane as being associated with the tool window given in
100 * pane_create().
101 *
102 * Parameters
103 * pane p == the pane handle for the tool window
104 * wimp_w w == the window handle of the new pane
105 */
106
107 void pane_addPane(pane p,wimp_w w)
108 {
109 pane__paneItem *new;
110 wimp_wstate ts;
111 wimp_wstate ps;
112 if (p==0)
113 return;
114 if (new=mem_alloc(sizeof(pane__paneItem)),!new)
115 return;
116 new->pane=w;
117 new->type=pane__WINDOW;
118 wimpt_noerr(wimp_get_wind_state(w,&ps));
119 wimpt_noerr(wimp_get_wind_state(p->tool,&ts));
120 new->box.x0=ps.o.box.x0-ts.o.box.x0;
121 new->box.y0=ps.o.box.y0-ts.o.box.y0;
122 new->box.x1=ps.o.box.x1-ts.o.box.x0;
123 new->box.y1=ps.o.box.y1-ts.o.box.y0;
124 new->next=p->panes;
125 p->panes=new;
126 }
127
128 /*
129 * void pane_addListbox(pane p,list l)
130 *
131 * Use
132 * Adds a listbox to the tool window. Handles things properly, so that
133 * scroll bars and things appear at the right time.
134 *
135 * Parameters
136 * pane p == the pane to add to
137 * list l == the list to add
138 */
139
140 void pane_addListbox(pane p,list l)
141 {
142 wimp_w w=list_syshandle(l);
143 pane__paneItem *new;
144 wimp_wstate ts;
145 wimp_wstate ps;
146 list_isPane(l,p);
147 if (p==0)
148 return;
149 if (new=mem_alloc(sizeof(pane__paneItem)),!new)
150 return;
151 new->pane=w;
152 new->type=pane__LISTBOX;
153 new->handle.l=l;
154 wimpt_noerr(wimp_get_wind_state(w,&ps));
155 wimpt_noerr(wimp_get_wind_state(p->tool,&ts));
156 new->box.x0=ps.o.box.x0-ts.o.box.x0;
157 new->box.y0=ps.o.box.y0-ts.o.box.y0;
158 new->box.x1=ps.o.box.x1-ts.o.box.x0;
159 new->box.y1=ps.o.box.y1-ts.o.box.y0;
160 new->next=p->panes;
161 p->panes=new;
162 }
163
164 /*
165 * void pane_delete(pane p)
166 *
167 * Use
168 * Destroys and mem_free()s the memory occupied by a pane structure.
169 *
170 * Parameters
171 * pane p == the pane's handle
172 */
173
174 void pane_delete(pane p)
175 {
176 pane__paneItem *itm=p->panes;
177 pane__paneItem *i;
178 while (itm)
179 {
180 i=itm;
181 itm=i->next;
182 switch (i->type)
183 {
184 case pane__LISTBOX:
185 list_isPane(i->handle.l,0);
186 break;
187 }
188 mem_free(i);
189 }
190 mem_free(p);
191 }
192
193 /*
194 * void pane_removePane(pane p,wimp_w w)
195 *
196 * Use
197 * Removes the specified pane from the structure.
198 *
199 * Parameters
200 * pane p == the pane in question
201 * wimp_w w == the window to remove
202 */
203
204 void pane_removePane(pane p,wimp_w w)
205 {
206 pane__paneItem *i=(pane__paneItem *)(&p->panes);
207 pane__paneItem *it;
208 while (i->next)
209 {
210 if (i->next->pane==w)
211 {
212 it=i->next;
213 i->next=it->next;
214 switch (it->type)
215 {
216 case pane__LISTBOX:
217 list_isPane(it->handle.l,0);
218 break;
219 }
220 mem_free(it);
221 return;
222 }
223 i=i->next;
224 }
225 }
226
227 /*
228 * void pane__doMove(pane p,wimp_openstr *o)
229 *
230 * Use
231 * Moves a set of panes to the place specified.
232 *
233 * Parameters
234 * pane p == the pane handle
235 * wimp_openstr *o == where to put them
236 */
237
238 static void pane__doMove(pane p,wimp_openstr *o)
239 {
240 pane__paneItem *i=p->panes;
241 wimp_wstate state;
242 wimp_w behind;
243 behind=o->behind;
244 if (behind==-2)
245 {
246 wimpt_noerr(wimp_open_wind(o));
247 wimpt_noerr(wimp_get_wind_state(o->w,&state));
248 behind=state.o.behind;
249 i=p->panes;
250 if (behind==i->pane)
251 {
252 wimpt_noerr(wimp_get_wind_state(i->pane,&state));
253 behind=state.o.behind;
254 }
255 }
256 i=p->panes;
257 while (i)
258 {
259 wimpt_noerr(wimp_get_wind_state(i->pane,&state));
260 state.o.box.x0=o->box.x0+i->box.x0;
261 state.o.box.y0=o->box.y0+i->box.y0;
262 state.o.box.x1=o->box.x0+i->box.x1;
263 state.o.box.y1=o->box.y0+i->box.y1;
264 state.o.behind=behind;
265 behind=i->pane;
266 wimpt_noerr(wimp_open_wind(&state.o));
267 i=i->next;
268 }
269 o->behind=behind;
270 wimpt_noerr(wimp_open_wind(o));
271 }
272
273 /*
274 * void pane_updatePanes(pane p)
275 *
276 * Use
277 * Updates position of panes attached to the main window after it has been
278 * moved.
279 *
280 * Parameters
281 * pane p == the pane handle
282 */
283
284 void pane_updatePanes(pane p)
285 {
286 wimp_wstate s;
287 wimpt_noerr(wimp_get_wind_state(p->tool,&s));
288 pane__doMove(p,&s.o);
289 }
290
291 /*
292 * void pane_moved(pane p)
293 *
294 * Use
295 * Asks the pane segment to reopen a pane in response to an wimp_EOPEN
296 * event.
297 *
298 * Parameters
299 * pane p == the pane handle
300 */
301
302 void pane_moved(pane p)
303 {
304 wimp_eventstr *e=wimpt_last_event();
305 if (e->e!=wimp_EOPEN || e->data.o.w!=p->tool)
306 {
307 werr
308 (
309 TRUE,
310 msgs_lookup("paneIPH:(pane_moved, caller fault): "
311 "not a wimp_EOPEN event or with wrong pane handle.")
312 );
313 return;
314 }
315 if (wimpt_justChangedMode())
316 win_adjustBox(&e->data.o);
317 pane__doMove(p,&e->data.o);
318 }
319
320 /*
321 * void pane_front(pane p)
322 *
323 * Use
324 * Moves a tool window and associated panes to the front of the screen.
325 *
326 * Parameters
327 * pane p == the pane handle
328 */
329
330 void pane_front(pane p)
331 {
332 wimp_wstate s;
333 wimpt_noerr(wimp_get_wind_state(p->tool,&s));
334 s.o.behind=-1;
335 pane__doMove(p,&s.o);
336 }
337
338 /*
339 * void pane_close(pane p)
340 *
341 * Use
342 * This routine will close all the windows attached to the pane structure.
343 *
344 * Parameters
345 * pane p == the pane handle
346 */
347
348 void pane_close(pane p)
349 {
350 pane__paneItem *i=p->panes;
351 wimpt_noerr(wimp_close_wind(p->tool));
352 while (i)
353 {
354 wimpt_noerr(wimp_close_wind(i->pane));
355 i=i->next;
356 }
357 }