TStructViewerGUI.cxx

Go to the documentation of this file.
00001 // @(#)root/gviz3d:$Id: TStructViewerGUI.cxx 32930 2010-04-09 16:18:32Z pcanal $
00002 // Author: Tomasz Sosnicki   18/09/09
00003 
00004 /************************************************************************
00005 * Copyright (C) 1995-2009, Rene Brun and Fons Rademakers.               *
00006 * All rights reserved.                                                  *
00007 *                                                                       *
00008 * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010 *************************************************************************/
00011 
00012 #include "TStructViewerGUI.h"
00013 #include <TRandom.h>
00014 #include "TStructViewer.h"
00015 #include "TStructNodeEditor.h"
00016 #include "TStructNodeProperty.h"
00017 #include "TStructNode.h"
00018 #include <TCanvas.h>
00019 #include <RQ_OBJECT.h>
00020 #include <TGLLogicalShape.h>
00021 #include <TGLPhysicalShape.h>
00022 #include <TGLWidget.h>
00023 #include <TGButtonGroup.h>
00024 #include <TGSplitter.h>
00025 #include <TList.h>
00026 #include <TClass.h>
00027 #include <TDataMember.h>
00028 #include <TExMap.h>
00029 #include <TPolyLine3D.h>
00030 #include <TObjArray.h>
00031 #include <TColor.h>
00032 #include <TGTab.h>
00033 #include <TGeoManager.h>
00034 #include <TGeoMatrix.h>
00035 #include <TMath.h>
00036 #include <TROOT.h>
00037 #include <TApplication.h>
00038 
00039 ClassImp(TStructViewerGUI);
00040 
00041 //________________________________________________________________________
00042 //////////////////////////////////////////////////////////////////////////
00043 //
00044 // TStructViewerGUI is main window of TStructViewer. It provides graphical
00045 // interface. In the window we can find panel with tabs and frame with 
00046 // GLViewer. Tab "Info" serves information about node and is used to naviagate 
00047 // backward and forward. Second tab "Options" is used to set few options 
00048 // such as links visibility, scaling method or setting a pointer.
00049 // Last tab "Editor" is tab when the TStructNodeEditor is placed.
00050 // 
00051 //////////////////////////////////////////////////////////////////////////
00052 
00053 TGeoMedium* TStructViewerGUI::fgMedium = NULL;
00054 UInt_t      TStructViewerGUI::fgCounter = 0;
00055 
00056 //________________________________________________________________________
00057 TStructViewerGUI::TStructViewerGUI(TStructViewer* parent, TStructNode* nodePtr, TList* colors, const TGWindow *p,UInt_t w,UInt_t h)
00058    : TGMainFrame(p, w, h, kHorizontalFrame)
00059 {
00060    // Constructs window with "w" as width, "h" as height and given parent "p". Argument "parent" is a pointer to TStructViewer which contains this GUI.
00061    // This constructor build window with all controls, build map with colors, init OpenGL Viewer and create TGeoVolumes.
00062 
00063    fParent = parent;
00064    fNodePtr = nodePtr;
00065    
00066    fMaxSlices = 10;
00067    fMouseX = 0;
00068    fMouseY = 0;
00069    fSelectedObject = NULL;
00070    fMaxRatio = 0;
00071    fColors = colors;
00072    
00073    if (!fgMedium) {
00074       fgMedium = new TGeoMedium("MED",1,new TGeoMaterial("Mat", 26.98,13,2.7));
00075    }
00076 
00077    SetCleanup(kDeepCleanup);
00078    //////////////////////////////////////////////////////////////////////////
00079    // layout
00080    //////////////////////////////////////////////////////////////////////////
00081    TGVerticalFrame* leftFrame = new TGVerticalFrame(this, 200, 200, kFixedWidth);
00082    this->AddFrame(leftFrame, new TGLayoutHints(kFixedWidth, 1, 1, 1, 1));
00083    TGTab* tabs = new TGTab(leftFrame);
00084    TGLayoutHints* expandX = new TGLayoutHints(kLHintsLeft | kLHintsExpandX, 5,5,5,5);
00085    //////////////////////////////////////////////////////////////////////////
00086    // INFO
00087    //////////////////////////////////////////////////////////////////////////
00088    TGCompositeFrame* infoFrame = tabs->AddTab("Info");
00089    TGGroupFrame* fInfoMenu = new TGGroupFrame(infoFrame, "Info");
00090    fNodeNameLabel = new TGLabel(fInfoMenu, "Name:");
00091    fInfoMenu->AddFrame(fNodeNameLabel, expandX);
00092    fNodeTypelabel = new TGLabel(fInfoMenu, "Type:");
00093    fInfoMenu->AddFrame(fNodeTypelabel, expandX);
00094    fMembersCountLabel = new TGLabel(fInfoMenu, "Members:");
00095    fInfoMenu->AddFrame(fMembersCountLabel, expandX);
00096    fAllMembersCountLabel = new TGLabel(fInfoMenu, "All members:");
00097    fInfoMenu->AddFrame(fAllMembersCountLabel, expandX);
00098    fLevelLabel = new TGLabel(fInfoMenu, "Level:");
00099    fInfoMenu->AddFrame(fLevelLabel, expandX);
00100    fSizeLabel = new TGLabel(fInfoMenu, "Size:");
00101    fInfoMenu->AddFrame(fSizeLabel, expandX);
00102    fTotalSizeLabel = new TGLabel(fInfoMenu, "Total size:");
00103    fInfoMenu->AddFrame(fTotalSizeLabel, expandX);
00104    infoFrame->AddFrame(fInfoMenu, expandX);
00105 
00106    //////////////////////////////////////////////////////////////////////////
00107    // OPTIONS
00108    //////////////////////////////////////////////////////////////////////////
00109    TGCompositeFrame* options = tabs->AddTab("Options");
00110     
00111    fShowLinksCheckButton = new TGCheckButton(options, "Show links");
00112    fShowLinksCheckButton->Connect("Toggled(Bool_t)", "TStructViewerGUI", this, "ShowLinksToggled(Bool_t)");
00113    options->AddFrame(fShowLinksCheckButton);
00114    fShowLinksCheckButton->SetOn();
00115  
00116    TGVButtonGroup* scaleByGroup = new TGVButtonGroup(options, "Scale by");
00117    fScaleBySizeButton = new TGRadioButton(scaleByGroup, "Size");
00118    fScaleBySizeButton->Connect("Clicked()", "TStructViewerGUI", this, "ScaleByChangedSlot()");
00119    fScaleBySizeButton->SetOn();
00120    fScaleByMembersButton = new TGRadioButton(scaleByGroup, "Members count");
00121    fScaleByMembersButton->Connect("Clicked()", "TStructViewerGUI", this, "ScaleByChangedSlot()");
00122    options->AddFrame(scaleByGroup, expandX);
00123 
00124    TGHorizontalFrame* defaultColorFrame = new TGHorizontalFrame(options);
00125    options->AddFrame(defaultColorFrame, expandX);
00126    TGLabel* defColorlabel = new TGLabel(defaultColorFrame, "Default color");
00127    defaultColorFrame->AddFrame(defColorlabel, expandX);
00128    TGColorSelect* defColorSelect = new TGColorSelect(defaultColorFrame, GetDefaultColor()->GetPixel());
00129    defColorSelect->Connect("ColorSelected(Pixel_t)", "TStructViewerGUI", this, "ColorSelectedSlot(Pixel_t)");
00130    defaultColorFrame->AddFrame(defColorSelect);
00131 
00132    TGHorizontalFrame* boxHeightFrame = new TGHorizontalFrame(options);
00133    options->AddFrame(boxHeightFrame, expandX);
00134    TGLabel* boxHeightLabel = new TGLabel(boxHeightFrame, "Box height:");
00135    boxHeightFrame->AddFrame(boxHeightLabel, expandX);
00136    fBoxHeightEntry = new TGNumberEntry(boxHeightFrame, 0.1);
00137    fBoxHeightEntry->SetLimits(TGNumberEntry::kNELLimitMin, 0.01);
00138    fBoxHeightEntry->Connect("ValueSet(Long_t)", "TStructViewerGUI", this, "BoxHeightValueSetSlot(Long_t)");
00139    boxHeightFrame->AddFrame(fBoxHeightEntry);
00140 
00141    TGHorizontalFrame* levelDistanceFrame = new TGHorizontalFrame(options);
00142    options->AddFrame(levelDistanceFrame, expandX);
00143    TGLabel* lvlDistLabel = new TGLabel(levelDistanceFrame, "Distance between levels");
00144    levelDistanceFrame->AddFrame(lvlDistLabel, expandX);
00145    fLevelDistanceEntry = new TGNumberEntry(levelDistanceFrame, 1.1);
00146    fLevelDistanceEntry->SetLimits(TGNumberEntry::kNELLimitMin, 0.01);
00147    fLevelDistanceEntry->Connect("ValueSet(Long_t)", "TStructViewerGUI", this, "LevelDistValueSetSlot(Long_t)");
00148    levelDistanceFrame->AddFrame(fLevelDistanceEntry);
00149 
00150    fAutoRefesh = new TGCheckButton(options, "Auto refresh");
00151    fAutoRefesh->SetOn();
00152    fAutoRefesh->Connect("Toggled(Bool_t)", "TStructViewerGUI", this, "AutoRefreshButtonSlot(Bool_t)");
00153    options->AddFrame(fAutoRefesh, expandX);
00154 
00155    TGLabel* pointerLabel = new TGLabel(options, "Pointer:");
00156    options->AddFrame(pointerLabel, expandX);
00157    fPointerTextEntry = new TGTextEntry(options, "0x0000000");
00158    options->AddFrame(fPointerTextEntry, expandX);
00159    TGLabel* fPointerTypeLabel = new TGLabel(options, "Pointer Type:");
00160    options->AddFrame(fPointerTypeLabel, expandX);
00161    fPointerTypeTextEntry = new TGTextEntry(options, "TObject");
00162    options->AddFrame(fPointerTypeTextEntry, expandX);
00163    TGTextButton* setPointerButton = new TGTextButton(options, "Set pointer");
00164    setPointerButton->Connect("Clicked()", "TStructViewerGUI", this, "SetPointerButtonSlot()");
00165    options->AddFrame(setPointerButton, expandX);
00166 
00167    //////////////////////////////////////////////////////////////////////////
00168    // EDITOR
00169    //////////////////////////////////////////////////////////////////////////
00170    TGCompositeFrame* editTab = tabs->AddTab("Editor");
00171    fEditor = new TStructNodeEditor(fColors, editTab);
00172    fEditor->Connect("Update(Bool_t)", "TStructViewerGUI", this, "Update(Bool_t)");
00173    editTab->AddFrame(fEditor, expandX);
00174 
00175    leftFrame->AddFrame(tabs, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 1,1,1,1));
00176 
00177    TGVSplitter* splitter = new TGVSplitter(this);
00178    splitter->SetFrame(leftFrame, true);
00179    this->AddFrame(splitter, new TGLayoutHints(kLHintsLeft | kLHintsExpandY));
00180  
00181    //////////////////////////////////////////////////////////////////////////
00182    // NAVIGATE
00183    //////////////////////////////////////////////////////////////////////////
00184    fUndoButton = new TGTextButton(leftFrame, "Undo");
00185    fUndoButton->Connect("Clicked()", "TStructViewerGUI", this, "UndoButtonSlot()");
00186    fUndoButton->SetEnabled(false);
00187    leftFrame->AddFrame(fUndoButton, expandX);
00188 
00189    fRedoButton = new TGTextButton(leftFrame, "Redo");
00190    fRedoButton->Connect("Clicked()", "TStructViewerGUI", this, "RedoButtonSlot()");
00191    fRedoButton->SetEnabled(false);
00192    leftFrame->AddFrame(fRedoButton, expandX);
00193 
00194    TGTextButton* resetCameraButton = new TGTextButton(leftFrame, "Reset camera");
00195    leftFrame->AddFrame(resetCameraButton, expandX);
00196    resetCameraButton->Connect("Clicked()", "TStructViewerGUI", this, "ResetButtonSlot()");
00197 
00198    TGTextButton* updateButton = new TGTextButton(leftFrame, "Update");
00199    updateButton->Connect("Clicked()", "TStructViewerGUI", this, "UpdateButtonSlot()");
00200    leftFrame->AddFrame(updateButton, expandX);
00201 
00202    TGTextButton* quitButton = new TGTextButton(leftFrame, "Quit");
00203    leftFrame->AddFrame(quitButton, expandX);
00204    quitButton->Connect("Clicked()", "TApplication", gApplication, "Terminate()");
00205 
00206    fTopVolume = gGeoManager->MakeBox("TOPVolume", fgMedium,100, 100, 100);
00207    gGeoManager->SetTopVolume(fTopVolume);
00208    gGeoManager->SetNsegments(40);
00209     
00210    fCanvas = new TCanvas("", "", 0, 0);
00211    // drawing after creating canvas to avoid drawing in default canvas
00212    fGLViewer = new TGLEmbeddedViewer(this, fCanvas);
00213    AddFrame(fGLViewer->GetFrame(), new TGLayoutHints(kLHintsExpandX| kLHintsExpandY, 10,10,10,10));
00214    fGLViewer->PadPaint(fCanvas);
00215    fGLViewer->Connect("MouseOver(TGLPhysicalShape*)", "TStructViewerGUI", this, "MouseOverSlot(TGLPhysicalShape*)");
00216    fGLViewer->GetGLWidget()->Connect("ProcessedEvent(Event_t*)", "TStructViewerGUI", this, "GLWidgetProcessedEventSlot(Event_t*))");
00217    fGLViewer->Connect("DoubleClicked()", "TStructViewerGUI", this, "DoubleClickedSlot()");
00218    fGLViewer->SetCurrentCamera(TGLViewer::kCameraPerspXOY);
00219    Update();
00220    fGLViewer->SetResetCamerasOnUpdate(false);
00221  
00222    SetWindowName("Struct Viewer");
00223    MapSubwindows();
00224    this->SetWMSizeHints(w, h, 2000, 2000, 0, 0);
00225    Resize(GetDefaultSize());
00226    MapWindow();
00227 
00228    fToolTip = new TGToolTip(0, 0, "ToolTip", 500);
00229 }
00230 
00231 //________________________________________________________________________
00232 TStructViewerGUI::~TStructViewerGUI()
00233 {
00234    // Destructor
00235 
00236    delete fCanvas;
00237 }
00238 
00239 //________________________________________________________________________
00240 void TStructViewerGUI::AutoRefreshButtonSlot(Bool_t on)
00241 {
00242    // Activated when user chage condition
00243 
00244    if (on) {
00245       Update();
00246    }
00247 }
00248 
00249 //________________________________________________________________________
00250 void TStructViewerGUI::BoxHeightValueSetSlot(Long_t /* h */)
00251 {
00252    // Emmited when user changes height of boxes
00253 
00254    if(fAutoRefesh->IsOn()) {
00255       Update();
00256    }
00257 }
00258 
00259 //________________________________________________________________________
00260 void TStructViewerGUI::CalculatePosistion(TStructNode* parent)
00261 {
00262    // Recursive method to calculating nodes posistion in 3D space
00263 
00264    // choose scaling method
00265    if (fScaleBySizeButton->GetState() == kButtonDown) {
00266       TStructNode::SetScaleBy(kSize);
00267    } else if (fScaleByMembersButton->GetState() == kButtonDown) {
00268       TStructNode::SetScaleBy(kMembers);
00269    }
00270    Float_t ratio = (Float_t)((parent->GetLevel()+1.0) / parent->GetLevel());
00271 
00272    // changing the angle between parent object and daughters
00273    // if center of parent is 0 that is real piramid
00274    parent->SetWidth(1);
00275    parent->SetHeight(1);
00276    parent->SetX(-parent->GetWidth()/2);
00277    parent->SetY(-parent->GetHeight()/2);
00278 
00279    fMaxRatio = parent->GetVolumeRatio();
00280 
00281    // sorting list of members by size or number of members
00282    parent->GetMembers()->Sort(kSortDescending);
00283    Divide(parent->GetMembers(), (parent->GetX()) *ratio, (parent->GetX() + parent->GetWidth())* ratio, (parent->GetY())* ratio, (parent->GetY() + parent->GetHeight())*ratio);
00284 
00285    // sclale all the objects
00286    Scale(parent);
00287 }
00288 
00289 //________________________________________________________________________
00290 void TStructViewerGUI::CheckMaxObjects(TStructNode* parent)
00291 {
00292    // Check if all of nodes can be displayed on scene. Hides redendant nodes.
00293 
00294    UInt_t object = 0;
00295 
00296    TList queue;
00297    queue.Add(parent);
00298    TStructNode* node;
00299 
00300    while ((node = (TStructNode*) queue.First() )) {
00301       object++;
00302 
00303       if (object > fNodePtr->GetMaxObjects() || node->GetLevel() - fNodePtr->GetLevel() >= fNodePtr->GetMaxLevel()) {
00304          break;
00305       }
00306 
00307       node->SetVisible(true);
00308 
00309       queue.AddAll(node->GetMembers());
00310       queue.RemoveFirst();
00311 
00312       fVisibleObjects.Add(node);
00313    }
00314 
00315    TIter it(&fVisibleObjects);
00316    TStructNode* member;
00317    while ((node = (TStructNode*) it() )) {
00318       if(node->GetLevel() - fNodePtr->GetLevel() == fNodePtr->GetMaxLevel()-1 && node->GetMembersCount() > 0) {
00319          node->SetCollapsed(true);
00320          continue;
00321       }
00322 
00323       TIter memIt(node->GetMembers());
00324       while ((member = (TStructNode*) memIt() )) {
00325          if(member->IsVisible() == false) {
00326             node->SetCollapsed(true);
00327             break;
00328          }
00329       }
00330    }
00331 }
00332 
00333 //________________________________________________________________________
00334 void TStructViewerGUI::CloseWindow()
00335 {
00336    // Delete window
00337 
00338    DeleteWindow();
00339 }
00340 
00341 //________________________________________________________________________
00342 void TStructViewerGUI::ColorSelectedSlot(Pixel_t pixel)
00343 {
00344    // Slot for default color selsect.
00345    // Sets default colot to "pixel"
00346 
00347    TStructNodeProperty* prop = GetDefaultColor();
00348    if(prop) {
00349       prop->SetColor(pixel);
00350       Update();
00351    }
00352 }
00353 
00354 //________________________________________________________________________
00355 void TStructViewerGUI::Divide(TList* list, Float_t x1, Float_t x2, Float_t y1, Float_t y2)
00356 {
00357    // Divides rectangle where the outlining box is placed.
00358 
00359    if (list->GetSize() > 1) { // spliting node into two lists
00360       ULong_t sum1 = 0, sum = 0;
00361 
00362       TStructNode* node;
00363       TList list1, list2;
00364       TIter it(list);
00365 
00366       while((node = (TStructNode*) it() )) {
00367          sum += node->GetVolume();
00368       }
00369       it.Reset();
00370       while((node = (TStructNode*) it() )) {
00371          if(sum1 >= sum/2.0) {
00372             list2.Add(node);
00373          } else {
00374             sum1 += node->GetVolume();
00375             list1.Add(node);
00376          }
00377       }
00378 
00379       Float_t ratio = (float)sum1/sum;
00380 
00381       Float_t width = x2 - x1;
00382       Float_t height = y2 - y1;
00383       if (width < height) { // vertical split
00384          Float_t split = y1 + ratio * height;
00385          Divide(&list1, x1, x2, y1, split);
00386          Divide(&list2, x1, x2, split, y2);
00387       } else { // horizontal
00388          Float_t split = x1 + ratio * width;
00389          Divide(&list1, x1, split, y1, y2);
00390          Divide(&list2, split, x2, y1, y2);
00391       }
00392    } else if (list->GetSize() == 1) { // divide place to node
00393       TStructNode* node = (TStructNode*)(list->First());
00394 
00395       node->SetWidth(x2 - x1);
00396       node->SetHeight(y2 - y1);
00397       node->SetX(x1);
00398       node->SetY(y1);
00399 
00400       if (node->GetVolumeRatio() > fMaxRatio) {
00401          fMaxRatio = node->GetVolumeRatio();
00402       }
00403 
00404       Float_t ratio = (Float_t)((node->GetLevel()+1.0)/node->GetLevel());
00405       node->GetMembers()->Sort(kSortDescending);
00406       Divide(node->GetMembers(), x1*ratio, x2*ratio, y1*ratio, y2*ratio);
00407    }
00408 }
00409 
00410 //________________________________________________________________________
00411 void TStructViewerGUI::DoubleClickedSlot()
00412 {
00413    // Activated when user double click on objects on 3D scene. Sets clicked node to top node 
00414    // and updates scene with camers reset.
00415 
00416    if (fSelectedObject) {
00417       if(fSelectedObject == fNodePtr) {
00418          return;
00419       }
00420 
00421       fUndoList.Add(fNodePtr);
00422       fNodePtr = fSelectedObject;
00423       fUndoButton->SetEnabled(true);
00424 
00425       Update(kTRUE);
00426    }
00427 }
00428 //________________________________________________________________________
00429 void TStructViewerGUI::Draw(Option_t* /*option*/)
00430 {
00431    // Check limits and draws nodes and links
00432 
00433    fVolumes.Clear();
00434    CheckMaxObjects(fNodePtr);
00435 
00436    CalculatePosistion(fNodePtr);
00437    DrawVolumes(fNodePtr);
00438 
00439    if(fShowLinksCheckButton->GetState() == kButtonDown) {
00440       DrawLink(fNodePtr);
00441    }
00442 
00443    UnCheckMaxObjects();
00444 }
00445 
00446 //________________________________________________________________________
00447 void TStructViewerGUI::DrawLink(TStructNode* parent)
00448 {
00449    // Recursive method to draw links
00450    if(parent->GetLevel() - fNodePtr->GetLevel() >= fNodePtr->GetMaxLevel()) {
00451       return;
00452    }
00453 
00454    if(parent->IsCollapsed()) {
00455       return;
00456    }
00457 
00458    TIter it(parent->GetMembers());
00459    TStructNode* node;
00460    while((node = (TStructNode*) it())) {
00461       TPolyLine3D *l = new TPolyLine3D(2);
00462       l->SetPoint(0 ,node->GetCenter(), node->GetMiddle(), -(node->GetLevel() * fLevelDistanceEntry->GetNumber()));
00463       l->SetPoint(1 ,parent->GetCenter(), parent->GetMiddle(), -(parent->GetLevel() * fLevelDistanceEntry->GetNumber()));
00464 
00465       l->SetLineColor(GetColor(node));
00466       l->SetLineWidth(1);
00467       l->Draw();
00468 
00469       if(!node->IsCollapsed()) {
00470          DrawLink(node);
00471       }
00472    }
00473 }
00474 
00475 //________________________________________________________________________
00476 void TStructViewerGUI::DrawNode(TStructNode* node)
00477 {
00478    // Creates and draws TGeoVolume from given "node"
00479 
00480    TGeoVolume* vol;
00481 
00482    /*if(node->IsCollapsed())
00483    {
00484    //float r = (node->GetWidth() < node->GetHeight() ? 0.5 * node->GetWidth() : 0.5 * node->GetHeight());
00485    //vol = gGeoManager->MakeTorus(node->GetName(),TStructNode::GetMedium(), 0.75*r, 0, r/4);
00486 
00487    vol = gGeoManager->MakeBox(TString(node->GetName()) + "up",TStructNode::GetMedium(), 0.45*node->GetWidth(), 0.45*node->GetHeight(), (node->GetWidth() < node->GetHeight() ? 0.45 * node->GetWidth() : 0.45 * node->GetHeight()));
00488    Double_t max = TMath::Max(0.22 * node->GetWidth(), 0.22 * node->GetHeight());
00489    TGeoVolume* subvol = gGeoManager->MakeTrd2(node->GetName(), TStructNode::GetMedium(), 0, 0.45 * node->GetWidth(), 0, 0.45 * node->GetHeight(), max);
00490    subvol->SetLineColor(GetColor(node));
00491    subvol->SetNumber((Int_t)node);
00492    TGeoTranslation* subtrans = new TGeoTranslation("subtranslation", 0, 0, -max);
00493    vol->AddNodeOverlap(subvol, 1, subtrans);
00494 
00495    subvol = gGeoManager->MakeTrd2(TString(node->GetName()) + "down", TStructNode::GetMedium(), 0.45 * node->GetWidth(), 0, 0.45 * node->GetHeight(), 0, max);
00496    subvol->SetLineColor(GetColor(node));
00497    subvol->SetNumber((Int_t)node);
00498    subtrans = new TGeoTranslation("subtranslation", 0, 0, max);
00499    vol->AddNodeOverlap(subvol, 1, subtrans);
00500    }
00501    else*/ if(node->GetNodeType() == kCollection) {
00502       vol = gGeoManager->MakeBox(Form("%s_%d", node->GetName(), fgCounter++), fgMedium, 0.45*node->GetWidth(), 0.45*node->GetHeight(), fBoxHeightEntry->GetNumber());
00503       // subboxes
00504       Float_t slices = (Float_t)(node->GetMembersCount());
00505       if (slices > fMaxSlices) {
00506          slices = (Float_t)fMaxSlices;
00507       }
00508 
00509       for (Float_t i = -(slices-1)/2; i < slices/2; i++) {
00510          TGeoVolume* sub = gGeoManager->MakeBox(Form("%s_%d", node->GetName(), fgCounter++), fgMedium,0.45*node->GetWidth() * 0.7 / slices, 0.45*node->GetHeight(), fBoxHeightEntry->GetNumber());
00511          sub->SetLineColor(GetColor(node));
00512          fVolumes.Add((Long_t)sub, (Long_t)node);
00513          TGeoTranslation* subtrans = new TGeoTranslation("subtranslation", i * node->GetWidth() / slices, 0, 0);
00514          vol->AddNodeOverlap(sub, 1, subtrans);
00515       }
00516    } else {
00517       vol = gGeoManager->MakeBox(Form("%s_%d", node->GetName(), fgCounter++), fgMedium, 0.45*node->GetWidth(), 0.45*node->GetHeight(), fBoxHeightEntry->GetNumber());
00518    }
00519 
00520    vol->SetLineColor(GetColor(node));
00521    vol->SetLineWidth(1);
00522 
00523    TGeoTranslation* trans = new TGeoTranslation("translation", node->GetCenter(), node->GetMiddle(), -(node->GetLevel() * fLevelDistanceEntry->GetNumber()));
00524    fVolumes.Add((Long_t)vol, (Long_t)node);
00525 
00526    fTopVolume->AddNode(vol,1, trans);
00527 }
00528 
00529 //________________________________________________________________________
00530 void TStructViewerGUI::DrawVolumes(TStructNode* parent)
00531 {
00532    // Recursive method to draw GeoVolumes
00533 
00534    if(parent->GetLevel() - fNodePtr->GetLevel() >= fNodePtr->GetMaxLevel()) {
00535       return;
00536    }
00537 
00538    DrawNode(parent);
00539 
00540    if(parent->IsCollapsed()) {
00541       return;
00542    }
00543 
00544    TIter nextVis(parent->GetMembers());
00545    TStructNode* node;
00546    while((node = (TStructNode*)nextVis())) {
00547       DrawVolumes(node);
00548    }
00549 }
00550 
00551 //________________________________________________________________________
00552 TStructNodeProperty* TStructViewerGUI::FindNodeProperty(TStructNode* node)
00553 {
00554    // Returns pointer to property associated with node "node". If property is not found
00555    // then it returns default property
00556 
00557    TIter it(fColors);
00558    TStructNodeProperty* prop;
00559    while ((prop = (TStructNodeProperty*) it() )) {
00560       TString propName(prop->GetName());
00561       if (propName.EndsWith("+")) {
00562 
00563          if (TClass* cl = TClass::GetClass(node->GetTypeName())) {
00564             propName.Remove(propName.Length()-1, 1);
00565             if (cl->InheritsFrom(propName.Data())) {
00566                return prop;
00567             }
00568          }
00569       } else {
00570          if (propName == TString(node->GetTypeName())) {
00571             return prop;
00572          }
00573       }
00574    }
00575 
00576    return (TStructNodeProperty*)fColors->Last();
00577 }
00578 
00579 //________________________________________________________________________`
00580 TCanvas* TStructViewerGUI::GetCanvas()
00581 {
00582    // Returns canvas used to keep TGeoVolumes
00583 
00584    return fCanvas;
00585 }
00586 //________________________________________________________________________
00587 Int_t TStructViewerGUI::GetColor(TStructNode* node) 
00588 {
00589    // Returns color form fColors for given "node"
00590 
00591    TStructNodeProperty* prop = FindNodeProperty(node);
00592    if (prop) {
00593       return prop->GetColor().GetNumber();
00594    }
00595 
00596    return 2;
00597 }
00598 
00599 //________________________________________________________________________
00600 TStructNodeProperty* TStructViewerGUI::GetDefaultColor()
00601 {
00602    // Return default color for nodes
00603 
00604    return ((TStructNodeProperty*)(fColors->Last()));
00605 }
00606 
00607 //________________________________________________________________________
00608 Bool_t TStructViewerGUI::GetLinksVisibility() const
00609 {
00610    // Returns true if links are visible, otherwise return false.
00611 
00612    if (fShowLinksCheckButton->GetState() == kButtonDown) {
00613       return true;
00614    } else {
00615       return false;
00616    }
00617 }
00618 
00619 //________________________________________________________________________
00620 TStructNode* TStructViewerGUI::GetNodePtr() const
00621 {
00622    // Returns top node pointer
00623 
00624    return fNodePtr;
00625 }
00626 
00627 //________________________________________________________________________
00628 void TStructViewerGUI::GLWidgetProcessedEventSlot(Event_t* event)
00629 {
00630    // Handle events. Sets fMouseX and fMouseY when user move a mouse over viewer and hides ToolTip
00631 
00632    switch (event->fType) {
00633       case kMotionNotify:
00634          fMouseX = event->fXRoot + 15;
00635          fMouseY = event->fYRoot + 15;
00636          break;
00637 
00638       case kButtonPress:
00639          fToolTip->Hide();
00640          if (fSelectedObject) {
00641             UpdateLabels(fSelectedObject);
00642             fEditor->SetModel(fSelectedObject);
00643          }         
00644          break;
00645 
00646       default:
00647          break;
00648    }
00649 }
00650 
00651 //________________________________________________________________________
00652 void TStructViewerGUI::LevelDistValueSetSlot(Long_t /* dist */)
00653 {
00654    // Emmited when user changes distance between levels
00655 
00656    if(fAutoRefesh->IsOn()) {
00657       Update(kTRUE);
00658    }
00659 }
00660 
00661 //________________________________________________________________________
00662 void TStructViewerGUI::MouseOverSlot(TGLPhysicalShape* shape)
00663 {
00664    // MouseOver slot. Activated when user out mouse over object on scene. 
00665    // Sets ToolTip and updates labels
00666 
00667    fToolTip->Hide();
00668    fSelectedObject = NULL;
00669    if (shape && shape->GetLogical()) {
00670       fSelectedObject =  (TStructNode*)(shape->GetLogical()->ID());
00671       if (fSelectedObject) {
00672          if (fSelectedObject->IsA()->InheritsFrom(TPolyLine3D::Class())) {
00673             fSelectedObject = NULL;
00674             return;
00675          }
00676          Long_t shapeID  = (Long_t)(shape->GetLogical()->ID());
00677          Long_t volValue = (Long_t)fVolumes.GetValue(shapeID);
00678          fSelectedObject = (TStructNode*)volValue;
00679          
00680          fToolTip->SetText(TString(fSelectedObject->GetName()) + "\n" + fSelectedObject->GetTypeName());
00681          fToolTip->SetPosition(fMouseX, fMouseY);
00682          fToolTip->Reset();
00683          UpdateLabels(fSelectedObject);
00684       }
00685    }
00686 }
00687 
00688 //________________________________________________________________________
00689 void TStructViewerGUI::RedoButtonSlot()
00690 {
00691    // Activated when user click Redo button. Repeat last Undo action.
00692 
00693    fUndoList.Add(fNodePtr);
00694    fUndoButton->SetEnabled(true);
00695    fNodePtr = (TStructNode*) fRedoList.Last();
00696    fRedoList.RemoveLast();
00697    if (!fRedoList.First()) {
00698       fRedoButton->SetEnabled(false);
00699    }
00700    Update(kTRUE);
00701    UpdateLabels(fNodePtr);
00702 }
00703 
00704 //________________________________________________________________________
00705 void TStructViewerGUI::ResetButtonSlot()
00706 {
00707    // Resets camera
00708 
00709    fGLViewer->UpdateScene();
00710    fGLViewer->ResetCurrentCamera();
00711 }
00712 
00713 //________________________________________________________________________
00714 void TStructViewerGUI::Scale(TStructNode* parent)
00715 {
00716    // Recursive method to scaling all modes on scene. We have to scale nodes to get real ratio between nodes. 
00717    // Uses fMaxRatio.
00718 
00719    // newRatio = sqrt(ratio/maxratio)
00720    Float_t newRatio = (Float_t)(TMath::Sqrt(parent->GetRelativeVolumeRatio()/fMaxRatio));
00721    // set left top conner in the center
00722    parent->SetX(parent->GetX() + parent->GetWidth()/2);
00723    parent->SetY(parent->GetY() + parent->GetHeight()/2);
00724    // set new size
00725    Float_t min = (Float_t)TMath::Min(parent->GetWidth(), parent->GetHeight());
00726    parent->SetWidth(parent->GetWidth() * newRatio);
00727    parent->SetHeight(parent->GetHeight() * newRatio);
00728    // fit the ratio -> height to width
00729    Float_t sqrt = (Float_t)(TMath::Sqrt(parent->GetWidth() * parent->GetHeight()));
00730    // it's a square
00731    if (min > sqrt) {
00732       parent->SetWidth(sqrt);
00733       parent->SetHeight(sqrt);
00734    } else { // it's rectangle
00735       if (parent->GetHeight() > parent->GetWidth()) {
00736          parent->SetWidth(min);
00737          parent->SetHeight(sqrt * sqrt / min);
00738       } else {
00739          parent->SetWidth(sqrt * sqrt / min);
00740          parent->SetHeight(min);
00741       }
00742    }
00743    // move left top corner
00744    parent->SetX(parent->GetX() - parent->GetWidth()/2);
00745    parent->SetY(parent->GetY() - parent->GetHeight()/2);
00746 
00747    // scale others nodes
00748    TStructNode* node;
00749    TIter it(parent->GetMembers());
00750    while ((node = (TStructNode*) it() )) {
00751       Scale(node);
00752    }
00753 }
00754 
00755 //________________________________________________________________________
00756 void TStructViewerGUI::SetNodePtr(TStructNode* val)
00757 {
00758    // Sets top node pointer and updates view
00759 
00760    fNodePtr = val;
00761    Update(kTRUE);
00762 }
00763 
00764 //________________________________________________________________________
00765 void TStructViewerGUI::SetLinksVisibility(Bool_t visible)
00766 {
00767    // Sets links visibility to "visible"
00768 
00769    if (visible) {
00770       fShowLinksCheckButton->SetState(kButtonDown);
00771    } else {
00772       fShowLinksCheckButton->SetState(kButtonUp);
00773    }
00774 }
00775 
00776 //________________________________________________________________________
00777 void TStructViewerGUI::SetPointerButtonSlot()
00778 {
00779    // Sets pointer given in fPointerTestEntry to the main pointer
00780 
00781    void* obj = (void*)gROOT->ProcessLine(fPointerTextEntry->GetText());
00782    fParent->SetPointer(obj, fPointerTypeTextEntry->GetText());
00783 }
00784 
00785 //________________________________________________________________________
00786 void TStructViewerGUI::ShowLinksToggled(Bool_t /*on*/)
00787 {
00788    // Changes links visibility and refresh view.
00789 
00790    if (fAutoRefesh->IsOn()) {
00791       Update();
00792    }
00793 }
00794 
00795 //________________________________________________________________________
00796 void TStructViewerGUI::UnCheckMaxObjects()
00797 {
00798    // Shows hidden nodes
00799 
00800    TStructNode* node;
00801    TIter it(&fVisibleObjects);
00802 
00803    while ((node = (TStructNode*) it() )) {
00804       node->SetCollapsed(false);
00805       node->SetVisible(false);
00806    }
00807 
00808    fVisibleObjects.Clear();
00809 }
00810 
00811 //________________________________________________________________________
00812 void TStructViewerGUI::Update(Bool_t resetCamera)
00813 {
00814    // Updates view. Clear all the nodes, call draw function and update scene. Doesn't reset camera.
00815 
00816    if (!fNodePtr) {
00817       return;
00818    }
00819 
00820    fCanvas->GetListOfPrimitives()->Clear();
00821    fTopVolume->ClearNodes();
00822    Draw();
00823    fCanvas->GetListOfPrimitives()->Add(fTopVolume);
00824    fGLViewer->UpdateScene();
00825 
00826    if(resetCamera) {
00827       fGLViewer->ResetCurrentCamera();
00828    }
00829 }
00830 
00831 //________________________________________________________________________
00832 void TStructViewerGUI::UpdateButtonSlot()
00833 {
00834    // Update button slot. Updates scene
00835 
00836    Update();
00837 }
00838 
00839 //________________________________________________________________________
00840 void TStructViewerGUI::UpdateLabels(TStructNode* node)
00841 {
00842    // Refresh information in labels when user put mouse over object
00843 
00844    fNodeNameLabel->SetText(node->GetName());
00845    fNodeTypelabel->SetText(node->GetTypeName());
00846 
00847    TString name = "Members: ";
00848    name += node->GetMembersCount();
00849    fMembersCountLabel->SetText(name);
00850    name = "All members: ";
00851    name += node->GetAllMembersCount();
00852    fAllMembersCountLabel->SetText(name);
00853    name = "Level: ";
00854    name += node->GetLevel();
00855    fLevelLabel->SetText(name);
00856    name = "Size: ";
00857    name += node->GetSize();
00858    fSizeLabel->SetText(name);
00859    name = "Total size: ";
00860    name += node->GetTotalSize();
00861    fTotalSizeLabel->SetText(name);
00862 }
00863 
00864 //________________________________________________________________________
00865 void TStructViewerGUI::UndoButtonSlot()
00866 {
00867    // UndoButton Slot. Activated when user press Undo button. Restore last top node pointer. 
00868 
00869    fRedoList.Add(fNodePtr);
00870    fRedoButton->SetEnabled(true);
00871    fNodePtr = (TStructNode*) fUndoList.Last();
00872    fUndoList.RemoveLast();
00873    if (!fUndoList.First()) {
00874       fUndoButton->SetEnabled(false);
00875    }
00876    Update(kTRUE);
00877    UpdateLabels(fNodePtr);
00878 }
00879 
00880 //________________________________________________________________________
00881 void TStructViewerGUI::ScaleByChangedSlot()
00882 {
00883    // Activated when user press radio button 
00884 
00885     if (fAutoRefesh->IsOn()) {
00886        Update();
00887     }
00888 }

Generated on Tue Jul 5 14:19:17 2011 for ROOT_528-00b_version by  doxygen 1.5.1