build git 2.17.1
[AROS-Contrib.git] / bgui / gadgets / TreeView / TVNewDispose.c
blob24abda6e56f14dc3f03d842aefa79622002a885c
1 /*
2 * @(#) $Header$
4 * BGUI Tree List View class
6 * (C) Copyright 1999 Manuel Lemos.
7 * (C) Copyright 1996-1999 Nick Christie.
8 * All Rights Reserved.
10 * $Log$
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
20 * call.
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"
58 #include "TVUtil.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[] = {
144 { 9,9,VIF_SCALE, },
145 { 0,0,VIF_MOVE, },
146 { 8,0,VIF_DRAW, },
147 { 8,8,VIF_DRAW, },
148 { 0,8,VIF_DRAW, },
149 { 0,0,VIF_DRAW, },
150 { 4,2,VIF_MOVE, },
151 { 4,6,VIF_DRAW, },
152 { 2,4,VIF_MOVE, },
153 { 6,4,VIF_DRAW|VIF_LASTITEM },
156 LOCAL struct VectorItem BoxMinusVector[] = {
157 { 9,9,VIF_SCALE, },
158 { 0,0,VIF_MOVE, },
159 { 8,0,VIF_DRAW, },
160 { 8,8,VIF_DRAW, },
161 { 0,8,VIF_DRAW, },
162 { 0,0,VIF_DRAW, },
163 { 2,4,VIF_MOVE, },
164 { 6,4,VIF_DRAW|VIF_LASTITEM },
167 LOCAL struct VectorItem ArrowRightVector[] = {
168 { 9,9,VIF_SCALE, },
169 { 2,0,VIF_MOVE|VIF_AREASTART, },
170 { 2,8,VIF_DRAW, },
171 { 6,4,VIF_DRAW, },
172 { 2,0,VIF_DRAW|VIF_AREAEND|VIF_LASTITEM },
175 LOCAL struct VectorItem ArrowDownVector[] = {
176 { 9,9,VIF_SCALE, },
177 { 0,2,VIF_MOVE|VIF_AREASTART, },
178 { 8,2,VIF_DRAW, },
179 { 4,6,VIF_DRAW, },
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
190 * on failure.
192 *************************************************************************/
194 METHOD(TV_New,struct opSet *, ops)
196 struct TagItem *tags;
197 struct VectorItem *expvi,*convi;
198 Object *lvobj;
199 HOOKPTR lvrsrchk,lvdisphk,lvcomphk,lvnotihk;
200 HOOKPTR tvrsrchk,tvdisphk,tvcomphk,tvexpahk;
201 IPTR rc;
203 if(BGUIBase==NULL
204 && (BGUIBase=OpenLibrary("bgui.library",41))==NULL)
205 return (IPTR)NULL;
207 lvrsrchk = lvdisphk = lvcomphk = lvnotihk = NULL;
208 tvrsrchk = tvdisphk = tvcomphk = tvexpahk = NULL;
209 tags = ops->ops_AttrList;
210 rc = 0;
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,
233 StartMember,
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),
246 EndObject,
247 EndMember,
248 TAG_DONE)
251 TVData *tv;
253 instances++;
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)
335 tvrsrchk = NULL;
337 if (tv->tv_DisplayHook == tvdisphk)
338 tvdisphk = NULL;
340 if (tv->tv_CompareHook == tvcomphk)
341 tvcomphk = NULL;
343 if (tv->tv_ExpandHook == tvexpahk)
344 tvexpahk = NULL;
347 * Collect other attributes specified by user,
348 * or set defaults.
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);
401 rc = (IPTR)NULL;
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:
422 if (!rc)
424 TV_FreeHook(lvnotihk);
425 TV_FreeHook(lvcomphk);
426 TV_FreeHook(lvdisphk);
427 TV_FreeHook(lvrsrchk);
428 if(instances==0
429 && BGUIBase)
431 CloseLibrary(BGUIBase);
432 BGUIBase=NULL;
436 return(rc);
438 METHOD_END
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)
450 TVData *tv;
451 ULONG rc;
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,
464 otherwise */
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
502 if (tv->tv_MemPool)
503 DeletePool(tv->tv_MemPool);
505 rc=DoSuperMethodA(cl,obj,msg);
506 if(--instances==0)
508 CloseLibrary(BGUIBase);
509 BGUIBase=NULL;
511 return rc;
513 METHOD_END
515 /************************************************************************
516 ************************** TV_TV???HANDLER() **************************
517 *************************************************************************
518 * Default internal hook functions for resource, display, compare and
519 * expand.
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))
528 TVData *tv;
529 IPTR rc;
531 rc = 0;
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);
538 else
539 TV_FreeVec(tv,tvr->tvr_Entry);
541 else
543 if (tvr->tvr_Command == TVRC_MAKE)
544 rc = (IPTR) tvr->tvr_Entry;
547 return(rc);
549 REGFUNC_END
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;
559 REGFUNC_END
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));
569 REGFUNC_END
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))
577 return(1L);
579 REGFUNC_END