00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
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 
00049 
00050 Bool_t TCanvas::fgIsFolder = kFALSE;
00051 
00052 const Size_t kDefaultCanvasSize   = 20;
00053 
00054 ClassImpQ(TCanvas)
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 
00087 
00088 
00089 
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104 
00105 
00106 
00107 
00108 
00109 
00110 
00111 
00112 
00113 
00114 
00115 
00116 
00117 
00118 
00119 
00120 
00121 
00122 
00123 
00124 
00125 
00126 
00127 
00128 
00129 TCanvas::TCanvas(Bool_t build) : TPad(), fDoubleBuffer(0)
00130 {
00131    
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    
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    
00186    
00187    
00188    
00189    
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    
00205    
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    
00226    
00227    
00228    
00229    
00230    
00231    
00232    
00233    
00234    
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    
00247    
00248    
00249    
00250    
00251    
00252    
00253    
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()) {   
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 {                  
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); 
00312    Build();
00313 
00314    
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    
00323    
00324    
00325    
00326    
00327    
00328    
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    
00340    
00341    
00342    
00343    
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()) {   
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); 
00384    Build();
00385 
00386    
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    
00396    
00397    
00398    
00399    
00400    
00401    
00402    
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    
00416    
00417    
00418    
00419    
00420    
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()) {   
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 {                   
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); 
00462    Build();
00463 
00464    
00465    fCanvasImp->Show();
00466 }
00467 
00468 
00469 
00470 void TCanvas::Init()
00471 {
00472    
00473 
00474    
00475    
00476    if (!gApplication)
00477       TApplication::CreateApplication();
00478 
00479    
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    
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    
00516 
00517    
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    
00526    gPad            = this;
00527    fCanvas         = this;
00528    fMother         = (TPad*)gPad;
00529 
00530    if (!IsBatch()) {    
00531       
00532       
00533       gVirtualX->SelectWindow(fCanvasID);
00534       gVirtualX->SetFillColor(1);         
00535       gVirtualX->SetLineColor(1);         
00536       gVirtualX->SetMarkerColor(1);       
00537       gVirtualX->SetTextColor(1);         
00538       
00539       gVirtualX->ClearWindow();
00540 
00541       
00542       SetDoubleBuffer(1);
00543 
00544       
00545       fCanvasImp->GetWindowGeometry(fWindowTopX, fWindowTopY,
00546                                     fWindowWidth, fWindowHeight);
00547 
00548       
00549       Int_t dum1, dum2;
00550       gVirtualX->GetGeometry(fCanvasID, dum1, dum2, fCw, fCh);
00551 
00552       fContextMenu = new TContextMenu("ContextMenu");
00553    } else {
00554       
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(); 
00576       SetPad(0, 0, 1, 1);
00577       Range(0, 0, 1, 1);   
00578 
00579       fPainter->SelectDrawable(fPixmapID);
00580       PaintBorder(GetFillColor(), kTRUE);    
00581    }
00582 
00583    
00584    
00585    if (TestBit(kMenuBar) && fCanvasImp) {
00586       if (TestBit(kShowEventStatus)) fCanvasImp->ShowStatusBar(kTRUE);
00587       
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    
00599 
00600    Destructor();
00601 }
00602 
00603 
00604 
00605 void TCanvas::Browse(TBrowser *b)
00606 {
00607    
00608 
00609    Draw();
00610    cd();
00611    if (fgIsFolder) fPrimitives->Browse(b);
00612 }
00613 
00614 
00615 
00616 void TCanvas::Destructor()
00617 {
00618    
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    
00641    
00642    
00643 
00644    if (fCanvasID == -1) return 0;
00645 
00646    TPad::cd(subpadnumber);
00647 
00648    
00649    if (!IsBatch()) {
00650       if (!fDoubleBuffer)
00651          gVirtualX->SelectWindow(fCanvasID);
00652    }
00653    return gPad;
00654 }
00655 
00656 
00657 
00658 void TCanvas::Clear(Option_t *option)
00659 {
00660    
00661    
00662    
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       
00675       
00676       
00677       if (fPrimitives) {
00678          TIter next(fPrimitives);
00679          TObject *obj;
00680          while ((obj=next())) {
00681             obj->Clear(option);
00682          }
00683       }
00684    } else {
00685       
00686       TPad::Clear(option);   
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    
00700 
00701    Emit("Cleared(TVirtualPad*)", (Long_t)pad);
00702 }
00703 
00704 
00705 
00706 void TCanvas::Closed()
00707 {
00708    
00709 
00710    Emit("Closed()");
00711 }
00712 
00713 
00714 
00715 void TCanvas::Close(Option_t *option)
00716 {
00717    
00718    
00719    
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);    
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    
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    
00768 
00769    if (!IsBatch()) {
00770       CopyPixmap();
00771       TPad::CopyPixmaps();
00772    }
00773 }
00774 
00775 
00776 
00777 void TCanvas::Draw(Option_t *)
00778 {
00779    
00780    
00781    
00782    
00783    
00784    
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    
00816    
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    
00840    
00841    
00842    
00843    
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    
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    
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    
00896    
00897    
00898    
00899 
00900    const Int_t kTMAX=256;
00901    static char atext[kTMAX];
00902 
00903    if (!TestBit(kShowEventStatus) || !selected) return;
00904 
00905    if (!fCanvasImp) return; 
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    
00927 
00928    TVirtualPadEditor::GetPadEditor();
00929 }
00930 
00931 
00932 
00933 void TCanvas::EmbedInto(Int_t winid, Int_t ww, Int_t wh)
00934 {
00935    
00936    
00937 
00938    
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    
00961    
00962    
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);  
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);  
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    
00995    
00996    
00997    
00998    
00999    
01000    
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    
01020 
01021    if (set) {
01022       SetDoubleBuffer(0);             
01023       gVirtualX->SetDrawMode(TVirtualX::kInvert);  
01024    } else {
01025       SetDoubleBuffer(1);             
01026       gVirtualX->SetDrawMode(TVirtualX::kCopy); 
01027    }
01028 }
01029 
01030 
01031 
01032 void TCanvas::Flush()
01033 {
01034    
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; 
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             
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    
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    
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    
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    
01117    
01118    
01119 
01120    TPad    *pad;
01121    TPad    *prevSelPad = (TPad*) fSelectedPad;
01122    TObject *prevSelObj = fSelected;
01123 
01124    fPadSave = (TPad*)gPad;
01125    cd();        
01126 
01127    fEvent  = event;
01128    fEventX = px;
01129    fEventY = py;
01130 
01131    switch (event) {
01132 
01133    case kMouseMotion:
01134       
01135       pad = Pick(px, py, prevSelObj);
01136       if (!pad) return;
01137 
01138       EnterLeave(prevSelPad, prevSelObj);
01139 
01140       gPad = pad;   
01141                     
01142                     
01143 
01144       fSelected->ExecuteEvent(event, px, py);
01145 
01146       RunAutoExec();
01147 
01148       break;
01149 
01150    case kMouseEnter:
01151       
01152       if (!fDoubleBuffer) FeedbackMode(kTRUE);
01153       break;
01154 
01155    case kMouseLeave:
01156       
01157       {
01158          
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       
01172       
01173 
01174    case kButton1Down:
01175       
01176       pad = Pick(px, py, prevSelObj);
01177       if (!pad) return;
01178 
01179       gPad = pad;   
01180                     
01181 
01182       if (fSelected) {
01183          FeedbackMode(kTRUE);   
01184          fSelected->ExecuteEvent(event, px, py);
01185 
01186          RunAutoExec();
01187       }
01188 
01189       break;
01190 
01191    case kButton1Motion:
01192    case kButton1ShiftMotion: 
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();    
01235       }
01236       break;
01237 
01238 
01239 
01240    case kButton2Down:
01241       
01242       pad = Pick(px, py, prevSelObj);
01243       if (!pad) return;
01244 
01245       gPad = pad;   
01246                     
01247 
01248       FeedbackMode(kTRUE);
01249 
01250       fSelected->Pop();           
01251       pad->cd();                  
01252       if (gDebug)
01253          printf("Current Pad: %s / %s\n", pad->GetName(), pad->GetTitle());
01254 
01255       
01256       {
01257          TIter next(gROOT->GetListOfCanvases());
01258          TCanvas *tc;
01259          while ((tc = (TCanvas *)next()))
01260             tc->Update();
01261       }
01262 
01263       
01264 
01265 
01266       break;   
01267 
01268    case kButton2Motion:
01269       
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       
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;   
01310                     
01311       fSelected->ExecuteEvent(event, px, py);
01312 
01313       RunAutoExec();
01314 
01315       break;
01316    case kButton1Shift:
01317       
01318       pad = Pick(px, py, prevSelObj);
01319 
01320       if (!pad) return;
01321 
01322       EnterLeave(prevSelPad, prevSelObj);
01323 
01324       gPad = pad;   
01325                     
01326                     
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) { 
01347       ProcessedEvent(event, px, py, fSelected);  
01348       DrawEventStatus(event, px, py, fSelected);
01349    }
01350 }
01351 
01352 
01353 
01354 Bool_t TCanvas::IsFolder() const
01355 {
01356    
01357 
01358    return fgIsFolder;
01359 }
01360 
01361 
01362 
01363 void TCanvas::ls(Option_t *option) const
01364 {
01365    
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    
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    
01405    
01406    
01407    
01408    
01409    
01410 
01411    SetBit(kMoveOpaque,set);
01412 }
01413 
01414 
01415 
01416 void TCanvas::Paint(Option_t *option)
01417 {
01418    
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    
01428    
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) {   
01444          fSelected    = pickobj->GetObject();
01445          fSelectedOpt = pickobj->GetOption();
01446       }
01447    }
01448    fSelectedPad = pad;
01449 
01450    if (fSelected != prevSelObj)
01451       Picked(fSelectedPad, fSelected, fEvent);  
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);  
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    
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    
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    
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    
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);      
01529       gVirtualX->ResizeWindow(fCanvasID);      
01530 
01531       
01532       fCanvasImp->GetWindowGeometry(fWindowTopX, fWindowTopY,
01533                                     fWindowWidth, fWindowHeight);
01534 
01535       
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 
01583    TPad::ResizePad();
01584 
01585    if (padsav) padsav->cd();
01586 }
01587 
01588 
01589 
01590 void TCanvas::ResizeOpaque(Int_t set)
01591 {
01592    
01593    
01594    
01595    
01596    
01597    
01598 
01599    SetBit(kResizeOpaque,set);
01600 }
01601 
01602 
01603 
01604 void TCanvas::RunAutoExec()
01605 {
01606    
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    
01618 
01619    
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    
01650    cd();
01651    TPad::SavePrimitive(out,option);
01652 }
01653 
01654 
01655 
01656 void TCanvas::SaveSource(const char *filename, Option_t *option)
01657 {
01658    
01659    
01660    
01661    
01662    
01663    
01664 
01665    
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    
01680    
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    
01704    Int_t precision = gEnv->GetValue("Canvas.SavePrecision",7);
01705    out.precision(precision);
01706 
01707    
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    
01731    if (InheritsFrom(TDialogCanvas::Class())) {
01732       out<<"   "<<ClassName()<<" *"<<cname<<" = new "<<ClassName()<<"("<<quote<<GetName()
01733          <<quote<<", "<<quote<<GetTitle()<<quote<<","<<w<<","<<h<<");"<<endl;
01734    } else {
01735    
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    
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    
01771    cd();
01772    if (invalid) SetName("c1");
01773    TPad::SavePrimitive(out,option);
01774    
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    
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    
01798    
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    
01811    
01812    
01813    
01814    
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    
01829 
01830    if (IsBatch()) return;
01831    gVirtualX->SetCursor(fCanvasID, cursor);
01832 }
01833 
01834 
01835 
01836 void TCanvas::SetDoubleBuffer(Int_t mode)
01837 {
01838    
01839 
01840    if (IsBatch()) return;
01841    fDoubleBuffer = mode;
01842    gVirtualX->SetDoubleBuffer(fCanvasID, mode);
01843 
01844    
01845    
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    
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    
01879    
01880 
01881    fgIsFolder = isfolder;
01882 }
01883 
01884 
01885 
01886 void TCanvas::SetSelected(TObject *obj)
01887 {
01888    
01889 
01890    fSelected = obj;
01891    if (obj) obj->SetBit(kMustCleanup);
01892 }
01893 
01894 
01895 
01896 void TCanvas::SetTitle(const char *title)
01897 {
01898    
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    
01909    
01910    
01911    
01912    
01913    
01914    
01915    
01916    
01917    
01918    
01919    
01920    
01921    
01922    
01923    
01924 
01925    fXsizeUser = xsize;
01926    fYsizeUser = ysize;
01927 
01928    Resize();
01929 }
01930 
01931 
01932 
01933 void TCanvas::Streamer(TBuffer &b)
01934 {
01935    
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       
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; 
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       
02004       
02005       
02006       
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);      
02034       b << TestBit(kResizeOpaque);    
02035       b << fHighLightColor;
02036       b << fBatch;                    
02037       b << TestBit(kShowEventStatus); 
02038       b << TestBit(kAutoExec);        
02039       b << TestBit(kMenuBar);         
02040       b.SetByteCount(R__c, kTRUE);
02041    }
02042 }
02043 
02044 
02045 
02046 void TCanvas::ToggleAutoExec()
02047 {
02048    
02049 
02050    Bool_t autoExec = TestBit(kAutoExec);
02051    SetBit(kAutoExec,!autoExec);
02052 }
02053 
02054 
02055 
02056 void TCanvas::ToggleEventStatus()
02057 {
02058    
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    
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    
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    
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    
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);      
02123 
02124    if (!UseGL())
02125       PaintModified();           
02126 
02127    Flush();                   
02128 
02129    SetCursor(kCross);
02130    fUpdating = kFALSE;
02131 }
02132 
02133 
02134 
02135 void TCanvas::DisconnectWidget()
02136 {
02137    
02138 
02139    fCanvasID    = 0;
02140    fContextMenu = 0;
02141 }
02142 
02143 
02144 
02145 Bool_t TCanvas::IsGrayscale()
02146 {
02147    
02148 
02149    return TestBit(kIsGrayscale);
02150 }
02151 
02152 
02153 
02154 void TCanvas::SetGrayscale(Bool_t set )
02155 {
02156    
02157    
02158 
02159    if (IsGrayscale() == set) return;
02160    SetBit(kIsGrayscale, set);
02161    Paint(); 
02162 }
02163 
02164 
02165 
02166 void TCanvas::CreatePainter()
02167 {
02168    
02169    
02170    
02171    
02172    
02173 
02174    
02175    
02176    if (!UseGL() || fBatch)
02177       fPainter = new TPadPainter;
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    
02193 
02194    if (!fPainter) CreatePainter();
02195    return fPainter;
02196 }