Text.mui cleanup:
[AROS.git] / workbench / libs / muimaster / classes / family.c
blob222a70fe712f5a3e51bc0390ab3b9ed0c144949e
1 /*
2 Copyright © 1999, David Le Corfec.
3 Copyright © 2002-2013, The AROS Development Team.
4 All rights reserved.
6 $Id$
7 */
9 #include <exec/types.h>
11 #include <clib/alib_protos.h>
12 #include <proto/exec.h>
13 #include <proto/intuition.h>
14 #include <proto/utility.h>
15 #include <proto/muimaster.h>
17 /* #define MYDEBUG 1 */
18 #include "debug.h"
19 #include "muimaster_intern.h"
20 #include "mui.h"
22 extern struct Library *MUIMasterBase;
24 struct MUI_FamilyData
26 struct List children;
30 * Family class is the base class for objects that are able
31 * to handle a list of children. This is e.g. the case for
32 * MUIs Menustrip, Menu and Menuitem objects.
33 * Group class and application class should also be a
34 * subclass of Family class, but due to BOOPSI system
35 * limitations, this is currently impossible.
39 Family.mui/MUIA_Family_Child [I..] done (note : == MUIA_Group_Child)
40 Family.mui/MUIA_Family_List [..G] done
42 Family.mui/MUIM_Family_AddHead done
43 Family.mui/MUIM_Family_AddTail done
44 Family.mui/MUIM_Family_Insert done
45 Family.mui/MUIM_Family_Remove done
46 Family.mui/MUIM_Family_Sort done
47 Family.mui/MUIM_Family_Transfer done
48 Notify.mui/MUIM_FindUData done
49 Notify.mui/MUIM_GetUData done
50 Notify.mui/MUIM_SetUData done
51 Notify.mui/MUIM_SetUDataOnce done
54 static const int __version = 1;
55 static const int __revision = 1;
57 /* static void */
58 /* debuglist(struct List *list) */
59 /* { */
60 /* g_print("list %p:\nlh_Head@%p = %p\nlh_Tail@%p = %p\nlh_TailPred@%p = %p\n", */
61 /* list, &list->lh_Head, list->lh_Head, */
62 /* &list->lh_Tail, list->lh_Tail, */
63 /* &list->lh_TailPred, list->lh_TailPred); */
64 /* } */
66 /* static void */
67 /* printlist (struct List *list) */
68 /* { */
69 /* struct Node *node; */
71 /* debuglist(list); */
73 /* for (node = list->lh_Head; node->ln_Succ; node = node->ln_Succ) */
74 /* { */
75 /* g_print("%s (ln_Succ@%p = %p | ln_Pred@%p = %p)\n", "node->ln_Name", */
76 /* &node->ln_Succ, node->ln_Succ, &node->ln_Pred, node->ln_Pred); */
77 /* } */
78 /* g_print("\n"); */
79 /* } */
82 * OM_NEW
84 IPTR Family__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
86 struct MUI_FamilyData *data;
87 struct TagItem *tags;
88 struct TagItem *tag;
89 BOOL bad_children = FALSE;
91 obj = (Object *) DoSuperMethodA(cl, obj, (Msg) msg);
92 if (!obj)
93 return FALSE;
95 * Initial local instance data
97 data = INST_DATA(cl, obj);
98 NewList(&(data->children));
101 * parse initial taglist
103 for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags));)
105 if (tag->ti_Tag == MUIA_Family_Child
106 || tag->ti_Tag == MUIA_Group_Child)
108 if (tag->ti_Data) /* add child */
109 DoMethod(obj, MUIM_Family_AddTail, tag->ti_Data);
110 else /* fail and dispose children */
112 bad_children = TRUE;
117 if (bad_children)
119 CoerceMethod(cl, obj, OM_DISPOSE);
120 return 0;
123 return (IPTR) obj;
128 * OM_DISPOSE
130 IPTR Family__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
132 struct MUI_FamilyData *data = INST_DATA(cl, obj);
133 Object *cstate = (Object *) data->children.lh_Head;
134 Object *child;
136 while ((child = NextObject(&cstate)))
138 /* g_print("Family_Dispose: dispose child %p\n", child); */
139 MUI_DisposeObject(child);
142 return DoSuperMethodA(cl, obj, msg);
147 * OM_GET
149 IPTR Family__OM_GET(struct IClass *cl, Object *obj, struct opGet *msg)
151 struct MUI_FamilyData *data = INST_DATA(cl, obj);
152 IPTR *store = msg->opg_Storage;
154 switch (msg->opg_AttrID)
156 case MUIA_Family_List:
157 *store = (IPTR) & data->children;
158 return TRUE;
160 case MUIA_Version:
161 *store = __version;
162 return TRUE;
164 case MUIA_Revision:
165 *store = __revision;
166 return TRUE;
168 case MUIA_Family_ChildCount:
170 Object *cstate = (Object *) data->children.lh_Head;
171 *store = 0;
172 while (NextObject(&cstate))
173 (*store)++;
174 return TRUE;
178 return (DoSuperMethodA(cl, obj, (Msg) msg));
183 * MUIM_Family_AddHead : Add an object as first object to the family.
185 IPTR Family__MUIM_AddHead(struct IClass *cl, Object *obj,
186 struct MUIP_Family_AddHead *msg)
188 struct MUI_FamilyData *data = INST_DATA(cl, obj);
190 if (msg->obj)
192 AddHead(&(data->children), (struct Node *)_OBJECT(msg->obj));
194 /* if we are in an application tree, propagate pointers */
195 if (muiNotifyData(obj)->mnd_GlobalInfo)
197 muiNotifyData(msg->obj)->mnd_ParentObject = obj;
198 DoMethod(msg->obj, MUIM_ConnectParent, (IPTR)obj);
201 return TRUE;
203 else
204 return FALSE;
209 * MUIM_Family_AddTail : Add an object as last object to the family.
211 IPTR Family__MUIM_AddTail(struct IClass *cl, Object *obj,
212 struct MUIP_Family_AddTail *msg)
214 struct MUI_FamilyData *data = INST_DATA(cl, obj);
216 if (msg->obj)
218 D(bug("Family_AddTail(%p): obj=%p node=%p\n", obj, msg->obj,
219 _OBJECT(msg->obj)));
220 DoMethod(msg->obj, OM_ADDTAIL, (IPTR) & data->children);
222 /* if we are in an application tree, propagate pointers */
223 if (muiNotifyData(obj)->mnd_GlobalInfo)
225 muiNotifyData(msg->obj)->mnd_ParentObject = obj;
226 DoMethod(msg->obj, MUIM_ConnectParent, (IPTR)obj);
229 return TRUE;
231 else
232 return FALSE;
237 * MUIM_Family_Insert : Add an object after another object to the family.
239 IPTR Family__MUIM_Insert(struct IClass *cl, Object *obj,
240 struct MUIP_Family_Insert *msg)
242 struct MUI_FamilyData *data = INST_DATA(cl, obj);
244 if (msg->obj)
246 Insert(&(data->children), (struct Node *)_OBJECT(msg->obj),
247 (struct Node *)_OBJECT(msg->pred));
249 /* if we are in an application tree, propagate pointers */
250 if (muiNotifyData(obj)->mnd_GlobalInfo)
252 muiNotifyData(msg->obj)->mnd_ParentObject = obj;
253 DoMethod(msg->obj, MUIM_ConnectParent, (IPTR)obj);
256 return TRUE;
258 else
259 return FALSE;
264 * MUIM_Family_Remove : Remove an object from a family.
266 IPTR Family__MUIM_Remove(struct IClass *cl, Object *obj,
267 struct MUIP_Family_Remove *msg)
269 /* struct MUI_FamilyData *data = INST_DATA(cl, obj);
270 struct Node *node; */
272 if (msg->obj)
274 /* D(bug("Family_Remove(%p): obj=%p\n", obj, msg->obj)); */
275 DoMethod(msg->obj, MUIM_DisconnectParent);
276 muiNotifyData(msg->obj)->mnd_ParentObject = NULL;
277 DoMethod(msg->obj, OM_REMOVE);
278 return TRUE;
280 else
281 return FALSE;
286 * MUIM_Family_Sort : Sort the children of a family.
288 IPTR Family__MUIM_Sort(struct IClass *cl, Object *obj,
289 struct MUIP_Family_Sort *msg)
291 struct MUI_FamilyData *data = INST_DATA(cl, obj);
292 int i;
294 NewList(&(data->children));
295 for (i = 0; msg->obj[i]; i++)
297 AddTail(&(data->children), (struct Node *)_OBJECT(msg->obj[i]));
299 return TRUE;
304 * MUIM_Family_Transfer : All the children of the family are removed and
305 * added to another family in the same order.
307 IPTR Family__MUIM_Transfer(struct IClass *cl, Object *obj,
308 struct MUIP_Family_Transfer *msg)
310 struct MUI_FamilyData *data = INST_DATA(cl, obj);
311 Object *cstate = (Object *) data->children.lh_Head;
312 Object *child;
314 while ((child = NextObject(&cstate)))
316 DoMethod(obj, MUIM_Family_Remove, (IPTR) child);
317 DoMethod(msg->family, MUIM_Family_AddTail, (IPTR) child);
319 return TRUE;
323 /**************************************************************************
324 MUIM_FindUData : tests if the MUIA_UserData of the object
325 contains the given <udata> and returns the object pointer in this case.
326 **************************************************************************/
327 IPTR Family__MUIM_FindUData(struct IClass *cl, Object *obj,
328 struct MUIP_FindUData *msg)
330 struct MUI_FamilyData *data = INST_DATA(cl, obj);
331 Object *cstate = (Object *) data->children.lh_Head;
332 Object *child;
334 if (muiNotifyData(obj)->mnd_UserData == msg->udata)
335 return (IPTR) obj;
337 while ((child = NextObject(&cstate)))
339 Object *found = (Object *) DoMethodA(child, (Msg) msg);
340 if (found)
341 return (IPTR) found;
343 return 0;
348 * MUIM_GetUData : This method tests if the MUIA_UserData of the object
349 * contains the given <udata> and gets <attr> to <storage> for itself
350 * in this case.
352 IPTR Family__MUIM_GetUData(struct IClass *cl, Object *obj,
353 struct MUIP_GetUData *msg)
355 struct MUI_FamilyData *data = INST_DATA(cl, obj);
356 Object *cstate = (Object *) data->children.lh_Head;
357 Object *child;
359 if (muiNotifyData(obj)->mnd_UserData == msg->udata)
361 get(obj, msg->attr, msg->storage);
362 return TRUE;
364 while ((child = NextObject(&cstate)))
365 if (DoMethodA(child, (Msg) msg))
366 return TRUE;
368 return FALSE;
373 * MUIM_SetUData : This method tests if the MUIA_UserData of the object
374 * contains the given <udata> and sets <attr> to <val> for itself in this case.
376 IPTR Family__MUIM_SetUData(struct IClass *cl, Object *obj,
377 struct MUIP_SetUData *msg)
379 struct MUI_FamilyData *data = INST_DATA(cl, obj);
380 Object *cstate = (Object *) data->children.lh_Head;
381 Object *child;
383 if (muiNotifyData(obj)->mnd_UserData == msg->udata)
384 set(obj, msg->attr, msg->val);
386 while ((child = NextObject(&cstate)))
387 DoMethodA(child, (Msg) msg);
389 return TRUE;
394 * MUIM_SetUDataOnce : This method tests if the MUIA_UserData of the object
395 * contains the given <udata> and sets <attr> to <val> for itself in this case.
397 IPTR Family__MUIM_SetUDataOnce(struct IClass *cl, Object *obj,
398 struct MUIP_SetUDataOnce *msg)
400 struct MUI_FamilyData *data = INST_DATA(cl, obj);
401 Object *cstate = (Object *) data->children.lh_Head;
402 Object *child;
404 if (muiNotifyData(obj)->mnd_UserData == msg->udata)
406 set(obj, msg->attr, msg->val);
407 return TRUE;
409 while ((child = NextObject(&cstate)))
410 if (DoMethodA(child, (Msg) msg))
411 return TRUE;
413 return FALSE;
416 IPTR Family__MUIM_GetChild(struct IClass *cl, Object *obj,
417 struct MUIP_Family_GetChild *msg)
419 struct MUI_FamilyData *data = INST_DATA(cl, obj);
420 Object *cstate = (Object *) data->children.lh_Head;
421 Object *child, *prev = NULL;
422 LONG counter = 0;
424 while ((child = NextObject(&cstate)))
426 if ((msg->nr >= 0) && (msg->nr == counter))
427 return (IPTR) child;
429 if ((msg->ref != NULL) && (msg->ref == child))
431 if (msg->nr == MUIV_Family_GetChild_Next)
432 return (IPTR) NextObject(&cstate);
433 if (msg->nr == MUIV_Family_GetChild_Previous)
434 return (IPTR) prev;
437 if (msg->nr == MUIV_Family_GetChild_First)
438 return (IPTR) child;
440 prev = child;
441 counter++;
444 if (msg->nr == MUIV_Family_GetChild_Last)
445 return (IPTR) prev;
447 return (IPTR) NULL;
450 BOOPSI_DISPATCHER(IPTR, Family_Dispatcher, cl, obj, msg)
452 switch (msg->MethodID)
454 case OM_NEW:
455 return Family__OM_NEW(cl, obj, (struct opSet *)msg);
457 case OM_DISPOSE:
458 return Family__OM_DISPOSE(cl, obj, msg);
460 case OM_GET:
461 return Family__OM_GET(cl, obj, (struct opGet *)msg);
463 case MUIM_Family_AddHead:
464 return Family__MUIM_AddHead(cl, obj, (APTR) msg);
466 case OM_ADDMEMBER:
467 case MUIM_Family_AddTail:
468 return Family__MUIM_AddTail(cl, obj, (APTR) msg);
470 case MUIM_Family_Insert:
471 return Family__MUIM_Insert(cl, obj, (APTR) msg);
473 case OM_REMMEMBER:
474 case MUIM_Family_Remove:
475 return Family__MUIM_Remove(cl, obj, (APTR) msg);
477 case MUIM_Family_Sort:
478 return Family__MUIM_Sort(cl, obj, (APTR) msg);
480 case MUIM_Family_Transfer:
481 return Family__MUIM_Transfer(cl, obj, (APTR) msg);
483 case MUIM_FindUData:
484 return Family__MUIM_FindUData(cl, obj, (APTR) msg);
486 case MUIM_GetUData:
487 return Family__MUIM_GetUData(cl, obj, (APTR) msg);
489 case MUIM_SetUData:
490 return Family__MUIM_SetUData(cl, obj, (APTR) msg);
492 case MUIM_SetUDataOnce:
493 return Family__MUIM_SetUDataOnce(cl, obj, (APTR) msg);
495 case MUIM_Family_GetChild:
496 return Family__MUIM_GetChild(cl, obj, (APTR) msg);
499 return (DoSuperMethodA(cl, obj, msg));
501 BOOPSI_DISPATCHER_END
504 * Class descriptor.
506 const struct __MUIBuiltinClass _MUI_Family_desc =
508 MUIC_Family,
509 MUIC_Notify,
510 sizeof(struct MUI_FamilyData),
511 (void *) Family_Dispatcher