2 Copyright © 1999, David Le Corfec.
3 Copyright © 2002-2012, 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_children
= FALSE
;
91 obj
= (Object
*) DoSuperMethodA(cl
, obj
, (Msg
) msg
);
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 */
119 CoerceMethod(cl
, obj
, 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
;
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
);
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
;
168 case MUIA_Family_ChildCount
:
170 Object
*cstate
= (Object
*) data
->children
.lh_Head
;
172 while (NextObject(&cstate
))
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
);
192 AddHead(&(data
->children
), (struct Node
*)_OBJECT(msg
->obj
));
201 * MUIM_Family_AddTail : Add an object as last object to the family.
203 IPTR
Family__MUIM_AddTail(struct IClass
*cl
, Object
*obj
,
204 struct MUIP_Family_AddTail
*msg
)
206 struct MUI_FamilyData
*data
= INST_DATA(cl
, obj
);
210 D(bug("Family_AddTail(%p): obj=%p node=%p\n", obj
, msg
->obj
,
212 DoMethod(msg
->obj
, OM_ADDTAIL
, (IPTR
) & data
->children
);
221 * MUIM_Family_Insert : Add an object after another object to the family.
223 IPTR
Family__MUIM_Insert(struct IClass
*cl
, Object
*obj
,
224 struct MUIP_Family_Insert
*msg
)
226 struct MUI_FamilyData
*data
= INST_DATA(cl
, obj
);
230 Insert(&(data
->children
), (struct Node
*)_OBJECT(msg
->obj
),
231 (struct Node
*)_OBJECT(msg
->pred
));
240 * MUIM_Family_Remove : Remove an object from a family.
242 IPTR
Family__MUIM_Remove(struct IClass
*cl
, Object
*obj
,
243 struct MUIP_Family_Remove
*msg
)
245 /* struct MUI_FamilyData *data = INST_DATA(cl, obj);
246 struct Node *node; */
250 /* D(bug("Family_Remove(%p): obj=%p\n", obj, msg->obj)); */
251 DoMethod(msg
->obj
, OM_REMOVE
);
260 * MUIM_Family_Sort : Sort the children of a family.
262 IPTR
Family__MUIM_Sort(struct IClass
*cl
, Object
*obj
,
263 struct MUIP_Family_Sort
*msg
)
265 struct MUI_FamilyData
*data
= INST_DATA(cl
, obj
);
268 NewList(&(data
->children
));
269 for (i
= 0; msg
->obj
[i
]; i
++)
271 AddTail(&(data
->children
), (struct Node
*)_OBJECT(msg
->obj
[i
]));
278 * MUIM_Family_Transfer : All the children of the family are removed and
279 * added to another family in the same order.
281 IPTR
Family__MUIM_Transfer(struct IClass
*cl
, Object
*obj
,
282 struct MUIP_Family_Transfer
*msg
)
284 struct MUI_FamilyData
*data
= INST_DATA(cl
, obj
);
285 Object
*cstate
= (Object
*) data
->children
.lh_Head
;
288 while ((child
= NextObject(&cstate
)))
290 DoMethod(obj
, MUIM_Family_Remove
, (IPTR
) child
);
291 DoMethod(msg
->family
, MUIM_Family_AddTail
, (IPTR
) child
);
297 /**************************************************************************
298 MUIM_FindUData : tests if the MUIA_UserData of the object
299 contains the given <udata> and returns the object pointer in this case.
300 **************************************************************************/
301 IPTR
Family__MUIM_FindUData(struct IClass
*cl
, Object
*obj
,
302 struct MUIP_FindUData
*msg
)
304 struct MUI_FamilyData
*data
= INST_DATA(cl
, obj
);
305 Object
*cstate
= (Object
*) data
->children
.lh_Head
;
308 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
311 while ((child
= NextObject(&cstate
)))
313 Object
*found
= (Object
*) DoMethodA(child
, (Msg
) msg
);
322 * MUIM_GetUData : This method tests if the MUIA_UserData of the object
323 * contains the given <udata> and gets <attr> to <storage> for itself
326 IPTR
Family__MUIM_GetUData(struct IClass
*cl
, Object
*obj
,
327 struct MUIP_GetUData
*msg
)
329 struct MUI_FamilyData
*data
= INST_DATA(cl
, obj
);
330 Object
*cstate
= (Object
*) data
->children
.lh_Head
;
333 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
335 get(obj
, msg
->attr
, msg
->storage
);
338 while ((child
= NextObject(&cstate
)))
339 if (DoMethodA(child
, (Msg
) msg
))
347 * MUIM_SetUData : This method tests if the MUIA_UserData of the object
348 * contains the given <udata> and sets <attr> to <val> for itself in this case.
350 IPTR
Family__MUIM_SetUData(struct IClass
*cl
, Object
*obj
,
351 struct MUIP_SetUData
*msg
)
353 struct MUI_FamilyData
*data
= INST_DATA(cl
, obj
);
354 Object
*cstate
= (Object
*) data
->children
.lh_Head
;
357 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
358 set(obj
, msg
->attr
, msg
->val
);
360 while ((child
= NextObject(&cstate
)))
361 DoMethodA(child
, (Msg
) msg
);
368 * MUIM_SetUDataOnce : This method tests if the MUIA_UserData of the object
369 * contains the given <udata> and sets <attr> to <val> for itself in this case.
371 IPTR
Family__MUIM_SetUDataOnce(struct IClass
*cl
, Object
*obj
,
372 struct MUIP_SetUDataOnce
*msg
)
374 struct MUI_FamilyData
*data
= INST_DATA(cl
, obj
);
375 Object
*cstate
= (Object
*) data
->children
.lh_Head
;
378 if (muiNotifyData(obj
)->mnd_UserData
== msg
->udata
)
380 set(obj
, msg
->attr
, msg
->val
);
383 while ((child
= NextObject(&cstate
)))
384 if (DoMethodA(child
, (Msg
) msg
))
390 IPTR
Family__MUIM_GetChild(struct IClass
*cl
, Object
*obj
,
391 struct MUIP_Family_GetChild
*msg
)
393 struct MUI_FamilyData
*data
= INST_DATA(cl
, obj
);
394 Object
*cstate
= (Object
*) data
->children
.lh_Head
;
395 Object
*child
, *prev
= NULL
;
398 while ((child
= NextObject(&cstate
)))
400 if ((msg
->nr
>= 0) && (msg
->nr
== counter
))
403 if ((msg
->ref
!= NULL
) && (msg
->ref
== child
))
405 if (msg
->nr
== MUIV_Family_GetChild_Next
)
406 return (IPTR
) NextObject(&cstate
);
407 if (msg
->nr
== MUIV_Family_GetChild_Previous
)
411 if (msg
->nr
== MUIV_Family_GetChild_First
)
418 if (msg
->nr
== MUIV_Family_GetChild_Last
)
424 BOOPSI_DISPATCHER(IPTR
, Family_Dispatcher
, cl
, obj
, msg
)
426 switch (msg
->MethodID
)
429 return Family__OM_NEW(cl
, obj
, (struct opSet
*)msg
);
432 return Family__OM_DISPOSE(cl
, obj
, msg
);
435 return Family__OM_GET(cl
, obj
, (struct opGet
*)msg
);
437 case MUIM_Family_AddHead
:
438 return Family__MUIM_AddHead(cl
, obj
, (APTR
) msg
);
441 case MUIM_Family_AddTail
:
442 return Family__MUIM_AddTail(cl
, obj
, (APTR
) msg
);
444 case MUIM_Family_Insert
:
445 return Family__MUIM_Insert(cl
, obj
, (APTR
) msg
);
448 case MUIM_Family_Remove
:
449 return Family__MUIM_Remove(cl
, obj
, (APTR
) msg
);
451 case MUIM_Family_Sort
:
452 return Family__MUIM_Sort(cl
, obj
, (APTR
) msg
);
454 case MUIM_Family_Transfer
:
455 return Family__MUIM_Transfer(cl
, obj
, (APTR
) msg
);
458 return Family__MUIM_FindUData(cl
, obj
, (APTR
) msg
);
461 return Family__MUIM_GetUData(cl
, obj
, (APTR
) msg
);
464 return Family__MUIM_SetUData(cl
, obj
, (APTR
) msg
);
466 case MUIM_SetUDataOnce
:
467 return Family__MUIM_SetUDataOnce(cl
, obj
, (APTR
) msg
);
469 case MUIM_Family_GetChild
:
470 return Family__MUIM_GetChild(cl
, obj
, (APTR
) msg
);
473 return (DoSuperMethodA(cl
, obj
, msg
));
475 BOOPSI_DISPATCHER_END
480 const struct __MUIBuiltinClass _MUI_Family_desc
=
484 sizeof(struct MUI_FamilyData
),
485 (void *) Family_Dispatcher