Listtree.mcc: code cleanup
[AROS.git] / workbench / classes / zune / listtree / listtree.c
bloba3fdbe2423b5bc9f51d75b892f2110b5b8e0d852
1 /*
2 Copyright © 2012-2015, The AROS Development Team. All rights reserved.
3 $Id$
4 */
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>
13 #undef TNF_OPEN
14 #undef TNF_LIST
15 #include "Listtree_mcc.h"
16 #include "listtree_private.h"
17 #include "support.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 */
31 struct ListImage
33 struct MinNode node;
34 Object *obj;
37 #define MADF_SETUP (1<< 28) /* PRIV - zune-specific */
39 /* Relations:
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)
55 struct opSet setmsg;
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;
66 switch(attr)
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;
71 break;
72 case(MUIA_NListtree_DoubleClick):
73 setti[0].ti_Tag = MUIA_Listtree_DoubleClick;
74 setti[0].ti_Data = val;
75 break;
76 case(MUIA_NListtree_Quiet):
77 setti[0].ti_Tag = MUIA_Listtree_Quiet;
78 setti[0].ti_Data = val;
79 break;
80 default:
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;
91 APTR tn = NULL;
93 if (!displayhook)
94 return 0;
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;
108 if (!sorthook)
109 return 0;
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;
124 if (!data)
125 return 0;
127 if (data->destrhook && tn)
128 CallHookPkt(data->destrhook, data->pool, tn->tn_User);
130 FreePooled(data->pool, tn, sizeof(struct MUIS_Listtree_TreeNodeInt));
132 return 0;
135 #define CONV(AATTR, BATTR) \
136 case(AATTR): \
137 convtags[i].ti_Tag = BATTR; \
138 convtags[i++].ti_Data = tag->ti_Data; \
139 break;
141 #define COPY(AATTR) \
142 case(AATTR): \
143 supertags[i].ti_Tag = AATTR; \
144 supertags[i++].ti_Data = tag->ti_Data; \
145 break;
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;
155 struct TagItem *tag;
156 struct TagItem *tags;
157 Object *nlisttree = NULL;
158 struct TagItem convtags[20];
159 struct TagItem supertags[20];
160 LONG i;
162 /* Convert tags designated for NListtree */
163 for (i = 0, tags = msg->ops_AttrList; (tag = NextTagItem(&tags)); )
165 switch (tag->ti_Tag)
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)); )
181 switch (tag->ti_Tag)
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,
193 TAG_DONE);
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)); )
208 switch (tag->ti_Tag)
210 case(MUIA_Listtree_ConstructHook):
211 data->constrhook = (struct Hook *)tag->ti_Data;
212 break;
213 case(MUIA_Listtree_DestructHook):
214 data->destrhook = (struct Hook *)tag->ti_Data;
215 break;
216 case(MUIA_Listtree_DisplayHook):
217 data->displayhook = (struct Hook *)tag->ti_Data;
218 break;
219 case(MUIA_Listtree_SortHook):
220 data->sorthook = (struct Hook *)tag->ti_Data;
221 break;
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):
230 case(MUIA_Frame):
231 break;
233 /* Forwarded to super class */
234 case(MUIA_ContextMenu):
235 break;
237 default:
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);
261 if (data->sorthook)
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)
282 return obj;
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) \
295 case(AATTR): \
296 set(data->nlisttree, BATTR, tag->ti_Data); \
297 break;
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;
303 struct TagItem *tag;
305 if (!data->nlisttree)
306 return DoSuperMethodA(cl, obj, (Msg) msg);
308 while ((tag = NextTagItem(&tstate)) != NULL)
310 switch (tag->ti_Tag)
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);
320 break;
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 */
326 break;
329 case MUIA_Listtree_DoubleClick:
330 case MUIA_Listview_SelectChange:
331 case MUIA_Prop_First:
332 case MUIA_Prop_DoSmooth:
333 case MUIA_NoNotify:
334 case MUIA_Prop_Entries:
335 case MUIA_Prop_Visible:
336 case MUIA_Prop_DeltaFactor:
337 case MUIA_Timer:
338 case MUIA_Selected:
339 case MUIA_Pressed:
340 break;
342 default:
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) \
352 case(AATTR): \
353 *(msg->opg_Storage) = XGET(data->nlisttree, BATTR); \
354 return TRUE;
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)
361 return FALSE;
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)
375 case MUIA_Disabled:
376 case MUIA_Parent:
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:
386 case MUIA_Timer:
387 case MUIA_Selected:
388 break;
390 default:
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;
404 if (_int == NULL)
405 return (IPTR)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);
412 else
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):
419 ln = msg->ListNode;
420 break;
421 default:
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):
431 pn = msg->PrevNode;
432 break;
433 default:
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):
454 tn = msg->Node;
455 break;
456 default:
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);
463 if (found)
465 SYNC_TREENODE_FLAGS(found);
466 return (IPTR)found->tn_User;
468 else
469 return (IPTR)NULL;
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):
481 ln = msg->ListNode;
482 break;
483 default:
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):
493 tn = msg->TreeNode;
494 break;
495 default:
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;
516 return TRUE;
519 return FALSE;
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;
541 return TRUE;
544 return FALSE;
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):
555 tn = msg->TreeNode;
556 break;
557 default:
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):
572 tn = msg->TreeNode;
573 break;
574 default:
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);
581 if (renamed)
583 ((struct MUIS_Listtree_TreeNode *)renamed->tn_User)->tn_Name = renamed->tn_Name;
584 return (IPTR)renamed->tn_User;
586 else
587 return (IPTR)NULL;
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;
596 switch(msg->pos)
598 case(MUIV_List_Redraw_Entry):
599 return DoMethod(data->nlisttree, MUIM_NList_RedrawEntry, entry);
600 default:
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):
615 ln = msg->ListNode;
616 break;
617 default:
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):
627 tn = msg->TreeNode;
628 break;
629 default:
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):
645 ln = msg->ListNode;
646 break;
647 default:
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);
654 if (found)
655 return (IPTR)found->tn_User;
656 else
657 return (IPTR)NULL;
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))
673 return 0;
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));
691 return _ret;
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;
699 if (!li)
700 return 0;
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):
717 ln = msg->ListNode;
718 break;
719 default:
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):
729 tn = msg->TreeNode;
730 break;
731 default:
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)