2 Copyright © 1999, David Le Corfec.
3 Copyright © 2002-2006, The AROS Development Team.
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 */
19 #include "muimaster_intern.h"
22 extern struct Library
*MUIMasterBase
;
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;
58 /* debuglist(struct List *list) */
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); */
67 /* printlist (struct List *list) */
69 /* struct Node *node; */
71 /* debuglist(list); */
73 /* for (node = list->lh_Head; node->ln_Succ; node = node->ln_Succ) */
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); */
84 IPTR
Family__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
86 struct MUI_FamilyData
*data
;
89 BOOL bad_childs
= FALSE
;
91 obj
= (Object
*)DoSuperMethodA(cl
, obj
, (Msg
)msg
);
95 * Initial local instance data
97 data
= INST_DATA(cl
, obj
);
98 NewList(&(data
->childs
));
101 * parse initial taglist
103 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem((const struct TagItem
**)&tags
)); )
105 if (tag
->ti_Tag
== MUIA_Family_Child
|| tag
->ti_Tag
== MUIA_Group_Child
)
107 if (tag
->ti_Data
) /* add child */
108 DoMethod(obj
, MUIM_Family_AddTail
, tag
->ti_Data
);
109 else /* fail and dispose childs */
118 CoerceMethod(cl
, obj
, OM_DISPOSE
);
129 IPTR
Family__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
131 struct MUI_FamilyData
*data
= INST_DATA(cl
, obj
);
132 Object
*cstate
= (Object
*)data
->childs
.lh_Head
;
135 while ((child
= NextObject(&cstate
)))
137 /* g_print("Family_Dispose: dispose child %p\n", child); */
138 MUI_DisposeObject(child
);
141 return DoSuperMethodA(cl
, obj
, msg
);
148 IPTR
Family__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
150 struct MUI_FamilyData
*data
= INST_DATA(cl
, obj
);
151 IPTR
*store
= msg
->opg_Storage
;
153 switch(msg
->opg_AttrID
)
155 case MUIA_Family_List
:
156 *store
= (IPTR
)&data
->childs
;
168 return(DoSuperMethodA(cl
, obj
, (Msg
) msg
));
173 * MUIM_Family_AddHead : Add an object as first object to the family.
175 IPTR
Family__MUIM_AddHead(struct IClass
*cl
, Object
*obj
, struct MUIP_Family_AddHead
*msg
)
177 struct MUI_FamilyData
*data
= INST_DATA(cl
, obj
);
181 AddHead(&(data
->childs
), (struct Node
*)_OBJECT(msg
->obj
));
190 * MUIM_Family_AddTail : Add an object as last object to the family.
192 IPTR
Family__MUIM_AddTail(struct IClass
*cl
, Object
*obj
, struct MUIP_Family_AddTail
*msg
)
194 struct MUI_FamilyData
*data
= INST_DATA(cl
, obj
);
198 D(bug("Family_AddTail(%p): obj=%p node=%p\n", obj
, msg
->obj
, _OBJECT(msg
->obj
)));
199 DoMethod(msg
->obj
, OM_ADDTAIL
, (IPTR
)&data
->childs
);
208 * MUIM_Family_Insert : Add an object after another object to the family.
210 IPTR
Family__MUIM_Insert(struct IClass
*cl
, Object
*obj
, struct MUIP_Family_Insert
*msg
)
212 struct MUI_FamilyData
*data
= INST_DATA(cl
, obj
);
216 Insert(&(data
->childs
), (struct Node
*)_OBJECT(msg
->obj
),
217 (struct Node
*)_OBJECT(msg
->pred
));
226 * MUIM_Family_Remove : Remove an object from a family.
228 IPTR
Family__MUIM_Remove(struct IClass
*cl
, Object
*obj
,
229 struct MUIP_Family_Remove
*msg
)
231 /* struct MUI_FamilyData *data = INST_DATA(cl, obj);
232 struct Node *node; */
236 /* D(bug("Family_Remove(%p): obj=%p\n", obj, msg->obj)); */
237 DoMethod(msg
->obj
, OM_REMOVE
);
246 * MUIM_Family_Sort : Sort the children of a family.
248 IPTR
Family__MUIM_Sort(struct IClass
*cl
, Object
*obj
,
249 struct MUIP_Family_Sort
*msg
)
251 struct MUI_FamilyData
*data
= INST_DATA(cl
, obj
);
254 NewList(&(data
->childs
));
255 for (i
= 0 ; msg
->obj
[i
] ; i
++)
257 AddTail(&(data
->childs
), (struct Node
*)_OBJECT(msg
->obj
[i
]));
264 * MUIM_Family_Transfer : All the children of the family are removed and
265 * added to another family in the same order.
267 IPTR
Family__MUIM_Transfer(struct IClass
*cl
, Object
*obj
, struct MUIP_Family_Transfer
*msg
)
269 struct MUI_FamilyData
*data
= INST_DATA(cl
, obj
);
270 Object
*cstate
= (Object
*)data
->childs
.lh_Head
;
273 while ((child
= NextObject(&cstate
)))
275 DoMethod(obj
, MUIM_Family_Remove
, (IPTR
)child
);
276 DoMethod(msg
->family
, MUIM_Family_AddTail
, (IPTR
)child
);
282 /**************************************************************************
283 MUIM_FindUData : tests if the MUIA_UserData of the object
284 contains the given <udata> and returns the object pointer in this case.
285 **************************************************************************/
286 IPTR
Family__MUIM_FindUData(struct IClass
*cl
, Object
*obj
, struct MUIP_FindUData
*msg
)
288 struct MUI_FamilyData
*data
= INST_DATA(cl
, obj
);
289 Object
*cstate
= (Object
*)data
->childs
.lh_Head
;
292 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
295 while ((child
= NextObject(&cstate
)))
297 Object
*found
= (Object
*)DoMethodA(child
, (Msg
)msg
);
298 if (found
) return (IPTR
)found
;
305 * MUIM_GetUData : This method tests if the MUIA_UserData of the object
306 * contains the given <udata> and gets <attr> to <storage> for itself
309 IPTR
Family__MUIM_GetUData(struct IClass
*cl
, Object
*obj
, struct MUIP_GetUData
*msg
)
311 struct MUI_FamilyData
*data
= INST_DATA(cl
, obj
);
312 Object
*cstate
= (Object
*)data
->childs
.lh_Head
;
315 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
317 get(obj
, msg
->attr
, msg
->storage
);
320 while ((child
= NextObject(&cstate
)))
321 if (DoMethodA(child
, (Msg
)msg
))
329 * MUIM_SetUData : This method tests if the MUIA_UserData of the object
330 * contains the given <udata> and sets <attr> to <val> for itself in this case.
332 IPTR
Family__MUIM_SetUData(struct IClass
*cl
, Object
*obj
, struct MUIP_SetUData
*msg
)
334 struct MUI_FamilyData
*data
= INST_DATA(cl
, obj
);
335 Object
*cstate
= (Object
*)data
->childs
.lh_Head
;
338 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
339 set(obj
, msg
->attr
, msg
->val
);
341 while ((child
= NextObject(&cstate
)))
342 DoMethodA(child
, (Msg
)msg
);
349 * MUIM_SetUDataOnce : This method tests if the MUIA_UserData of the object
350 * contains the given <udata> and sets <attr> to <val> for itself in this case.
352 IPTR
Family__MUIM_SetUDataOnce(struct IClass
*cl
, Object
*obj
, struct MUIP_SetUDataOnce
*msg
)
354 struct MUI_FamilyData
*data
= INST_DATA(cl
, obj
);
355 Object
*cstate
= (Object
*)data
->childs
.lh_Head
;
358 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
360 set(obj
, msg
->attr
, msg
->val
);
363 while ((child
= NextObject(&cstate
)))
364 if (DoMethodA(child
, (Msg
)msg
))
371 BOOPSI_DISPATCHER(IPTR
, Family_Dispatcher
, cl
, obj
, msg
)
373 switch (msg
->MethodID
)
376 return Family__OM_NEW(cl
, obj
, (struct opSet
*) msg
);
379 return Family__OM_DISPOSE(cl
, obj
, msg
);
382 return Family__OM_GET(cl
, obj
, (struct opGet
*)msg
);
384 case MUIM_Family_AddHead
:
385 return Family__MUIM_AddHead(cl
, obj
, (APTR
)msg
);
388 case MUIM_Family_AddTail
:
389 return Family__MUIM_AddTail(cl
, obj
, (APTR
)msg
);
391 case MUIM_Family_Insert
:
392 return Family__MUIM_Insert(cl
, obj
, (APTR
)msg
);
395 case MUIM_Family_Remove
:
396 return Family__MUIM_Remove(cl
, obj
, (APTR
)msg
);
398 case MUIM_Family_Sort
:
399 return Family__MUIM_Sort(cl
, obj
, (APTR
)msg
);
401 case MUIM_Family_Transfer
:
402 return Family__MUIM_Transfer(cl
, obj
, (APTR
)msg
);
405 return Family__MUIM_FindUData(cl
, obj
, (APTR
)msg
);
408 return Family__MUIM_GetUData(cl
, obj
, (APTR
)msg
);
411 return Family__MUIM_SetUData(cl
, obj
, (APTR
)msg
);
413 case MUIM_SetUDataOnce
:
414 return Family__MUIM_SetUDataOnce(cl
, obj
, (APTR
)msg
);
417 return(DoSuperMethodA(cl
, obj
, msg
));
419 BOOPSI_DISPATCHER_END
425 const struct __MUIBuiltinClass _MUI_Family_desc
= {
428 sizeof(struct MUI_FamilyData
),
429 (void*)Family_Dispatcher