2 Copyright © 2012-2015, The AROS Development Team. All rights reserved.
6 #include <proto/intuition.h>
7 #include <proto/utility.h>
8 #include <proto/graphics.h>
9 #include <clib/alib_protos.h>
10 #include <mui/NListtree_mcc.h>
11 #include <mui/NList_mcc.h>
15 #include "Listtree_mcc.h"
16 #include "listtree_private.h"
19 #include <aros/debug.h>
21 #define MUIA_List_ListArea (MUIB_List | 0x00000003)
23 #define MUIA_List_Prop_Entries (MUIB_MUI | 0x0042a8f5) /* .sg LONG PRIV */
24 #define MUIA_List_Prop_Visible (MUIB_MUI | 0x004273e9) /* .sg LONG PRIV */
25 #define MUIA_List_Prop_First (MUIB_MUI | 0x00429df3) /* .sg LONG PRIV */
27 #define MUIA_List_VertProp_Entries MUIA_List_Prop_Entries /* PRIV */
28 #define MUIA_List_VertProp_Visible MUIA_List_Prop_Visible /* PRIV */
29 #define MUIA_List_VertProp_First MUIA_List_Prop_First /* PRIV */
37 #define MADF_SETUP (1<< 28) /* PRIV - zune-specific */
40 * MUIS_Listtree_Treenode -> MUI_NListtree_Treenode via MUIS_Listtree_TreeNodeInt.ref
41 * MUI_NListtree_Treenode -> MUIS_Listtree_Treenode via MUI_NListtree_Treenode.tn_User
43 struct MUIS_Listtree_TreeNodeInt
45 struct MUIS_Listtree_TreeNode base
;
46 struct MUI_NListtree_TreeNode
*ref
;
49 #define SYNC_TREENODE_FLAGS(tn) \
50 if (tn && tn->tn_User) \
51 ((struct MUIS_Listtree_TreeNode *)tn->tn_User)->tn_Flags = tn->tn_Flags;
53 #define SYNC_TREENODE_NAME(tn) \
54 if (tn && tn->tn_User) \
55 ((struct MUIS_Listtree_TreeNode *)tn->tn_User)->tn_Name = tn->tn_Name;
57 static IPTR
NotifySimulate_Function(struct Hook
*hook
, Object
*obj
, void ** msg
)
60 struct TagItem setti
[] = {{0,0},{TAG_DONE
, TAG_DONE
}};
62 IPTR attr
= (IPTR
)msg
[0];
63 IPTR val
= (IPTR
)msg
[1];
64 struct IClass
* cl
= hook
->h_Data
;
66 setmsg
.MethodID
= OM_SET
;
67 setmsg
.ops_AttrList
= setti
;
68 setmsg
.ops_GInfo
= NULL
;
72 case(MUIA_NListtree_Active
):
73 setti
[0].ti_Tag
= MUIA_Listtree_Active
;
74 setti
[0].ti_Data
= val
? (IPTR
)((struct MUI_NListtree_TreeNode
*)val
)->tn_User
: 0;
76 case(MUIA_NListtree_DoubleClick
):
77 setti
[0].ti_Tag
= MUIA_Listtree_DoubleClick
;
78 setti
[0].ti_Data
= val
;
80 case(MUIA_NListtree_Quiet
):
81 setti
[0].ti_Tag
= MUIA_Listtree_Quiet
;
82 setti
[0].ti_Data
= val
;
85 bug("[Listtree] NotifySimulate_Function - unhandled attribute %x\n", attr
);
88 /* Super method OM_SET call will go to Notify class and trigger notifications */
89 return DoSuperMethodA(cl
, obj
, (Msg
) &setmsg
);
92 static IPTR
DisplayHook_Proxy(struct Hook
*hook
, Object
*obj
, struct MUIP_NListtree_DisplayMessage
*msg
)
94 struct Hook
* displayhook
= (struct Hook
*)hook
->h_Data
;
100 SYNC_TREENODE_FLAGS(msg
->TreeNode
);
102 tn
= msg
->TreeNode
? msg
->TreeNode
->tn_User
: NULL
;
104 return CallHookPkt(displayhook
, msg
->Array
, tn
);
107 static IPTR
SortHook_Proxy(struct Hook
*hook
, Object
*obj
, struct MUIP_NListtree_CompareMessage
*msg
)
109 struct Hook
* sorthook
= (struct Hook
*)hook
->h_Data
;
110 APTR tn1
= NULL
, tn2
= NULL
;
115 SYNC_TREENODE_FLAGS(msg
->TreeNode1
);
116 SYNC_TREENODE_FLAGS(msg
->TreeNode2
);
118 tn1
= msg
->TreeNode1
? msg
->TreeNode1
->tn_User
: NULL
;
119 tn2
= msg
->TreeNode2
? msg
->TreeNode2
->tn_User
: NULL
;
121 return CallHookPkt(sorthook
, tn1
, tn2
);
124 static IPTR
DestructHook_Proxy(struct Hook
*hook
, Object
*obj
, struct MUIP_NListtree_DestructMessage
*msg
)
126 struct Listtree_DATA
* data
= (struct Listtree_DATA
*)hook
->h_Data
;
127 struct MUIS_Listtree_TreeNode
* tn
= (struct MUIS_Listtree_TreeNode
*)msg
->UserData
;
131 if (data
->destrhook
&& tn
)
132 CallHookPkt(data
->destrhook
, data
->pool
, tn
->tn_User
);
134 FreePooled(data
->pool
, tn
, sizeof(struct MUIS_Listtree_TreeNodeInt
));
139 static IPTR
ConstructHook_Proxy(struct Hook
*hook
, Object
*obj
, struct MUIP_NListtree_ConstructMessage
*msg
)
141 struct Listtree_DATA
* data
= (struct Listtree_DATA
*)hook
->h_Data
;
142 struct MUIS_Listtree_TreeNode
* tn
= NULL
;
146 tn
= AllocPooled(data
->pool
, sizeof(struct MUIS_Listtree_TreeNodeInt
));
151 if (data
->constrhook
)
152 tn
->tn_User
= (APTR
)CallHookPkt(data
->constrhook
, data
->pool
, msg
->UserData
);
154 tn
->tn_User
= msg
->UserData
;
159 #define CONV(AATTR, BATTR) \
161 convtags[i].ti_Tag = BATTR; \
162 convtags[i++].ti_Data = tag->ti_Data; \
165 #define COPY(AATTR) \
167 supertags[i].ti_Tag = AATTR; \
168 supertags[i++].ti_Data = tag->ti_Data; \
171 #define NOTIFY_FORWARD(AATTR) \
172 DoMethod(data->nlisttree, MUIM_Notify, AATTR, MUIV_EveryTime, \
173 obj, 4, MUIM_CallHook, &data->notifysimulatehook, AATTR, MUIV_TriggerValue);
175 /*** Methods ****************************************************************/
176 Object
*Listtree__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
178 struct Listtree_DATA
*data
= NULL
;
180 struct TagItem
*tags
;
181 Object
*nlisttree
= NULL
;
182 struct TagItem convtags
[20];
183 struct TagItem supertags
[20];
186 /* Convert tags designated for NListtree */
187 for (i
= 0, tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
)); )
191 CONV(MUIA_Frame
, MUIA_Frame
)
192 CONV(MUIA_Listtree_Format
, MUIA_NListtree_Format
)
193 CONV(MUIA_Listtree_Title
, MUIA_NListtree_Title
)
194 CONV(MUIA_Listtree_DragDropSort
, MUIA_NListtree_DragDropSort
)
195 CONV(MUIA_List_Title
, MUIA_NList_Title
)
196 CONV(MUIA_List_DragSortable
, MUIA_NList_DragSortable
)
197 CONV(MUIA_List_MinLineHeight
, MUIA_NList_MinLineHeight
)
200 convtags
[i
].ti_Tag
= TAG_DONE
;
202 /* Copy tags designated for super class */
203 for (i
= 0, tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
)); )
207 COPY(MUIA_ContextMenu
) /* ContextMenuBuild/Choice will be called on child classes of Listtree */
210 supertags
[i
].ti_Tag
= TAG_DONE
;
212 nlisttree
= (Object
*) NewObjectA(CL_NListtreeInt
->mcc_Class
, NULL
, convtags
);
214 obj
= (Object
*) DoSuperNewTags(cl
, obj
, 0,
215 MUIA_List_ListArea
, nlisttree
,
216 TAG_MORE
, (IPTR
)supertags
,
219 if (!obj
) return FALSE
;
221 data
= INST_DATA(cl
, obj
);
222 data
->nlisttree
= nlisttree
;
223 data
->notifysimulatehook
.h_Entry
= HookEntry
;
224 data
->notifysimulatehook
.h_SubEntry
= (HOOKFUNC
)NotifySimulate_Function
;
225 data
->notifysimulatehook
.h_Data
= cl
;
227 data
->pool
= CreatePool(MEMF_ANY
| MEMF_CLEAR
, 16 * 1024, 8 * 1024);
229 /* parse initial taglist */
230 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
)); )
234 case(MUIA_Listtree_ConstructHook
):
235 data
->constrhook
= (struct Hook
*)tag
->ti_Data
;
237 case(MUIA_Listtree_DestructHook
):
238 data
->destrhook
= (struct Hook
*)tag
->ti_Data
;
240 case(MUIA_Listtree_DisplayHook
):
241 data
->displayhook
= (struct Hook
*)tag
->ti_Data
;
243 case(MUIA_Listtree_SortHook
):
244 data
->sorthook
= (struct Hook
*)tag
->ti_Data
;
247 /* Forwarded to NListtree */
248 case(MUIA_List_MinLineHeight
):
249 case(MUIA_List_DragSortable
):
250 case(MUIA_List_Title
):
251 case(MUIA_Listtree_DragDropSort
):
252 case(MUIA_Listtree_Format
):
253 case(MUIA_Listtree_Title
):
257 /* Forwarded to super class */
258 case(MUIA_ContextMenu
):
262 bug("[Listtree] OM_NEW: unhandled %x\n", tag
->ti_Tag
);
266 /* Setup connection */
267 set(data
->nlisttree
, MUIA_NListtreeInt_Listtree
, obj
);
269 /* Setup root node */
272 * Leave the tn_User of root node as NULL. It is expected that
273 * parent of first level item is returned as NULL in Listtree
277 /* Setup hook proxies */
278 if (data
->displayhook
)
280 data
->displayhookproxy
.h_Entry
= HookEntry
;
281 data
->displayhookproxy
.h_SubEntry
= (HOOKFUNC
)DisplayHook_Proxy
;
282 data
->displayhookproxy
.h_Data
= data
->displayhook
;
283 nnset(data
->nlisttree
, MUIA_NListtree_DisplayHook
, &data
->displayhookproxy
);
287 data
->sorthookproxy
.h_Entry
= HookEntry
;
288 data
->sorthookproxy
.h_SubEntry
= (HOOKFUNC
)SortHook_Proxy
;
289 data
->sorthookproxy
.h_Data
= data
->sorthook
;
290 nnset(data
->nlisttree
, MUIA_NListtree_CompareHook
, &data
->sorthookproxy
);
293 /* Construct hook is mandatory to allocate proxy structures */
295 data
->constructhookproxy
.h_Entry
= HookEntry
;
296 data
->constructhookproxy
.h_SubEntry
= (HOOKFUNC
)ConstructHook_Proxy
;
297 data
->constructhookproxy
.h_Data
= data
;
298 nnset(data
->nlisttree
, MUIA_NListtree_ConstructHook
, &data
->constructhookproxy
);
300 /* Destroy hook is mandatory to free proxy structures */
302 data
->destructhookproxy
.h_Entry
= HookEntry
;
303 data
->destructhookproxy
.h_SubEntry
= (HOOKFUNC
)DestructHook_Proxy
;
304 data
->destructhookproxy
.h_Data
= data
;
305 nnset(data
->nlisttree
, MUIA_NListtree_DestructHook
, &data
->destructhookproxy
);
308 /* Setup notification forwarding */
309 NOTIFY_FORWARD(MUIA_NListtree_Active
)
310 NOTIFY_FORWARD(MUIA_NListtree_DoubleClick
)
311 NOTIFY_FORWARD(MUIA_NListtree_Quiet
)
316 IPTR
Listtree__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
318 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
320 APTR pool
= data
->pool
;
321 IPTR result
= DoSuperMethodA(cl
, obj
, msg
);
323 /* Destruct hook called by dispose on NListree will need the pool,
324 * so destroy it only after super dispose is called */
330 #define FORWARDSET(AATTR, BATTR) \
332 set(data->nlisttree, BATTR, tag->ti_Data); \
335 IPTR
Listtree__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
337 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
338 struct TagItem
*tstate
= msg
->ops_AttrList
;
341 if (!data
->nlisttree
)
342 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
344 while ((tag
= NextTagItem(&tstate
)) != NULL
)
348 FORWARDSET(MUIA_Listtree_Quiet
, MUIA_NListtree_Quiet
)
349 FORWARDSET(MUIA_List_Active
, MUIA_NList_Active
)
350 FORWARDSET(MUIA_List_Prop_First
, MUIA_NList_Prop_First
)
351 FORWARDSET(MUIA_List_Prop_Visible
, MUIA_NList_Prop_Visible
)
353 case(MUIA_Listtree_Active
):
354 set(data
->nlisttree
, MUIA_NListtree_Active
,
355 ((struct MUIS_Listtree_TreeNodeInt
*)tag
->ti_Data
)->ref
);
358 /* Setting MUIA_List_First causes weird behaviour of scroll bar */
359 case(MUIA_List_First
):
360 /* set(data->nlisttree, MUIA_NList_First, tag->ti_Data); */ /* Don't set directly */
361 tag
->ti_Tag
= TAG_IGNORE
; /* Don't set via forward via Group(List)->NListtree */
365 case MUIA_Listtree_DoubleClick
:
366 case MUIA_Listview_SelectChange
:
367 case MUIA_Prop_First
:
368 case MUIA_Prop_DoSmooth
:
370 case MUIA_Prop_Entries
:
371 case MUIA_Prop_Visible
:
372 case MUIA_Prop_DeltaFactor
:
379 bug("[Listtree] OM_SET: passing to parent class %x\n", tag
->ti_Tag
);
384 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
387 #define FORWARDGET(AATTR, BATTR) \
389 *(msg->opg_Storage) = XGET(data->nlisttree, BATTR); \
392 IPTR
Listtree__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
394 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
396 if (!data
->nlisttree
)
399 switch (msg
->opg_AttrID
)
401 FORWARDGET(MUIA_Frame
, MUIA_Frame
)
402 FORWARDGET(MUIA_Listtree_DoubleClick
, MUIA_NListtree_DoubleClick
)
403 FORWARDGET(MUIA_List_Active
, MUIA_NList_Active
)
404 FORWARDGET(MUIA_Listtree_Active
, MUIA_NListtree_Active
)
405 FORWARDGET(MUIA_Listtree_Quiet
, MUIA_NListtree_Quiet
)
406 FORWARDGET(MUIA_List_Visible
, MUIA_NList_Visible
)
407 FORWARDGET(MUIA_List_VertProp_First
, MUIA_NList_Prop_First
)
408 FORWARDGET(MUIA_List_VertProp_Entries
, MUIA_NList_Prop_Entries
)
409 FORWARDGET(MUIA_List_VertProp_Visible
, MUIA_NList_Prop_Visible
)
413 case MUIA_Group_ChildList
:
414 case MUIA_Prop_First
:
415 case MUIA_Prop_DoSmooth
:
416 case MUIA_Listview_List
:
417 case MUIA_Virtgroup_Left
:
418 case MUIA_Virtgroup_Top
:
419 case 0x9d510020 /*MUIA_NListview_NList*/:
420 case MUIA_Listview_DoubleClick
:
421 case MUIA_Listview_SelectChange
:
427 bug("[Listtree] OM_GET: passing to parent class %x\n", msg
->opg_AttrID
);
430 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
433 IPTR
Listtree__MUIM_Listtree_Insert(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_Insert
*msg
)
435 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
436 struct MUI_NListtree_TreeNode
* ln
= NULL
, * pn
= NULL
, * created
= NULL
;
438 switch((IPTR
)msg
->ListNode
)
440 case(MUIV_Listtree_Insert_ListNode_Root
):
441 case(MUIV_Listtree_Insert_ListNode_Active
):
445 ln
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->ListNode
)->ref
;
448 switch((IPTR
)msg
->PrevNode
)
450 case(MUIV_Listtree_Insert_PrevNode_Head
):
451 case(MUIV_Listtree_Insert_PrevNode_Tail
):
452 case(MUIV_Listtree_Insert_PrevNode_Active
):
453 case(MUIV_Listtree_Insert_PrevNode_Sorted
):
457 pn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->PrevNode
)->ref
;
460 created
= (struct MUI_NListtree_TreeNode
*)DoMethod(data
->nlisttree
,
461 MUIM_NListtree_Insert
, msg
->Name
, msg
->User
, ln
, pn
, msg
->Flags
);
465 SYNC_TREENODE_FLAGS(created
);
466 SYNC_TREENODE_NAME(created
);
467 ((struct MUIS_Listtree_TreeNodeInt
*)created
->tn_User
)->ref
= created
;
468 return (IPTR
)created
->tn_User
;
474 IPTR
Listtree__MUIM_Listtree_GetEntry(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_GetEntry
*msg
)
476 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
477 struct MUI_NListtree_TreeNode
* tn
= NULL
, * found
= NULL
;
479 switch ((IPTR
)msg
->Node
)
481 case(MUIV_Listtree_GetEntry_ListNode_Root
):
482 case(MUIV_Listtree_GetEntry_ListNode_Active
):
486 tn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->Node
)->ref
;
489 found
= (struct MUI_NListtree_TreeNode
*) DoMethod(data
->nlisttree
,
490 MUIM_NListtree_GetEntry
, tn
, msg
->Position
, msg
->Flags
);
494 SYNC_TREENODE_FLAGS(found
);
495 return (IPTR
)found
->tn_User
;
501 IPTR
Listtree__MUIM_Listtree_Remove(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_Remove
*msg
)
503 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
504 struct MUI_NListtree_TreeNode
* tn
= NULL
, * ln
= NULL
;
506 switch((IPTR
)msg
->ListNode
)
508 case(MUIV_Listtree_Remove_ListNode_Root
):
509 case(MUIV_Listtree_Remove_ListNode_Active
):
513 ln
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->ListNode
)->ref
;
516 switch((IPTR
)msg
->TreeNode
)
518 case(MUIV_Listtree_Remove_TreeNode_Head
):
519 case(MUIV_Listtree_Remove_TreeNode_Tail
):
520 case(MUIV_Listtree_Remove_TreeNode_Active
):
521 case(MUIV_Listtree_Remove_TreeNode_All
):
525 tn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->TreeNode
)->ref
;
528 /* Deallocating of MUIS_Listtree_TreeNode is happening in the DestructHook */
529 return DoMethod(data
->nlisttree
, MUIM_NListtree_Remove
, ln
, tn
, msg
->Flags
);
533 IPTR
Listtree__MUIM_List_TestPos(struct IClass
*cl
, Object
*obj
, struct MUIP_List_TestPos
*msg
)
535 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
537 struct MUI_NList_TestPos_Result res
;
538 if (DoMethod(data
->nlisttree
, MUIM_List_TestPos
, msg
->x
, msg
->y
, &res
))
540 msg
->res
->entry
= res
.entry
;
541 msg
->res
->column
= res
.column
;
542 msg
->res
->flags
= res
.flags
;
543 msg
->res
->xoffset
= res
.xoffset
;
544 msg
->res
->yoffset
= res
.yoffset
;
551 IPTR
Listtree__MUIM_Listtree_TestPos(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_TestPos
*msg
)
553 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
555 struct MUI_NListtree_TestPos_Result res
;
556 struct MUIS_Listtree_TestPos_Result
* _ret
= (struct MUIS_Listtree_TestPos_Result
*)msg
->Result
;
558 _ret
->tpr_TreeNode
= NULL
;
560 DoMethod(data
->nlisttree
, MUIM_NListtree_TestPos
, msg
->X
, msg
->Y
, &res
);
562 _ret
->tpr_Flags
= res
.tpr_Type
;
563 _ret
->tpr_ListEntry
= res
.tpr_ListEntry
;
564 _ret
->tpr_ListFlags
= res
.tpr_ListFlags
;
566 if (res
.tpr_TreeNode
!= NULL
)
568 SYNC_TREENODE_FLAGS(res
.tpr_TreeNode
);
569 _ret
->tpr_TreeNode
= res
.tpr_TreeNode
->tn_User
;
576 IPTR
Listtree__MUIM_Listtree_GetNr(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_GetNr
*msg
)
578 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
579 struct MUI_NListtree_TreeNode
* tn
= NULL
;
581 switch((IPTR
)msg
->TreeNode
)
583 case(MUIV_Listtree_GetNr_TreeNode_Active
):
587 tn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->TreeNode
)->ref
;
590 return DoMethod(data
->nlisttree
, MUIM_NListtree_GetNr
, tn
, msg
->Flags
);
593 IPTR
Listtree__MUIM_Listtree_Rename(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_Rename
*msg
)
595 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
596 struct MUI_NListtree_TreeNode
* tn
= NULL
, * renamed
= NULL
;
598 switch((IPTR
)msg
->TreeNode
)
600 case(MUIV_Listtree_Rename_TreeNode_Active
):
604 tn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->TreeNode
)->ref
;
607 renamed
= (struct MUI_NListtree_TreeNode
*)DoMethod(data
->nlisttree
,
608 MUIM_NListtree_Rename
, tn
, msg
->NewName
, msg
->Flags
);
612 ((struct MUIS_Listtree_TreeNode
*)renamed
->tn_User
)->tn_Name
= renamed
->tn_Name
;
613 return (IPTR
)renamed
->tn_User
;
619 IPTR
Listtree__MUIM_List_Redraw(struct IClass
*cl
, Object
*obj
, struct MUIP_List_Redraw
*msg
)
621 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
622 struct MUI_NListtree_TreeNode
* entry
= msg
->entry
?
623 ((struct MUIS_Listtree_TreeNodeInt
*)msg
->entry
)->ref
: NULL
;
627 case(MUIV_List_Redraw_Entry
):
628 return DoMethod(data
->nlisttree
, MUIM_NList_RedrawEntry
, entry
);
630 return DoMethod(data
->nlisttree
, MUIM_NList_Redraw
, msg
->pos
);
634 IPTR
Listtree__MUIM_Listtree_Open(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_Open
*msg
)
636 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
637 struct MUI_NListtree_TreeNode
* tn
= NULL
, * ln
= NULL
;
639 switch((IPTR
)msg
->ListNode
)
641 case(MUIV_Listtree_Open_ListNode_Root
):
642 case(MUIV_Listtree_Open_ListNode_Parent
):
643 case(MUIV_Listtree_Open_ListNode_Active
):
647 ln
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->ListNode
)->ref
;
650 switch((IPTR
)msg
->TreeNode
)
652 case(MUIV_Listtree_Open_TreeNode_Head
):
653 case(MUIV_Listtree_Open_TreeNode_Tail
):
654 case(MUIV_Listtree_Open_TreeNode_Active
):
655 case(MUIV_Listtree_Open_TreeNode_All
):
659 tn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->TreeNode
)->ref
;
662 return DoMethod(data
->nlisttree
, MUIM_NListtree_Open
, ln
, tn
, msg
->Flags
);
665 IPTR
Listtree__MUIM_Listtree_FindName(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_FindName
*msg
)
667 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
668 struct MUI_NListtree_TreeNode
* ln
= NULL
, * found
= NULL
;
670 switch((IPTR
)msg
->ListNode
)
672 case(MUIV_Listtree_FindName_ListNode_Root
):
673 case(MUIV_Listtree_FindName_ListNode_Active
):
677 ln
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->ListNode
)->ref
;
680 found
= (struct MUI_NListtree_TreeNode
*) DoMethod(data
->nlisttree
, MUIM_NListtree_FindName
,
681 ln
, msg
->Name
, msg
->Flags
);
684 return (IPTR
)found
->tn_User
;
689 IPTR
DoSetupMethod(Object
* obj
, struct MUI_RenderInfo
* info
)
691 /* MUI set the correct render info *before* it calls MUIM_Setup so please
692 * only use this function instead of DoMethodA() */
693 muiRenderInfo(obj
) = info
;
694 return DoMethod(obj
, MUIM_Setup
, (IPTR
) info
);
697 IPTR
Listtree__MUIM_List_CreateImage(struct IClass
*cl
, Object
*obj
, struct MUIP_List_CreateImage
*msg
)
699 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
701 if (!(_flags(obj
) & MADF_SETUP
))
704 IPTR _ret
= DoMethod(data
->nlisttree
, MUIM_NList_CreateImage
, msg
->obj
, msg
->flags
);
706 /* There is a use case where an image object created in a Listtree can be passed as O[address]
707 * in the text in the display callback of List. Since Listtree just wraps around NListtree and the
708 * return structures from List_CreateImage and NList_CreateImage are different, this would normally
709 * not work. Luckily, List needs only the msg->obj and it is at the same offset in ListImage and
710 * in structure returned by NList. The case will work as long as this is met.
712 struct ListImage
* li
= (struct ListImage
*)_ret
;
713 if (li
->obj
!= msg
->obj
)
714 bug("[Listtree] CreateImage condition BROKEN, see comment in code!\n");
716 /* Setup the msg->obj as the List is doing */
717 DoMethod(li
->obj
, MUIM_ConnectParent
, (IPTR
) obj
);
718 DoSetupMethod(li
->obj
, muiRenderInfo(obj
));
723 IPTR
Listtree__MUIM_List_DeleteImage(struct IClass
*cl
, Object
*obj
, struct MUIP_List_DeleteImage
*msg
)
725 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
726 struct ListImage
* li
= (struct ListImage
*)msg
->listimg
;
731 /* DoMethod(li->obj, MUIM_Cleanup); // Called in MUIM_NList_DeleteImage */
732 DoMethod(li
->obj
, MUIM_DisconnectParent
);
733 return DoMethod(data
->nlisttree
, MUIM_NList_DeleteImage
, msg
->listimg
);
736 IPTR
Listtree__MUIM_Listtree_Close(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_Close
*msg
)
738 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
739 struct MUI_NListtree_TreeNode
* tn
= NULL
, * ln
= NULL
;
741 switch((IPTR
)msg
->ListNode
)
743 case(MUIV_Listtree_Close_ListNode_Root
):
744 case(MUIV_Listtree_Close_ListNode_Parent
):
745 case(MUIV_Listtree_Close_ListNode_Active
):
749 ln
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->ListNode
)->ref
;
752 switch((IPTR
)msg
->TreeNode
)
754 case(MUIV_Listtree_Close_TreeNode_Head
):
755 case(MUIV_Listtree_Close_TreeNode_Tail
):
756 case(MUIV_Listtree_Close_TreeNode_Active
):
757 case(MUIV_Listtree_Close_TreeNode_All
):
761 tn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->TreeNode
)->ref
;
764 return DoMethod(data
->nlisttree
, MUIM_NListtree_Close
, ln
, tn
, msg
->Flags
);
767 #define FORWARDNLISTTREEMETHOD(methodname) \
768 IPTR Listtree__##methodname(struct IClass *cl, Object *obj, Msg msg) \
770 struct Listtree_DATA *data = INST_DATA(cl, obj); \
771 return DoMethodA(data->nlisttree, msg); \
774 FORWARDNLISTTREEMETHOD(MUIM_CreateDragImage
)
775 FORWARDNLISTTREEMETHOD(MUIM_DeleteDragImage
)
777 IPTR
Listtree__MUIM_Notify(struct IClass
*cl
, Object
*obj
, struct MUIP_Notify
*msg
)
779 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
781 /* NList expects this notification to be set and uses its content */
782 if (msg
->TrigAttr
== MUIA_List_Prop_First
)
783 DoMethodA(data
->nlisttree
, msg
);
785 if (msg
->TrigAttr
== MUIA_List_First
)
786 bug("Listtree.mcc: notifications on MUIA_List_First are not fired!\n");
788 return DoSuperMethodA(cl
, obj
, msg
);
791 #define METHODSTUB(methodname) \
792 IPTR Listtree__##methodname(struct IClass *cl, Object *obj, Msg msg) \
794 bug("[Listtree] Usupported : %s\n", #methodname); \
795 return (IPTR)FALSE; \
798 /* SetDropMark has no counterpart in NListtree and no documentation */
799 METHODSTUB(MUIM_Listtree_SetDropMark
)