2 Copyright © 2012-2015, The AROS Development Team. All rights reserved.
6 #define MUIMASTER_YES_INLINE_STDARG
8 #include <proto/muimaster.h>
9 #include <proto/intuition.h>
10 #include <proto/utility.h>
11 #include <proto/graphics.h>
12 #include <clib/alib_protos.h>
13 #include <mui/NListtree_mcc.h>
14 #include <mui/NList_mcc.h>
18 #include "Listtree_mcc.h"
19 #include "listtree_private.h"
21 #include <aros/debug.h>
23 /* Internal version of NListtree that enables controling the dispatcher */
24 #include <aros/symbolsets.h>
25 #define ADD2INITCLASSES(symbol, pri) ADD2SET(symbol, CLASSESINIT, pri)
26 #define ADD2EXPUNGECLASSES(symbol, pri) ADD2SET(symbol, CLASSESEXPUNGE, pri)
28 struct NListtreeInt_DATA
33 static struct MUI_CustomClass
* CL_NListtreeInt
;
35 BOOPSI_DISPATCHER(IPTR
, NListtreeInt_Dispatcher
, cl
, obj
, msg
)
37 switch (msg
->MethodID
)
41 return DoSuperMethodA(cl
, obj
, msg
);
45 static int MCC_NListtreeInt_Startup(struct Library
* lib
)
47 CL_NListtreeInt
= MUI_CreateCustomClass(lib
, MUIC_NListtree
, NULL
, sizeof(struct NListtreeInt_DATA
), NListtreeInt_Dispatcher
);
48 return CL_NListtreeInt
!= NULL
;
51 static void MCC_NListtreeInt_Shutdown(struct Library
* lib
)
53 MUI_DeleteCustomClass(CL_NListtreeInt
);
56 ADD2INITCLASSES(MCC_NListtreeInt_Startup
, -1);
57 ADD2EXPUNGECLASSES(MCC_NListtreeInt_Shutdown
, -1);
58 /* Internal version of NListtree that enables controling the dispatcher */
61 * MUIS_Listtree_Treenode -> MUI_NListtree_Treenode via MUIS_Listtree_TreeNodeInt.ref
62 * MUI_NListtree_Treenode -> MUIS_Listtree_Treenode via MUI_NListtree_Treenode.tn_User
64 struct MUIS_Listtree_TreeNodeInt
66 struct MUIS_Listtree_TreeNode base
;
67 struct MUI_NListtree_TreeNode
*ref
;
70 static IPTR
NotifySimulate_Function(struct Hook
*hook
, Object
*obj
, void ** msg
)
73 struct TagItem setti
[] = {{0,0},{TAG_DONE
, TAG_DONE
}};
75 IPTR attr
= (IPTR
)msg
[0];
76 IPTR val
= (IPTR
)msg
[1];
77 struct IClass
* cl
= hook
->h_Data
;
79 setmsg
.MethodID
= OM_SET
;
80 setmsg
.ops_AttrList
= setti
;
81 setmsg
.ops_GInfo
= NULL
;
85 case(MUIA_NListtree_Active
):
86 setti
[0].ti_Tag
= MUIA_Listtree_Active
;
87 setti
[0].ti_Data
= val
? (IPTR
)((struct MUI_NListtree_TreeNode
*)val
)->tn_User
: 0;
90 bug("[Listtree] NotifySimulate_Function - unhandled attribute %x\n", attr
);
93 /* Super method OM_SET call will go to Notify class and trigger notifications */
94 return DoSuperMethodA(cl
, obj
, (Msg
) &setmsg
);
97 static IPTR
DisplayHook_Proxy(struct Hook
*hook
, Object
*obj
, struct MUIP_NListtree_DisplayMessage
*msg
)
99 struct _temp
{ STACKED APTR array
; STACKED APTR treenode
; } t
;
100 struct Hook
* displayhook
= (struct Hook
*)hook
->h_Data
;
105 t
.array
= msg
->Array
;
106 t
.treenode
= msg
->TreeNode
? msg
->TreeNode
->tn_User
: NULL
;
108 return CallHookPkt(displayhook
, t
.array
, t
.treenode
);
111 #define NEWHANDLE(attrname) \
113 bug("[Listtree] OM_NEW:%s - unsupported\n", #attrname); \
116 #define CONV(AATTR, BATTR) \
118 convtags[i].ti_Tag = BATTR; \
119 convtags[i++].ti_Data = tag->ti_Data; \
122 #define COPY(AATTR) \
124 supertags[i].ti_Tag = AATTR; \
125 supertags[i++].ti_Data = tag->ti_Data; \
128 #define SYNC_TREENODE_FLAGS(tn) \
129 ((struct MUIS_Listtree_TreeNode *)tn->tn_User)->tn_Flags = tn->tn_Flags;
131 /*** Methods ****************************************************************/
132 Object
*Listtree__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
134 struct Listtree_DATA
*data
= NULL
;
136 struct TagItem
*tags
;
137 Object
*nlisttree
= NULL
;
138 struct TagItem convtags
[20];
139 struct TagItem supertags
[20];
142 /* Convert tags designated for NListtree */
143 for (i
= 0, tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
)); )
147 CONV(MUIA_Frame
, MUIA_Frame
)
148 CONV(MUIA_Listtree_Format
, MUIA_NListtree_Format
)
149 CONV(MUIA_Listtree_Title
, MUIA_NListtree_Title
)
150 CONV(MUIA_Listtree_DragDropSort
, MUIA_NListtree_DragDropSort
)
151 CONV(MUIA_List_Title
, MUIA_NList_Title
)
152 CONV(MUIA_List_DragSortable
, MUIA_NList_DragSortable
)
153 CONV(MUIA_List_MinLineHeight
, MUIA_NList_MinLineHeight
)
156 convtags
[i
].ti_Tag
= TAG_DONE
;
158 /* Copy tags designated for super class */
159 for (i
= 0, tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
)); )
163 COPY(MUIA_ContextMenu
) /* ContextMenuBuild/Choice will be called on child classes of Listtree */
166 supertags
[i
].ti_Tag
= TAG_DONE
;
169 * set up a DestructHook which will call proxy MUIS_Listtree_TreeNode destrhook and
172 obj
= (Object
*) DoSuperNewTags(cl
, obj
, 0,
173 Child
, nlisttree
= (Object
*) NewObjectA(CL_NListtreeInt
->mcc_Class
, NULL
, convtags
),
174 TAG_MORE
, (IPTR
)supertags
,
177 if (!obj
) return FALSE
;
179 data
= INST_DATA(cl
, obj
);
180 data
->nlisttree
= nlisttree
;
181 data
->notifysimulatehook
.h_Entry
= HookEntry
;
182 data
->notifysimulatehook
.h_SubEntry
= (HOOKFUNC
)NotifySimulate_Function
;
183 data
->notifysimulatehook
.h_Data
= cl
;
185 data
->pool
= CreatePool(MEMF_ANY
| MEMF_CLEAR
, 16 * 1024, 8 * 1024);
187 /* parse initial taglist */
188 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
)); )
192 case(MUIA_Listtree_ConstructHook
):
193 data
->constrhook
= (struct Hook
*)tag
->ti_Data
;
195 case(MUIA_Listtree_DestructHook
):
196 data
->destrhook
= (struct Hook
*)tag
->ti_Data
;
198 case(MUIA_Listtree_DisplayHook
):
199 data
->displayhook
= (struct Hook
*)tag
->ti_Data
;
201 case(MUIA_List_MinLineHeight
):
202 case(MUIA_List_DragSortable
):
203 case(MUIA_List_Title
):
204 case(MUIA_Listtree_DragDropSort
):
205 case(MUIA_Listtree_Format
):
206 case(MUIA_Listtree_Title
):
208 /* Forwarded to NListtree */
210 case(MUIA_ContextMenu
):
211 /* Forwarded to super class */
213 NEWHANDLE(MUIA_Listtree_SortHook
)
215 bug("[Listtree] OM_NEW: unhandled %x\n", tag
->ti_Tag
);
219 /* Setup root node */
221 struct MUIS_Listtree_TreeNodeInt
* _int
= AllocPooled(data
->pool
, sizeof(struct MUIS_Listtree_TreeNodeInt
));
222 struct MUI_NListtree_TreeNode
* root
= NULL
;
223 root
= (struct MUI_NListtree_TreeNode
*)DoMethod(data
->nlisttree
, MUIM_NListtree_GetEntry
,
224 NULL
, -15 /* priv -> position root */, 0);
225 root
->tn_User
= _int
;
229 /* Setup hook proxies */
230 if (data
->displayhook
)
232 data
->displayhookproxy
.h_Entry
= HookEntry
;
233 data
->displayhookproxy
.h_SubEntry
= (HOOKFUNC
)DisplayHook_Proxy
;
234 data
->displayhookproxy
.h_Data
= data
->displayhook
;
235 nnset(data
->nlisttree
, MUIA_NListtree_DisplayHook
, &data
->displayhookproxy
);
238 /* Setup notification forwarding */
239 DoMethod(data
->nlisttree
, MUIM_Notify
, MUIA_NListtree_Active
, MUIV_EveryTime
,
240 obj
, 4, MUIM_CallHook
, &data
->notifysimulatehook
, MUIA_NListtree_Active
, MUIV_TriggerValue
);
245 #define SETHANDLE(attrname) \
247 bug("[Listtree] OM_SET:%s - unsupported\n", #attrname); \
250 #define FORWARDSET(AATTR, BATTR) \
252 set(data->nlisttree, BATTR, tag->ti_Data); \
255 #define IGNORESET(AATTR) case(AATTR): break;
257 IPTR
Listtree__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
259 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
260 struct TagItem
*tstate
= msg
->ops_AttrList
;
263 if (!data
->nlisttree
)
264 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
266 while ((tag
= NextTagItem(&tstate
)) != NULL
)
270 FORWARDSET(MUIA_Listtree_Quiet
, MUIA_NListtree_Quiet
)
271 FORWARDSET(MUIA_List_Active
, MUIA_NList_Active
)
273 IGNORESET(MUIA_Listview_SelectChange
)
275 case(MUIA_Listtree_Active
):
276 set(data
->nlisttree
, MUIA_NListtree_Active
,
277 ((struct MUIS_Listtree_TreeNodeInt
*)tag
->ti_Data
)->ref
);
280 SETHANDLE(MUIA_Listtree_DoubleClick
)
281 case MUIB_List
| 0x00000010: break;
282 case MUIA_Prop_First
: break;
283 case MUIA_Prop_DoSmooth
: break;
284 case MUIA_NoNotify
: break;
285 case MUIA_Prop_Entries
: break;
286 case MUIA_Prop_Visible
: break;
287 case MUIA_Prop_DeltaFactor
: break;
289 bug("[Listtree] OM_SET: passing to parent class %x\n", tag
->ti_Tag
);
294 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
297 #define GETHANDLE(attrname) \
299 bug("[Listtree] OM_GET:%s - unsupported\n", #attrname); \
303 #define MUIA_List_Prop_Entries /* PRIV */ \
304 (MUIB_MUI | 0x0042a8f5) /* .sg LONG PRIV */
305 #define MUIA_List_Prop_Visible /* PRIV */ \
306 (MUIB_MUI | 0x004273e9) /* .sg LONG PRIV */
307 #define MUIA_List_Prop_First /* PRIV */ \
308 (MUIB_MUI | 0x00429df3) /* .sg LONG PRIV */
310 #define MUIA_List_VertProp_Entries /* PRIV */ \
311 MUIA_List_Prop_Entries /* PRIV */
312 #define MUIA_List_VertProp_Visible /* PRIV */ \
313 MUIA_List_Prop_Visible /* PRIV */
314 #define MUIA_List_VertProp_First /* PRIV */ \
315 MUIA_List_Prop_First /* PRIV */
317 #define FORWARDGET(AATTR, BATTR) \
319 *(msg->opg_Storage) = XGET(data->nlisttree, BATTR); \
322 IPTR
Listtree__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
324 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
326 if (!data
->nlisttree
)
329 switch (msg
->opg_AttrID
)
331 FORWARDGET(MUIA_Frame
, MUIA_Frame
)
332 FORWARDGET(MUIA_Listtree_DoubleClick
, MUIA_NListtree_DoubleClick
)
333 FORWARDGET(MUIA_List_Active
, MUIA_NList_Active
)
334 FORWARDGET(MUIA_Listtree_Active
, MUIA_NListtree_Active
)
335 FORWARDGET(MUIA_Listtree_Quiet
, MUIA_NListtree_Quiet
)
336 FORWARDGET(MUIA_List_Visible
, MUIA_NList_Visible
)
338 GETHANDLE(MUIA_List_VertProp_Entries
)
339 GETHANDLE(MUIA_List_VertProp_Visible
)
340 GETHANDLE(MUIA_List_VertProp_First
)
341 case MUIA_Disabled
: break;
342 case MUIA_Parent
: break;
343 case MUIA_Group_ChildList
: break;
344 case MUIA_Prop_First
: break;
345 case MUIA_Prop_DoSmooth
: break;
346 case MUIA_Listview_List
: break;
347 case MUIA_Virtgroup_Left
: break;
348 case MUIA_Virtgroup_Top
: break;
349 case 0x9d510020 /*MUIA_NListview_NList*/: break;
351 bug("[Listtree] OM_GET: passing to parent class %x\n", msg
->opg_AttrID
);
354 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
357 #define METHODSTUB(methodname) \
358 IPTR Listtree__##methodname(struct IClass *cl, Object *obj, Msg msg) \
360 bug("[Listtree] Usupported : %s\n", #methodname); \
361 return (IPTR)FALSE; \
364 METHODSTUB(MUIM_Listtree_SetDropMark
)
366 IPTR
Listtree__MUIM_Listtree_Insert(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_Insert
*msg
)
368 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
369 struct MUIS_Listtree_TreeNodeInt
* _int
= AllocPooled(data
->pool
, sizeof(struct MUIS_Listtree_TreeNodeInt
));
370 struct MUIS_Listtree_TreeNode
* _return
= NULL
;
371 struct MUI_NListtree_TreeNode
* ln
= NULL
, * pn
= NULL
;
376 _return
= &_int
->base
;
378 _return
->tn_Flags
= (UWORD
)msg
->Flags
;
379 if (data
->constrhook
)
380 _return
->tn_User
= (APTR
)CallHookPkt(data
->constrhook
, data
->pool
, msg
->User
);
382 _return
->tn_User
= msg
->User
;
384 switch((IPTR
)msg
->ListNode
)
386 case(MUIV_Listtree_Insert_ListNode_Root
):
387 case(MUIV_Listtree_Insert_ListNode_Active
):
391 ln
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->ListNode
)->ref
;
394 switch((IPTR
)msg
->PrevNode
)
396 case(MUIV_Listtree_Insert_PrevNode_Head
):
397 case(MUIV_Listtree_Insert_PrevNode_Tail
):
398 case(MUIV_Listtree_Insert_PrevNode_Active
):
399 case(MUIV_Listtree_Insert_PrevNode_Sorted
):
403 pn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->PrevNode
)->ref
;
406 _int
->ref
= (struct MUI_NListtree_TreeNode
*)DoMethod(data
->nlisttree
,
407 MUIM_NListtree_Insert
, msg
->Name
, _return
, ln
, pn
, msg
->Flags
);
409 _return
->tn_Name
= _int
->ref
->tn_Name
;
411 return (IPTR
)_return
;
414 IPTR
Listtree__MUIM_Listtree_GetEntry(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_GetEntry
*msg
)
416 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
417 struct MUI_NListtree_TreeNode
* tn
= NULL
, * found
= NULL
;
419 switch ((IPTR
)msg
->Node
)
421 case(MUIV_Listtree_GetEntry_ListNode_Root
):
422 case(MUIV_Listtree_GetEntry_ListNode_Active
):
426 tn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->Node
)->ref
;
429 found
= (struct MUI_NListtree_TreeNode
*) DoMethod(data
->nlisttree
,
430 MUIM_NListtree_GetEntry
, tn
, msg
->Position
, msg
->Flags
);
434 SYNC_TREENODE_FLAGS(found
);
435 return (IPTR
)found
->tn_User
;
441 IPTR
Listtree__MUIM_Listtree_Remove(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_Remove
*msg
)
443 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
445 /* TODO: handle remaining enumeration values */
446 if ((msg
->ListNode
== (APTR
)MUIV_Listtree_Remove_ListNode_Root
) &&
447 ((msg
->TreeNode
== (APTR
)MUIV_Listtree_Remove_TreeNode_Active
) ||
448 (msg
->TreeNode
== (APTR
)MUIV_Listtree_Remove_TreeNode_All
)))
450 /* Deallocating of MUIS_Listtree_TreeNode is happening in the DestructHook */
451 return DoMethod(data
->nlisttree
, MUIM_NListtree_Remove
, msg
->ListNode
, msg
->TreeNode
, msg
->Flags
);
455 * add handling for cases where ListNode/TreeNode actually point to Treenode structure
457 bug("[Listtree] MUIM_Listtree_Remove unsupported code path Listnode: %x, Treenode: %x, Flags: %d\n", msg
->ListNode
, msg
->TreeNode
, msg
->Flags
);
462 IPTR
Listtree__MUIM_List_TestPos(struct IClass
*cl
, Object
*obj
, struct MUIP_List_TestPos
*msg
)
464 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
466 struct MUI_NList_TestPos_Result res
;
467 if (DoMethod(data
->nlisttree
, MUIM_List_TestPos
, msg
->x
, msg
->y
, &res
))
469 msg
->res
->entry
= res
.entry
;
470 msg
->res
->column
= res
.column
;
471 msg
->res
->flags
= res
.flags
;
472 msg
->res
->xoffset
= res
.xoffset
;
473 msg
->res
->yoffset
= res
.yoffset
;
480 IPTR
Listtree__MUIM_Listtree_TestPos(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_TestPos
*msg
)
482 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
484 struct MUI_NListtree_TestPos_Result res
;
485 struct MUIS_Listtree_TestPos_Result
* _ret
= (struct MUIS_Listtree_TestPos_Result
*)msg
->Result
;
487 _ret
->tpr_TreeNode
= NULL
;
489 DoMethod(data
->nlisttree
, MUIM_NListtree_TestPos
, msg
->X
, msg
->Y
, &res
);
491 _ret
->tpr_Flags
= res
.tpr_Type
;
492 _ret
->tpr_ListEntry
= res
.tpr_ListEntry
;
493 _ret
->tpr_ListFlags
= res
.tpr_ListFlags
;
495 if (res
.tpr_TreeNode
!= NULL
)
497 SYNC_TREENODE_FLAGS(res
.tpr_TreeNode
);
498 _ret
->tpr_TreeNode
= res
.tpr_TreeNode
->tn_User
;
505 IPTR
Listtree__MUIM_Listtree_GetNr(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_GetNr
*msg
)
507 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
508 struct MUI_NListtree_TreeNode
* tn
= NULL
;
510 switch((IPTR
)msg
->TreeNode
)
512 case(MUIV_Listtree_GetNr_TreeNode_Active
):
516 tn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->TreeNode
)->ref
;
519 return DoMethod(data
->nlisttree
, MUIM_NListtree_GetNr
, tn
, msg
->Flags
);
522 IPTR
Listtree__MUIM_Listtree_Rename(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_Rename
*msg
)
524 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
525 struct MUI_NListtree_TreeNode
* tn
= NULL
, * renamed
= NULL
;
527 switch((IPTR
)msg
->TreeNode
)
529 case(MUIV_Listtree_Rename_TreeNode_Active
):
533 tn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->TreeNode
)->ref
;
536 renamed
= (struct MUI_NListtree_TreeNode
*)DoMethod(data
->nlisttree
,
537 MUIM_NListtree_Rename
, tn
, msg
->NewName
, msg
->Flags
);
541 ((struct MUIS_Listtree_TreeNode
*)renamed
->tn_User
)->tn_Name
= renamed
->tn_Name
;
542 return (IPTR
)renamed
->tn_User
;
548 IPTR
Listtree__MUIM_List_Redraw(struct IClass
*cl
, Object
*obj
, struct MUIP_List_Redraw
*msg
)
550 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
551 struct MUI_NListtree_TreeNode
* entry
= msg
->entry
?
552 ((struct MUIS_Listtree_TreeNodeInt
*)msg
->entry
)->ref
: NULL
;
556 case(MUIV_List_Redraw_Entry
):
557 return DoMethod(data
->nlisttree
, MUIM_NList_RedrawEntry
, entry
);
559 return DoMethod(data
->nlisttree
, MUIM_NList_Redraw
, msg
->pos
);
563 IPTR
Listtree__MUIM_Listtree_Open(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_Open
*msg
)
565 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
566 struct MUI_NListtree_TreeNode
* tn
= NULL
, * ln
= NULL
;
568 switch((IPTR
)msg
->ListNode
)
570 case(MUIV_Listtree_Open_ListNode_Root
):
571 case(MUIV_Listtree_Open_ListNode_Parent
):
572 case(MUIV_Listtree_Open_ListNode_Active
):
576 ln
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->ListNode
)->ref
;
579 switch((IPTR
)msg
->TreeNode
)
581 case(MUIV_Listtree_Open_TreeNode_Head
):
582 case(MUIV_Listtree_Open_TreeNode_Tail
):
583 case(MUIV_Listtree_Open_TreeNode_Active
):
584 case(MUIV_Listtree_Open_TreeNode_All
):
588 tn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->TreeNode
)->ref
;
591 return DoMethod(data
->nlisttree
, MUIM_NListtree_Open
, ln
, tn
, msg
->Flags
);
594 IPTR
Listtree__MUIM_Listtree_FindName(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_FindName
*msg
)
596 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
597 struct MUI_NListtree_TreeNode
* ln
= NULL
, * found
= NULL
;
599 switch((IPTR
)msg
->ListNode
)
601 case(MUIV_Listtree_FindName_ListNode_Root
):
602 case(MUIV_Listtree_FindName_ListNode_Active
):
606 ln
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->ListNode
)->ref
;
609 found
= (struct MUI_NListtree_TreeNode
*) DoMethod(data
->nlisttree
, MUIM_NListtree_FindName
,
610 ln
, msg
->Name
, msg
->Flags
);
613 return (IPTR
)found
->tn_User
;
624 #define MADF_SETUP (1<< 28) /* PRIV - zune-specific */
626 IPTR
DoSetupMethod(Object
* obj
, struct MUI_RenderInfo
* info
)
628 /* MUI set the correct render info *before* it calls MUIM_Setup so please
629 * only use this function instead of DoMethodA() */
630 muiRenderInfo(obj
) = info
;
631 return DoMethod(obj
, MUIM_Setup
, (IPTR
) info
);
634 IPTR
Listtree__MUIM_List_CreateImage(struct IClass
*cl
, Object
*obj
, struct MUIP_List_CreateImage
*msg
)
636 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
638 if (!(_flags(obj
) & MADF_SETUP
))
641 IPTR _ret
= DoMethod(data
->nlisttree
, MUIM_NList_CreateImage
, msg
->obj
, msg
->flags
);
643 /* There is a use case where an image object created in a Listtree can be passed as O[address]
644 * in the text in the display callback of List. Since Listtree just wraps around NListtree and the
645 * return structures from List_CreateImage and NList_CreateImage are different, this would normally
646 * not work. Luckily, List needs only the msg->obj and it is at the same offset in ListImage and
647 * in structure returned by NList. The case will work as long as this is met.
649 struct ListImage
* li
= (struct ListImage
*)_ret
;
650 if (li
->obj
!= msg
->obj
)
651 bug("[Listtree] CreateImage condition BROKEN, see comment in code!\n");
653 /* Setup the msg->obj as the List is doing */
654 DoMethod(li
->obj
, MUIM_ConnectParent
, (IPTR
) obj
);
655 DoSetupMethod(li
->obj
, muiRenderInfo(obj
));
660 IPTR
Listtree__MUIM_List_DeleteImage(struct IClass
*cl
, Object
*obj
, struct MUIP_List_DeleteImage
*msg
)
662 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
663 struct ListImage
* li
= (struct ListImage
*)msg
->listimg
;
665 /* DoMethod(li->obj, MUIM_Cleanup); // Called in MUIM_NList_DeleteImage */
666 DoMethod(li
->obj
, MUIM_DisconnectParent
);
667 return DoMethod(data
->nlisttree
, MUIM_NList_DeleteImage
, msg
->listimg
);
670 IPTR
Listtree__MUIM_Listtree_Close(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_Close
*msg
)
672 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
673 struct MUI_NListtree_TreeNode
* tn
= NULL
, * ln
= NULL
;
675 switch((IPTR
)msg
->ListNode
)
677 case(MUIV_Listtree_Close_ListNode_Root
):
678 case(MUIV_Listtree_Close_ListNode_Parent
):
679 case(MUIV_Listtree_Close_ListNode_Active
):
683 ln
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->ListNode
)->ref
;
686 switch((IPTR
)msg
->TreeNode
)
688 case(MUIV_Listtree_Close_TreeNode_Head
):
689 case(MUIV_Listtree_Close_TreeNode_Tail
):
690 case(MUIV_Listtree_Close_TreeNode_Active
):
691 case(MUIV_Listtree_Close_TreeNode_All
):
695 tn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->TreeNode
)->ref
;
698 return DoMethod(data
->nlisttree
, MUIM_NListtree_Close
, ln
, tn
, msg
->Flags
);