39 ClassImp(TStructViewerGUI);
53 TGeoMedium* TStructViewerGUI::fgMedium = NULL;
54 UInt_t TStructViewerGUI::fgCounter = 0;
60 TStructViewerGUI::TStructViewerGUI(TStructViewer* parent, TStructNode* nodePtr, TList* colors,
const TGWindow *p,UInt_t w,UInt_t h)
61 : TGMainFrame(p, w, h, kHorizontalFrame)
69 fSelectedObject = NULL;
73 if (!gGeoManager)
new TGeoManager(
"tmp",
"tmp");
75 fgMedium =
new TGeoMedium(
"MED",1,
new TGeoMaterial(
"Mat", 26.98,13,2.7));
78 SetCleanup(kDeepCleanup);
82 TGVerticalFrame* leftFrame =
new TGVerticalFrame(
this, 200, 200, kFixedWidth);
83 this->AddFrame(leftFrame,
new TGLayoutHints(kFixedWidth, 1, 1, 1, 1));
84 TGTab* tabs =
new TGTab(leftFrame);
85 TGLayoutHints* expandX =
new TGLayoutHints(kLHintsLeft | kLHintsExpandX, 5,5,5,5);
89 TGCompositeFrame* infoFrame = tabs->AddTab(
"Info");
90 TGGroupFrame* fInfoMenu =
new TGGroupFrame(infoFrame,
"Info");
91 fNodeNameLabel =
new TGLabel(fInfoMenu,
"Name:");
92 fInfoMenu->AddFrame(fNodeNameLabel, expandX);
93 fNodeTypelabel =
new TGLabel(fInfoMenu,
"Type:");
94 fInfoMenu->AddFrame(fNodeTypelabel, expandX);
95 fMembersCountLabel =
new TGLabel(fInfoMenu,
"Members:");
96 fInfoMenu->AddFrame(fMembersCountLabel, expandX);
97 fAllMembersCountLabel =
new TGLabel(fInfoMenu,
"All members:");
98 fInfoMenu->AddFrame(fAllMembersCountLabel, expandX);
99 fLevelLabel =
new TGLabel(fInfoMenu,
"Level:");
100 fInfoMenu->AddFrame(fLevelLabel, expandX);
101 fSizeLabel =
new TGLabel(fInfoMenu,
"Size:");
102 fInfoMenu->AddFrame(fSizeLabel, expandX);
103 fTotalSizeLabel =
new TGLabel(fInfoMenu,
"Total size:");
104 fInfoMenu->AddFrame(fTotalSizeLabel, expandX);
105 infoFrame->AddFrame(fInfoMenu, expandX);
110 TGCompositeFrame* options = tabs->AddTab(
"Options");
112 fShowLinksCheckButton =
new TGCheckButton(options,
"Show links");
113 fShowLinksCheckButton->Connect(
"Toggled(Bool_t)",
"TStructViewerGUI",
this,
"ShowLinksToggled(Bool_t)");
114 options->AddFrame(fShowLinksCheckButton);
115 fShowLinksCheckButton->SetOn();
117 TGVButtonGroup* scaleByGroup =
new TGVButtonGroup(options,
"Scale by");
118 fScaleBySizeButton =
new TGRadioButton(scaleByGroup,
"Size");
119 fScaleBySizeButton->Connect(
"Clicked()",
"TStructViewerGUI",
this,
"ScaleByChangedSlot()");
120 fScaleBySizeButton->SetOn();
121 fScaleByMembersButton =
new TGRadioButton(scaleByGroup,
"Members count");
122 fScaleByMembersButton->Connect(
"Clicked()",
"TStructViewerGUI",
this,
"ScaleByChangedSlot()");
123 options->AddFrame(scaleByGroup, expandX);
125 TGHorizontalFrame* defaultColorFrame =
new TGHorizontalFrame(options);
126 options->AddFrame(defaultColorFrame, expandX);
127 TGLabel* defColorlabel =
new TGLabel(defaultColorFrame,
"Default color");
128 defaultColorFrame->AddFrame(defColorlabel, expandX);
129 TGColorSelect* defColorSelect =
new TGColorSelect(defaultColorFrame, GetDefaultColor()->GetPixel());
130 defColorSelect->Connect(
"ColorSelected(Pixel_t)",
"TStructViewerGUI",
this,
"ColorSelectedSlot(Pixel_t)");
131 defaultColorFrame->AddFrame(defColorSelect);
133 TGHorizontalFrame* boxHeightFrame =
new TGHorizontalFrame(options);
134 options->AddFrame(boxHeightFrame, expandX);
135 TGLabel* boxHeightLabel =
new TGLabel(boxHeightFrame,
"Box height:");
136 boxHeightFrame->AddFrame(boxHeightLabel, expandX);
137 fBoxHeightEntry =
new TGNumberEntry(boxHeightFrame, 0.1);
138 fBoxHeightEntry->SetLimits(TGNumberEntry::kNELLimitMin, 0.01);
139 fBoxHeightEntry->Connect(
"ValueSet(Long_t)",
"TStructViewerGUI",
this,
"BoxHeightValueSetSlot(Long_t)");
140 boxHeightFrame->AddFrame(fBoxHeightEntry);
142 TGHorizontalFrame* levelDistanceFrame =
new TGHorizontalFrame(options);
143 options->AddFrame(levelDistanceFrame, expandX);
144 TGLabel* lvlDistLabel =
new TGLabel(levelDistanceFrame,
"Distance between levels");
145 levelDistanceFrame->AddFrame(lvlDistLabel, expandX);
146 fLevelDistanceEntry =
new TGNumberEntry(levelDistanceFrame, 1.1);
147 fLevelDistanceEntry->SetLimits(TGNumberEntry::kNELLimitMin, 0.01);
148 fLevelDistanceEntry->Connect(
"ValueSet(Long_t)",
"TStructViewerGUI",
this,
"LevelDistValueSetSlot(Long_t)");
149 levelDistanceFrame->AddFrame(fLevelDistanceEntry);
151 fAutoRefesh =
new TGCheckButton(options,
"Auto refresh");
152 fAutoRefesh->SetOn();
153 fAutoRefesh->Connect(
"Toggled(Bool_t)",
"TStructViewerGUI",
this,
"AutoRefreshButtonSlot(Bool_t)");
154 options->AddFrame(fAutoRefesh, expandX);
156 TGLabel* pointerLabel =
new TGLabel(options,
"Pointer:");
157 options->AddFrame(pointerLabel, expandX);
158 fPointerTextEntry =
new TGTextEntry(options,
"0x0000000");
159 options->AddFrame(fPointerTextEntry, expandX);
160 TGLabel* fPointerTypeLabel =
new TGLabel(options,
"Pointer Type:");
161 options->AddFrame(fPointerTypeLabel, expandX);
162 fPointerTypeTextEntry =
new TGTextEntry(options,
"TObject");
163 options->AddFrame(fPointerTypeTextEntry, expandX);
164 TGTextButton* setPointerButton =
new TGTextButton(options,
"Set pointer");
165 setPointerButton->Connect(
"Clicked()",
"TStructViewerGUI",
this,
"SetPointerButtonSlot()");
166 options->AddFrame(setPointerButton, expandX);
171 TGCompositeFrame* editTab = tabs->AddTab(
"Editor");
172 fEditor =
new TStructNodeEditor(fColors, editTab);
173 fEditor->Connect(
"Update(Bool_t)",
"TStructViewerGUI",
this,
"Update(Bool_t)");
174 editTab->AddFrame(fEditor, expandX);
176 leftFrame->AddFrame(tabs,
new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 1,1,1,1));
178 TGVSplitter* splitter =
new TGVSplitter(
this);
179 splitter->SetFrame(leftFrame,
true);
180 this->AddFrame(splitter,
new TGLayoutHints(kLHintsLeft | kLHintsExpandY));
185 fUndoButton =
new TGTextButton(leftFrame,
"Undo");
186 fUndoButton->Connect(
"Clicked()",
"TStructViewerGUI",
this,
"UndoButtonSlot()");
187 fUndoButton->SetEnabled(
false);
188 leftFrame->AddFrame(fUndoButton, expandX);
190 fRedoButton =
new TGTextButton(leftFrame,
"Redo");
191 fRedoButton->Connect(
"Clicked()",
"TStructViewerGUI",
this,
"RedoButtonSlot()");
192 fRedoButton->SetEnabled(
false);
193 leftFrame->AddFrame(fRedoButton, expandX);
195 TGTextButton* resetCameraButton =
new TGTextButton(leftFrame,
"Reset camera");
196 leftFrame->AddFrame(resetCameraButton, expandX);
197 resetCameraButton->Connect(
"Clicked()",
"TStructViewerGUI",
this,
"ResetButtonSlot()");
199 TGTextButton* updateButton =
new TGTextButton(leftFrame,
"Update");
200 updateButton->Connect(
"Clicked()",
"TStructViewerGUI",
this,
"UpdateButtonSlot()");
201 leftFrame->AddFrame(updateButton, expandX);
203 TGTextButton* quitButton =
new TGTextButton(leftFrame,
"Quit");
204 leftFrame->AddFrame(quitButton, expandX);
205 quitButton->Connect(
"Clicked()",
"TApplication", gApplication,
"Terminate()");
207 fTopVolume = gGeoManager->MakeBox(
"TOPVolume", fgMedium,100, 100, 100);
208 gGeoManager->SetTopVolume(fTopVolume);
209 gGeoManager->SetNsegments(40);
211 fCanvas =
new TCanvas(
"c",
"c", 0, 0);
213 fGLViewer =
new TGLEmbeddedViewer(
this, fCanvas);
214 AddFrame(fGLViewer->GetFrame(),
new TGLayoutHints(kLHintsExpandX| kLHintsExpandY, 10,10,10,10));
215 fGLViewer->PadPaint(fCanvas);
216 fGLViewer->Connect(
"MouseOver(TGLPhysicalShape*)",
"TStructViewerGUI",
this,
"MouseOverSlot(TGLPhysicalShape*)");
217 fGLViewer->GetGLWidget()->Connect(
"ProcessedEvent(Event_t*)",
"TStructViewerGUI",
this,
"GLWidgetProcessedEventSlot(Event_t*))");
218 fGLViewer->Connect(
"DoubleClicked()",
"TStructViewerGUI",
this,
"DoubleClickedSlot()");
219 fGLViewer->SetCurrentCamera(TGLViewer::kCameraPerspXOY);
221 fGLViewer->SetResetCamerasOnUpdate(
false);
223 SetWindowName(
"Struct Viewer");
225 this->SetWMSizeHints(w, h, 2000, 2000, 0, 0);
226 Resize(GetDefaultSize());
229 fToolTip =
new TGToolTip(0, 0,
"ToolTip", 500);
235 TStructViewerGUI::~TStructViewerGUI()
243 void TStructViewerGUI::AutoRefreshButtonSlot(Bool_t on)
253 void TStructViewerGUI::BoxHeightValueSetSlot(Long_t )
255 if(fAutoRefesh->IsOn()) {
263 void TStructViewerGUI::CalculatePosistion(TStructNode* parent)
266 if (fScaleBySizeButton->GetState() == kButtonDown) {
267 TStructNode::SetScaleBy(kSize);
268 }
else if (fScaleByMembersButton->GetState() == kButtonDown) {
269 TStructNode::SetScaleBy(kMembers);
271 Float_t ratio = (Float_t)((parent->GetLevel()+1.0) / parent->GetLevel());
276 parent->SetHeight(1);
277 parent->SetX(-parent->GetWidth()/2);
278 parent->SetY(-parent->GetHeight()/2);
280 fMaxRatio = parent->GetVolumeRatio();
283 parent->GetMembers()->Sort(kSortDescending);
284 Divide(parent->GetMembers(), (parent->GetX()) *ratio, (parent->GetX() + parent->GetWidth())* ratio, (parent->GetY())* ratio, (parent->GetY() + parent->GetHeight())*ratio);
293 void TStructViewerGUI::CheckMaxObjects(TStructNode* parent)
301 while ((node = (TStructNode*) queue.First() )) {
304 if (
object > fNodePtr->GetMaxObjects() || node->GetLevel() - fNodePtr->GetLevel() >= fNodePtr->GetMaxLevel()) {
308 node->SetVisible(
true);
310 queue.AddAll(node->GetMembers());
313 fVisibleObjects.Add(node);
316 TIter it(&fVisibleObjects);
318 while ((node = (TStructNode*) it() )) {
319 if(node->GetLevel() - fNodePtr->GetLevel() == fNodePtr->GetMaxLevel()-1 && node->GetMembersCount() > 0) {
320 node->SetCollapsed(
true);
324 TIter memIt(node->GetMembers());
325 while ((member = (TStructNode*) memIt() )) {
326 if(member->IsVisible() ==
false) {
327 node->SetCollapsed(
true);
337 void TStructViewerGUI::CloseWindow()
346 void TStructViewerGUI::ColorSelectedSlot(Pixel_t pixel)
348 TStructNodeProperty* prop = GetDefaultColor();
350 prop->SetColor(pixel);
358 void TStructViewerGUI::Divide(TList* list, Float_t x1, Float_t x2, Float_t y1, Float_t y2)
360 if (list->GetSize() > 1) {
361 ULong_t sum1 = 0, sum = 0;
367 while((node = (TStructNode*) it() )) {
368 sum += node->GetVolume();
371 while((node = (TStructNode*) it() )) {
372 if(sum1 >= sum/2.0) {
375 sum1 += node->GetVolume();
381 Float_t ratio = (float)sum1/sum;
383 Float_t width = x2 - x1;
384 Float_t height = y2 - y1;
385 if (width < height) {
386 Float_t split = y1 + ratio * height;
387 Divide(&list1, x1, x2, y1, split);
388 Divide(&list2, x1, x2, split, y2);
390 Float_t split = x1 + ratio * width;
391 Divide(&list1, x1, split, y1, y2);
392 Divide(&list2, split, x2, y1, y2);
394 }
else if (list->GetSize() == 1) {
395 TStructNode* node = (TStructNode*)(list->First());
397 node->SetWidth(x2 - x1);
398 node->SetHeight(y2 - y1);
402 if (node->GetVolumeRatio() > fMaxRatio) {
403 fMaxRatio = node->GetVolumeRatio();
406 Float_t ratio = (Float_t)((node->GetLevel()+1.0)/node->GetLevel());
407 node->GetMembers()->Sort(kSortDescending);
408 Divide(node->GetMembers(), x1*ratio, x2*ratio, y1*ratio, y2*ratio);
416 void TStructViewerGUI::DoubleClickedSlot()
418 if (fSelectedObject) {
419 if(fSelectedObject == fNodePtr) {
423 fUndoList.Add(fNodePtr);
424 fNodePtr = fSelectedObject;
425 fUndoButton->SetEnabled(
true);
433 void TStructViewerGUI::Draw(Option_t* )
436 CheckMaxObjects(fNodePtr);
438 CalculatePosistion(fNodePtr);
439 DrawVolumes(fNodePtr);
441 if(fShowLinksCheckButton->GetState() == kButtonDown) {
451 void TStructViewerGUI::DrawLink(TStructNode* parent)
453 if(parent->GetLevel() - fNodePtr->GetLevel() >= fNodePtr->GetMaxLevel()) {
457 if(parent->IsCollapsed()) {
461 TIter it(parent->GetMembers());
463 while((node = (TStructNode*) it())) {
464 TPolyLine3D *l =
new TPolyLine3D(2);
465 l->SetPoint(0 ,node->GetCenter(), node->GetMiddle(), -(node->GetLevel() * fLevelDistanceEntry->GetNumber()));
466 l->SetPoint(1 ,parent->GetCenter(), parent->GetMiddle(), -(parent->GetLevel() * fLevelDistanceEntry->GetNumber()));
468 l->SetLineColor(GetColor(node));
472 if(!node->IsCollapsed()) {
481 void TStructViewerGUI::DrawNode(TStructNode* node)
504 if(node->GetNodeType() == kCollection) {
505 vol = gGeoManager->MakeBox(Form(
"%s_%d", node->GetName(), fgCounter++), fgMedium, 0.45*node->GetWidth(), 0.45*node->GetHeight(), fBoxHeightEntry->GetNumber());
507 Float_t slices = (Float_t)(node->GetMembersCount());
508 if (slices > fMaxSlices) {
509 slices = (Float_t)fMaxSlices;
512 for (Float_t i = -(slices-1)/2; i < slices/2; i++) {
513 TGeoVolume* sub = gGeoManager->MakeBox(Form(
"%s_%d", node->GetName(), fgCounter++), fgMedium,0.45*node->GetWidth() * 0.7 / slices, 0.45*node->GetHeight(), fBoxHeightEntry->GetNumber());
514 sub->SetLineColor(GetColor(node));
515 fVolumes.Add((Long_t)sub, (Long_t)node);
516 TGeoTranslation* subtrans =
new TGeoTranslation(
"subtranslation", i * node->GetWidth() / slices, 0, 0);
517 vol->AddNodeOverlap(sub, 1, subtrans);
520 vol = gGeoManager->MakeBox(Form(
"%s_%d", node->GetName(), fgCounter++), fgMedium, 0.45*node->GetWidth(), 0.45*node->GetHeight(), fBoxHeightEntry->GetNumber());
523 vol->SetLineColor(GetColor(node));
524 vol->SetLineWidth(1);
526 TGeoTranslation* trans =
new TGeoTranslation(
"translation", node->GetCenter(), node->GetMiddle(), -(node->GetLevel() * fLevelDistanceEntry->GetNumber()));
527 fVolumes.Add((Long_t)vol, (Long_t)node);
529 fTopVolume->AddNode(vol,1, trans);
535 void TStructViewerGUI::DrawVolumes(TStructNode* parent)
537 if(parent->GetLevel() - fNodePtr->GetLevel() >= fNodePtr->GetMaxLevel()) {
543 if(parent->IsCollapsed()) {
547 TIter nextVis(parent->GetMembers());
549 while((node = (TStructNode*)nextVis())) {
558 TStructNodeProperty* TStructViewerGUI::FindNodeProperty(TStructNode* node)
561 TStructNodeProperty* prop;
562 while ((prop = (TStructNodeProperty*) it() )) {
563 TString propName(prop->GetName());
564 if (propName.EndsWith(
"+")) {
566 if (TClass* cl = TClass::GetClass(node->GetTypeName())) {
567 propName.Remove(propName.Length()-1, 1);
568 if (cl->InheritsFrom(propName.Data())) {
573 if (propName == TString(node->GetTypeName())) {
579 return (TStructNodeProperty*)fColors->Last();
583 TCanvas* TStructViewerGUI::GetCanvas()
592 Int_t TStructViewerGUI::GetColor(TStructNode* node)
594 TStructNodeProperty* prop = FindNodeProperty(node);
596 return prop->GetColor().GetNumber();
605 TStructNodeProperty* TStructViewerGUI::GetDefaultColor()
607 return ((TStructNodeProperty*)(fColors->Last()));
613 Bool_t TStructViewerGUI::GetLinksVisibility()
const
615 if (fShowLinksCheckButton->GetState() == kButtonDown) {
625 TStructNode* TStructViewerGUI::GetNodePtr()
const
633 void TStructViewerGUI::GLWidgetProcessedEventSlot(Event_t* event)
635 switch (event->fType) {
637 fMouseX =
event->fXRoot + 15;
638 fMouseY =
event->fYRoot + 15;
643 if (fSelectedObject) {
644 UpdateLabels(fSelectedObject);
645 fEditor->SetModel(fSelectedObject);
657 void TStructViewerGUI::LevelDistValueSetSlot(Long_t )
659 if(fAutoRefesh->IsOn()) {
668 void TStructViewerGUI::MouseOverSlot(TGLPhysicalShape* shape)
671 fSelectedObject = NULL;
672 if (shape && shape->GetLogical()) {
673 fSelectedObject = (TStructNode*)(shape->GetLogical()->ID());
674 if (fSelectedObject) {
675 if (fSelectedObject->IsA()->InheritsFrom(TPolyLine3D::Class())) {
676 fSelectedObject = NULL;
679 Long_t shapeID = (Long_t)(shape->GetLogical()->ID());
680 Long_t volValue = (Long_t)fVolumes.GetValue(shapeID);
681 fSelectedObject = (TStructNode*)volValue;
683 fToolTip->SetText(TString(fSelectedObject->GetName()) +
"\n" + fSelectedObject->GetTypeName());
684 fToolTip->SetPosition(fMouseX, fMouseY);
686 UpdateLabels(fSelectedObject);
694 void TStructViewerGUI::RedoButtonSlot()
696 fUndoList.Add(fNodePtr);
697 fUndoButton->SetEnabled(
true);
698 fNodePtr = (TStructNode*) fRedoList.Last();
699 fRedoList.RemoveLast();
700 if (!fRedoList.First()) {
701 fRedoButton->SetEnabled(
false);
704 UpdateLabels(fNodePtr);
710 void TStructViewerGUI::ResetButtonSlot()
712 fGLViewer->UpdateScene();
713 fGLViewer->ResetCurrentCamera();
720 void TStructViewerGUI::Scale(TStructNode* parent)
723 Float_t newRatio = (Float_t)(TMath::Sqrt(parent->GetRelativeVolumeRatio()/fMaxRatio));
725 parent->SetX(parent->GetX() + parent->GetWidth()/2);
726 parent->SetY(parent->GetY() + parent->GetHeight()/2);
728 Float_t min = (Float_t)TMath::Min(parent->GetWidth(), parent->GetHeight());
729 parent->SetWidth(parent->GetWidth() * newRatio);
730 parent->SetHeight(parent->GetHeight() * newRatio);
732 Float_t sqrt = (Float_t)(TMath::Sqrt(parent->GetWidth() * parent->GetHeight()));
735 parent->SetWidth(sqrt);
736 parent->SetHeight(sqrt);
738 if (parent->GetHeight() > parent->GetWidth()) {
739 parent->SetWidth(min);
740 parent->SetHeight(sqrt * sqrt / min);
742 parent->SetWidth(sqrt * sqrt / min);
743 parent->SetHeight(min);
747 parent->SetX(parent->GetX() - parent->GetWidth()/2);
748 parent->SetY(parent->GetY() - parent->GetHeight()/2);
752 TIter it(parent->GetMembers());
753 while ((node = (TStructNode*) it() )) {
761 void TStructViewerGUI::SetNodePtr(TStructNode* val)
770 void TStructViewerGUI::SetLinksVisibility(Bool_t visible)
773 fShowLinksCheckButton->SetState(kButtonDown);
775 fShowLinksCheckButton->SetState(kButtonUp);
782 void TStructViewerGUI::SetPointerButtonSlot()
784 void* obj = (
void*)gROOT->ProcessLine(fPointerTextEntry->GetText());
785 fParent->SetPointer(obj, fPointerTypeTextEntry->GetText());
791 void TStructViewerGUI::ShowLinksToggled(Bool_t )
793 if (fAutoRefesh->IsOn()) {
801 void TStructViewerGUI::UnCheckMaxObjects()
804 TIter it(&fVisibleObjects);
806 while ((node = (TStructNode*) it() )) {
807 node->SetCollapsed(
false);
808 node->SetVisible(
false);
811 fVisibleObjects.Clear();
817 void TStructViewerGUI::Update(Bool_t resetCamera)
823 fCanvas->GetListOfPrimitives()->Clear();
824 fTopVolume->ClearNodes();
826 fCanvas->GetListOfPrimitives()->Add(fTopVolume);
827 fGLViewer->UpdateScene();
830 fGLViewer->ResetCurrentCamera();
837 void TStructViewerGUI::UpdateButtonSlot()
845 void TStructViewerGUI::UpdateLabels(TStructNode* node)
847 fNodeNameLabel->SetText(node->GetName());
848 fNodeTypelabel->SetText(node->GetTypeName());
850 TString name =
"Members: ";
851 name += node->GetMembersCount();
852 fMembersCountLabel->SetText(name);
853 name =
"All members: ";
854 name += node->GetAllMembersCount();
855 fAllMembersCountLabel->SetText(name);
857 name += node->GetLevel();
858 fLevelLabel->SetText(name);
860 name += node->GetSize();
861 fSizeLabel->SetText(name);
862 name =
"Total size: ";
863 name += node->GetTotalSize();
864 fTotalSizeLabel->SetText(name);
870 void TStructViewerGUI::UndoButtonSlot()
872 fRedoList.Add(fNodePtr);
873 fRedoButton->SetEnabled(
true);
874 fNodePtr = (TStructNode*) fUndoList.Last();
875 fUndoList.RemoveLast();
876 if (!fUndoList.First()) {
877 fUndoButton->SetEnabled(
false);
880 UpdateLabels(fNodePtr);
886 void TStructViewerGUI::ScaleByChangedSlot()
888 if (fAutoRefesh->IsOn()) {