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 /* Routing of inherited methods calls:
29 * Some methods are often overriden in child classes of Listree, for example DragReport.
30 * On the other hand, those methods get called as interaction on the NListtree object.
31 * To allow using overriden methods, the following call sequence is implemented:
32 * NListtreeInt.A -> Listreee.A
33 * Listtree.A -> NListtreeInt.SuperA
34 * In case user inherited code, the call sequence looks as follows
35 * NListtreeInt.A -> Listreee-inherited.A
36 * Listreee-inherited.A -> Listreee.A
37 * Listtree.A -> NListtreeInt.SuperA
40 #define MUIA_NListtreeInt_Listtree 0xfec81401UL /* .s. Object * */
42 #define MUIM_NListtreeInt_ForwardSuperMethod 0xfec81301UL
44 struct MUIP_NListtreeInt_ForwardSuperMethod
46 STACKED ULONG MethodID
;
50 struct NListtreeInt_DATA
55 static struct MUI_CustomClass
* CL_NListtreeInt
;
57 IPTR
NListtreeInt__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
59 struct NListtreeInt_DATA
*data
= INST_DATA(cl
, obj
);
60 struct TagItem
*tstate
= msg
->ops_AttrList
;
63 while ((tag
= NextTagItem(&tstate
)) != NULL
)
67 case(MUIA_NListtreeInt_Listtree
):
68 data
->listtree
= (Object
*)tag
->ti_Data
;
73 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
76 IPTR
NListtreeInt__ForwardListree(struct IClass
*cl
, Object
*obj
, Msg msg
)
78 struct NListtreeInt_DATA
*data
= INST_DATA(cl
, obj
);
80 return DoMethodA(data
->listtree
, msg
);
83 IPTR
NListtreeInt__ForwardSuperMethod(struct IClass
*cl
, Object
*obj
, struct MUIP_NListtreeInt_ForwardSuperMethod
* msg
)
85 return DoSuperMethodA(cl
, obj
, msg
->msg
);
88 IPTR
NListtreeInt__DoDrag(struct IClass
*cl
, Object
*obj
, struct MUIP_DoDrag
* msg
)
90 struct NListtreeInt_DATA
*data
= INST_DATA(cl
, obj
);
92 /* Use the listtree as the dragged object */
93 DoMethod(_win(data
->listtree
), MUIB_Window
| 0x00000003,
94 (IPTR
)data
->listtree
, msg
->touchx
, msg
->touchy
, msg
->flags
);
98 BOOPSI_DISPATCHER(IPTR
, NListtreeInt_Dispatcher
, cl
, obj
, msg
)
100 switch (msg
->MethodID
)
102 case(OM_SET
): return NListtreeInt__OM_SET(cl
, obj
, (struct opSet
*)msg
);
103 case(MUIM_NListtreeInt_ForwardSuperMethod
):
104 return NListtreeInt__ForwardSuperMethod(cl
, obj
, (struct MUIP_NListtreeInt_ForwardSuperMethod
*)msg
);
106 return NListtreeInt__DoDrag(cl
, obj
, (struct MUIP_DoDrag
*)msg
);
109 return DoSuperMethodA(cl
, obj
, msg
);
111 BOOPSI_DISPATCHER_END
113 static int MCC_NListtreeInt_Startup(struct Library
* lib
)
115 CL_NListtreeInt
= MUI_CreateCustomClass(lib
, MUIC_NListtree
, NULL
, sizeof(struct NListtreeInt_DATA
), NListtreeInt_Dispatcher
);
116 return CL_NListtreeInt
!= NULL
;
119 static void MCC_NListtreeInt_Shutdown(struct Library
* lib
)
121 MUI_DeleteCustomClass(CL_NListtreeInt
);
124 ADD2INITCLASSES(MCC_NListtreeInt_Startup
, -1);
125 ADD2EXPUNGECLASSES(MCC_NListtreeInt_Shutdown
, -1);
126 /* Internal version of NListtree that enables controling the dispatcher */
142 * MUIS_Listtree_Treenode -> MUI_NListtree_Treenode via MUIS_Listtree_TreeNodeInt.ref
143 * MUI_NListtree_Treenode -> MUIS_Listtree_Treenode via MUI_NListtree_Treenode.tn_User
145 struct MUIS_Listtree_TreeNodeInt
147 struct MUIS_Listtree_TreeNode base
;
148 struct MUI_NListtree_TreeNode
*ref
;
151 #define SYNC_TREENODE_FLAGS(tn) \
152 if (tn && tn->tn_User) \
153 ((struct MUIS_Listtree_TreeNode *)tn->tn_User)->tn_Flags = tn->tn_Flags;
155 static IPTR
NotifySimulate_Function(struct Hook
*hook
, Object
*obj
, void ** msg
)
158 struct TagItem setti
[] = {{0,0},{TAG_DONE
, TAG_DONE
}};
160 IPTR attr
= (IPTR
)msg
[0];
161 IPTR val
= (IPTR
)msg
[1];
162 struct IClass
* cl
= hook
->h_Data
;
164 setmsg
.MethodID
= OM_SET
;
165 setmsg
.ops_AttrList
= setti
;
166 setmsg
.ops_GInfo
= NULL
;
170 case(MUIA_NListtree_Active
):
171 setti
[0].ti_Tag
= MUIA_Listtree_Active
;
172 setti
[0].ti_Data
= val
? (IPTR
)((struct MUI_NListtree_TreeNode
*)val
)->tn_User
: 0;
174 case(MUIA_NListtree_DoubleClick
):
175 setti
[0].ti_Tag
= MUIA_Listtree_DoubleClick
;
176 setti
[0].ti_Data
= val
;
178 case(MUIA_NListtree_Quiet
):
179 setti
[0].ti_Tag
= MUIA_Listtree_Quiet
;
180 setti
[0].ti_Data
= val
;
183 bug("[Listtree] NotifySimulate_Function - unhandled attribute %x\n", attr
);
186 /* Super method OM_SET call will go to Notify class and trigger notifications */
187 return DoSuperMethodA(cl
, obj
, (Msg
) &setmsg
);
190 static IPTR
DisplayHook_Proxy(struct Hook
*hook
, Object
*obj
, struct MUIP_NListtree_DisplayMessage
*msg
)
192 struct Hook
* displayhook
= (struct Hook
*)hook
->h_Data
;
198 SYNC_TREENODE_FLAGS(msg
->TreeNode
);
200 tn
= msg
->TreeNode
? msg
->TreeNode
->tn_User
: NULL
;
202 return CallHookPkt(displayhook
, msg
->Array
, tn
);
205 static IPTR
DestructHook_Proxy(struct Hook
*hook
, Object
*obj
, struct MUIP_NListtree_DestructMessage
*msg
)
207 struct Listtree_DATA
* data
= (struct Listtree_DATA
*)hook
->h_Data
;
208 struct MUIS_Listtree_TreeNode
* tn
= (struct MUIS_Listtree_TreeNode
*)msg
->UserData
;
212 if (data
->destrhook
&& tn
)
213 CallHookPkt(data
->destrhook
, data
->pool
, tn
->tn_User
);
215 FreePooled(data
->pool
, tn
, sizeof(struct MUIS_Listtree_TreeNodeInt
));
220 #define NEWHANDLE(attrname) \
222 bug("[Listtree] OM_NEW:%s - unsupported\n", #attrname); \
225 #define CONV(AATTR, BATTR) \
227 convtags[i].ti_Tag = BATTR; \
228 convtags[i++].ti_Data = tag->ti_Data; \
231 #define COPY(AATTR) \
233 supertags[i].ti_Tag = AATTR; \
234 supertags[i++].ti_Data = tag->ti_Data; \
237 #define NOTIFY_FORWARD(AATTR) \
238 DoMethod(data->nlisttree, MUIM_Notify, AATTR, MUIV_EveryTime, \
239 obj, 4, MUIM_CallHook, &data->notifysimulatehook, AATTR, MUIV_TriggerValue);
242 /*** Methods ****************************************************************/
243 Object
*Listtree__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
245 struct Listtree_DATA
*data
= NULL
;
247 struct TagItem
*tags
;
248 Object
*nlisttree
= NULL
;
249 struct TagItem convtags
[20];
250 struct TagItem supertags
[20];
253 /* Convert tags designated for NListtree */
254 for (i
= 0, tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
)); )
258 CONV(MUIA_Frame
, MUIA_Frame
)
259 CONV(MUIA_Listtree_Format
, MUIA_NListtree_Format
)
260 CONV(MUIA_Listtree_Title
, MUIA_NListtree_Title
)
261 CONV(MUIA_Listtree_DragDropSort
, MUIA_NListtree_DragDropSort
)
262 CONV(MUIA_List_Title
, MUIA_NList_Title
)
263 CONV(MUIA_List_DragSortable
, MUIA_NList_DragSortable
)
264 CONV(MUIA_List_MinLineHeight
, MUIA_NList_MinLineHeight
)
267 convtags
[i
].ti_Tag
= TAG_DONE
;
269 /* Copy tags designated for super class */
270 for (i
= 0, tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
)); )
274 COPY(MUIA_ContextMenu
) /* ContextMenuBuild/Choice will be called on child classes of Listtree */
277 supertags
[i
].ti_Tag
= TAG_DONE
;
280 * set up a DestructHook which will call proxy MUIS_Listtree_TreeNode destrhook and
283 obj
= (Object
*) DoSuperNewTags(cl
, obj
, 0,
284 Child
, nlisttree
= (Object
*) NewObjectA(CL_NListtreeInt
->mcc_Class
, NULL
, convtags
),
285 TAG_MORE
, (IPTR
)supertags
,
288 if (!obj
) return FALSE
;
290 data
= INST_DATA(cl
, obj
);
291 data
->nlisttree
= nlisttree
;
292 data
->notifysimulatehook
.h_Entry
= HookEntry
;
293 data
->notifysimulatehook
.h_SubEntry
= (HOOKFUNC
)NotifySimulate_Function
;
294 data
->notifysimulatehook
.h_Data
= cl
;
296 data
->pool
= CreatePool(MEMF_ANY
| MEMF_CLEAR
, 16 * 1024, 8 * 1024);
298 /* parse initial taglist */
299 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
)); )
303 case(MUIA_Listtree_ConstructHook
):
304 data
->constrhook
= (struct Hook
*)tag
->ti_Data
;
306 case(MUIA_Listtree_DestructHook
):
307 data
->destrhook
= (struct Hook
*)tag
->ti_Data
;
309 case(MUIA_Listtree_DisplayHook
):
310 data
->displayhook
= (struct Hook
*)tag
->ti_Data
;
312 case(MUIA_List_MinLineHeight
):
313 case(MUIA_List_DragSortable
):
314 case(MUIA_List_Title
):
315 case(MUIA_Listtree_DragDropSort
):
316 case(MUIA_Listtree_Format
):
317 case(MUIA_Listtree_Title
):
319 /* Forwarded to NListtree */
321 case(MUIA_ContextMenu
):
322 /* Forwarded to super class */
324 NEWHANDLE(MUIA_Listtree_SortHook
)
326 bug("[Listtree] OM_NEW: unhandled %x\n", tag
->ti_Tag
);
330 /* Setup connection */
331 set(data
->nlisttree
, MUIA_NListtreeInt_Listtree
, obj
);
333 /* Setup root node */
336 * Leave the tn_User of root node as NULL. It is expected that
337 * parent of first level item is returned as NULL in Listtree
341 /* Setup hook proxies */
342 if (data
->displayhook
)
344 data
->displayhookproxy
.h_Entry
= HookEntry
;
345 data
->displayhookproxy
.h_SubEntry
= (HOOKFUNC
)DisplayHook_Proxy
;
346 data
->displayhookproxy
.h_Data
= data
->displayhook
;
347 nnset(data
->nlisttree
, MUIA_NListtree_DisplayHook
, &data
->displayhookproxy
);
349 /* Destroy hook is mandatory to free proxy structures */
351 data
->destructhookproxy
.h_Entry
= HookEntry
;
352 data
->destructhookproxy
.h_SubEntry
= (HOOKFUNC
)DestructHook_Proxy
;
353 data
->destructhookproxy
.h_Data
= data
;
354 nnset(data
->nlisttree
, MUIA_NListtree_DestructHook
, &data
->destructhookproxy
);
357 /* Setup notification forwarding */
358 NOTIFY_FORWARD(MUIA_NListtree_Active
)
359 NOTIFY_FORWARD(MUIA_NListtree_DoubleClick
)
360 NOTIFY_FORWARD(MUIA_NListtree_Quiet
)
365 IPTR
Listtree__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
367 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
369 DeletePool(data
->pool
);
371 return DoSuperMethodA(cl
, obj
, msg
);
374 #define SETHANDLE(attrname) \
376 bug("[Listtree] OM_SET:%s - unsupported\n", #attrname); \
379 #define FORWARDSET(AATTR, BATTR) \
381 set(data->nlisttree, BATTR, tag->ti_Data); \
384 #define IGNORESET(AATTR) case(AATTR): break;
386 IPTR
Listtree__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
388 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
389 struct TagItem
*tstate
= msg
->ops_AttrList
;
392 if (!data
->nlisttree
)
393 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
395 while ((tag
= NextTagItem(&tstate
)) != NULL
)
399 FORWARDSET(MUIA_Listtree_Quiet
, MUIA_NListtree_Quiet
)
400 FORWARDSET(MUIA_List_Active
, MUIA_NList_Active
)
402 IGNORESET(MUIA_Listview_SelectChange
)
404 case(MUIA_Listtree_Active
):
405 set(data
->nlisttree
, MUIA_NListtree_Active
,
406 ((struct MUIS_Listtree_TreeNodeInt
*)tag
->ti_Data
)->ref
);
409 SETHANDLE(MUIA_Listtree_DoubleClick
)
410 case MUIB_List
| 0x00000010: break;
411 case MUIA_Prop_First
: break;
412 case MUIA_Prop_DoSmooth
: break;
413 case MUIA_NoNotify
: break;
414 case MUIA_Prop_Entries
: break;
415 case MUIA_Prop_Visible
: break;
416 case MUIA_Prop_DeltaFactor
: break;
418 bug("[Listtree] OM_SET: passing to parent class %x\n", tag
->ti_Tag
);
423 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
426 #define GETHANDLE(attrname) \
428 bug("[Listtree] OM_GET:%s - unsupported\n", #attrname); \
432 #define MUIA_List_Prop_Entries /* PRIV */ \
433 (MUIB_MUI | 0x0042a8f5) /* .sg LONG PRIV */
434 #define MUIA_List_Prop_Visible /* PRIV */ \
435 (MUIB_MUI | 0x004273e9) /* .sg LONG PRIV */
436 #define MUIA_List_Prop_First /* PRIV */ \
437 (MUIB_MUI | 0x00429df3) /* .sg LONG PRIV */
439 #define MUIA_List_VertProp_Entries /* PRIV */ \
440 MUIA_List_Prop_Entries /* PRIV */
441 #define MUIA_List_VertProp_Visible /* PRIV */ \
442 MUIA_List_Prop_Visible /* PRIV */
443 #define MUIA_List_VertProp_First /* PRIV */ \
444 MUIA_List_Prop_First /* PRIV */
446 #define FORWARDGET(AATTR, BATTR) \
448 *(msg->opg_Storage) = XGET(data->nlisttree, BATTR); \
451 IPTR
Listtree__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
453 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
455 if (!data
->nlisttree
)
458 switch (msg
->opg_AttrID
)
460 FORWARDGET(MUIA_Frame
, MUIA_Frame
)
461 FORWARDGET(MUIA_Listtree_DoubleClick
, MUIA_NListtree_DoubleClick
)
462 FORWARDGET(MUIA_List_Active
, MUIA_NList_Active
)
463 FORWARDGET(MUIA_Listtree_Active
, MUIA_NListtree_Active
)
464 FORWARDGET(MUIA_Listtree_Quiet
, MUIA_NListtree_Quiet
)
465 FORWARDGET(MUIA_List_Visible
, MUIA_NList_Visible
)
467 GETHANDLE(MUIA_List_VertProp_Entries
)
468 GETHANDLE(MUIA_List_VertProp_Visible
)
469 GETHANDLE(MUIA_List_VertProp_First
)
470 case MUIA_Disabled
: break;
471 case MUIA_Parent
: break;
472 case MUIA_Group_ChildList
: break;
473 case MUIA_Prop_First
: break;
474 case MUIA_Prop_DoSmooth
: break;
475 case MUIA_Listview_List
: break;
476 case MUIA_Virtgroup_Left
: break;
477 case MUIA_Virtgroup_Top
: break;
478 case 0x9d510020 /*MUIA_NListview_NList*/: break;
480 bug("[Listtree] OM_GET: passing to parent class %x\n", msg
->opg_AttrID
);
483 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
486 #define METHODSTUB(methodname) \
487 IPTR Listtree__##methodname(struct IClass *cl, Object *obj, Msg msg) \
489 bug("[Listtree] Usupported : %s\n", #methodname); \
490 return (IPTR)FALSE; \
493 METHODSTUB(MUIM_Listtree_SetDropMark
)
495 IPTR
Listtree__MUIM_Listtree_Insert(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_Insert
*msg
)
497 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
498 struct MUIS_Listtree_TreeNodeInt
* _int
= AllocPooled(data
->pool
, sizeof(struct MUIS_Listtree_TreeNodeInt
));
499 struct MUIS_Listtree_TreeNode
* _return
= NULL
;
500 struct MUI_NListtree_TreeNode
* ln
= NULL
, * pn
= NULL
;
505 _return
= &_int
->base
;
507 _return
->tn_Flags
= (UWORD
)msg
->Flags
;
508 if (data
->constrhook
)
509 _return
->tn_User
= (APTR
)CallHookPkt(data
->constrhook
, data
->pool
, msg
->User
);
511 _return
->tn_User
= msg
->User
;
513 switch((IPTR
)msg
->ListNode
)
515 case(MUIV_Listtree_Insert_ListNode_Root
):
516 case(MUIV_Listtree_Insert_ListNode_Active
):
520 ln
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->ListNode
)->ref
;
523 switch((IPTR
)msg
->PrevNode
)
525 case(MUIV_Listtree_Insert_PrevNode_Head
):
526 case(MUIV_Listtree_Insert_PrevNode_Tail
):
527 case(MUIV_Listtree_Insert_PrevNode_Active
):
528 case(MUIV_Listtree_Insert_PrevNode_Sorted
):
532 pn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->PrevNode
)->ref
;
535 _int
->ref
= (struct MUI_NListtree_TreeNode
*)DoMethod(data
->nlisttree
,
536 MUIM_NListtree_Insert
, msg
->Name
, _return
, ln
, pn
, msg
->Flags
);
538 _return
->tn_Name
= _int
->ref
->tn_Name
;
540 return (IPTR
)_return
;
543 IPTR
Listtree__MUIM_Listtree_GetEntry(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_GetEntry
*msg
)
545 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
546 struct MUI_NListtree_TreeNode
* tn
= NULL
, * found
= NULL
;
548 switch ((IPTR
)msg
->Node
)
550 case(MUIV_Listtree_GetEntry_ListNode_Root
):
551 case(MUIV_Listtree_GetEntry_ListNode_Active
):
555 tn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->Node
)->ref
;
558 found
= (struct MUI_NListtree_TreeNode
*) DoMethod(data
->nlisttree
,
559 MUIM_NListtree_GetEntry
, tn
, msg
->Position
, msg
->Flags
);
563 SYNC_TREENODE_FLAGS(found
);
564 return (IPTR
)found
->tn_User
;
570 IPTR
Listtree__MUIM_Listtree_Remove(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_Remove
*msg
)
572 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
574 /* TODO: handle remaining enumeration values */
575 if ((msg
->ListNode
== (APTR
)MUIV_Listtree_Remove_ListNode_Root
) &&
576 ((msg
->TreeNode
== (APTR
)MUIV_Listtree_Remove_TreeNode_Active
) ||
577 (msg
->TreeNode
== (APTR
)MUIV_Listtree_Remove_TreeNode_All
)))
579 /* Deallocating of MUIS_Listtree_TreeNode is happening in the DestructHook */
580 return DoMethod(data
->nlisttree
, MUIM_NListtree_Remove
, msg
->ListNode
, msg
->TreeNode
, msg
->Flags
);
584 * add handling for cases where ListNode/TreeNode actually point to Treenode structure
586 bug("[Listtree] MUIM_Listtree_Remove unsupported code path Listnode: %x, Treenode: %x, Flags: %d\n", msg
->ListNode
, msg
->TreeNode
, msg
->Flags
);
591 IPTR
Listtree__MUIM_List_TestPos(struct IClass
*cl
, Object
*obj
, struct MUIP_List_TestPos
*msg
)
593 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
595 struct MUI_NList_TestPos_Result res
;
596 if (DoMethod(data
->nlisttree
, MUIM_List_TestPos
, msg
->x
, msg
->y
, &res
))
598 msg
->res
->entry
= res
.entry
;
599 msg
->res
->column
= res
.column
;
600 msg
->res
->flags
= res
.flags
;
601 msg
->res
->xoffset
= res
.xoffset
;
602 msg
->res
->yoffset
= res
.yoffset
;
609 IPTR
Listtree__MUIM_Listtree_TestPos(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_TestPos
*msg
)
611 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
613 struct MUI_NListtree_TestPos_Result res
;
614 struct MUIS_Listtree_TestPos_Result
* _ret
= (struct MUIS_Listtree_TestPos_Result
*)msg
->Result
;
616 _ret
->tpr_TreeNode
= NULL
;
618 DoMethod(data
->nlisttree
, MUIM_NListtree_TestPos
, msg
->X
, msg
->Y
, &res
);
620 _ret
->tpr_Flags
= res
.tpr_Type
;
621 _ret
->tpr_ListEntry
= res
.tpr_ListEntry
;
622 _ret
->tpr_ListFlags
= res
.tpr_ListFlags
;
624 if (res
.tpr_TreeNode
!= NULL
)
626 SYNC_TREENODE_FLAGS(res
.tpr_TreeNode
);
627 _ret
->tpr_TreeNode
= res
.tpr_TreeNode
->tn_User
;
634 IPTR
Listtree__MUIM_Listtree_GetNr(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_GetNr
*msg
)
636 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
637 struct MUI_NListtree_TreeNode
* tn
= NULL
;
639 switch((IPTR
)msg
->TreeNode
)
641 case(MUIV_Listtree_GetNr_TreeNode_Active
):
645 tn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->TreeNode
)->ref
;
648 return DoMethod(data
->nlisttree
, MUIM_NListtree_GetNr
, tn
, msg
->Flags
);
651 IPTR
Listtree__MUIM_Listtree_Rename(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_Rename
*msg
)
653 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
654 struct MUI_NListtree_TreeNode
* tn
= NULL
, * renamed
= NULL
;
656 switch((IPTR
)msg
->TreeNode
)
658 case(MUIV_Listtree_Rename_TreeNode_Active
):
662 tn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->TreeNode
)->ref
;
665 renamed
= (struct MUI_NListtree_TreeNode
*)DoMethod(data
->nlisttree
,
666 MUIM_NListtree_Rename
, tn
, msg
->NewName
, msg
->Flags
);
670 ((struct MUIS_Listtree_TreeNode
*)renamed
->tn_User
)->tn_Name
= renamed
->tn_Name
;
671 return (IPTR
)renamed
->tn_User
;
677 IPTR
Listtree__MUIM_List_Redraw(struct IClass
*cl
, Object
*obj
, struct MUIP_List_Redraw
*msg
)
679 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
680 struct MUI_NListtree_TreeNode
* entry
= msg
->entry
?
681 ((struct MUIS_Listtree_TreeNodeInt
*)msg
->entry
)->ref
: NULL
;
685 case(MUIV_List_Redraw_Entry
):
686 return DoMethod(data
->nlisttree
, MUIM_NList_RedrawEntry
, entry
);
688 return DoMethod(data
->nlisttree
, MUIM_NList_Redraw
, msg
->pos
);
692 IPTR
Listtree__MUIM_Listtree_Open(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_Open
*msg
)
694 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
695 struct MUI_NListtree_TreeNode
* tn
= NULL
, * ln
= NULL
;
697 switch((IPTR
)msg
->ListNode
)
699 case(MUIV_Listtree_Open_ListNode_Root
):
700 case(MUIV_Listtree_Open_ListNode_Parent
):
701 case(MUIV_Listtree_Open_ListNode_Active
):
705 ln
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->ListNode
)->ref
;
708 switch((IPTR
)msg
->TreeNode
)
710 case(MUIV_Listtree_Open_TreeNode_Head
):
711 case(MUIV_Listtree_Open_TreeNode_Tail
):
712 case(MUIV_Listtree_Open_TreeNode_Active
):
713 case(MUIV_Listtree_Open_TreeNode_All
):
717 tn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->TreeNode
)->ref
;
720 return DoMethod(data
->nlisttree
, MUIM_NListtree_Open
, ln
, tn
, msg
->Flags
);
723 IPTR
Listtree__MUIM_Listtree_FindName(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_FindName
*msg
)
725 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
726 struct MUI_NListtree_TreeNode
* ln
= NULL
, * found
= NULL
;
728 switch((IPTR
)msg
->ListNode
)
730 case(MUIV_Listtree_FindName_ListNode_Root
):
731 case(MUIV_Listtree_FindName_ListNode_Active
):
735 ln
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->ListNode
)->ref
;
738 found
= (struct MUI_NListtree_TreeNode
*) DoMethod(data
->nlisttree
, MUIM_NListtree_FindName
,
739 ln
, msg
->Name
, msg
->Flags
);
742 return (IPTR
)found
->tn_User
;
753 #define MADF_SETUP (1<< 28) /* PRIV - zune-specific */
755 IPTR
DoSetupMethod(Object
* obj
, struct MUI_RenderInfo
* info
)
757 /* MUI set the correct render info *before* it calls MUIM_Setup so please
758 * only use this function instead of DoMethodA() */
759 muiRenderInfo(obj
) = info
;
760 return DoMethod(obj
, MUIM_Setup
, (IPTR
) info
);
763 IPTR
Listtree__MUIM_List_CreateImage(struct IClass
*cl
, Object
*obj
, struct MUIP_List_CreateImage
*msg
)
765 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
767 if (!(_flags(obj
) & MADF_SETUP
))
770 IPTR _ret
= DoMethod(data
->nlisttree
, MUIM_NList_CreateImage
, msg
->obj
, msg
->flags
);
772 /* There is a use case where an image object created in a Listtree can be passed as O[address]
773 * in the text in the display callback of List. Since Listtree just wraps around NListtree and the
774 * return structures from List_CreateImage and NList_CreateImage are different, this would normally
775 * not work. Luckily, List needs only the msg->obj and it is at the same offset in ListImage and
776 * in structure returned by NList. The case will work as long as this is met.
778 struct ListImage
* li
= (struct ListImage
*)_ret
;
779 if (li
->obj
!= msg
->obj
)
780 bug("[Listtree] CreateImage condition BROKEN, see comment in code!\n");
782 /* Setup the msg->obj as the List is doing */
783 DoMethod(li
->obj
, MUIM_ConnectParent
, (IPTR
) obj
);
784 DoSetupMethod(li
->obj
, muiRenderInfo(obj
));
789 IPTR
Listtree__MUIM_List_DeleteImage(struct IClass
*cl
, Object
*obj
, struct MUIP_List_DeleteImage
*msg
)
791 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
792 struct ListImage
* li
= (struct ListImage
*)msg
->listimg
;
797 /* DoMethod(li->obj, MUIM_Cleanup); // Called in MUIM_NList_DeleteImage */
798 DoMethod(li
->obj
, MUIM_DisconnectParent
);
799 return DoMethod(data
->nlisttree
, MUIM_NList_DeleteImage
, msg
->listimg
);
802 IPTR
Listtree__MUIM_Listtree_Close(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_Close
*msg
)
804 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
805 struct MUI_NListtree_TreeNode
* tn
= NULL
, * ln
= NULL
;
807 switch((IPTR
)msg
->ListNode
)
809 case(MUIV_Listtree_Close_ListNode_Root
):
810 case(MUIV_Listtree_Close_ListNode_Parent
):
811 case(MUIV_Listtree_Close_ListNode_Active
):
815 ln
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->ListNode
)->ref
;
818 switch((IPTR
)msg
->TreeNode
)
820 case(MUIV_Listtree_Close_TreeNode_Head
):
821 case(MUIV_Listtree_Close_TreeNode_Tail
):
822 case(MUIV_Listtree_Close_TreeNode_Active
):
823 case(MUIV_Listtree_Close_TreeNode_All
):
827 tn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->TreeNode
)->ref
;
830 return DoMethod(data
->nlisttree
, MUIM_NListtree_Close
, ln
, tn
, msg
->Flags
);
833 IPTR
Listtree__MUIM_CreateDragImage(struct IClass
*cl
, Object
*obj
, struct MUIP_CreateDragImage
*msg
)
835 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
836 return DoMethodA(data
->nlisttree
, (Msg
)msg
);
839 IPTR
Listtree__MUIM_DeleteDragImage(struct IClass
*cl
, Object
*obj
, struct MUIP_DeleteDragImage
*msg
)
841 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
842 return DoMethodA(data
->nlisttree
, (Msg
)msg
);
845 #define FORWARDNLISTTREESUPERMETHOD(methodname) \
846 IPTR Listtree__##methodname(struct IClass *cl, Object *obj, Msg msg) \
848 struct Listtree_DATA *data = INST_DATA(cl, obj); \
849 return DoMethod(data->nlisttree, MUIM_NListtreeInt_ForwardSuperMethod, msg); \