TCanvas.cxx

Go to the documentation of this file.
00001 // @(#)root/gpad:$Id: TCanvas.cxx 36278 2010-10-11 08:26:49Z couet $
00002 // Author: Rene Brun   12/12/94
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, 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 <string.h>
00013 #include <stdlib.h>
00014 
00015 #include "Riostream.h"
00016 #include "TROOT.h"
00017 #include "TCanvas.h"
00018 #include "TClass.h"
00019 #include "TStyle.h"
00020 #include "TText.h"
00021 #include "TBox.h"
00022 #include "TCanvasImp.h"
00023 #include "TDialogCanvas.h"
00024 #include "TGuiFactory.h"
00025 #include "TEnv.h"
00026 #include "TError.h"
00027 #include "TContextMenu.h"
00028 #include "TControlBar.h"
00029 #include "TInterpreter.h"
00030 #include "TApplication.h"
00031 #include "TColor.h"
00032 #include "TVirtualPadEditor.h"
00033 #include "TVirtualViewer3D.h"
00034 #include "TPadPainter.h"
00035 #include "TVirtualGL.h"
00036 #include "TVirtualPS.h"
00037 #include "TObjectSpy.h"
00038 #include "TAxis.h"
00039 #include "TView.h"
00040 
00041 class TCanvasInit {
00042 public:
00043    TCanvasInit() { TApplication::NeedGraphicsLibs(); }
00044 };
00045 static TCanvasInit gCanvasInit;
00046 
00047 
00048 //*-*x16 macros/layout_canvas
00049 
00050 Bool_t TCanvas::fgIsFolder = kFALSE;
00051 
00052 const Size_t kDefaultCanvasSize   = 20;
00053 
00054 ClassImpQ(TCanvas)
00055 
00056 
00057 //______________________________________________________________________________
00058 /* Begin_Html
00059 <center><h2>The Canvas class</h2></center>
00060 
00061 A Canvas is an area mapped to a window directly under the control of the display
00062 manager. A ROOT session may have several canvases open at any given time.
00063 <p>
00064 A Canvas may be subdivided into independent graphical areas: the <b>Pads</b>.
00065 A canvas has a default pad which has the name of the canvas itself.
00066 An example of a Canvas layout is sketched in the picture below.
00067 
00068 <pre>
00069      ***********************************************************************
00070      *                       Menus bar for Canvas                          *
00071      ***********************************************************************
00072      *                                                                     *
00073      *  ************************************    *************************  *
00074      *  *                                  *    *                       *  *
00075      *  *                                  *    *                       *  *
00076      *  *                                  *    *                       *  *
00077      *  *                                  *    *                       *  *
00078      *  *                                  *    *                       *  *
00079      *  *                                  *    *                       *  *
00080      *  *              Pad 1               *    *        Pad 2          *  *
00081      *  *                                  *    *                       *  *
00082      *  *                                  *    *                       *  *
00083      *  *                                  *    *                       *  *
00084      *  *                                  *    *                       *  *
00085      *  *                                  *    *                       *  *
00086      *  *                                  *    *                       *  *
00087      *  ************************************    *************************  *
00088      *                                                                     *
00089      ***********************************************************************
00090 </pre>
00091 
00092 This canvas contains two pads named P1 and P2. Both Canvas, P1 and P2 can be
00093 moved, grown, shrinked using the normal rules of the Display manager.
00094 <p>
00095 The image below shows a canvas with 4 pads:
00096 
00097 <center>
00098 <img src="gif/canvas_layout.gif">
00099 </center>
00100 
00101 Once objects have been drawn in a canvas, they can be edited/moved by pointing
00102 directly to them. The cursor shape is changed to suggest the type of action that
00103 one can do on this object. Clicking with the right mouse button on an object
00104 pops-up a contextmenu with a complete list of actions possible on this object.
00105 <p>
00106 A graphical editor may be started from the canvas "View" menu under the menu
00107 entry "Toolbar".
00108 <p>
00109 An interactive HELP is available by clicking on the HELP button at the top right
00110 of the canvas. It gives a short explanation about the canvas' menus.
00111 <p>
00112 A canvas may be automatically divided into pads via <tt>TPad::Divide</tt>.
00113 <p>
00114 At creation time, the canvas size defines the size of the canvas window
00115 (including the window manager's decoration). To define precisely the graphics
00116 area size of a canvas, the following four lines of code should be used:
00117 <pre>
00118    {
00119       Double_t w = 600;
00120       Double_t h = 600;
00121       TCanvas * c1 = new TCanvas("c", "c", w, h);
00122       c->SetWindowSize(w + (w - c->GetWw()), h + (h - c->GetWh()));
00123    }
00124 </pre>
00125 End_Html */
00126 
00127 
00128 //______________________________________________________________________________
00129 TCanvas::TCanvas(Bool_t build) : TPad(), fDoubleBuffer(0)
00130 {
00131    // Canvas default constructor.
00132 
00133    fPainter = 0;
00134    fUseGL = gStyle->GetCanvasPreferGL();
00135 
00136    if (!build || TClass::IsCallingNew() != TClass::kRealNew) {
00137       Constructor();
00138    } else {
00139       const char *defcanvas = gROOT->GetDefCanvasName();
00140       char *cdef;
00141 
00142       TList *lc = (TList*)gROOT->GetListOfCanvases();
00143       if (lc->FindObject(defcanvas))
00144          cdef = StrDup(Form("%s_n%d",defcanvas,lc->GetSize()+1));
00145       else
00146          cdef = StrDup(Form("%s",defcanvas));
00147       Constructor(cdef, cdef, 1);
00148       delete [] cdef;
00149    }
00150 }
00151 
00152 
00153 //______________________________________________________________________________
00154 void TCanvas::Constructor()
00155 {
00156    // Canvas default constructor
00157 
00158    if (gThreadXAR) {
00159       void *arr[2];
00160       arr[1] = this;
00161       if ((*gThreadXAR)("CANV", 2, arr, 0)) return;
00162    }
00163 
00164    fCanvas    = 0;
00165    fCanvasID  = -1;
00166    fCanvasImp = 0;
00167    fBatch     = kTRUE;
00168    fUpdating  = kFALSE;
00169 
00170    fContextMenu   = 0;
00171    fSelected      = 0;
00172    fClickSelected = 0;
00173    fSelectedPad   = 0;
00174    fClickSelectedPad = 0;
00175    fPadSave       = 0;
00176    SetBit(kAutoExec);
00177    SetBit(kShowEditor);
00178    SetBit(kShowToolBar);
00179 }
00180 
00181 
00182 //______________________________________________________________________________
00183 TCanvas::TCanvas(const char *name, Int_t ww, Int_t wh, Int_t winid) : TPad(), fDoubleBuffer(0)
00184 {
00185    // Create an embedded canvas, i.e. a canvas that is in a TGCanvas widget
00186    // which is placed in a TGFrame. This ctor is only called via the
00187    // TRootEmbeddedCanvas class.
00188    //
00189    //  If "name" starts with "gl" the canvas is ready to receive GL output.
00190 
00191    fPainter = 0;
00192    Init();
00193 
00194    fCanvasID     = winid;
00195    fWindowTopX   = 0;
00196    fWindowTopY   = 0;
00197    fWindowWidth  = ww;
00198    fWindowHeight = wh;
00199    fCw           = ww + 4;
00200    fCh           = wh +28;
00201    fBatch        = kFALSE;
00202    fUpdating     = kFALSE;
00203 
00204    //This is a very special ctor. A window exists already!
00205    //Can create painter now.
00206    fUseGL = gStyle->GetCanvasPreferGL();
00207 
00208    if (fUseGL) {
00209       fGLDevice = gGLManager->CreateGLContext(winid);
00210       if (fGLDevice == -1)
00211          fUseGL = kFALSE;
00212    }
00213 
00214    CreatePainter();
00215 
00216    fCanvasImp    = gBatchGuiFactory->CreateCanvasImp(this, name, fCw, fCh);
00217    SetName(name);
00218    Build();
00219 }
00220 
00221 
00222 //_____________________________________________________________________________
00223 TCanvas::TCanvas(const char *name, const char *title, Int_t form) : TPad(), fDoubleBuffer(0)
00224 {
00225    //  Create a new canvas with a predefined size form.
00226    //  If form < 0  the menubar is not shown.
00227    //
00228    //  form = 1    700x500 at 10,10 (set by TStyle::SetCanvasDefH,W,X,Y)
00229    //  form = 2    500x500 at 20,20
00230    //  form = 3    500x500 at 30,30
00231    //  form = 4    500x500 at 40,40
00232    //  form = 5    500x500 at 50,50
00233    //
00234    //  If "name" starts with "gl" the canvas is ready to receive GL output.
00235 
00236    fPainter = 0;
00237    fUseGL = gStyle->GetCanvasPreferGL();
00238 
00239    Constructor(name, title, form);
00240 }
00241 
00242 
00243 //_____________________________________________________________________________
00244 void TCanvas::Constructor(const char *name, const char *title, Int_t form)
00245 {
00246    //  Create a new canvas with a predefined size form.
00247    //  If form < 0  the menubar is not shown.
00248    //
00249    //  form = 1    700x500 at 10,10 (set by TStyle::SetCanvasDefH,W,X,Y)
00250    //  form = 2    500x500 at 20,20
00251    //  form = 3    500x500 at 30,30
00252    //  form = 4    500x500 at 40,40
00253    //  form = 5    500x500 at 50,50
00254 
00255    if (gThreadXAR) {
00256       void *arr[6];
00257       static Int_t ww = 500;
00258       static Int_t wh = 500;
00259       arr[1] = this; arr[2] = (void*)name; arr[3] = (void*)title; arr[4] =&ww; arr[5] = &wh;
00260       if ((*gThreadXAR)("CANV", 6, arr, 0)) return;
00261    }
00262 
00263    Init();
00264    SetBit(kMenuBar,1);
00265    if (form < 0) {
00266       form     = -form;
00267       SetBit(kMenuBar,0);
00268    }
00269    fCanvasID = -1;
00270    TCanvas *old = (TCanvas*)gROOT->GetListOfCanvases()->FindObject(name);
00271    if (old && old->IsOnHeap()) {
00272       Warning("Constructor","Deleting canvas with same name: %s",name);
00273       delete old;
00274    }
00275    if (strlen(name) == 0 || gROOT->IsBatch()) {   //We are in Batch mode
00276       fWindowTopX = fWindowTopY = 0;
00277       if (form == 1) {
00278          fWindowWidth  = gStyle->GetCanvasDefW();
00279          fWindowHeight = gStyle->GetCanvasDefH();
00280       } else {
00281          fWindowWidth  = 500;
00282          fWindowHeight = 500;
00283       }
00284       fCw           = fWindowWidth;
00285       fCh           = fWindowHeight;
00286       fCanvasImp    = gBatchGuiFactory->CreateCanvasImp(this, name, fCw, fCh);
00287       fBatch        = kTRUE;
00288    } else {                  //normal mode with a screen window
00289       Float_t cx = gStyle->GetScreenFactor();
00290       if (form < 1 || form > 5) form = 1;
00291       if (form == 1) {
00292          UInt_t uh = UInt_t(cx*gStyle->GetCanvasDefH());
00293          UInt_t uw = UInt_t(cx*gStyle->GetCanvasDefW());
00294          Int_t  ux = Int_t(cx*gStyle->GetCanvasDefX());
00295          Int_t  uy = Int_t(cx*gStyle->GetCanvasDefY());
00296          fCanvasImp = gGuiFactory->CreateCanvasImp(this, name, ux, uy, uw, uh);
00297       }
00298       fCw = 500;
00299       fCh = 500;
00300       if (form == 2) fCanvasImp = gGuiFactory->CreateCanvasImp(this, name, 20, 20, UInt_t(cx*500), UInt_t(cx*500));
00301       if (form == 3) fCanvasImp = gGuiFactory->CreateCanvasImp(this, name, 30, 30, UInt_t(cx*500), UInt_t(cx*500));
00302       if (form == 4) fCanvasImp = gGuiFactory->CreateCanvasImp(this, name, 40, 40, UInt_t(cx*500), UInt_t(cx*500));
00303       if (form == 5) fCanvasImp = gGuiFactory->CreateCanvasImp(this, name, 50, 50, UInt_t(cx*500), UInt_t(cx*500));
00304       fCanvasImp->ShowMenuBar(TestBit(kMenuBar));
00305       fBatch = kFALSE;
00306    }
00307 
00308    CreatePainter();
00309 
00310    SetName(name);
00311    SetTitle(title); // requires fCanvasImp set
00312    Build();
00313 
00314    // Popup canvas
00315    fCanvasImp->Show();
00316 }
00317 
00318 
00319 //_____________________________________________________________________________
00320 TCanvas::TCanvas(const char *name, const char *title, Int_t ww, Int_t wh) : TPad(), fDoubleBuffer(0)
00321 {
00322    //  Create a new canvas at a random position.
00323    //
00324    //  ww is the canvas size in pixels along X
00325    //      (if ww < 0  the menubar is not shown)
00326    //  wh is the canvas size in pixels along Y
00327    //
00328    //  If "name" starts with "gl" the canvas is ready to receive GL output.
00329    fPainter = 0;
00330    fUseGL = gStyle->GetCanvasPreferGL();
00331 
00332    Constructor(name, title, ww, wh);
00333 }
00334 
00335 
00336 //_____________________________________________________________________________
00337 void TCanvas::Constructor(const char *name, const char *title, Int_t ww, Int_t wh)
00338 {
00339    //  Create a new canvas at a random position.
00340    //
00341    //  ww is the canvas size in pixels along X
00342    //      (if ww < 0  the menubar is not shown)
00343    //  wh is the canvas size in pixels along Y
00344 
00345    if (gThreadXAR) {
00346       void *arr[6];
00347       arr[1] = this; arr[2] = (void*)name; arr[3] = (void*)title; arr[4] =&ww; arr[5] = &wh;
00348       if ((*gThreadXAR)("CANV", 6, arr, 0)) return;
00349    }
00350 
00351    Init();
00352    SetBit(kMenuBar,1);
00353    if (ww < 0) {
00354       ww       = -ww;
00355       SetBit(kMenuBar,0);
00356    }
00357    fCw       = ww;
00358    fCh       = wh;
00359    fCanvasID = -1;
00360    TCanvas *old = (TCanvas*)gROOT->GetListOfCanvases()->FindObject(name);
00361    if (old && old->IsOnHeap()) {
00362       Warning("Constructor","Deleting canvas with same name: %s",name);
00363       delete old;
00364    }
00365    if (strlen(name) == 0 || gROOT->IsBatch()) {   //We are in Batch mode
00366       fWindowTopX   = fWindowTopY = 0;
00367       fWindowWidth  = ww;
00368       fWindowHeight = wh;
00369       fCw           = ww;
00370       fCh           = wh;
00371       fCanvasImp    = gBatchGuiFactory->CreateCanvasImp(this, name, fCw, fCh);
00372       fBatch        = kTRUE;
00373    } else {
00374       Float_t cx = gStyle->GetScreenFactor();
00375       fCanvasImp = gGuiFactory->CreateCanvasImp(this, name, UInt_t(cx*ww), UInt_t(cx*wh));
00376       fCanvasImp->ShowMenuBar(TestBit(kMenuBar));
00377       fBatch = kFALSE;
00378    }
00379 
00380    CreatePainter();
00381 
00382    SetName(name);
00383    SetTitle(title); // requires fCanvasImp set
00384    Build();
00385 
00386    // Popup canvas
00387    fCanvasImp->Show();
00388 }
00389 
00390 
00391 //_____________________________________________________________________________
00392 TCanvas::TCanvas(const char *name, const char *title, Int_t wtopx, Int_t wtopy, Int_t ww, Int_t wh)
00393         : TPad(), fDoubleBuffer(0)
00394 {
00395    //  Create a new canvas.
00396    //
00397    //  wtopx,wtopy are the pixel coordinates of the top left corner of
00398    //  the canvas (if wtopx < 0) the menubar is not shown)
00399    //  ww is the canvas size in pixels along X
00400    //  wh is the canvas size in pixels along Y
00401    //
00402    //  If "name" starts with "gl" the canvas is ready to receive GL output.
00403 
00404    fPainter = 0;
00405    fUseGL = gStyle->GetCanvasPreferGL();
00406 
00407    Constructor(name, title, wtopx, wtopy, ww, wh);
00408 }
00409 
00410 
00411 //_____________________________________________________________________________
00412 void TCanvas::Constructor(const char *name, const char *title, Int_t wtopx,
00413                           Int_t wtopy, Int_t ww, Int_t wh)
00414 {
00415    //  Create a new canvas.
00416    //
00417    //  wtopx,wtopy are the pixel coordinates of the top left corner of
00418    //  the canvas (if wtopx < 0) the menubar is not shown)
00419    //  ww is the canvas size in pixels along X
00420    //  wh is the canvas size in pixels along Y
00421 
00422    if (gThreadXAR) {
00423       void *arr[8];
00424       arr[1] = this;   arr[2] = (void*)name;   arr[3] = (void*)title;
00425       arr[4] = &wtopx; arr[5] = &wtopy; arr[6] = &ww; arr[7] = &wh;
00426       if ((*gThreadXAR)("CANV", 8, arr, 0)) return;
00427    }
00428 
00429    Init();
00430    SetBit(kMenuBar,1);
00431    if (wtopx < 0) {
00432       wtopx    = -wtopx;
00433       SetBit(kMenuBar,0);
00434    }
00435    fCw       = ww;
00436    fCh       = wh;
00437    fCanvasID = -1;
00438    TCanvas *old = (TCanvas*)gROOT->GetListOfCanvases()->FindObject(name);
00439    if (old && old->IsOnHeap()) {
00440       Warning("Constructor","Deleting canvas with same name: %s",name);
00441       delete old;
00442    }
00443    if (strlen(name) == 0 || gROOT->IsBatch()) {   //We are in Batch mode
00444       fWindowTopX   = fWindowTopY = 0;
00445       fWindowWidth  = ww;
00446       fWindowHeight = wh;
00447       fCw           = ww;
00448       fCh           = wh;
00449       fCanvasImp    = gBatchGuiFactory->CreateCanvasImp(this, name, fCw, fCh);
00450       fBatch        = kTRUE;
00451    } else {                   //normal mode with a screen window
00452       Float_t cx = gStyle->GetScreenFactor();
00453       fCanvasImp = gGuiFactory->CreateCanvasImp(this, name, Int_t(cx*wtopx), Int_t(cx*wtopy), UInt_t(cx*ww), UInt_t(cx*wh));
00454       fCanvasImp->ShowMenuBar(TestBit(kMenuBar));
00455       fBatch = kFALSE;
00456    }
00457 
00458    CreatePainter();
00459 
00460    SetName(name);
00461    SetTitle(title); // requires fCanvasImp set
00462    Build();
00463 
00464    // Popup canvas
00465    fCanvasImp->Show();
00466 }
00467 
00468 
00469 //_____________________________________________________________________________
00470 void TCanvas::Init()
00471 {
00472    // Initialize the TCanvas members. Called by all constructors.
00473 
00474    // Make sure the application environment exists. It is need for graphics
00475    // (colors are initialized in the TApplication ctor).
00476    if (!gApplication)
00477       TApplication::CreateApplication();
00478 
00479    // Get some default from .rootrc. Used in fCanvasImp->InitWindow().
00480    fHighLightColor     = gEnv->GetValue("Canvas.HighLightColor", kRed);
00481    SetBit(kMoveOpaque,   gEnv->GetValue("Canvas.MoveOpaque", 0));
00482    SetBit(kResizeOpaque, gEnv->GetValue("Canvas.ResizeOpaque", 0));
00483    if (gEnv->GetValue("Canvas.ShowEventStatus", kFALSE)) SetBit(kShowEventStatus);
00484    if (gEnv->GetValue("Canvas.ShowToolTips", kFALSE)) SetBit(kShowToolTips);
00485    if (gEnv->GetValue("Canvas.ShowToolBar", kFALSE)) SetBit(kShowToolBar);
00486    if (gEnv->GetValue("Canvas.ShowEditor", kFALSE)) SetBit(kShowEditor);
00487    if (gEnv->GetValue("Canvas.AutoExec", kTRUE)) SetBit(kAutoExec);
00488 
00489    // Fill canvas ROOT data structure
00490    fXsizeUser = 0;
00491    fYsizeUser = 0;
00492    fXsizeReal = kDefaultCanvasSize;
00493    fYsizeReal = kDefaultCanvasSize;
00494 
00495    fDISPLAY         = "$DISPLAY";
00496    fUpdating        = kFALSE;
00497    fRetained        = kTRUE;
00498    fSelected        = 0;
00499    fClickSelected   = 0;
00500    fSelectedX       = 0;
00501    fSelectedY       = 0;
00502    fSelectedPad     = 0;
00503    fClickSelectedPad= 0;
00504    fPadSave         = 0;
00505    fEvent           = -1;
00506    fEventX          = -1;
00507    fEventY          = -1;
00508    fContextMenu     = 0;
00509 }
00510 
00511 
00512 //_____________________________________________________________________________
00513 void TCanvas::Build()
00514 {
00515    // Build a canvas. Called by all constructors.
00516 
00517    // Get window identifier
00518    if (fCanvasID == -1 && fCanvasImp)
00519       fCanvasID = fCanvasImp->InitWindow();
00520    if (fCanvasID == -1) return;
00521 
00522    if (fCw < fCh) fXsizeReal = fYsizeReal*Float_t(fCw)/Float_t(fCh);
00523    else           fYsizeReal = fXsizeReal*Float_t(fCh)/Float_t(fCw);
00524 
00525    // Set Pad parameters
00526    gPad            = this;
00527    fCanvas         = this;
00528    fMother         = (TPad*)gPad;
00529 
00530    if (!IsBatch()) {    //normal mode with a screen window
00531       // Set default physical canvas attributes
00532       //Should be done via gVirtualX, not via fPainter (at least now). No changes here.
00533       gVirtualX->SelectWindow(fCanvasID);
00534       gVirtualX->SetFillColor(1);         //Set color index for fill area
00535       gVirtualX->SetLineColor(1);         //Set color index for lines
00536       gVirtualX->SetMarkerColor(1);       //Set color index for markers
00537       gVirtualX->SetTextColor(1);         //Set color index for text
00538       // Clear workstation
00539       gVirtualX->ClearWindow();
00540 
00541       // Set Double Buffer on by default
00542       SetDoubleBuffer(1);
00543 
00544       // Get effective window parameters (with borders and menubar)
00545       fCanvasImp->GetWindowGeometry(fWindowTopX, fWindowTopY,
00546                                     fWindowWidth, fWindowHeight);
00547 
00548       // Get effective canvas parameters without borders
00549       Int_t dum1, dum2;
00550       gVirtualX->GetGeometry(fCanvasID, dum1, dum2, fCw, fCh);
00551 
00552       fContextMenu = new TContextMenu("ContextMenu");
00553    } else {
00554       // Make sure that batch interactive canvas sizes are the same
00555       fCw -= 4;
00556       fCh -= 28;
00557    }
00558    gROOT->GetListOfCanvases()->Add(this);
00559 
00560    if (!fPrimitives) {
00561       fPrimitives     = new TList;
00562       SetFillColor(gStyle->GetCanvasColor());
00563       SetFillStyle(1001);
00564       SetGrid(gStyle->GetPadGridX(),gStyle->GetPadGridY());
00565       SetTicks(gStyle->GetPadTickX(),gStyle->GetPadTickY());
00566       SetLogx(gStyle->GetOptLogx());
00567       SetLogy(gStyle->GetOptLogy());
00568       SetLogz(gStyle->GetOptLogz());
00569       SetBottomMargin(gStyle->GetPadBottomMargin());
00570       SetTopMargin(gStyle->GetPadTopMargin());
00571       SetLeftMargin(gStyle->GetPadLeftMargin());
00572       SetRightMargin(gStyle->GetPadRightMargin());
00573       SetBorderSize(gStyle->GetCanvasBorderSize());
00574       SetBorderMode(gStyle->GetCanvasBorderMode());
00575       fBorderMode=gStyle->GetCanvasBorderMode(); // do not call SetBorderMode (function redefined in TCanvas)
00576       SetPad(0, 0, 1, 1);
00577       Range(0, 0, 1, 1);   //pad range is set by default to [0,1] in x and y
00578 
00579       fPainter->SelectDrawable(fPixmapID);//gVirtualX->SelectPixmap(fPixmapID);    //pixmap must be selected
00580       PaintBorder(GetFillColor(), kTRUE);    //paint background
00581    }
00582 
00583    // transient canvases have typically no menubar and should not get
00584    // by default the event status bar (if set by default)
00585    if (TestBit(kMenuBar) && fCanvasImp) {
00586       if (TestBit(kShowEventStatus)) fCanvasImp->ShowStatusBar(kTRUE);
00587       // ... and toolbar + editor
00588       if (TestBit(kShowToolBar))     fCanvasImp->ShowToolBar(kTRUE);
00589       if (TestBit(kShowEditor))      fCanvasImp->ShowEditor(kTRUE);
00590       if (TestBit(kShowToolTips))    fCanvasImp->ShowToolTips(kTRUE);
00591    }
00592 }
00593 
00594 
00595 //______________________________________________________________________________
00596 TCanvas::~TCanvas()
00597 {
00598    // Canvas destructor
00599 
00600    Destructor();
00601 }
00602 
00603 
00604 //______________________________________________________________________________
00605 void TCanvas::Browse(TBrowser *b)
00606 {
00607    // Browse.
00608 
00609    Draw();
00610    cd();
00611    if (fgIsFolder) fPrimitives->Browse(b);
00612 }
00613 
00614 
00615 //______________________________________________________________________________
00616 void TCanvas::Destructor()
00617 {
00618    // Actual canvas destructor.
00619 
00620    if (gThreadXAR) {
00621       void *arr[2];
00622       arr[1] = this;
00623       if ((*gThreadXAR)("CDEL", 2, arr, 0)) return;
00624    }
00625 
00626    if (!TestBit(kNotDeleted)) return;
00627 
00628    if (fContextMenu) { delete fContextMenu; fContextMenu = 0; }
00629    if (!gPad) return;
00630 
00631    Close();
00632 
00633    delete fPainter;
00634 }
00635 
00636 
00637 //______________________________________________________________________________
00638 TVirtualPad *TCanvas::cd(Int_t subpadnumber)
00639 {
00640    // Set current canvas & pad. Returns the new current pad,
00641    // or 0 in case of failure.
00642    // See TPad::cd() for an explanation of the parameter.
00643 
00644    if (fCanvasID == -1) return 0;
00645 
00646    TPad::cd(subpadnumber);
00647 
00648    // in case doublebuffer is off, draw directly onto display window
00649    if (!IsBatch()) {
00650       if (!fDoubleBuffer)
00651          gVirtualX->SelectWindow(fCanvasID);//Ok, does not matter for glpad.
00652    }
00653    return gPad;
00654 }
00655 
00656 
00657 //______________________________________________________________________________
00658 void TCanvas::Clear(Option_t *option)
00659 {
00660    // Remove all primitives from the canvas.
00661    // If option "D" is specified, direct subpads are cleared but not deleted.
00662    // This option is not recursive, i.e. pads in direct subpads are deleted.
00663 
00664    if (fCanvasID == -1) return;
00665 
00666    if ((!gROOT->IsLineProcessing()) && (!gVirtualX->IsCmdThread())) {
00667       gInterpreter->Execute(this, IsA(), "Clear", option);
00668       return;
00669    }
00670 
00671    TString opt = option;
00672    opt.ToLower();
00673    if (opt.Contains("d")) {
00674       // clear subpads, but do not delete pads in case the canvas
00675       // has been divided (note: option "D" is propagated so could cause
00676       // conflicts for primitives using option "D" for something else)
00677       if (fPrimitives) {
00678          TIter next(fPrimitives);
00679          TObject *obj;
00680          while ((obj=next())) {
00681             obj->Clear(option);
00682          }
00683       }
00684    } else {
00685       //default, clear everything in the canvas. Subpads are deleted
00686       TPad::Clear(option);   //Remove primitives from pad
00687    }
00688 
00689    fSelected      = 0;
00690    fClickSelected = 0;
00691    fSelectedPad   = 0;
00692    fClickSelectedPad = 0;
00693 }
00694 
00695 
00696 //______________________________________________________________________________
00697 void TCanvas::Cleared(TVirtualPad *pad)
00698 {
00699    // Emit pad Cleared signal.
00700 
00701    Emit("Cleared(TVirtualPad*)", (Long_t)pad);
00702 }
00703 
00704 
00705 //______________________________________________________________________________
00706 void TCanvas::Closed()
00707 {
00708    // Emit Closed signal.
00709 
00710    Emit("Closed()");
00711 }
00712 
00713 
00714 //______________________________________________________________________________
00715 void TCanvas::Close(Option_t *option)
00716 {
00717    // Close canvas.
00718    //
00719    //  Delete window/pads data structure
00720 
00721    TPad    *padsave = (TPad*)gPad;
00722    TCanvas *cansave = 0;
00723    if (padsave) cansave = (TCanvas*)gPad->GetCanvas();
00724 
00725    if (fCanvasID == -1) goto deletepad;
00726 
00727    if ((!gROOT->IsLineProcessing()) && (!gVirtualX->IsCmdThread())) {
00728       gInterpreter->Execute(this, IsA(), "Close", option);
00729       return;
00730    }
00731 
00732    FeedbackMode(kFALSE);
00733 
00734    cd();
00735    TPad::Close(option);
00736 
00737    if (!IsBatch()) {
00738       gVirtualX->SelectWindow(fCanvasID);    //select current canvas
00739 
00740       if (fGLDevice != -1)
00741          gGLManager->DeleteGLContext(fGLDevice);//?
00742 
00743       if (fCanvasImp) fCanvasImp->Close();
00744    }
00745    fCanvasID = -1;
00746    fBatch    = kTRUE;
00747 
00748    gROOT->GetListOfCanvases()->Remove(this);
00749 
00750    // Close actual window on screen
00751    SafeDelete(fCanvasImp);
00752 
00753 deletepad:
00754    if (cansave == this) {
00755       gPad = (TCanvas *) gROOT->GetListOfCanvases()->First();
00756    } else {
00757       gPad = padsave;
00758    }
00759 
00760    Closed();
00761 }
00762 
00763 
00764 //______________________________________________________________________________
00765 void TCanvas::CopyPixmaps()
00766 {
00767    // Copy the canvas pixmap of the pad to the canvas.
00768 
00769    if (!IsBatch()) {
00770       CopyPixmap();
00771       TPad::CopyPixmaps();
00772    }
00773 }
00774 
00775 
00776 //______________________________________________________________________________
00777 void TCanvas::Draw(Option_t *)
00778 {
00779    //  Draw a canvas.
00780    //  If a canvas with the name is already on the screen, the canvas is repainted.
00781    //  This function is useful when a canvas object has been saved in a Root file.
00782    //  One can then do:
00783    //     Root > Tfile f("file.root");
00784    //     Root > canvas.Draw();
00785 
00786    TCanvas *old = (TCanvas*)gROOT->GetListOfCanvases()->FindObject(GetName());
00787    if (old == this) {
00788       Paint();
00789       return;
00790    }
00791    if (old) { gROOT->GetListOfCanvases()->Remove(old); delete old;}
00792 
00793    if (fWindowWidth  == 0) {
00794       if (fCw !=0) fWindowWidth = fCw+4; 
00795       else         fWindowWidth = 800;
00796    }
00797    if (fWindowHeight == 0) {
00798       if (fCh !=0) fWindowHeight = fCh+28;
00799       else         fWindowHeight = 600;
00800    }
00801    fCanvasImp = gGuiFactory->CreateCanvasImp(this, GetName(), fWindowTopX, fWindowTopY,
00802                                              fWindowWidth, fWindowHeight);
00803    fCanvasImp->ShowMenuBar(TestBit(kMenuBar));
00804 
00805    Build();
00806    ResizePad();
00807    fCanvasImp->Show();
00808    Modified();
00809 }
00810 
00811 
00812 //______________________________________________________________________________
00813 TObject *TCanvas::DrawClone(Option_t *option) const
00814 {
00815    // Draw a clone of this canvas
00816    // A new canvas is created that is a clone of this canvas
00817 
00818    const char *defcanvas = gROOT->GetDefCanvasName();
00819    char *cdef;
00820 
00821    TList *lc = (TList*)gROOT->GetListOfCanvases();
00822    if (lc->FindObject(defcanvas))
00823       cdef = Form("%s_n%d",defcanvas,lc->GetSize()+1);
00824    else
00825       cdef = Form("%s",defcanvas);
00826 
00827    TCanvas *newCanvas = (TCanvas*)Clone();
00828    newCanvas->SetName(cdef);
00829 
00830    newCanvas->Draw(option);
00831    newCanvas->Update();
00832    return newCanvas;
00833 }
00834 
00835 
00836 //______________________________________________________________________________
00837 TObject *TCanvas::DrawClonePad()
00838 {
00839    // Draw a clone of this canvas into the current pad
00840    // In an interactive session, select the destination/current pad
00841    // with the middle mouse button, then point to the canvas area to select
00842    // the canvas context menu item DrawClonePad.
00843    // Note that the original canvas may have subpads.
00844 
00845    TPad *padsav = (TPad*)gPad;
00846    TPad *selpad = (TPad*)gROOT->GetSelectedPad();
00847    TPad *pad = padsav;
00848    if (pad == this) pad = selpad;
00849    if (padsav == 0 || pad == 0 || pad == this) {
00850       TCanvas *newCanvas = (TCanvas*)DrawClone();
00851       newCanvas->SetWindowSize(GetWindowWidth(),GetWindowHeight());
00852       return newCanvas;
00853    }
00854    if (fCanvasID == -1) {
00855       fCanvasImp = gGuiFactory->CreateCanvasImp(this, GetName(), fWindowTopX, fWindowTopY,
00856                                              fWindowWidth, fWindowHeight);
00857       fCanvasImp->ShowMenuBar(TestBit(kMenuBar));
00858       fCanvasID = fCanvasImp->InitWindow();
00859    }
00860    this->cd();
00861    TObject *obj, *clone;
00862    //copy pad attributes
00863    pad->Range(fX1,fY1,fX2,fY2);
00864    pad->SetTickx(GetTickx());
00865    pad->SetTicky(GetTicky());
00866    pad->SetGridx(GetGridx());
00867    pad->SetGridy(GetGridy());
00868    pad->SetLogx(GetLogx());
00869    pad->SetLogy(GetLogy());
00870    pad->SetLogz(GetLogz());
00871    pad->SetBorderSize(GetBorderSize());
00872    pad->SetBorderMode(GetBorderMode());
00873    TAttLine::Copy((TAttLine&)*pad);
00874    TAttFill::Copy((TAttFill&)*pad);
00875    TAttPad::Copy((TAttPad&)*pad);
00876 
00877    //copy primitives
00878    TIter next(GetListOfPrimitives());
00879    while ((obj=next())) {
00880       pad->cd();
00881       clone = obj->Clone();
00882       pad->GetListOfPrimitives()->Add(clone,next.GetOption());
00883    }
00884    pad->ResizePad();
00885    pad->Modified();
00886    pad->Update();
00887    if (padsav) padsav->cd();
00888    return 0;
00889 }
00890 
00891 
00892 //______________________________________________________________________________
00893 void TCanvas::DrawEventStatus(Int_t event, Int_t px, Int_t py, TObject *selected)
00894 {
00895    // Report name and title of primitive below the cursor.
00896    //
00897    //    This function is called when the option "Event Status"
00898    //    in the canvas menu "Options" is selected.
00899 
00900    const Int_t kTMAX=256;
00901    static char atext[kTMAX];
00902 
00903    if (!TestBit(kShowEventStatus) || !selected) return;
00904 
00905    if (!fCanvasImp) return; //this may happen when closing a TAttCanvas
00906 
00907    TVirtualPad* savepad;
00908    savepad = gPad;
00909    gPad = GetSelectedPad();
00910 
00911    fCanvasImp->SetStatusText(selected->GetTitle(),0);
00912    fCanvasImp->SetStatusText(selected->GetName(),1);
00913    if (event == kKeyPress)
00914       snprintf(atext, kTMAX, "%c", (char) px);
00915    else
00916       snprintf(atext, kTMAX, "%d,%d", px, py);
00917    fCanvasImp->SetStatusText(atext,2);
00918    fCanvasImp->SetStatusText(selected->GetObjectInfo(px,py),3);
00919    gPad = savepad;
00920 }
00921 
00922 
00923 //______________________________________________________________________________
00924 void TCanvas::EditorBar()
00925 {
00926    // Get editor bar.
00927 
00928    TVirtualPadEditor::GetPadEditor();
00929 }
00930 
00931 
00932 //______________________________________________________________________________
00933 void TCanvas::EmbedInto(Int_t winid, Int_t ww, Int_t wh)
00934 {
00935    // Embedded a canvas into a TRootEmbeddedCanvas. This method is only called
00936    // via TRootEmbeddedCanvas::AdoptCanvas.
00937 
00938    // If fCanvasImp already exists, no need to go further.
00939    if(fCanvasImp) return;
00940 
00941    fCanvasID     = winid;
00942    fWindowTopX   = 0;
00943    fWindowTopY   = 0;
00944    fWindowWidth  = ww;
00945    fWindowHeight = wh;
00946    fCw           = ww;
00947    fCh           = wh;
00948    fBatch        = kFALSE;
00949    fUpdating     = kFALSE;
00950 
00951    fCanvasImp    = gBatchGuiFactory->CreateCanvasImp(this, GetName(), fCw, fCh);
00952    Build();
00953    Resize();
00954 }
00955 
00956 
00957 //______________________________________________________________________________
00958 void TCanvas::EnterLeave(TPad *prevSelPad, TObject *prevSelObj)
00959 {
00960    // Generate kMouseEnter and kMouseLeave events depending on the previously
00961    // selected object and the currently selected object. Does nothing if the
00962    // selected object does not change.
00963 
00964    if (prevSelObj == fSelected) return;
00965 
00966    TPad *padsav = (TPad *)gPad;
00967    Int_t sevent = fEvent;
00968 
00969    if (prevSelObj) {
00970       gPad = prevSelPad;
00971       prevSelObj->ExecuteEvent(kMouseLeave, fEventX, fEventY);
00972       fEvent = kMouseLeave;
00973       RunAutoExec();
00974       ProcessedEvent(kMouseLeave, fEventX, fEventY, prevSelObj);  // emit signal
00975    }
00976 
00977    gPad = fSelectedPad;
00978 
00979    if (fSelected) {
00980       fSelected->ExecuteEvent(kMouseEnter, fEventX, fEventY);
00981       fEvent = kMouseEnter;
00982       RunAutoExec();
00983       ProcessedEvent(kMouseEnter, fEventX, fEventY, fSelected);  // emit signal
00984    }
00985 
00986    fEvent = sevent;
00987    gPad   = padsav;
00988 }
00989 
00990 
00991 //______________________________________________________________________________
00992 void TCanvas::ExecuteEvent(Int_t event, Int_t px, Int_t py)
00993 {
00994    // Execute action corresponding to one event.
00995    //
00996    //  This member function must be implemented to realize the action
00997    //  corresponding to the mouse click on the object in the canvas
00998    //
00999    //  Only handle mouse motion events in TCanvas, all other events are
01000    //  ignored for the time being
01001 
01002    if (gROOT->GetEditorMode()) {
01003       TPad::ExecuteEvent(event,px,py);
01004       return;
01005    }
01006 
01007    switch (event) {
01008 
01009    case kMouseMotion:
01010       SetCursor(kCross);
01011       break;
01012    }
01013 }
01014 
01015 
01016 //______________________________________________________________________________
01017 void TCanvas::FeedbackMode(Bool_t set)
01018 {
01019    // Turn rubberband feedback mode on or off.
01020 
01021    if (set) {
01022       SetDoubleBuffer(0);             // turn off double buffer mode
01023       gVirtualX->SetDrawMode(TVirtualX::kInvert);  // set the drawing mode to XOR mode
01024    } else {
01025       SetDoubleBuffer(1);             // turn on double buffer mode
01026       gVirtualX->SetDrawMode(TVirtualX::kCopy); // set drawing mode back to normal (copy) mode
01027    }
01028 }
01029 
01030 
01031 //______________________________________________________________________________
01032 void TCanvas::Flush()
01033 {
01034    // Flush canvas buffers.
01035 
01036    if (fCanvasID == -1) return;
01037 
01038    TPad *padsav = (TPad*)gPad;
01039    cd();
01040    if (!IsBatch()) {
01041       if (!UseGL()) {
01042          gVirtualX->SelectWindow(fCanvasID);
01043          gPad = padsav; //don't do cd() because than also the pixmap is changed
01044          CopyPixmaps();
01045          gVirtualX->UpdateWindow(1);
01046       } else {
01047          TVirtualPS *tvps = gVirtualPS;
01048          gVirtualPS = 0;
01049          gGLManager->MakeCurrent(fGLDevice);
01050          fPainter->InitPainter();
01051          Paint();
01052          if (padsav && padsav->GetCanvas() == this) {
01053             padsav->cd();
01054             padsav->HighLight(padsav->GetHighLightColor());
01055             //cd();
01056          }
01057          fPainter->LockPainter();
01058          gGLManager->Flush(fGLDevice);
01059          gVirtualPS = tvps;
01060       }
01061    }
01062    if (padsav) padsav->cd();
01063 }
01064 
01065 
01066 //______________________________________________________________________________
01067 void TCanvas::UseCurrentStyle()
01068 {
01069    // Force a copy of current style for all objects in canvas.
01070 
01071    if ((!gROOT->IsLineProcessing()) && (!gVirtualX->IsCmdThread())) {
01072       gInterpreter->Execute(this, IsA(), "UseCurrentStyle", "");
01073       return;
01074    }
01075    TPad::UseCurrentStyle();
01076 
01077    if (gStyle->IsReading()) {
01078       SetFillColor(gStyle->GetCanvasColor());
01079       fBorderSize = gStyle->GetCanvasBorderSize();
01080       fBorderMode = gStyle->GetCanvasBorderMode();
01081    } else {
01082       gStyle->SetCanvasColor(GetFillColor());
01083       gStyle->SetCanvasBorderSize(fBorderSize);
01084       gStyle->SetCanvasBorderMode(fBorderMode);
01085    }
01086 }
01087 
01088 
01089 //______________________________________________________________________________
01090 Int_t TCanvas::GetWindowTopX()
01091 {
01092    // Returns current top x position of window on screen.
01093 
01094    if (fCanvasImp) fCanvasImp->GetWindowGeometry(fWindowTopX, fWindowTopY,
01095                                                  fWindowWidth,fWindowHeight);
01096 
01097    return fWindowTopX;
01098 }
01099 
01100 
01101 //______________________________________________________________________________
01102 Int_t TCanvas::GetWindowTopY()
01103 {
01104    // Returns current top y position of window on screen.
01105 
01106    if (fCanvasImp) fCanvasImp->GetWindowGeometry(fWindowTopX, fWindowTopY,
01107                                                  fWindowWidth,fWindowHeight);
01108 
01109    return fWindowTopY;
01110 }
01111 
01112 
01113 //______________________________________________________________________________
01114 void TCanvas::HandleInput(EEventType event, Int_t px, Int_t py)
01115 {
01116    // Handle Input Events.
01117    //
01118    //  Handle input events, like button up/down in current canvas.
01119 
01120    TPad    *pad;
01121    TPad    *prevSelPad = (TPad*) fSelectedPad;
01122    TObject *prevSelObj = fSelected;
01123 
01124    fPadSave = (TPad*)gPad;
01125    cd();        // make sure this canvas is the current canvas
01126 
01127    fEvent  = event;
01128    fEventX = px;
01129    fEventY = py;
01130 
01131    switch (event) {
01132 
01133    case kMouseMotion:
01134       // highlight object tracked over
01135       pad = Pick(px, py, prevSelObj);
01136       if (!pad) return;
01137 
01138       EnterLeave(prevSelPad, prevSelObj);
01139 
01140       gPad = pad;   // don't use cd() we will use the current
01141                     // canvas via the GetCanvas member and not via
01142                     // gPad->GetCanvas
01143 
01144       fSelected->ExecuteEvent(event, px, py);
01145 
01146       RunAutoExec();
01147 
01148       break;
01149 
01150    case kMouseEnter:
01151       // mouse enters canvas
01152       if (!fDoubleBuffer) FeedbackMode(kTRUE);
01153       break;
01154 
01155    case kMouseLeave:
01156       // mouse leaves canvas
01157       {
01158          // force popdown of tooltips
01159          TObject *sobj = fSelected;
01160          TPad    *spad = fSelectedPad;
01161          fSelected     = 0;
01162          fSelectedPad  = 0;
01163          EnterLeave(prevSelPad, prevSelObj);
01164          fSelected     = sobj;
01165          fSelectedPad  = spad;
01166          if (!fDoubleBuffer) FeedbackMode(kFALSE);
01167       }
01168       break;
01169 
01170    case kButton1Double:
01171       // triggered on the second button down within 350ms and within
01172       // 3x3 pixels of the first button down, button up finishes action
01173 
01174    case kButton1Down:
01175       // find pad in which input occured
01176       pad = Pick(px, py, prevSelObj);
01177       if (!pad) return;
01178 
01179       gPad = pad;   // don't use cd() because we won't draw in pad
01180                     // we will only use its coordinate system
01181 
01182       if (fSelected) {
01183          FeedbackMode(kTRUE);   // to draw in rubberband mode
01184          fSelected->ExecuteEvent(event, px, py);
01185 
01186          RunAutoExec();
01187       }
01188 
01189       break;
01190 
01191    case kButton1Motion:
01192    case kButton1ShiftMotion: //8 == kButton1Motion + shift modifier
01193       if (fSelected) {
01194          gPad = fSelectedPad;
01195 
01196          fSelected->ExecuteEvent(event, px, py);
01197          gVirtualX->Update();
01198 
01199          if (!fSelected->InheritsFrom(TAxis::Class())) {
01200             Bool_t resize = kFALSE;
01201             if (fSelected->InheritsFrom(TBox::Class()))
01202                resize = ((TBox*)fSelected)->IsBeingResized();
01203             if (fSelected->InheritsFrom(TVirtualPad::Class()))
01204                resize = ((TVirtualPad*)fSelected)->IsBeingResized();
01205 
01206             if ((!resize && TestBit(kMoveOpaque)) || (resize && TestBit(kResizeOpaque))) {
01207                gPad = fPadSave;
01208                Update();
01209                FeedbackMode(kTRUE);
01210             }
01211          }
01212 
01213          RunAutoExec();
01214       }
01215 
01216       break;
01217 
01218    case kButton1Up:
01219 
01220       if (fSelected) {
01221          gPad = fSelectedPad;
01222 
01223          fSelected->ExecuteEvent(event, px, py);
01224 
01225          RunAutoExec();
01226 
01227          if (fPadSave)
01228             gPad = fPadSave;
01229          else {
01230             gPad     = this;
01231             fPadSave = this;
01232          }
01233 
01234          Update();    // before calling update make sure gPad is reset
01235       }
01236       break;
01237 
01238 //*-*----------------------------------------------------------------------
01239 
01240    case kButton2Down:
01241       // find pad in which input occured
01242       pad = Pick(px, py, prevSelObj);
01243       if (!pad) return;
01244 
01245       gPad = pad;   // don't use cd() because we won't draw in pad
01246                     // we will only use its coordinate system
01247 
01248       FeedbackMode(kTRUE);
01249 
01250       fSelected->Pop();           // pop object to foreground
01251       pad->cd();                  // and make its pad the current pad
01252       if (gDebug)
01253          printf("Current Pad: %s / %s\n", pad->GetName(), pad->GetTitle());
01254 
01255       // loop over all canvases to make sure that only one pad is highlighted
01256       {
01257          TIter next(gROOT->GetListOfCanvases());
01258          TCanvas *tc;
01259          while ((tc = (TCanvas *)next()))
01260             tc->Update();
01261       }
01262 
01263       /*if (pad->GetGLDevice() != -1 && fSelected)
01264          fSelected->ExecuteEvent(event, px, py);*/
01265 
01266       break;   // don't want fPadSave->cd() to be executed at the end
01267 
01268    case kButton2Motion:
01269       //was empty!
01270    case kButton2Up:
01271       if (fSelected) {
01272          gPad = fSelectedPad;
01273 
01274          fSelected->ExecuteEvent(event, px, py);
01275          RunAutoExec();
01276       }
01277       break;
01278 
01279    case kButton2Double:
01280       break;
01281 
01282 //*-*----------------------------------------------------------------------
01283 
01284    case kButton3Down:
01285       // popup context menu
01286       pad = Pick(px, py, prevSelObj);
01287       if (!pad) return;
01288 
01289       if (!fDoubleBuffer) FeedbackMode(kFALSE);
01290 
01291       if (fContextMenu && !fSelected->TestBit(kNoContextMenu) &&
01292          !pad->TestBit(kNoContextMenu) && !TestBit(kNoContextMenu))
01293          fContextMenu->Popup(px, py, fSelected, this, pad);
01294 
01295       break;
01296 
01297    case kButton3Motion:
01298       break;
01299 
01300    case kButton3Up:
01301       if (!fDoubleBuffer) FeedbackMode(kTRUE);
01302       break;
01303 
01304    case kButton3Double:
01305       break;
01306 
01307    case kKeyPress:
01308       if (!fSelectedPad || !fSelected) return;
01309       gPad = fSelectedPad;   // don't use cd() because we won't draw in pad
01310                     // we will only use its coordinate system
01311       fSelected->ExecuteEvent(event, px, py);
01312 
01313       RunAutoExec();
01314 
01315       break;
01316    case kButton1Shift:
01317       // Try to select
01318       pad = Pick(px, py, prevSelObj);
01319 
01320       if (!pad) return;
01321 
01322       EnterLeave(prevSelPad, prevSelObj);
01323 
01324       gPad = pad;   // don't use cd() we will use the current
01325                     // canvas via the GetCanvas member and not via
01326                     // gPad->GetCanvas
01327       fSelected->ExecuteEvent(event, px, py);
01328       RunAutoExec();
01329 
01330       break;
01331    case kWheelUp:
01332    case kWheelDown:
01333       pad = Pick(px, py, prevSelObj);
01334       if (!pad) return;
01335 
01336       gPad = pad;
01337       fSelected->ExecuteEvent(event, px, py);
01338       break;
01339    default:
01340       break;
01341    }
01342 
01343    if (fPadSave && event != kButton2Down)
01344       fPadSave->cd();
01345 
01346    if (event != kMouseLeave) { // signal was already emitted for this event
01347       ProcessedEvent(event, px, py, fSelected);  // emit signal
01348       DrawEventStatus(event, px, py, fSelected);
01349    }
01350 }
01351 
01352 
01353 //______________________________________________________________________________
01354 Bool_t TCanvas::IsFolder() const
01355 {
01356    // Is folder ?
01357 
01358    return fgIsFolder;
01359 }
01360 
01361 
01362 //______________________________________________________________________________
01363 void TCanvas::ls(Option_t *option) const
01364 {
01365    // List all pads.
01366 
01367    TROOT::IndentLevel();
01368    cout <<"Canvas Name=" <<GetName()<<" Title="<<GetTitle()<<" Option="<<option<<endl;
01369    TROOT::IncreaseDirLevel();
01370    TPad::ls(option);
01371    TROOT::DecreaseDirLevel();
01372 }
01373 
01374 
01375 //______________________________________________________________________________
01376 TCanvas *TCanvas::MakeDefCanvas()
01377 {
01378    // Static function to build a default canvas.
01379 
01380    const char *defcanvas = gROOT->GetDefCanvasName();
01381    char *cdef;
01382 
01383    TList *lc = (TList*)gROOT->GetListOfCanvases();
01384    if (lc->FindObject(defcanvas)) {
01385       Int_t n = lc->GetSize() + 1;
01386       cdef = new char[strlen(defcanvas)+15];
01387       do {
01388          strlcpy(cdef,Form("%s_n%d", defcanvas, n++),strlen(defcanvas)+15);
01389       } while (lc->FindObject(cdef));
01390    } else
01391       cdef = StrDup(Form("%s",defcanvas));
01392 
01393    TCanvas *c = new TCanvas(cdef, cdef, 1);
01394 
01395    ::Info("TCanvas::MakeDefCanvas"," created default TCanvas with name %s",cdef);
01396    delete [] cdef;
01397    return c;
01398 }
01399 
01400 
01401 //______________________________________________________________________________
01402 void TCanvas::MoveOpaque(Int_t set)
01403 {
01404    // Set option to move objects/pads in a canvas.
01405    //
01406    //  if set = 1 (default) graphics objects are moved in opaque mode
01407    //         = 0 only the outline of objects is drawn when moving them
01408    //  The option opaque produces the best effect. It requires however a
01409    //  a reasonably fast workstation or response time.
01410 
01411    SetBit(kMoveOpaque,set);
01412 }
01413 
01414 
01415 //______________________________________________________________________________
01416 void TCanvas::Paint(Option_t *option)
01417 {
01418    // Paint canvas.
01419 
01420    if (fCanvas) TPad::Paint(option);
01421 }
01422 
01423 
01424 //______________________________________________________________________________
01425 TPad *TCanvas::Pick(Int_t px, Int_t py, TObject *prevSelObj)
01426 {
01427    // Prepare for pick, call TPad::Pick() and when selected object
01428    // is different from previous then emit Picked() signal.
01429 
01430    TObjLink *pickobj = 0;
01431 
01432    fSelected    = 0;
01433    fSelectedOpt = "";
01434    fSelectedPad = 0;
01435 
01436    TPad *pad = Pick(px, py, pickobj);
01437    if (!pad) return 0;
01438 
01439    if (!pickobj) {
01440       fSelected    = pad;
01441       fSelectedOpt = "";
01442    } else {
01443       if (!fSelected) {   // can be set via TCanvas::SetSelected()
01444          fSelected    = pickobj->GetObject();
01445          fSelectedOpt = pickobj->GetOption();
01446       }
01447    }
01448    fSelectedPad = pad;
01449 
01450    if (fSelected != prevSelObj)
01451       Picked(fSelectedPad, fSelected, fEvent);  // emit signal
01452 
01453    if ((fEvent == kButton1Down) || (fEvent == kButton2Down) || (fEvent == kButton3Down)) {
01454       if (fSelected && !fSelected->InheritsFrom(TView::Class())) {
01455          fClickSelected = fSelected;
01456          fClickSelectedPad = fSelectedPad;
01457          Selected(fSelectedPad, fSelected, fEvent);  // emit signal
01458          fSelectedX = px;
01459          fSelectedY = py;
01460       }
01461    }
01462    return pad;
01463 }
01464 
01465 
01466 //______________________________________________________________________________
01467 void TCanvas::Picked(TPad *pad, TObject *obj, Int_t event)
01468 {
01469    // Emit Picked() signal.
01470 
01471    Long_t args[3];
01472 
01473    args[0] = (Long_t) pad;
01474    args[1] = (Long_t) obj;
01475    args[2] = event;
01476 
01477    Emit("Picked(TPad*,TObject*,Int_t)", args);
01478 }
01479 
01480 
01481 //______________________________________________________________________________
01482 void TCanvas::Selected(TVirtualPad *pad, TObject *obj, Int_t event)
01483 {
01484    // Emit Selected() signal.
01485 
01486    Long_t args[3];
01487 
01488    args[0] = (Long_t) pad;
01489    args[1] = (Long_t) obj;
01490    args[2] = event;
01491 
01492    Emit("Selected(TVirtualPad*,TObject*,Int_t)", args);
01493 }
01494 
01495 
01496 //______________________________________________________________________________
01497 void TCanvas::ProcessedEvent(Int_t event, Int_t x, Int_t y, TObject *obj)
01498 {
01499    // Emit ProcessedEvent() signal.
01500 
01501    Long_t args[4];
01502 
01503    args[0] = event;
01504    args[1] = x;
01505    args[2] = y;
01506    args[3] = (Long_t) obj;
01507 
01508    Emit("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)", args);
01509 }
01510 
01511 
01512 //______________________________________________________________________________
01513 void TCanvas::Resize(Option_t *)
01514 {
01515    // Recompute canvas parameters following a X11 Resize.
01516 
01517    if (fCanvasID == -1) return;
01518 
01519    if ((!gROOT->IsLineProcessing()) && (!gVirtualX->IsCmdThread())) {
01520       gInterpreter->Execute(this, IsA(), "Resize", "");
01521       return;
01522    }
01523 
01524    TPad *padsav  = (TPad*)gPad;
01525    cd();
01526 
01527    if (!IsBatch()) {
01528       gVirtualX->SelectWindow(fCanvasID);      //select current canvas
01529       gVirtualX->ResizeWindow(fCanvasID);      //resize canvas and off-screen buffer
01530 
01531       // Get effective window parameters including menubar and borders
01532       fCanvasImp->GetWindowGeometry(fWindowTopX, fWindowTopY,
01533                                     fWindowWidth, fWindowHeight);
01534 
01535       // Get effective canvas parameters without borders
01536       Int_t dum1, dum2;
01537       gVirtualX->GetGeometry(fCanvasID, dum1, dum2, fCw, fCh);
01538    }
01539 
01540    if (fXsizeUser && fYsizeUser) {
01541       UInt_t nwh = fCh;
01542       UInt_t nww = fCw;
01543       Double_t rxy = fXsizeUser/fYsizeUser;
01544       if (rxy < 1) {
01545          UInt_t twh = UInt_t(Double_t(fCw)/rxy);
01546          if (twh > fCh)
01547             nww = UInt_t(Double_t(fCh)*rxy);
01548          else
01549             nwh = twh;
01550          if (nww > fCw) {
01551             nww = fCw; nwh = twh;
01552          }
01553          if (nwh > fCh) {
01554             nwh = fCh; nww = UInt_t(Double_t(fCh)/rxy);
01555          }
01556       } else {
01557          UInt_t twh = UInt_t(Double_t(fCw)*rxy);
01558          if (twh > fCh)
01559             nwh = UInt_t(Double_t(fCw)/rxy);
01560          else
01561             nww = twh;
01562          if (nww > fCw) {
01563             nww = fCw; nwh = twh;
01564          }
01565          if (nwh > fCh) {
01566             nwh = fCh; nww = UInt_t(Double_t(fCh)*rxy);
01567          }
01568       }
01569       fCw = nww;
01570       fCh = nwh;
01571    }
01572 
01573    if (fCw < fCh) {
01574       fYsizeReal = kDefaultCanvasSize;
01575       fXsizeReal = fYsizeReal*Double_t(fCw)/Double_t(fCh);
01576    }
01577    else {
01578       fXsizeReal = kDefaultCanvasSize;
01579       fYsizeReal = fXsizeReal*Double_t(fCh)/Double_t(fCw);
01580    }
01581 
01582 //*-*- Loop on all pads to recompute conversion coefficients
01583    TPad::ResizePad();
01584 
01585    if (padsav) padsav->cd();
01586 }
01587 
01588 
01589 //______________________________________________________________________________
01590 void TCanvas::ResizeOpaque(Int_t set)
01591 {
01592    // Set option to resize objects/pads in a canvas.
01593    //
01594    //  if set = 1 (default) graphics objects are resized in opaque mode
01595    //         = 0 only the outline of objects is drawn when resizing them
01596    //  The option opaque produces the best effect. It requires however a
01597    //  a reasonably fast workstation or response time.
01598 
01599    SetBit(kResizeOpaque,set);
01600 }
01601 
01602 
01603 //______________________________________________________________________________
01604 void TCanvas::RunAutoExec()
01605 {
01606    // Execute the list of TExecs in the current pad.
01607 
01608    if (!TestBit(kAutoExec)) return;
01609    if (!gPad) return;
01610    ((TPad*)gPad)->AutoExec();
01611 }
01612 
01613 
01614 //______________________________________________________________________________
01615 void TCanvas::SavePrimitive(ostream &out, Option_t *option /*= ""*/)
01616 {
01617    // Save primitives in this canvas in C++ macro file with GUI.
01618 
01619    // Write canvas options (in $TROOT or $TStyle)
01620    if (gStyle->GetOptFit()) {
01621       out<<"   gStyle->SetOptFit(1);"<<endl;
01622    }
01623    if (!gStyle->GetOptStat()) {
01624       out<<"   gStyle->SetOptStat(0);"<<endl;
01625    }
01626    if (!gStyle->GetOptTitle()) {
01627       out<<"   gStyle->SetOptTitle(0);"<<endl;
01628    }
01629    if (gROOT->GetEditHistograms()) {
01630       out<<"   gROOT->SetEditHistograms();"<<endl;
01631    }
01632    if (GetShowEventStatus()) {
01633       out<<"   "<<GetName()<<"->ToggleEventStatus();"<<endl;
01634    }
01635    if (GetShowToolTips()) {
01636       out<<"   "<<GetName()<<"->ToggleToolTips();"<<endl;
01637    }
01638    if (GetShowToolBar()) {
01639       out<<"   "<<GetName()<<"->ToggleToolBar();"<<endl;
01640    }
01641    if (GetHighLightColor() != 5) {
01642       if (GetHighLightColor() > 228) {
01643          TColor::SaveColor(out, GetHighLightColor());
01644          out<<"   "<<GetName()<<"->SetHighLightColor(ci);" << endl;
01645       } else
01646          out<<"   "<<GetName()<<"->SetHighLightColor("<<GetHighLightColor()<<");"<<endl;
01647    }
01648 
01649    // Now recursively scan all pads of this canvas
01650    cd();
01651    TPad::SavePrimitive(out,option);
01652 }
01653 
01654 
01655 //______________________________________________________________________________
01656 void TCanvas::SaveSource(const char *filename, Option_t *option)
01657 {
01658    // Save primitives in this canvas as a C++ macro file.
01659    // This function loops on all the canvas primitives and for each primitive
01660    // calls the object SavePrimitive function.
01661    // When outputing floating point numbers, the default precision is 7 digits.
01662    // The precision can be changed (via system.rootrc) by changing the value
01663    // of the environment variable "Canvas.SavePrecision"
01664 
01665    //    reset bit TClass::kClassSaved for all classes
01666    TIter next(gROOT->GetListOfClasses());
01667    TClass *cl;
01668    while((cl = (TClass*)next())) {
01669       cl->ResetBit(TClass::kClassSaved);
01670    }
01671 
01672    char quote = '"';
01673    ofstream out;
01674    Int_t lenfile = strlen(filename);
01675    char * fname;
01676    char lcname[10];
01677    const char *cname = GetName();
01678    Bool_t invalid = kFALSE;
01679    //    if filename is given, open this file, otherwise create a file
01680    //    with a name equal to the canvasname.C
01681    if (lenfile) {
01682       fname = (char*)filename;
01683       out.open(fname, ios::out);
01684    } else {
01685       Int_t nch = strlen(cname);
01686       if (nch < 10) {
01687          strlcpy(lcname,cname,10);
01688          for (Int_t k=1;k<=nch;k++) {if (lcname[nch-k] == ' ') lcname[nch-k] = 0;}
01689          if (lcname[0] == 0) {invalid = kTRUE; strlcpy(lcname,"c1",10); nch = 2;}
01690          cname = lcname;
01691       }
01692       fname = new char[nch+3];
01693       strlcpy(fname,cname,nch+3);
01694       strncat(fname,".C",2);
01695       out.open(fname, ios::out);
01696    }
01697    if (!out.good ()) {
01698       Printf("SaveSource cannot open file: %s",fname);
01699       if (!lenfile) delete [] fname;
01700       return;
01701    }
01702 
01703    //set precision
01704    Int_t precision = gEnv->GetValue("Canvas.SavePrecision",7);
01705    out.precision(precision);
01706 
01707    //   Write macro header and date/time stamp
01708    TDatime t;
01709    Float_t cx = gStyle->GetScreenFactor();
01710    Int_t topx,topy;
01711    UInt_t w, h;
01712    UInt_t editorWidth = fCanvasImp->GetWindowGeometry(topx,topy,w,h);
01713    w = UInt_t((fWindowWidth - editorWidth)/cx);
01714    h = UInt_t((fWindowHeight)/cx);
01715    topx = GetWindowTopX();
01716    topy = GetWindowTopY();
01717 
01718    if (w == 0) {
01719       w = GetWw()+4; h = GetWh()+4;
01720       topx = 1;    topy = 1;
01721    }
01722 
01723    out <<"{"<<endl;
01724    out <<"//=========Macro generated from canvas: "<<GetName()<<"/"<<GetTitle()<<endl;
01725    out <<"//=========  ("<<t.AsString()<<") by ROOT version"<<gROOT->GetVersion()<<endl;
01726 
01727    if (gStyle->GetCanvasPreferGL())
01728       out <<endl<<"   gStyle->SetCanvasPreferGL(kTRUE);"<<endl<<endl;
01729 
01730    //   Write canvas parameters (TDialogCanvas case)
01731    if (InheritsFrom(TDialogCanvas::Class())) {
01732       out<<"   "<<ClassName()<<" *"<<cname<<" = new "<<ClassName()<<"("<<quote<<GetName()
01733          <<quote<<", "<<quote<<GetTitle()<<quote<<","<<w<<","<<h<<");"<<endl;
01734    } else {
01735    //   Write canvas parameters (TCanvas case)
01736       out<<"   TCanvas *"<<cname<<" = new TCanvas("<<quote<<GetName()<<quote<<", "<<quote<<GetTitle()
01737          <<quote;
01738       if (!HasMenuBar())
01739          out<<",-"<<topx<<","<<topy<<","<<w<<","<<h<<");"<<endl;
01740       else
01741          out<<","<<topx<<","<<topy<<","<<w<<","<<h<<");"<<endl;
01742    }
01743    //   Write canvas options (in $TROOT or $TStyle)
01744    if (gStyle->GetOptFit()) {
01745       out<<"   gStyle->SetOptFit(1);"<<endl;
01746    }
01747    if (!gStyle->GetOptStat()) {
01748       out<<"   gStyle->SetOptStat(0);"<<endl;
01749    }
01750    if (!gStyle->GetOptTitle()) {
01751       out<<"   gStyle->SetOptTitle(0);"<<endl;
01752    }
01753    if (gROOT->GetEditHistograms()) {
01754       out<<"   gROOT->SetEditHistograms();"<<endl;
01755    }
01756    if (GetShowEventStatus()) {
01757       out<<"   "<<GetName()<<"->ToggleEventStatus();"<<endl;
01758    }
01759    if (GetShowToolTips()) {
01760       out<<"   "<<GetName()<<"->ToggleToolTips();"<<endl;
01761    }
01762    if (GetHighLightColor() != 5) {
01763       if (GetHighLightColor() > 228) {
01764          TColor::SaveColor(out, GetHighLightColor());
01765          out<<"   "<<GetName()<<"->SetHighLightColor(ci);" << endl;
01766       } else
01767          out<<"   "<<GetName()<<"->SetHighLightColor("<<GetHighLightColor()<<");"<<endl;
01768    }
01769 
01770    //   Now recursively scan all pads of this canvas
01771    cd();
01772    if (invalid) SetName("c1");
01773    TPad::SavePrimitive(out,option);
01774    //   Write canvas options related to pad editor
01775    out<<"   "<<GetName()<<"->SetSelected("<<GetName()<<");"<<endl;
01776    if (GetShowToolBar()) {
01777       out<<"   "<<GetName()<<"->ToggleToolBar();"<<endl;
01778    }
01779    if (invalid) SetName(" ");
01780 
01781    out <<"}"<<endl;
01782    out.close();
01783    Info("SaveSource","C++ Macro file: %s has been generated", fname);
01784 
01785    //    reset bit TClass::kClassSaved for all classes
01786    next.Reset();
01787    while((cl = (TClass*)next())) {
01788       cl->ResetBit(TClass::kClassSaved);
01789    }
01790    if (!lenfile) delete [] fname;
01791 }
01792 
01793 
01794 //______________________________________________________________________________
01795 void TCanvas::SetBatch(Bool_t batch)
01796 {
01797    // Toggle batch mode. However, if the canvas is created without a window
01798    // then batch mode always stays set.
01799 
01800    if (gROOT->IsBatch())
01801       fBatch = kTRUE;
01802    else
01803       fBatch = batch;
01804 }
01805 
01806 
01807 //______________________________________________________________________________
01808 void TCanvas::SetCanvasSize(UInt_t ww, UInt_t wh)
01809 {
01810    // Set Width and Height of canvas to ww and wh respectively
01811    // If ww and/or wh are greater than the current canvas window
01812    // a scroll bar is automatically generated.
01813    // Use this function to zoom in a canvas and naviguate via
01814    // the scroll bars.
01815 
01816    if (fCanvasImp) {
01817       fCanvasImp->SetCanvasSize(ww, wh);
01818       fCw = ww;
01819       fCh = wh;
01820       ResizePad();
01821    }
01822 }
01823 
01824 
01825 //______________________________________________________________________________
01826 void TCanvas::SetCursor(ECursor cursor)
01827 {
01828    // Set cursor.
01829 
01830    if (IsBatch()) return;
01831    gVirtualX->SetCursor(fCanvasID, cursor);
01832 }
01833 
01834 
01835 //______________________________________________________________________________
01836 void TCanvas::SetDoubleBuffer(Int_t mode)
01837 {
01838    // Set Double Buffer On/Off.
01839 
01840    if (IsBatch()) return;
01841    fDoubleBuffer = mode;
01842    gVirtualX->SetDoubleBuffer(fCanvasID, mode);
01843 
01844    // depending of the buffer mode set the drawing window to either
01845    // the canvas pixmap or to the canvas on-screen window
01846    if (fDoubleBuffer) {
01847       if (fPixmapID != -1) fPainter->SelectDrawable(fPixmapID);
01848    } else
01849       if (fCanvasID != -1) fPainter->SelectDrawable(fCanvasID);
01850 }
01851 
01852 
01853 //______________________________________________________________________________
01854 void TCanvas::SetFixedAspectRatio(Bool_t fixed)
01855 {
01856    // Fix canvas aspect ratio to current value if fixed is true.
01857 
01858    if (fixed) {
01859       if (!fFixedAspectRatio) {
01860          if (fCh != 0)
01861             fAspectRatio = Double_t(fCw) / fCh;
01862          else {
01863             Error("SetAspectRatio", "cannot fix aspect ratio, height of canvas is 0");
01864             return;
01865          }
01866          fFixedAspectRatio = kTRUE;
01867       }
01868    } else {
01869       fFixedAspectRatio = kFALSE;
01870       fAspectRatio = 0;
01871    }
01872 }
01873 
01874 
01875 //______________________________________________________________________________
01876 void TCanvas::SetFolder(Bool_t isfolder)
01877 {
01878    // If isfolder=kTRUE, the canvas can be browsed like a folder
01879    // by default a canvas is not browsable.
01880 
01881    fgIsFolder = isfolder;
01882 }
01883 
01884 
01885 //______________________________________________________________________________
01886 void TCanvas::SetSelected(TObject *obj)
01887 {
01888    // Set selected canvas.
01889 
01890    fSelected = obj;
01891    if (obj) obj->SetBit(kMustCleanup);
01892 }
01893 
01894 
01895 //______________________________________________________________________________
01896 void TCanvas::SetTitle(const char *title)
01897 {
01898    // Set canvas title.
01899 
01900    fTitle = title;
01901    if (fCanvasImp) fCanvasImp->SetWindowTitle(title);
01902 }
01903 
01904 
01905 //______________________________________________________________________________
01906 void TCanvas::Size(Float_t xsize, Float_t ysize)
01907 {
01908    // Set the canvas scale in centimeters.
01909    //
01910    //  This information is used by PostScript to set the page size.
01911    //  xsize  = size of the canvas in centimeters along X
01912    //  ysize  = size of the canvas in centimeters along Y
01913    //   if xsize and ysize are not equal to 0, then the scale factors will
01914    //   be computed to keep the ratio ysize/xsize independently of the canvas
01915    //   size (parts of the physical canvas will be unused).
01916    //
01917    //   if xsize = 0 and ysize is not zero, then xsize will be computed
01918    //      to fit to the current canvas scale. If the canvas is resized,
01919    //      a new value for xsize will be recomputed. In this case the aspect
01920    //      ratio is not preserved.
01921    //
01922    //   if both xsize = 0 and ysize = 0, then the scaling is automatic.
01923    //   the largest dimension will be allocated a size of 20 centimeters.
01924 
01925    fXsizeUser = xsize;
01926    fYsizeUser = ysize;
01927 
01928    Resize();
01929 }
01930 
01931 
01932 //_______________________________________________________________________
01933 void TCanvas::Streamer(TBuffer &b)
01934 {
01935    // Stream a class object.
01936 
01937    UInt_t R__s, R__c;
01938    if (b.IsReading()) {
01939       Version_t v = b.ReadVersion(&R__s, &R__c);
01940       gPad    = this;
01941       fCanvas = this;
01942       TPad::Streamer(b);
01943       gPad    = this;
01944       //restore the colors
01945       TObjArray *colors = (TObjArray*)fPrimitives->FindObject("ListOfColors");
01946       if (colors) {
01947          TIter next(colors);
01948          TColor *colold;
01949          while ((colold = (TColor*)next())) {
01950             if (colold) {
01951                Int_t cn = 0;
01952                if (colold) cn = colold->GetNumber();
01953                TColor *colcur = gROOT->GetColor(cn);
01954                if (colcur) {
01955                   colcur->SetRGB(colold->GetRed(),colold->GetGreen(),colold->GetBlue());
01956                } else {
01957                   colcur = new TColor(cn,colold->GetRed(),
01958                                         colold->GetGreen(),
01959                                         colold->GetBlue(),
01960                                         colold->GetName());
01961                   if (!colcur) return;
01962                }
01963             }
01964          }
01965          fPrimitives->Remove(colors);
01966          colors->Delete();
01967          delete colors;
01968       }
01969 
01970       fDISPLAY.Streamer(b);
01971       b >> fDoubleBuffer;
01972       b >> fRetained;
01973       b >> fXsizeUser;
01974       b >> fYsizeUser;
01975       b >> fXsizeReal;
01976       b >> fYsizeReal;
01977       fCanvasID = -1;
01978       b >> fWindowTopX;
01979       b >> fWindowTopY;
01980       if (v > 2) {
01981          b >> fWindowWidth;
01982          b >> fWindowHeight;
01983       }
01984       b >> fCw;
01985       b >> fCh;
01986       if (v <= 2) {
01987          fWindowWidth  = fCw;
01988          fWindowHeight = fCh;
01989       }
01990       fCatt.Streamer(b);
01991       Bool_t dummy;
01992       b >> dummy; if (dummy) MoveOpaque(1);
01993       b >> dummy; if (dummy) ResizeOpaque(1);
01994       b >> fHighLightColor;
01995       b >> dummy; //was fBatch
01996       if (v < 2) return;
01997       b >> dummy; if (dummy) SetBit(kShowEventStatus);
01998       if (v > 3) {b >> dummy; if (dummy) SetBit(kAutoExec);}
01999       b >> dummy; if (dummy) SetBit(kMenuBar);
02000       fBatch = gROOT->IsBatch();
02001       b.CheckByteCount(R__s, R__c, TCanvas::IsA());
02002    } else {
02003       //save list of colors
02004       //we must protect the case when two or more canvases are saved
02005       //in the same buffer. If the list of colors has already been saved
02006       //in the buffer, do not add the list of colors to the list of primitives.
02007       TObjArray *colors = 0;
02008       if (!b.CheckObject(gROOT->GetListOfColors(),TObjArray::Class())) {
02009          colors = (TObjArray*)gROOT->GetListOfColors();
02010          fPrimitives->Add(colors);
02011       }
02012       R__c = b.WriteVersion(TCanvas::IsA(), kTRUE);
02013       TPad::Streamer(b);
02014       if(colors) fPrimitives->Remove(colors);
02015       fDISPLAY.Streamer(b);
02016       b << fDoubleBuffer;
02017       b << fRetained;
02018       b << fXsizeUser;
02019       b << fYsizeUser;
02020       b << fXsizeReal;
02021       b << fYsizeReal;
02022       UInt_t w   = fWindowWidth,  h    = fWindowHeight;
02023       Int_t topx = fWindowTopX,   topy = fWindowTopY;
02024       UInt_t editorWidth = 0;
02025       if(fCanvasImp) editorWidth = fCanvasImp->GetWindowGeometry(topx,topy,w,h);
02026       b << topx;
02027       b << topy;
02028       b << (UInt_t)(w-editorWidth);
02029       b << h;
02030       b << fCw;
02031       b << fCh;
02032       fCatt.Streamer(b);
02033       b << TestBit(kMoveOpaque);      //please remove in ROOT version 6
02034       b << TestBit(kResizeOpaque);    //please remove in ROOT version 6
02035       b << fHighLightColor;
02036       b << fBatch;                    //please remove in ROOT version 6
02037       b << TestBit(kShowEventStatus); //please remove in ROOT version 6
02038       b << TestBit(kAutoExec);        //please remove in ROOT version 6
02039       b << TestBit(kMenuBar);         //please remove in ROOT version 6
02040       b.SetByteCount(R__c, kTRUE);
02041    }
02042 }
02043 
02044 
02045 //______________________________________________________________________________
02046 void TCanvas::ToggleAutoExec()
02047 {
02048    // Toggle pad auto execution of list of TExecs.
02049 
02050    Bool_t autoExec = TestBit(kAutoExec);
02051    SetBit(kAutoExec,!autoExec);
02052 }
02053 
02054 
02055 //______________________________________________________________________________
02056 void TCanvas::ToggleEventStatus()
02057 {
02058    // Toggle event statusbar.
02059 
02060    Bool_t showEventStatus = !TestBit(kShowEventStatus);
02061    SetBit(kShowEventStatus,showEventStatus);
02062 
02063    if (fCanvasImp) fCanvasImp->ShowStatusBar(showEventStatus);
02064 }
02065 
02066 
02067 //______________________________________________________________________________
02068 void TCanvas::ToggleToolBar()
02069 {
02070    // Toggle toolbar.
02071 
02072    Bool_t showToolBar = !TestBit(kShowToolBar);
02073    SetBit(kShowToolBar,showToolBar);
02074 
02075    if (fCanvasImp) fCanvasImp->ShowToolBar(showToolBar);
02076 }
02077 
02078 
02079 //______________________________________________________________________________
02080 void TCanvas::ToggleEditor()
02081 {
02082    // Toggle editor.
02083 
02084    Bool_t showEditor = !TestBit(kShowEditor);
02085    SetBit(kShowEditor,showEditor);
02086 
02087    if (fCanvasImp) fCanvasImp->ShowEditor(showEditor);
02088 }
02089 
02090 //______________________________________________________________________________
02091 void TCanvas::ToggleToolTips()
02092 {
02093    // Toggle tooltip display.
02094 
02095    Bool_t showToolTips = !TestBit(kShowToolTips);
02096    SetBit(kShowToolTips, showToolTips);
02097 
02098    if (fCanvasImp) fCanvasImp->ShowToolTips(showToolTips);
02099 }
02100 
02101 //______________________________________________________________________________
02102 void TCanvas::Update()
02103 {
02104    // Update canvas pad buffers.
02105 
02106    if (fUpdating) return;
02107 
02108    if (gThreadXAR) {
02109       void *arr[2];
02110       arr[1] = this;
02111       if ((*gThreadXAR)("CUPD", 2, arr, 0)) return;
02112    }
02113 
02114    if (!fCanvasImp) return;
02115 
02116    if (!gVirtualX->IsCmdThread()) {
02117       gInterpreter->Execute(this, IsA(), "Update", "");
02118       return;
02119    }
02120    fUpdating = kTRUE;
02121 
02122    if (!IsBatch()) FeedbackMode(kFALSE);      // Goto double buffer mode
02123 
02124    if (!UseGL())
02125       PaintModified();           // Repaint all modified pad's
02126 
02127    Flush();                   // Copy all pad pixmaps to the screen
02128 
02129    SetCursor(kCross);
02130    fUpdating = kFALSE;
02131 }
02132 
02133 
02134 //______________________________________________________________________________
02135 void TCanvas::DisconnectWidget()
02136 {
02137    // Used by friend class TCanvasImp.
02138 
02139    fCanvasID    = 0;
02140    fContextMenu = 0;
02141 }
02142 
02143 
02144 //______________________________________________________________________________
02145 Bool_t TCanvas::IsGrayscale()
02146 {
02147    // Check whether this canvas is to be drawn in grayscale mode.
02148 
02149    return TestBit(kIsGrayscale);
02150 }
02151 
02152 
02153 //______________________________________________________________________________
02154 void TCanvas::SetGrayscale(Bool_t set /*= kTRUE*/)
02155 {
02156    // Set whether this canvas should be painted in grayscale, and re-paint
02157    // it if necessary.
02158 
02159    if (IsGrayscale() == set) return;
02160    SetBit(kIsGrayscale, set);
02161    Paint(); // update canvas and all sub-pads, unconditionally!
02162 }
02163 
02164 
02165 //______________________________________________________________________________
02166 void TCanvas::CreatePainter()
02167 {
02168    // Probably, TPadPainter must be placed in a separate ROOT module -
02169    // "padpainter" (the same as "histpainter"). But now, it's directly in a
02170    // gpad dir, so, in case of default painter, no *.so should be loaded,
02171    // no need in plugin managers.
02172    // May change in future.
02173 
02174    //Even for batch mode painter is still required, just to delegate
02175    //some calls to batch "virtual X".
02176    if (!UseGL() || fBatch)
02177       fPainter = new TPadPainter;//Do not need plugin manager for this!
02178    else {
02179       fPainter = TVirtualPadPainter::PadPainter("gl");
02180       if (!fPainter) {
02181          Error("CreatePainter", "GL Painter creation failed! Will use default!");
02182          fPainter = new TPadPainter;
02183          fUseGL = kFALSE;
02184       }
02185    }
02186 }
02187 
02188 
02189 //______________________________________________________________________________
02190 TVirtualPadPainter *TCanvas::GetCanvasPainter()
02191 {
02192    // Access and (probably) creation of pad painter.
02193 
02194    if (!fPainter) CreatePainter();
02195    return fPainter;
02196 }

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