1 /*
2  *  This file is part of the XForms library package.
3  *
4  *  XForms is free software; you can redistribute it and/or modify it
5  *  under the terms of the GNU Lesser General Public License as
6  *  published by the Free Software Foundation; either version 2.1, or
7  *  (at your option) any later version.
8  *
9  *  XForms is distributed in the hope that it will be useful, but
10  *  WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  *  Lesser General Public License for more details.
13  *
14  *  You should have received a copy of the GNU Lesser General Public License
15  *  along with XForms.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 
19 /**
20  * \file child.c
21  *
22  *  This file is part of the XForms library package.
23  *  Copyright (c) 1996-2002  T.C. Zhao
24  *  All rights reserved.
25  */
26 
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30 
31 #include "include/forms.h"
32 #include "flinternal.h"
33 
34 
35 /***************************************
36  ***************************************/
37 
38 void
fl_add_child(FL_OBJECT * parent,FL_OBJECT * child)39 fl_add_child( FL_OBJECT * parent,
40               FL_OBJECT * child )
41 {
42     FL_OBJECT *t;
43 
44     /* If the child is already linked to a form that is not the one of the
45        parent unlink it from that form and then add it to the parents
46        form (if the parent already belongs to one) */
47 
48     if ( child->form && child->form != parent->form )
49         fl_delete_object( child );
50 
51     if ( ! child->form && parent->form )
52         fl_add_object( parent->form, child );
53 
54     /* Now set up the parent-child relationship */
55 
56     child->parent = parent;
57 
58     /* Child gets same gravity and resize attributes as the parent */
59 
60     child->nwgravity = parent->nwgravity;
61     child->segravity = parent->segravity;
62     child->resize    = parent->resize;
63 
64     /* Append the new child to the linked list of objects that are
65        children of the parent */
66 
67     if ( parent->child == NULL )
68         parent->child = child;
69     else
70     {
71         for ( t = parent->child; t->nc; t = t->nc )
72             /* empty */ ;
73         t->nc = child;
74     }
75 
76     /* If the child itself has children set their gravity and resizing
77        behaviour to that of the parent */
78 
79     if ( ! child->child )
80     {
81         parent = child;
82 
83         for ( child = child->child; child; child = child->nc )
84         {
85             fli_set_composite_gravity( child, parent->nwgravity,
86                                        parent->segravity );
87             fli_set_composite_resize( child, parent->resize );
88         }
89     }
90 }
91 
92 
93 /***************************************
94  * Adds all children of an object to its form
95  ***************************************/
96 
97 void
fli_add_composite(FL_OBJECT * obj)98 fli_add_composite( FL_OBJECT * obj )
99 {
100     FL_FORM *form = obj->form;
101     FL_OBJECT *tmp;
102 
103     for ( tmp = obj->child; tmp; tmp = tmp->nc )
104     {
105         tmp->parent = obj;
106         fl_add_object( form, tmp );
107     }
108 }
109 
110 
111 /***************************************
112  * Inserts all children of a object before the object 'before'
113  ***************************************/
114 
115 void
fli_insert_composite(FL_OBJECT * obj,FL_OBJECT * before)116 fli_insert_composite( FL_OBJECT * obj,
117                       FL_OBJECT * before )
118 {
119     FL_OBJECT *tmp;
120 
121     for ( tmp = obj->child; tmp; tmp = tmp->nc )
122     {
123         tmp->parent = obj;
124         fli_insert_object( tmp, before );
125     }
126 }
127 
128 
129 /***************************************
130  * Unlinks all children of an object from its form
131  ***************************************/
132 
133 void
fli_delete_composite(FL_OBJECT * obj)134 fli_delete_composite( FL_OBJECT * obj )
135 {
136     for ( obj = obj->child; obj; obj = obj->nc )
137         if ( obj->form )
138             fl_delete_object( obj );
139 }
140 
141 
142 /***************************************
143  * Irrevocably deletes all children of an object
144  ***************************************/
145 
146 void
fli_free_composite(FL_OBJECT * obj)147 fli_free_composite( FL_OBJECT * obj )
148 {
149     FL_OBJECT *next,
150               *parent = obj;
151 
152     for ( obj = obj->child; obj; obj = next )
153     {
154         next = obj->nc;
155         fl_free_object( obj ) ;
156     }
157 
158     parent->child = NULL;
159 }
160 
161 
162 /***************************************
163  ***************************************/
164 
165 void
fli_show_composite(FL_OBJECT * obj)166 fli_show_composite( FL_OBJECT * obj )
167 {
168     for ( obj = obj->child; obj; obj = obj->nc )
169         fli_show_object( obj );
170 }
171 
172 
173 /***************************************
174  ***************************************/
175 
176 void
fli_hide_composite(FL_OBJECT * obj,Region * reg)177 fli_hide_composite( FL_OBJECT * obj,
178                     Region    * reg )
179 {
180     for ( obj = obj->child; obj; obj = obj->nc )
181     {
182         if ( obj->child )
183             fli_hide_composite( obj, reg );
184 
185         fli_hide_and_get_region( obj, reg );
186     }
187 }
188 
189 
190 /***************************************
191  ***************************************/
192 
193 void
fli_activate_composite(FL_OBJECT * ob)194 fli_activate_composite( FL_OBJECT * ob )
195 {
196     for ( ob = ob->child; ob; ob = ob->nc )
197     {
198         if ( ob->child )
199             fli_activate_composite( ob );
200         ob->active = 1;
201     }
202 }
203 
204 
205 /***************************************
206  ***************************************/
207 
208 void
fli_deactivate_composite(FL_OBJECT * ob)209 fli_deactivate_composite( FL_OBJECT * ob )
210 {
211     for ( ob = ob->child; ob; ob = ob->nc )
212     {
213         if ( ob->child )
214             fli_deactivate_composite( ob );
215 
216         ob->active = 0;
217     }
218 }
219 
220 
221 /***************************************
222  ***************************************/
223 
224 void
fli_set_composite_resize(FL_OBJECT * obj,unsigned int resize)225 fli_set_composite_resize( FL_OBJECT *  obj,
226                           unsigned int resize )
227 {
228     for ( obj = obj->child; obj; obj = obj->nc )
229     {
230         if ( obj->child )
231             fli_set_composite_resize( obj, resize );
232         obj->resize = resize;
233     }
234 }
235 
236 
237 /***************************************
238  * Sets the gravity property for the children of an object
239  * (and their children in turn)
240  ***************************************/
241 
242 void
fli_set_composite_gravity(FL_OBJECT * obj,unsigned int nw,unsigned int se)243 fli_set_composite_gravity( FL_OBJECT *  obj,
244                            unsigned int nw,
245                            unsigned int se )
246 {
247     for ( obj = obj->child; obj; obj = obj->nc )
248     {
249         if ( obj->child )
250             fli_set_composite_gravity( obj, nw, se );
251 
252         obj->nwgravity = nw;
253         obj->segravity = se;
254     }
255 }
256 
257 
258 /***************************************
259  ***************************************/
260 
261 void
fli_composite_has_been_resized(FL_OBJECT * obj)262 fli_composite_has_been_resized( FL_OBJECT * obj )
263 {
264     for ( obj = obj->child; obj; obj = obj->nc )
265     {
266         if ( obj->child )
267             fli_composite_has_been_resized( obj );
268         fli_handle_object( obj, FL_RESIZED, 0, 0, 0, NULL, 0 );
269     }
270 }
271 
272 
273 /***************************************
274  * Inserts a composite object into a form after object 'after'
275  ***************************************/
276 
277 void
fli_insert_composite_after(FL_OBJECT * obj,FL_OBJECT * after)278 fli_insert_composite_after( FL_OBJECT * obj,
279                             FL_OBJECT * after )
280 {
281     FL_OBJECT *next,
282               *tmp,
283               *prev;
284     FL_FORM *form;
285 
286     if ( ! obj || ! after )
287     {
288         M_err( "fli_insert_composite_after", "Bad argument" );
289         return;
290     }
291 
292     if ( ! ( form = after->form ) )
293     {
294         M_err( "fli_insert_composite_after", "Null form" );
295         return;
296     }
297 
298     obj->form = form;
299 
300     next            = after->next;
301     after->next     = obj;
302     obj->prev       = after;
303     obj->next       = obj->child;
304     obj->next->prev = obj;
305     prev            = obj;
306 
307     for ( tmp = obj->child; tmp->nc; prev = tmp, tmp = tmp->nc )
308     {
309         tmp->parent = obj;
310         tmp->form   = form;
311         tmp->next   = tmp->nc;
312         tmp->prev   = prev;
313     }
314 
315     tmp->next = next;
316     tmp->prev = prev;
317     tmp->form = form;
318 
319     if ( form->last == after )
320         form->last = tmp;
321 }
322 
323 
324 /***************************************
325  ***************************************/
326 
327 FL_OBJECT *
fl_get_object_component(FL_OBJECT * composite,int objclass,int type,int numb)328 fl_get_object_component( FL_OBJECT * composite,
329                          int         objclass,
330                          int         type,
331                          int         numb )
332 {
333     FL_OBJECT *tmp;
334     int n;
335 
336     for ( n = 0, tmp = composite->child; tmp; tmp = tmp->nc )
337         if ( tmp->objclass == objclass && ( tmp->type == type || type < 0 ) )
338         {
339             if ( ++n >= numb )
340                 return tmp;
341         }
342 
343     M_err( "fl_get_object_component", "Requested object not found" );
344 
345     return NULL;
346 }
347 
348 
349 /***************************************
350  * copy the parent attributes. gravity stuff is taken care of by
351  * fl_add_child()
352  ***************************************/
353 
354 void
fli_inherit_attributes(FL_OBJECT * parent,FL_OBJECT * child)355 fli_inherit_attributes( FL_OBJECT * parent,
356                         FL_OBJECT * child )
357 {
358     child->bw     = parent->bw;
359     child->lcol   = parent->lcol;
360     child->col1   = parent->col1;
361     child->lsize  = parent->lsize;
362     child->lstyle = parent->lstyle;
363 
364     if ( ! child->child )
365         return;
366 
367     parent = child;
368 
369     for ( child = child->child; child; child = child->nc )
370         fli_inherit_attributes( parent, child );
371 }
372 
373 
374 /*
375  * Local variables:
376  * tab-width: 4
377  * indent-tabs-mode: nil
378  * End:
379  */
380