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 static IPTR
NotifySimulate_Function(struct Hook
*hook
, Object
*obj
, void ** msg
)
56 struct TagItem setti
[] = {{0,0},{TAG_DONE
, TAG_DONE
}};
58 IPTR attr
= (IPTR
)msg
[0];
59 IPTR val
= (IPTR
)msg
[1];
60 struct IClass
* cl
= hook
->h_Data
;
62 setmsg
.MethodID
= OM_SET
;
63 setmsg
.ops_AttrList
= setti
;
64 setmsg
.ops_GInfo
= NULL
;
68 case(MUIA_NListtree_Active
):
69 setti
[0].ti_Tag
= MUIA_Listtree_Active
;
70 setti
[0].ti_Data
= val
? (IPTR
)((struct MUI_NListtree_TreeNode
*)val
)->tn_User
: 0;
72 case(MUIA_NListtree_DoubleClick
):
73 setti
[0].ti_Tag
= MUIA_Listtree_DoubleClick
;
74 setti
[0].ti_Data
= val
;
76 case(MUIA_NListtree_Quiet
):
77 setti
[0].ti_Tag
= MUIA_Listtree_Quiet
;
78 setti
[0].ti_Data
= val
;
81 bug("[Listtree] NotifySimulate_Function - unhandled attribute %x\n", attr
);
84 /* Super method OM_SET call will go to Notify class and trigger notifications */
85 return DoSuperMethodA(cl
, obj
, (Msg
) &setmsg
);
88 static IPTR
DisplayHook_Proxy(struct Hook
*hook
, Object
*obj
, struct MUIP_NListtree_DisplayMessage
*msg
)
90 struct Hook
* displayhook
= (struct Hook
*)hook
->h_Data
;
96 SYNC_TREENODE_FLAGS(msg
->TreeNode
);
98 tn
= msg
->TreeNode
? msg
->TreeNode
->tn_User
: NULL
;
100 return CallHookPkt(displayhook
, msg
->Array
, tn
);
103 static IPTR
SortHook_Proxy(struct Hook
*hook
, Object
*obj
, struct MUIP_NListtree_CompareMessage
*msg
)
105 struct Hook
* sorthook
= (struct Hook
*)hook
->h_Data
;
106 APTR tn1
= NULL
, tn2
= NULL
;
111 SYNC_TREENODE_FLAGS(msg
->TreeNode1
);
112 SYNC_TREENODE_FLAGS(msg
->TreeNode2
);
114 tn1
= msg
->TreeNode1
? msg
->TreeNode1
->tn_User
: NULL
;
115 tn2
= msg
->TreeNode2
? msg
->TreeNode2
->tn_User
: NULL
;
117 return CallHookPkt(sorthook
, tn1
, tn2
);
120 static IPTR
DestructHook_Proxy(struct Hook
*hook
, Object
*obj
, struct MUIP_NListtree_DestructMessage
*msg
)
122 struct Listtree_DATA
* data
= (struct Listtree_DATA
*)hook
->h_Data
;
123 struct MUIS_Listtree_TreeNode
* tn
= (struct MUIS_Listtree_TreeNode
*)msg
->UserData
;
127 if (data
->destrhook
&& tn
)
128 CallHookPkt(data
->destrhook
, data
->pool
, tn
->tn_User
);
130 FreePooled(data
->pool
, tn
, sizeof(struct MUIS_Listtree_TreeNodeInt
));
135 #define CONV(AATTR, BATTR) \
137 convtags[i].ti_Tag = BATTR; \
138 convtags[i++].ti_Data = tag->ti_Data; \
141 #define COPY(AATTR) \
143 supertags[i].ti_Tag = AATTR; \
144 supertags[i++].ti_Data = tag->ti_Data; \
147 #define NOTIFY_FORWARD(AATTR) \
148 DoMethod(data->nlisttree, MUIM_Notify, AATTR, MUIV_EveryTime, \
149 obj, 4, MUIM_CallHook, &data->notifysimulatehook, AATTR, MUIV_TriggerValue);
151 /*** Methods ****************************************************************/
152 Object
*Listtree__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
154 struct Listtree_DATA
*data
= NULL
;
156 struct TagItem
*tags
;
157 Object
*nlisttree
= NULL
;
158 struct TagItem convtags
[20];
159 struct TagItem supertags
[20];
162 /* Convert tags designated for NListtree */
163 for (i
= 0, tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
)); )
167 CONV(MUIA_Frame
, MUIA_Frame
)
168 CONV(MUIA_Listtree_Format
, MUIA_NListtree_Format
)
169 CONV(MUIA_Listtree_Title
, MUIA_NListtree_Title
)
170 CONV(MUIA_Listtree_DragDropSort
, MUIA_NListtree_DragDropSort
)
171 CONV(MUIA_List_Title
, MUIA_NList_Title
)
172 CONV(MUIA_List_DragSortable
, MUIA_NList_DragSortable
)
173 CONV(MUIA_List_MinLineHeight
, MUIA_NList_MinLineHeight
)
176 convtags
[i
].ti_Tag
= TAG_DONE
;
178 /* Copy tags designated for super class */
179 for (i
= 0, tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
)); )
183 COPY(MUIA_ContextMenu
) /* ContextMenuBuild/Choice will be called on child classes of Listtree */
186 supertags
[i
].ti_Tag
= TAG_DONE
;
188 nlisttree
= (Object
*) NewObjectA(CL_NListtreeInt
->mcc_Class
, NULL
, convtags
);
190 obj
= (Object
*) DoSuperNewTags(cl
, obj
, 0,
191 MUIA_List_ListArea
, nlisttree
,
192 TAG_MORE
, (IPTR
)supertags
,
195 if (!obj
) return FALSE
;
197 data
= INST_DATA(cl
, obj
);
198 data
->nlisttree
= nlisttree
;
199 data
->notifysimulatehook
.h_Entry
= HookEntry
;
200 data
->notifysimulatehook
.h_SubEntry
= (HOOKFUNC
)NotifySimulate_Function
;
201 data
->notifysimulatehook
.h_Data
= cl
;
203 data
->pool
= CreatePool(MEMF_ANY
| MEMF_CLEAR
, 16 * 1024, 8 * 1024);
205 /* parse initial taglist */
206 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
)); )
210 case(MUIA_Listtree_ConstructHook
):
211 data
->constrhook
= (struct Hook
*)tag
->ti_Data
;
213 case(MUIA_Listtree_DestructHook
):
214 data
->destrhook
= (struct Hook
*)tag
->ti_Data
;
216 case(MUIA_Listtree_DisplayHook
):
217 data
->displayhook
= (struct Hook
*)tag
->ti_Data
;
219 case(MUIA_Listtree_SortHook
):
220 data
->sorthook
= (struct Hook
*)tag
->ti_Data
;
223 /* Forwarded to NListtree */
224 case(MUIA_List_MinLineHeight
):
225 case(MUIA_List_DragSortable
):
226 case(MUIA_List_Title
):
227 case(MUIA_Listtree_DragDropSort
):
228 case(MUIA_Listtree_Format
):
229 case(MUIA_Listtree_Title
):
233 /* Forwarded to super class */
234 case(MUIA_ContextMenu
):
238 bug("[Listtree] OM_NEW: unhandled %x\n", tag
->ti_Tag
);
242 /* Setup connection */
243 set(data
->nlisttree
, MUIA_NListtreeInt_Listtree
, obj
);
245 /* Setup root node */
248 * Leave the tn_User of root node as NULL. It is expected that
249 * parent of first level item is returned as NULL in Listtree
253 /* Setup hook proxies */
254 if (data
->displayhook
)
256 data
->displayhookproxy
.h_Entry
= HookEntry
;
257 data
->displayhookproxy
.h_SubEntry
= (HOOKFUNC
)DisplayHook_Proxy
;
258 data
->displayhookproxy
.h_Data
= data
->displayhook
;
259 nnset(data
->nlisttree
, MUIA_NListtree_DisplayHook
, &data
->displayhookproxy
);
263 data
->sorthookproxy
.h_Entry
= HookEntry
;
264 data
->sorthookproxy
.h_SubEntry
= (HOOKFUNC
)SortHook_Proxy
;
265 data
->sorthookproxy
.h_Data
= data
->sorthook
;
266 nnset(data
->nlisttree
, MUIA_NListtree_CompareHook
, &data
->sorthookproxy
);
269 /* Destroy hook is mandatory to free proxy structures */
271 data
->destructhookproxy
.h_Entry
= HookEntry
;
272 data
->destructhookproxy
.h_SubEntry
= (HOOKFUNC
)DestructHook_Proxy
;
273 data
->destructhookproxy
.h_Data
= data
;
274 nnset(data
->nlisttree
, MUIA_NListtree_DestructHook
, &data
->destructhookproxy
);
277 /* Setup notification forwarding */
278 NOTIFY_FORWARD(MUIA_NListtree_Active
)
279 NOTIFY_FORWARD(MUIA_NListtree_DoubleClick
)
280 NOTIFY_FORWARD(MUIA_NListtree_Quiet
)
285 IPTR
Listtree__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
287 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
289 DeletePool(data
->pool
);
291 return DoSuperMethodA(cl
, obj
, msg
);
294 #define FORWARDSET(AATTR, BATTR) \
296 set(data->nlisttree, BATTR, tag->ti_Data); \
299 IPTR
Listtree__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
301 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
302 struct TagItem
*tstate
= msg
->ops_AttrList
;
305 if (!data
->nlisttree
)
306 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
308 while ((tag
= NextTagItem(&tstate
)) != NULL
)
312 FORWARDSET(MUIA_Listtree_Quiet
, MUIA_NListtree_Quiet
)
313 FORWARDSET(MUIA_List_Active
, MUIA_NList_Active
)
314 FORWARDSET(MUIA_List_Prop_First
, MUIA_NList_Prop_First
)
315 FORWARDSET(MUIA_List_Prop_Visible
, MUIA_NList_Prop_Visible
)
317 case(MUIA_Listtree_Active
):
318 set(data
->nlisttree
, MUIA_NListtree_Active
,
319 ((struct MUIS_Listtree_TreeNodeInt
*)tag
->ti_Data
)->ref
);
322 /* Setting MUIA_List_First causes weird behaviour of scroll bar */
323 case(MUIA_List_First
):
324 /* set(data->nlisttree, MUIA_NList_First, tag->ti_Data); */ /* Don't set directly */
325 tag
->ti_Tag
= TAG_IGNORE
; /* Don't set via forward via Group(List)->NListtree */
329 case MUIA_Listtree_DoubleClick
:
330 case MUIA_Listview_SelectChange
:
331 case MUIA_Prop_First
:
332 case MUIA_Prop_DoSmooth
:
334 case MUIA_Prop_Entries
:
335 case MUIA_Prop_Visible
:
336 case MUIA_Prop_DeltaFactor
:
343 bug("[Listtree] OM_SET: passing to parent class %x\n", tag
->ti_Tag
);
348 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
351 #define FORWARDGET(AATTR, BATTR) \
353 *(msg->opg_Storage) = XGET(data->nlisttree, BATTR); \
356 IPTR
Listtree__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
358 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
360 if (!data
->nlisttree
)
363 switch (msg
->opg_AttrID
)
365 FORWARDGET(MUIA_Frame
, MUIA_Frame
)
366 FORWARDGET(MUIA_Listtree_DoubleClick
, MUIA_NListtree_DoubleClick
)
367 FORWARDGET(MUIA_List_Active
, MUIA_NList_Active
)
368 FORWARDGET(MUIA_Listtree_Active
, MUIA_NListtree_Active
)
369 FORWARDGET(MUIA_Listtree_Quiet
, MUIA_NListtree_Quiet
)
370 FORWARDGET(MUIA_List_Visible
, MUIA_NList_Visible
)
371 FORWARDGET(MUIA_List_VertProp_First
, MUIA_NList_Prop_First
)
372 FORWARDGET(MUIA_List_VertProp_Entries
, MUIA_NList_Prop_Entries
)
373 FORWARDGET(MUIA_List_VertProp_Visible
, MUIA_NList_Prop_Visible
)
377 case MUIA_Group_ChildList
:
378 case MUIA_Prop_First
:
379 case MUIA_Prop_DoSmooth
:
380 case MUIA_Listview_List
:
381 case MUIA_Virtgroup_Left
:
382 case MUIA_Virtgroup_Top
:
383 case 0x9d510020 /*MUIA_NListview_NList*/:
384 case MUIA_Listview_DoubleClick
:
385 case MUIA_Listview_SelectChange
:
391 bug("[Listtree] OM_GET: passing to parent class %x\n", msg
->opg_AttrID
);
394 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
397 IPTR
Listtree__MUIM_Listtree_Insert(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_Insert
*msg
)
399 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
400 struct MUIS_Listtree_TreeNodeInt
* _int
= AllocPooled(data
->pool
, sizeof(struct MUIS_Listtree_TreeNodeInt
));
401 struct MUIS_Listtree_TreeNode
* _return
= NULL
;
402 struct MUI_NListtree_TreeNode
* ln
= NULL
, * pn
= NULL
;
407 _return
= &_int
->base
;
409 _return
->tn_Flags
= (UWORD
)msg
->Flags
;
410 if (data
->constrhook
)
411 _return
->tn_User
= (APTR
)CallHookPkt(data
->constrhook
, data
->pool
, msg
->User
);
413 _return
->tn_User
= msg
->User
;
415 switch((IPTR
)msg
->ListNode
)
417 case(MUIV_Listtree_Insert_ListNode_Root
):
418 case(MUIV_Listtree_Insert_ListNode_Active
):
422 ln
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->ListNode
)->ref
;
425 switch((IPTR
)msg
->PrevNode
)
427 case(MUIV_Listtree_Insert_PrevNode_Head
):
428 case(MUIV_Listtree_Insert_PrevNode_Tail
):
429 case(MUIV_Listtree_Insert_PrevNode_Active
):
430 case(MUIV_Listtree_Insert_PrevNode_Sorted
):
434 pn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->PrevNode
)->ref
;
437 _int
->ref
= (struct MUI_NListtree_TreeNode
*)DoMethod(data
->nlisttree
,
438 MUIM_NListtree_Insert
, msg
->Name
, _return
, ln
, pn
, msg
->Flags
);
440 _return
->tn_Name
= _int
->ref
->tn_Name
;
442 return (IPTR
)_return
;
445 IPTR
Listtree__MUIM_Listtree_GetEntry(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_GetEntry
*msg
)
447 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
448 struct MUI_NListtree_TreeNode
* tn
= NULL
, * found
= NULL
;
450 switch ((IPTR
)msg
->Node
)
452 case(MUIV_Listtree_GetEntry_ListNode_Root
):
453 case(MUIV_Listtree_GetEntry_ListNode_Active
):
457 tn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->Node
)->ref
;
460 found
= (struct MUI_NListtree_TreeNode
*) DoMethod(data
->nlisttree
,
461 MUIM_NListtree_GetEntry
, tn
, msg
->Position
, msg
->Flags
);
465 SYNC_TREENODE_FLAGS(found
);
466 return (IPTR
)found
->tn_User
;
472 IPTR
Listtree__MUIM_Listtree_Remove(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_Remove
*msg
)
474 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
475 struct MUI_NListtree_TreeNode
* tn
= NULL
, * ln
= NULL
;
477 switch((IPTR
)msg
->ListNode
)
479 case(MUIV_Listtree_Remove_ListNode_Root
):
480 case(MUIV_Listtree_Remove_ListNode_Active
):
484 ln
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->ListNode
)->ref
;
487 switch((IPTR
)msg
->TreeNode
)
489 case(MUIV_Listtree_Remove_TreeNode_Head
):
490 case(MUIV_Listtree_Remove_TreeNode_Tail
):
491 case(MUIV_Listtree_Remove_TreeNode_Active
):
492 case(MUIV_Listtree_Remove_TreeNode_All
):
496 tn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->TreeNode
)->ref
;
499 /* Deallocating of MUIS_Listtree_TreeNode is happening in the DestructHook */
500 return DoMethod(data
->nlisttree
, MUIM_NListtree_Remove
, ln
, tn
, msg
->Flags
);
504 IPTR
Listtree__MUIM_List_TestPos(struct IClass
*cl
, Object
*obj
, struct MUIP_List_TestPos
*msg
)
506 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
508 struct MUI_NList_TestPos_Result res
;
509 if (DoMethod(data
->nlisttree
, MUIM_List_TestPos
, msg
->x
, msg
->y
, &res
))
511 msg
->res
->entry
= res
.entry
;
512 msg
->res
->column
= res
.column
;
513 msg
->res
->flags
= res
.flags
;
514 msg
->res
->xoffset
= res
.xoffset
;
515 msg
->res
->yoffset
= res
.yoffset
;
522 IPTR
Listtree__MUIM_Listtree_TestPos(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_TestPos
*msg
)
524 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
526 struct MUI_NListtree_TestPos_Result res
;
527 struct MUIS_Listtree_TestPos_Result
* _ret
= (struct MUIS_Listtree_TestPos_Result
*)msg
->Result
;
529 _ret
->tpr_TreeNode
= NULL
;
531 DoMethod(data
->nlisttree
, MUIM_NListtree_TestPos
, msg
->X
, msg
->Y
, &res
);
533 _ret
->tpr_Flags
= res
.tpr_Type
;
534 _ret
->tpr_ListEntry
= res
.tpr_ListEntry
;
535 _ret
->tpr_ListFlags
= res
.tpr_ListFlags
;
537 if (res
.tpr_TreeNode
!= NULL
)
539 SYNC_TREENODE_FLAGS(res
.tpr_TreeNode
);
540 _ret
->tpr_TreeNode
= res
.tpr_TreeNode
->tn_User
;
547 IPTR
Listtree__MUIM_Listtree_GetNr(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_GetNr
*msg
)
549 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
550 struct MUI_NListtree_TreeNode
* tn
= NULL
;
552 switch((IPTR
)msg
->TreeNode
)
554 case(MUIV_Listtree_GetNr_TreeNode_Active
):
558 tn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->TreeNode
)->ref
;
561 return DoMethod(data
->nlisttree
, MUIM_NListtree_GetNr
, tn
, msg
->Flags
);
564 IPTR
Listtree__MUIM_Listtree_Rename(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_Rename
*msg
)
566 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
567 struct MUI_NListtree_TreeNode
* tn
= NULL
, * renamed
= NULL
;
569 switch((IPTR
)msg
->TreeNode
)
571 case(MUIV_Listtree_Rename_TreeNode_Active
):
575 tn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->TreeNode
)->ref
;
578 renamed
= (struct MUI_NListtree_TreeNode
*)DoMethod(data
->nlisttree
,
579 MUIM_NListtree_Rename
, tn
, msg
->NewName
, msg
->Flags
);
583 ((struct MUIS_Listtree_TreeNode
*)renamed
->tn_User
)->tn_Name
= renamed
->tn_Name
;
584 return (IPTR
)renamed
->tn_User
;
590 IPTR
Listtree__MUIM_List_Redraw(struct IClass
*cl
, Object
*obj
, struct MUIP_List_Redraw
*msg
)
592 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
593 struct MUI_NListtree_TreeNode
* entry
= msg
->entry
?
594 ((struct MUIS_Listtree_TreeNodeInt
*)msg
->entry
)->ref
: NULL
;
598 case(MUIV_List_Redraw_Entry
):
599 return DoMethod(data
->nlisttree
, MUIM_NList_RedrawEntry
, entry
);
601 return DoMethod(data
->nlisttree
, MUIM_NList_Redraw
, msg
->pos
);
605 IPTR
Listtree__MUIM_Listtree_Open(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_Open
*msg
)
607 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
608 struct MUI_NListtree_TreeNode
* tn
= NULL
, * ln
= NULL
;
610 switch((IPTR
)msg
->ListNode
)
612 case(MUIV_Listtree_Open_ListNode_Root
):
613 case(MUIV_Listtree_Open_ListNode_Parent
):
614 case(MUIV_Listtree_Open_ListNode_Active
):
618 ln
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->ListNode
)->ref
;
621 switch((IPTR
)msg
->TreeNode
)
623 case(MUIV_Listtree_Open_TreeNode_Head
):
624 case(MUIV_Listtree_Open_TreeNode_Tail
):
625 case(MUIV_Listtree_Open_TreeNode_Active
):
626 case(MUIV_Listtree_Open_TreeNode_All
):
630 tn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->TreeNode
)->ref
;
633 return DoMethod(data
->nlisttree
, MUIM_NListtree_Open
, ln
, tn
, msg
->Flags
);
636 IPTR
Listtree__MUIM_Listtree_FindName(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_FindName
*msg
)
638 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
639 struct MUI_NListtree_TreeNode
* ln
= NULL
, * found
= NULL
;
641 switch((IPTR
)msg
->ListNode
)
643 case(MUIV_Listtree_FindName_ListNode_Root
):
644 case(MUIV_Listtree_FindName_ListNode_Active
):
648 ln
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->ListNode
)->ref
;
651 found
= (struct MUI_NListtree_TreeNode
*) DoMethod(data
->nlisttree
, MUIM_NListtree_FindName
,
652 ln
, msg
->Name
, msg
->Flags
);
655 return (IPTR
)found
->tn_User
;
660 IPTR
DoSetupMethod(Object
* obj
, struct MUI_RenderInfo
* info
)
662 /* MUI set the correct render info *before* it calls MUIM_Setup so please
663 * only use this function instead of DoMethodA() */
664 muiRenderInfo(obj
) = info
;
665 return DoMethod(obj
, MUIM_Setup
, (IPTR
) info
);
668 IPTR
Listtree__MUIM_List_CreateImage(struct IClass
*cl
, Object
*obj
, struct MUIP_List_CreateImage
*msg
)
670 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
672 if (!(_flags(obj
) & MADF_SETUP
))
675 IPTR _ret
= DoMethod(data
->nlisttree
, MUIM_NList_CreateImage
, msg
->obj
, msg
->flags
);
677 /* There is a use case where an image object created in a Listtree can be passed as O[address]
678 * in the text in the display callback of List. Since Listtree just wraps around NListtree and the
679 * return structures from List_CreateImage and NList_CreateImage are different, this would normally
680 * not work. Luckily, List needs only the msg->obj and it is at the same offset in ListImage and
681 * in structure returned by NList. The case will work as long as this is met.
683 struct ListImage
* li
= (struct ListImage
*)_ret
;
684 if (li
->obj
!= msg
->obj
)
685 bug("[Listtree] CreateImage condition BROKEN, see comment in code!\n");
687 /* Setup the msg->obj as the List is doing */
688 DoMethod(li
->obj
, MUIM_ConnectParent
, (IPTR
) obj
);
689 DoSetupMethod(li
->obj
, muiRenderInfo(obj
));
694 IPTR
Listtree__MUIM_List_DeleteImage(struct IClass
*cl
, Object
*obj
, struct MUIP_List_DeleteImage
*msg
)
696 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
697 struct ListImage
* li
= (struct ListImage
*)msg
->listimg
;
702 /* DoMethod(li->obj, MUIM_Cleanup); // Called in MUIM_NList_DeleteImage */
703 DoMethod(li
->obj
, MUIM_DisconnectParent
);
704 return DoMethod(data
->nlisttree
, MUIM_NList_DeleteImage
, msg
->listimg
);
707 IPTR
Listtree__MUIM_Listtree_Close(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_Close
*msg
)
709 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
710 struct MUI_NListtree_TreeNode
* tn
= NULL
, * ln
= NULL
;
712 switch((IPTR
)msg
->ListNode
)
714 case(MUIV_Listtree_Close_ListNode_Root
):
715 case(MUIV_Listtree_Close_ListNode_Parent
):
716 case(MUIV_Listtree_Close_ListNode_Active
):
720 ln
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->ListNode
)->ref
;
723 switch((IPTR
)msg
->TreeNode
)
725 case(MUIV_Listtree_Close_TreeNode_Head
):
726 case(MUIV_Listtree_Close_TreeNode_Tail
):
727 case(MUIV_Listtree_Close_TreeNode_Active
):
728 case(MUIV_Listtree_Close_TreeNode_All
):
732 tn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->TreeNode
)->ref
;
735 return DoMethod(data
->nlisttree
, MUIM_NListtree_Close
, ln
, tn
, msg
->Flags
);
738 #define FORWARDNLISTTREEMETHOD(methodname) \
739 IPTR Listtree__##methodname(struct IClass *cl, Object *obj, Msg msg) \
741 struct Listtree_DATA *data = INST_DATA(cl, obj); \
742 return DoMethodA(data->nlisttree, msg); \
745 FORWARDNLISTTREEMETHOD(MUIM_CreateDragImage
)
746 FORWARDNLISTTREEMETHOD(MUIM_DeleteDragImage
)
748 IPTR
Listtree__MUIM_Notify(struct IClass
*cl
, Object
*obj
, struct MUIP_Notify
*msg
)
750 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
752 /* NList expects this notification to be set and uses its content */
753 if (msg
->TrigAttr
== MUIA_List_Prop_First
)
754 DoMethodA(data
->nlisttree
, msg
);
756 if (msg
->TrigAttr
== MUIA_List_First
)
757 bug("Listtree.mcc: notifications on MUIA_List_First are not fired!\n");
759 return DoSuperMethodA(cl
, obj
, msg
);
762 #define METHODSTUB(methodname) \
763 IPTR Listtree__##methodname(struct IClass *cl, Object *obj, Msg msg) \
765 bug("[Listtree] Usupported : %s\n", #methodname); \
766 return (IPTR)FALSE; \
769 METHODSTUB(MUIM_Listtree_SetDropMark
)