Listtree.mcc: implement Listtree_Open and Listtree_FindName
[AROS.git] / workbench / classes / zune / listtree / listtree.c
blob687cb79ef81a2217aa743de420024247b59af4f9
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 struct MUIS_Listtree_TreeNodeInt
25 struct MUIS_Listtree_TreeNode base;
26 struct MUI_NListtree_TreeNode *ref;
29 static IPTR NotifySimulate_Function(struct Hook *hook, Object *obj, void ** msg)
31 struct opSet setmsg;
32 struct TagItem setti[] = {{0,0},{TAG_DONE, TAG_DONE}};
34 IPTR attr = (IPTR)msg[0];
35 IPTR val = (IPTR)msg[1];
36 struct IClass * cl = hook->h_Data;
38 setmsg.MethodID = OM_SET;
39 setmsg.ops_AttrList = setti;
40 setmsg.ops_GInfo = NULL;
42 switch(attr)
44 case(MUIA_NListtree_Active):
45 setti[0].ti_Tag = MUIA_Listtree_Active;
46 setti[0].ti_Data = val ? (IPTR)((struct MUI_NListtree_TreeNode *)val)->tn_User : 0;
47 break;
48 default:
49 bug("[Listtree] NotifySimulate_Function - unhandled attribute %x\n", attr);
52 /* Super method OM_SET call will go to Notify class and trigger notifications */
53 return DoSuperMethodA(cl, obj, (Msg) &setmsg);
56 #define NEWHANDLE(attrname) \
57 case(attrname): \
58 bug("[Listtree] OM_NEW:%s - unsupported\n", #attrname); \
59 break;
61 #define CONV(AATTR, BATTR) \
62 case(AATTR): \
63 convtags[i].ti_Tag = BATTR; \
64 convtags[i++].ti_Data = tag->ti_Data; \
65 break;
67 #define CONVFIN \
68 convtags[i].ti_Tag = TAG_DONE; \
69 convtags[i].ti_Data = TAG_DONE;
71 /*** Methods ****************************************************************/
72 Object *Listtree__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
74 struct Listtree_DATA *data = NULL;
75 struct TagItem *tag;
76 struct TagItem *tags;
77 Object *nlisttree = NULL;
78 struct TagItem convtags[20];
79 LONG i = 0;
81 /* Convert tags designated for NListtree */
82 for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags)); )
84 switch (tag->ti_Tag)
86 CONV(MUIA_Frame, MUIA_Frame)
87 CONV(MUIA_Listtree_Format, MUIA_NListtree_Format)
88 CONV(MUIA_Listtree_Title, MUIA_NListtree_Title)
89 CONV(MUIA_Listtree_DragDropSort, MUIA_NListtree_DragDropSort)
90 CONV(MUIA_List_Title, MUIA_NList_Title)
91 CONV(MUIA_List_DragSortable, MUIA_NList_DragSortable)
92 // CONV(MUIA_ContextMenu, MUIA_ContextMenu) // FIXME causes a crash when right clicking
93 CONV(MUIA_List_MinLineHeight, MUIA_NList_MinLineHeight)
96 CONVFIN
98 /* TODO:
99 * set up a DestructHook which will call proxy MUIS_Listtree_TreeNode destrhook and
100 * free it afterwards
102 obj = (Object *) DoSuperNewTags(cl, obj, 0,
103 Child, nlisttree = (Object *) NListtreeObject,
104 TAG_MORE, (IPTR)convtags,
105 End,
108 if (!obj) return FALSE;
110 data = INST_DATA(cl, obj);
111 data->nlisttree = nlisttree;
112 data->notifysimulatehook.h_Entry = HookEntry;
113 data->notifysimulatehook.h_SubEntry = (HOOKFUNC)NotifySimulate_Function;
114 data->notifysimulatehook.h_Data = cl;
116 data->pool = CreatePool(MEMF_ANY | MEMF_CLEAR, 16 * 1024, 8 * 1024);
118 /* parse initial taglist */
119 for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags)); )
121 switch (tag->ti_Tag)
123 case(MUIA_Listtree_ConstructHook):
124 data->constrhook = (struct Hook *)tag->ti_Data;
125 break;
126 case(MUIA_Listtree_DestructHook):
127 data->destrhook = (struct Hook *)tag->ti_Data;
128 break;
129 case(MUIA_List_MinLineHeight):
130 case(MUIA_ContextMenu):
131 case(MUIA_List_DragSortable):
132 case(MUIA_List_Title):
133 case(MUIA_Listtree_DragDropSort):
134 case(MUIA_Listtree_Format):
135 case(MUIA_Listtree_Title):
136 case(MUIA_Frame):
137 /* Forwarded to NListtree */
138 break;
139 NEWHANDLE(MUIA_Listtree_DisplayHook)
140 NEWHANDLE(MUIA_Listtree_SortHook)
141 default:
142 bug("[Listtree] OM_NEW: unhandled %x\n", tag->ti_Tag);
146 /* Setup notification forwarding */
147 DoMethod(data->nlisttree, MUIM_Notify, MUIA_NListtree_Active, MUIV_EveryTime,
148 obj, 4, MUIM_CallHook, &data->notifysimulatehook, MUIA_NListtree_Active, MUIV_TriggerValue);
150 return obj;
153 #define SETHANDLE(attrname) \
154 case(attrname): \
155 bug("[Listtree] OM_SET:%s - unsupported\n", #attrname); \
156 break;
158 #define FORWARDSET(AATTR, BATTR) \
159 case(AATTR): \
160 set(data->nlisttree, BATTR, tag->ti_Data); \
161 break;
163 #define IGNORESET(AATTR) case(AATTR): break;
165 IPTR Listtree__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg)
167 struct Listtree_DATA *data = INST_DATA(cl, obj);
168 struct TagItem *tstate = msg->ops_AttrList;
169 struct TagItem *tag;
171 if (!data->nlisttree)
172 return DoSuperMethodA(cl, obj, (Msg) msg);
174 while ((tag = NextTagItem(&tstate)) != NULL)
176 switch (tag->ti_Tag)
178 FORWARDSET(MUIA_Listtree_Quiet, MUIA_NListtree_Quiet)
179 FORWARDSET(MUIA_List_Active, MUIA_NList_Active)
181 IGNORESET(MUIA_Listview_SelectChange)
183 case(MUIA_Listtree_Active):
184 set(data->nlisttree, MUIA_NListtree_Active,
185 ((struct MUIS_Listtree_TreeNodeInt *)tag->ti_Data)->ref);
186 break;
188 SETHANDLE(MUIA_Listtree_DoubleClick)
189 case MUIB_List | 0x00000010: break;
190 case MUIA_Prop_First: break;
191 case MUIA_Prop_DoSmooth: break;
192 case MUIA_NoNotify: break;
193 case MUIA_Prop_Entries: break;
194 case MUIA_Prop_Visible: break;
195 case MUIA_Prop_DeltaFactor: break;
196 default:
197 bug("[Listtree] OM_SET: passing to parent class %x\n", tag->ti_Tag);
202 return DoSuperMethodA(cl, obj, (Msg) msg);
205 #define GETHANDLE(attrname) \
206 case(attrname): \
207 bug("[Listtree] OM_GET:%s - unsupported\n", #attrname); \
208 break;
211 #define MUIA_List_Prop_Entries /* PRIV */ \
212 (MUIB_MUI | 0x0042a8f5) /* .sg LONG PRIV */
213 #define MUIA_List_Prop_Visible /* PRIV */ \
214 (MUIB_MUI | 0x004273e9) /* .sg LONG PRIV */
215 #define MUIA_List_Prop_First /* PRIV */ \
216 (MUIB_MUI | 0x00429df3) /* .sg LONG PRIV */
218 #define MUIA_List_VertProp_Entries /* PRIV */ \
219 MUIA_List_Prop_Entries /* PRIV */
220 #define MUIA_List_VertProp_Visible /* PRIV */ \
221 MUIA_List_Prop_Visible /* PRIV */
222 #define MUIA_List_VertProp_First /* PRIV */ \
223 MUIA_List_Prop_First /* PRIV */
225 #define FORWARDGET(AATTR, BATTR) \
226 case(AATTR): \
227 *(msg->opg_Storage) = XGET(data->nlisttree, BATTR); \
228 return TRUE;
230 IPTR Listtree__OM_GET(struct IClass *cl, Object *obj, struct opGet *msg)
232 struct Listtree_DATA *data = INST_DATA(cl, obj);
234 if (!data->nlisttree)
235 return FALSE;
237 switch (msg->opg_AttrID)
239 FORWARDGET(MUIA_Frame, MUIA_Frame)
240 FORWARDGET(MUIA_Listtree_DoubleClick, MUIA_NListtree_DoubleClick)
241 FORWARDGET(MUIA_List_Active, MUIA_NList_Active)
242 FORWARDGET(MUIA_Listtree_Active, MUIA_NListtree_Active)
243 FORWARDGET(MUIA_Listtree_Quiet, MUIA_NListtree_Quiet)
244 FORWARDGET(MUIA_List_Visible, MUIA_NList_Visible)
246 GETHANDLE(MUIA_List_VertProp_Entries)
247 GETHANDLE(MUIA_List_VertProp_Visible)
248 GETHANDLE(MUIA_List_VertProp_First)
249 case MUIA_Disabled: break;
250 case MUIA_Parent: break;
251 case MUIA_Group_ChildList: break;
252 case MUIA_Prop_First: break;
253 case MUIA_Prop_DoSmooth: break;
254 case MUIA_Listview_List: break;
255 case MUIA_Virtgroup_Left: break;
256 case MUIA_Virtgroup_Top: break;
257 case 0x9d510020 /*MUIA_NListview_NList*/: break;
258 default:
259 bug("[Listtree] OM_GET: passing to parent class %x\n", msg->opg_AttrID);
262 return DoSuperMethodA(cl, obj, (Msg) msg);
265 #define METHODSTUB(methodname) \
266 IPTR Listtree__##methodname(struct IClass *cl, Object *obj, Msg msg) \
268 bug("[Listtree] Usupported : %s\n", #methodname); \
269 return (IPTR)FALSE; \
272 METHODSTUB(MUIM_Listtree_Close)
273 METHODSTUB(MUIM_Listtree_SetDropMark)
275 IPTR Listtree__MUIM_Listtree_Insert(struct IClass *cl, Object *obj, struct MUIP_Listtree_Insert *msg)
277 struct Listtree_DATA *data = INST_DATA(cl, obj);
278 struct MUIS_Listtree_TreeNodeInt * _int = AllocPooled(data->pool, sizeof(struct MUIS_Listtree_TreeNodeInt));
279 struct MUIS_Listtree_TreeNode * _return = NULL;
280 struct MUI_NListtree_TreeNode * ln = NULL, * pn = NULL;
282 if (_int == NULL)
283 return (IPTR)NULL;
285 _return = &_int->base;
287 _return->tn_Flags = (UWORD)msg->Flags;
288 if (data->constrhook)
289 _return->tn_User = (APTR)CallHookPkt(data->constrhook, data->pool, msg->User);
290 else
291 _return->tn_User = msg->User;
293 switch((IPTR)msg->ListNode)
295 case(MUIV_Listtree_Insert_ListNode_Root):
296 case(MUIV_Listtree_Insert_ListNode_Active):
297 ln = msg->ListNode;
298 break;
299 default:
300 ln = ((struct MUIS_Listtree_TreeNodeInt *)msg->ListNode)->ref;
303 switch((IPTR)msg->PrevNode)
305 case(MUIV_Listtree_Insert_PrevNode_Head):
306 case(MUIV_Listtree_Insert_PrevNode_Tail):
307 case(MUIV_Listtree_Insert_PrevNode_Active):
308 case(MUIV_Listtree_Insert_PrevNode_Sorted):
309 pn = msg->PrevNode;
310 break;
311 default:
312 pn = ((struct MUIS_Listtree_TreeNodeInt *)msg->PrevNode)->ref;
315 _int->ref = (struct MUI_NListtree_TreeNode *)DoMethod(data->nlisttree,
316 MUIM_NListtree_Insert, msg->Name, _return, ln, pn, msg->Flags);
318 _return->tn_Name = _int->ref->tn_Name;
320 return (IPTR)_return;
323 IPTR Listtree__MUIM_Listtree_GetEntry(struct IClass *cl, Object *obj, struct MUIP_Listtree_GetEntry *msg)
325 struct Listtree_DATA *data = INST_DATA(cl, obj);
326 struct MUI_NListtree_TreeNode * n = NULL;
328 switch ((IPTR)msg->Node)
330 case(MUIV_Listtree_GetEntry_ListNode_Root):
331 case(MUIV_Listtree_GetEntry_ListNode_Active):
332 n = msg->Node;
333 break;
334 default:
335 n = ((struct MUIS_Listtree_TreeNodeInt *)msg->Node)->ref;
338 struct MUI_NListtree_TreeNode * tn = (struct MUI_NListtree_TreeNode *) DoMethod(data->nlisttree,
339 MUIM_NListtree_GetEntry, n, msg->Position, msg->Flags);
341 if (tn)
342 return (IPTR)tn->tn_User;
343 else
344 return (IPTR)NULL;
347 IPTR Listtree__MUIM_Listtree_Remove(struct IClass *cl, Object *obj, struct MUIP_Listtree_Remove *msg)
349 struct Listtree_DATA *data = INST_DATA(cl, obj);
351 /* TODO: handle remaining enumeration values */
352 if ((msg->ListNode == (APTR)MUIV_Listtree_Remove_ListNode_Root) &&
353 ((msg->TreeNode == (APTR)MUIV_Listtree_Remove_TreeNode_Active) ||
354 (msg->TreeNode == (APTR)MUIV_Listtree_Remove_TreeNode_All)))
356 /* Deallocating of MUIS_Listtree_TreeNode is happening in the DestructHook */
357 return DoMethod(data->nlisttree, MUIM_NListtree_Remove, msg->ListNode, msg->TreeNode, msg->Flags);
360 /* TODO
361 * add handling for cases where ListNode/TreeNode actually point to Treenode structure
363 bug("[Listtree] MUIM_Listtree_Remove unsupported code path Listnode: %x, Treenode: %x, Flags: %d\n", msg->ListNode, msg->TreeNode, msg->Flags);
365 return (IPTR)FALSE;
368 IPTR Listtree__MUIM_List_TestPos(struct IClass *cl, Object *obj, struct MUIP_List_TestPos *msg)
370 struct Listtree_DATA *data = INST_DATA(cl, obj);
372 struct MUI_NList_TestPos_Result res;
373 if (DoMethod(data->nlisttree, MUIM_List_TestPos, msg->x, msg->y, &res))
375 msg->res->entry = res.entry;
376 msg->res->column = res.column;
377 msg->res->flags = res.flags;
378 msg->res->xoffset = res.xoffset;
379 msg->res->yoffset = res.yoffset;
380 return TRUE;
383 return FALSE;
386 IPTR Listtree__MUIM_Listtree_TestPos(struct IClass *cl, Object *obj, struct MUIP_Listtree_TestPos *msg)
388 struct Listtree_DATA *data = INST_DATA(cl, obj);
390 struct MUI_NListtree_TestPos_Result res;
391 struct MUIS_Listtree_TestPos_Result * _ret = (struct MUIS_Listtree_TestPos_Result *)msg->Result;
393 _ret->tpr_TreeNode = NULL;
395 DoMethod(data->nlisttree, MUIM_NListtree_TestPos, msg->X, msg->Y, &res);
397 _ret->tpr_Flags = res.tpr_Type;
398 _ret->tpr_ListEntry = res.tpr_ListEntry;
399 _ret->tpr_ListFlags = res.tpr_ListFlags;
401 if (res.tpr_TreeNode != NULL)
403 _ret->tpr_TreeNode = res.tpr_TreeNode->tn_User;
404 return TRUE;
407 return FALSE;
410 IPTR Listtree__MUIM_Listtree_GetNr(struct IClass *cl, Object *obj, struct MUIP_Listtree_GetNr *msg)
412 struct Listtree_DATA *data = INST_DATA(cl, obj);
413 struct MUI_NListtree_TreeNode * tn = NULL;
415 switch((IPTR)msg->TreeNode)
417 case(MUIV_Listtree_GetNr_TreeNode_Active):
418 tn = msg->TreeNode;
419 break;
420 default:
421 tn = ((struct MUIS_Listtree_TreeNodeInt *)msg->TreeNode)->ref;
424 return DoMethod(data->nlisttree, MUIM_NListtree_GetNr, tn, msg->Flags);
427 IPTR Listtree__MUIM_Listtree_Rename(struct IClass *cl, Object *obj, struct MUIP_Listtree_Rename *msg)
429 struct Listtree_DATA *data = INST_DATA(cl, obj);
430 struct MUI_NListtree_TreeNode * tn = NULL, * renamed = NULL;
432 switch((IPTR)msg->TreeNode)
434 case(MUIV_Listtree_Rename_TreeNode_Active):
435 tn = msg->TreeNode;
436 break;
437 default:
438 tn = ((struct MUIS_Listtree_TreeNodeInt *)msg->TreeNode)->ref;
441 renamed = (struct MUI_NListtree_TreeNode *)DoMethod(data->nlisttree,
442 MUIM_NListtree_Rename, tn, msg->NewName, msg->Flags);
444 if (renamed)
446 ((struct MUIS_Listtree_TreeNode *)renamed->tn_User)->tn_Name = renamed->tn_Name;
447 return (IPTR)renamed->tn_User;
449 else
450 return (IPTR)NULL;
453 IPTR Listtree__MUIM_List_Redraw(struct IClass *cl, Object *obj, struct MUIP_List_Redraw *msg)
455 struct Listtree_DATA *data = INST_DATA(cl, obj);
456 struct MUI_NListtree_TreeNode * entry = msg->entry ?
457 ((struct MUIS_Listtree_TreeNodeInt *)msg->entry)->ref : NULL;
459 switch(msg->pos)
461 case(MUIV_List_Redraw_Entry):
462 return DoMethod(data->nlisttree, MUIM_NList_RedrawEntry, entry);
463 default:
464 return DoMethod(data->nlisttree, MUIM_NList_Redraw, msg->pos);
468 IPTR Listtree__MUIM_Listtree_Open(struct IClass *cl, Object *obj, struct MUIP_Listtree_Open *msg)
470 struct Listtree_DATA *data = INST_DATA(cl, obj);
471 struct MUI_NListtree_TreeNode * tn = NULL, * ln = NULL;
473 switch((IPTR)msg->ListNode)
475 case(MUIV_Listtree_Open_ListNode_Root):
476 case(MUIV_Listtree_Open_ListNode_Parent):
477 case(MUIV_Listtree_Open_ListNode_Active):
478 ln = msg->ListNode;
479 break;
480 default:
481 ln = ((struct MUIS_Listtree_TreeNodeInt *)msg->ListNode)->ref;
484 switch((IPTR)msg->TreeNode)
486 case(MUIV_Listtree_Open_TreeNode_Head):
487 case(MUIV_Listtree_Open_TreeNode_Tail):
488 case(MUIV_Listtree_Open_TreeNode_Active):
489 case(MUIV_Listtree_Open_TreeNode_All):
490 tn = msg->TreeNode;
491 break;
492 default:
493 tn = ((struct MUIS_Listtree_TreeNodeInt *)msg->TreeNode)->ref;
496 return DoMethod(data->nlisttree, MUIM_NListtree_Open, ln, tn, msg->Flags);
499 IPTR Listtree__MUIM_Listtree_FindName(struct IClass *cl, Object *obj, struct MUIP_Listtree_FindName *msg)
501 struct Listtree_DATA *data = INST_DATA(cl, obj);
502 struct MUI_NListtree_TreeNode * ln = NULL, * found = NULL;
504 switch((IPTR)msg->ListNode)
506 case(MUIV_Listtree_FindName_ListNode_Root):
507 case(MUIV_Listtree_FindName_ListNode_Active):
508 ln = msg->ListNode;
509 break;
510 default:
511 ln = ((struct MUIS_Listtree_TreeNodeInt *)msg->ListNode)->ref;
514 found = (struct MUI_NListtree_TreeNode *) DoMethod(data->nlisttree, MUIM_NListtree_FindName,
515 ln, msg->Name, msg->Flags);
517 if (found)
518 return (IPTR)found->tn_User;
519 else
520 return (IPTR)NULL;