3 #include "RenderElement.h"
4 #include "ReveManager.h"
9 #include <TGListTree.h>
10 #include <TGPicture.h>
16 //______________________________________________________________________________
21 ClassImp(RenderElement)
23 const TGPicture* RenderElement::fgRnrIcons[4] = { 0 };
24 const TGPicture* RenderElement::fgListTreeIcons[8] = { 0 };
26 //______________________________________________________________________________
27 RenderElement::RenderElement() :
33 fDestroyOnZeroRefCnt (kTRUE),
37 // Default contructor.
40 //______________________________________________________________________________
41 RenderElement::RenderElement(Color_t& main_color) :
44 fMainColorPtr (&main_color),
47 fDestroyOnZeroRefCnt (kTRUE),
54 //______________________________________________________________________________
55 RenderElement::~RenderElement()
59 static const Exc_t _eh("RenderElement::RenderElement ");
63 for (List_i p=fParents.begin(); p!=fParents.end(); ++p)
65 (*p)->RemoveElementLocal(this);
66 (*p)->fChildren.remove(this);
70 for (sLTI_i i=fItems.begin(); i!=fItems.end(); ++i)
71 i->fTree->DeleteItem(i->fItem);
74 /**************************************************************************/
76 //______________________________________________________________________________
77 void RenderElement::SetRnrElNameTitle(const Text_t* name, const Text_t* title)
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.
83 TNamed* named = dynamic_cast<TNamed*>(GetObject());
85 named->SetNameTitle(name, title);
88 //______________________________________________________________________________
89 const Text_t* RenderElement::GetRnrElName() const
91 // Virtual function for retrieveing name of the render-element.
92 // Here we attempt to cast the assigned object into TNamed and call
95 TObject* named = dynamic_cast<TObject*>(GetObject());
96 return named ? named->GetName() : "<no-name>";
99 //______________________________________________________________________________
100 const Text_t* RenderElement::GetRnrElTitle() const
102 // Virtual function for retrieveing title of the render-element.
103 // Here we attempt to cast the assigned object into TNamed and call
106 TObject* named = dynamic_cast<TObject*>(GetObject());
107 return named ? named->GetTitle() : "<no-title>";
110 /******************************************************************************/
112 //______________________________________________________________________________
113 void RenderElement::AddParent(RenderElement* re)
115 // Add re into the list parents.
116 // Adding parent is subordinate to adding an element.
117 // This is an internal function.
119 fParents.push_back(re);
122 void RenderElement::RemoveParent(RenderElement* re)
124 // Remove re from the list of parents.
125 // Removing parent is subordinate to removing an element.
126 // This is an internal function.
128 static const Exc_t eH("RenderElement::RemoveParent ");
131 CheckReferenceCount(eH);
134 /******************************************************************************/
136 //______________________________________________________________________________
137 void RenderElement::CheckReferenceCount(const Reve::Exc_t& eh)
139 // Check external references to this and eventually auto-destruct
140 // the render-element.
142 if(fParents.empty() && fItems.empty() &&
143 fDenyDestroy <= 0 && fDestroyOnZeroRefCnt)
146 Info(eh, Form("auto-destructing '%s' on zero reference count.", GetRnrElName()));
148 gReve->PreDeleteRenderElement(this);
153 //______________________________________________________________________________
154 void RenderElement::CollectSceneParents(List_t& scenes)
156 // Collect all parents of class Reve::Scene. This is needed to
157 // automatically detect which scenes need to be updated.
159 // Overriden in Reve::Scene to include itself and return.
161 for(List_i p=fParents.begin(); p!=fParents.end(); ++p)
162 (*p)->CollectSceneParents(scenes);
165 //______________________________________________________________________________
166 void RenderElement::CollectSceneParentsFromChildren(List_t& scenes, RenderElement* parent)
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.
174 for (List_i p=fParents.begin(); p!=fParents.end(); ++p)
176 if (*p != parent) (*p)->CollectSceneParents(scenes);
179 for (List_i c=fChildren.begin(); c!=fChildren.end(); ++c)
181 (*c)->CollectSceneParentsFromChildren(scenes, this);
185 /******************************************************************************/
187 /******************************************************************************/
189 //______________________________________________________________________________
190 Int_t RenderElement::ExpandIntoListTree(TGListTree* ltree,
191 TGListTreeItem* parent)
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.
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.
202 if (parent->GetFirstChild() != 0)
205 for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
206 (*i)->AddIntoListTree(ltree, parent);
212 //______________________________________________________________________________
213 Int_t RenderElement::DestroyListSubTree(TGListTree* ltree,
214 TGListTreeItem* parent)
217 TGListTreeItem* i = parent->GetFirstChild();
220 //n += DestroyListSubTree(ltree, i);
221 RenderElement* re = (RenderElement*) i->GetUserData();
222 i = i->GetNextSibling();
223 re->RemoveFromListTree(ltree, parent);
228 //______________________________________________________________________________
229 TGListTreeItem* RenderElement::AddIntoListTree(TGListTree* ltree,
230 TGListTreeItem* parent_lti)
232 // Add this render element into ltree to already existing item
235 static const Exc_t eH("RenderElement::AddIntoListTree ");
237 TObject* tobj = GetObject(eH);
238 TGListTreeItem* item = ltree->AddItem(parent_lti, tobj->GetName(), this,
240 item->SetCheckBoxPictures(GetCheckBoxPicture(1, fRnrChildren),
241 GetCheckBoxPicture(0, fRnrChildren));
243 item->SetPictures(GetListTreeIcon(),GetListTreeIcon());
244 item->CheckItem(fRnrSelf);
246 if (fMainColorPtr != 0) item->SetColor(GetMainColor());
247 item->SetTipText(tobj->GetTitle());
249 fItems.insert(ListTreeInfo(ltree, item));
250 ltree->ClearViewPort();
255 //______________________________________________________________________________
256 TGListTreeItem* RenderElement::AddIntoListTree(TGListTree* ltree,
257 RenderElement* parent)
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).
263 TGListTreeItem* lti = 0;
265 lti = AddIntoListTree(ltree, (TGListTreeItem*) 0);
267 for (sLTI_ri i = parent->fItems.rbegin(); i != parent->fItems.rend(); ++i)
269 if (i->fTree == ltree)
270 lti = AddIntoListTree(ltree, i->fItem);
276 //______________________________________________________________________________
277 TGListTreeItem* RenderElement::AddIntoListTrees(RenderElement* parent)
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).
283 TGListTreeItem* lti = 0;
284 for (sLTI_ri i = parent->fItems.rbegin(); i != parent->fItems.rend(); ++i)
286 lti = AddIntoListTree(i->fTree, i->fItem);
291 //______________________________________________________________________________
292 Bool_t RenderElement::RemoveFromListTree(TGListTree* ltree,
293 TGListTreeItem* parent_lti)
295 static const Exc_t eH("RenderElement::RemoveFromListTree ");
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();
303 if (parent_lti == 0) CheckReferenceCount(eH);
310 //______________________________________________________________________________
311 Int_t RenderElement::RemoveFromListTrees(RenderElement* parent)
315 sLTI_i i = fItems.begin();
316 while (i != fItems.end())
319 TGListTreeItem *plti = j->fItem->GetParent();
320 if (plti != 0 && (RenderElement*) plti->GetUserData() == parent)
322 DestroyListSubTree(j->fTree, j->fItem);
323 j->fTree->DeleteItem(j->fItem);
324 j->fTree->ClearViewPort();
333 //______________________________________________________________________________
334 RenderElement::sLTI_i RenderElement::FindItem(TGListTree* ltree)
336 for (sLTI_i i = fItems.begin(); i != fItems.end(); ++i)
337 if (i->fTree == ltree)
342 //______________________________________________________________________________
343 RenderElement::sLTI_i RenderElement::FindItem(TGListTree* ltree,
344 TGListTreeItem* parent_lti)
346 for (sLTI_i i = fItems.begin(); i != fItems.end(); ++i)
347 if (i->fTree == ltree && i->fItem->GetParent() == parent_lti)
352 //______________________________________________________________________________
353 TGListTreeItem* RenderElement::FindListTreeItem(TGListTree* ltree)
355 for (sLTI_i i = fItems.begin(); i != fItems.end(); ++i)
356 if (i->fTree == ltree)
361 //______________________________________________________________________________
362 TGListTreeItem* RenderElement::FindListTreeItem(TGListTree* ltree,
363 TGListTreeItem* parent_lti)
365 for (sLTI_i i = fItems.begin(); i != fItems.end(); ++i)
366 if (i->fTree == ltree && i->fItem->GetParent() == parent_lti)
371 //______________________________________________________________________________
372 void RenderElement::UpdateItems()
374 // Update list-tree-items representing this render-element.
376 static const Exc_t eH("RenderElement::UpdateItems ");
378 TObject* tobj = GetObject(eH);
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();
389 /******************************************************************************/
391 //______________________________________________________________________________
392 TObject* RenderElement::GetObject(Exc_t eh) const
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.
400 const TObject* obj = dynamic_cast<const TObject*>(this);
402 throw(eh + "not a TObject.");
403 return const_cast<TObject*>(obj);
406 //______________________________________________________________________________
407 void RenderElement::SpawnEditor()
409 // Show GUI editor for this object.
411 gReve->EditRenderElement(this);
414 //______________________________________________________________________________
415 void RenderElement::ExportToCINT(Text_t* var_name)
417 // Export render-element to CINT with variable name var_name.
419 const char* cname = IsA()->GetName();
420 gROOT->ProcessLine(Form("%s* %s = (%s*)0x%lx;", cname, var_name, cname, this));
423 /**************************************************************************/
425 //______________________________________________________________________________
426 void RenderElement::PadPaint(Option_t* option)
428 // Paint self and/or children into currently active pad.
430 if (GetRnrSelf() && GetObject())
431 GetObject()->Paint(option);
434 if (GetRnrChildren()) {
435 for (List_i i=BeginChildren(); i!=EndChildren(); ++i) {
436 (*i)->PadPaint(option);
441 /**************************************************************************/
443 //______________________________________________________________________________
444 void RenderElement::SetRnrSelf(Bool_t rnr)
450 for (sLTI_i i=fItems.begin(); i!=fItems.end(); ++i)
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();
462 //______________________________________________________________________________
463 void RenderElement::SetRnrChildren(Bool_t rnr)
465 if (rnr != fRnrChildren)
469 for (sLTI_i i=fItems.begin(); i!=fItems.end(); ++i)
471 i->fItem->SetCheckBoxPictures(GetCheckBoxPicture(fRnrSelf, fRnrChildren),
472 GetCheckBoxPicture(fRnrSelf, fRnrChildren));
473 i->fTree->ClearViewPort();
478 //______________________________________________________________________________
479 void RenderElement::SetRnrState(Bool_t rnr)
481 if (fRnrSelf != rnr || fRnrChildren != rnr)
483 fRnrSelf = fRnrChildren = rnr;
485 for (sLTI_i i=fItems.begin(); i!=fItems.end(); ++i)
487 i->fItem->SetCheckBoxPictures(GetCheckBoxPicture(1,1), GetCheckBoxPicture(0,0));
488 i->fItem->CheckItem(fRnrSelf);
489 i->fTree->ClearViewPort();
494 /**************************************************************************/
496 //______________________________________________________________________________
497 void RenderElement::SetMainColor(Color_t color)
499 // Set main color of the render-element.
500 // List-tree-items are updated.
502 Color_t oldcol = GetMainColor();
503 for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
504 if ((*i)->GetMainColor() == oldcol) (*i)->SetMainColor(color);
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();
518 //______________________________________________________________________________
519 void RenderElement::SetMainColor(Pixel_t pixel)
521 // Convert pixel to Color_t and call the above function.
523 SetMainColor(Color_t(TColor::GetColor(pixel)));
526 /**************************************************************************/
528 //______________________________________________________________________________
529 TGListTreeItem* RenderElement::AddElement(RenderElement* el)
531 // Add el to the list of children.
533 static const Exc_t eH("RenderElement::AddElement ");
535 if ( ! AcceptRenderElement(el))
536 throw(eH + Form("parent '%s' rejects '%s'.",
537 GetRnrElName(), el->GetRnrElName()));
540 fChildren.push_back(el);
541 TGListTreeItem* ret = el->AddIntoListTrees(this);
546 //______________________________________________________________________________
547 void RenderElement::RemoveElement(RenderElement* el)
549 // Remove el from the list of children.
551 el->RemoveFromListTrees(this);
552 RemoveElementLocal(el);
553 el->RemoveParent(this);
554 fChildren.remove(el);
558 //______________________________________________________________________________
559 void RenderElement::RemoveElementLocal(RenderElement* /*el*/)
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().
571 //______________________________________________________________________________
572 void RenderElement::RemoveElements()
574 // Remove all elements. This assumes removing of all elements can be
575 // done more efficiently then looping over them and removing one by
578 for (sLTI_i i=fItems.begin(); i!=fItems.end(); ++i)
580 DestroyListSubTree(i->fTree, i->fItem);
582 RemoveElementsLocal();
583 for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i)
585 (*i)->RemoveParent(this);
591 //______________________________________________________________________________
592 void RenderElement::RemoveElementsLocal()
594 // Perform additional local removal of all elements.
595 // See comment to RemoveelementLocal(RenderElement*).
598 /**************************************************************************/
600 //______________________________________________________________________________
601 void RenderElement::EnableListElements(Bool_t rnr_self, Bool_t rnr_children)
603 // Enable rendering of children and their list contents.
604 // Arguments control how to set self/child rendering.
606 for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i)
608 (*i)->SetRnrSelf(rnr_self);
609 (*i)->SetRnrChildren(rnr_children);
612 ElementChanged(kTRUE, kTRUE);
615 //______________________________________________________________________________
616 void RenderElement::DisableListElements(Bool_t rnr_self, Bool_t rnr_children)
618 // Disable rendering of children and their list contents.
619 // Arguments control how to set self/child rendering.
621 // Same as above function, but default arguments are different. This
622 // is convenient for calls via context menu.
624 for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i)
626 (*i)->SetRnrSelf(rnr_self);
627 (*i)->SetRnrChildren(rnr_children);
630 ElementChanged(kTRUE, kTRUE);
633 /**************************************************************************/
635 //______________________________________________________________________________
636 void RenderElement::Destroy()
638 static const Exc_t eH("RenderElement::Destroy ");
640 if (fDenyDestroy > 0)
641 throw(eH + "this element '%s' is protected against destruction.", GetRnrElName());
643 gReve->PreDeleteRenderElement(this);
648 //______________________________________________________________________________
649 void RenderElement::DestroyElements()
651 static const Exc_t eH("RenderElement::DestroyElements ");
653 while ( ! fChildren.empty()) {
654 RenderElement* c = fChildren.front();
655 if (c->fDenyDestroy <= 0)
661 Warning(eH, Form("element destruction failed: '%s'.", exc.Data()));
668 Info(eH, Form("element '%s' is protected agains destruction, removin locally.", c->GetRnrElName()));
675 /**************************************************************************/
677 //______________________________________________________________________________
678 Bool_t RenderElement::HandleElementPaste(RenderElement* el)
680 // React to element being pasted or dnd-ed.
681 // Return true if redraw is needed.
683 gReve->AddRenderElement(el, this);
687 //______________________________________________________________________________
688 void RenderElement::ElementChanged(Bool_t update_scenes, Bool_t redraw)
691 gReve->RenderElementChanged(this);
696 /**************************************************************************/
698 /**************************************************************************/
700 //______________________________________________________________________________
702 RenderElement::GetCheckBoxPicture(Bool_t rnrSelf, Bool_t rnrDaughters)
705 if (rnrSelf) idx = 2;
706 if (rnrDaughters ) idx++;
708 return fgRnrIcons[idx];
712 /**************************************************************************/
713 /**************************************************************************/
715 //______________________________________________________________________________
716 // Reve::RenderElementObjPtr
719 ClassImp(RenderElementObjPtr)
721 //______________________________________________________________________________
722 RenderElementObjPtr::RenderElementObjPtr(TObject* obj, Bool_t own) :
730 //______________________________________________________________________________
731 RenderElementObjPtr::RenderElementObjPtr(TObject* obj, Color_t& mainColor, Bool_t own) :
732 RenderElement(mainColor),
739 //______________________________________________________________________________
740 TObject* RenderElementObjPtr::GetObject(Reve::Exc_t eh) const
742 // Return external object.
743 // Virtual from RenderElement.
746 throw(eh + "fObject not set.");
750 //______________________________________________________________________________
751 void RenderElementObjPtr::ExportToCINT(Text_t* var_name)
753 // Export external object to CINT with variable name var_name.
754 // Virtual from RenderElement.
756 static const Exc_t eH("RenderElementObjPtr::ExportToCINT ");
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));
763 //______________________________________________________________________________
764 RenderElementObjPtr::~RenderElementObjPtr()
773 /******************************************************************************/
774 /******************************************************************************/
776 //______________________________________________________________________________
777 // Reve::RenderElementList
779 // A list of render elements.
780 // Class of acceptable children can be limited by setting the
781 // fChildClass member.
784 // !!! should have two ctors (like in RenderElement), one with Color_t&
785 // and set fDoColor automatically, based on which ctor is called.
787 ClassImp(RenderElementList)
789 //______________________________________________________________________________
790 RenderElementList::RenderElementList(const Text_t* n, const Text_t* t, Bool_t doColor) :
800 SetMainColorPtr(&fColor);
804 //______________________________________________________________________________
805 Bool_t RenderElementList::AcceptRenderElement(RenderElement* el)
807 // Check if RenderElement el is inherited from fChildClass.
808 // Virtual from RenderElement.
810 if (fChildClass && ! el->IsA()->InheritsFrom(fChildClass))