]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVE/Reve/RenderElement.cxx
Implemented proper reference management accross render-elements, render-element-lists...
[u/mrichter/AliRoot.git] / EVE / Reve / RenderElement.cxx
1 // $Header$
2
3 #include "RenderElement.h"
4 #include "RGTopFrame.h"
5
6 #include <TColor.h>
7 #include <TCanvas.h>
8 #include <TGListTree.h>
9 #include <THashList.h>
10
11 using namespace Reve;
12
13 //______________________________________________________________________
14 // RenderElement
15 //
16 //
17
18 ClassImp(RenderElement)
19
20 RenderElement::RenderElement() :
21   fRnrElement          (kTRUE),
22   fMainColorPtr        (0),
23   fDestroyOnZeroRefCnt (kTRUE),
24   fDenyDestroy         (kFALSE)
25 {}
26
27 RenderElement::RenderElement(Color_t& main_color) :
28   fRnrElement          (kTRUE),
29   fMainColorPtr        (&main_color),
30   fDestroyOnZeroRefCnt (kTRUE),
31   fDenyDestroy         (kFALSE)
32 {}
33
34 RenderElement::~RenderElement()
35 {
36   static const Exc_t _eh("RenderElement::RenderElement ");
37
38   for(lpRE_i p=fParents.begin(); p!=fParents.end(); ++p) {
39     RenderElementListBase* l = dynamic_cast<RenderElementListBase*>(*p);
40     if(l)
41       l->RemoveElementLocal(this);
42   }
43   fParents.clear();
44
45   for(sLTI_i i=fItems.begin(); i!=fItems.end(); ++i) {
46     i->fTree->DeleteItem(i->fItem);
47     gClient->NeedRedraw(i->fTree);
48   }
49 }
50
51 void RenderElement::Destroy()
52 {
53   static const Exc_t eH("RenderElement::Destroy ");
54
55   if(fDenyDestroy)
56     throw(eH + "this object is protected against destruction.");
57
58   delete this;
59   gReve->Redraw3D();
60 }
61
62 /**************************************************************************/
63
64 void RenderElement::AddParent(RenderElement* re)
65 {
66   fParents.push_back(re);
67 }
68
69 void RenderElement::RemoveParent(RenderElement* re)
70 {
71   static const Exc_t eH("RenderElement::RemoveParent ");
72
73   fParents.remove(re);
74   if(fParents.empty() && fDestroyOnZeroRefCnt) {
75     // TObject* tobj = GetObject(eH);
76     // Warning(eH.Data(), Form("auto-destructing '%s' on zero reference count.", tobj->GetName()));
77     delete this;
78   }
79 }
80
81 /**************************************************************************/
82
83 TObject* RenderElement::GetObject(Exc_t eh)
84 {
85   TObject* obj = dynamic_cast<TObject*>(this);
86   if(obj == 0)
87     throw(eh + "not a TObject.");
88   return obj;
89 }
90
91 /**************************************************************************/
92
93 TGListTreeItem* RenderElement::AddIntoListTree(TGListTree* ltree,
94                                                TGListTreeItem* parent_lti)
95 {
96   static const Exc_t eH("RenderElement::AddIntoListTree ");
97
98   TObject* tobj = GetObject(eH);
99   TGListTreeItem* item = ltree->AddItem(parent_lti, tobj->GetName(), this,
100                                         0, 0, kTRUE);
101   gClient->NeedRedraw(ltree);
102   item->CheckItem(GetRnrElement());
103   
104   if(fMainColorPtr != 0) item->SetColor(GetMainColor());
105   item->SetTipText(tobj->GetTitle());
106
107   fItems.insert(ListTreeInfo(ltree, item));
108
109   return item;
110 }
111
112 TGListTreeItem* RenderElement::AddIntoListTree(TGListTree* ltree,
113                                                RenderElement* parent)
114 {
115   TGListTreeItem* parent_lti = parent ? parent->FindListTreeItem(ltree) : 0;
116   return AddIntoListTree(ltree, parent_lti);
117 }
118
119 Bool_t RenderElement::RemoveFromListTree(TGListTree* ltree)
120 {
121   sLTI_i i = FindItem(ltree);
122   if(i != fItems.end()) {
123     ltree->DeleteItem(i->fItem);
124     fItems.erase(i);
125     gClient->NeedRedraw(ltree);
126     return kTRUE;
127   } else {
128     return kFALSE;
129   }
130 }
131
132 Bool_t RenderElement::RemoveFromListTree(TGListTree* ltree,
133                                          TGListTreeItem* parent_lti)
134 {
135   sLTI_i i = FindItem(ltree, parent_lti);
136   if(i != fItems.end()) {
137     ltree->DeleteItem(i->fItem);
138     fItems.erase(i);
139     gClient->NeedRedraw(ltree);
140     return kTRUE;
141   } else {
142     return kFALSE;
143   }
144 }
145
146 RenderElement::sLTI_i RenderElement::FindItem(TGListTree* ltree)
147 {
148   for(sLTI_i i = fItems.begin(); i != fItems.end(); ++i)
149     if(i->fTree == ltree)
150       return i;
151   return fItems.end();
152 }
153
154 RenderElement::sLTI_i RenderElement::FindItem(TGListTree* ltree,
155                                               TGListTreeItem* parent_lti)
156 {
157   for(sLTI_i i = fItems.begin(); i != fItems.end(); ++i)
158     if(i->fTree == ltree && i->fItem->GetParent() == parent_lti)
159       return i;
160   return fItems.end();
161 }
162
163 TGListTreeItem* RenderElement::FindListTreeItem(TGListTree* ltree)
164 {
165   for(sLTI_i i = fItems.begin(); i != fItems.end(); ++i)
166     if(i->fTree == ltree)
167       return i->fItem;
168   return 0;
169 }
170
171 TGListTreeItem* RenderElement::FindListTreeItem(TGListTree* ltree,
172                                                 TGListTreeItem* parent_lti)
173 {
174   for(sLTI_i i = fItems.begin(); i != fItems.end(); ++i)
175     if(i->fTree == ltree && i->fItem->GetParent() == parent_lti)
176       return i->fItem;
177   return 0;
178 }
179
180 /**************************************************************************/
181
182 void RenderElement::UpdateItems()
183 {
184   static const Exc_t eH("RenderElement::UpdateItems ");
185
186   TObject* tobj = GetObject(eH);
187   for(sLTI_i i=fItems.begin(); i!=fItems.end(); ++i) {
188     i->fItem->Rename(tobj->GetName());
189     i->fItem->SetTipText(tobj->GetTitle());
190     i->fItem->CheckItem(fRnrElement);
191     if(fMainColorPtr != 0) i->fItem->SetColor(GetMainColor());
192     gClient->NeedRedraw(i->fTree);
193   }
194   gReve->Redraw3D(); // This will go away once editor can notify ALL changes.
195 }
196
197 /**************************************************************************/
198
199 void RenderElement::SpawnEditor()
200 {
201   // Here spawn a sub-class of TGedFrame with special UpdateMethod.
202   gReve->EditRenderElement(this);
203 }
204
205 void RenderElement::ExportToCINT(Text_t* var_name)
206 {
207   static const Exc_t eH("RenderElement::ExportToCINT ");
208
209   TObject* obj = GetObject(eH);
210   const char* cname = obj->IsA()->GetName();
211   gROOT->ProcessLine(Form("%s* %s = (%s*) %p;", cname, var_name, cname, obj));
212 }
213
214 /**************************************************************************/
215 /*
216 void RenderElement::DumpSourceObject()
217 {
218   TObject* o = GetSourceObject();
219   if(o == 0) {
220     printf("Source object not set.\n");
221   } else {
222     o->Dump();
223   }
224 }
225
226 void RenderElement::InspectSourceObject()
227 {
228   TObject* o = GetSourceObject();
229   if(o == 0) {
230     printf("Source object not set.\n");
231   } else {
232     o->Inspect();
233   }
234 }
235 */
236 /**************************************************************************/
237
238 void RenderElement::SetRnrElement(Bool_t rnr)
239 {
240   if(rnr != fRnrElement) {
241     fRnrElement = rnr;
242     UpdateItems();
243   }
244 }
245
246 /**************************************************************************/
247
248 void RenderElement::SetMainColor(Color_t color)
249 {
250   if (fMainColorPtr) {
251     *fMainColorPtr = color;
252     UpdateItems();
253   }
254 }
255
256 void RenderElement::SetMainColor(Pixel_t pixel)
257 {
258   SetMainColor(Color_t(TColor::GetColor(pixel)));
259 }
260
261 /**************************************************************************/
262 /**************************************************************************/
263
264 ClassImp(RenderElementObjPtr)
265
266 RenderElementObjPtr::RenderElementObjPtr(TObject* obj, Bool_t own) :
267   RenderElement(),
268   fObject(obj),
269   fOwnObject(own)
270 {}
271
272 RenderElementObjPtr::RenderElementObjPtr(TObject* obj, Color_t& mainColor, Bool_t own) :
273   RenderElement(mainColor),
274   fObject(obj),
275   fOwnObject(own)
276 {}
277
278 RenderElementObjPtr::~RenderElementObjPtr()
279 {
280   if(fOwnObject)
281     delete fObject;
282 }
283
284 /**************************************************************************/
285
286 TObject* RenderElementObjPtr::GetObject(Reve::Exc_t eh)
287 {
288   if(fObject == 0)
289     throw(eh + "fObject not set.");
290   return fObject;
291 }
292
293 /**************************************************************************/
294 /**************************************************************************/
295
296 ClassImp(RenderElementListBase)
297
298 RenderElementListBase::~RenderElementListBase()
299 {
300   // Collapse all sub-trees
301   for(sLTI_i i=fItems.begin(); i!=fItems.end(); ++i) {
302     DestroyListSubTree(i->fTree, i->fItem);
303     // My own items removed in ~RenderElement
304   }
305   RemoveElements();
306 }
307
308 /**************************************************************************/
309
310 void RenderElementListBase::AddElement(RenderElement* el)
311 {
312   fChildren.push_back(el);
313   el->AddParent(this);
314 }
315
316 void RenderElementListBase::RemoveElement(RenderElement* el)
317 {
318   el->RemoveParent(this);
319   RemoveElementLocal(el);
320 }
321
322 void RenderElementListBase::RemoveElementLocal(RenderElement* el)
323 {
324   fChildren.remove(el);
325 }
326
327 void RenderElementListBase::RemoveElements()
328 {
329   for(lpRE_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
330     (*i)->RemoveParent(this);
331   }
332   fChildren.clear();
333 }
334
335 /**************************************************************************/
336
337 Int_t RenderElementListBase::ExpandIntoListTree(TGListTree* ltree,
338                                                 TGListTreeItem* parent)
339 {
340   // Populates parent with elements.
341   // parent must be an already existing representation of *this*.
342   // Returns number of inserted elements.
343   // If parent already has children, it does nothing.
344   //
345   // RnrEl can be inserted in a list-tree several times, thus we can not
346   // search through fItems to get parent here.
347   // Anyhow, it is probably known as it must have been selected by the user.
348
349   if(parent->GetFirstChild() != 0)
350     return 0;
351   Int_t n = 0;
352   for(lpRE_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
353     (*i)->AddIntoListTree(ltree, parent);
354     ++n;
355   }
356   return n;
357 }
358
359 Int_t RenderElementListBase::DestroyListSubTree(TGListTree* ltree,
360                                                 TGListTreeItem* parent)
361 {
362   Int_t n = 0;
363   TGListTreeItem* i = parent->GetFirstChild();
364   while(i != 0) {
365     n += DestroyListSubTree(ltree, i);
366     RenderElement* re = (RenderElement*) i->GetUserData();
367     i = i->GetNextSibling();
368     re->RemoveFromListTree(ltree, parent);
369   }
370   return n;
371 }
372
373 /**************************************************************************/
374
375 void RenderElementListBase::EnableListElements()
376 {
377   for(lpRE_i i=fChildren.begin(); i!=fChildren.end(); ++i)
378     (*i)->SetRnrElement(kTRUE);
379 }
380
381 void RenderElementListBase::DisableListElements()
382 {
383   for(lpRE_i i=fChildren.begin(); i!=fChildren.end(); ++i)
384     (*i)->SetRnrElement(kFALSE);
385 }
386
387 /**************************************************************************/
388
389 void RenderElementListBase::SetMainColor(Color_t col)
390 {
391   Color_t oldcol = GetMainColor();
392   for(lpRE_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
393     if((*i)->GetMainColor() == oldcol) (*i)->SetMainColor(col);
394   }
395   RenderElement::SetMainColor(col);
396 }
397
398 void RenderElementListBase::SetMainColor(Pixel_t pixel)
399 {
400   // This one needed for proper calling via CINT (signals).
401
402   SetMainColor(Color_t(TColor::GetColor(pixel)));
403 }
404
405 /**************************************************************************/
406
407 void RenderElementListBase::PaintElements(Option_t* option)
408 {
409   if(fRnrElement) {
410     for(lpRE_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
411       if((*i)->GetRnrElement())
412         (*i)->GetObject()->Paint(option);
413     }
414   }
415 }
416
417 /**************************************************************************/
418 /**************************************************************************/
419
420 ClassImp(RenderElementList)
421
422 RenderElementList::RenderElementList(const Text_t* n, const Text_t* t, Bool_t doColor) :
423   RenderElementListBase(),
424   TNamed(n, t),
425   fColor(0),
426   fDoColor(doColor)
427 {
428   if(fDoColor) {
429     SetMainColorPtr(&fColor);
430   }
431 }