2 Copyright © 2012-2015, The AROS Development Team. All rights reserved.
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>
18 #include "Listtree_mcc.h"
19 #include "listtree_private.h"
21 #include <aros/debug.h>
24 * MUIS_Listtree_Treenode -> MUI_NListtree_Treenode via MUIS_Listtree_TreeNodeInt.ref
25 * MUI_NListtree_Treenode -> MUIS_Listtree_Treenode via MUI_NListtree_Treenode.tn_User
27 struct MUIS_Listtree_TreeNodeInt
29 struct MUIS_Listtree_TreeNode base
;
30 struct MUI_NListtree_TreeNode
*ref
;
33 static IPTR
NotifySimulate_Function(struct Hook
*hook
, Object
*obj
, void ** msg
)
36 struct TagItem setti
[] = {{0,0},{TAG_DONE
, TAG_DONE
}};
38 IPTR attr
= (IPTR
)msg
[0];
39 IPTR val
= (IPTR
)msg
[1];
40 struct IClass
* cl
= hook
->h_Data
;
42 setmsg
.MethodID
= OM_SET
;
43 setmsg
.ops_AttrList
= setti
;
44 setmsg
.ops_GInfo
= NULL
;
48 case(MUIA_NListtree_Active
):
49 setti
[0].ti_Tag
= MUIA_Listtree_Active
;
50 setti
[0].ti_Data
= val
? (IPTR
)((struct MUI_NListtree_TreeNode
*)val
)->tn_User
: 0;
53 bug("[Listtree] NotifySimulate_Function - unhandled attribute %x\n", attr
);
56 /* Super method OM_SET call will go to Notify class and trigger notifications */
57 return DoSuperMethodA(cl
, obj
, (Msg
) &setmsg
);
60 static IPTR
DisplayHook_Proxy(struct Hook
*hook
, Object
*obj
, struct MUIP_NListtree_DisplayMessage
*msg
)
62 struct _temp
{ STACKED APTR array
; STACKED APTR treenode
; } t
;
63 struct Hook
* displayhook
= (struct Hook
*)hook
->h_Data
;
69 t
.treenode
= msg
->TreeNode
? msg
->TreeNode
->tn_User
: NULL
;
71 return CallHookPkt(displayhook
, t
.array
, t
.treenode
);
74 #define NEWHANDLE(attrname) \
76 bug("[Listtree] OM_NEW:%s - unsupported\n", #attrname); \
79 #define CONV(AATTR, BATTR) \
81 convtags[i].ti_Tag = BATTR; \
82 convtags[i++].ti_Data = tag->ti_Data; \
86 convtags[i].ti_Tag = TAG_DONE; \
87 convtags[i].ti_Data = TAG_DONE;
89 /*** Methods ****************************************************************/
90 Object
*Listtree__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
92 struct Listtree_DATA
*data
= NULL
;
95 Object
*nlisttree
= NULL
;
96 struct TagItem convtags
[20];
99 /* Convert tags designated for NListtree */
100 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
)); )
104 CONV(MUIA_Frame
, MUIA_Frame
)
105 CONV(MUIA_Listtree_Format
, MUIA_NListtree_Format
)
106 CONV(MUIA_Listtree_Title
, MUIA_NListtree_Title
)
107 CONV(MUIA_Listtree_DragDropSort
, MUIA_NListtree_DragDropSort
)
108 CONV(MUIA_List_Title
, MUIA_NList_Title
)
109 CONV(MUIA_List_DragSortable
, MUIA_NList_DragSortable
)
110 // CONV(MUIA_ContextMenu, MUIA_ContextMenu) // FIXME causes a crash when right clicking
111 CONV(MUIA_List_MinLineHeight
, MUIA_NList_MinLineHeight
)
117 * set up a DestructHook which will call proxy MUIS_Listtree_TreeNode destrhook and
120 obj
= (Object
*) DoSuperNewTags(cl
, obj
, 0,
121 Child
, nlisttree
= (Object
*) NListtreeObject
,
122 TAG_MORE
, (IPTR
)convtags
,
126 if (!obj
) return FALSE
;
128 data
= INST_DATA(cl
, obj
);
129 data
->nlisttree
= nlisttree
;
130 data
->notifysimulatehook
.h_Entry
= HookEntry
;
131 data
->notifysimulatehook
.h_SubEntry
= (HOOKFUNC
)NotifySimulate_Function
;
132 data
->notifysimulatehook
.h_Data
= cl
;
134 data
->pool
= CreatePool(MEMF_ANY
| MEMF_CLEAR
, 16 * 1024, 8 * 1024);
136 /* parse initial taglist */
137 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
)); )
141 case(MUIA_Listtree_ConstructHook
):
142 data
->constrhook
= (struct Hook
*)tag
->ti_Data
;
144 case(MUIA_Listtree_DestructHook
):
145 data
->destrhook
= (struct Hook
*)tag
->ti_Data
;
147 case(MUIA_Listtree_DisplayHook
):
148 data
->displayhook
= (struct Hook
*)tag
->ti_Data
;
150 case(MUIA_List_MinLineHeight
):
151 case(MUIA_ContextMenu
):
152 case(MUIA_List_DragSortable
):
153 case(MUIA_List_Title
):
154 case(MUIA_Listtree_DragDropSort
):
155 case(MUIA_Listtree_Format
):
156 case(MUIA_Listtree_Title
):
158 /* Forwarded to NListtree */
160 NEWHANDLE(MUIA_Listtree_SortHook
)
162 bug("[Listtree] OM_NEW: unhandled %x\n", tag
->ti_Tag
);
166 /* Setup hook proxies */
167 if (data
->displayhook
)
169 data
->displayhookproxy
.h_Entry
= HookEntry
;
170 data
->displayhookproxy
.h_SubEntry
= (HOOKFUNC
)DisplayHook_Proxy
;
171 data
->displayhookproxy
.h_Data
= data
->displayhook
;
172 nnset(data
->nlisttree
, MUIA_NListtree_DisplayHook
, &data
->displayhookproxy
);
175 /* Setup notification forwarding */
176 DoMethod(data
->nlisttree
, MUIM_Notify
, MUIA_NListtree_Active
, MUIV_EveryTime
,
177 obj
, 4, MUIM_CallHook
, &data
->notifysimulatehook
, MUIA_NListtree_Active
, MUIV_TriggerValue
);
182 #define SETHANDLE(attrname) \
184 bug("[Listtree] OM_SET:%s - unsupported\n", #attrname); \
187 #define FORWARDSET(AATTR, BATTR) \
189 set(data->nlisttree, BATTR, tag->ti_Data); \
192 #define IGNORESET(AATTR) case(AATTR): break;
194 IPTR
Listtree__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
196 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
197 struct TagItem
*tstate
= msg
->ops_AttrList
;
200 if (!data
->nlisttree
)
201 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
203 while ((tag
= NextTagItem(&tstate
)) != NULL
)
207 FORWARDSET(MUIA_Listtree_Quiet
, MUIA_NListtree_Quiet
)
208 FORWARDSET(MUIA_List_Active
, MUIA_NList_Active
)
210 IGNORESET(MUIA_Listview_SelectChange
)
212 case(MUIA_Listtree_Active
):
213 set(data
->nlisttree
, MUIA_NListtree_Active
,
214 ((struct MUIS_Listtree_TreeNodeInt
*)tag
->ti_Data
)->ref
);
217 SETHANDLE(MUIA_Listtree_DoubleClick
)
218 case MUIB_List
| 0x00000010: break;
219 case MUIA_Prop_First
: break;
220 case MUIA_Prop_DoSmooth
: break;
221 case MUIA_NoNotify
: break;
222 case MUIA_Prop_Entries
: break;
223 case MUIA_Prop_Visible
: break;
224 case MUIA_Prop_DeltaFactor
: break;
226 bug("[Listtree] OM_SET: passing to parent class %x\n", tag
->ti_Tag
);
231 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
234 #define GETHANDLE(attrname) \
236 bug("[Listtree] OM_GET:%s - unsupported\n", #attrname); \
240 #define MUIA_List_Prop_Entries /* PRIV */ \
241 (MUIB_MUI | 0x0042a8f5) /* .sg LONG PRIV */
242 #define MUIA_List_Prop_Visible /* PRIV */ \
243 (MUIB_MUI | 0x004273e9) /* .sg LONG PRIV */
244 #define MUIA_List_Prop_First /* PRIV */ \
245 (MUIB_MUI | 0x00429df3) /* .sg LONG PRIV */
247 #define MUIA_List_VertProp_Entries /* PRIV */ \
248 MUIA_List_Prop_Entries /* PRIV */
249 #define MUIA_List_VertProp_Visible /* PRIV */ \
250 MUIA_List_Prop_Visible /* PRIV */
251 #define MUIA_List_VertProp_First /* PRIV */ \
252 MUIA_List_Prop_First /* PRIV */
254 #define FORWARDGET(AATTR, BATTR) \
256 *(msg->opg_Storage) = XGET(data->nlisttree, BATTR); \
259 IPTR
Listtree__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
261 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
263 if (!data
->nlisttree
)
266 switch (msg
->opg_AttrID
)
268 FORWARDGET(MUIA_Frame
, MUIA_Frame
)
269 FORWARDGET(MUIA_Listtree_DoubleClick
, MUIA_NListtree_DoubleClick
)
270 FORWARDGET(MUIA_List_Active
, MUIA_NList_Active
)
271 FORWARDGET(MUIA_Listtree_Active
, MUIA_NListtree_Active
)
272 FORWARDGET(MUIA_Listtree_Quiet
, MUIA_NListtree_Quiet
)
273 FORWARDGET(MUIA_List_Visible
, MUIA_NList_Visible
)
275 GETHANDLE(MUIA_List_VertProp_Entries
)
276 GETHANDLE(MUIA_List_VertProp_Visible
)
277 GETHANDLE(MUIA_List_VertProp_First
)
278 case MUIA_Disabled
: break;
279 case MUIA_Parent
: break;
280 case MUIA_Group_ChildList
: break;
281 case MUIA_Prop_First
: break;
282 case MUIA_Prop_DoSmooth
: break;
283 case MUIA_Listview_List
: break;
284 case MUIA_Virtgroup_Left
: break;
285 case MUIA_Virtgroup_Top
: break;
286 case 0x9d510020 /*MUIA_NListview_NList*/: break;
288 bug("[Listtree] OM_GET: passing to parent class %x\n", msg
->opg_AttrID
);
291 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
294 #define METHODSTUB(methodname) \
295 IPTR Listtree__##methodname(struct IClass *cl, Object *obj, Msg msg) \
297 bug("[Listtree] Usupported : %s\n", #methodname); \
298 return (IPTR)FALSE; \
301 METHODSTUB(MUIM_Listtree_Close
)
302 METHODSTUB(MUIM_Listtree_SetDropMark
)
304 IPTR
Listtree__MUIM_Listtree_Insert(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_Insert
*msg
)
306 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
307 struct MUIS_Listtree_TreeNodeInt
* _int
= AllocPooled(data
->pool
, sizeof(struct MUIS_Listtree_TreeNodeInt
));
308 struct MUIS_Listtree_TreeNode
* _return
= NULL
;
309 struct MUI_NListtree_TreeNode
* ln
= NULL
, * pn
= NULL
;
314 _return
= &_int
->base
;
316 _return
->tn_Flags
= (UWORD
)msg
->Flags
;
317 if (data
->constrhook
)
318 _return
->tn_User
= (APTR
)CallHookPkt(data
->constrhook
, data
->pool
, msg
->User
);
320 _return
->tn_User
= msg
->User
;
322 switch((IPTR
)msg
->ListNode
)
324 case(MUIV_Listtree_Insert_ListNode_Root
):
325 case(MUIV_Listtree_Insert_ListNode_Active
):
329 ln
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->ListNode
)->ref
;
332 switch((IPTR
)msg
->PrevNode
)
334 case(MUIV_Listtree_Insert_PrevNode_Head
):
335 case(MUIV_Listtree_Insert_PrevNode_Tail
):
336 case(MUIV_Listtree_Insert_PrevNode_Active
):
337 case(MUIV_Listtree_Insert_PrevNode_Sorted
):
341 pn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->PrevNode
)->ref
;
344 _int
->ref
= (struct MUI_NListtree_TreeNode
*)DoMethod(data
->nlisttree
,
345 MUIM_NListtree_Insert
, msg
->Name
, _return
, ln
, pn
, msg
->Flags
);
347 _return
->tn_Name
= _int
->ref
->tn_Name
;
349 return (IPTR
)_return
;
352 IPTR
Listtree__MUIM_Listtree_GetEntry(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_GetEntry
*msg
)
354 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
355 struct MUI_NListtree_TreeNode
* tn
= NULL
, * found
= NULL
;
357 switch ((IPTR
)msg
->Node
)
359 case(MUIV_Listtree_GetEntry_ListNode_Root
):
360 case(MUIV_Listtree_GetEntry_ListNode_Active
):
364 tn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->Node
)->ref
;
367 found
= (struct MUI_NListtree_TreeNode
*) DoMethod(data
->nlisttree
,
368 MUIM_NListtree_GetEntry
, tn
, msg
->Position
, msg
->Flags
);
371 return (IPTR
)found
->tn_User
;
376 IPTR
Listtree__MUIM_Listtree_Remove(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_Remove
*msg
)
378 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
380 /* TODO: handle remaining enumeration values */
381 if ((msg
->ListNode
== (APTR
)MUIV_Listtree_Remove_ListNode_Root
) &&
382 ((msg
->TreeNode
== (APTR
)MUIV_Listtree_Remove_TreeNode_Active
) ||
383 (msg
->TreeNode
== (APTR
)MUIV_Listtree_Remove_TreeNode_All
)))
385 /* Deallocating of MUIS_Listtree_TreeNode is happening in the DestructHook */
386 return DoMethod(data
->nlisttree
, MUIM_NListtree_Remove
, msg
->ListNode
, msg
->TreeNode
, msg
->Flags
);
390 * add handling for cases where ListNode/TreeNode actually point to Treenode structure
392 bug("[Listtree] MUIM_Listtree_Remove unsupported code path Listnode: %x, Treenode: %x, Flags: %d\n", msg
->ListNode
, msg
->TreeNode
, msg
->Flags
);
397 IPTR
Listtree__MUIM_List_TestPos(struct IClass
*cl
, Object
*obj
, struct MUIP_List_TestPos
*msg
)
399 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
401 struct MUI_NList_TestPos_Result res
;
402 if (DoMethod(data
->nlisttree
, MUIM_List_TestPos
, msg
->x
, msg
->y
, &res
))
404 msg
->res
->entry
= res
.entry
;
405 msg
->res
->column
= res
.column
;
406 msg
->res
->flags
= res
.flags
;
407 msg
->res
->xoffset
= res
.xoffset
;
408 msg
->res
->yoffset
= res
.yoffset
;
415 IPTR
Listtree__MUIM_Listtree_TestPos(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_TestPos
*msg
)
417 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
419 struct MUI_NListtree_TestPos_Result res
;
420 struct MUIS_Listtree_TestPos_Result
* _ret
= (struct MUIS_Listtree_TestPos_Result
*)msg
->Result
;
422 _ret
->tpr_TreeNode
= NULL
;
424 DoMethod(data
->nlisttree
, MUIM_NListtree_TestPos
, msg
->X
, msg
->Y
, &res
);
426 _ret
->tpr_Flags
= res
.tpr_Type
;
427 _ret
->tpr_ListEntry
= res
.tpr_ListEntry
;
428 _ret
->tpr_ListFlags
= res
.tpr_ListFlags
;
430 if (res
.tpr_TreeNode
!= NULL
)
432 _ret
->tpr_TreeNode
= res
.tpr_TreeNode
->tn_User
;
439 IPTR
Listtree__MUIM_Listtree_GetNr(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_GetNr
*msg
)
441 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
442 struct MUI_NListtree_TreeNode
* tn
= NULL
;
444 switch((IPTR
)msg
->TreeNode
)
446 case(MUIV_Listtree_GetNr_TreeNode_Active
):
450 tn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->TreeNode
)->ref
;
453 return DoMethod(data
->nlisttree
, MUIM_NListtree_GetNr
, tn
, msg
->Flags
);
456 IPTR
Listtree__MUIM_Listtree_Rename(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_Rename
*msg
)
458 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
459 struct MUI_NListtree_TreeNode
* tn
= NULL
, * renamed
= NULL
;
461 switch((IPTR
)msg
->TreeNode
)
463 case(MUIV_Listtree_Rename_TreeNode_Active
):
467 tn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->TreeNode
)->ref
;
470 renamed
= (struct MUI_NListtree_TreeNode
*)DoMethod(data
->nlisttree
,
471 MUIM_NListtree_Rename
, tn
, msg
->NewName
, msg
->Flags
);
475 ((struct MUIS_Listtree_TreeNode
*)renamed
->tn_User
)->tn_Name
= renamed
->tn_Name
;
476 return (IPTR
)renamed
->tn_User
;
482 IPTR
Listtree__MUIM_List_Redraw(struct IClass
*cl
, Object
*obj
, struct MUIP_List_Redraw
*msg
)
484 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
485 struct MUI_NListtree_TreeNode
* entry
= msg
->entry
?
486 ((struct MUIS_Listtree_TreeNodeInt
*)msg
->entry
)->ref
: NULL
;
490 case(MUIV_List_Redraw_Entry
):
491 return DoMethod(data
->nlisttree
, MUIM_NList_RedrawEntry
, entry
);
493 return DoMethod(data
->nlisttree
, MUIM_NList_Redraw
, msg
->pos
);
497 IPTR
Listtree__MUIM_Listtree_Open(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_Open
*msg
)
499 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
500 struct MUI_NListtree_TreeNode
* tn
= NULL
, * ln
= NULL
;
502 switch((IPTR
)msg
->ListNode
)
504 case(MUIV_Listtree_Open_ListNode_Root
):
505 case(MUIV_Listtree_Open_ListNode_Parent
):
506 case(MUIV_Listtree_Open_ListNode_Active
):
510 ln
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->ListNode
)->ref
;
513 switch((IPTR
)msg
->TreeNode
)
515 case(MUIV_Listtree_Open_TreeNode_Head
):
516 case(MUIV_Listtree_Open_TreeNode_Tail
):
517 case(MUIV_Listtree_Open_TreeNode_Active
):
518 case(MUIV_Listtree_Open_TreeNode_All
):
522 tn
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->TreeNode
)->ref
;
525 return DoMethod(data
->nlisttree
, MUIM_NListtree_Open
, ln
, tn
, msg
->Flags
);
528 IPTR
Listtree__MUIM_Listtree_FindName(struct IClass
*cl
, Object
*obj
, struct MUIP_Listtree_FindName
*msg
)
530 struct Listtree_DATA
*data
= INST_DATA(cl
, obj
);
531 struct MUI_NListtree_TreeNode
* ln
= NULL
, * found
= NULL
;
533 switch((IPTR
)msg
->ListNode
)
535 case(MUIV_Listtree_FindName_ListNode_Root
):
536 case(MUIV_Listtree_FindName_ListNode_Active
):
540 ln
= ((struct MUIS_Listtree_TreeNodeInt
*)msg
->ListNode
)->ref
;
543 found
= (struct MUI_NListtree_TreeNode
*) DoMethod(data
->nlisttree
, MUIM_NListtree_FindName
,
544 ln
, msg
->Name
, msg
->Flags
);
547 return (IPTR
)found
->tn_User
;