TGLSAViewer.cxx

Go to the documentation of this file.
00001 // @(#)root/gl:$Id: TGLSAViewer.cxx 36973 2010-11-26 11:55:05Z matevz $
00002 // Author:  Timur Pocheptsov / Richard Maunder
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2004, 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 <memory>
00013 
00014 #include "TRootHelpDialog.h"
00015 #include "TPluginManager.h"
00016 #include "TApplication.h"
00017 #include "TGClient.h"
00018 #include "TGCanvas.h"
00019 #include "HelpText.h"
00020 #include "GuiTypes.h"
00021 #include "TG3DLine.h"
00022 #include "TSystem.h"
00023 #include "TGFrame.h"
00024 #include "TGLabel.h"
00025 #include "TGMenu.h"
00026 #include "TGButton.h"
00027 #include "TGSplitter.h"
00028 #include "TColor.h"
00029 
00030 #include "TVirtualPad.h"
00031 #include "TGedEditor.h"
00032 #include "TRootEmbeddedCanvas.h"
00033 #include "TString.h"
00034 #include "TGFileDialog.h"
00035 
00036 #include "TGLOutput.h"
00037 #include "TGLFormat.h"
00038 
00039 #include "TGLLogicalShape.h"
00040 #include "TGLPhysicalShape.h"
00041 #include "TGLPShapeObj.h"
00042 #include "TGLClip.h"
00043 #include "TROOT.h"
00044 
00045 #ifdef WIN32
00046 #include "TWin32SplashThread.h"
00047 #endif
00048 
00049 #include "TGLPhysicalShape.h"
00050 #include "TGLWidget.h"
00051 #include "TGLSAViewer.h"
00052 #include "TGLSAFrame.h"
00053 #include "TGLOutput.h"
00054 #include "TGLEventHandler.h"
00055 
00056 
00057 const char * TGLSAViewer::fgHelpText1 = "\
00058 DIRECT SCENE INTERACTIONS\n\n\
00059    Press:\n\
00060    \tw          --- wireframe mode\n\
00061    \te          --- switch between dark / light color-set\n\
00062    \tr          --- filled polygons mode\n\
00063    \tt          --- outline mode\n\
00064    \tj          --- ZOOM in\n\
00065    \tk          --- ZOOM out\n\
00066    \tArrow Keys --- PAN (TRUCK) across scene\n\
00067    \tHome       --- reset current camera\n\
00068    \tCtrl-Home  --- switch external/automatic camera center\n\
00069 \n\
00070    LEFT mouse button -- ROTATE (ORBIT) the scene by holding the mouse button and moving\n\
00071    the mouse (perspective camera, needs to be enabled in menu for orthograpic cameras).\n\
00072    By default, the scene will be rotated about its center. To select arbitrary center\n\
00073    bring up the viewer-editor (e.g., shift-click into empty background) and use\n\
00074    'Camera center' controls in the 'Guides' tab.\n\
00075 \n\
00076    MIDDLE mouse button or arrow keys --  PAN (TRUCK) the camera.\n\
00077 \n\
00078    RIGHT mouse button action depends on camera type:\n\
00079      orthographic -- zoom,\n\
00080      perspective  -- move camera forwards / backwards\n\
00081 \n\
00082    By pressing Ctrl and Shift keys the mouse precision can be changed:\n\
00083      Shift      -- 10 times less precise\n\
00084      Ctrl       -- 10 times more precise\n\
00085      Ctrl Shift -- 100 times more precise\n\
00086 \n\
00087    Mouse wheel action depends on camera type:\n\
00088      orthographic -- zoom,\n\
00089      perspective  -- change field-of-view (focal length)\n\
00090 \n\
00091    To invert direction of mouse and key actions from scene-centric\n\
00092    to viewer-centric, set in your .rootrc file:\n\
00093       OpenGL.EventHandler.ViewerCentricControls: 1\n\
00094 \n\
00095    Double clik will show GUI editor of the viewer (if assigned).\n\
00096 \n\
00097    RESET the camera via the button in viewer-editor or Home key.\n\
00098 \n\
00099    SELECT a shape with Shift+Left mouse button click.\n\
00100 \n\
00101    SELECT the viewer with Shift+Left mouse button click on a free space.\n\
00102 \n\
00103    MOVE a selected shape using Shift+Mid mouse drag.\n\
00104 \n\
00105    Invoke the CONTEXT menu with Shift+Right mouse click.\n\n"
00106    "Secondary selection and direct render object interaction is initiated\n\
00107    by Alt+Left mouse click (Mod1, actually). Only few classes support this option.\n\
00108    When 'Alt' is taken by window manager, try Alt-Ctrl-Left.\n\
00109 \n\
00110 CAMERA\n\
00111 \n\
00112    The \"Camera\" menu is used to select the different projections from \n\
00113    the 3D world onto the 2D viewport. There are three perspective cameras:\n\
00114 \n\
00115    \tPerspective (Floor XOZ)\n\
00116    \tPerspective (Floor YOZ)\n\
00117    \tPerspective (Floor XOY)\n\
00118 \n\
00119    In each case the floor plane (defined by two axes) is kept level.\n\
00120 \n\
00121    There are also three orthographic cameras:\n\
00122 \n\
00123    \tOrthographic (XOY)\n\
00124    \tOrthographic (XOZ)\n\
00125    \tOrthographic (ZOY)\n\
00126 \n\
00127    In each case the first axis is placed horizontal, the second vertical e.g.\n\
00128    XOY means X horizontal, Y vertical.\n\n";
00129 
00130 const char * TGLSAViewer::fgHelpText2 = "\
00131 SHAPES COLOR AND MATERIAL\n\
00132 \n\
00133    The selected shape's color can be modified in the Shapes-Color tabs.\n\
00134    Shape's color is specified by the percentage of red, green, blue light\n\
00135    it reflects. A surface can reflect DIFFUSE, AMBIENT and SPECULAR light.\n\
00136    A surface can also emit light. The EMISSIVE parameter allows to define it.\n\
00137    The surface SHININESS can also be modified.\n\
00138 \n\
00139 SHAPES GEOMETRY\n\
00140 \n\
00141    The selected shape's location and geometry can be modified in the Shapes-Geom\n\
00142    tabs by entering desired values in respective number entry controls.\n\
00143 \n\
00144 SCENE CLIPPING\n\
00145 \n\
00146    In the Scene-Clipping tabs select a 'Clip Type': None, Plane, Box\n\
00147 \n\
00148    For 'Plane' and 'Box' the lower pane shows the relevant parameters:\n\
00149 \n\
00150 \tPlane: Equation coefficients of form aX + bY + cZ + d = 0\n\
00151 \tBox: Center X/Y/Z and Length X/Y/Z\n\n"
00152    "For Box checking the 'Show / Edit' checkbox shows the clip box (in light blue)\n\
00153    in viewer. It also attaches the current manipulator to the box - enabling\n\
00154    direct editing in viewer.\n\
00155 \n\
00156 MANIPULATORS\n\
00157 \n\
00158    A widget attached to the selected object - allowing direct manipulation\n\
00159    of the object with respect to its local axes.\n\
00160 \n\
00161    There are three modes, toggled with keys while manipulator is active, that is,\n\
00162    mouse pointer is above it (switches color to yellow):\n\
00163    \tMode\t\tWidget Component Style\t\tKey\n\
00164    \t----\t\t----------------------\t\t---\n\
00165    \tTranslation\tLocal axes with arrows\t\tv\n\
00166    \tScale\t\tLocal axes with boxes\t\tx\n\
00167    \tRotate\t\tLocal axes rings\t\tc\n\
00168 \n\
00169    Each widget has three axis components - red (X), green (Y) and blue (Z).\n\
00170    The component turns yellow, indicating an active state, when the mouse is moved\n\
00171    over it. Left click and drag on the active component to adjust the objects\n\
00172    translation, scale or rotation.\n\
00173    Some objects do not support all manipulations (e.g. clipping planes cannot be \n\
00174    scaled). If a manipulation is not permitted the component it drawn in grey and \n\
00175    cannot be selected/dragged.\n";
00176 
00177 
00178 //==============================================================================
00179 // TGLSAViewer
00180 //==============================================================================
00181 
00182 //______________________________________________________________________________
00183 //
00184 // The top level standalone GL-viewer - created via plugin manager.
00185 
00186 
00187 ClassImp(TGLSAViewer);
00188 
00189 Long_t TGLSAViewer::fgMenuHidingTimeout = 400;
00190 
00191 const Int_t TGLSAViewer::fgInitX = 0;
00192 const Int_t TGLSAViewer::fgInitY = 0;
00193 const Int_t TGLSAViewer::fgInitW = 780;
00194 const Int_t TGLSAViewer::fgInitH = 670;
00195 
00196 // A lot of raw pointers/naked new-expressions - good way to discredit C++ (or C++ programmer
00197 // ROOT has system to cleanup - I'll try to use it
00198 
00199 const char *gGLSaveAsTypes[] = {"Encapsulated PostScript", "*.eps",
00200                                 "PDF",                     "*.pdf",
00201                                 "GIF",                     "*.gif",
00202                                 "Animated GIF",            "*.gif+",
00203                                 "JPEG",                    "*.jpg",
00204                                 "PNG",                     "*.png",
00205                                 0, 0};
00206 
00207 //______________________________________________________________________________
00208 TGLSAViewer::TGLSAViewer(TVirtualPad *pad, TGLFormat* format) :
00209    TGLViewer(pad, fgInitX, fgInitY, fgInitW, fgInitH),
00210    fFrame(0),
00211    fFormat(format),
00212    fFileMenu(0),
00213    fFileSaveMenu(0),
00214    fCameraMenu(0),
00215    fHelpMenu(0),
00216    fLeftVerticalFrame(0),
00217    fRightVerticalFrame(0),
00218    fDirName("."),
00219    fTypeIdx(0),
00220    fOverwrite(kFALSE),
00221    fMenuBar(0),
00222    fMenuBut(0),
00223    fHideMenuBar(kFALSE),
00224    fMenuHidingTimer(0),
00225    fMenuHidingShowMenu(kTRUE),
00226    fDeleteMenuBar(kFALSE)
00227 {
00228    // Construct a standalone viewer, bound to supplied 'pad'.
00229 
00230    fFrame = new TGLSAFrame(*this);
00231 
00232    CreateMenus();
00233    CreateFrames();
00234 
00235    fFrame->SetWindowName("ROOT's GL viewer");
00236    fFrame->SetClassHints("GLViewer", "GLViewer");
00237    fFrame->SetMWMHints(kMWMDecorAll, kMWMFuncAll, kMWMInputModeless);
00238    fFrame->MapSubwindows();
00239    fFrame->HideFrame(fMenuBut);
00240 
00241    fFrame->Resize(fFrame->GetDefaultSize());
00242    fFrame->MoveResize(fgInitX, fgInitY, fgInitW, fgInitH);
00243    fFrame->SetWMPosition(fgInitX, fgInitY);
00244 
00245    // set recursive cleanup, but exclude fGedEditor
00246    // destructor of fGedEditor has own way of handling child nodes
00247    TObject* fe = fLeftVerticalFrame->GetList()->First();
00248    fLeftVerticalFrame->GetList()->Remove(fe);
00249    fFrame->SetCleanup(kDeepCleanup);
00250    fLeftVerticalFrame->GetList()->AddFirst(fe);
00251 
00252    Show();
00253 }
00254 
00255 //______________________________________________________________________________
00256 TGLSAViewer::TGLSAViewer(const TGWindow *parent, TVirtualPad *pad, TGedEditor *ged,
00257                          TGLFormat* format) :
00258    TGLViewer(pad, fgInitX, fgInitY, fgInitW, fgInitH),
00259    fFrame(0),
00260    fFormat(format),
00261    fFileMenu(0),
00262    fCameraMenu(0),
00263    fHelpMenu(0),
00264    fLeftVerticalFrame(0),
00265    fRightVerticalFrame(0),
00266    fTypeIdx(0),
00267    fMenuBar(0),
00268    fMenuBut(0),
00269    fHideMenuBar(kFALSE),
00270    fMenuHidingTimer(0),
00271    fMenuHidingShowMenu(kTRUE),
00272    fDeleteMenuBar(kFALSE)
00273 {
00274    // Construct an embedded standalone viewer, bound to supplied 'pad'.
00275    // If format is passed, it gets adopted by the viewer as it might
00276    // need to be reused several times when recreating the GL-widget.
00277    //
00278    // Modified version of the previous constructor for embedding the
00279    // viewer into another frame (parent).
00280 
00281    fGedEditor = ged;
00282    fFrame = new TGLSAFrame(parent, *this);
00283 
00284    CreateMenus();
00285    CreateFrames();
00286 
00287    fFrame->MapSubwindows();
00288    fFrame->HideFrame(fMenuBut);
00289    fFrame->Resize(fFrame->GetDefaultSize());
00290    fFrame->Resize(fgInitW, fgInitH);
00291 
00292    // set recursive cleanup, but exclude fGedEditor
00293    // destructor of fGedEditor has own way of handling child nodes
00294    if (fLeftVerticalFrame)
00295    {
00296       TObject* fe = fLeftVerticalFrame->GetList()->First();
00297       fLeftVerticalFrame->GetList()->Remove(fe);
00298       fFrame->SetCleanup(kDeepCleanup);
00299       fLeftVerticalFrame->GetList()->AddFirst(fe);
00300    }
00301 
00302    Show();
00303 }
00304 
00305 //______________________________________________________________________________
00306 TGLSAViewer::~TGLSAViewer()
00307 {
00308    // Destroy standalone viewer object.
00309 
00310    fGedEditor->DisconnectFromCanvas();
00311 
00312    DisableMenuBarHiding();
00313 
00314    delete fHelpMenu;
00315    delete fCameraMenu;
00316    delete fFileSaveMenu;
00317    delete fFileMenu;
00318    if(fDeleteMenuBar) {
00319       delete fMenuBar;
00320    }
00321    delete fFormat;
00322    delete fFrame;
00323    fGLWidget = 0;
00324 }
00325 
00326 //______________________________________________________________________________
00327 TGCompositeFrame* TGLSAViewer::GetFrame() const
00328 {
00329    // Return the main-frame.
00330 
00331    return fFrame;
00332 }
00333 
00334 //______________________________________________________________________________
00335 void TGLSAViewer::CreateGLWidget()
00336 {
00337    // Create a GLwidget, it is an error if it is already created.
00338    // This is needed for frame-swapping on mac.
00339 
00340    if (fGLWidget) {
00341       Error("CreateGLWidget", "Widget already exists.");
00342       return;
00343    }
00344 
00345    if (fFormat == 0)
00346       fFormat = new TGLFormat;
00347 
00348    fGLWidget = TGLWidget::Create(*fFormat, fRightVerticalFrame, kTRUE, kTRUE, 0, 10, 10);
00349    fGLWidget->SetEventHandler(fEventHandler);
00350 
00351    fRightVerticalFrame->AddFrame(fGLWidget, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
00352    fFrame->Layout();
00353 
00354    fGLWidget->MapWindow();
00355 }
00356 
00357 //______________________________________________________________________________
00358 void TGLSAViewer::DestroyGLWidget()
00359 {
00360    // Destroy the GLwidget, it is an error if it does not exist.
00361    // This is needed for frame-swapping on mac.
00362 
00363    if (fGLWidget == 0) {
00364       Error("DestroyGLWidget", "Widget does not exist.");
00365       return;
00366    }
00367 
00368    fGLWidget->UnmapWindow();
00369    fGLWidget->SetEventHandler(0);
00370 
00371    fRightVerticalFrame->RemoveFrame(fGLWidget);
00372    fGLWidget->DeleteWindow();
00373    fGLWidget = 0;
00374 }
00375 
00376 //______________________________________________________________________________
00377 void TGLSAViewer::CreateMenus()
00378 {
00379    //File/Camera/Help menus.
00380 
00381    fFileMenu = new TGPopupMenu(fFrame->GetClient()->GetDefaultRoot());
00382    fFileMenu->AddEntry("&Hide Menus", kGLHideMenus);
00383    fFileMenu->AddEntry("&Edit Object", kGLEditObject);
00384    fFileMenu->AddSeparator();
00385    fFileMenu->AddEntry("&Close Viewer", kGLCloseViewer);
00386    fFileMenu->AddSeparator();
00387    fFileSaveMenu = new TGPopupMenu(fFrame->GetClient()->GetDefaultRoot());
00388    fFileSaveMenu->AddEntry("viewer.&eps", kGLSaveEPS);
00389    fFileSaveMenu->AddEntry("viewer.&pdf", kGLSavePDF);
00390    fFileSaveMenu->AddEntry("viewer.&gif", kGLSaveGIF);
00391    fFileSaveMenu->AddEntry("viewer.g&if+", kGLSaveAnimGIF);
00392    fFileSaveMenu->AddEntry("viewer.&jpg", kGLSaveJPG);
00393    fFileSaveMenu->AddEntry("viewer.p&ng", kGLSavePNG);
00394    fFileMenu->AddPopup("&Save", fFileSaveMenu);
00395    fFileMenu->AddEntry("Save &As...", kGLSaveAS);
00396    fFileMenu->AddSeparator();
00397    fFileMenu->AddEntry("&Quit ROOT", kGLQuitROOT);
00398    fFileMenu->Associate(fFrame);
00399 
00400    fCameraMenu = new TGPopupMenu(fFrame->GetClient()->GetDefaultRoot());
00401    fCameraMenu->AddEntry("Perspective (Floor XOZ)", kGLPerspXOZ);
00402    fCameraMenu->AddEntry("Perspective (Floor YOZ)", kGLPerspYOZ);
00403    fCameraMenu->AddEntry("Perspective (Floor XOY)", kGLPerspXOY);
00404    fCameraMenu->AddEntry("Orthographic (XOY)", kGLXOY);
00405    fCameraMenu->AddEntry("Orthographic (XOZ)", kGLXOZ);
00406    fCameraMenu->AddEntry("Orthographic (ZOY)", kGLZOY);
00407    fCameraMenu->AddEntry("Orthographic (XnOY)", kGLXnOY);
00408    fCameraMenu->AddEntry("Orthographic (XnOZ)", kGLXnOZ);
00409    fCameraMenu->AddEntry("Orthographic (ZnOY)", kGLZnOY);
00410    fCameraMenu->AddSeparator();
00411    fCameraMenu->AddEntry("Ortho allow rotate", kGLOrthoRotate);
00412    fCameraMenu->AddEntry("Ortho allow dolly",  kGLOrthoDolly);
00413    fCameraMenu->Associate(fFrame);
00414 
00415    fHelpMenu = new TGPopupMenu(fFrame->GetClient()->GetDefaultRoot());
00416    fHelpMenu->AddEntry("Help on GL Viewer...", kGLHelpViewer);
00417    fHelpMenu->AddSeparator();
00418    fHelpMenu->AddEntry("&About ROOT...", kGLHelpAbout);
00419    fHelpMenu->Associate(fFrame);
00420 
00421    // Create menubar
00422    fMenuBar = new TGMenuBar(fFrame);
00423    fMenuBar->AddPopup("&File", fFileMenu, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0));
00424    fMenuBar->AddPopup("&Camera", fCameraMenu, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0));
00425    fMenuBar->AddPopup("&Help",   fHelpMenu,   new TGLayoutHints(kLHintsTop | kLHintsRight));
00426    fFrame->AddFrame(fMenuBar, new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX, 0, 0, 1, 1));
00427    gVirtualX->SelectInput(fMenuBar->GetId(),
00428                           kKeyPressMask | kExposureMask | kPointerMotionMask
00429                           | kStructureNotifyMask | kFocusChangeMask
00430                           | kEnterWindowMask | kLeaveWindowMask);
00431 
00432    fMenuBut = new TGButton(fFrame);
00433    fMenuBut->ChangeOptions(kRaisedFrame | kFixedHeight);
00434    fMenuBut->Resize(20, 4);
00435    fMenuBut->SetBackgroundColor(0x80A0C0);
00436    fFrame->AddFrame(fMenuBut, new TGLayoutHints(kLHintsNormal | kLHintsExpandX, 0, 0, 1, 1));
00437 }
00438 
00439 //______________________________________________________________________________
00440 void TGLSAViewer::CreateFrames()
00441 {
00442    // Internal frames creation.
00443 
00444    TGCompositeFrame* compositeFrame = fFrame;
00445    if (fGedEditor == 0)
00446    {
00447       compositeFrame = new TGCompositeFrame(fFrame, 100, 100, kHorizontalFrame | kRaisedFrame);
00448       fFrame->AddFrame(compositeFrame, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
00449 
00450       fLeftVerticalFrame = new TGVerticalFrame(compositeFrame, 195, 10, kFixedWidth);
00451       compositeFrame->AddFrame(fLeftVerticalFrame, new TGLayoutHints(kLHintsLeft | kLHintsExpandY, 2, 2, 2, 2));
00452 
00453       const TGWindow* cw =  fFrame->GetClient()->GetRoot();
00454       fFrame->GetClient()->SetRoot(fLeftVerticalFrame);
00455 
00456       fGedEditor = new TGedEditor();
00457       fGedEditor->GetTGCanvas()->ChangeOptions(0);
00458       fLeftVerticalFrame->RemoveFrame(fGedEditor);
00459       fLeftVerticalFrame->AddFrame(fGedEditor, new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX | kLHintsExpandY, 0, 0, 2, 2));
00460       fLeftVerticalFrame->GetClient()->SetRoot((TGWindow*)cw);
00461       fLeftVerticalFrame->MapSubwindows();
00462 
00463       TGVSplitter *splitter = new TGVSplitter(compositeFrame);
00464       splitter->SetFrame(fLeftVerticalFrame, kTRUE);
00465       compositeFrame->AddFrame(splitter, new TGLayoutHints(kLHintsLeft | kLHintsExpandY, 0,1,2,2) );
00466    }
00467 
00468    // SunkenFrame introduces 1-pixel offset - in TGFrame.cxx:163
00469    //
00470    // TGVerticalFrame *rightVerticalFrame = new TGVerticalFrame(compositeFrame, 10, 10, kSunkenFrame);
00471    // compositeFrame->AddFrame(rightVerticalFrame, new TGLayoutHints(kLHintsRight | kLHintsExpandX | kLHintsExpandY,0,2,2,2));
00472    fRightVerticalFrame = new TGVerticalFrame(compositeFrame, 10, 10);
00473    compositeFrame->AddFrame(fRightVerticalFrame, new TGLayoutHints(kLHintsRight | kLHintsExpandX | kLHintsExpandY));
00474 
00475    fEventHandler = new TGLEventHandler(0, this);
00476    CreateGLWidget();
00477 }
00478 
00479 //______________________________________________________________________________
00480 void TGLSAViewer::SelectionChanged()
00481 {
00482    // Update GUI components for embedded viewer selection change.
00483    // Override from TGLViewer.
00484 
00485    TGLPhysicalShape *selected = const_cast<TGLPhysicalShape*>(GetSelected());
00486 
00487    if (selected) {
00488       fPShapeWrap->fPShape = selected;
00489       if (fFileMenu->IsEntryChecked(kGLEditObject))
00490          fGedEditor->SetModel(fPad, selected->GetLogical()->GetExternal(), kButton1Down);
00491       else
00492          fGedEditor->SetModel(fPad, fPShapeWrap, kButton1Down);
00493    } else {
00494       fPShapeWrap->fPShape = 0;
00495       fGedEditor->SetModel(fPad, this, kButton1Down);
00496    }
00497 }
00498 
00499 //______________________________________________________________________________
00500 void TGLSAViewer::Show()
00501 {
00502    // Show the viewer
00503    fFrame->MapRaised();
00504    fGedEditor->SetModel(fPad, this, kButton1Down);
00505    RequestDraw();
00506 }
00507 
00508 //______________________________________________________________________________
00509 void TGLSAViewer::Close()
00510 {
00511    // Close the viewer - destructed.
00512 
00513    // Commit suicide when contained GUI is closed.
00514    delete this;
00515 }
00516 
00517 //______________________________________________________________________________
00518 void TGLSAViewer::DeleteMenuBar()
00519 {
00520    // Delete the menu bar.
00521    fDeleteMenuBar=kTRUE;
00522 }
00523 
00524 //______________________________________________________________________________
00525 void TGLSAViewer::DisableCloseMenuEntries()
00526 {
00527    // Deactivate menu entries for closing the GL window and exiting ROOT.
00528 
00529    fFileMenu->DeleteEntry(kGLCloseViewer);
00530    fFileMenu->DeleteEntry(kGLQuitROOT);
00531 }
00532 
00533 //______________________________________________________________________________
00534 void TGLSAViewer::EnableMenuBarHiding()
00535 {
00536    // Enable hiding of menu bar.
00537 
00538    if (fHideMenuBar)
00539       return;
00540 
00541    fHideMenuBar = kTRUE;
00542 
00543    fMenuBar->Connect("ProcessedEvent(Event_t*)", "TGLSAViewer", this, "HandleMenuBarHiding(Event_t*)");
00544    fMenuBut->Connect("ProcessedEvent(Event_t*)", "TGLSAViewer", this, "HandleMenuBarHiding(Event_t*)");
00545 
00546    fFrame->HideFrame(fMenuBar);
00547    fFrame->ShowFrame(fMenuBut);
00548    fFrame->Layout();
00549 
00550    fMenuHidingTimer = new TTimer;
00551    fMenuHidingTimer->Connect("Timeout()", "TGLSAViewer", this, "MenuHidingTimeout()");
00552 
00553    fFileMenu->CheckEntry(kGLHideMenus);
00554 }
00555 
00556 //______________________________________________________________________________
00557 void TGLSAViewer::DisableMenuBarHiding()
00558 {
00559    // Disable hiding of menu bar.
00560 
00561    if (!fHideMenuBar)
00562       return;
00563 
00564    fHideMenuBar = kFALSE;
00565 
00566    fMenuBar->Disconnect("ProcessedEvent(Event_t*)", this, "HandleMenuBarHiding(Event_t*)");
00567    fMenuBut->Disconnect("ProcessedEvent(Event_t*)", this, "HandleMenuBarHiding(Event_t*)");
00568 
00569    fFrame->ShowFrame(fMenuBar);
00570    fFrame->HideFrame(fMenuBut);
00571    fFrame->Layout();
00572 
00573    fMenuHidingTimer->TurnOff();
00574    delete fMenuHidingTimer;
00575    fMenuHidingTimer = 0;
00576 
00577    fFileMenu->UnCheckEntry(kGLHideMenus);
00578 }
00579 
00580 //______________________________________________________________________________
00581 void TGLSAViewer::HandleMenuBarHiding(Event_t* ev)
00582 {
00583    // Maybe switch menu-bar / menu-button.
00584 
00585    TGFrame *f = (TGFrame*) gTQSender;
00586 
00587    if (f == fMenuBut)
00588    {
00589       if (ev->fType == kEnterNotify)
00590          ResetMenuHidingTimer(kTRUE);
00591       else
00592          fMenuHidingTimer->TurnOff();
00593    }
00594    else if (f == fMenuBar)
00595    {
00596       if (ev->fType == kLeaveNotify &&
00597           (ev->fX < 0 || ev->fX >= (Int_t) f->GetWidth() ||
00598            ev->fY < 0 || ev->fY >= (Int_t) f->GetHeight()))
00599       {
00600          if (fMenuBar->GetCurrent() == 0)
00601             ResetMenuHidingTimer(kFALSE);
00602          else
00603             fMenuBar->GetCurrent()->Connect("ProcessedEvent(Event_t*)", "TGLSAViewer", this, "HandleMenuBarHiding(Event_t*)");
00604       }
00605       else
00606       {
00607          fMenuHidingTimer->TurnOff();
00608       }
00609    }
00610    else
00611    {
00612       f->Disconnect("ProcessedEvent(Event_t*)", this);
00613       ResetMenuHidingTimer(kFALSE);
00614    }
00615 }
00616 
00617 //______________________________________________________________________________
00618 void TGLSAViewer::ResetMenuHidingTimer(Bool_t show_menu)
00619 {
00620    // Reset the timer for menu-bar hiding.
00621 
00622    // This happens, mysteriously.
00623    if (fMenuHidingTimer == 0)
00624       return;
00625 
00626    fMenuHidingTimer->TurnOff();
00627 
00628    fMenuHidingShowMenu = show_menu;
00629 
00630    fMenuHidingTimer->SetTime(fgMenuHidingTimeout);
00631    fMenuHidingTimer->Reset();
00632    fMenuHidingTimer->TurnOn();
00633 }
00634 
00635 //______________________________________________________________________________
00636 void TGLSAViewer::MenuHidingTimeout()
00637 {
00638    // Action for menu-hiding timeout.
00639 
00640    fMenuHidingTimer->TurnOff();
00641    if (fMenuHidingShowMenu) {
00642       fFrame->HideFrame(fMenuBut);
00643       fFrame->ShowFrame(fMenuBar);
00644    } else {
00645       fFrame->HideFrame(fMenuBar);
00646       fFrame->ShowFrame(fMenuBut);
00647    }
00648    fFrame->Layout();
00649 }
00650 
00651 //______________________________________________________________________________
00652 void TGLSAViewer::SetMenuHidingTimeout(Long_t timeout)
00653 {
00654    // Set global timeout for menu-hiding in mili-seconds.
00655    // Static function.
00656 
00657    fgMenuHidingTimeout = timeout;
00658 }
00659 
00660 //______________________________________________________________________________
00661 Bool_t TGLSAViewer::ProcessFrameMessage(Long_t msg, Long_t parm1, Long_t)
00662 {
00663    // Process GUI message capture by the main GUI frame (TGLSAFrame).
00664 
00665    switch (GET_MSG(msg)) {
00666    case kC_COMMAND:
00667       switch (GET_SUBMSG(msg)) {
00668       case kCM_BUTTON:
00669       case kCM_MENU:
00670          switch (parm1) {
00671          case kGLHelpAbout: {
00672 #ifdef R__UNIX
00673             TString rootx;
00674 #ifdef ROOTBINDIR
00675             rootx = ROOTBINDIR;
00676 #else
00677             rootx = gSystem->Getenv("ROOTSYS");
00678             if (!rootx.IsNull()) rootx += "/bin";
00679 #endif
00680             rootx += "/root -a &";
00681             gSystem->Exec(rootx);
00682 #else
00683 #ifdef WIN32
00684             new TWin32SplashThread(kTRUE);
00685 #else
00686             char str[32];
00687             snprintf(str,32, "About ROOT %s...", gROOT->GetVersion());
00688             hd = new TRootHelpDialog(this, str, 600, 400);
00689             hd->SetText(gHelpAbout);
00690             hd->Popup();
00691 #endif
00692 #endif
00693             break;
00694          }
00695          case kGLHelpViewer: {
00696             TRootHelpDialog * hd = new TRootHelpDialog(fFrame, "Help on GL Viewer...", 660, 400);
00697             hd->AddText(fgHelpText1);
00698             hd->AddText(fgHelpText2);
00699             hd->Popup();
00700             break;
00701          }
00702          case kGLPerspYOZ:
00703             SetCurrentCamera(TGLViewer::kCameraPerspYOZ);
00704             break;
00705          case kGLPerspXOZ:
00706             SetCurrentCamera(TGLViewer::kCameraPerspXOZ);
00707             break;
00708          case kGLPerspXOY:
00709             SetCurrentCamera(TGLViewer::kCameraPerspXOY);
00710             break;
00711          case kGLXOY:
00712             SetCurrentCamera(TGLViewer::kCameraOrthoXOY);
00713             break;
00714          case kGLXOZ:
00715             SetCurrentCamera(TGLViewer::kCameraOrthoXOZ);
00716             break;
00717          case kGLZOY:
00718             SetCurrentCamera(TGLViewer::kCameraOrthoZOY);
00719             break;
00720          case kGLXnOY:
00721             SetCurrentCamera(TGLViewer::kCameraOrthoXnOY);
00722             break;
00723          case kGLXnOZ:
00724             SetCurrentCamera(TGLViewer::kCameraOrthoXnOZ);
00725             break;
00726          case kGLZnOY:
00727             SetCurrentCamera(TGLViewer::kCameraOrthoZnOY);
00728             break;
00729          case kGLOrthoRotate:
00730             ToggleOrthoRotate();
00731             break;
00732          case kGLOrthoDolly:
00733             ToggleOrthoDolly();
00734             break;
00735          case kGLSaveEPS:
00736             SavePicture("viewer.eps");
00737             break;
00738          case kGLSavePDF:
00739             SavePicture("viewer.pdf");
00740             break;
00741          case kGLSaveGIF:
00742             SavePicture("viewer.gif");
00743             break;
00744          case kGLSaveAnimGIF:
00745             SavePicture("viewer.gif+");
00746             break;
00747          case kGLSaveJPG:
00748             SavePicture("viewer.jpg");
00749             break;
00750          case kGLSavePNG:
00751             SavePicture("viewer.png");
00752             break;
00753          case kGLSaveAS:
00754             {
00755                TGFileInfo fi;
00756                fi.fFileTypes   = gGLSaveAsTypes;
00757                fi.fIniDir      = StrDup(fDirName);
00758                fi.fFileTypeIdx = fTypeIdx;
00759                fi.fOverwrite   = fOverwrite;
00760                new TGFileDialog(gClient->GetDefaultRoot(), fFrame, kFDSave, &fi);
00761                if (!fi.fFilename) return kTRUE;
00762                TString ft(fi.fFileTypes[fi.fFileTypeIdx+1]);
00763                fDirName   = fi.fIniDir;
00764                fTypeIdx   = fi.fFileTypeIdx;
00765                fOverwrite = fi.fOverwrite;
00766 
00767                TString file = fi.fFilename;
00768                Bool_t  match = kFALSE;
00769                const char** fin = gGLSaveAsTypes; ++fin;
00770                while (*fin != 0)
00771                {
00772                   if (file.EndsWith(*fin + 1))
00773                   {
00774                      match = kTRUE;
00775                      break;
00776                   }
00777                   fin += 2;
00778                }
00779                if ( ! match)
00780                {
00781                   file += ft(ft.Index("."), ft.Length());
00782                }
00783                SavePicture(file);
00784             }
00785             break;
00786          case kGLHideMenus:
00787             if (fHideMenuBar)
00788                DisableMenuBarHiding();
00789             else
00790                EnableMenuBarHiding();
00791             break;
00792          case kGLEditObject:
00793             ToggleEditObject();
00794             break;
00795          case kGLCloseViewer:
00796             // Exit needs to be delayed to avoid bad drawable X ids - GUI
00797             // will all be changed in future anyway
00798             TTimer::SingleShot(50, "TGLSAFrame", fFrame, "SendCloseMessage()");
00799             break;
00800          case kGLQuitROOT:
00801             if (!gApplication->ReturnFromRun())
00802                delete this;
00803             gApplication->Terminate(0);
00804             break;
00805          default:
00806             break;
00807          }
00808       default:
00809          break;
00810       }
00811    default:
00812       break;
00813    }
00814 
00815    return kTRUE;
00816 }
00817 
00818 //______________________________________________________________________________
00819 void TGLSAViewer::ToggleEditObject()
00820 {
00821    // Toggle state of the 'Edit Object' menu entry.
00822 
00823    if (fFileMenu->IsEntryChecked(kGLEditObject))
00824       fFileMenu->UnCheckEntry(kGLEditObject);
00825    else
00826       fFileMenu->CheckEntry(kGLEditObject);
00827    SelectionChanged();
00828 }
00829 
00830 //______________________________________________________________________________
00831 void TGLSAViewer::ToggleOrthoRotate()
00832 {
00833    // Toggle state of the 'Ortho allow rotate' menu entry.
00834 
00835    if (fCameraMenu->IsEntryChecked(kGLOrthoRotate))
00836       fCameraMenu->UnCheckEntry(kGLOrthoRotate);
00837    else
00838       fCameraMenu->CheckEntry(kGLOrthoRotate);
00839    Bool_t state = fCameraMenu->IsEntryChecked(kGLOrthoRotate);
00840    fOrthoXOYCamera.SetEnableRotate(state);
00841    fOrthoXOZCamera.SetEnableRotate(state);
00842    fOrthoZOYCamera.SetEnableRotate(state);
00843    fOrthoXnOYCamera.SetEnableRotate(state);
00844    fOrthoXnOZCamera.SetEnableRotate(state);
00845    fOrthoZnOYCamera.SetEnableRotate(state);
00846 }
00847 
00848 //______________________________________________________________________________
00849 void TGLSAViewer::ToggleOrthoDolly()
00850 {
00851    // Toggle state of the 'Ortho allow dolly' menu entry.
00852 
00853    if (fCameraMenu->IsEntryChecked(kGLOrthoDolly))
00854       fCameraMenu->UnCheckEntry(kGLOrthoDolly);
00855    else
00856       fCameraMenu->CheckEntry(kGLOrthoDolly);
00857    Bool_t state = ! fCameraMenu->IsEntryChecked(kGLOrthoDolly);
00858    fOrthoXOYCamera.SetDollyToZoom(state);
00859    fOrthoXOZCamera.SetDollyToZoom(state);
00860    fOrthoZOYCamera.SetDollyToZoom(state);
00861 }

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