Listtree.mcc: implement Listtree_Rename
[AROS.git] / workbench / classes / zune / listtree / listtree.c
blob052b0011ded9fc0a567245125401203909b08b3f
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 = (IPTR)((struct MUI_NListtree_TreeNode *)val)->tn_User;
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_Open)
273 METHODSTUB(MUIM_Listtree_Close)
274 METHODSTUB(MUIM_Listtree_SetDropMark)
275 METHODSTUB(MUIM_Listtree_FindName)
277 IPTR Listtree__MUIM_Listtree_Insert(struct IClass *cl, Object *obj, struct MUIP_Listtree_Insert *msg)
279 struct Listtree_DATA *data = INST_DATA(cl, obj);
280 struct MUIS_Listtree_TreeNodeInt * _int = AllocPooled(data->pool, sizeof(struct MUIS_Listtree_TreeNodeInt));
281 struct MUIS_Listtree_TreeNode * _return = NULL;
282 struct MUI_NListtree_TreeNode * ln = NULL, * pn = NULL;
284 if (_int == NULL)
285 return (IPTR)NULL;
287 _return = &_int->base;
289 _return->tn_Flags = (UWORD)msg->Flags;
290 if (data->constrhook)
291 _return->tn_User = (APTR)CallHookPkt(data->constrhook, data->pool, msg->User);
292 else
293 _return->tn_User = msg->User;
295 switch((IPTR)msg->ListNode)
297 case(MUIV_Listtree_Insert_ListNode_Root):
298 case(MUIV_Listtree_Insert_ListNode_Active):
299 ln = msg->ListNode;
300 break;
301 default:
302 ln = ((struct MUIS_Listtree_TreeNodeInt *)msg->ListNode)->ref;
305 switch((IPTR)msg->PrevNode)
307 case(MUIV_Listtree_Insert_PrevNode_Head):
308 case(MUIV_Listtree_Insert_PrevNode_Tail):
309 case(MUIV_Listtree_Insert_PrevNode_Active):
310 case(MUIV_Listtree_Insert_PrevNode_Sorted):
311 pn = msg->PrevNode;
312 break;
313 default:
314 pn = ((struct MUIS_Listtree_TreeNodeInt *)msg->PrevNode)->ref;
317 _int->ref = (struct MUI_NListtree_TreeNode *)DoMethod(data->nlisttree,
318 MUIM_NListtree_Insert, msg->Name, _return, ln, pn, msg->Flags);
320 _return->tn_Name = _int->ref->tn_Name;
322 return (IPTR)_return;
325 IPTR Listtree__MUIM_Listtree_GetEntry(struct IClass *cl, Object *obj, struct MUIP_Listtree_GetEntry *msg)
327 struct Listtree_DATA *data = INST_DATA(cl, obj);
328 struct MUI_NListtree_TreeNode * n = NULL;
330 switch ((IPTR)msg->Node)
332 case(MUIV_Listtree_GetEntry_ListNode_Root):
333 case(MUIV_Listtree_GetEntry_ListNode_Active):
334 n = msg->Node;
335 break;
336 default:
337 n = ((struct MUIS_Listtree_TreeNodeInt *)msg->Node)->ref;
340 struct MUI_NListtree_TreeNode * tn = (struct MUI_NListtree_TreeNode *) DoMethod(data->nlisttree,
341 MUIM_NListtree_GetEntry, n, msg->Position, msg->Flags);
343 if (tn)
344 return (IPTR)tn->tn_User;
345 else
346 return (IPTR)NULL;
349 IPTR Listtree__MUIM_Listtree_Remove(struct IClass *cl, Object *obj, struct MUIP_Listtree_Remove *msg)
351 struct Listtree_DATA *data = INST_DATA(cl, obj);
353 /* TODO: handle remaining enumeration values */
354 if ((msg->ListNode == (APTR)MUIV_Listtree_Remove_ListNode_Root) &&
355 ((msg->TreeNode == (APTR)MUIV_Listtree_Remove_TreeNode_Active) ||
356 (msg->TreeNode == (APTR)MUIV_Listtree_Remove_TreeNode_All)))
358 /* Deallocating of MUIS_Listtree_TreeNode is happening in the DestructHook */
359 return DoMethod(data->nlisttree, MUIM_NListtree_Remove, msg->ListNode, msg->TreeNode, msg->Flags);
362 /* TODO
363 * add handling for cases where ListNode/TreeNode actually point to Treenode structure
365 bug("[Listtree] MUIM_Listtree_Remove unsupported code path Listnode: %x, Treenode: %x, Flags: %d\n", msg->ListNode, msg->TreeNode, msg->Flags);
367 return (IPTR)FALSE;
370 IPTR Listtree__MUIM_List_TestPos(struct IClass *cl, Object *obj, struct MUIP_List_TestPos *msg)
372 struct Listtree_DATA *data = INST_DATA(cl, obj);
374 struct MUI_NList_TestPos_Result res;
375 if (DoMethod(data->nlisttree, MUIM_List_TestPos, msg->x, msg->y, &res))
377 msg->res->entry = res.entry;
378 msg->res->column = res.column;
379 msg->res->flags = res.flags;
380 msg->res->xoffset = res.xoffset;
381 msg->res->yoffset = res.yoffset;
382 return TRUE;
385 return FALSE;
388 IPTR Listtree__MUIM_Listtree_TestPos(struct IClass *cl, Object *obj, struct MUIP_Listtree_TestPos *msg)
390 struct Listtree_DATA *data = INST_DATA(cl, obj);
392 struct MUI_NListtree_TestPos_Result res;
393 struct MUIS_Listtree_TestPos_Result * _ret = (struct MUIS_Listtree_TestPos_Result *)msg->Result;
395 _ret->tpr_TreeNode = NULL;
397 DoMethod(data->nlisttree, MUIM_NListtree_TestPos, msg->X, msg->Y, &res);
399 _ret->tpr_Flags = res.tpr_Type;
400 _ret->tpr_ListEntry = res.tpr_ListEntry;
401 _ret->tpr_ListFlags = res.tpr_ListFlags;
403 if (res.tpr_TreeNode != NULL)
405 _ret->tpr_TreeNode = res.tpr_TreeNode->tn_User;
406 return TRUE;
409 return FALSE;
412 IPTR Listtree__MUIM_Listtree_GetNr(struct IClass *cl, Object *obj, struct MUIP_Listtree_GetNr *msg)
414 struct Listtree_DATA *data = INST_DATA(cl, obj);
415 struct MUI_NListtree_TreeNode * tn = NULL;
417 switch((IPTR)msg->TreeNode)
419 case(MUIV_Listtree_GetNr_TreeNode_Active):
420 tn = msg->TreeNode;
421 break;
422 default:
423 tn = ((struct MUIS_Listtree_TreeNodeInt *)msg->TreeNode)->ref;
426 return DoMethod(data->nlisttree, MUIM_NListtree_GetNr, tn, msg->Flags);
429 IPTR Listtree__MUIM_Listtree_Rename(struct IClass *cl, Object *obj, struct MUIP_Listtree_Rename *msg)
431 struct Listtree_DATA *data = INST_DATA(cl, obj);
432 struct MUI_NListtree_TreeNode * tn = NULL, * renamed = NULL;
434 switch((IPTR)msg->TreeNode)
436 case(MUIV_Listtree_Rename_TreeNode_Active):
437 tn = msg->TreeNode;
438 break;
439 default:
440 tn = ((struct MUIS_Listtree_TreeNodeInt *)msg->TreeNode)->ref;
443 renamed = (struct MUI_NListtree_TreeNode *)DoMethod(data->nlisttree,
444 MUIM_NListtree_Rename, tn, msg->NewName, msg->Flags);
446 if (renamed)
448 ((struct MUIS_Listtree_TreeNode *)renamed->tn_User)->tn_Name = renamed->tn_Name;
449 return (IPTR)renamed->tn_User;
451 else
452 return (IPTR)NULL;