Listtree.mcc: handle MUIA_List_VertProp_#? and MUIM_Notify takeover by NList
[AROS.git] / workbench / classes / zune / listtree / listtree.c
blob47d3b565c2dfc568510581ae31afc6c3c55644f8
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 /* Relations:
22 * MUIS_Listtree_Treenode -> MUI_NListtree_Treenode via MUIS_Listtree_TreeNodeInt.ref
23 * MUI_NListtree_Treenode -> MUIS_Listtree_Treenode via MUI_NListtree_Treenode.tn_User
25 struct MUIS_Listtree_TreeNodeInt
27 struct MUIS_Listtree_TreeNode base;
28 struct MUI_NListtree_TreeNode *ref;
31 #define SYNC_TREENODE_FLAGS(tn) \
32 if (tn && tn->tn_User) \
33 ((struct MUIS_Listtree_TreeNode *)tn->tn_User)->tn_Flags = tn->tn_Flags;
35 static IPTR NotifySimulate_Function(struct Hook *hook, Object *obj, void ** msg)
37 struct opSet setmsg;
38 struct TagItem setti[] = {{0,0},{TAG_DONE, TAG_DONE}};
40 IPTR attr = (IPTR)msg[0];
41 IPTR val = (IPTR)msg[1];
42 struct IClass * cl = hook->h_Data;
44 setmsg.MethodID = OM_SET;
45 setmsg.ops_AttrList = setti;
46 setmsg.ops_GInfo = NULL;
48 switch(attr)
50 case(MUIA_NListtree_Active):
51 setti[0].ti_Tag = MUIA_Listtree_Active;
52 setti[0].ti_Data = val ? (IPTR)((struct MUI_NListtree_TreeNode *)val)->tn_User : 0;
53 break;
54 case(MUIA_NListtree_DoubleClick):
55 setti[0].ti_Tag = MUIA_Listtree_DoubleClick;
56 setti[0].ti_Data = val;
57 break;
58 case(MUIA_NListtree_Quiet):
59 setti[0].ti_Tag = MUIA_Listtree_Quiet;
60 setti[0].ti_Data = val;
61 break;
62 default:
63 bug("[Listtree] NotifySimulate_Function - unhandled attribute %x\n", attr);
66 /* Super method OM_SET call will go to Notify class and trigger notifications */
67 return DoSuperMethodA(cl, obj, (Msg) &setmsg);
70 static IPTR DisplayHook_Proxy(struct Hook *hook, Object *obj, struct MUIP_NListtree_DisplayMessage *msg)
72 struct Hook * displayhook = (struct Hook *)hook->h_Data;
73 APTR tn = NULL;
75 if (!displayhook)
76 return 0;
78 SYNC_TREENODE_FLAGS(msg->TreeNode);
80 tn = msg->TreeNode ? msg->TreeNode->tn_User : NULL;
82 return CallHookPkt(displayhook, msg->Array, tn);
85 static IPTR SortHook_Proxy(struct Hook *hook, Object *obj, struct MUIP_NListtree_CompareMessage *msg)
87 struct Hook * sorthook = (struct Hook *)hook->h_Data;
88 APTR tn1 = NULL, tn2 = NULL;
90 if (!sorthook)
91 return 0;
93 SYNC_TREENODE_FLAGS(msg->TreeNode1);
94 SYNC_TREENODE_FLAGS(msg->TreeNode2);
96 tn1 = msg->TreeNode1 ? msg->TreeNode1->tn_User : NULL;
97 tn2 = msg->TreeNode2 ? msg->TreeNode2->tn_User : NULL;
99 return CallHookPkt(sorthook, tn1, tn2);
102 static IPTR DestructHook_Proxy(struct Hook *hook, Object *obj, struct MUIP_NListtree_DestructMessage *msg)
104 struct Listtree_DATA * data = (struct Listtree_DATA *)hook->h_Data;
105 struct MUIS_Listtree_TreeNode * tn = (struct MUIS_Listtree_TreeNode *)msg->UserData;
106 if (!data)
107 return 0;
109 if (data->destrhook && tn)
110 CallHookPkt(data->destrhook, data->pool, tn->tn_User);
112 FreePooled(data->pool, tn, sizeof(struct MUIS_Listtree_TreeNodeInt));
114 return 0;
117 #define NEWHANDLE(attrname) \
118 case(attrname): \
119 bug("[Listtree] OM_NEW:%s - unsupported\n", #attrname); \
120 break;
122 #define CONV(AATTR, BATTR) \
123 case(AATTR): \
124 convtags[i].ti_Tag = BATTR; \
125 convtags[i++].ti_Data = tag->ti_Data; \
126 break;
128 #define COPY(AATTR) \
129 case(AATTR): \
130 supertags[i].ti_Tag = AATTR; \
131 supertags[i++].ti_Data = tag->ti_Data; \
132 break;
134 #define NOTIFY_FORWARD(AATTR) \
135 DoMethod(data->nlisttree, MUIM_Notify, AATTR, MUIV_EveryTime, \
136 obj, 4, MUIM_CallHook, &data->notifysimulatehook, AATTR, MUIV_TriggerValue);
139 /*** Methods ****************************************************************/
140 Object *Listtree__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
142 struct Listtree_DATA *data = NULL;
143 struct TagItem *tag;
144 struct TagItem *tags;
145 Object *nlisttree = NULL;
146 struct TagItem convtags[20];
147 struct TagItem supertags[20];
148 LONG i;
150 /* Convert tags designated for NListtree */
151 for (i = 0, tags = msg->ops_AttrList; (tag = NextTagItem(&tags)); )
153 switch (tag->ti_Tag)
155 CONV(MUIA_Frame, MUIA_Frame)
156 CONV(MUIA_Listtree_Format, MUIA_NListtree_Format)
157 CONV(MUIA_Listtree_Title, MUIA_NListtree_Title)
158 CONV(MUIA_Listtree_DragDropSort, MUIA_NListtree_DragDropSort)
159 CONV(MUIA_List_Title, MUIA_NList_Title)
160 CONV(MUIA_List_DragSortable, MUIA_NList_DragSortable)
161 CONV(MUIA_List_MinLineHeight, MUIA_NList_MinLineHeight)
164 convtags[i].ti_Tag = TAG_DONE;
166 /* Copy tags designated for super class */
167 for (i = 0, tags = msg->ops_AttrList; (tag = NextTagItem(&tags)); )
169 switch (tag->ti_Tag)
171 COPY(MUIA_ContextMenu) /* ContextMenuBuild/Choice will be called on child classes of Listtree */
174 supertags[i].ti_Tag = TAG_DONE;
176 /* TODO:
177 * set up a DestructHook which will call proxy MUIS_Listtree_TreeNode destrhook and
178 * free it afterwards
180 obj = (Object *) DoSuperNewTags(cl, obj, 0,
181 Child, nlisttree = (Object *) NewObjectA(CL_NListtreeInt->mcc_Class, NULL, convtags),
182 TAG_MORE, (IPTR)supertags,
183 TAG_DONE);
185 if (!obj) return FALSE;
187 data = INST_DATA(cl, obj);
188 data->nlisttree = nlisttree;
189 data->notifysimulatehook.h_Entry = HookEntry;
190 data->notifysimulatehook.h_SubEntry = (HOOKFUNC)NotifySimulate_Function;
191 data->notifysimulatehook.h_Data = cl;
193 data->pool = CreatePool(MEMF_ANY | MEMF_CLEAR, 16 * 1024, 8 * 1024);
195 /* parse initial taglist */
196 for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags)); )
198 switch (tag->ti_Tag)
200 case(MUIA_Listtree_ConstructHook):
201 data->constrhook = (struct Hook *)tag->ti_Data;
202 break;
203 case(MUIA_Listtree_DestructHook):
204 data->destrhook = (struct Hook *)tag->ti_Data;
205 break;
206 case(MUIA_Listtree_DisplayHook):
207 data->displayhook = (struct Hook *)tag->ti_Data;
208 break;
209 case(MUIA_Listtree_SortHook):
210 data->sorthook = (struct Hook *)tag->ti_Data;
211 break;
212 case(MUIA_List_MinLineHeight):
213 case(MUIA_List_DragSortable):
214 case(MUIA_List_Title):
215 case(MUIA_Listtree_DragDropSort):
216 case(MUIA_Listtree_Format):
217 case(MUIA_Listtree_Title):
218 case(MUIA_Frame):
219 /* Forwarded to NListtree */
220 break;
221 case(MUIA_ContextMenu):
222 /* Forwarded to super class */
223 break;
224 default:
225 bug("[Listtree] OM_NEW: unhandled %x\n", tag->ti_Tag);
229 /* Setup connection */
230 set(data->nlisttree, MUIA_NListtreeInt_Listtree, obj);
232 /* Setup root node */
235 * Leave the tn_User of root node as NULL. It is expected that
236 * parent of first level item is returned as NULL in Listtree
240 /* Setup hook proxies */
241 if (data->displayhook)
243 data->displayhookproxy.h_Entry = HookEntry;
244 data->displayhookproxy.h_SubEntry = (HOOKFUNC)DisplayHook_Proxy;
245 data->displayhookproxy.h_Data = data->displayhook;
246 nnset(data->nlisttree, MUIA_NListtree_DisplayHook, &data->displayhookproxy);
248 if (data->sorthook)
250 data->sorthookproxy.h_Entry = HookEntry;
251 data->sorthookproxy.h_SubEntry = (HOOKFUNC)SortHook_Proxy;
252 data->sorthookproxy.h_Data = data->sorthook;
253 nnset(data->nlisttree, MUIA_NListtree_CompareHook, &data->sorthookproxy);
256 /* Destroy hook is mandatory to free proxy structures */
258 data->destructhookproxy.h_Entry = HookEntry;
259 data->destructhookproxy.h_SubEntry = (HOOKFUNC)DestructHook_Proxy;
260 data->destructhookproxy.h_Data = data;
261 nnset(data->nlisttree, MUIA_NListtree_DestructHook, &data->destructhookproxy);
264 /* Setup notification forwarding */
265 NOTIFY_FORWARD(MUIA_NListtree_Active)
266 NOTIFY_FORWARD(MUIA_NListtree_DoubleClick)
267 NOTIFY_FORWARD(MUIA_NListtree_Quiet)
269 return obj;
272 IPTR Listtree__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
274 struct Listtree_DATA *data = INST_DATA(cl, obj);
276 DeletePool(data->pool);
278 return DoSuperMethodA(cl, obj, msg);
281 #define MUIA_List_Prop_Entries /* PRIV */ \
282 (MUIB_MUI | 0x0042a8f5) /* .sg LONG PRIV */
283 #define MUIA_List_Prop_Visible /* PRIV */ \
284 (MUIB_MUI | 0x004273e9) /* .sg LONG PRIV */
285 #define MUIA_List_Prop_First /* PRIV */ \
286 (MUIB_MUI | 0x00429df3) /* .sg LONG PRIV */
288 #define MUIA_List_VertProp_Entries /* PRIV */ \
289 MUIA_List_Prop_Entries /* PRIV */
290 #define MUIA_List_VertProp_Visible /* PRIV */ \
291 MUIA_List_Prop_Visible /* PRIV */
292 #define MUIA_List_VertProp_First /* PRIV */ \
293 MUIA_List_Prop_First /* PRIV */
295 #define SETHANDLE(attrname) \
296 case(attrname): \
297 bug("[Listtree] OM_SET:%s - unsupported\n", #attrname); \
298 break;
300 #define FORWARDSET(AATTR, BATTR) \
301 case(AATTR): \
302 set(data->nlisttree, BATTR, tag->ti_Data); \
303 break;
305 #define IGNORESET(AATTR) case(AATTR): break;
307 IPTR Listtree__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg)
309 struct Listtree_DATA *data = INST_DATA(cl, obj);
310 struct TagItem *tstate = msg->ops_AttrList;
311 struct TagItem *tag;
313 if (!data->nlisttree)
314 return DoSuperMethodA(cl, obj, (Msg) msg);
316 while ((tag = NextTagItem(&tstate)) != NULL)
318 switch (tag->ti_Tag)
320 FORWARDSET(MUIA_Listtree_Quiet, MUIA_NListtree_Quiet)
321 FORWARDSET(MUIA_List_Active, MUIA_NList_Active)
322 FORWARDSET(MUIA_List_Prop_First, MUIA_NList_Prop_First)
324 IGNORESET(MUIA_Listview_SelectChange)
326 case(MUIA_Listtree_Active):
327 set(data->nlisttree, MUIA_NListtree_Active,
328 ((struct MUIS_Listtree_TreeNodeInt *)tag->ti_Data)->ref);
329 break;
331 SETHANDLE(MUIA_Listtree_DoubleClick)
332 case MUIB_List | 0x00000010: break;
333 case MUIA_Prop_First: break;
334 case MUIA_Prop_DoSmooth: break;
335 case MUIA_NoNotify: break;
336 case MUIA_Prop_Entries: break;
337 case MUIA_Prop_Visible: break;
338 case MUIA_Prop_DeltaFactor: break;
339 default:
340 bug("[Listtree] OM_SET: passing to parent class %x\n", tag->ti_Tag);
345 return DoSuperMethodA(cl, obj, (Msg) msg);
348 #define GETHANDLE(attrname) \
349 case(attrname): \
350 bug("[Listtree] OM_GET:%s - unsupported\n", #attrname); \
351 break;
353 #define FORWARDGET(AATTR, BATTR) \
354 case(AATTR): \
355 *(msg->opg_Storage) = XGET(data->nlisttree, BATTR); \
356 return TRUE;
358 IPTR Listtree__OM_GET(struct IClass *cl, Object *obj, struct opGet *msg)
360 struct Listtree_DATA *data = INST_DATA(cl, obj);
362 if (!data->nlisttree)
363 return FALSE;
365 switch (msg->opg_AttrID)
367 FORWARDGET(MUIA_Frame, MUIA_Frame)
368 FORWARDGET(MUIA_Listtree_DoubleClick, MUIA_NListtree_DoubleClick)
369 FORWARDGET(MUIA_List_Active, MUIA_NList_Active)
370 FORWARDGET(MUIA_Listtree_Active, MUIA_NListtree_Active)
371 FORWARDGET(MUIA_Listtree_Quiet, MUIA_NListtree_Quiet)
372 FORWARDGET(MUIA_List_Visible, MUIA_NList_Visible)
373 FORWARDGET(MUIA_List_VertProp_First, MUIA_NList_Prop_First)
374 FORWARDGET(MUIA_List_VertProp_Entries, MUIA_NList_Prop_Entries)
375 FORWARDGET(MUIA_List_VertProp_Visible, MUIA_NList_Prop_Visible)
377 case MUIA_Disabled: break;
378 case MUIA_Parent: break;
379 case MUIA_Group_ChildList: break;
380 case MUIA_Prop_First: break;
381 case MUIA_Prop_DoSmooth: break;
382 case MUIA_Listview_List: break;
383 case MUIA_Virtgroup_Left: break;
384 case MUIA_Virtgroup_Top: break;
385 case 0x9d510020 /*MUIA_NListview_NList*/: break;
386 default:
387 bug("[Listtree] OM_GET: passing to parent class %x\n", msg->opg_AttrID);
390 return DoSuperMethodA(cl, obj, (Msg) msg);
393 #define METHODSTUB(methodname) \
394 IPTR Listtree__##methodname(struct IClass *cl, Object *obj, Msg msg) \
396 bug("[Listtree] Usupported : %s\n", #methodname); \
397 return (IPTR)FALSE; \
400 METHODSTUB(MUIM_Listtree_SetDropMark)
402 IPTR Listtree__MUIM_Listtree_Insert(struct IClass *cl, Object *obj, struct MUIP_Listtree_Insert *msg)
404 struct Listtree_DATA *data = INST_DATA(cl, obj);
405 struct MUIS_Listtree_TreeNodeInt * _int = AllocPooled(data->pool, sizeof(struct MUIS_Listtree_TreeNodeInt));
406 struct MUIS_Listtree_TreeNode * _return = NULL;
407 struct MUI_NListtree_TreeNode * ln = NULL, * pn = NULL;
409 if (_int == NULL)
410 return (IPTR)NULL;
412 _return = &_int->base;
414 _return->tn_Flags = (UWORD)msg->Flags;
415 if (data->constrhook)
416 _return->tn_User = (APTR)CallHookPkt(data->constrhook, data->pool, msg->User);
417 else
418 _return->tn_User = msg->User;
420 switch((IPTR)msg->ListNode)
422 case(MUIV_Listtree_Insert_ListNode_Root):
423 case(MUIV_Listtree_Insert_ListNode_Active):
424 ln = msg->ListNode;
425 break;
426 default:
427 ln = ((struct MUIS_Listtree_TreeNodeInt *)msg->ListNode)->ref;
430 switch((IPTR)msg->PrevNode)
432 case(MUIV_Listtree_Insert_PrevNode_Head):
433 case(MUIV_Listtree_Insert_PrevNode_Tail):
434 case(MUIV_Listtree_Insert_PrevNode_Active):
435 case(MUIV_Listtree_Insert_PrevNode_Sorted):
436 pn = msg->PrevNode;
437 break;
438 default:
439 pn = ((struct MUIS_Listtree_TreeNodeInt *)msg->PrevNode)->ref;
442 _int->ref = (struct MUI_NListtree_TreeNode *)DoMethod(data->nlisttree,
443 MUIM_NListtree_Insert, msg->Name, _return, ln, pn, msg->Flags);
445 _return->tn_Name = _int->ref->tn_Name;
447 return (IPTR)_return;
450 IPTR Listtree__MUIM_Listtree_GetEntry(struct IClass *cl, Object *obj, struct MUIP_Listtree_GetEntry *msg)
452 struct Listtree_DATA *data = INST_DATA(cl, obj);
453 struct MUI_NListtree_TreeNode * tn = NULL, * found = NULL;
455 switch ((IPTR)msg->Node)
457 case(MUIV_Listtree_GetEntry_ListNode_Root):
458 case(MUIV_Listtree_GetEntry_ListNode_Active):
459 tn = msg->Node;
460 break;
461 default:
462 tn = ((struct MUIS_Listtree_TreeNodeInt *)msg->Node)->ref;
465 found = (struct MUI_NListtree_TreeNode *) DoMethod(data->nlisttree,
466 MUIM_NListtree_GetEntry, tn, msg->Position, msg->Flags);
468 if (found)
470 SYNC_TREENODE_FLAGS(found);
471 return (IPTR)found->tn_User;
473 else
474 return (IPTR)NULL;
477 IPTR Listtree__MUIM_Listtree_Remove(struct IClass *cl, Object *obj, struct MUIP_Listtree_Remove *msg)
479 struct Listtree_DATA *data = INST_DATA(cl, obj);
480 struct MUI_NListtree_TreeNode * tn = NULL, * ln = NULL;
482 switch((IPTR)msg->ListNode)
484 case(MUIV_Listtree_Remove_ListNode_Root):
485 case(MUIV_Listtree_Remove_ListNode_Active):
486 ln = msg->ListNode;
487 break;
488 default:
489 ln = ((struct MUIS_Listtree_TreeNodeInt *)msg->ListNode)->ref;
492 switch((IPTR)msg->TreeNode)
494 case(MUIV_Listtree_Remove_TreeNode_Head):
495 case(MUIV_Listtree_Remove_TreeNode_Tail):
496 case(MUIV_Listtree_Remove_TreeNode_Active):
497 case(MUIV_Listtree_Remove_TreeNode_All):
498 tn = msg->TreeNode;
499 break;
500 default:
501 tn = ((struct MUIS_Listtree_TreeNodeInt *)msg->TreeNode)->ref;
504 /* Deallocating of MUIS_Listtree_TreeNode is happening in the DestructHook */
505 return DoMethod(data->nlisttree, MUIM_NListtree_Remove, ln, tn, msg->Flags);
509 IPTR Listtree__MUIM_List_TestPos(struct IClass *cl, Object *obj, struct MUIP_List_TestPos *msg)
511 struct Listtree_DATA *data = INST_DATA(cl, obj);
513 struct MUI_NList_TestPos_Result res;
514 if (DoMethod(data->nlisttree, MUIM_List_TestPos, msg->x, msg->y, &res))
516 msg->res->entry = res.entry;
517 msg->res->column = res.column;
518 msg->res->flags = res.flags;
519 msg->res->xoffset = res.xoffset;
520 msg->res->yoffset = res.yoffset;
521 return TRUE;
524 return FALSE;
527 IPTR Listtree__MUIM_Listtree_TestPos(struct IClass *cl, Object *obj, struct MUIP_Listtree_TestPos *msg)
529 struct Listtree_DATA *data = INST_DATA(cl, obj);
531 struct MUI_NListtree_TestPos_Result res;
532 struct MUIS_Listtree_TestPos_Result * _ret = (struct MUIS_Listtree_TestPos_Result *)msg->Result;
534 _ret->tpr_TreeNode = NULL;
536 DoMethod(data->nlisttree, MUIM_NListtree_TestPos, msg->X, msg->Y, &res);
538 _ret->tpr_Flags = res.tpr_Type;
539 _ret->tpr_ListEntry = res.tpr_ListEntry;
540 _ret->tpr_ListFlags = res.tpr_ListFlags;
542 if (res.tpr_TreeNode != NULL)
544 SYNC_TREENODE_FLAGS(res.tpr_TreeNode);
545 _ret->tpr_TreeNode = res.tpr_TreeNode->tn_User;
546 return TRUE;
549 return FALSE;
552 IPTR Listtree__MUIM_Listtree_GetNr(struct IClass *cl, Object *obj, struct MUIP_Listtree_GetNr *msg)
554 struct Listtree_DATA *data = INST_DATA(cl, obj);
555 struct MUI_NListtree_TreeNode * tn = NULL;
557 switch((IPTR)msg->TreeNode)
559 case(MUIV_Listtree_GetNr_TreeNode_Active):
560 tn = msg->TreeNode;
561 break;
562 default:
563 tn = ((struct MUIS_Listtree_TreeNodeInt *)msg->TreeNode)->ref;
566 return DoMethod(data->nlisttree, MUIM_NListtree_GetNr, tn, msg->Flags);
569 IPTR Listtree__MUIM_Listtree_Rename(struct IClass *cl, Object *obj, struct MUIP_Listtree_Rename *msg)
571 struct Listtree_DATA *data = INST_DATA(cl, obj);
572 struct MUI_NListtree_TreeNode * tn = NULL, * renamed = NULL;
574 switch((IPTR)msg->TreeNode)
576 case(MUIV_Listtree_Rename_TreeNode_Active):
577 tn = msg->TreeNode;
578 break;
579 default:
580 tn = ((struct MUIS_Listtree_TreeNodeInt *)msg->TreeNode)->ref;
583 renamed = (struct MUI_NListtree_TreeNode *)DoMethod(data->nlisttree,
584 MUIM_NListtree_Rename, tn, msg->NewName, msg->Flags);
586 if (renamed)
588 ((struct MUIS_Listtree_TreeNode *)renamed->tn_User)->tn_Name = renamed->tn_Name;
589 return (IPTR)renamed->tn_User;
591 else
592 return (IPTR)NULL;
595 IPTR Listtree__MUIM_List_Redraw(struct IClass *cl, Object *obj, struct MUIP_List_Redraw *msg)
597 struct Listtree_DATA *data = INST_DATA(cl, obj);
598 struct MUI_NListtree_TreeNode * entry = msg->entry ?
599 ((struct MUIS_Listtree_TreeNodeInt *)msg->entry)->ref : NULL;
601 switch(msg->pos)
603 case(MUIV_List_Redraw_Entry):
604 return DoMethod(data->nlisttree, MUIM_NList_RedrawEntry, entry);
605 default:
606 return DoMethod(data->nlisttree, MUIM_NList_Redraw, msg->pos);
610 IPTR Listtree__MUIM_Listtree_Open(struct IClass *cl, Object *obj, struct MUIP_Listtree_Open *msg)
612 struct Listtree_DATA *data = INST_DATA(cl, obj);
613 struct MUI_NListtree_TreeNode * tn = NULL, * ln = NULL;
615 switch((IPTR)msg->ListNode)
617 case(MUIV_Listtree_Open_ListNode_Root):
618 case(MUIV_Listtree_Open_ListNode_Parent):
619 case(MUIV_Listtree_Open_ListNode_Active):
620 ln = msg->ListNode;
621 break;
622 default:
623 ln = ((struct MUIS_Listtree_TreeNodeInt *)msg->ListNode)->ref;
626 switch((IPTR)msg->TreeNode)
628 case(MUIV_Listtree_Open_TreeNode_Head):
629 case(MUIV_Listtree_Open_TreeNode_Tail):
630 case(MUIV_Listtree_Open_TreeNode_Active):
631 case(MUIV_Listtree_Open_TreeNode_All):
632 tn = msg->TreeNode;
633 break;
634 default:
635 tn = ((struct MUIS_Listtree_TreeNodeInt *)msg->TreeNode)->ref;
638 return DoMethod(data->nlisttree, MUIM_NListtree_Open, ln, tn, msg->Flags);
641 IPTR Listtree__MUIM_Listtree_FindName(struct IClass *cl, Object *obj, struct MUIP_Listtree_FindName *msg)
643 struct Listtree_DATA *data = INST_DATA(cl, obj);
644 struct MUI_NListtree_TreeNode * ln = NULL, * found = NULL;
646 switch((IPTR)msg->ListNode)
648 case(MUIV_Listtree_FindName_ListNode_Root):
649 case(MUIV_Listtree_FindName_ListNode_Active):
650 ln = msg->ListNode;
651 break;
652 default:
653 ln = ((struct MUIS_Listtree_TreeNodeInt *)msg->ListNode)->ref;
656 found = (struct MUI_NListtree_TreeNode *) DoMethod(data->nlisttree, MUIM_NListtree_FindName,
657 ln, msg->Name, msg->Flags);
659 if (found)
660 return (IPTR)found->tn_User;
661 else
662 return (IPTR)NULL;
665 struct ListImage
667 struct MinNode node;
668 Object *obj;
671 #define MADF_SETUP (1<< 28) /* PRIV - zune-specific */
673 IPTR DoSetupMethod(Object * obj, struct MUI_RenderInfo * info)
675 /* MUI set the correct render info *before* it calls MUIM_Setup so please
676 * only use this function instead of DoMethodA() */
677 muiRenderInfo(obj) = info;
678 return DoMethod(obj, MUIM_Setup, (IPTR) info);
681 IPTR Listtree__MUIM_List_CreateImage(struct IClass *cl, Object *obj, struct MUIP_List_CreateImage *msg)
683 struct Listtree_DATA *data = INST_DATA(cl, obj);
685 if (!(_flags(obj) & MADF_SETUP))
686 return 0;
688 IPTR _ret = DoMethod(data->nlisttree, MUIM_NList_CreateImage, msg->obj, msg->flags);
690 /* There is a use case where an image object created in a Listtree can be passed as O[address]
691 * in the text in the display callback of List. Since Listtree just wraps around NListtree and the
692 * return structures from List_CreateImage and NList_CreateImage are different, this would normally
693 * not work. Luckily, List needs only the msg->obj and it is at the same offset in ListImage and
694 * in structure returned by NList. The case will work as long as this is met.
696 struct ListImage * li = (struct ListImage *)_ret;
697 if (li->obj != msg->obj)
698 bug("[Listtree] CreateImage condition BROKEN, see comment in code!\n");
700 /* Setup the msg->obj as the List is doing */
701 DoMethod(li->obj, MUIM_ConnectParent, (IPTR) obj);
702 DoSetupMethod(li->obj, muiRenderInfo(obj));
704 return _ret;
707 IPTR Listtree__MUIM_List_DeleteImage(struct IClass *cl, Object *obj, struct MUIP_List_DeleteImage *msg)
709 struct Listtree_DATA *data = INST_DATA(cl, obj);
710 struct ListImage * li = (struct ListImage *)msg->listimg;
712 if (!li)
713 return 0;
715 /* DoMethod(li->obj, MUIM_Cleanup); // Called in MUIM_NList_DeleteImage */
716 DoMethod(li->obj, MUIM_DisconnectParent);
717 return DoMethod(data->nlisttree, MUIM_NList_DeleteImage, msg->listimg);
720 IPTR Listtree__MUIM_Listtree_Close(struct IClass *cl, Object *obj, struct MUIP_Listtree_Close *msg)
722 struct Listtree_DATA *data = INST_DATA(cl, obj);
723 struct MUI_NListtree_TreeNode * tn = NULL, * ln = NULL;
725 switch((IPTR)msg->ListNode)
727 case(MUIV_Listtree_Close_ListNode_Root):
728 case(MUIV_Listtree_Close_ListNode_Parent):
729 case(MUIV_Listtree_Close_ListNode_Active):
730 ln = msg->ListNode;
731 break;
732 default:
733 ln = ((struct MUIS_Listtree_TreeNodeInt *)msg->ListNode)->ref;
736 switch((IPTR)msg->TreeNode)
738 case(MUIV_Listtree_Close_TreeNode_Head):
739 case(MUIV_Listtree_Close_TreeNode_Tail):
740 case(MUIV_Listtree_Close_TreeNode_Active):
741 case(MUIV_Listtree_Close_TreeNode_All):
742 tn = msg->TreeNode;
743 break;
744 default:
745 tn = ((struct MUIS_Listtree_TreeNodeInt *)msg->TreeNode)->ref;
748 return DoMethod(data->nlisttree, MUIM_NListtree_Close, ln, tn, msg->Flags);
751 #define FORWARDNLISTTREESUPERMETHOD(methodname) \
752 IPTR Listtree__##methodname(struct IClass *cl, Object *obj, Msg msg) \
754 struct Listtree_DATA *data = INST_DATA(cl, obj); \
755 return DoMethod(data->nlisttree, MUIM_NListtreeInt_ForwardSuperMethod, msg); \
758 #define FORWARDNLISTTREEMETHOD(methodname) \
759 IPTR Listtree__##methodname(struct IClass *cl, Object *obj, Msg msg) \
761 struct Listtree_DATA *data = INST_DATA(cl, obj); \
762 return DoMethodA(data->nlisttree, msg); \
765 FORWARDNLISTTREEMETHOD(MUIM_CreateDragImage)
766 FORWARDNLISTTREEMETHOD(MUIM_DeleteDragImage)
768 IPTR Listtree__MUIM_Notify(struct IClass *cl, Object *obj, struct MUIP_Notify *msg)
770 struct Listtree_DATA *data = INST_DATA(cl, obj);
772 /* NList expects this notification to be set and uses its content */
773 if (msg->TrigAttr == MUIA_List_Prop_First)
774 DoMethodA(data->nlisttree, msg);
776 return DoSuperMethodA(cl, obj, msg);