Listtree.mcc: implement Listtree_Close
[AROS.git] / workbench / classes / zune / listtree / listtree.c
blobe9f11b33191bf839187e20a6ba3f076596e4c14c
1 /*
2 Copyright © 2012-2015, The AROS Development Team. All rights reserved.
3 $Id$
4 */
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>
16 #undef TNF_OPEN
17 #undef TNF_LIST
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 struct NListtreeInt_DATA
30 Object * listtree;
33 static struct MUI_CustomClass * CL_NListtreeInt;
35 BOOPSI_DISPATCHER(IPTR, NListtreeInt_Dispatcher, cl, obj, msg)
37 switch (msg->MethodID)
41 return DoSuperMethodA(cl, obj, msg);
43 BOOPSI_DISPATCHER_END
45 static int MCC_NListtreeInt_Startup(struct Library * lib)
47 CL_NListtreeInt = MUI_CreateCustomClass(lib, MUIC_NListtree, NULL, sizeof(struct NListtreeInt_DATA), NListtreeInt_Dispatcher);
48 return CL_NListtreeInt != NULL;
51 static void MCC_NListtreeInt_Shutdown(struct Library * lib)
53 MUI_DeleteCustomClass(CL_NListtreeInt);
56 ADD2INITCLASSES(MCC_NListtreeInt_Startup, -1);
57 ADD2EXPUNGECLASSES(MCC_NListtreeInt_Shutdown, -1);
58 /* Internal version of NListtree that enables controling the dispatcher */
60 /* Relations:
61 * MUIS_Listtree_Treenode -> MUI_NListtree_Treenode via MUIS_Listtree_TreeNodeInt.ref
62 * MUI_NListtree_Treenode -> MUIS_Listtree_Treenode via MUI_NListtree_Treenode.tn_User
64 struct MUIS_Listtree_TreeNodeInt
66 struct MUIS_Listtree_TreeNode base;
67 struct MUI_NListtree_TreeNode *ref;
70 static IPTR NotifySimulate_Function(struct Hook *hook, Object *obj, void ** msg)
72 struct opSet setmsg;
73 struct TagItem setti[] = {{0,0},{TAG_DONE, TAG_DONE}};
75 IPTR attr = (IPTR)msg[0];
76 IPTR val = (IPTR)msg[1];
77 struct IClass * cl = hook->h_Data;
79 setmsg.MethodID = OM_SET;
80 setmsg.ops_AttrList = setti;
81 setmsg.ops_GInfo = NULL;
83 switch(attr)
85 case(MUIA_NListtree_Active):
86 setti[0].ti_Tag = MUIA_Listtree_Active;
87 setti[0].ti_Data = val ? (IPTR)((struct MUI_NListtree_TreeNode *)val)->tn_User : 0;
88 break;
89 default:
90 bug("[Listtree] NotifySimulate_Function - unhandled attribute %x\n", attr);
93 /* Super method OM_SET call will go to Notify class and trigger notifications */
94 return DoSuperMethodA(cl, obj, (Msg) &setmsg);
97 static IPTR DisplayHook_Proxy(struct Hook *hook, Object *obj, struct MUIP_NListtree_DisplayMessage *msg)
99 struct _temp { STACKED APTR array; STACKED APTR treenode; } t;
100 struct Hook * displayhook = (struct Hook *)hook->h_Data;
102 if (!displayhook)
103 return FALSE;
105 t.array = msg->Array;
106 t.treenode = msg->TreeNode ? msg->TreeNode->tn_User : NULL;
108 return CallHookPkt(displayhook, t.array, t.treenode);
111 #define NEWHANDLE(attrname) \
112 case(attrname): \
113 bug("[Listtree] OM_NEW:%s - unsupported\n", #attrname); \
114 break;
116 #define CONV(AATTR, BATTR) \
117 case(AATTR): \
118 convtags[i].ti_Tag = BATTR; \
119 convtags[i++].ti_Data = tag->ti_Data; \
120 break;
122 #define COPY(AATTR) \
123 case(AATTR): \
124 supertags[i].ti_Tag = AATTR; \
125 supertags[i++].ti_Data = tag->ti_Data; \
126 break;
128 #define SYNC_TREENODE_FLAGS(tn) \
129 ((struct MUIS_Listtree_TreeNode *)tn->tn_User)->tn_Flags = tn->tn_Flags;
131 /*** Methods ****************************************************************/
132 Object *Listtree__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
134 struct Listtree_DATA *data = NULL;
135 struct TagItem *tag;
136 struct TagItem *tags;
137 Object *nlisttree = NULL;
138 struct TagItem convtags[20];
139 struct TagItem supertags[20];
140 LONG i;
142 /* Convert tags designated for NListtree */
143 for (i = 0, tags = msg->ops_AttrList; (tag = NextTagItem(&tags)); )
145 switch (tag->ti_Tag)
147 CONV(MUIA_Frame, MUIA_Frame)
148 CONV(MUIA_Listtree_Format, MUIA_NListtree_Format)
149 CONV(MUIA_Listtree_Title, MUIA_NListtree_Title)
150 CONV(MUIA_Listtree_DragDropSort, MUIA_NListtree_DragDropSort)
151 CONV(MUIA_List_Title, MUIA_NList_Title)
152 CONV(MUIA_List_DragSortable, MUIA_NList_DragSortable)
153 CONV(MUIA_List_MinLineHeight, MUIA_NList_MinLineHeight)
156 convtags[i].ti_Tag = TAG_DONE;
158 /* Copy tags designated for super class */
159 for (i = 0, tags = msg->ops_AttrList; (tag = NextTagItem(&tags)); )
161 switch (tag->ti_Tag)
163 COPY(MUIA_ContextMenu) /* ContextMenuBuild/Choice will be called on child classes of Listtree */
166 supertags[i].ti_Tag = TAG_DONE;
168 /* TODO:
169 * set up a DestructHook which will call proxy MUIS_Listtree_TreeNode destrhook and
170 * free it afterwards
172 obj = (Object *) DoSuperNewTags(cl, obj, 0,
173 Child, nlisttree = (Object *) NewObjectA(CL_NListtreeInt->mcc_Class, NULL, convtags),
174 TAG_MORE, (IPTR)supertags,
175 TAG_DONE);
177 if (!obj) return FALSE;
179 data = INST_DATA(cl, obj);
180 data->nlisttree = nlisttree;
181 data->notifysimulatehook.h_Entry = HookEntry;
182 data->notifysimulatehook.h_SubEntry = (HOOKFUNC)NotifySimulate_Function;
183 data->notifysimulatehook.h_Data = cl;
185 data->pool = CreatePool(MEMF_ANY | MEMF_CLEAR, 16 * 1024, 8 * 1024);
187 /* parse initial taglist */
188 for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags)); )
190 switch (tag->ti_Tag)
192 case(MUIA_Listtree_ConstructHook):
193 data->constrhook = (struct Hook *)tag->ti_Data;
194 break;
195 case(MUIA_Listtree_DestructHook):
196 data->destrhook = (struct Hook *)tag->ti_Data;
197 break;
198 case(MUIA_Listtree_DisplayHook):
199 data->displayhook = (struct Hook *)tag->ti_Data;
200 break;
201 case(MUIA_List_MinLineHeight):
202 case(MUIA_List_DragSortable):
203 case(MUIA_List_Title):
204 case(MUIA_Listtree_DragDropSort):
205 case(MUIA_Listtree_Format):
206 case(MUIA_Listtree_Title):
207 case(MUIA_Frame):
208 /* Forwarded to NListtree */
209 break;
210 case(MUIA_ContextMenu):
211 /* Forwarded to super class */
212 break;
213 NEWHANDLE(MUIA_Listtree_SortHook)
214 default:
215 bug("[Listtree] OM_NEW: unhandled %x\n", tag->ti_Tag);
219 /* Setup root node */
221 struct MUIS_Listtree_TreeNodeInt * _int = AllocPooled(data->pool, sizeof(struct MUIS_Listtree_TreeNodeInt));
222 struct MUI_NListtree_TreeNode * root = NULL;
223 root = (struct MUI_NListtree_TreeNode *)DoMethod(data->nlisttree, MUIM_NListtree_GetEntry,
224 NULL, -15 /* priv -> position root */, 0);
225 root->tn_User = _int;
226 _int->ref = root;
229 /* Setup hook proxies */
230 if (data->displayhook)
232 data->displayhookproxy.h_Entry = HookEntry;
233 data->displayhookproxy.h_SubEntry = (HOOKFUNC)DisplayHook_Proxy;
234 data->displayhookproxy.h_Data = data->displayhook;
235 nnset(data->nlisttree, MUIA_NListtree_DisplayHook, &data->displayhookproxy);
238 /* Setup notification forwarding */
239 DoMethod(data->nlisttree, MUIM_Notify, MUIA_NListtree_Active, MUIV_EveryTime,
240 obj, 4, MUIM_CallHook, &data->notifysimulatehook, MUIA_NListtree_Active, MUIV_TriggerValue);
242 return obj;
245 #define SETHANDLE(attrname) \
246 case(attrname): \
247 bug("[Listtree] OM_SET:%s - unsupported\n", #attrname); \
248 break;
250 #define FORWARDSET(AATTR, BATTR) \
251 case(AATTR): \
252 set(data->nlisttree, BATTR, tag->ti_Data); \
253 break;
255 #define IGNORESET(AATTR) case(AATTR): break;
257 IPTR Listtree__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg)
259 struct Listtree_DATA *data = INST_DATA(cl, obj);
260 struct TagItem *tstate = msg->ops_AttrList;
261 struct TagItem *tag;
263 if (!data->nlisttree)
264 return DoSuperMethodA(cl, obj, (Msg) msg);
266 while ((tag = NextTagItem(&tstate)) != NULL)
268 switch (tag->ti_Tag)
270 FORWARDSET(MUIA_Listtree_Quiet, MUIA_NListtree_Quiet)
271 FORWARDSET(MUIA_List_Active, MUIA_NList_Active)
273 IGNORESET(MUIA_Listview_SelectChange)
275 case(MUIA_Listtree_Active):
276 set(data->nlisttree, MUIA_NListtree_Active,
277 ((struct MUIS_Listtree_TreeNodeInt *)tag->ti_Data)->ref);
278 break;
280 SETHANDLE(MUIA_Listtree_DoubleClick)
281 case MUIB_List | 0x00000010: break;
282 case MUIA_Prop_First: break;
283 case MUIA_Prop_DoSmooth: break;
284 case MUIA_NoNotify: break;
285 case MUIA_Prop_Entries: break;
286 case MUIA_Prop_Visible: break;
287 case MUIA_Prop_DeltaFactor: break;
288 default:
289 bug("[Listtree] OM_SET: passing to parent class %x\n", tag->ti_Tag);
294 return DoSuperMethodA(cl, obj, (Msg) msg);
297 #define GETHANDLE(attrname) \
298 case(attrname): \
299 bug("[Listtree] OM_GET:%s - unsupported\n", #attrname); \
300 break;
303 #define MUIA_List_Prop_Entries /* PRIV */ \
304 (MUIB_MUI | 0x0042a8f5) /* .sg LONG PRIV */
305 #define MUIA_List_Prop_Visible /* PRIV */ \
306 (MUIB_MUI | 0x004273e9) /* .sg LONG PRIV */
307 #define MUIA_List_Prop_First /* PRIV */ \
308 (MUIB_MUI | 0x00429df3) /* .sg LONG PRIV */
310 #define MUIA_List_VertProp_Entries /* PRIV */ \
311 MUIA_List_Prop_Entries /* PRIV */
312 #define MUIA_List_VertProp_Visible /* PRIV */ \
313 MUIA_List_Prop_Visible /* PRIV */
314 #define MUIA_List_VertProp_First /* PRIV */ \
315 MUIA_List_Prop_First /* PRIV */
317 #define FORWARDGET(AATTR, BATTR) \
318 case(AATTR): \
319 *(msg->opg_Storage) = XGET(data->nlisttree, BATTR); \
320 return TRUE;
322 IPTR Listtree__OM_GET(struct IClass *cl, Object *obj, struct opGet *msg)
324 struct Listtree_DATA *data = INST_DATA(cl, obj);
326 if (!data->nlisttree)
327 return FALSE;
329 switch (msg->opg_AttrID)
331 FORWARDGET(MUIA_Frame, MUIA_Frame)
332 FORWARDGET(MUIA_Listtree_DoubleClick, MUIA_NListtree_DoubleClick)
333 FORWARDGET(MUIA_List_Active, MUIA_NList_Active)
334 FORWARDGET(MUIA_Listtree_Active, MUIA_NListtree_Active)
335 FORWARDGET(MUIA_Listtree_Quiet, MUIA_NListtree_Quiet)
336 FORWARDGET(MUIA_List_Visible, MUIA_NList_Visible)
338 GETHANDLE(MUIA_List_VertProp_Entries)
339 GETHANDLE(MUIA_List_VertProp_Visible)
340 GETHANDLE(MUIA_List_VertProp_First)
341 case MUIA_Disabled: break;
342 case MUIA_Parent: break;
343 case MUIA_Group_ChildList: break;
344 case MUIA_Prop_First: break;
345 case MUIA_Prop_DoSmooth: break;
346 case MUIA_Listview_List: break;
347 case MUIA_Virtgroup_Left: break;
348 case MUIA_Virtgroup_Top: break;
349 case 0x9d510020 /*MUIA_NListview_NList*/: break;
350 default:
351 bug("[Listtree] OM_GET: passing to parent class %x\n", msg->opg_AttrID);
354 return DoSuperMethodA(cl, obj, (Msg) msg);
357 #define METHODSTUB(methodname) \
358 IPTR Listtree__##methodname(struct IClass *cl, Object *obj, Msg msg) \
360 bug("[Listtree] Usupported : %s\n", #methodname); \
361 return (IPTR)FALSE; \
364 METHODSTUB(MUIM_Listtree_SetDropMark)
366 IPTR Listtree__MUIM_Listtree_Insert(struct IClass *cl, Object *obj, struct MUIP_Listtree_Insert *msg)
368 struct Listtree_DATA *data = INST_DATA(cl, obj);
369 struct MUIS_Listtree_TreeNodeInt * _int = AllocPooled(data->pool, sizeof(struct MUIS_Listtree_TreeNodeInt));
370 struct MUIS_Listtree_TreeNode * _return = NULL;
371 struct MUI_NListtree_TreeNode * ln = NULL, * pn = NULL;
373 if (_int == NULL)
374 return (IPTR)NULL;
376 _return = &_int->base;
378 _return->tn_Flags = (UWORD)msg->Flags;
379 if (data->constrhook)
380 _return->tn_User = (APTR)CallHookPkt(data->constrhook, data->pool, msg->User);
381 else
382 _return->tn_User = msg->User;
384 switch((IPTR)msg->ListNode)
386 case(MUIV_Listtree_Insert_ListNode_Root):
387 case(MUIV_Listtree_Insert_ListNode_Active):
388 ln = msg->ListNode;
389 break;
390 default:
391 ln = ((struct MUIS_Listtree_TreeNodeInt *)msg->ListNode)->ref;
394 switch((IPTR)msg->PrevNode)
396 case(MUIV_Listtree_Insert_PrevNode_Head):
397 case(MUIV_Listtree_Insert_PrevNode_Tail):
398 case(MUIV_Listtree_Insert_PrevNode_Active):
399 case(MUIV_Listtree_Insert_PrevNode_Sorted):
400 pn = msg->PrevNode;
401 break;
402 default:
403 pn = ((struct MUIS_Listtree_TreeNodeInt *)msg->PrevNode)->ref;
406 _int->ref = (struct MUI_NListtree_TreeNode *)DoMethod(data->nlisttree,
407 MUIM_NListtree_Insert, msg->Name, _return, ln, pn, msg->Flags);
409 _return->tn_Name = _int->ref->tn_Name;
411 return (IPTR)_return;
414 IPTR Listtree__MUIM_Listtree_GetEntry(struct IClass *cl, Object *obj, struct MUIP_Listtree_GetEntry *msg)
416 struct Listtree_DATA *data = INST_DATA(cl, obj);
417 struct MUI_NListtree_TreeNode * tn = NULL, * found = NULL;
419 switch ((IPTR)msg->Node)
421 case(MUIV_Listtree_GetEntry_ListNode_Root):
422 case(MUIV_Listtree_GetEntry_ListNode_Active):
423 tn = msg->Node;
424 break;
425 default:
426 tn = ((struct MUIS_Listtree_TreeNodeInt *)msg->Node)->ref;
429 found = (struct MUI_NListtree_TreeNode *) DoMethod(data->nlisttree,
430 MUIM_NListtree_GetEntry, tn, msg->Position, msg->Flags);
432 if (found)
434 SYNC_TREENODE_FLAGS(found);
435 return (IPTR)found->tn_User;
437 else
438 return (IPTR)NULL;
441 IPTR Listtree__MUIM_Listtree_Remove(struct IClass *cl, Object *obj, struct MUIP_Listtree_Remove *msg)
443 struct Listtree_DATA *data = INST_DATA(cl, obj);
445 /* TODO: handle remaining enumeration values */
446 if ((msg->ListNode == (APTR)MUIV_Listtree_Remove_ListNode_Root) &&
447 ((msg->TreeNode == (APTR)MUIV_Listtree_Remove_TreeNode_Active) ||
448 (msg->TreeNode == (APTR)MUIV_Listtree_Remove_TreeNode_All)))
450 /* Deallocating of MUIS_Listtree_TreeNode is happening in the DestructHook */
451 return DoMethod(data->nlisttree, MUIM_NListtree_Remove, msg->ListNode, msg->TreeNode, msg->Flags);
454 /* TODO
455 * add handling for cases where ListNode/TreeNode actually point to Treenode structure
457 bug("[Listtree] MUIM_Listtree_Remove unsupported code path Listnode: %x, Treenode: %x, Flags: %d\n", msg->ListNode, msg->TreeNode, msg->Flags);
459 return (IPTR)FALSE;
462 IPTR Listtree__MUIM_List_TestPos(struct IClass *cl, Object *obj, struct MUIP_List_TestPos *msg)
464 struct Listtree_DATA *data = INST_DATA(cl, obj);
466 struct MUI_NList_TestPos_Result res;
467 if (DoMethod(data->nlisttree, MUIM_List_TestPos, msg->x, msg->y, &res))
469 msg->res->entry = res.entry;
470 msg->res->column = res.column;
471 msg->res->flags = res.flags;
472 msg->res->xoffset = res.xoffset;
473 msg->res->yoffset = res.yoffset;
474 return TRUE;
477 return FALSE;
480 IPTR Listtree__MUIM_Listtree_TestPos(struct IClass *cl, Object *obj, struct MUIP_Listtree_TestPos *msg)
482 struct Listtree_DATA *data = INST_DATA(cl, obj);
484 struct MUI_NListtree_TestPos_Result res;
485 struct MUIS_Listtree_TestPos_Result * _ret = (struct MUIS_Listtree_TestPos_Result *)msg->Result;
487 _ret->tpr_TreeNode = NULL;
489 DoMethod(data->nlisttree, MUIM_NListtree_TestPos, msg->X, msg->Y, &res);
491 _ret->tpr_Flags = res.tpr_Type;
492 _ret->tpr_ListEntry = res.tpr_ListEntry;
493 _ret->tpr_ListFlags = res.tpr_ListFlags;
495 if (res.tpr_TreeNode != NULL)
497 SYNC_TREENODE_FLAGS(res.tpr_TreeNode);
498 _ret->tpr_TreeNode = res.tpr_TreeNode->tn_User;
499 return TRUE;
502 return FALSE;
505 IPTR Listtree__MUIM_Listtree_GetNr(struct IClass *cl, Object *obj, struct MUIP_Listtree_GetNr *msg)
507 struct Listtree_DATA *data = INST_DATA(cl, obj);
508 struct MUI_NListtree_TreeNode * tn = NULL;
510 switch((IPTR)msg->TreeNode)
512 case(MUIV_Listtree_GetNr_TreeNode_Active):
513 tn = msg->TreeNode;
514 break;
515 default:
516 tn = ((struct MUIS_Listtree_TreeNodeInt *)msg->TreeNode)->ref;
519 return DoMethod(data->nlisttree, MUIM_NListtree_GetNr, tn, msg->Flags);
522 IPTR Listtree__MUIM_Listtree_Rename(struct IClass *cl, Object *obj, struct MUIP_Listtree_Rename *msg)
524 struct Listtree_DATA *data = INST_DATA(cl, obj);
525 struct MUI_NListtree_TreeNode * tn = NULL, * renamed = NULL;
527 switch((IPTR)msg->TreeNode)
529 case(MUIV_Listtree_Rename_TreeNode_Active):
530 tn = msg->TreeNode;
531 break;
532 default:
533 tn = ((struct MUIS_Listtree_TreeNodeInt *)msg->TreeNode)->ref;
536 renamed = (struct MUI_NListtree_TreeNode *)DoMethod(data->nlisttree,
537 MUIM_NListtree_Rename, tn, msg->NewName, msg->Flags);
539 if (renamed)
541 ((struct MUIS_Listtree_TreeNode *)renamed->tn_User)->tn_Name = renamed->tn_Name;
542 return (IPTR)renamed->tn_User;
544 else
545 return (IPTR)NULL;
548 IPTR Listtree__MUIM_List_Redraw(struct IClass *cl, Object *obj, struct MUIP_List_Redraw *msg)
550 struct Listtree_DATA *data = INST_DATA(cl, obj);
551 struct MUI_NListtree_TreeNode * entry = msg->entry ?
552 ((struct MUIS_Listtree_TreeNodeInt *)msg->entry)->ref : NULL;
554 switch(msg->pos)
556 case(MUIV_List_Redraw_Entry):
557 return DoMethod(data->nlisttree, MUIM_NList_RedrawEntry, entry);
558 default:
559 return DoMethod(data->nlisttree, MUIM_NList_Redraw, msg->pos);
563 IPTR Listtree__MUIM_Listtree_Open(struct IClass *cl, Object *obj, struct MUIP_Listtree_Open *msg)
565 struct Listtree_DATA *data = INST_DATA(cl, obj);
566 struct MUI_NListtree_TreeNode * tn = NULL, * ln = NULL;
568 switch((IPTR)msg->ListNode)
570 case(MUIV_Listtree_Open_ListNode_Root):
571 case(MUIV_Listtree_Open_ListNode_Parent):
572 case(MUIV_Listtree_Open_ListNode_Active):
573 ln = msg->ListNode;
574 break;
575 default:
576 ln = ((struct MUIS_Listtree_TreeNodeInt *)msg->ListNode)->ref;
579 switch((IPTR)msg->TreeNode)
581 case(MUIV_Listtree_Open_TreeNode_Head):
582 case(MUIV_Listtree_Open_TreeNode_Tail):
583 case(MUIV_Listtree_Open_TreeNode_Active):
584 case(MUIV_Listtree_Open_TreeNode_All):
585 tn = msg->TreeNode;
586 break;
587 default:
588 tn = ((struct MUIS_Listtree_TreeNodeInt *)msg->TreeNode)->ref;
591 return DoMethod(data->nlisttree, MUIM_NListtree_Open, ln, tn, msg->Flags);
594 IPTR Listtree__MUIM_Listtree_FindName(struct IClass *cl, Object *obj, struct MUIP_Listtree_FindName *msg)
596 struct Listtree_DATA *data = INST_DATA(cl, obj);
597 struct MUI_NListtree_TreeNode * ln = NULL, * found = NULL;
599 switch((IPTR)msg->ListNode)
601 case(MUIV_Listtree_FindName_ListNode_Root):
602 case(MUIV_Listtree_FindName_ListNode_Active):
603 ln = msg->ListNode;
604 break;
605 default:
606 ln = ((struct MUIS_Listtree_TreeNodeInt *)msg->ListNode)->ref;
609 found = (struct MUI_NListtree_TreeNode *) DoMethod(data->nlisttree, MUIM_NListtree_FindName,
610 ln, msg->Name, msg->Flags);
612 if (found)
613 return (IPTR)found->tn_User;
614 else
615 return (IPTR)NULL;
618 struct ListImage
620 struct MinNode node;
621 Object *obj;
624 #define MADF_SETUP (1<< 28) /* PRIV - zune-specific */
626 IPTR DoSetupMethod(Object * obj, struct MUI_RenderInfo * info)
628 /* MUI set the correct render info *before* it calls MUIM_Setup so please
629 * only use this function instead of DoMethodA() */
630 muiRenderInfo(obj) = info;
631 return DoMethod(obj, MUIM_Setup, (IPTR) info);
634 IPTR Listtree__MUIM_List_CreateImage(struct IClass *cl, Object *obj, struct MUIP_List_CreateImage *msg)
636 struct Listtree_DATA *data = INST_DATA(cl, obj);
638 if (!(_flags(obj) & MADF_SETUP))
639 return 0;
641 IPTR _ret = DoMethod(data->nlisttree, MUIM_NList_CreateImage, msg->obj, msg->flags);
643 /* There is a use case where an image object created in a Listtree can be passed as O[address]
644 * in the text in the display callback of List. Since Listtree just wraps around NListtree and the
645 * return structures from List_CreateImage and NList_CreateImage are different, this would normally
646 * not work. Luckily, List needs only the msg->obj and it is at the same offset in ListImage and
647 * in structure returned by NList. The case will work as long as this is met.
649 struct ListImage * li = (struct ListImage *)_ret;
650 if (li->obj != msg->obj)
651 bug("[Listtree] CreateImage condition BROKEN, see comment in code!\n");
653 /* Setup the msg->obj as the List is doing */
654 DoMethod(li->obj, MUIM_ConnectParent, (IPTR) obj);
655 DoSetupMethod(li->obj, muiRenderInfo(obj));
657 return _ret;
660 IPTR Listtree__MUIM_List_DeleteImage(struct IClass *cl, Object *obj, struct MUIP_List_DeleteImage *msg)
662 struct Listtree_DATA *data = INST_DATA(cl, obj);
663 struct ListImage * li = (struct ListImage *)msg->listimg;
665 /* DoMethod(li->obj, MUIM_Cleanup); // Called in MUIM_NList_DeleteImage */
666 DoMethod(li->obj, MUIM_DisconnectParent);
667 return DoMethod(data->nlisttree, MUIM_NList_DeleteImage, msg->listimg);
670 IPTR Listtree__MUIM_Listtree_Close(struct IClass *cl, Object *obj, struct MUIP_Listtree_Close *msg)
672 struct Listtree_DATA *data = INST_DATA(cl, obj);
673 struct MUI_NListtree_TreeNode * tn = NULL, * ln = NULL;
675 switch((IPTR)msg->ListNode)
677 case(MUIV_Listtree_Close_ListNode_Root):
678 case(MUIV_Listtree_Close_ListNode_Parent):
679 case(MUIV_Listtree_Close_ListNode_Active):
680 ln = msg->ListNode;
681 break;
682 default:
683 ln = ((struct MUIS_Listtree_TreeNodeInt *)msg->ListNode)->ref;
686 switch((IPTR)msg->TreeNode)
688 case(MUIV_Listtree_Close_TreeNode_Head):
689 case(MUIV_Listtree_Close_TreeNode_Tail):
690 case(MUIV_Listtree_Close_TreeNode_Active):
691 case(MUIV_Listtree_Close_TreeNode_All):
692 tn = msg->TreeNode;
693 break;
694 default:
695 tn = ((struct MUIS_Listtree_TreeNodeInt *)msg->TreeNode)->ref;
698 return DoMethod(data->nlisttree, MUIM_NListtree_Close, ln, tn, msg->Flags);