Listtree.mcc: simulate triggeting notifications for Listtree_Active attribute
[AROS.git] / workbench / classes / zune / listtree / listtree.c
blob877554422737a265860782c066477fe4edb73b4e
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_Rename)
273 METHODSTUB(MUIM_Listtree_Open)
274 METHODSTUB(MUIM_Listtree_Close)
275 METHODSTUB(MUIM_Listtree_SetDropMark)
276 METHODSTUB(MUIM_Listtree_FindName)
278 IPTR Listtree__MUIM_Listtree_Insert(struct IClass *cl, Object *obj, struct MUIP_Listtree_Insert *msg)
280 struct Listtree_DATA *data = INST_DATA(cl, obj);
281 struct MUIS_Listtree_TreeNodeInt * _int = AllocPooled(data->pool, sizeof(struct MUIS_Listtree_TreeNodeInt));
282 struct MUIS_Listtree_TreeNode * _return = NULL;
283 struct MUI_NListtree_TreeNode * ln = NULL, * pn = NULL;
285 if (_int == NULL)
286 return (IPTR)NULL;
288 _return = &_int->base;
290 _return->tn_Flags = (UWORD)msg->Flags;
291 if (msg->Name)
293 LONG len = strlen(msg->Name) + 1;
294 _return->tn_Name = AllocPooled(data->pool, len);
295 CopyMem(msg->Name, _return->tn_Name, len);
298 if (data->constrhook)
299 _return->tn_User = (APTR)CallHookPkt(data->constrhook, data->pool, msg->User);
300 else
301 _return->tn_User = msg->User;
303 switch((IPTR)msg->ListNode)
305 case(MUIV_Listtree_Insert_ListNode_Root):
306 case(MUIV_Listtree_Insert_ListNode_Active):
307 ln = msg->ListNode;
308 break;
309 default:
310 ln = ((struct MUIS_Listtree_TreeNodeInt *)msg->ListNode)->ref;
313 switch((IPTR)msg->PrevNode)
315 case(MUIV_Listtree_Insert_PrevNode_Head):
316 case(MUIV_Listtree_Insert_PrevNode_Tail):
317 case(MUIV_Listtree_Insert_PrevNode_Active):
318 case(MUIV_Listtree_Insert_PrevNode_Sorted):
319 pn = msg->PrevNode;
320 break;
321 default:
322 pn = ((struct MUIS_Listtree_TreeNodeInt *)msg->PrevNode)->ref;
325 _int->ref = (struct MUI_NListtree_TreeNode *)DoMethod(data->nlisttree,
326 MUIM_NListtree_Insert, msg->Name, _return, ln, pn, msg->Flags);
328 return (IPTR)_return;
331 IPTR Listtree__MUIM_Listtree_GetEntry(struct IClass *cl, Object *obj, struct MUIP_Listtree_GetEntry *msg)
333 struct Listtree_DATA *data = INST_DATA(cl, obj);
334 struct MUI_NListtree_TreeNode * n = NULL;
336 switch ((IPTR)msg->Node)
338 case(MUIV_Listtree_GetEntry_ListNode_Root):
339 case(MUIV_Listtree_GetEntry_ListNode_Active):
340 n = msg->Node;
341 break;
342 default:
343 n = ((struct MUIS_Listtree_TreeNodeInt *)msg->Node)->ref;
346 struct MUI_NListtree_TreeNode * tn = (struct MUI_NListtree_TreeNode *) DoMethod(data->nlisttree,
347 MUIM_NListtree_GetEntry, n, msg->Position, msg->Flags);
349 if (tn)
350 return (IPTR)tn->tn_User;
351 else
352 return (IPTR)NULL;
355 IPTR Listtree__MUIM_Listtree_Remove(struct IClass *cl, Object *obj, struct MUIP_Listtree_Remove *msg)
357 struct Listtree_DATA *data = INST_DATA(cl, obj);
359 /* TODO: handle remaining enumeration values */
360 if ((msg->ListNode == (APTR)MUIV_Listtree_Remove_ListNode_Root) &&
361 ((msg->TreeNode == (APTR)MUIV_Listtree_Remove_TreeNode_Active) ||
362 (msg->TreeNode == (APTR)MUIV_Listtree_Remove_TreeNode_All)))
364 /* Deallocating of MUIS_Listtree_TreeNode is happening in the DestructHook */
365 return DoMethod(data->nlisttree, MUIM_NListtree_Remove, msg->ListNode, msg->TreeNode, msg->Flags);
368 /* TODO
369 * add handling for cases where ListNode/TreeNode actually point to Treenode structure
371 bug("[Listtree] MUIM_Listtree_Remove unsupported code path Listnode: %x, Treenode: %x, Flags: %d\n", msg->ListNode, msg->TreeNode, msg->Flags);
373 return (IPTR)FALSE;
376 IPTR Listtree__MUIM_List_TestPos(struct IClass *cl, Object *obj, struct MUIP_List_TestPos *msg)
378 struct Listtree_DATA *data = INST_DATA(cl, obj);
380 struct MUI_NList_TestPos_Result res;
381 if (DoMethod(data->nlisttree, MUIM_List_TestPos, msg->x, msg->y, &res))
383 msg->res->entry = res.entry;
384 msg->res->column = res.column;
385 msg->res->flags = res.flags;
386 msg->res->xoffset = res.xoffset;
387 msg->res->yoffset = res.yoffset;
388 return TRUE;
391 return FALSE;
394 IPTR Listtree__MUIM_Listtree_TestPos(struct IClass *cl, Object *obj, struct MUIP_Listtree_TestPos *msg)
396 struct Listtree_DATA *data = INST_DATA(cl, obj);
398 struct MUI_NListtree_TestPos_Result res;
399 struct MUIS_Listtree_TestPos_Result * _ret = (struct MUIS_Listtree_TestPos_Result *)msg->Result;
401 _ret->tpr_TreeNode = NULL;
403 DoMethod(data->nlisttree, MUIM_NListtree_TestPos, msg->X, msg->Y, &res);
405 _ret->tpr_Flags = res.tpr_Type;
406 _ret->tpr_ListEntry = res.tpr_ListEntry;
407 _ret->tpr_ListFlags = res.tpr_ListFlags;
409 if (res.tpr_TreeNode != NULL)
411 _ret->tpr_TreeNode = res.tpr_TreeNode->tn_User;
412 return TRUE;
415 return FALSE;
418 IPTR Listtree__MUIM_Listtree_GetNr(struct IClass *cl, Object *obj, struct MUIP_Listtree_GetNr *msg)
420 struct Listtree_DATA *data = INST_DATA(cl, obj);
421 struct MUI_NListtree_TreeNode * tn = NULL;
423 switch((IPTR)msg->TreeNode)
425 case(MUIV_Listtree_GetNr_TreeNode_Active):
426 tn = msg->TreeNode;
427 break;
428 default:
429 tn = ((struct MUIS_Listtree_TreeNodeInt *)msg->TreeNode)->ref;
432 return DoMethod(data->nlisttree, MUIM_NListtree_GetNr, tn, msg->Flags);