4 * BGUI Tree List View class
6 * (C) Copyright 1999 Manuel Lemos.
7 * (C) Copyright 1996-1999 Nick Christie.
11 * Revision 42.3 2004/06/16 20:16:49 verhaegs
12 * Use METHODPROTO, METHOD_END and REGFUNCPROTOn where needed.
14 * Revision 42.2 2004/03/24 12:40:28 stegerg
15 * Real bug fix (not AROS related): in dispose method
16 * do LVM_CLEAR method on listview, because otherwise
17 * the superclass (listclass) might try to access
18 * the resource hook, although treeview class already
19 * has freed that hook, before making the DoSuperMethodA
22 * Revision 42.1 2000/05/15 19:29:08 stegerg
23 * replacements for REG macro
25 * Revision 42.0 2000/05/09 22:21:55 mlemos
26 * Bumped to revision 42.0 before handing BGUI to AROS team
28 * Revision 41.11 2000/05/09 20:35:42 mlemos
29 * Bumped to revision 41.11
31 * Revision 1.2 2000/05/09 20:00:40 mlemos
32 * Merged with the branch Manuel_Lemos_fixes.
34 * Revision 1.1.2.3 1999/05/31 01:17:13 mlemos
35 * Made the method functions take the arguments in the apropriate registers.
36 * Ensured that the bgui.library only remains opened while there are any
37 * outstanding instances.
39 * Revision 1.1.2.2 1999/05/24 23:59:43 mlemos
40 * Corrected the declaration of SysBase.
42 * Revision 1.1.2.1 1999/02/21 04:07:55 mlemos
43 * Nick Christie sources.
49 /************************************************************************
50 ********************* TREEVIEW CLASS: NEW/DISPOSE *********************
51 ************************************************************************/
53 /************************************************************************
54 ****************************** INCLUDES *******************************
55 ************************************************************************/
57 #include "TreeViewPrivate.h"
60 /************************************************************************
61 ************************** LOCAL DEFINITIONS **************************
62 ************************************************************************/
65 /************************************************************************
66 ************************* EXTERNAL REFERENCES *************************
67 ************************************************************************/
70 * Functions from TVLVHandlers:
73 //extern ASM SAVEDS ULONG TV_LVRsrcHandler(REG(a0) struct Hook *hook,
74 // REG(a2) Object *obj, REG(a1) struct lvResource *lvr);
75 extern ASM SAVEDS
REGFUNCPROTO3(ULONG
, TV_LVRsrcHandler
,
76 REGPARAM(A0
, struct Hook
*, hook
),
77 REGPARAM(A2
, Object
*, obj
),
78 REGPARAM(A1
, struct lvResource
*, lvr
));
80 //extern ASM SAVEDS ULONG TV_LVDispHandler(REG(a0) struct Hook *hook,
81 // REG(a2) Object *obj, REG(a1) struct lvRender *lvr);
82 extern ASM SAVEDS
REGFUNCPROTO3(ULONG
, TV_LVDispHandler
,
83 REGPARAM(A0
, struct Hook
*, hook
),
84 REGPARAM(A2
, Object
*, obj
),
85 REGPARAM(A1
, struct lvRender
*, lvr
));
87 //extern ASM SAVEDS ULONG TV_LVCompHandler(REG(a0) struct Hook *hook,
88 // REG(a2) Object *obj, REG(a1) struct lvCompare *lvc);
89 extern ASM SAVEDS
REGFUNCPROTO3(ULONG
, TV_LVCompHandler
,
90 REGPARAM(A0
, struct Hook
*, hook
),
91 REGPARAM(A2
, Object
*, obj
),
92 REGPARAM(A1
, struct lvCompare
*, lvc
));
94 //extern ASM SAVEDS ULONG TV_LVNotifyHandler(REG(a0) struct Hook *hook,
95 // REG(a2) Object *obj, REG(a1) struct opUpdate *opu);
96 extern ASM SAVEDS
REGFUNCPROTO3(ULONG
, TV_LVNotifyHandler
,
97 REGPARAM(A0
, struct Hook
*, hook
),
98 REGPARAM(A2
, Object
*, obj
),
99 REGPARAM(A1
, struct opUpdate
*, opu
));
102 * Functions from TVUtil are listed in TVUtil.h
106 * Data from startup module
109 extern struct ExecBase
*SysBase
;
111 /************************************************************************
112 ***************************** PROTOTYPES ******************************
113 ************************************************************************/
115 LOCAL ASM SAVEDS
REGFUNCPROTO3(IPTR
, TV_TVRsrcHandler
,
116 REGPARAM(A0
, struct Hook
*, hook
),
117 REGPARAM(A2
, Object
*, obj
),
118 REGPARAM(A1
, struct tvResource
*, tvr
));
120 LOCAL ASM SAVEDS
REGFUNCPROTO3(IPTR
, TV_TVDispHandler
,
121 REGPARAM(A0
, struct Hook
*, hook
),
122 REGPARAM(A2
, Object
*, obj
),
123 REGPARAM(A1
, struct tvRender
*, tvr
));
125 LOCAL ASM SAVEDS
REGFUNCPROTO3(IPTR
, TV_TVCompHandler
,
126 REGPARAM(A0
, struct Hook
*, hook
),
127 REGPARAM(A2
, Object
*, obj
),
128 REGPARAM(A1
, struct tvCompare
*, tvc
));
130 LOCAL ASM SAVEDS
REGFUNCPROTO3(IPTR
, TV_TVExpandHandler
,
131 REGPARAM(A0
, struct Hook
*, hook
),
132 REGPARAM(A2
, Object
*, obj
),
133 REGPARAM(A1
, struct tvExpand
*, tve
));
135 /************************************************************************
136 ***************************** LOCAL DATA ******************************
137 ************************************************************************/
140 * Vector item data for the built-in expanded and contracted node images
143 LOCAL
struct VectorItem BoxPlusVector
[] = {
153 { 6,4,VIF_DRAW
|VIF_LASTITEM
},
156 LOCAL
struct VectorItem BoxMinusVector
[] = {
164 { 6,4,VIF_DRAW
|VIF_LASTITEM
},
167 LOCAL
struct VectorItem ArrowRightVector
[] = {
169 { 2,0,VIF_MOVE
|VIF_AREASTART
, },
172 { 2,0,VIF_DRAW
|VIF_AREAEND
|VIF_LASTITEM
},
175 LOCAL
struct VectorItem ArrowDownVector
[] = {
177 { 0,2,VIF_MOVE
|VIF_AREASTART
, },
180 { 0,2,VIF_DRAW
|VIF_AREAEND
|VIF_LASTITEM
},
183 static ULONG instances
=0;
185 /************************************************************************
186 ****************************** TV_NEW() *******************************
187 *************************************************************************
188 * Handle OM_NEW: create and return a new object. Supply our class ptr,
189 * object ptr and initial attributes. Returns the new object or NULL
192 *************************************************************************/
194 METHOD(TV_New
,struct opSet
*, ops
)
196 struct TagItem
*tags
;
197 struct VectorItem
*expvi
,*convi
;
199 HOOKPTR lvrsrchk
,lvdisphk
,lvcomphk
,lvnotihk
;
200 HOOKPTR tvrsrchk
,tvdisphk
,tvcomphk
,tvexpahk
;
204 && (BGUIBase
=OpenLibrary("bgui.library",41))==NULL
)
207 lvrsrchk
= lvdisphk
= lvcomphk
= lvnotihk
= NULL
;
208 tvrsrchk
= tvdisphk
= tvcomphk
= tvexpahk
= NULL
;
209 tags
= ops
->ops_AttrList
;
213 * Allocate and initialise a bunch of hook structures for
214 * the embedded listview object as well as ourselves.
217 if ( (lvrsrchk
= TV_AllocHook((HOOKFUNC
) TV_LVRsrcHandler
,NULL
)) &&
218 (lvdisphk
= TV_AllocHook((HOOKFUNC
) TV_LVDispHandler
,NULL
)) &&
219 (lvcomphk
= TV_AllocHook((HOOKFUNC
) TV_LVCompHandler
,NULL
)) &&
220 (lvnotihk
= TV_AllocHook((HOOKFUNC
) TV_LVNotifyHandler
,NULL
)) &&
221 (tvrsrchk
= TV_AllocHook((HOOKFUNC
) TV_TVRsrcHandler
,NULL
)) &&
222 (tvdisphk
= TV_AllocHook((HOOKFUNC
) TV_TVDispHandler
,NULL
)) &&
223 (tvcomphk
= TV_AllocHook((HOOKFUNC
) TV_TVCompHandler
,NULL
)) &&
224 (tvexpahk
= TV_AllocHook((HOOKFUNC
) TV_TVExpandHandler
,NULL
))
228 * Create a group containing just the listview. Let some
229 * acceptable listview tags through to the embedded object.
232 if ((rc
= TV_DoSuperNew(cl
,obj
,
234 lvobj
= ListviewObject
,
235 LISTV_ResourceHook
, lvrsrchk
,
236 LISTV_DisplayHook
, lvdisphk
,
237 LISTV_CompareHook
, lvcomphk
,
238 LISTV_ListFont
, GetTagData(LISTV_ListFont
,(IPTR
)NULL
,tags
),
239 LISTV_MinEntriesShown
, GetTagData(LISTV_MinEntriesShown
,3,tags
),
240 LISTV_MultiSelect
, GetTagData(LISTV_MultiSelect
,FALSE
,tags
),
241 LISTV_MultiSelectNoShift
,GetTagData(LISTV_MultiSelectNoShift
,FALSE
,tags
),
242 LISTV_ReadOnly
, GetTagData(LISTV_ReadOnly
,FALSE
,tags
),
243 LISTV_ThinFrames
, GetTagData(LISTV_ThinFrames
,FALSE
,tags
),
244 PGA_NewLook
, GetTagData(PGA_NewLook
,FALSE
,tags
),
245 GA_ID
, GetTagData(GA_ID
,(IPTR
)NULL
,tags
),
256 * Get a ptr to our instance data and clear it
259 tv
= (TVData
*) INST_DATA(cl
,rc
);
260 memset(tv
,0,sizeof(TVData
));
263 * Initialise the root node.
266 NewList(RootList(tv
));
267 tv
->tv_RootNode
.tn_Flags
= TNF_EXPANDED
;
270 * If the OS is >= V39, create a private
271 * memory pool for allocating treenodes in
274 if (((struct Library
*) SysBase
)->lib_Version
>= 39)
275 tv
->tv_MemPool
= CreatePool(MEMF_STD
,2048,768);
278 * Useful in hook functions to have reverse references
279 * from the instance data back to the class/object:
282 tv
->tv_TreeView
= (Object
*) rc
;
283 tv
->tv_TreeViewClass
= cl
;
286 * Transfer the ptrs to allocated listview hooks into the
287 * object's instance data, then clear the original pointers.
288 * Also place a ptr to the object instance data in the hooks.
291 tv
->tv_LVRsrcHook
= lvrsrchk
;
292 tv
->tv_LVRsrcHook
->h_Data
= (APTR
) tv
;
293 tv
->tv_LVDispHook
= lvdisphk
;
294 tv
->tv_LVDispHook
->h_Data
= (APTR
) tv
;
295 tv
->tv_LVCompHook
= lvcomphk
;
296 tv
->tv_LVCompHook
->h_Data
= (APTR
) tv
;
297 tv
->tv_LVNotifyHook
= lvnotihk
;
298 tv
->tv_LVNotifyHook
->h_Data
= (APTR
) tv
;
299 lvrsrchk
= lvdisphk
= lvcomphk
= lvnotihk
= NULL
;
302 * Place a ptr to the embedded listview
303 * object in our instance data
306 tv
->tv_Listview
= lvobj
;
309 * Add our notification hook to the listview
312 AddHook(lvobj
,tv
->tv_LVNotifyHook
);
315 * Put ptrs to our instance data in the hook data
316 * of our default treeview hook functions
319 tvrsrchk
->h_Data
= (APTR
) tv
;
320 tvdisphk
->h_Data
= (APTR
) tv
;
321 tvcomphk
->h_Data
= (APTR
) tv
;
322 tvexpahk
->h_Data
= (APTR
) tv
;
325 * Collect user's treeview hook functions,
326 * set defaults if omitted.
329 tv
->tv_ResourceHook
= (HOOKPTR
) GetTagData(TVA_ResourceHook
,( IPTR
) tvrsrchk
,tags
);
330 tv
->tv_DisplayHook
= (HOOKPTR
) GetTagData(TVA_DisplayHook
,( IPTR
) tvdisphk
,tags
);
331 tv
->tv_CompareHook
= (HOOKPTR
) GetTagData(TVA_CompareHook
,( IPTR
) tvcomphk
,tags
);
332 tv
->tv_ExpandHook
= (HOOKPTR
) GetTagData(TVA_ExpandHook
,( IPTR
) tvexpahk
,tags
);
334 if (tv
->tv_ResourceHook
== tvrsrchk
)
337 if (tv
->tv_DisplayHook
== tvdisphk
)
340 if (tv
->tv_CompareHook
== tvcomphk
)
343 if (tv
->tv_ExpandHook
== tvexpahk
)
347 * Collect other attributes specified by user,
351 tv
->tv_Indentation
= GetTagData(TVA_Indentation
,8,tags
);
352 tv
->tv_CopyEntries
= GetTagData(TVA_CopyEntries
,FALSE
,tags
);
353 tv
->tv_LineStyle
= GetTagData(TVA_LineStyle
,TVLS_NONE
,tags
);
354 tv
->tv_LeftAlignImage
= GetTagData(TVA_LeftAlignImage
,FALSE
,tags
);
355 tv
->tv_NoLeafImage
= GetTagData(TVA_NoLeafImage
,FALSE
,tags
);
357 tv
->tv_Indentation
= max(tv
->tv_Indentation
,8);
360 * Collect user supplied expanded/contracted images.
363 tv
->tv_ExpandedImage
= (Object
*) GetTagData(TVA_ExpandedImage
,(IPTR
)NULL
,tags
);
364 tv
->tv_ContractedImage
= (Object
*) GetTagData(TVA_ContractedImage
,(IPTR
)NULL
,tags
);
367 * For either image not supplied explicity by user, determine
368 * which built-in image to use instead and create the objects.
371 expvi
= BoxMinusVector
;
372 convi
= BoxPlusVector
;
374 if (GetTagData(TVA_ImageStyle
,0,tags
) == TVIS_ARROW
)
376 expvi
= ArrowDownVector
;
377 convi
= ArrowRightVector
;
380 if (!tv
->tv_ExpandedImage
)
382 tv
->tv_ExpandedImage
= VectorObject
,VIT_VectorArray
,expvi
,
383 IA_Width
,9,IA_Height
,9,EndObject
;
384 tv
->tv_DefExpImage
= TRUE
;
387 if (!tv
->tv_ContractedImage
)
389 tv
->tv_ContractedImage
= VectorObject
,VIT_VectorArray
,convi
,
390 IA_Width
,9,IA_Height
,9,EndObject
;
391 tv
->tv_DefConImage
= TRUE
;
394 if (!(tv
->tv_ExpandedImage
&& tv
->tv_ContractedImage
))
397 * Failed to obtain one or both images: commit suicide.
400 CoerceMethod(cl
,(Object
*) rc
,OM_DISPOSE
);
404 } /* endif create object */
406 } /* endif alloc hooks */
409 * Free any unused default treeview hooks
412 TV_FreeHook(tvrsrchk
);
413 TV_FreeHook(tvdisphk
);
414 TV_FreeHook(tvcomphk
);
415 TV_FreeHook(tvexpahk
);
418 * If we failed to create the object,
419 * free the allocated listview hooks:
424 TV_FreeHook(lvnotihk
);
425 TV_FreeHook(lvcomphk
);
426 TV_FreeHook(lvdisphk
);
427 TV_FreeHook(lvrsrchk
);
431 CloseLibrary(BGUIBase
);
440 /************************************************************************
441 **************************** TV_DISPOSE() *****************************
442 *************************************************************************
443 * Dispose of treeview object. We need to free our hook structures, and
444 * the node images, before asking our superclass to dispose of us.
446 *************************************************************************/
448 METHOD(TV_Dispose
, Msg
, msg
)
453 tv
= (TVData
*) INST_DATA(cl
,obj
);
456 * Free all the treenodes
459 TV_FreeTreeNodeList(tv
,RootList(tv
));
461 /* stegerg: CHECKME: Added following line, because
462 of real bug. superclass might access the resource
463 hook, which was killed before calling superclass,
465 DoMethod(tv
->tv_Listview
,LVM_CLEAR
,0);
468 * Free the images, if default ones were created
471 if (tv
->tv_DefExpImage
)
472 DisposeObject(tv
->tv_ExpandedImage
);
473 if (tv
->tv_DefConImage
)
474 DisposeObject(tv
->tv_ContractedImage
);
477 * Free all the internal listview hook structures
480 TV_FreeHook(tv
->tv_LVNotifyHook
);
481 TV_FreeHook(tv
->tv_LVCompHook
);
482 TV_FreeHook(tv
->tv_LVDispHook
);
483 TV_FreeHook(tv
->tv_LVRsrcHook
);
486 * Free default treeview hook structures, if any
489 if (tv
->tv_ResourceHook
->h_Entry
== (APTR
)TV_TVRsrcHandler
)
490 TV_FreeHook(tv
->tv_ResourceHook
);
491 if (tv
->tv_DisplayHook
->h_Entry
== (APTR
)TV_TVDispHandler
)
492 TV_FreeHook(tv
->tv_DisplayHook
);
493 if (tv
->tv_CompareHook
->h_Entry
== (APTR
)TV_TVCompHandler
)
494 TV_FreeHook(tv
->tv_CompareHook
);
495 if (tv
->tv_ExpandHook
->h_Entry
== (APTR
)TV_TVExpandHandler
)
496 TV_FreeHook(tv
->tv_ExpandHook
);
499 * Free memory pool that treenodes were allocated in
503 DeletePool(tv
->tv_MemPool
);
505 rc
=DoSuperMethodA(cl
,obj
,msg
);
508 CloseLibrary(BGUIBase
);
515 /************************************************************************
516 ************************** TV_TV???HANDLER() **************************
517 *************************************************************************
518 * Default internal hook functions for resource, display, compare and
521 *************************************************************************/
523 LOCAL ASM SAVEDS
REGFUNC3(IPTR
, TV_TVRsrcHandler
,
524 REGPARAM(A0
, struct Hook
*, hook
),
525 REGPARAM(A2
, Object
*, obj
),
526 REGPARAM(A1
, struct tvResource
*, tvr
))
532 tv
= (TVData
*) hook
->h_Data
;
534 if (tv
->tv_CopyEntries
)
536 if (tvr
->tvr_Command
== TVRC_MAKE
)
537 rc
= (IPTR
) TV_AllocStrCpy(tv
,tvr
->tvr_Entry
,0);
539 TV_FreeVec(tv
,tvr
->tvr_Entry
);
543 if (tvr
->tvr_Command
== TVRC_MAKE
)
544 rc
= (IPTR
) tvr
->tvr_Entry
;
552 LOCAL ASM SAVEDS
REGFUNC3(IPTR
, TV_TVDispHandler
,
553 REGPARAM(A0
, struct Hook
*, hook
),
554 REGPARAM(A2
, Object
*, obj
),
555 REGPARAM(A1
, struct tvRender
*, tvr
))
557 return (IPTR
)tvr
->tvr_Entry
;
562 LOCAL ASM SAVEDS
REGFUNC3(IPTR
, TV_TVCompHandler
,
563 REGPARAM(A0
, struct Hook
*, hook
),
564 REGPARAM(A2
, Object
*, obj
),
565 REGPARAM(A1
, struct tvCompare
*, tvc
))
567 return((IPTR
) Stricmp((STRPTR
) tvc
->tvc_EntryA
,(STRPTR
) tvc
->tvc_EntryB
));
572 LOCAL ASM SAVEDS
REGFUNC3(IPTR
, TV_TVExpandHandler
,
573 REGPARAM(A0
, struct Hook
*, hook
),
574 REGPARAM(A2
, Object
*, obj
),
575 REGPARAM(A1
, struct tvExpand
*, tve
))