]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVE/Reve/RenderElement.cxx
f228fbdac605c1380e12c002c74db0f89f0f9e3e
[u/mrichter/AliRoot.git] / EVE / Reve / RenderElement.cxx
1 // $Header$
2
3 #include "RenderElement.h"
4 #include "ReveManager.h"
5 #include "RGEditor.h"
6
7 #include <TColor.h>
8 #include <TCanvas.h>
9 #include <TGListTree.h>
10 #include <TGPicture.h>
11
12 #include <algorithm>
13
14 using namespace Reve;
15
16 //______________________________________________________________________________
17 // RenderElement
18 //
19 //
20
21 ClassImp(RenderElement)
22
23 const TGPicture* RenderElement::fgRnrIcons[4] = { 0 };
24 const TGPicture* RenderElement::fgListTreeIcons[8] = { 0 };
25
26 //______________________________________________________________________________
27 RenderElement::RenderElement() :
28   fRnrSelf             (kTRUE),
29   fRnrChildren         (kTRUE),
30   fMainColorPtr        (0),
31   fItems               (),
32   fParents             (),
33   fDestroyOnZeroRefCnt (kTRUE),
34   fDenyDestroy         (0),
35   fChildren            ()
36 {
37   // Default contructor.
38 }
39
40 //______________________________________________________________________________
41 RenderElement::RenderElement(Color_t& main_color) :
42   fRnrSelf             (kTRUE),
43   fRnrChildren         (kTRUE),
44   fMainColorPtr        (&main_color),
45   fItems               (),
46   fParents             (),
47   fDestroyOnZeroRefCnt (kTRUE),
48   fDenyDestroy         (0),
49   fChildren            ()
50 {
51   // Constructor.
52 }
53
54 //______________________________________________________________________________
55 RenderElement::~RenderElement()
56 {
57   // Destructor.
58
59   static const Exc_t _eh("RenderElement::RenderElement ");
60
61   RemoveElements();
62
63   for (List_i p=fParents.begin(); p!=fParents.end(); ++p)
64   {
65     (*p)->RemoveElementLocal(this);
66     (*p)->fChildren.remove(this);
67   }
68   fParents.clear();
69
70   for (sLTI_i i=fItems.begin(); i!=fItems.end(); ++i)
71     i->fTree->DeleteItem(i->fItem);
72 }
73
74 /**************************************************************************/
75
76 //______________________________________________________________________________
77 void RenderElement::SetRnrElNameTitle(const Text_t* name, const Text_t* title)
78 {
79   // Virtual function for setting of name and title of render element.
80   // Here we attempt to cast the assigned object into TNamed and call
81   // SetNameTitle() there.
82
83   TNamed* named = dynamic_cast<TNamed*>(GetObject());
84   if (named)
85     named->SetNameTitle(name, title);
86 }
87
88 //______________________________________________________________________________
89 const Text_t* RenderElement::GetRnrElName() const
90 {
91   // Virtual function for retrieveing name of the render-element.
92   // Here we attempt to cast the assigned object into TNamed and call
93   // GetName() there.
94
95   TObject* named = dynamic_cast<TObject*>(GetObject());
96   return named ? named->GetName() : "<no-name>";
97 }
98
99 //______________________________________________________________________________
100 const Text_t*  RenderElement::GetRnrElTitle() const
101 {
102   // Virtual function for retrieveing title of the render-element.
103   // Here we attempt to cast the assigned object into TNamed and call
104   // GetTitle() there.
105
106   TObject* named = dynamic_cast<TObject*>(GetObject());
107   return named ? named->GetTitle() : "<no-title>";
108 }
109
110 /******************************************************************************/
111
112 //______________________________________________________________________________
113 void RenderElement::AddParent(RenderElement* re)
114 {
115   // Add re into the list parents.
116   // Adding parent is subordinate to adding an element.
117   // This is an internal function.
118
119   fParents.push_back(re);
120 }
121
122 void RenderElement::RemoveParent(RenderElement* re)
123 {
124   // Remove re from the list of parents.
125   // Removing parent is subordinate to removing an element.
126   // This is an internal function.
127
128   static const Exc_t eH("RenderElement::RemoveParent ");
129
130   fParents.remove(re);
131   CheckReferenceCount(eH);
132 }
133
134 /******************************************************************************/
135
136 //______________________________________________________________________________
137 void RenderElement::CheckReferenceCount(const Reve::Exc_t& eh)
138 {
139   // Check external references to this and eventually auto-destruct
140   // the render-element.
141
142   if(fParents.empty()   &&  fItems.empty()         &&
143      fDenyDestroy <= 0  &&  fDestroyOnZeroRefCnt)
144   {
145     if (gDebug > 0)
146        Info(eh, Form("auto-destructing '%s' on zero reference count.", GetRnrElName()));
147
148     gReve->PreDeleteRenderElement(this);
149     delete this;
150   }
151 }
152
153 //______________________________________________________________________________
154 void RenderElement::CollectSceneParents(List_t& scenes)
155 {
156   // Collect all parents of class Reve::Scene. This is needed to
157   // automatically detect which scenes need to be updated.
158   //
159   // Overriden in Reve::Scene to include itself and return.
160
161   for(List_i p=fParents.begin(); p!=fParents.end(); ++p)
162     (*p)->CollectSceneParents(scenes);
163 }
164
165 //______________________________________________________________________________
166 void RenderElement::CollectSceneParentsFromChildren(List_t& scenes, RenderElement* parent)
167 {
168   // Collect scene-parents from all children. This is needed to
169   // automatically detect which scenes need to be updated during/after
170   // a full sub-tree update.
171   // Argument parent specifies parent in traversed hierarchy for which we can
172   // skip the upwards search.
173
174   for (List_i p=fParents.begin(); p!=fParents.end(); ++p)
175   {
176     if (*p != parent) (*p)->CollectSceneParents(scenes);
177   }
178
179   for (List_i c=fChildren.begin(); c!=fChildren.end(); ++c)
180   {
181     (*c)->CollectSceneParentsFromChildren(scenes, this);
182   }
183 }
184
185 /******************************************************************************/
186 // List-tree stuff
187 /******************************************************************************/
188
189 //______________________________________________________________________________
190 Int_t RenderElement::ExpandIntoListTree(TGListTree* ltree,
191                                         TGListTreeItem* parent)
192 {
193   // Populates parent with elements.
194   // parent must be an already existing representation of *this*.
195   // Returns number of inserted elements.
196   // If parent already has children, it does nothing.
197   //
198   // RnrEl can be inserted in a list-tree several times, thus we can not
199   // search through fItems to get parent here.
200   // Anyhow, it is probably known as it must have been selected by the user.
201
202   if (parent->GetFirstChild() != 0)
203     return 0;
204   Int_t n = 0;
205   for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
206     (*i)->AddIntoListTree(ltree, parent);
207     ++n;
208   }
209   return n;
210 }
211
212 //______________________________________________________________________________
213 Int_t RenderElement::DestroyListSubTree(TGListTree* ltree,
214                                         TGListTreeItem* parent)
215 {
216   Int_t n = 0;
217   TGListTreeItem* i = parent->GetFirstChild();
218   while (i != 0)
219   {
220     //n += DestroyListSubTree(ltree, i);
221     RenderElement* re = (RenderElement*) i->GetUserData();
222     i = i->GetNextSibling();
223     re->RemoveFromListTree(ltree, parent);
224   }
225   return n;
226 }
227
228 //______________________________________________________________________________
229 TGListTreeItem* RenderElement::AddIntoListTree(TGListTree* ltree,
230                                                TGListTreeItem* parent_lti)
231 {
232   // Add this render element into ltree to already existing item
233   // parent_lti.
234
235   static const Exc_t eH("RenderElement::AddIntoListTree ");
236
237   TObject* tobj = GetObject(eH);
238   TGListTreeItem* item = ltree->AddItem(parent_lti, tobj->GetName(), this,
239                                         0, 0, kTRUE);
240   item->SetCheckBoxPictures(GetCheckBoxPicture(1, fRnrChildren),
241                             GetCheckBoxPicture(0, fRnrChildren));
242
243   item->SetPictures(GetListTreeIcon(),GetListTreeIcon());
244   item->CheckItem(fRnrSelf);
245
246   if (fMainColorPtr != 0) item->SetColor(GetMainColor());
247   item->SetTipText(tobj->GetTitle());
248
249   fItems.insert(ListTreeInfo(ltree, item));
250   ltree->ClearViewPort();
251
252   return item;
253 }
254
255 //______________________________________________________________________________
256 TGListTreeItem* RenderElement::AddIntoListTree(TGListTree* ltree,
257                                                RenderElement* parent)
258 {
259   // Add this render element into ltree to all items belonging to
260   // parent. Returns list-tree-item from the first register entry (but
261   // we use a set for that so it can be anything).
262
263   TGListTreeItem* lti = 0;
264   if (parent == 0) {
265     lti = AddIntoListTree(ltree, (TGListTreeItem*) 0);
266   } else {
267     for (sLTI_ri i = parent->fItems.rbegin(); i != parent->fItems.rend(); ++i)
268     {
269       if (i->fTree == ltree)
270         lti = AddIntoListTree(ltree, i->fItem);
271     }
272   }
273   return lti;
274 }
275
276 //______________________________________________________________________________
277 TGListTreeItem* RenderElement::AddIntoListTrees(RenderElement* parent)
278 {
279   // Add this render element into all list-trees and all items
280   // belonging to parent. Returns list-tree-item from the first
281   // register entry (but we use a set for that so it can be anything).
282
283   TGListTreeItem* lti = 0;
284   for (sLTI_ri i = parent->fItems.rbegin(); i != parent->fItems.rend(); ++i)
285   {
286     lti = AddIntoListTree(i->fTree, i->fItem);
287   }
288   return lti;
289 }
290
291 //______________________________________________________________________________
292 Bool_t RenderElement::RemoveFromListTree(TGListTree* ltree,
293                                          TGListTreeItem* parent_lti)
294 {
295   static const Exc_t eH("RenderElement::RemoveFromListTree ");
296
297   sLTI_i i = FindItem(ltree, parent_lti);
298   if (i != fItems.end()) {
299     DestroyListSubTree(ltree, i->fItem);
300     ltree->DeleteItem(i->fItem);
301     ltree->ClearViewPort();
302     fItems.erase(i);
303     if (parent_lti == 0) CheckReferenceCount(eH);
304     return kTRUE;
305   } else {
306     return kFALSE;
307   }
308 }
309
310 //______________________________________________________________________________
311 Int_t RenderElement::RemoveFromListTrees(RenderElement* parent)
312 {
313   Int_t count = 0;
314
315   sLTI_i i  = fItems.begin();
316   while (i != fItems.end())
317   {
318     sLTI_i j = i++;
319     TGListTreeItem *plti = j->fItem->GetParent();
320     if (plti != 0 && (RenderElement*) plti->GetUserData() == parent)
321     {
322       DestroyListSubTree(j->fTree, j->fItem);
323       j->fTree->DeleteItem(j->fItem);
324       j->fTree->ClearViewPort();
325       fItems.erase(j);
326       ++count;
327     }
328   }
329
330   return count;
331 }
332
333 //______________________________________________________________________________
334 RenderElement::sLTI_i RenderElement::FindItem(TGListTree* ltree)
335 {
336   for (sLTI_i i = fItems.begin(); i != fItems.end(); ++i)
337     if (i->fTree == ltree)
338       return i;
339   return fItems.end();
340 }
341
342 //______________________________________________________________________________
343 RenderElement::sLTI_i RenderElement::FindItem(TGListTree* ltree,
344                                               TGListTreeItem* parent_lti)
345 {
346   for (sLTI_i i = fItems.begin(); i != fItems.end(); ++i)
347     if (i->fTree == ltree && i->fItem->GetParent() == parent_lti)
348       return i;
349   return fItems.end();
350 }
351
352 //______________________________________________________________________________
353 TGListTreeItem* RenderElement::FindListTreeItem(TGListTree* ltree)
354 {
355   for (sLTI_i i = fItems.begin(); i != fItems.end(); ++i)
356     if (i->fTree == ltree)
357       return i->fItem;
358   return 0;
359 }
360
361 //______________________________________________________________________________
362 TGListTreeItem* RenderElement::FindListTreeItem(TGListTree* ltree,
363                                                 TGListTreeItem* parent_lti)
364 {
365   for (sLTI_i i = fItems.begin(); i != fItems.end(); ++i)
366     if (i->fTree == ltree && i->fItem->GetParent() == parent_lti)
367       return i->fItem;
368   return 0;
369 }
370
371 //______________________________________________________________________________
372 void RenderElement::UpdateItems()
373 {
374   // Update list-tree-items representing this render-element.
375
376   static const Exc_t eH("RenderElement::UpdateItems ");
377
378   TObject* tobj = GetObject(eH);
379
380   for (sLTI_i i=fItems.begin(); i!=fItems.end(); ++i) {
381     i->fItem->Rename(tobj->GetName());
382     i->fItem->SetTipText(tobj->GetTitle());
383     i->fItem->CheckItem(fRnrSelf);
384     if (fMainColorPtr != 0) i->fItem->SetColor(GetMainColor());
385     i->fTree->ClearViewPort();
386   }
387 }
388
389 /******************************************************************************/
390
391 //______________________________________________________________________________
392 TObject* RenderElement::GetObject(Exc_t eh) const
393 {
394   // Get a TObject associated with this render-element.
395   // Most cases uses double-inheritance from RenderElement and TObject
396   // so we just do a dynamic cast here.
397   // If some RenderElement descendant implements a different scheme,
398   // this virtual method should be overriden accordingly.
399
400   const TObject* obj = dynamic_cast<const TObject*>(this);
401   if (obj == 0)
402     throw(eh + "not a TObject.");
403   return const_cast<TObject*>(obj);
404 }
405
406 //______________________________________________________________________________
407 void RenderElement::SpawnEditor()
408 {
409   // Show GUI editor for this object.
410
411   gReve->EditRenderElement(this);
412 }
413
414 //______________________________________________________________________________
415 void RenderElement::ExportToCINT(Text_t* var_name)
416 {
417   // Export render-element to CINT with variable name var_name.
418
419   const char* cname = IsA()->GetName();
420   gROOT->ProcessLine(Form("%s* %s = (%s*)0x%lx;", cname, var_name, cname, this));
421 }
422
423 /**************************************************************************/
424
425 //______________________________________________________________________________
426 void RenderElement::PadPaint(Option_t* option)
427 {
428   // Paint self and/or children into currently active pad.
429
430   if (GetRnrSelf() && GetObject()) 
431     GetObject()->Paint(option);
432   
433
434   if (GetRnrChildren()) {
435     for (List_i i=BeginChildren(); i!=EndChildren(); ++i) {
436       (*i)->PadPaint(option);
437     }
438   }
439 }
440
441 /**************************************************************************/
442
443 //______________________________________________________________________________
444 void RenderElement::SetRnrSelf(Bool_t rnr)
445 {
446   if (rnr != fRnrSelf)
447   {
448     fRnrSelf = rnr;
449     
450     for (sLTI_i i=fItems.begin(); i!=fItems.end(); ++i) 
451     {
452       if (i->fItem->IsChecked() != rnr) {
453         i->fItem->SetCheckBoxPictures(GetCheckBoxPicture(1, fRnrChildren),
454                                       GetCheckBoxPicture(0, fRnrChildren));
455         i->fItem->CheckItem(fRnrSelf);
456         i->fTree->ClearViewPort();
457       }
458     }
459   }
460 }
461
462 //______________________________________________________________________________
463 void RenderElement::SetRnrChildren(Bool_t rnr)
464 {
465   if (rnr != fRnrChildren)
466   {
467     fRnrChildren = rnr; 
468
469     for (sLTI_i i=fItems.begin(); i!=fItems.end(); ++i) 
470     {
471       i->fItem->SetCheckBoxPictures(GetCheckBoxPicture(fRnrSelf, fRnrChildren),
472                                     GetCheckBoxPicture(fRnrSelf, fRnrChildren));
473       i->fTree->ClearViewPort();
474     }
475   }
476 }
477
478 //______________________________________________________________________________
479 void RenderElement::SetRnrState(Bool_t rnr)
480 {
481   if (fRnrSelf != rnr || fRnrChildren != rnr)
482   {
483     fRnrSelf = fRnrChildren = rnr; 
484
485     for (sLTI_i i=fItems.begin(); i!=fItems.end(); ++i) 
486     {
487       i->fItem->SetCheckBoxPictures(GetCheckBoxPicture(1,1), GetCheckBoxPicture(0,0));
488       i->fItem->CheckItem(fRnrSelf);
489       i->fTree->ClearViewPort();
490     }
491   }
492 }
493
494 /**************************************************************************/
495
496 //______________________________________________________________________________
497 void RenderElement::SetMainColor(Color_t color)
498 {
499   // Set main color of the render-element.
500   // List-tree-items are updated.
501
502   Color_t oldcol = GetMainColor();
503   for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
504     if ((*i)->GetMainColor() == oldcol) (*i)->SetMainColor(color);
505   }
506
507   if (fMainColorPtr) {
508     *fMainColorPtr = color;
509     for (sLTI_i i=fItems.begin(); i!=fItems.end(); ++i) {
510       if (i->fItem->GetColor() != color) {
511         i->fItem->SetColor(GetMainColor());
512         i->fTree->ClearViewPort();
513       }
514     }
515   }
516 }
517
518 //______________________________________________________________________________
519 void RenderElement::SetMainColor(Pixel_t pixel)
520 {
521   // Convert pixel to Color_t and call the above function.
522
523   SetMainColor(Color_t(TColor::GetColor(pixel)));
524 }
525
526 /**************************************************************************/
527
528 //______________________________________________________________________________
529 TGListTreeItem* RenderElement::AddElement(RenderElement* el)
530 {
531   // Add el to the list of children.
532
533   static const Exc_t eH("RenderElement::AddElement ");
534
535   if ( ! AcceptRenderElement(el))
536     throw(eH + Form("parent '%s' rejects '%s'.",
537                     GetRnrElName(), el->GetRnrElName()));
538
539   el->AddParent(this);
540   fChildren.push_back(el);
541   TGListTreeItem* ret = el->AddIntoListTrees(this);
542   ElementChanged();
543   return ret;
544 }
545
546 //______________________________________________________________________________
547 void RenderElement::RemoveElement(RenderElement* el)
548 {
549   // Remove el from the list of children.
550
551   el->RemoveFromListTrees(this);
552   RemoveElementLocal(el);
553   el->RemoveParent(this);
554   fChildren.remove(el);
555   ElementChanged();
556 }
557
558 //______________________________________________________________________________
559 void RenderElement::RemoveElementLocal(RenderElement* /*el*/)
560 {
561   // Perform additional local removal of el.
562   // Called from RemoveElement() which does whole untangling.
563   // Put into special function as framework-related handling of
564   // element removal should really be common to all classes and
565   // clearing of local structures happens in between removal
566   // of list-tree-items and final removal.
567   // If you override this, you should also override
568   // RemoveElementsLocal().
569 }
570
571 //______________________________________________________________________________
572 void RenderElement::RemoveElements()
573 {
574   // Remove all elements. This assumes removing of all elements can be
575   // done more efficiently then looping over them and removing one by
576   // one.
577
578   for (sLTI_i i=fItems.begin(); i!=fItems.end(); ++i)
579   {
580     DestroyListSubTree(i->fTree, i->fItem);
581   }
582   RemoveElementsLocal();
583   for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i)
584   {
585     (*i)->RemoveParent(this);
586   }
587   fChildren.clear();
588   ElementChanged();
589 }
590
591 //______________________________________________________________________________
592 void RenderElement::RemoveElementsLocal()
593 {
594   // Perform additional local removal of all elements.
595   // See comment to RemoveelementLocal(RenderElement*).
596 }
597
598 /**************************************************************************/
599
600 //______________________________________________________________________________
601 void RenderElement::EnableListElements(Bool_t rnr_self,  Bool_t rnr_children)
602 {
603   // Enable rendering of children and their list contents.
604   // Arguments control how to set self/child rendering.
605
606   for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i)
607   {
608     (*i)->SetRnrSelf(rnr_self);
609     (*i)->SetRnrChildren(rnr_children);
610   }
611
612   ElementChanged(kTRUE, kTRUE);
613 }
614
615 //______________________________________________________________________________
616 void RenderElement::DisableListElements(Bool_t rnr_self,  Bool_t rnr_children)
617 {
618   // Disable rendering of children and their list contents.
619   // Arguments control how to set self/child rendering.
620   //
621   // Same as above function, but default arguments are different. This
622   // is convenient for calls via context menu.
623
624   for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i)
625   {
626     (*i)->SetRnrSelf(rnr_self);
627     (*i)->SetRnrChildren(rnr_children);
628   }
629
630   ElementChanged(kTRUE, kTRUE);
631 }
632
633 /**************************************************************************/
634
635 //______________________________________________________________________________
636 void RenderElement::Destroy()
637 {
638   static const Exc_t eH("RenderElement::Destroy ");
639
640   if (fDenyDestroy > 0)
641     throw(eH + "this element '%s' is protected against destruction.", GetRnrElName());
642
643   gReve->PreDeleteRenderElement(this);
644   delete this;
645   gReve->Redraw3D();
646 }
647
648 //______________________________________________________________________________
649 void RenderElement::DestroyElements()
650 {
651   static const Exc_t eH("RenderElement::DestroyElements ");
652
653   while ( ! fChildren.empty()) {
654     RenderElement* c = fChildren.front();
655     if (c->fDenyDestroy <= 0)
656     {
657       try {
658         c->Destroy();
659       }
660       catch (Exc_t exc) {
661         Warning(eH, Form("element destruction failed: '%s'.", exc.Data()));
662         RemoveElement(c);
663       }
664     }
665     else
666     {
667       if (gDebug > 0)
668         Info(eH, Form("element '%s' is protected agains destruction, removin locally.", c->GetRnrElName()));
669
670       RemoveElement(c);
671     }
672   }
673 }
674
675 /**************************************************************************/
676
677 //______________________________________________________________________________
678 Bool_t RenderElement::HandleElementPaste(RenderElement* el)
679 {
680   // React to element being pasted or dnd-ed.
681   // Return true if redraw is needed.
682
683   gReve->AddRenderElement(el, this);
684   return kTRUE;
685 }
686
687 //______________________________________________________________________________
688 void RenderElement::ElementChanged(Bool_t update_scenes, Bool_t redraw)
689 {
690   if (update_scenes)
691     gReve->RenderElementChanged(this);
692   if (redraw)
693     gReve->Redraw3D();
694 }
695
696 /**************************************************************************/
697 // Statics
698 /**************************************************************************/
699
700 //______________________________________________________________________________
701 const TGPicture*
702 RenderElement::GetCheckBoxPicture(Bool_t rnrSelf, Bool_t rnrDaughters)
703 {
704   Int_t idx = 0;
705   if (rnrSelf)       idx = 2;
706   if (rnrDaughters ) idx++;
707
708   return fgRnrIcons[idx];
709 }
710
711
712 /**************************************************************************/
713 /**************************************************************************/
714
715 //______________________________________________________________________________
716 // Reve::RenderElementObjPtr
717 //
718
719 ClassImp(RenderElementObjPtr)
720
721 //______________________________________________________________________________
722 RenderElementObjPtr::RenderElementObjPtr(TObject* obj, Bool_t own) :
723   RenderElement(),
724   fObject(obj),
725   fOwnObject(own)
726 {
727   // Constructor.
728 }
729
730 //______________________________________________________________________________
731 RenderElementObjPtr::RenderElementObjPtr(TObject* obj, Color_t& mainColor, Bool_t own) :
732   RenderElement(mainColor),
733   fObject(obj),
734   fOwnObject(own)
735 {
736   // Constructor.
737 }
738
739 //______________________________________________________________________________
740 TObject* RenderElementObjPtr::GetObject(Reve::Exc_t eh) const
741 {
742   // Return external object.
743   // Virtual from RenderElement.
744
745   if(fObject == 0)
746     throw(eh + "fObject not set.");
747   return fObject;
748 }
749
750 //______________________________________________________________________________
751 void RenderElementObjPtr::ExportToCINT(Text_t* var_name)
752 {
753   // Export external object to CINT with variable name var_name.
754   // Virtual from RenderElement.
755
756   static const Exc_t eH("RenderElementObjPtr::ExportToCINT ");
757
758   TObject* obj = GetObject(eH);
759   const char* cname = obj->IsA()->GetName();
760   gROOT->ProcessLine(Form("%s* %s = (%s*)0x%lx;", cname, var_name, cname, obj));
761 }
762
763 //______________________________________________________________________________
764 RenderElementObjPtr::~RenderElementObjPtr()
765 {
766   // Destructor.
767
768   if(fOwnObject)
769     delete fObject;
770 }
771
772
773 /******************************************************************************/
774 /******************************************************************************/
775
776 //______________________________________________________________________________
777 // Reve::RenderElementList
778 //
779 // A list of render elements.
780 // Class of acceptable children can be limited by setting the
781 // fChildClass member.
782 // 
783
784 // !!! should have two ctors (like in RenderElement), one with Color_t&
785 // and set fDoColor automatically, based on which ctor is called.
786
787 ClassImp(RenderElementList)
788
789 //______________________________________________________________________________
790 RenderElementList::RenderElementList(const Text_t* n, const Text_t* t, Bool_t doColor) :
791   RenderElement(),
792   TNamed(n, t),
793   fColor(0),
794   fDoColor(doColor),
795   fChildClass(0)
796 {
797   // Constructor.
798
799   if(fDoColor) {
800     SetMainColorPtr(&fColor);
801   }
802 }
803
804 //______________________________________________________________________________
805 Bool_t RenderElementList::AcceptRenderElement(RenderElement* el)
806 {
807   // Check if RenderElement el is inherited from fChildClass.
808   // Virtual from RenderElement.
809
810   if (fChildClass && ! el->IsA()->InheritsFrom(fChildClass))
811     return kFALSE;
812   return kTRUE;
813 }