chiark / gitweb /
Create readable text `.bas' for each tokenized BASIC `,ffb' file.
[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 }