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