Logo ROOT   6.12/07
Reference Guide
TPad.cxx
Go to the documentation of this file.
1 // @(#)root/gpad:$Id$
2 // Author: Rene Brun 12/12/94
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include <string.h>
13 #include <stdlib.h>
14 
15 #include "Riostream.h"
16 #include "TROOT.h"
17 #include "TError.h"
18 #include "TMath.h"
19 #include "TSystem.h"
20 #include "TStyle.h"
21 #include "TH1.h"
22 #include "TH2.h"
23 #include "TH3.h"
24 #include "TClass.h"
25 #include "TBaseClass.h"
26 #include "TClassTable.h"
27 #include "TVirtualPS.h"
28 #include "TVirtualX.h"
29 #include "TVirtualViewer3D.h"
30 #include "TView.h"
31 #include "TPoint.h"
32 #include "TGraph.h"
33 #include "TMultiGraph.h"
34 #include "THStack.h"
35 #include "TPaveText.h"
36 #include "TPaveStats.h"
37 #include "TGroupButton.h"
38 #include "TBrowser.h"
39 #include "TVirtualGL.h"
40 #include "TString.h"
41 #include "TDataMember.h"
42 #include "TMethod.h"
43 #include "TDataType.h"
44 #include "TRealData.h"
45 #include "TFrame.h"
46 #include "TExec.h"
47 #include "TDatime.h"
48 #include "TColor.h"
49 #include "TCanvas.h"
50 #include "TPluginManager.h"
51 #include "TEnv.h"
52 #include "TImage.h"
53 #include "TViewer3DPad.h"
54 #include "TBuffer3D.h"
55 #include "TBuffer3DTypes.h"
56 #include "TCreatePrimitives.h"
57 #include "TLegend.h"
58 #include "TAtt3D.h"
59 #include "TObjString.h"
60 #include "TApplication.h"
61 #include "TVirtualPadPainter.h"
62 
63 #include "TVirtualMutex.h"
64 
65 static Int_t gReadLevel = 0;
66 
68 
70 
71 /** \class TPad
72 \ingroup gpad
73 
74 The most important graphics class in the ROOT system.
75 
76 A Pad is contained in a Canvas.
77 
78 A Pad may contain other pads (unlimited pad hierarchy).
79 
80 A pad is a linked list of primitives of any type (graphics objects,
81 histograms, detectors, tracks, etc.).
82 
83 Adding a new element into a pad is in general performed by the Draw
84 member function of the object classes.
85 
86 It is important to realize that the pad is a linked list of references
87 to the original object.
88 For example, in case of a histogram, the histogram.Draw() operation
89 only stores a reference to the histogram object and not a graphical
90 representation of this histogram.
91 When the mouse is used to change (say the bin content), the bin content
92 of the original histogram is changed.
93 
94 The convention used in ROOT is that a Draw operation only adds
95 a reference to the object. The effective drawing is performed
96 when the canvas receives a signal to be painted.
97 
98 \image html gpad_pad1.png
99 
100 This signal is generally sent when typing carriage return in the
101 command input or when a graphical operation has been performed on one
102 of the pads of this canvas.
103 When a Canvas/Pad is repainted, the member function Paint for all
104 objects in the Pad linked list is invoked.
105 
106 \image html gpad_pad2.png
107 
108 When the mouse is moved on the Pad, The member function DistancetoPrimitive
109 is called for all the elements in the pad. DistancetoPrimitive returns
110 the distance in pixels to this object.
111 
112 When the object is within the distance window, the member function
113 ExecuteEvent is called for this object.
114 
115 In ExecuteEvent, move, changes can be performed on the object.
116 
117 For examples of DistancetoPrimitive and ExecuteEvent functions,
118 see classes
119 ~~~ {.cpp}
120  TLine::DistancetoPrimitive, TLine::ExecuteEvent
121  TBox::DistancetoPrimitive, TBox::ExecuteEvent
122  TH1::DistancetoPrimitive, TH1::ExecuteEvent
123 ~~~
124 A Pad supports linear and log scales coordinate systems.
125 The transformation coefficients are explained in TPad::ResizePad.
126 */
127 
128 ////////////////////////////////////////////////////////////////////////////////
129 /// Pad default constructor.
130 
132 {
133  fModified = kTRUE;
134  fTip = 0;
135  fPadPointer = 0;
136  fPrimitives = 0;
137  fExecs = 0;
138  fCanvas = 0;
139  fPadPaint = 0;
140  fPixmapID = -1;
141  fGLDevice = -1;
142  fCopyGLDevice = kFALSE;
143  fEmbeddedGL = kFALSE;
144  fTheta = 30;
145  fPhi = 30;
146  fNumber = 0;
147  fAbsCoord = kFALSE;
148  fEditable = kTRUE;
149  fCrosshair = 0;
150  fCrosshairPos = 0;
151  fPadView3D = 0;
152  fMother = (TPad*)gPad;
153 
154  fAbsHNDC = 0.;
155  fAbsPixeltoXk = 0.;
156  fAbsPixeltoYk = 0.;
157  fAbsWNDC = 0.;
158  fAbsXlowNDC = 0.;
159  fAbsYlowNDC = 0.;
160  fBorderMode = 0;
161  fBorderSize = 0;
162  fPixeltoX = 0;
163  fPixeltoXk = 0.;
164  fPixeltoY = 0.;
165  fPixeltoYk = 0.;
166  fUtoAbsPixelk = 0.;
167  fUtoPixel = 0.;
168  fUtoPixelk = 0.;
169  fVtoAbsPixelk = 0.;
170  fVtoPixel = 0.;
171  fVtoPixelk = 0.;
172  fXtoAbsPixelk = 0.;
173  fXtoPixel = 0.;
174  fXtoPixelk = 0.;
175  fYtoAbsPixelk = 0.;
176  fYtoPixel = 0.;
177  fYtoPixelk = 0.;
178  fXUpNDC = 0.;
179  fYUpNDC = 0.;
180 
181  fFixedAspectRatio = kFALSE;
182  fAspectRatio = 0.;
183 
184  fNumPaletteColor = 0;
185  fNextPaletteColor = 0;
186  fCollideGrid = 0;
187  fCGnx = 0;
188  fCGny = 0;
189 
190  fLogx = 0;
191  fLogy = 0;
192  fLogz = 0;
193  fGridx = 0;
194  fGridy = 0;
195  fTickx = 0;
196  fTicky = 0;
197  fFrame = 0;
198  fView = 0;
199 
200  fUxmin = fUymin = fUxmax = fUymax = 0;
201 
202  // Set default world coordinates to NDC [0,1]
203  fX1 = 0;
204  fX2 = 1;
205  fY1 = 0;
206  fY2 = 1;
207 
208  // Set default pad range
209  fXlowNDC = 0;
210  fYlowNDC = 0;
211  fWNDC = 1;
212  fHNDC = 1;
213 
214  fViewer3D = 0;
215  SetBit(kMustCleanup);
216 
217  // the following line is temporarily disabled. It has side effects
218  // when the pad is a TDrawPanelHist or a TFitPanel.
219  // the line was supposed to fix a problem with DrawClonePad
220  // gROOT->SetSelectedPad(this);
221 }
222 
223 ////////////////////////////////////////////////////////////////////////////////
224 /// Pad constructor.
225 ///
226 /// A pad is a linked list of primitives.
227 /// A pad is contained in a canvas. It may contain other pads.
228 /// A pad has attributes. When a pad is created, the attributes
229 /// defined in the current style are copied to the pad attributes.
230 ///
231 /// \param[in] name pad name
232 /// \param[in] title pad title
233 /// \param[in] xlow [0,1] is the position of the bottom left point of the pad
234 /// expressed in the mother pad reference system
235 /// \param[in] ylow [0,1] is the Y position of this point.
236 /// \param[in] xup [0,1] is the x position of the top right point of the pad
237 /// expressed in the mother pad reference system
238 /// \param[in] yup [0,1] is the Y position of this point.
239 /// \param[in] color pad color
240 /// \param[in] bordersize border size in pixels
241 /// \param[in] bordermode border mode
242 /// - bordermode = -1 box looks as it is behind the screen
243 /// - bordermode = 0 no special effects
244 /// - bordermode = 1 box looks as it is in front of the screen
245 
246 TPad::TPad(const char *name, const char *title, Double_t xlow,
247  Double_t ylow, Double_t xup, Double_t yup,
248  Color_t color, Short_t bordersize, Short_t bordermode)
249  : TVirtualPad(name,title,xlow,ylow,xup,yup,color,bordersize,bordermode)
250 {
251  fModified = kTRUE;
252  fTip = 0;
253  fBorderSize = bordersize;
254  fBorderMode = bordermode;
255  if (gPad) fCanvas = gPad->GetCanvas();
256  else fCanvas = (TCanvas*)this;
257  fMother = (TPad*)gPad;
258  fPrimitives = new TList;
259  fExecs = new TList;
260  fPadPointer = 0;
261  fTheta = 30;
262  fPhi = 30;
267  fFrame = 0;
268  fView = 0;
269  fPadPaint = 0;
270  fPadView3D = 0;
271  fPixmapID = -1; // -1 means pixmap will be created by ResizePad()
274  fNumber = 0;
275  fAbsCoord = kFALSE;
276  fEditable = kTRUE;
277  fCrosshair = 0;
278  fCrosshairPos = 0;
279 
280  fVtoAbsPixelk = 0.;
281  fVtoPixelk = 0.;
282  fVtoPixel = 0.;
283  fAbsPixeltoXk = 0.;
284  fPixeltoXk = 0.;
285  fPixeltoX = 0;
286  fAbsPixeltoYk = 0.;
287  fPixeltoYk = 0.;
288  fPixeltoY = 0.;
289  fXlowNDC = 0;
290  fYlowNDC = 0;
291  fWNDC = 1;
292  fHNDC = 1;
293  fXUpNDC = 0.;
294  fYUpNDC = 0.;
295  fAbsXlowNDC = 0.;
296  fAbsYlowNDC = 0.;
297  fAbsWNDC = 0.;
298  fAbsHNDC = 0.;
299  fXtoAbsPixelk = 0.;
300  fXtoPixelk = 0.;
301  fXtoPixel = 0.;
302  fYtoAbsPixelk = 0.;
303  fYtoPixelk = 0.;
304  fYtoPixel = 0.;
305  fUtoAbsPixelk = 0.;
306  fUtoPixelk = 0.;
307  fUtoPixel = 0.;
308 
309  fUxmin = fUymin = fUxmax = fUymax = 0;
310  fLogx = gStyle->GetOptLogx();
311  fLogy = gStyle->GetOptLogy();
312  fLogz = gStyle->GetOptLogz();
313 
315  fAspectRatio = 0.;
316 
317  fNumPaletteColor = 0;
318  fNextPaletteColor = 0;
319  fCollideGrid = 0;
320  fCGnx = 0;
321  fCGny = 0;
322 
323  fViewer3D = 0;
324 
326  // Set default world coordinates to NDC [0,1]
327  fX1 = 0;
328  fX2 = 1;
329  fY1 = 0;
330  fY2 = 1;
331 
332  if (!gPad) {
333  Error("TPad", "You must create a TCanvas before creating a TPad");
334  MakeZombie();
335  return;
336  }
337 
338  TPad *padsav = (TPad*)gPad;
339 
340  if ((xlow < 0) || (xlow > 1) || (ylow < 0) || (ylow > 1)) {
341  Error("TPad", "illegal bottom left position: x=%f, y=%f", xlow, ylow);
342  goto zombie;
343  }
344  if ((xup < 0) || (xup > 1) || (yup < 0) || (yup > 1)) {
345  Error("TPad", "illegal top right position: x=%f, y=%f", xup, yup);
346  goto zombie;
347  }
348 
349  fLogx = gStyle->GetOptLogx();
350  fLogy = gStyle->GetOptLogy();
351  fLogz = gStyle->GetOptLogz();
352 
353  fUxmin = fUymin = fUxmax = fUymax = 0;
354 
355  // Set pad parameters and Compute conversion coefficients
356  SetPad(name, title, xlow, ylow, xup, yup, color, bordersize, bordermode);
357  Range(0, 0, 1, 1);
360 
361  padsav->cd();
362  return;
363 
364 zombie:
365  // error in creating pad occurred, make this pad a zombie
366  MakeZombie();
367  padsav->cd();
368 }
369 
370 
371 ////////////////////////////////////////////////////////////////////////////////
372 /// Pad destructor.
373 
375 {
376  if (!TestBit(kNotDeleted)) return;
377  Close();
380  auto primitives = fPrimitives;
381  // In some cases, fPrimitives has the kMustCleanup bit set which will lead
382  // its destructor to call RecursiveRemove and since this pad is still
383  // likely to be (indirectly) in the list of cleanups, we must set
384  // fPrimitives to nullptr to avoid TPad::RecursiveRemove from calling
385  // a member function of a partially destructed object.
386  fPrimitives = nullptr;
387  delete primitives;
389  delete fViewer3D;
390  if (fCollideGrid) delete [] fCollideGrid;
391 
392  // Required since we overload TObject::Hash.
394 }
395 
396 ////////////////////////////////////////////////////////////////////////////////
397 /// Add a new TExec object to the list of Execs.
398 ///
399 /// When an event occurs in the pad (mouse click, etc) the list of C++ commands
400 /// in the list of Execs are executed via TPad::AutoExec.
401 ///
402 /// When a pad event occurs (mouse move, click, etc) all the commands
403 /// contained in the fExecs list are executed in the order found in the list.
404 ///
405 /// This facility is activated by default. It can be deactivated by using
406 /// the canvas "Option" menu.
407 ///
408 /// The following examples of TExec commands are provided in the tutorials:
409 /// macros exec1.C and exec2.C.
410 ///
411 /// ### Example1 of use of exec1.C
412 /// ~~~ {.cpp}
413 /// Root > TFile f("hsimple.root")
414 /// Root > hpx.Draw()
415 /// Root > c1.AddExec("ex1",".x exec1.C")
416 /// ~~~
417 ///
418 /// At this point you can use the mouse to click on the contour of
419 /// the histogram hpx. When the mouse is clicked, the bin number and its
420 /// contents are printed.
421 ///
422 /// ### Example2 of use of exec1.C
423 /// ~~~ {.cpp}
424 /// Root > TFile f("hsimple.root")
425 /// Root > hpxpy.Draw()
426 /// Root > c1.AddExec("ex2",".x exec2.C")
427 /// ~~~
428 ///
429 /// When moving the mouse in the canvas, a second canvas shows the
430 /// projection along X of the bin corresponding to the Y position
431 /// of the mouse. The resulting histogram is fitted with a gaussian.
432 /// A "dynamic" line shows the current bin position in Y.
433 /// This more elaborated example can be used as a starting point
434 /// to develop more powerful interactive applications exploiting the C++
435 /// interpreter as a development engine.
436 
437 void TPad::AddExec(const char *name, const char*command)
438 {
439  if (!fExecs) fExecs = new TList;
440  TExec *ex = new TExec(name,command);
441  fExecs->Add(ex);
442 }
443 
444 ////////////////////////////////////////////////////////////////////////////////
445 /// Execute the list of Execs when a pad event occurs.
446 
448 {
449  if (GetCrosshair()) DrawCrosshair();
450 
451  if (!fExecs) fExecs = new TList;
452  TIter next(fExecs);
453  TExec *exec;
454  while ((exec = (TExec*)next())) {
455  exec->Exec();
456  }
457 }
458 
459 ////////////////////////////////////////////////////////////////////////////////
460 /// Browse pad.
461 
463 {
464  cd();
465  if (fPrimitives) fPrimitives->Browse(b);
466 }
467 
468 ////////////////////////////////////////////////////////////////////////////////
469 /// Build a legend from the graphical objects in the pad.
470 ///
471 /// A simple method to build automatically a TLegend from the primitives in a TPad.
472 ///
473 /// Only those deriving from TAttLine, TAttMarker and TAttFill are added, excluding
474 /// TPave and TFrame derived classes.
475 ///
476 /// \param[in] x1, y1, x2, y2 The TLegend coordinates
477 /// \param[in] title The legend title. By default it is " "
478 /// \param[in] option The TLegend option
479 ///
480 /// The caller program owns the returned TLegend.
481 ///
482 /// If the pad contains some TMultiGraph or THStack the individual
483 /// graphs or histograms in them are added to the TLegend.
484 
486  const char* title, Option_t *option)
487 {
488  TList *lop=GetListOfPrimitives();
489  if (!lop) return 0;
490  TLegend *leg=0;
491  TIter next(lop);
492  TString mes;
493  TObject *o=0;
494  TString opt("");
495  while( (o=next()) ) {
497  o->InheritsFrom(TAttFill::Class())) &&
498  ( !(o->InheritsFrom(TFrame::Class())) && !(o->InheritsFrom(TPave::Class())) )) {
499  if (!leg) leg = new TLegend(x1, y1, x2, y2, title);
500  if (o->InheritsFrom(TNamed::Class()) && strlen(((TNamed *)o)->GetTitle()))
501  mes = ((TNamed *)o)->GetTitle();
502  else if (strlen(o->GetName()))
503  mes = o->GetName();
504  else
505  mes = o->ClassName();
506  if (strlen(option)) {
507  opt = option;
508  } else {
509  if (o->InheritsFrom(TAttLine::Class())) opt += "l";
510  if (o->InheritsFrom(TAttMarker::Class())) opt += "p";
511  if (o->InheritsFrom(TAttFill::Class())) opt += "f";
512  }
513  leg->AddEntry(o,mes.Data(),opt.Data());
514  } else if ( o->InheritsFrom(TMultiGraph::Class() ) ) {
515  if (!leg) leg = new TLegend(x1, y1, x2, y2, title);
516  TList * grlist = ((TMultiGraph *)o)->GetListOfGraphs();
517  TIter nextgraph(grlist);
518  TGraph * gr;
519  TObject * obj;
520  while ((obj = nextgraph())) {
521  gr = (TGraph*) obj;
522  if (strlen(gr->GetTitle())) mes = gr->GetTitle();
523  else if (strlen(gr->GetName())) mes = gr->GetName();
524  else mes = gr->ClassName();
525  if (strlen(option)) opt = option;
526  else opt = "lpf";
527  leg->AddEntry( obj, mes.Data(), opt );
528  }
529  } else if ( o->InheritsFrom(THStack::Class() ) ) {
530  if (!leg) leg = new TLegend(x1, y1, x2, y2, title);
531  TList * hlist = ((THStack *)o)->GetHists();
532  TIter nexthist(hlist);
533  TH1 * hist;
534  TObject * obj;
535  while ((obj = nexthist())) {
536  hist = (TH1*) obj;
537  if (strlen(hist->GetTitle())) mes = hist->GetTitle();
538  else if (strlen(hist->GetName())) mes = hist->GetName();
539  else mes = hist->ClassName();
540  if (strlen(option)) opt = option;
541  else opt = "lpf";
542  leg->AddEntry( obj, mes.Data(), opt );
543  }
544  }
545  }
546  if (leg) {
547  TVirtualPad *gpadsave;
548  gpadsave = gPad;
549  this->cd();
550  leg->Draw();
551  gpadsave->cd();
552  } else {
553  Info("BuildLegend(void)","No object to build a TLegend.");
554  }
555  return leg;
556 }
557 
558 ////////////////////////////////////////////////////////////////////////////////
559 /// Set Current pad.
560 ///
561 /// When a canvas/pad is divided via TPad::Divide, one can directly
562 /// set the current path to one of the subdivisions.
563 /// See TPad::Divide for the convention to number sub-pads.
564 ///
565 /// Returns the new current pad, or 0 in case of failure.
566 ///
567 /// For example:
568 /// ~~~ {.cpp}
569 /// c1.Divide(2,3); // create 6 pads (2 divisions along x, 3 along y).
570 /// ~~~
571 /// To set the current pad to the bottom right pad, do
572 /// ~~~ {.cpp}
573 /// c1.cd(6);
574 /// ~~~
575 /// Note1: c1.cd() is equivalent to c1.cd(0) and sets the current pad
576 /// to c1 itself.
577 ///
578 /// Note2: after a statement like c1.cd(6), the global variable gPad
579 /// points to the current pad. One can use gPad to set attributes
580 /// of the current pad.
581 ///
582 /// Note3: One can get a pointer to one of the sub-pads of pad with:
583 /// TPad *subpad = (TPad*)pad->GetPad(subpadnumber);
584 
585 TVirtualPad *TPad::cd(Int_t subpadnumber)
586 {
587  if (!subpadnumber) {
588  gPad = this;
589  if (!gPad->IsBatch() && GetPainter()) GetPainter()->SelectDrawable(fPixmapID);
590  return gPad;
591  }
592 
593  TObject *obj;
594  if (!fPrimitives) fPrimitives = new TList;
595  TIter next(fPrimitives);
596  while ((obj = next())) {
597  if (obj->InheritsFrom(TPad::Class())) {
598  Int_t n = ((TPad*)obj)->GetNumber();
599  if (n == subpadnumber) {
600  return ((TPad*)obj)->cd();
601  }
602  }
603  }
604  return 0;
605 }
606 
607 ////////////////////////////////////////////////////////////////////////////////
608 /// Delete all pad primitives.
609 ///
610 /// If the bit kClearAfterCR has been set for this pad, the Clear function
611 /// will execute only after having pressed a CarriageReturn
612 /// Set the bit with `mypad->SetBit(TPad::kClearAfterCR)`
613 
614 void TPad::Clear(Option_t *option)
615 {
616  if (!IsEditable()) return;
617 
619 
620  if (!fPadPaint) {
621  SafeDelete(fView);
622  if (fPrimitives) fPrimitives->Clear(option);
623  if (fFrame) {
624  if (fFrame->TestBit(kNotDeleted)) delete fFrame;
625  fFrame = 0;
626  }
627  }
628  if (fCanvas) fCanvas->Cleared(this);
629 
630  cd();
631 
632  if (TestBit(kClearAfterCR)) {
633  // Intentional do not use the return value of getchar,
634  // we just want to get it and forget it
635  getchar();
636  }
637 
638  if (!gPad->IsBatch()) GetPainter()->ClearDrawable();
639  if (gVirtualPS && gPad == gPad->GetCanvas()) gVirtualPS->NewPage();
640 
642  fCrosshairPos = 0;
643  fNumPaletteColor = 0;
644  if (fCollideGrid) {
645  delete [] fCollideGrid;
646  fCollideGrid = 0;
647  fCGnx = 0;
648  fCGny = 0;
649  }
651 }
652 
653 ////////////////////////////////////////////////////////////////////////////////
654 /// Clipping routine: Cohen Sutherland algorithm.
655 ///
656 /// - If Clip ==2 the segment is outside the boundary.
657 /// - If Clip ==1 the segment has one point outside the boundary.
658 /// - If Clip ==0 the segment is inside the boundary.
659 ///
660 /// \param[in] x[],y[] Segment coordinates (2 points)
661 /// \param[in] xclipl,yclipb,xclipr,yclipt Clipping boundary
662 /// \param[out] x[],y[] New segment coordinates( 2 points)
663 
664 Int_t TPad::Clip(Float_t *x, Float_t *y, Float_t xclipl, Float_t yclipb, Float_t xclipr, Float_t yclipt)
665 {
666  const Float_t kP=10000;
667  Int_t clip = 0;
668 
669  for (Int_t i=0;i<2;i++) {
670  if (TMath::Abs(xclipl-x[i]) <= TMath::Abs(xclipr-xclipl)/kP) x[i] = xclipl;
671  if (TMath::Abs(xclipr-x[i]) <= TMath::Abs(xclipr-xclipl)/kP) x[i] = xclipr;
672  if (TMath::Abs(yclipb-y[i]) <= TMath::Abs(yclipt-yclipb)/kP) y[i] = yclipb;
673  if (TMath::Abs(yclipt-y[i]) <= TMath::Abs(yclipt-yclipb)/kP) y[i] = yclipt;
674  }
675 
676  // Compute the first endpoint codes.
677  Int_t code1 = ClippingCode(x[0],y[0],xclipl,yclipb,xclipr,yclipt);
678  Int_t code2 = ClippingCode(x[1],y[1],xclipl,yclipb,xclipr,yclipt);
679 
680  Double_t xt=0, yt=0;
681  Int_t clipped = 0; //this variable could be used in a future version
682  while(code1 + code2) {
683  clipped = 1;
684 
685  // The line lies entirely outside the clipping boundary
686  if (code1&code2) {
687  clip = 2;
688  return clip;
689  }
690 
691  // The line is subdivided into several parts
692  Int_t ic = code1;
693  if (ic == 0) ic = code2;
694  if (ic & 0x1) {
695  yt = y[0] + (y[1]-y[0])*(xclipl-x[0])/(x[1]-x[0]);
696  xt = xclipl;
697  }
698  if (ic & 0x2) {
699  yt = y[0] + (y[1]-y[0])*(xclipr-x[0])/(x[1]-x[0]);
700  xt = xclipr;
701  }
702  if (ic & 0x4) {
703  xt = x[0] + (x[1]-x[0])*(yclipb-y[0])/(y[1]-y[0]);
704  yt = yclipb;
705  }
706  if (ic & 0x8) {
707  xt = x[0] + (x[1]-x[0])*(yclipt-y[0])/(y[1]-y[0]);
708  yt = yclipt;
709  }
710  if (ic == code1) {
711  x[0] = xt;
712  y[0] = yt;
713  code1 = ClippingCode(xt,yt,xclipl,yclipb,xclipr,yclipt);
714  } else {
715  x[1] = xt;
716  y[1] = yt;
717  code2 = ClippingCode(xt,yt,xclipl,yclipb,xclipr,yclipt);
718  }
719  }
720  clip = clipped;
721  return clip;
722 }
723 
724 ////////////////////////////////////////////////////////////////////////////////
725 /// Clipping routine: Cohen Sutherland algorithm.
726 ///
727 /// - If Clip ==2 the segment is outside the boundary.
728 /// - If Clip ==1 the segment has one point outside the boundary.
729 /// - If Clip ==0 the segment is inside the boundary.
730 ///
731 /// \param[in] x[],y[] Segment coordinates (2 points)
732 /// \param[in] xclipl,yclipb,xclipr,yclipt Clipping boundary
733 /// \param[out] x[],y[] New segment coordinates(2 points)
734 
735 Int_t TPad::Clip(Double_t *x, Double_t *y, Double_t xclipl, Double_t yclipb, Double_t xclipr, Double_t yclipt)
736 {
737  const Double_t kP=10000;
738  Int_t clip = 0;
739 
740  for (Int_t i=0;i<2;i++) {
741  if (TMath::Abs(xclipl-x[i]) <= TMath::Abs(xclipr-xclipl)/kP) x[i] = xclipl;
742  if (TMath::Abs(xclipr-x[i]) <= TMath::Abs(xclipr-xclipl)/kP) x[i] = xclipr;
743  if (TMath::Abs(yclipb-y[i]) <= TMath::Abs(yclipt-yclipb)/kP) y[i] = yclipb;
744  if (TMath::Abs(yclipt-y[i]) <= TMath::Abs(yclipt-yclipb)/kP) y[i] = yclipt;
745  }
746 
747  // Compute the first endpoint codes.
748  Int_t code1 = 0;
749  if (x[0] < xclipl) code1 = code1 | 0x1;
750  if (x[0] > xclipr) code1 = code1 | 0x2;
751  if (y[0] < yclipb) code1 = code1 | 0x4;
752  if (y[0] > yclipt) code1 = code1 | 0x8;
753  Int_t code2 = 0;
754  if (x[1] < xclipl) code2 = code2 | 0x1;
755  if (x[1] > xclipr) code2 = code2 | 0x2;
756  if (y[1] < yclipb) code2 = code2 | 0x4;
757  if (y[1] > yclipt) code2 = code2 | 0x8;
758 
759  Double_t xt=0, yt=0;
760  Int_t clipped = 0; //this variable could be used in a future version
761  while(code1 + code2) {
762  clipped = 1;
763 
764  // The line lies entirely outside the clipping boundary
765  if (code1&code2) {
766  clip = 2;
767  return clip;
768  }
769 
770  // The line is subdivided into several parts
771  Int_t ic = code1;
772  if (ic == 0) ic = code2;
773  if (ic & 0x1) {
774  yt = y[0] + (y[1]-y[0])*(xclipl-x[0])/(x[1]-x[0]);
775  xt = xclipl;
776  }
777  if (ic & 0x2) {
778  yt = y[0] + (y[1]-y[0])*(xclipr-x[0])/(x[1]-x[0]);
779  xt = xclipr;
780  }
781  if (ic & 0x4) {
782  xt = x[0] + (x[1]-x[0])*(yclipb-y[0])/(y[1]-y[0]);
783  yt = yclipb;
784  }
785  if (ic & 0x8) {
786  xt = x[0] + (x[1]-x[0])*(yclipt-y[0])/(y[1]-y[0]);
787  yt = yclipt;
788  }
789  if (ic == code1) {
790  x[0] = xt;
791  y[0] = yt;
792  code1 = ClippingCode(xt,yt,xclipl,yclipb,xclipr,yclipt);
793  } else {
794  x[1] = xt;
795  y[1] = yt;
796  code2 = ClippingCode(xt,yt,xclipl,yclipb,xclipr,yclipt);
797  }
798  }
799  clip = clipped;
800  return clip;
801 }
802 
803 ////////////////////////////////////////////////////////////////////////////////
804 /// Compute the endpoint codes for TPad::Clip.
805 
807 {
808  Int_t code = 0;
809  if (x < xcl1) code = code | 0x1;
810  if (x > xcl2) code = code | 0x2;
811  if (y < ycl1) code = code | 0x4;
812  if (y > ycl2) code = code | 0x8;
813  return code;
814 }
815 
816 ////////////////////////////////////////////////////////////////////////////////
817 /// Clip polygon using the Sutherland-Hodgman algorithm.
818 ///
819 /// \param[in] n Number of points in the polygon to
820 /// be clipped
821 /// \param[in] x[n],y[n] Polygon do be clipped vertices
822 /// \param[in] xclipl,yclipb,xclipr,yclipt Clipping boundary
823 /// \param[out] nn Number of points in xc and yc
824 /// \param[out] xc,yc Clipped polygon vertices. The Int_t
825 /// returned by this function is
826 /// the number of points in the clipped
827 /// polygon. These vectors must
828 /// be allocated by the calling function.
829 /// A size of 2*n for each is
830 /// enough.
831 ///
832 /// Sutherland and Hodgman's polygon-clipping algorithm uses a divide-and-conquer
833 /// strategy: It solves a series of simple and identical problems that, when
834 /// combined, solve the overall problem. The simple problem is to clip a polygon
835 /// against a single infinite clip edge. Four clip edges, each defining one boundary
836 /// of the clip rectangle, successively clip a polygon against a clip rectangle.
837 ///
838 /// Steps of Sutherland-Hodgman's polygon-clipping algorithm:
839 ///
840 /// * Polygons can be clipped against each edge of the window one at a time.
841 /// Windows/edge intersections, if any, are easy to find since the X or Y coordinates
842 /// are already known.
843 /// * Vertices which are kept after clipping against one window edge are saved for
844 /// clipping against the remaining edges.
845 /// * Note that the number of vertices usually changes and will often increases.
846 ///
847 /// The clip boundary determines a visible and invisible region. The edges from
848 /// vertex i to vertex i+1 can be one of four types:
849 ///
850 /// * Case 1 : Wholly inside visible region - save endpoint
851 /// * Case 2 : Exit visible region - save the intersection
852 /// * Case 3 : Wholly outside visible region - save nothing
853 /// * Case 4 : Enter visible region - save intersection and endpoint
854 
856 {
857  Int_t nc, nc2;
858  Double_t x1, y1, x2, y2, slope; // Segment to be clipped
859 
860  Double_t *xc2 = new Double_t[nn];
861  Double_t *yc2 = new Double_t[nn];
862 
863  // Clip against the left boundary
864  x1 = x[n-1]; y1 = y[n-1];
865  nc2 = 0;
866  Int_t i;
867  for (i=0; i<n; i++) {
868  x2 = x[i]; y2 = y[i];
869  if (x1 == x2) {
870  slope = 0;
871  } else {
872  slope = (y2-y1)/(x2-x1);
873  }
874  if (x1 >= xclipl) {
875  if (x2 < xclipl) {
876  xc2[nc2] = xclipl; yc2[nc2++] = slope*(xclipl-x1)+y1;
877  } else {
878  xc2[nc2] = x2; yc2[nc2++] = y2;
879  }
880  } else {
881  if (x2 >= xclipl) {
882  xc2[nc2] = xclipl; yc2[nc2++] = slope*(xclipl-x1)+y1;
883  xc2[nc2] = x2; yc2[nc2++] = y2;
884  }
885  }
886  x1 = x2; y1 = y2;
887  }
888 
889  // Clip against the top boundary
890  x1 = xc2[nc2-1]; y1 = yc2[nc2-1];
891  nc = 0;
892  for (i=0; i<nc2; i++) {
893  x2 = xc2[i]; y2 = yc2[i];
894  if (y1 == y2) {
895  slope = 0;
896  } else {
897  slope = (x2-x1)/(y2-y1);
898  }
899  if (y1 <= yclipt) {
900  if (y2 > yclipt) {
901  xc[nc] = x1+(yclipt-y1)*slope; yc[nc++] = yclipt;
902  } else {
903  xc[nc] = x2; yc[nc++] = y2;
904  }
905  } else {
906  if (y2 <= yclipt) {
907  xc[nc] = x1+(yclipt-y1)*slope; yc[nc++] = yclipt;
908  xc[nc] = x2; yc[nc++] = y2;
909  }
910  }
911  x1 = x2; y1 = y2;
912  }
913 
914  // Clip against the right boundary
915  x1 = xc[nc-1]; y1 = yc[nc-1];
916  nc2 = 0;
917  for (i=0; i<nc; i++) {
918  x2 = xc[i]; y2 = yc[i];
919  if (x1 == x2) {
920  slope = 0;
921  } else {
922  slope = (y2-y1)/(x2-x1);
923  }
924  if (x1 <= xclipr) {
925  if (x2 > xclipr) {
926  xc2[nc2] = xclipr; yc2[nc2++] = slope*(xclipr-x1)+y1;
927  } else {
928  xc2[nc2] = x2; yc2[nc2++] = y2;
929  }
930  } else {
931  if (x2 <= xclipr) {
932  xc2[nc2] = xclipr; yc2[nc2++] = slope*(xclipr-x1)+y1;
933  xc2[nc2] = x2; yc2[nc2++] = y2;
934  }
935  }
936  x1 = x2; y1 = y2;
937  }
938 
939  // Clip against the bottom boundary
940  x1 = xc2[nc2-1]; y1 = yc2[nc2-1];
941  nc = 0;
942  for (i=0; i<nc2; i++) {
943  x2 = xc2[i]; y2 = yc2[i];
944  if (y1 == y2) {
945  slope = 0;
946  } else {
947  slope = (x2-x1)/(y2-y1);
948  }
949  if (y1 >= yclipb) {
950  if (y2 < yclipb) {
951  xc[nc] = x1+(yclipb-y1)*slope; yc[nc++] = yclipb;
952  } else {
953  xc[nc] = x2; yc[nc++] = y2;
954  }
955  } else {
956  if (y2 >= yclipb) {
957  xc[nc] = x1+(yclipb-y1)*slope; yc[nc++] = yclipb;
958  xc[nc] = x2; yc[nc++] = y2;
959  }
960  }
961  x1 = x2; y1 = y2;
962  }
963 
964  delete [] xc2;
965  delete [] yc2;
966 
967  if (nc < 3) nc =0;
968  return nc;
969 }
970 
971 ////////////////////////////////////////////////////////////////////////////////
972 /// Delete all primitives in pad and pad itself.
973 /// Pad cannot be used anymore after this call.
974 /// Emits signal "Closed()".
975 
977 {
978  if (!TestBit(kNotDeleted)) return;
979  if (!fMother) return;
980 
981  if (fPrimitives)
982  fPrimitives->Clear();
983  if (fView) {
984  if (fView->TestBit(kNotDeleted)) delete fView;
985  fView = 0;
986  }
987  if (fFrame) {
988  if (fFrame->TestBit(kNotDeleted)) delete fFrame;
989  fFrame = 0;
990  }
991 
992  // emit signal
993  if (IsA() != TCanvas::Class())
994  Closed();
995 
996  if (fPixmapID != -1) {
997  if (gPad) {
998  if (!gPad->IsBatch())
1000  }
1001  fPixmapID = -1;
1002 
1003  if (!gROOT->GetListOfCanvases()) return;
1004  if (fMother == this) {
1005  gROOT->GetListOfCanvases()->Remove(this);
1006  return; // in case of TCanvas
1007  }
1008 
1009  // remove from the mother's list of primitives
1010  if (fMother) {
1013 
1014  if (gPad == this) fMother->cd();
1015  }
1016 
1017  if (fCanvas->GetPadSave() == this)
1018  fCanvas->ClearPadSave();
1019  if (fCanvas->GetSelectedPad() == this)
1020  fCanvas->SetSelectedPad(0);
1021  if (fCanvas->GetClickSelectedPad() == this)
1023  }
1024 
1025  fMother = 0;
1026  if (gROOT->GetSelectedPad() == this) gROOT->SetSelectedPad(0);
1027 }
1028 
1029 ////////////////////////////////////////////////////////////////////////////////
1030 /// Copy the pixmap of the pad to the canvas.
1031 
1033 {
1034  int px, py;
1035  XYtoAbsPixel(fX1, fY2, px, py);
1036 
1037  if (fPixmapID != -1)
1038  GetPainter()->CopyDrawable(fPixmapID, px, py);
1039 
1040  if (this == gPad) HighLight(gPad->GetHighLightColor());
1041 }
1042 
1043 ////////////////////////////////////////////////////////////////////////////////
1044 /// Copy the sub-pixmaps of the pad to the canvas.
1045 
1047 {
1048  TObject *obj;
1049  if (!fPrimitives) fPrimitives = new TList;
1050  TIter next(GetListOfPrimitives());
1051  while ((obj = next())) {
1052  if (obj->InheritsFrom(TPad::Class())) {
1053  ((TPad*)obj)->CopyPixmap();
1054  ((TPad*)obj)->CopyPixmaps();
1055  }
1056  }
1057 }
1058 
1059 ////////////////////////////////////////////////////////////////////////////////
1060 /// Remove TExec name from the list of Execs.
1061 
1062 void TPad::DeleteExec(const char *name)
1063 {
1064  if (!fExecs) fExecs = new TList;
1065  TExec *ex = (TExec*)fExecs->FindObject(name);
1066  if (!ex) return;
1067  fExecs->Remove(ex);
1068  delete ex;
1069 }
1070 
1071 ////////////////////////////////////////////////////////////////////////////////
1072 /// Compute distance from point px,py to a box.
1073 ///
1074 /// Compute the closest distance of approach from point px,py to the
1075 /// edges of this pad.
1076 /// The distance is computed in pixels units.
1077 
1079 {
1080  Int_t pxl, pyl, pxt, pyt;
1081  Int_t px1 = gPad->XtoAbsPixel(fX1);
1082  Int_t py1 = gPad->YtoAbsPixel(fY1);
1083  Int_t px2 = gPad->XtoAbsPixel(fX2);
1084  Int_t py2 = gPad->YtoAbsPixel(fY2);
1085  if (px1 < px2) {pxl = px1; pxt = px2;}
1086  else {pxl = px2; pxt = px1;}
1087  if (py1 < py2) {pyl = py1; pyt = py2;}
1088  else {pyl = py2; pyt = py1;}
1089 
1090  // Are we inside the box?
1091  // ======================
1092  if ( (px > pxl && px < pxt) && (py > pyl && py < pyt) ) {
1093  if (GetFillStyle()) return 0; //*-* if pad is filled
1094  }
1095 
1096  // Are we on the edges?
1097  // ====================
1098  Int_t dxl = TMath::Abs(px - pxl);
1099  if (py < pyl) dxl += pyl - py;
1100  if (py > pyt) dxl += py - pyt;
1101  Int_t dxt = TMath::Abs(px - pxt);
1102  if (py < pyl) dxt += pyl - py;
1103  if (py > pyt) dxt += py - pyt;
1104  Int_t dyl = TMath::Abs(py - pyl);
1105  if (px < pxl) dyl += pxl - px;
1106  if (px > pxt) dyl += px - pxt;
1107  Int_t dyt = TMath::Abs(py - pyt);
1108  if (px < pxl) dyt += pxl - px;
1109  if (px > pxt) dyt += px - pxt;
1110 
1111  Int_t distance = dxl;
1112  if (dxt < distance) distance = dxt;
1113  if (dyl < distance) distance = dyl;
1114  if (dyt < distance) distance = dyt;
1115 
1116  return distance - Int_t(0.5*fLineWidth);
1117 }
1118 
1119 ////////////////////////////////////////////////////////////////////////////////
1120 /// Automatic pad generation by division.
1121 ///
1122 /// - The current canvas is divided in nx by ny equal divisions (pads).
1123 /// - xmargin is the space along x between pads in percent of canvas.
1124 /// - ymargin is the space along y between pads in percent of canvas.
1125 /// - color is the color of the new pads. If 0, color is the canvas color.
1126 ///
1127 /// Pads are automatically named `canvasname_n` where `n` is the division number
1128 /// starting from top left pad.
1129 ///
1130 /// Example if canvasname=c1 , nx=2, ny=3:
1131 ///
1132 /// \image html gpad_pad3.png
1133 ///
1134 /// Once a pad is divided into sub-pads, one can set the current pad
1135 /// to a subpad with a given division number as illustrated above
1136 /// with TPad::cd(subpad_number).
1137 ///
1138 /// For example, to set the current pad to c1_4, one can do:
1139 /// ~~~ {.cpp}
1140 /// c1->cd(4)
1141 /// ~~~
1142 /// __Note1:__ c1.cd() is equivalent to c1.cd(0) and sets the current pad
1143 /// to c1 itself.
1144 ///
1145 /// __Note2:__ after a statement like c1.cd(6), the global variable gPad
1146 /// points to the current pad. One can use gPad to set attributes
1147 /// of the current pad.
1148 ///
1149 /// __Note3:__ in case xmargin <=0 and ymargin <= 0, there is no space
1150 /// between pads. The current pad margins are recomputed to
1151 /// optimize the layout.
1152 
1153 void TPad::Divide(Int_t nx, Int_t ny, Float_t xmargin, Float_t ymargin, Int_t color)
1154 {
1155  if (!IsEditable()) return;
1156 
1157 
1158  if (gThreadXAR) {
1159  void *arr[7];
1160  arr[1] = this; arr[2] = (void*)&nx;arr[3] = (void*)& ny;
1161  arr[4] = (void*)&xmargin; arr[5] = (void *)& ymargin; arr[6] = (void *)&color;
1162  if ((*gThreadXAR)("PDCD", 7, arr, 0)) return;
1163  }
1164 
1165  TPad *padsav = (TPad*)gPad;
1166  cd();
1167  if (nx <= 0) nx = 1;
1168  if (ny <= 0) ny = 1;
1169  Int_t ix,iy;
1170  Double_t x1,y1,x2,y2;
1171  Double_t dx,dy;
1172  TPad *pad;
1173  Int_t nchname = strlen(GetName())+6;
1174  Int_t nchtitle = strlen(GetTitle())+6;
1175  char *name = new char [nchname];
1176  char *title = new char [nchtitle];
1177  Int_t n = 0;
1178  if (color == 0) color = GetFillColor();
1179  if (xmargin > 0 && ymargin > 0) {
1180  //general case
1181  dy = 1/Double_t(ny);
1182  dx = 1/Double_t(nx);
1183  for (iy=0;iy<ny;iy++) {
1184  y2 = 1 - iy*dy - ymargin;
1185  y1 = y2 - dy + 2*ymargin;
1186  if (y1 < 0) y1 = 0;
1187  if (y1 > y2) continue;
1188  for (ix=0;ix<nx;ix++) {
1189  x1 = ix*dx + xmargin;
1190  x2 = x1 +dx -2*xmargin;
1191  if (x1 > x2) continue;
1192  n++;
1193  snprintf(name,nchname,"%s_%d",GetName(),n);
1194  pad = new TPad(name,name,x1,y1,x2,y2,color);
1195  pad->SetNumber(n);
1196  pad->Draw();
1197  }
1198  }
1199  } else {
1200  // special case when xmargin <= 0 && ymargin <= 0
1201  Double_t xl = GetLeftMargin();
1202  Double_t xr = GetRightMargin();
1203  Double_t yb = GetBottomMargin();
1204  Double_t yt = GetTopMargin();
1205  xl /= (1-xl+xr)*nx;
1206  xr /= (1-xl+xr)*nx;
1207  yb /= (1-yb+yt)*ny;
1208  yt /= (1-yb+yt)*ny;
1209  SetLeftMargin(xl);
1210  SetRightMargin(xr);
1211  SetBottomMargin(yb);
1212  SetTopMargin(yt);
1213  dx = (1-xl-xr)/nx;
1214  dy = (1-yb-yt)/ny;
1215  Int_t number = 0;
1216  for (Int_t i=0;i<nx;i++) {
1217  x1 = i*dx+xl;
1218  x2 = x1 + dx;
1219  if (i == 0) x1 = 0;
1220  if (i == nx-1) x2 = 1-xr;
1221  for (Int_t j=0;j<ny;j++) {
1222  number = j*nx + i +1;
1223  y2 = 1 -j*dy -yt;
1224  y1 = y2 - dy;
1225  if (j == 0) y2 = 1-yt;
1226  if (j == ny-1) y1 = 0;
1227  snprintf(name,nchname,"%s_%d",GetName(),number);
1228  snprintf(title,nchtitle,"%s_%d",GetTitle(),number);
1229  pad = new TPad(name,title,x1,y1,x2,y2);
1230  pad->SetNumber(number);
1231  pad->SetBorderMode(0);
1232  if (i == 0) pad->SetLeftMargin(xl*nx);
1233  else pad->SetLeftMargin(0);
1234  pad->SetRightMargin(0);
1235  pad->SetTopMargin(0);
1236  if (j == ny-1) pad->SetBottomMargin(yb*ny);
1237  else pad->SetBottomMargin(0);
1238  pad->Draw();
1239  }
1240  }
1241  }
1242  delete [] name;
1243  delete [] title;
1244  Modified();
1245  if (padsav) padsav->cd();
1246 }
1247 
1248 ////////////////////////////////////////////////////////////////////////////////
1249 /// "n" is the total number of sub-pads. The number of sub-pads along the X
1250 /// and Y axis are computed according to the square root of n.
1251 
1252 void TPad::DivideSquare(Int_t n, Float_t xmargin, Float_t ymargin, Int_t color)
1253 {
1254  Int_t w = 1, h = 1;
1255 
1257  w = TMath::Ceil(TMath::Sqrt(n));
1258  h = TMath::Floor(TMath::Sqrt(n));
1259  if (w*h < n) w++;
1260  } else {
1261  h = TMath::Ceil(TMath::Sqrt(n));
1262  w = TMath::Floor(TMath::Sqrt(n));
1263  if (w*h < n) h++;
1264  }
1265 
1266  Divide( w, h, xmargin, ymargin, color);
1267 }
1268 
1269 ////////////////////////////////////////////////////////////////////////////////
1270 /// Draw Pad in Current pad (re-parent pad if necessary).
1271 
1272 void TPad::Draw(Option_t *option)
1273 {
1274  // if no canvas opened yet create a default canvas
1275  if (!gPad) {
1276  gROOT->MakeDefCanvas();
1277  }
1278 
1279  // pad cannot be in itself and it can only be in one other pad at a time
1280  if (!fPrimitives) fPrimitives = new TList;
1281  if (gPad != this) {
1282  if (fMother) fMother->GetListOfPrimitives()->Remove(this);
1283  TPad *oldMother = fMother;
1284  fCanvas = gPad->GetCanvas();
1285  //
1286  fMother = (TPad*)gPad;
1287  if (oldMother != fMother || fPixmapID == -1) ResizePad();
1288  }
1289 
1290  Paint();
1291 
1292  if (gPad->IsRetained() && gPad != this && fMother)
1293  fMother->GetListOfPrimitives()->Add(this, option);
1294 }
1295 
1296 ////////////////////////////////////////////////////////////////////////////////
1297 /// Draw class inheritance tree of the class to which obj belongs.
1298 ///
1299 /// If a class B inherits from a class A, description of B is drawn
1300 /// on the right side of description of A.
1301 ///
1302 /// Member functions overridden by B are shown in class A with a blue line
1303 /// crossing-out the corresponding member function.
1304 
1305 void TPad::DrawClassObject(const TObject *classobj, Option_t *option)
1306 {
1307  char dname[256];
1308  const Int_t kMAXLEVELS = 10;
1309  TClass *clevel[kMAXLEVELS], *cl, *cll;
1310  TBaseClass *base, *cinherit;
1311  TText *ptext = 0;
1312  TString opt=option;
1313  Double_t x,y,dy,y1,v1,v2,dv;
1314  Int_t nd,nf,nc,nkd,nkf,i,j;
1315  TPaveText *pt;
1316  Int_t maxlev = 4;
1317  if (opt.Contains("2")) maxlev = 2;
1318  if (opt.Contains("3")) maxlev = 3;
1319  if (opt.Contains("5")) maxlev = 5;
1320  if (opt.Contains("6")) maxlev = 6;
1321  if (opt.Contains("7")) maxlev = 7;
1322 
1323  // Clear and Set Pad range
1324  Double_t xpad = 20.5;
1325  Double_t ypad = 27.5;
1326  Clear();
1327  Range(0,0,xpad,ypad);
1328 
1329  // Find number of levels
1330  Int_t nlevel = 0;
1331  TClass *obj = (TClass*)classobj;
1332  clevel[nlevel] = obj;
1333  TList *lbase = obj->GetListOfBases();
1334  while(lbase) {
1335  base = (TBaseClass*)lbase->First();
1336  if (!base) break;
1337  if ( base->GetClassPointer() == 0) break;
1338  nlevel++;
1339  clevel[nlevel] = base->GetClassPointer();
1340  lbase = clevel[nlevel]->GetListOfBases();
1341  if (nlevel >= maxlev-1) break;
1342  }
1343  Int_t maxelem = 0;
1344  Int_t ncdraw = 0;
1345  Int_t ilevel, nelem;
1346  for (ilevel=nlevel;ilevel>=0;ilevel--) {
1347  cl = clevel[ilevel];
1348  nelem = cl->GetNdata() + cl->GetNmethods();
1349  if (nelem > maxelem) maxelem = nelem;
1350  nc = (nelem/50) + 1;
1351  ncdraw += nc;
1352  }
1353 
1354  Double_t tsizcm = 0.40;
1355  Double_t x1 = 0.25;
1356  Double_t x2 = 0;
1357  Double_t dx = 3.5;
1358  if (ncdraw > 4) {
1359  dx = dx - 0.42*Double_t(ncdraw-5);
1360  if (dx < 1.3) dx = 1.3;
1361  tsizcm = tsizcm - 0.03*Double_t(ncdraw-5);
1362  if (tsizcm < 0.27) tsizcm = 0.27;
1363  }
1364  Double_t tsiz = 1.2*tsizcm/ypad;
1365 
1366  // Now loop on levels
1367  for (ilevel=nlevel;ilevel>=0;ilevel--) {
1368  cl = clevel[ilevel];
1369  nelem = cl->GetNdata() + cl->GetNmethods();
1370  if (nelem > maxelem) maxelem = nelem;
1371  nc = (nelem/50) + 1;
1372  dy = 0.45;
1373  if (ilevel < nlevel) x1 = x2 + 0.5;
1374  x2 = x1 + nc*dx;
1375  v2 = ypad - 0.5;
1376  lbase = cl->GetListOfBases();
1377  cinherit = 0;
1378  if (lbase) cinherit = (TBaseClass*)lbase->First();
1379 
1380  do {
1381  nd = cl->GetNdata();
1382  nf = cl->GetNmethods() - 2; //do not show default constructor and destructor
1383  if (cl->GetListOfMethods()->FindObject("Dictionary")) {
1384  nf -= 6; // do not count the Dictionary/ClassDef functions
1385  }
1386  nkf= nf/nc +1;
1387  nkd= nd/nc +1;
1388  if (nd == 0) nkd=0;
1389  if (nf == 0) nkf=0;
1390  y1 = v2 - 0.7;
1391  v1 = y1 - Double_t(nkf+nkd+nc-1)*dy;
1392  dv = v2 - v1;
1393 
1394  // Create a new PaveText
1395  pt = new TPaveText(x1,v1,x2,v2);
1396  pt->SetBit(kCanDelete);
1397  pt->SetFillColor(19);
1398  pt->Draw();
1399  pt->SetTextColor(4);
1400  pt->SetTextFont(61);
1401  pt->SetTextAlign(12);
1402  pt->SetTextSize(tsiz);
1403  TBox *box = pt->AddBox(0,(y1+0.01-v1)/dv,0,(v2-0.01-v1)/dv);
1404  if (box) box->SetFillColor(17);
1405  pt->AddLine(0,(y1-v1)/dv,0,(y1-v1)/dv);
1406  TText *title = pt->AddText(0.5,(0.5*(y1+v2)-v1)/dv,(char*)cl->GetName());
1407  title->SetTextAlign(22);
1408  title->SetTextSize(0.6*(v2-y1)/ypad);
1409 
1410  // Draw data Members
1411  i = 0;
1412  x = 0.03;
1413  y = y1 + 0.5*dy;
1414  TDataMember *d;
1415  TIter nextd(cl->GetListOfDataMembers());
1416  while ((d = (TDataMember *) nextd())) {
1417  if (i >= nkd) { i = 1; y = y1 - 0.5*dy; x += 1/Double_t(nc); }
1418  else { i++; y -= dy; }
1419 
1420  // Take in account the room the array index will occupy
1421 
1422  Int_t dim = d->GetArrayDim();
1423  Int_t indx = 0;
1424  snprintf(dname,256,"%s",d->GetName());
1425  Int_t ldname = 0;
1426  while (indx < dim ){
1427  ldname = strlen(dname);
1428  snprintf(&dname[ldname],256-ldname,"[%d]",d->GetMaxIndex(indx));
1429  indx++;
1430  }
1431  pt->AddText(x,(y-v1)/dv,dname);
1432  }
1433 
1434  // Draw a separator line
1435  Double_t ysep;
1436  if (nd) {
1437  ysep = y1 - Double_t(nkd)*dy;
1438  pt->AddLine(0,(ysep-v1)/dv,0,(ysep-v1)/dv);
1439  ysep -= 0.5*dy;
1440  } else ysep = y1;
1441 
1442  // Draw Member Functions
1443  Int_t fcount = 0;
1444  i = 0;
1445  x = 0.03;
1446  y = ysep + 0.5*dy;
1447  TMethod *m;
1448  TIter nextm(cl->GetListOfMethods());
1449  while ((m = (TMethod *) nextm())) {
1450  if (
1451  !strcmp( m->GetName(), "Dictionary" ) ||
1452  !strcmp( m->GetName(), "Class_Version" ) ||
1453  !strcmp( m->GetName(), "DeclFileName" ) ||
1454  !strcmp( m->GetName(), "DeclFileLine" ) ||
1455  !strcmp( m->GetName(), "ImplFileName" ) ||
1456  !strcmp( m->GetName(), "ImplFileLine" )
1457  ) continue;
1458  fcount++;
1459  if (fcount > nf) break;
1460  if (i >= nkf) { i = 1; y = ysep - 0.5*dy; x += 1/Double_t(nc); }
1461  else { i++; y -= dy; }
1462 
1463  ptext = pt->AddText(x,(y-v1)/dv,m->GetName());
1464  // Check if method is overloaded in a derived class
1465  // If yes, Change the color of the text to blue
1466  for (j=ilevel-1;j>=0;j--) {
1467  if (cl == clevel[ilevel]) {
1468  if (clevel[j]->GetMethodAny((char*)m->GetName())) {
1469  ptext->SetTextColor(15);
1470  break;
1471  }
1472  }
1473  }
1474  }
1475 
1476  // Draw second inheritance classes for this class
1477  cll = 0;
1478  if (cinherit) {
1479  cinherit = (TBaseClass*)lbase->After(cinherit);
1480  if (cinherit) {
1481  cl = cinherit->GetClassPointer();
1482  cll = cl;
1483  v2 = v1 -0.4;
1484  dy = 0.35;
1485  }
1486  }
1487  } while (cll);
1488  }
1489  Update();
1490 }
1491 
1492 ////////////////////////////////////////////////////////////////////////////////
1493 /// Function called to draw a crosshair in the canvas
1494 ///
1495 /// Example:
1496 /// ~~~ {.cpp}
1497 /// Root > TFile f("hsimple.root");
1498 /// Root > hpxpy.Draw();
1499 /// Root > c1.SetCrosshair();
1500 /// ~~~
1501 /// When moving the mouse in the canvas, a crosshair is drawn
1502 ///
1503 /// - if the canvas fCrosshair = 1 , the crosshair spans the full canvas
1504 /// - if the canvas fCrosshair > 1 , the crosshair spans only the pad
1505 
1507 {
1508  if (gPad->GetEvent() == kMouseEnter) return;
1509 
1510  TPad *cpad = (TPad*)gPad;
1511  TCanvas *canvas = cpad->GetCanvas();
1512  canvas->FeedbackMode(kTRUE);
1513 
1514  //erase old position and draw a line at current position
1515  Int_t pxmin,pxmax,pymin,pymax,pxold,pyold,px,py;
1516  pxold = fCrosshairPos%10000;
1517  pyold = fCrosshairPos/10000;
1518  px = cpad->GetEventX();
1519  py = cpad->GetEventY()+1;
1520  if (canvas->GetCrosshair() > 1) { //crosshair only in the current pad
1521  pxmin = cpad->XtoAbsPixel(fX1);
1522  pxmax = cpad->XtoAbsPixel(fX2);
1523  pymin = cpad->YtoAbsPixel(fY1);
1524  pymax = cpad->YtoAbsPixel(fY2);
1525  } else { //default; crosshair spans the full canvas
1526  pxmin = 0;
1527  pxmax = canvas->GetWw();
1528  pymin = 0;
1529  pymax = cpad->GetWh();
1530  }
1531  if(pxold) gVirtualX->DrawLine(pxold,pymin,pxold,pymax);
1532  if(pyold) gVirtualX->DrawLine(pxmin,pyold,pxmax,pyold);
1533  if (cpad->GetEvent() == kButton1Down ||
1534  cpad->GetEvent() == kButton1Up ||
1535  cpad->GetEvent() == kMouseLeave) {
1536  fCrosshairPos = 0;
1537  return;
1538  }
1539  gVirtualX->DrawLine(px,pymin,px,pymax);
1540  gVirtualX->DrawLine(pxmin,py,pxmax,py);
1541  fCrosshairPos = px + 10000*py;
1542 }
1543 
1544 ////////////////////////////////////////////////////////////////////////////////
1545 /// Draw an empty pad frame with X and Y axis.
1546 ///
1547 /// \param[in] xmin X axis lower limit
1548 /// \param[in] xmax X axis upper limit
1549 /// \param[in] ymin Y axis lower limit
1550 /// \param[in] ymax Y axis upper limit
1551 /// \param[in] title Pad title.If title is of the form "stringt;stringx;stringy"
1552 /// the pad title is set to stringt, the x axis title to
1553 /// stringx, the y axis title to stringy.
1554 
1556 {
1557  if (!IsEditable()) return 0;
1558  TPad *padsav = (TPad*)gPad;
1559  if (this != padsav) {
1560  Warning("DrawFrame","Must be called for the current pad only");
1561  return padsav->DrawFrame(xmin,ymin,xmax,ymax,title);
1562  }
1563 
1564  cd();
1565 
1566  TH1F *hframe = (TH1F*)FindObject("hframe");
1567  if (hframe) delete hframe;
1568  Int_t nbins = 1000;
1569  //if log scale in X, use variable bin size linear with log(x)
1570  //this gives a better precision when zooming on the axis
1571  if (fLogx && xmin > 0 && xmax > xmin) {
1572  Double_t xminl = TMath::Log(xmin);
1573  Double_t xmaxl = TMath::Log(xmax);
1574  Double_t dx = (xmaxl-xminl)/nbins;
1575  Double_t *xbins = new Double_t[nbins+1];
1576  xbins[0] = xmin;
1577  for (Int_t i=1;i<=nbins;i++) {
1578  xbins[i] = TMath::Exp(xminl+i*dx);
1579  }
1580  hframe = new TH1F("hframe",title,nbins,xbins);
1581  delete [] xbins;
1582  } else {
1583  hframe = new TH1F("hframe",title,nbins,xmin,xmax);
1584  }
1585  hframe->SetBit(TH1::kNoStats);
1586  hframe->SetBit(kCanDelete);
1587  hframe->SetMinimum(ymin);
1588  hframe->SetMaximum(ymax);
1589  hframe->GetYaxis()->SetLimits(ymin,ymax);
1590  hframe->SetDirectory(0);
1591  hframe->Draw(" ");
1592  Update();
1593  if (padsav) padsav->cd();
1594  return hframe;
1595 }
1596 
1597 ////////////////////////////////////////////////////////////////////////////////
1598 /// Static function to Display Color Table in a pad.
1599 
1601 {
1602  Int_t i, j;
1603  Int_t color;
1604  Double_t xlow, ylow, xup, yup, hs, ws;
1605  Double_t x1, y1, x2, y2;
1606  x1 = y1 = 0;
1607  x2 = y2 = 20;
1608 
1609  gPad->SetFillColor(0);
1610  gPad->Clear();
1611  gPad->Range(x1,y1,x2,y2);
1612 
1613  TText *text = new TText(0,0,"");
1614  text->SetTextFont(61);
1615  text->SetTextSize(0.07);
1616  text->SetTextAlign(22);
1617 
1618  TBox *box = new TBox();
1619 
1620  // Draw color table boxes.
1621  hs = (y2-y1)/Double_t(5);
1622  ws = (x2-x1)/Double_t(10);
1623  for (i=0;i<10;i++) {
1624  xlow = x1 + ws*(Double_t(i)+0.1);
1625  xup = x1 + ws*(Double_t(i)+0.9);
1626  for (j=0;j<5;j++) {
1627  ylow = y1 + hs*(Double_t(j)+0.1);
1628  yup = y1 + hs*(Double_t(j)+0.9);
1629  color = 10*j + i;
1630  box->SetFillStyle(1001);
1631  box->SetFillColor(color);
1632  box->DrawBox(xlow, ylow, xup, yup);
1633  box->SetFillStyle(0);
1634  box->SetLineColor(1);
1635  box->DrawBox(xlow, ylow, xup, yup);
1636  if (color == 1) text->SetTextColor(0);
1637  else text->SetTextColor(1);
1638  text->DrawText(0.5*(xlow+xup), 0.5*(ylow+yup), Form("%d",color));
1639  }
1640  }
1641 }
1642 
1643 ////////////////////////////////////////////////////////////////////////////////
1644 /// Execute action corresponding to one event.
1645 ///
1646 /// This member function is called when a TPad object is clicked.
1647 ///
1648 /// If the mouse is clicked in one of the 4 corners of the pad (pA,pB,pC,pD)
1649 /// the pad is resized with the rubber rectangle.
1650 ///
1651 /// If the mouse is clicked inside the pad, the pad is moved.
1652 ///
1653 /// If the mouse is clicked on the 4 edges (pL,pR,pTop,pBot), the pad is scaled
1654 /// parallel to this edge.
1655 ///
1656 /// \image html gpad_pad4.png
1657 ///
1658 /// Note that this function duplicates on purpose the functionality
1659 /// already implemented in TBox::ExecuteEvent.
1660 /// If somebody modifies this function, may be similar changes should also
1661 /// be applied to TBox::ExecuteEvent.
1662 
1664 {
1665  const Int_t kMaxDiff = 5;
1666  const Int_t kMinSize = 20;
1667  static Int_t pxorg, pyorg;
1668  static Int_t px1, px2, py1, py2, pxl, pyl, pxt, pyt, pxold, pyold;
1669  static Int_t px1p, px2p, py1p, py2p, pxlp, pylp, pxtp, pytp;
1670  static Bool_t pA, pB, pC, pD, pTop, pL, pR, pBot, pINSIDE;
1671  Int_t wx, wy;
1672  Bool_t opaque = OpaqueMoving();
1673  Bool_t ropaque = OpaqueResizing();
1674  Bool_t fixedr = HasFixedAspectRatio();
1675 
1676  if (!IsEditable() && event != kMouseEnter) return;
1677  TVirtualPad *parent = GetMother();
1678  if (!parent->IsEditable()) return;
1679 
1680  HideToolTip(event);
1681 
1682  if (fXlowNDC < 0 && event != kButton1Down) return;
1683  if (fYlowNDC < 0 && event != kButton1Down) return;
1684 
1685  // keep old mouse position
1686  if (event == kButton1Down) {
1687  pxorg = px;
1688  pyorg = py;
1689  }
1690 
1691  Int_t newcode = gROOT->GetEditorMode();
1692  if (newcode)
1693  pA = pB = pC = pD = pTop = pL = pR = pBot = pINSIDE = kFALSE;
1694  switch (newcode) {
1695  case kPad:
1696  TCreatePrimitives::Pad(event,px,py,0);
1697  break;
1698  case kMarker:
1699  case kText:
1700  TCreatePrimitives::Text(event,px,py,newcode);
1701  break;
1702  case kLine:
1703  TCreatePrimitives::Line(event,px,py,kLine);
1704  break;
1705  case kArrow:
1706  TCreatePrimitives::Line(event,px,py,kArrow);
1707  break;
1708  case kCurlyLine:
1709  TCreatePrimitives::Line(event,px,py,kCurlyLine);
1710  break;
1711  case kCurlyArc:
1712  TCreatePrimitives::Line(event,px,py,kCurlyArc);
1713  break;
1714  case kPolyLine:
1716  break;
1717  case kCutG:
1718  TCreatePrimitives::PolyLine(event,px,py,kCutG);
1719  break;
1720  case kArc:
1721  TCreatePrimitives::Ellipse(event,px,py,kArc);
1722  break;
1723  case kEllipse:
1724  TCreatePrimitives::Ellipse(event,px,py,kEllipse);
1725  break;
1726  case kButton:
1727  case kPave:
1728  case kPaveLabel:
1729  case kPaveText:
1730  case kPavesText:
1731  case kDiamond:
1732  TCreatePrimitives::Pave(event,px,py,newcode);
1733  return;
1734  default:
1735  break;
1736  }
1737  if (newcode) return;
1738 
1739  switch (event) {
1740 
1741  case kMouseEnter:
1742  if (fTip)
1743  ResetToolTip(fTip);
1744  break;
1745 
1746  case kArrowKeyPress:
1747  case kButton1Down:
1748 
1749  fXUpNDC = fXlowNDC + fWNDC;
1750  fYUpNDC = fYlowNDC + fHNDC;
1751 
1752  GetPainter()->SetLineColor(-1);
1753  TAttLine::Modify(); //Change line attributes only if necessary
1754  if (GetFillColor())
1756  else
1757  GetPainter()->SetLineColor(1);
1758  GetPainter()->SetLineWidth(2);
1759 
1760  // No break !!!
1761 
1762  case kMouseMotion:
1763 
1764  px1 = XtoAbsPixel(fX1);
1765  py1 = YtoAbsPixel(fY1);
1766  px2 = XtoAbsPixel(fX2);
1767  py2 = YtoAbsPixel(fY2);
1768 
1769  if (px1 < px2) {
1770  pxl = px1;
1771  pxt = px2;
1772  } else {
1773  pxl = px2;
1774  pxt = px1;
1775  }
1776  if (py1 < py2) {
1777  pyl = py1;
1778  pyt = py2;
1779  } else {
1780  pyl = py2;
1781  pyt = py1;
1782  }
1783 
1784  px1p = parent->XtoAbsPixel(parent->GetX1()) + parent->GetBorderSize();
1785  py1p = parent->YtoAbsPixel(parent->GetY1()) - parent->GetBorderSize();
1786  px2p = parent->XtoAbsPixel(parent->GetX2()) - parent->GetBorderSize();
1787  py2p = parent->YtoAbsPixel(parent->GetY2()) + parent->GetBorderSize();
1788 
1789  if (px1p < px2p) {
1790  pxlp = px1p;
1791  pxtp = px2p;
1792  } else {
1793  pxlp = px2p;
1794  pxtp = px1p;
1795  }
1796  if (py1p < py2p) {
1797  pylp = py1p;
1798  pytp = py2p;
1799  } else {
1800  pylp = py2p;
1801  pytp = py1p;
1802  }
1803 
1804  pA = pB = pC = pD = pTop = pL = pR = pBot = pINSIDE = kFALSE;
1805 
1806  // case pA
1807  if (TMath::Abs(px - pxl) <= kMaxDiff && TMath::Abs(py - pyl) <= kMaxDiff) {
1808  pxold = pxl; pyold = pyl; pA = kTRUE;
1810  }
1811  // case pB
1812  if (TMath::Abs(px - pxt) <= kMaxDiff && TMath::Abs(py - pyl) <= kMaxDiff) {
1813  pxold = pxt; pyold = pyl; pB = kTRUE;
1815  }
1816  // case pC
1817  if (TMath::Abs(px - pxt) <= kMaxDiff && TMath::Abs(py - pyt) <= kMaxDiff) {
1818  pxold = pxt; pyold = pyt; pC = kTRUE;
1820  }
1821  // case pD
1822  if (TMath::Abs(px - pxl) <= kMaxDiff && TMath::Abs(py - pyt) <= kMaxDiff) {
1823  pxold = pxl; pyold = pyt; pD = kTRUE;
1825  }
1826 
1827  if ((px > pxl+kMaxDiff && px < pxt-kMaxDiff) &&
1828  TMath::Abs(py - pyl) < kMaxDiff) { // top edge
1829  pxold = pxl; pyold = pyl; pTop = kTRUE;
1831  }
1832 
1833  if ((px > pxl+kMaxDiff && px < pxt-kMaxDiff) &&
1834  TMath::Abs(py - pyt) < kMaxDiff) { // bottom edge
1835  pxold = pxt; pyold = pyt; pBot = kTRUE;
1837  }
1838 
1839  if ((py > pyl+kMaxDiff && py < pyt-kMaxDiff) &&
1840  TMath::Abs(px - pxl) < kMaxDiff) { // left edge
1841  pxold = pxl; pyold = pyl; pL = kTRUE;
1843  }
1844 
1845  if ((py > pyl+kMaxDiff && py < pyt-kMaxDiff) &&
1846  TMath::Abs(px - pxt) < kMaxDiff) { // right edge
1847  pxold = pxt; pyold = pyt; pR = kTRUE;
1849  }
1850 
1851  if ((px > pxl+kMaxDiff && px < pxt-kMaxDiff) &&
1852  (py > pyl+kMaxDiff && py < pyt-kMaxDiff)) { // inside box
1853  pxold = px; pyold = py; pINSIDE = kTRUE;
1854  if (event == kButton1Down)
1855  SetCursor(kMove);
1856  else
1857  SetCursor(kCross);
1858  }
1859 
1860  fResizing = kFALSE;
1861  if (pA || pB || pC || pD || pTop || pL || pR || pBot)
1862  fResizing = kTRUE;
1863 
1864  if (!pA && !pB && !pC && !pD && !pTop && !pL && !pR && !pBot && !pINSIDE)
1865  SetCursor(kCross);
1866 
1867  break;
1868 
1869  case kArrowKeyRelease:
1870  case kButton1Motion:
1871 
1872  if (TestBit(kCannotMove)) break;
1873  wx = wy = 0;
1874 
1875  if (pA) {
1876  if (!ropaque) gVirtualX->DrawBox(pxold, pyt, pxt, pyold, TVirtualX::kHollow);
1877  if (px > pxt-kMinSize) { px = pxt-kMinSize; wx = px; }
1878  if (py > pyt-kMinSize) { py = pyt-kMinSize; wy = py; }
1879  if (px < pxlp) { px = pxlp; wx = px; }
1880  if (py < pylp) { py = pylp; wy = py; }
1881  if (fixedr) {
1882  Double_t dy = Double_t(TMath::Abs(pxt-px))/parent->UtoPixel(1.) /
1883  fAspectRatio;
1884  Int_t npy2 = pyt - TMath::Abs(parent->VtoAbsPixel(dy) -
1885  parent->VtoAbsPixel(0));
1886  if (npy2 < pylp) {
1887  px = pxold;
1888  py = pyold;
1889  } else
1890  py = npy2;
1891 
1892  wx = wy = 0;
1893  }
1894  if (!ropaque) gVirtualX->DrawBox(px, pyt, pxt, py, TVirtualX::kHollow);
1895  }
1896  if (pB) {
1897  if (!ropaque) gVirtualX->DrawBox(pxl , pyt, pxold, pyold, TVirtualX::kHollow);
1898  if (px < pxl+kMinSize) { px = pxl+kMinSize; wx = px; }
1899  if (py > pyt-kMinSize) { py = pyt-kMinSize; wy = py; }
1900  if (px > pxtp) { px = pxtp; wx = px; }
1901  if (py < pylp) { py = pylp; wy = py; }
1902  if (fixedr) {
1903  Double_t dy = Double_t(TMath::Abs(pxl-px))/parent->UtoPixel(1.) /
1904  fAspectRatio;
1905  Int_t npy2 = pyt - TMath::Abs(parent->VtoAbsPixel(dy) -
1906  parent->VtoAbsPixel(0));
1907  if (npy2 < pylp) {
1908  px = pxold;
1909  py = pyold;
1910  } else
1911  py = npy2;
1912 
1913  wx = wy = 0;
1914  }
1915  if (!ropaque) gVirtualX->DrawBox(pxl , pyt, px , py, TVirtualX::kHollow);
1916  }
1917  if (pC) {
1918  if (!ropaque) gVirtualX->DrawBox(pxl , pyl, pxold, pyold, TVirtualX::kHollow);
1919  if (px < pxl+kMinSize) { px = pxl+kMinSize; wx = px; }
1920  if (py < pyl+kMinSize) { py = pyl+kMinSize; wy = py; }
1921  if (px > pxtp) { px = pxtp; wx = px; }
1922  if (py > pytp) { py = pytp; wy = py; }
1923  if (fixedr) {
1924  Double_t dy = Double_t(TMath::Abs(pxl-px))/parent->UtoPixel(1.) /
1925  fAspectRatio;
1926  Int_t npy2 = pyl + TMath::Abs(parent->VtoAbsPixel(dy) -
1927  parent->VtoAbsPixel(0));
1928  if (npy2 > pytp) {
1929  px = pxold;
1930  py = pyold;
1931  } else
1932  py = npy2;
1933 
1934  wx = wy = 0;
1935  }
1936  if (!ropaque) gVirtualX->DrawBox(pxl, pyl, px, py, TVirtualX::kHollow);
1937  }
1938  if (pD) {
1939  if (!ropaque) gVirtualX->DrawBox(pxold, pyold, pxt, pyl, TVirtualX::kHollow);
1940  if (px > pxt-kMinSize) { px = pxt-kMinSize; wx = px; }
1941  if (py < pyl+kMinSize) { py = pyl+kMinSize; wy = py; }
1942  if (px < pxlp) { px = pxlp; wx = px; }
1943  if (py > pytp) { py = pytp; wy = py; }
1944  if (fixedr) {
1945  Double_t dy = Double_t(TMath::Abs(pxt-px))/parent->UtoPixel(1.) /
1946  fAspectRatio;
1947  Int_t npy2 = pyl + TMath::Abs(parent->VtoAbsPixel(dy) -
1948  parent->VtoAbsPixel(0));
1949  if (npy2 > pytp) {
1950  px = pxold;
1951  py = pyold;
1952  } else
1953  py = npy2;
1954 
1955  wx = wy = 0;
1956  }
1957  if (!ropaque) gVirtualX->DrawBox(px, py, pxt, pyl, TVirtualX::kHollow);
1958  }
1959  if (pTop) {
1960  if (!ropaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
1961  py2 += py - pyold;
1962  if (py2 > py1-kMinSize) { py2 = py1-kMinSize; wy = py2; }
1963  if (py2 < py2p) { py2 = py2p; wy = py2; }
1964  if (fixedr) {
1965  Double_t dx = Double_t(TMath::Abs(py2-py1))/parent->VtoPixel(0) *
1966  fAspectRatio;
1967  Int_t npx2 = px1 + parent->UtoPixel(dx);
1968  if (npx2 > px2p)
1969  py2 -= py - pyold;
1970  else
1971  px2 = npx2;
1972  }
1973  if (!ropaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
1974  }
1975  if (pBot) {
1976  if (!ropaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
1977  py1 += py - pyold;
1978  if (py1 < py2+kMinSize) { py1 = py2+kMinSize; wy = py1; }
1979  if (py1 > py1p) { py1 = py1p; wy = py1; }
1980  if (fixedr) {
1981  Double_t dx = Double_t(TMath::Abs(py2-py1))/parent->VtoPixel(0) *
1982  fAspectRatio;
1983  Int_t npx2 = px1 + parent->UtoPixel(dx);
1984  if (npx2 > px2p)
1985  py1 -= py - pyold;
1986  else
1987  px2 = npx2;
1988  }
1989  if (!ropaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
1990  }
1991  if (pL) {
1992  if (!ropaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
1993  px1 += px - pxold;
1994  if (px1 > px2-kMinSize) { px1 = px2-kMinSize; wx = px1; }
1995  if (px1 < px1p) { px1 = px1p; wx = px1; }
1996  if (fixedr) {
1997  Double_t dy = Double_t(TMath::Abs(px2-px1))/parent->UtoPixel(1.) /
1998  fAspectRatio;
1999  Int_t npy2 = py1 - TMath::Abs(parent->VtoAbsPixel(dy) -
2000  parent->VtoAbsPixel(0));
2001  if (npy2 < py2p)
2002  px1 -= px - pxold;
2003  else
2004  py2 = npy2;
2005  }
2006  if (!ropaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
2007  }
2008  if (pR) {
2009  if (!ropaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
2010  px2 += px - pxold;
2011  if (px2 < px1+kMinSize) { px2 = px1+kMinSize; wx = px2; }
2012  if (px2 > px2p) { px2 = px2p; wx = px2; }
2013  if (fixedr) {
2014  Double_t dy = Double_t(TMath::Abs(px2-px1))/parent->UtoPixel(1.) /
2015  fAspectRatio;
2016  Int_t npy2 = py1 - TMath::Abs(parent->VtoAbsPixel(dy) -
2017  parent->VtoAbsPixel(0));
2018  if (npy2 < py2p)
2019  px2 -= px - pxold;
2020  else
2021  py2 = npy2;
2022  }
2023  if (!ropaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
2024  }
2025  if (pINSIDE) {
2026  if (!opaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow); // draw the old box
2027  Int_t dx = px - pxold;
2028  Int_t dy = py - pyold;
2029  px1 += dx; py1 += dy; px2 += dx; py2 += dy;
2030  if (px1 < px1p) { dx = px1p - px1; px1 += dx; px2 += dx; wx = px+dx; }
2031  if (px2 > px2p) { dx = px2 - px2p; px1 -= dx; px2 -= dx; wx = px-dx; }
2032  if (py1 > py1p) { dy = py1 - py1p; py1 -= dy; py2 -= dy; wy = py-dy; }
2033  if (py2 < py2p) { dy = py2p - py2; py1 += dy; py2 += dy; wy = py+dy; }
2034  if (!opaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow); // draw the new box
2035  }
2036 
2037  if (wx || wy) {
2038  if (wx) px = wx;
2039  if (wy) py = wy;
2040  gVirtualX->Warp(px, py);
2041  }
2042 
2043  pxold = px;
2044  pyold = py;
2045 
2046  Double_t x1, y1, x2, y2;
2047  x1 = x2 = y1 = y2 = 0;
2048 
2049  if ((!fResizing && opaque) || (fResizing && ropaque)) {
2050  if (pA) {
2051  x1 = AbsPixeltoX(pxold);
2052  y1 = AbsPixeltoY(pyt);
2053  x2 = AbsPixeltoX(pxt);
2054  y2 = AbsPixeltoY(pyold);
2055  }
2056  if (pB) {
2057  x1 = AbsPixeltoX(pxl);
2058  y1 = AbsPixeltoY(pyt);
2059  x2 = AbsPixeltoX(pxold);
2060  y2 = AbsPixeltoY(pyold);
2061  }
2062  if (pC) {
2063  x1 = AbsPixeltoX(pxl);
2064  y1 = AbsPixeltoY(pyold);
2065  x2 = AbsPixeltoX(pxold);
2066  y2 = AbsPixeltoY(pyl);
2067  }
2068  if (pD) {
2069  x1 = AbsPixeltoX(pxold);
2070  y1 = AbsPixeltoY(pyold);
2071  x2 = AbsPixeltoX(pxt);
2072  y2 = AbsPixeltoY(pyl);
2073  }
2074  if (pTop || pBot || pL || pR || pINSIDE) {
2075  x1 = AbsPixeltoX(px1);
2076  y1 = AbsPixeltoY(py1);
2077  x2 = AbsPixeltoX(px2);
2078  y2 = AbsPixeltoY(py2);
2079  }
2080 
2081  if (px != pxorg || py != pyorg) {
2082 
2083  // Get parent corners pixels coordinates
2084  Int_t parentpx1 = fMother->XtoAbsPixel(parent->GetX1());
2085  Int_t parentpx2 = fMother->XtoAbsPixel(parent->GetX2());
2086  Int_t parentpy1 = fMother->YtoAbsPixel(parent->GetY1());
2087  Int_t parentpy2 = fMother->YtoAbsPixel(parent->GetY2());
2088 
2089  // Get pad new corners pixels coordinates
2090  Int_t apx1 = XtoAbsPixel(x1); if (apx1 < parentpx1) {apx1 = parentpx1; }
2091  Int_t apx2 = XtoAbsPixel(x2); if (apx2 > parentpx2) {apx2 = parentpx2; }
2092  Int_t apy1 = YtoAbsPixel(y1); if (apy1 > parentpy1) {apy1 = parentpy1; }
2093  Int_t apy2 = YtoAbsPixel(y2); if (apy2 < parentpy2) {apy2 = parentpy2; }
2094 
2095  // Compute new pad positions in the NDC space of parent
2096  fXlowNDC = Double_t(apx1 - parentpx1)/Double_t(parentpx2 - parentpx1);
2097  fYlowNDC = Double_t(apy1 - parentpy1)/Double_t(parentpy2 - parentpy1);
2098  fWNDC = Double_t(apx2 - apx1)/Double_t(parentpx2 - parentpx1);
2099  fHNDC = Double_t(apy2 - apy1)/Double_t(parentpy2 - parentpy1);
2100  }
2101 
2102  // Reset pad parameters and recompute conversion coefficients
2103  ResizePad();
2104 
2105  if (pINSIDE) gPad->ShowGuidelines(this, event);
2106  if (pTop) gPad->ShowGuidelines(this, event, 't', true);
2107  if (pBot) gPad->ShowGuidelines(this, event, 'b', true);
2108  if (pL) gPad->ShowGuidelines(this, event, 'l', true);
2109  if (pR) gPad->ShowGuidelines(this, event, 'r', true);
2110  if (pA) gPad->ShowGuidelines(this, event, '1', true);
2111  if (pB) gPad->ShowGuidelines(this, event, '2', true);
2112  if (pC) gPad->ShowGuidelines(this, event, '3', true);
2113  if (pD) gPad->ShowGuidelines(this, event, '4', true);
2114 
2115  Modified(kTRUE);
2116  }
2117 
2118  break;
2119 
2120  case kButton1Up:
2121 
2122  if (gROOT->IsEscaped()) {
2123  gROOT->SetEscape(kFALSE);
2124  break;
2125  }
2126 
2127  if (opaque||ropaque) {
2128  ShowGuidelines(this, event);
2129  } else {
2130  x1 = x2 = y1 = y2 = 0;
2131 
2132  if (pA) {
2133  x1 = AbsPixeltoX(pxold);
2134  y1 = AbsPixeltoY(pyt);
2135  x2 = AbsPixeltoX(pxt);
2136  y2 = AbsPixeltoY(pyold);
2137  }
2138  if (pB) {
2139  x1 = AbsPixeltoX(pxl);
2140  y1 = AbsPixeltoY(pyt);
2141  x2 = AbsPixeltoX(pxold);
2142  y2 = AbsPixeltoY(pyold);
2143  }
2144  if (pC) {
2145  x1 = AbsPixeltoX(pxl);
2146  y1 = AbsPixeltoY(pyold);
2147  x2 = AbsPixeltoX(pxold);
2148  y2 = AbsPixeltoY(pyl);
2149  }
2150  if (pD) {
2151  x1 = AbsPixeltoX(pxold);
2152  y1 = AbsPixeltoY(pyold);
2153  x2 = AbsPixeltoX(pxt);
2154  y2 = AbsPixeltoY(pyl);
2155  }
2156  if (pTop || pBot || pL || pR || pINSIDE) {
2157  x1 = AbsPixeltoX(px1);
2158  y1 = AbsPixeltoY(py1);
2159  x2 = AbsPixeltoX(px2);
2160  y2 = AbsPixeltoY(py2);
2161  }
2162 
2163  if (pA || pB || pC || pD || pTop || pL || pR || pBot)
2164  Modified(kTRUE);
2165 
2166  gVirtualX->SetLineColor(-1);
2167  gVirtualX->SetLineWidth(-1);
2168 
2169  if (px != pxorg || py != pyorg) {
2170 
2171  // Get parent corners pixels coordinates
2172  Int_t parentpx1 = fMother->XtoAbsPixel(parent->GetX1());
2173  Int_t parentpx2 = fMother->XtoAbsPixel(parent->GetX2());
2174  Int_t parentpy1 = fMother->YtoAbsPixel(parent->GetY1());
2175  Int_t parentpy2 = fMother->YtoAbsPixel(parent->GetY2());
2176 
2177  // Get pad new corners pixels coordinates
2178  Int_t apx1 = XtoAbsPixel(x1); if (apx1 < parentpx1) {apx1 = parentpx1; }
2179  Int_t apx2 = XtoAbsPixel(x2); if (apx2 > parentpx2) {apx2 = parentpx2; }
2180  Int_t apy1 = YtoAbsPixel(y1); if (apy1 > parentpy1) {apy1 = parentpy1; }
2181  Int_t apy2 = YtoAbsPixel(y2); if (apy2 < parentpy2) {apy2 = parentpy2; }
2182 
2183  // Compute new pad positions in the NDC space of parent
2184  fXlowNDC = Double_t(apx1 - parentpx1)/Double_t(parentpx2 - parentpx1);
2185  fYlowNDC = Double_t(apy1 - parentpy1)/Double_t(parentpy2 - parentpy1);
2186  fWNDC = Double_t(apx2 - apx1)/Double_t(parentpx2 - parentpx1);
2187  fHNDC = Double_t(apy2 - apy1)/Double_t(parentpy2 - parentpy1);
2188  }
2189 
2190  // Reset pad parameters and recompute conversion coefficients
2191  ResizePad();
2192 
2193 
2194  // emit signal
2195  RangeChanged();
2196  }
2197 
2198  break;
2199 
2200  case kButton1Locate:
2201 
2202  ExecuteEvent(kButton1Down, px, py);
2203 
2204  while (1) {
2205  px = py = 0;
2206  event = gVirtualX->RequestLocator(1, 1, px, py);
2207 
2208  ExecuteEvent(kButton1Motion, px, py);
2209 
2210  if (event != -1) { // button is released
2211  ExecuteEvent(kButton1Up, px, py);
2212  return;
2213  }
2214  }
2215 
2216  case kButton2Down:
2217 
2218  Pop();
2219  break;
2220 
2221  }
2222 }
2223 
2224 ////////////////////////////////////////////////////////////////////////////////
2225 /// Execute action corresponding to one event for a TAxis object
2226 /// (called by TAxis::ExecuteEvent.)
2227 /// This member function is called when an axis is clicked with the locator
2228 ///
2229 /// The axis range is set between the position where the mouse is pressed
2230 /// and the position where it is released.
2231 ///
2232 /// If the mouse position is outside the current axis range when it is released
2233 /// the axis is unzoomed with the corresponding proportions.
2234 ///
2235 /// Note that the mouse does not need to be in the pad or even canvas
2236 /// when it is released.
2237 
2238 void TPad::ExecuteEventAxis(Int_t event, Int_t px, Int_t py, TAxis *axis)
2239 {
2240  if (!IsEditable()) return;
2241 
2242  SetCursor(kHand);
2243 
2244  TView *view = GetView();
2245  static Int_t axisNumber;
2246  static Double_t ratio1, ratio2;
2247  static Int_t px1old, py1old, px2old, py2old;
2248  Int_t bin1, bin2, first, last;
2249  Double_t temp, xmin,xmax;
2250  Bool_t opaque = gPad->OpaqueMoving();
2251  static TBox *zoombox;
2252  Double_t zbx1=0,zbx2=0,zby1=0,zby2=0;
2253 
2254  // The CONT4 option, used to paint TH2, is a special case; it uses a 3D
2255  // drawing technique to paint a 2D plot.
2256  TString opt = axis->GetParent()->GetDrawOption();
2257  opt.ToLower();
2258  Bool_t kCont4 = kFALSE;
2259  if (strstr(opt,"cont4")) {
2260  view = 0;
2261  kCont4 = kTRUE;
2262  }
2263 
2264  switch (event) {
2265 
2266  case kButton1Down:
2267  axisNumber = 1;
2268  if (!strcmp(axis->GetName(),"xaxis")) {
2269  axisNumber = 1;
2270  if (!IsVertical()) axisNumber = 2;
2271  }
2272  if (!strcmp(axis->GetName(),"yaxis")) {
2273  axisNumber = 2;
2274  if (!IsVertical()) axisNumber = 1;
2275  }
2276  if (!strcmp(axis->GetName(),"zaxis")) {
2277  axisNumber = 3;
2278  }
2279  if (view) {
2280  view->GetDistancetoAxis(axisNumber, px, py, ratio1);
2281  } else {
2282  if (axisNumber == 1) {
2283  ratio1 = (AbsPixeltoX(px) - GetUxmin())/(GetUxmax() - GetUxmin());
2284  px1old = XtoAbsPixel(GetUxmin()+ratio1*(GetUxmax() - GetUxmin()));
2285  py1old = YtoAbsPixel(GetUymin());
2286  px2old = px1old;
2287  py2old = YtoAbsPixel(GetUymax());
2288  } else if (axisNumber == 2) {
2289  ratio1 = (AbsPixeltoY(py) - GetUymin())/(GetUymax() - GetUymin());
2290  py1old = YtoAbsPixel(GetUymin()+ratio1*(GetUymax() - GetUymin()));
2291  px1old = XtoAbsPixel(GetUxmin());
2292  px2old = XtoAbsPixel(GetUxmax());
2293  py2old = py1old;
2294  } else {
2295  ratio1 = (AbsPixeltoY(py) - GetUymin())/(GetUymax() - GetUymin());
2296  py1old = YtoAbsPixel(GetUymin()+ratio1*(GetUymax() - GetUymin()));
2297  px1old = XtoAbsPixel(GetUxmax());
2298  px2old = XtoAbsPixel(GetX2());
2299  py2old = py1old;
2300  }
2301  if (!opaque) {
2302  gVirtualX->DrawBox(px1old, py1old, px2old, py2old, TVirtualX::kHollow);
2303  } else {
2304  if (axisNumber == 1) {
2305  zbx1 = AbsPixeltoX(px1old);
2306  zbx2 = AbsPixeltoX(px2old);
2307  zby1 = GetUymin();
2308  zby2 = GetUymax();
2309  } else if (axisNumber == 2) {
2310  zbx1 = GetUxmin();
2311  zbx2 = GetUxmax();
2312  zby1 = AbsPixeltoY(py1old);
2313  zby2 = AbsPixeltoY(py2old);
2314  }
2315  if (GetLogx()) {
2316  zbx1 = TMath::Power(10,zbx1);
2317  zbx2 = TMath::Power(10,zbx2);
2318  }
2319  if (GetLogy()) {
2320  zby1 = TMath::Power(10,zby1);
2321  zby2 = TMath::Power(10,zby2);
2322  }
2323  zoombox = new TBox(zbx1, zby1, zbx2, zby2);
2324  Int_t ci = TColor::GetColor("#7d7dff");
2325  TColor *zoomcolor = gROOT->GetColor(ci);
2326  if (!TCanvas::SupportAlpha() || !zoomcolor) zoombox->SetFillStyle(3002);
2327  else zoomcolor->SetAlpha(0.5);
2328  zoombox->SetFillColor(ci);
2329  zoombox->Draw();
2330  gPad->Modified();
2331  gPad->Update();
2332  }
2333  }
2334  if (!opaque) gVirtualX->SetLineColor(-1);
2335  // No break !!!
2336 
2337  case kButton1Motion:
2338  if (view) {
2339  view->GetDistancetoAxis(axisNumber, px, py, ratio2);
2340  } else {
2341  if (!opaque) gVirtualX->DrawBox(px1old, py1old, px2old, py2old, TVirtualX::kHollow);
2342  if (axisNumber == 1) {
2343  ratio2 = (AbsPixeltoX(px) - GetUxmin())/(GetUxmax() - GetUxmin());
2344  px2old = XtoAbsPixel(GetUxmin()+ratio2*(GetUxmax() - GetUxmin()));
2345  } else {
2346  ratio2 = (AbsPixeltoY(py) - GetUymin())/(GetUymax() - GetUymin());
2347  py2old = YtoAbsPixel(GetUymin()+ratio2*(GetUymax() - GetUymin()));
2348  }
2349  if (!opaque) {
2350  gVirtualX->DrawBox(px1old, py1old, px2old, py2old, TVirtualX::kHollow);
2351  } else {
2352  if (axisNumber == 1) {
2353  zbx1 = AbsPixeltoX(px1old);
2354  zbx2 = AbsPixeltoX(px2old);
2355  zby1 = GetUymin();
2356  zby2 = GetUymax();
2357  } else if (axisNumber == 2) {
2358  zbx1 = GetUxmin();
2359  zbx2 = GetUxmax();
2360  zby1 = AbsPixeltoY(py1old);
2361  zby2 = AbsPixeltoY(py2old);
2362  }
2363  if (GetLogx()) {
2364  zbx1 = TMath::Power(10,zbx1);
2365  zbx2 = TMath::Power(10,zbx2);
2366  }
2367  if (GetLogy()) {
2368  zby1 = TMath::Power(10,zby1);
2369  zby2 = TMath::Power(10,zby2);
2370  }
2371  if (zoombox) {
2372  zoombox->SetX1(zbx1);
2373  zoombox->SetY1(zby1);
2374  zoombox->SetX2(zbx2);
2375  zoombox->SetY2(zby2);
2376  }
2377  gPad->Modified();
2378  gPad->Update();
2379  }
2380  }
2381  break;
2382 
2383  case kWheelUp:
2384  bin1 = axis->GetFirst()+1;
2385  bin2 = axis->GetLast()-1;
2386  bin1 = TMath::Max(bin1, 1);
2387  bin2 = TMath::Min(bin2, axis->GetNbins());
2388  if (bin2>bin1) {
2389  axis->SetRange(bin1,bin2);
2390  gPad->Modified();
2391  gPad->Update();
2392  }
2393  break;
2394 
2395  case kWheelDown:
2396  bin1 = axis->GetFirst()-1;
2397  bin2 = axis->GetLast()+1;
2398  bin1 = TMath::Max(bin1, 1);
2399  bin2 = TMath::Min(bin2, axis->GetNbins());
2400  if (bin2>bin1) {
2401  axis->SetRange(bin1,bin2);
2402  gPad->Modified();
2403  gPad->Update();
2404  }
2405  break;
2406 
2407  case kButton1Up:
2408  if (gROOT->IsEscaped()) {
2409  gROOT->SetEscape(kFALSE);
2410  if (opaque && zoombox) {
2411  zoombox->Delete();
2412  zoombox = 0;
2413  }
2414  break;
2415  }
2416 
2417  if (view) {
2418  view->GetDistancetoAxis(axisNumber, px, py, ratio2);
2419  if (ratio1 > ratio2) {
2420  temp = ratio1;
2421  ratio1 = ratio2;
2422  ratio2 = temp;
2423  }
2424  if (ratio2 - ratio1 > 0.05) {
2425  TH1 *hobj = (TH1*)axis->GetParent();
2426  if (axisNumber == 3 && hobj && hobj->GetDimension() != 3) {
2427  Float_t zmin = hobj->GetMinimum();
2428  Float_t zmax = hobj->GetMaximum();
2429  if(GetLogz()){
2430  if (zmin <= 0 && zmax > 0) zmin = TMath::Min((Double_t)1,
2431  (Double_t)0.001*zmax);
2432  zmin = TMath::Log10(zmin);
2433  zmax = TMath::Log10(zmax);
2434  }
2435  Float_t newmin = zmin + (zmax-zmin)*ratio1;
2436  Float_t newmax = zmin + (zmax-zmin)*ratio2;
2437  if(newmin < zmin)newmin = hobj->GetBinContent(hobj->GetMinimumBin());
2438  if(newmax > zmax)newmax = hobj->GetBinContent(hobj->GetMaximumBin());
2439  if(GetLogz()){
2440  newmin = TMath::Exp(2.302585092994*newmin);
2441  newmax = TMath::Exp(2.302585092994*newmax);
2442  }
2443  hobj->SetMinimum(newmin);
2444  hobj->SetMaximum(newmax);
2445  hobj->SetBit(TH1::kIsZoomed);
2446  } else {
2447  first = axis->GetFirst();
2448  last = axis->GetLast();
2449  bin1 = first + Int_t((last-first+1)*ratio1);
2450  bin2 = first + Int_t((last-first+1)*ratio2);
2451  bin1 = TMath::Max(bin1, 1);
2452  bin2 = TMath::Min(bin2, axis->GetNbins());
2453  axis->SetRange(bin1, bin2);
2454  }
2455  delete view;
2456  SetView(0);
2457  Modified(kTRUE);
2458  }
2459  } else {
2460  if (axisNumber == 1) {
2461  ratio2 = (AbsPixeltoX(px) - GetUxmin())/(GetUxmax() - GetUxmin());
2462  xmin = GetUxmin() +ratio1*(GetUxmax() - GetUxmin());
2463  xmax = GetUxmin() +ratio2*(GetUxmax() - GetUxmin());
2464  if (GetLogx() && !kCont4) {
2465  xmin = PadtoX(xmin);
2466  xmax = PadtoX(xmax);
2467  }
2468  } else if (axisNumber == 2) {
2469  ratio2 = (AbsPixeltoY(py) - GetUymin())/(GetUymax() - GetUymin());
2470  xmin = GetUymin() +ratio1*(GetUymax() - GetUymin());
2471  xmax = GetUymin() +ratio2*(GetUymax() - GetUymin());
2472  if (GetLogy() && !kCont4) {
2473  xmin = PadtoY(xmin);
2474  xmax = PadtoY(xmax);
2475  }
2476  } else {
2477  ratio2 = (AbsPixeltoY(py) - GetUymin())/(GetUymax() - GetUymin());
2478  xmin = ratio1;
2479  xmax = ratio2;
2480  }
2481  if (xmin > xmax) {
2482  temp = xmin;
2483  xmin = xmax;
2484  xmax = temp;
2485  temp = ratio1;
2486  ratio1 = ratio2;
2487  ratio2 = temp;
2488  }
2489 
2490  // xmin and xmax need to be adjusted in case of CONT4.
2491  if (kCont4) {
2492  Double_t low = axis->GetBinLowEdge(axis->GetFirst());
2493  Double_t up = axis->GetBinUpEdge(axis->GetLast());
2494  Double_t xmi = GetUxmin();
2495  Double_t xma = GetUxmax();
2496  xmin = ((xmin-xmi)/(xma-xmi))*(up-low)+low;
2497  xmax = ((xmax-xmi)/(xma-xmi))*(up-low)+low;
2498  }
2499 
2500  if (!strcmp(axis->GetName(),"xaxis")) axisNumber = 1;
2501  if (!strcmp(axis->GetName(),"yaxis")) axisNumber = 2;
2502  if (ratio2 - ratio1 > 0.05) {
2503  //update object owning this axis
2504  TH1 *hobj1 = (TH1*)axis->GetParent();
2505  bin1 = axis->FindFixBin(xmin);
2506  bin2 = axis->FindFixBin(xmax);
2507  bin1 = TMath::Max(bin1, 1);
2508  bin2 = TMath::Min(bin2, axis->GetNbins());
2509  if (axisNumber == 1) axis->SetRange(bin1,bin2);
2510  if (axisNumber == 2 && hobj1) {
2511  if (hobj1->GetDimension() == 1) {
2512  if (hobj1->GetNormFactor() != 0) {
2513  Double_t norm = hobj1->GetSumOfWeights()/hobj1->GetNormFactor();
2514  xmin *= norm;
2515  xmax *= norm;
2516  }
2517  hobj1->SetMinimum(xmin);
2518  hobj1->SetMaximum(xmax);
2519  hobj1->SetBit(TH1::kIsZoomed);
2520  } else {
2521  axis->SetRange(bin1,bin2);
2522  }
2523  }
2524  //update all histograms in the pad
2525  TIter next(GetListOfPrimitives());
2526  TObject *obj;
2527  while ((obj= next())) {
2528  if (!obj->InheritsFrom(TH1::Class())) continue;
2529  TH1 *hobj = (TH1*)obj;
2530  if (hobj == hobj1) continue;
2531  bin1 = hobj->GetXaxis()->FindFixBin(xmin);
2532  bin2 = hobj->GetXaxis()->FindFixBin(xmax);
2533  if (axisNumber == 1) {
2534  hobj->GetXaxis()->SetRange(bin1,bin2);
2535  } else if (axisNumber == 2) {
2536  if (hobj->GetDimension() == 1) {
2537  Double_t xxmin = xmin;
2538  Double_t xxmax = xmax;
2539  if (hobj->GetNormFactor() != 0) {
2540  Double_t norm = hobj->GetSumOfWeights()/hobj->GetNormFactor();
2541  xxmin *= norm;
2542  xxmax *= norm;
2543  }
2544  hobj->SetMinimum(xxmin);
2545  hobj->SetMaximum(xxmax);
2546  hobj->SetBit(TH1::kIsZoomed);
2547  } else {
2548  bin1 = hobj->GetYaxis()->FindFixBin(xmin);
2549  bin2 = hobj->GetYaxis()->FindFixBin(xmax);
2550  hobj->GetYaxis()->SetRange(bin1,bin2);
2551  }
2552  }
2553  }
2554  Modified(kTRUE);
2555  }
2556  }
2557  if (!opaque) {
2558  gVirtualX->SetLineColor(-1);
2559  } else {
2560  if (zoombox) {
2561  zoombox->Delete();
2562  zoombox = 0;
2563  }
2564  }
2565  break;
2566  }
2567 }
2568 
2569 ////////////////////////////////////////////////////////////////////////////////
2570 /// Search if object named name is inside this pad or in pads inside this pad.
2571 ///
2572 /// In case name is in several sub-pads the first one is returned.
2573 
2574 TObject *TPad::FindObject(const char *name) const
2575 {
2576  if (!fPrimitives) return 0;
2577  TObject *found = fPrimitives->FindObject(name);
2578  if (found) return found;
2579  TObject *cur;
2580  TIter next(GetListOfPrimitives());
2581  while ((cur = next())) {
2582  if (cur->InheritsFrom(TPad::Class())) {
2583  found = ((TPad*)cur)->FindObject(name);
2584  if (found) return found;
2585  }
2586  }
2587  return 0;
2588 }
2589 
2590 ////////////////////////////////////////////////////////////////////////////////
2591 /// Search if obj is in pad or in pads inside this pad.
2592 ///
2593 /// In case obj is in several sub-pads the first one is returned.
2594 
2596 {
2597  if (!fPrimitives) return 0;
2598  TObject *found = fPrimitives->FindObject(obj);
2599  if (found) return found;
2600  TObject *cur;
2601  TIter next(GetListOfPrimitives());
2602  while ((cur = next())) {
2603  if (cur->InheritsFrom(TPad::Class())) {
2604  found = ((TPad*)cur)->FindObject(obj);
2605  if (found) return found;
2606  }
2607  }
2608  return 0;
2609 }
2610 
2611 ////////////////////////////////////////////////////////////////////////////////
2612 /// Get canvas identifier.
2613 
2615 {
2616  return fCanvas ? fCanvas->GetCanvasID() : -1;
2617 }
2618 
2619 ////////////////////////////////////////////////////////////////////////////////
2620 /// Get canvas implementation pointer if any
2621 
2623 {
2624  return fCanvas ? fCanvas->GetCanvasImp() : 0;
2625 }
2626 
2627 ////////////////////////////////////////////////////////////////////////////////
2628 /// Get Event.
2629 
2631 {
2632  return fCanvas ? fCanvas->GetEvent() : 0;
2633 }
2634 
2635 ////////////////////////////////////////////////////////////////////////////////
2636 /// Get X event.
2637 
2639 {
2640  return fCanvas ? fCanvas->GetEventX() : 0;
2641 }
2642 
2643 ////////////////////////////////////////////////////////////////////////////////
2644 /// Get Y event.
2645 
2647 {
2648  return fCanvas ? fCanvas->GetEventY() : 0;
2649 }
2650 
2651 ////////////////////////////////////////////////////////////////////////////////
2652 /// Get virtual canvas.
2653 
2655 {
2656  return fCanvas ? (TVirtualPad*) fCanvas : 0;
2657 }
2658 
2659 ////////////////////////////////////////////////////////////////////////////////
2660 /// Get highlight color.
2661 
2663 {
2664  return fCanvas ? fCanvas->GetHighLightColor() : 0;
2665 }
2666 
2667 ////////////////////////////////////////////////////////////////////////////////
2668 /// Static function (see also TPad::SetMaxPickDistance)
2669 
2671 {
2672  return fgMaxPickDistance;
2673 }
2674 
2675 ////////////////////////////////////////////////////////////////////////////////
2676 /// Get selected.
2677 
2679 {
2680  if (fCanvas == this) return 0;
2681  return fCanvas ? fCanvas->GetSelected() : 0;
2682 }
2683 
2684 ////////////////////////////////////////////////////////////////////////////////
2685 /// Get selected pad.
2686 
2688 {
2689  if (fCanvas == this) return 0;
2690  return fCanvas ? fCanvas->GetSelectedPad() : 0;
2691 }
2692 
2693 ////////////////////////////////////////////////////////////////////////////////
2694 /// Get save pad.
2695 
2697 {
2698  if (fCanvas == this) return 0;
2699  return fCanvas ? fCanvas->GetPadSave() : 0;
2700 }
2701 
2702 ////////////////////////////////////////////////////////////////////////////////
2703 /// Get Wh.
2704 
2706 {
2707  return fCanvas ? fCanvas->GetWh() : 0;
2708 }
2709 
2710 ////////////////////////////////////////////////////////////////////////////////
2711 /// Get Ww.
2712 
2714 {
2715  return fCanvas ? fCanvas->GetWw() : 0;
2716 }
2717 
2718 ////////////////////////////////////////////////////////////////////////////////
2719 /// Hide tool tip depending on the event type. Typically tool tips
2720 /// are hidden when event is not a kMouseEnter and not a kMouseMotion
2721 /// event.
2722 
2724 {
2725  if (event != kMouseEnter && event != kMouseMotion && fTip)
2726  gPad->CloseToolTip(fTip);
2727 }
2728 
2729 ////////////////////////////////////////////////////////////////////////////////
2730 /// Is pad in batch mode ?
2731 
2733 {
2734  return fCanvas ? fCanvas->IsBatch() : 0;
2735 }
2736 
2737 ////////////////////////////////////////////////////////////////////////////////
2738 /// Is pad retained ?
2739 
2741 {
2742  return fCanvas ? fCanvas->IsRetained() : 0;
2743 }
2744 
2745 ////////////////////////////////////////////////////////////////////////////////
2746 /// Is pad moving in opaque mode ?
2747 
2749 {
2750  return fCanvas ? fCanvas->OpaqueMoving() : 0;
2751 }
2752 
2753 ////////////////////////////////////////////////////////////////////////////////
2754 /// Is pad resizing in opaque mode ?
2755 
2757 {
2758  return fCanvas ? fCanvas->OpaqueResizing() : 0;
2759 }
2760 
2761 ////////////////////////////////////////////////////////////////////////////////
2762 /// Set pad in batch mode.
2763 
2765 {
2766  if (fCanvas) fCanvas->SetBatch(batch);
2767 }
2768 
2769 ////////////////////////////////////////////////////////////////////////////////
2770 /// Set canvas size.
2771 
2773 {
2774  if (fCanvas) fCanvas->SetCanvasSize(ww,wh);
2775 }
2776 
2777 ////////////////////////////////////////////////////////////////////////////////
2778 /// Set cursor type.
2779 
2781 {
2782  if (fCanvas) fCanvas->SetCursor(cursor);
2783 }
2784 
2785 ////////////////////////////////////////////////////////////////////////////////
2786 /// Set double buffer mode ON or OFF.
2787 
2789 {
2790  if (fCanvas) fCanvas->SetDoubleBuffer(mode);
2791 }
2792 
2793 ////////////////////////////////////////////////////////////////////////////////
2794 /// Set selected.
2795 
2797 {
2798  if (fCanvas) fCanvas->SetSelected(obj);
2799 }
2800 
2801 ////////////////////////////////////////////////////////////////////////////////
2802 /// Update pad.
2803 
2805 {
2806  if (fCanvas) fCanvas->Update();
2807 }
2808 
2809 ////////////////////////////////////////////////////////////////////////////////
2810 /// Get frame.
2811 
2813 {
2814  if (!fPrimitives) fPrimitives = new TList;
2816  if (!frame) frame = (TFrame*)GetListOfPrimitives()->FindObject("TFrame");
2817  fFrame = frame;
2818  if (!fFrame) {
2819  if (!frame) fFrame = new TFrame(0,0,1,1);
2820  Int_t framecolor = GetFrameFillColor();
2821  if (!framecolor) framecolor = GetFillColor();
2822  fFrame->SetFillColor(framecolor);
2829  }
2830  return fFrame;
2831 }
2832 
2833 ////////////////////////////////////////////////////////////////////////////////
2834 /// Get primitive.
2835 
2836 TObject *TPad::GetPrimitive(const char *name) const
2837 {
2838  if (!fPrimitives) return 0;
2839  TIter next(fPrimitives);
2840  TObject *found, *obj;
2841  while ((obj=next())) {
2842  if (!strcmp(name, obj->GetName())) return obj;
2843  if (obj->InheritsFrom(TPad::Class())) continue;
2844  found = obj->FindObject(name);
2845  if (found) return found;
2846  }
2847  return 0;
2848 }
2849 
2850 ////////////////////////////////////////////////////////////////////////////////
2851 /// Get a pointer to subpadnumber of this pad.
2852 
2853 TVirtualPad *TPad::GetPad(Int_t subpadnumber) const
2854 {
2855  if (!subpadnumber) {
2856  return (TVirtualPad*)this;
2857  }
2858 
2859  TObject *obj;
2860  if (!fPrimitives) return 0;
2861  TIter next(GetListOfPrimitives());
2862  while ((obj = next())) {
2863  if (obj->InheritsFrom(TVirtualPad::Class())) {
2864  TVirtualPad *pad = (TVirtualPad*)obj;
2865  if (pad->GetNumber() == subpadnumber) return pad;
2866  }
2867  }
2868  return 0;
2869 }
2870 
2871 ////////////////////////////////////////////////////////////////////////////////
2872 /// Return lower and upper bounds of the pad in NDC coordinates.
2873 
2874 void TPad::GetPadPar(Double_t &xlow, Double_t &ylow, Double_t &xup, Double_t &yup)
2875 {
2876  xlow = fXlowNDC;
2877  ylow = fYlowNDC;
2878  xup = fXlowNDC+fWNDC;
2879  yup = fYlowNDC+fHNDC;
2880 }
2881 
2882 ////////////////////////////////////////////////////////////////////////////////
2883 /// Return pad world coordinates range.
2884 
2886 {
2887  x1 = fX1;
2888  y1 = fY1;
2889  x2 = fX2;
2890  y2 = fY2;
2891 }
2892 
2893 ////////////////////////////////////////////////////////////////////////////////
2894 /// Return pad axis coordinates range.
2895 
2897 {
2898  xmin = fUxmin;
2899  ymin = fUymin;
2900  xmax = fUxmax;
2901  ymax = fUymax;
2902 }
2903 
2904 ////////////////////////////////////////////////////////////////////////////////
2905 /// Highlight pad.
2906 /// do not highlight when printing on Postscript
2907 
2909 {
2910  if (gVirtualPS && gVirtualPS->TestBit(kPrintingPS)) return;
2911 
2912  if (color <= 0) return;
2913 
2915 
2916  // We do not want to have active(executable) buttons, etc highlighted
2917  // in this manner, unless we want to edit'em
2918  if (GetMother() && GetMother()->IsEditable() && !InheritsFrom(TButton::Class())) {
2919  //When doing a DrawClone from the GUI you would do
2920  // - select an empty pad -
2921  // - right click on object -
2922  // - select DrawClone on menu -
2923  //
2924  // Without the SetSelectedPad(); in the HighLight function, the
2925  // above instruction lead to the clone to be drawn in the
2926  // same canvas as the original object. This is because the
2927  // 'right clicking' (via TCanvas::HandleInput) changes gPad
2928  // momentarily such that when DrawClone is called, it is
2929  // not the right value (for DrawClone). Should be FIXED.
2930  gROOT->SetSelectedPad(this);
2931  if (GetBorderMode()>0) {
2932  if (set) PaintBorder(-color, kFALSE);
2933  else PaintBorder(-GetFillColor(), kFALSE);
2934  }
2935  }
2936 
2938 }
2939 
2940 ////////////////////////////////////////////////////////////////////////////////
2941 /// List all primitives in pad.
2942 
2943 void TPad::ls(Option_t *option) const
2944 {
2946  std::cout <<IsA()->GetName()<<" fXlowNDC=" <<fXlowNDC<<" fYlowNDC="<<fYlowNDC<<" fWNDC="<<GetWNDC()<<" fHNDC="<<GetHNDC()
2947  <<" Name= "<<GetName()<<" Title= "<<GetTitle()<<" Option="<<option<<std::endl;
2949  if (!fPrimitives) return;
2950  fPrimitives->ls(option);
2952 }
2953 
2954 ////////////////////////////////////////////////////////////////////////////////
2955 /// Increment (i==1) or set (i>1) the number of autocolor in the pad.
2956 
2958 {
2959  if (opt.Index("pfc")>=0 || opt.Index("plc")>=0 || opt.Index("pmc")>=0) {
2960  if (i==1) fNumPaletteColor++;
2961  else fNumPaletteColor = i;
2962  return fNumPaletteColor;
2963  } else {
2964  return 0;
2965  }
2966 }
2967 
2968 ////////////////////////////////////////////////////////////////////////////////
2969 /// Get the next autocolor in the pad.
2970 
2972 {
2973  Int_t i = 0;
2974  Int_t ncolors = gStyle->GetNumberOfColors();
2975  if (fNumPaletteColor>1) {
2976  i = fNextPaletteColor*(ncolors/(fNumPaletteColor-1));
2977  if (i>=ncolors) i = ncolors-1;
2978  }
2981  return gStyle->GetColorPalette(i);
2982 }
2983 
2984 ////////////////////////////////////////////////////////////////////////////////
2985 /// Initialise the grid used to find empty space when adding a box (Legend) in a pad
2986 
2988 {
2989  Int_t const cellSize = 10; // Sive of an individual grid cell in pixels.
2990 
2991  if (fCGnx == 0 && fCGny == 0) {
2992  fCGnx = gPad->GetWw()/cellSize;
2993  fCGny = gPad->GetWh()/cellSize;
2994  } else {
2995  Int_t CGnx = gPad->GetWw()/cellSize;
2996  Int_t CGny = gPad->GetWh()/cellSize;
2997  if (fCGnx != CGnx || fCGny != CGny) {
2998  fCGnx = CGnx;
2999  fCGny = CGny;
3000  delete [] fCollideGrid;
3001  fCollideGrid = 0;
3002  }
3003  }
3004 
3005  // Initialise the collide grid
3006  if (!fCollideGrid) {
3007  fCollideGrid = new Bool_t [fCGnx*fCGny];
3008  for (int i = 0; i<fCGnx; i++) {
3009  for (int j = 0; j<fCGny; j++) {
3010  fCollideGrid[i + j*fCGnx] = kTRUE;
3011  }
3012  }
3013  }
3014 
3015  // Fill the collide grid
3017  Int_t np = l->GetSize();
3018  TObject *o;
3019 
3020  for (int i=0; i<np; i++) {
3021  o = (TObject *) l->At(i);
3022  if (o!=oi) {
3023  if (o->InheritsFrom(TFrame::Class())) { FillCollideGridTFrame(o); continue;}
3024  if (o->InheritsFrom(TBox::Class())) { FillCollideGridTBox(o); continue;}
3025  if (o->InheritsFrom(TH1::Class())) { FillCollideGridTH1(o); continue;}
3026  if (o->InheritsFrom(TGraph::Class())) { FillCollideGridTGraph(o); continue;}
3027  }
3028  }
3029 }
3030 
3031 ////////////////////////////////////////////////////////////////////////////////
3032 /// Check if a box of size w and h collide some primitives in the pad at
3033 /// position i,j
3034 
3036 {
3037  for (int r=i; r<w+i; r++) {
3038  for (int c=j; c<h+j; c++) {
3039  if (!fCollideGrid[r + c*fCGnx]) return kTRUE;
3040  }
3041  }
3042  return kFALSE;
3043 }
3044 
3045 ////////////////////////////////////////////////////////////////////////////////
3046 /// Place a box in NDC space
3047 
3049 {
3050  FillCollideGrid(o);
3051 
3052  Int_t iw = (int)(fCGnx*w);
3053  Int_t ih = (int)(fCGny*h);
3054 
3055  Int_t nxmax = fCGnx-iw-1;
3056  Int_t nymax = fCGny-ih-1;
3057 
3058  for (Int_t i = 0; i<nxmax; i++) {
3059  for (Int_t j = 0; j<=nymax; j++) {
3060  if (Collide(i,j,iw,ih)) {
3061  continue;
3062  } else {
3063  xl = (Double_t)(i)/(Double_t)(fCGnx);
3064  yb = (Double_t)(j)/(Double_t)(fCGny);
3065  return kTRUE;
3066  }
3067  }
3068  }
3069  return kFALSE;
3070 }
3071 
3072 #define NotFree(i, j) fCollideGrid[TMath::Max(TMath::Min(i+j*fCGnx,fCGnx*fCGny),0)] = kFALSE;
3073 
3074 ////////////////////////////////////////////////////////////////////////////////
3075 /// Mark as "not free" the cells along a line.
3076 
3078 {
3079  NotFree(x1, y1);
3080  NotFree(x2, y2);
3081  Int_t i, j, xt, yt;
3082 
3083  // horizontal lines
3084  if (y1==y2) {
3085  for (i=x1+1; i<x2; i++) NotFree(i,y1);
3086  return;
3087  }
3088 
3089  // vertical lines
3090  if (x1==x2) {
3091  for (i=y1+1; i<y2; i++) NotFree(x1,i);
3092  return;
3093  }
3094 
3095  // other lines
3096  if (TMath::Abs(x2-x1)>TMath::Abs(y2-y1)) {
3097  if (x1>x2) {
3098  xt = x1; x1 = x2; x2 = xt;
3099  yt = y1; y1 = y2; y2 = yt;
3100  }
3101  for (i=x1+1; i<x2; i++) {
3102  j = (Int_t)((Double_t)(y2-y1)*(Double_t)((i-x1)/(Double_t)(x2-x1))+y1);
3103  NotFree(i,j);
3104  NotFree(i,(j+1));
3105  }
3106  } else {
3107  if (y1>y2) {
3108  yt = y1; y1 = y2; y2 = yt;
3109  xt = x1; x1 = x2; x2 = xt;
3110  }
3111  for (j=y1+1; j<y2; j++) {
3112  i = (Int_t)((Double_t)(x2-x1)*(Double_t)((j-y1)/(Double_t)(y2-y1))+x1);
3113  NotFree(i,j);
3114  NotFree((i+1),j);
3115  }
3116  }
3117 }
3118 
3119 ////////////////////////////////////////////////////////////////////////////////
3121 {
3122  TBox *b = (TBox *)o;
3123 
3124  Double_t xs = (fX2-fX1)/fCGnx;
3125  Double_t ys = (fY2-fY1)/fCGny;
3126 
3127  Int_t x1 = (Int_t)((b->GetX1()-fX1)/xs);
3128  Int_t x2 = (Int_t)((b->GetX2()-fX1)/xs);
3129  Int_t y1 = (Int_t)((b->GetY1()-fY1)/ys);
3130  Int_t y2 = (Int_t)((b->GetY2()-fY1)/ys);
3131  for (int i = x1; i<=x2; i++) {
3132  for (int j = y1; j<=y2; j++) NotFree(i, j);
3133  }
3134 }
3135 
3136 ////////////////////////////////////////////////////////////////////////////////
3138 {
3139  TFrame *f = (TFrame *)o;
3140 
3141  Double_t xs = (fX2-fX1)/fCGnx;
3142  Double_t ys = (fY2-fY1)/fCGny;
3143 
3144  Int_t x1 = (Int_t)((f->GetX1()-fX1)/xs);
3145  Int_t x2 = (Int_t)((f->GetX2()-fX1)/xs);
3146  Int_t y1 = (Int_t)((f->GetY1()-fY1)/ys);
3147  Int_t y2 = (Int_t)((f->GetY2()-fY1)/ys);
3148  Int_t i;
3149 
3150  for (i = x1; i<=x2; i++) {
3151  NotFree(i, y1);
3152  NotFree(i, (y1-1));
3153  NotFree(i, (y1-2));
3154  }
3155  for (i = y1; i<=y2; i++) {
3156  NotFree(x1, i);
3157  NotFree((x1-1), i);
3158  NotFree((x1-2), i);
3159  }
3160 }
3161 
3162 ////////////////////////////////////////////////////////////////////////////////
3164 {
3165  TGraph *g = (TGraph *)o;
3166 
3167  Double_t xs = (fX2-fX1)/fCGnx;
3168  Double_t ys = (fY2-fY1)/fCGny;
3169 
3170  Int_t n = g->GetN();
3171  Double_t x1, x2, y1, y2;
3172 
3173  for (Int_t i=1; i<n; i++) {
3174  g->GetPoint(i-1,x1,y1);
3175  g->GetPoint(i ,x2,y2);
3176  if (fLogx) {
3177  if (x1 > 0) x1 = TMath::Log10(x1);
3178  else x1 = fUxmin;
3179  if (x2 > 0) x2 = TMath::Log10(x2);
3180  else x2 = fUxmin;
3181  }
3182  if (fLogy) {
3183  if (y1 > 0) y1 = TMath::Log10(y1);
3184  else y1 = fUymin;
3185  if (y2 > 0) y2 = TMath::Log10(y2);
3186  else y2 = fUymin;
3187  }
3188  LineNotFree((int)((x1-fX1)/xs), (int)((x2-fX1)/xs),
3189  (int)((y1-fY1)/ys), (int)((y2-fY1)/ys));
3190  }
3191 }
3192 
3193 ////////////////////////////////////////////////////////////////////////////////
3195 {
3196  TH1 *h = (TH1 *)o;
3197 
3198  if (o->InheritsFrom(TH2::Class())) return;
3199  if (o->InheritsFrom(TH3::Class())) return;
3200 
3201  TString name = h->GetName();
3202  if (name.Index("hframe") >= 0) return;
3203 
3204  Double_t xs = (fX2-fX1)/fCGnx;
3205  Double_t ys = (fY2-fY1)/fCGny;
3206 
3207  bool haserrors = false;
3208  TString drawOption = h->GetDrawOption();
3209  drawOption.ToLower();
3210  drawOption.ReplaceAll("same","");
3211 
3212  if (drawOption.Index("hist") < 0) {
3213  if (drawOption.Index("e") >= 0) haserrors = true;
3214  }
3215 
3216  Int_t nx = h->GetNbinsX();
3217  Int_t x1, y1, y2;
3218  Int_t i, j;
3219  Double_t x1l, y1l, y2l;
3220 
3221  for (i = 1; i<nx; i++) {
3222  if (haserrors) {
3223  x1l = h->GetBinCenter(i);
3224  if (fLogx) {
3225  if (x1l > 0) x1l = TMath::Log10(x1l);
3226  else x1l = fUxmin;
3227  }
3228  x1 = (Int_t)((x1l-fX1)/xs);
3229  y1l = h->GetBinContent(i)-h->GetBinErrorLow(i);
3230  if (fLogy) {
3231  if (y1l > 0) y1l = TMath::Log10(y1l);
3232  else y1l = fUymin;
3233  }
3234  y1 = (Int_t)((y1l-fY1)/ys);
3235  y2l = h->GetBinContent(i)+h->GetBinErrorUp(i);
3236  if (fLogy) {
3237  if (y2l > 0) y2l = TMath::Log10(y2l);
3238  else y2l = fUymin;
3239  }
3240  y2 = (Int_t)((y2l-fY1)/ys);
3241  for (j=y1; j<=y2; j++) {
3242  NotFree(x1, j);
3243  }
3244  }
3245  x1l = h->GetBinLowEdge(i);
3246  if (fLogx) {
3247  if (x1l > 0) x1l = TMath::Log10(x1l);
3248  else x1l = fUxmin;
3249  }
3250  x1 = (Int_t)((x1l-fX1)/xs);
3251  y1l = h->GetBinContent(i);
3252  if (fLogy) {
3253  if (y1l > 0) y1l = TMath::Log10(y1l);
3254  else y1l = fUymin;
3255  }
3256  y1 = (Int_t)((y1l-fY1)/ys);
3257  NotFree(x1, y1);
3258  x1l = h->GetBinLowEdge(i)+h->GetBinWidth(i);
3259  if (fLogx) {
3260  if (x1l > 0) x1l = TMath::Log10(x1l);
3261  else x1l = fUxmin;
3262  }
3263  x1 = (int)((x1l-fX1)/xs);
3264  NotFree(x1, y1);
3265  }
3266 
3267  // Extra objects in the list of function
3269  if (ps) FillCollideGridTBox(ps);
3270 }
3271 
3272 ////////////////////////////////////////////////////////////////////////////////
3273 /// This method draws the collide grid on top of the canvas. This is used for
3274 /// debugging only. At some point it will be removed.
3275 
3277 {
3278  auto box = new TBox();
3279  box->SetFillColorAlpha(kRed,0.5);
3280 
3281  Double_t xs = (fX2-fX1)/fCGnx;
3282  Double_t ys = (fY2-fY1)/fCGny;
3283 
3284  Double_t X1L, X2L, Y1L, Y2L;
3285  Double_t t = 0.15;
3286  Double_t Y1, Y2;
3287  Double_t X1 = fX1;
3288  Double_t X2 = X1+xs;
3289 
3290  for (int i = 0; i<fCGnx; i++) {
3291  Y1 = fY1;
3292  Y2 = Y1+ys;
3293  for (int j = 0; j<fCGny; j++) {
3294  if (gPad->GetLogx()) {
3295  X1L = TMath::Power(10,X1);
3296  X2L = TMath::Power(10,X2);
3297  } else {
3298  X1L = X1;
3299  X2L = X2;
3300  }
3301  if (gPad->GetLogy()) {
3302  Y1L = TMath::Power(10,Y1);
3303  Y2L = TMath::Power(10,Y2);
3304  } else {
3305  Y1L = Y1;
3306  Y2L = Y2;
3307  }
3308  if (!fCollideGrid[i + j*fCGnx]) {
3309  box->SetFillColorAlpha(kBlack,t);
3310  box->DrawBox(X1L, Y1L, X2L, Y2L);
3311  } else {
3312  box->SetFillColorAlpha(kRed,t);
3313  box->DrawBox(X1L, Y1L, X2L, Y2L);
3314  }
3315  Y1 = Y2;
3316  Y2 = Y1+ys;
3317  if (t==0.15) t = 0.1;
3318  else t = 0.15;
3319  }
3320  X1 = X2;
3321  X2 = X1+xs;
3322  }
3323 }
3324 
3325 
3326 ////////////////////////////////////////////////////////////////////////////////
3327 /// Convert x from pad to X.
3328 
3330 {
3331  if (fLogx && x < 50) return Double_t(TMath::Exp(2.302585092994*x));
3332  return x;
3333 }
3334 
3335 ////////////////////////////////////////////////////////////////////////////////
3336 /// Convert y from pad to Y.
3337 
3339 {
3340  if (fLogy && y < 50) return Double_t(TMath::Exp(2.302585092994*y));
3341  return y;
3342 }
3343 
3344 ////////////////////////////////////////////////////////////////////////////////
3345 /// Convert x from X to pad.
3346 
3348 {
3349  if (fLogx) {
3350  if (x > 0) x = TMath::Log10(x);
3351  else x = fUxmin;
3352  }
3353  return x;
3354 }
3355 
3356 ////////////////////////////////////////////////////////////////////////////////
3357 /// Convert y from Y to pad.
3358 
3360 {
3361  if (fLogy) {
3362  if (y > 0) y = TMath::Log10(y);
3363  else y = fUymin;
3364  }
3365  return y;
3366 }
3367 
3368 ////////////////////////////////////////////////////////////////////////////////
3369 /// Paint all primitives in pad.
3370 
3371 void TPad::Paint(Option_t * /*option*/)
3372 {
3373  if (!fPrimitives) fPrimitives = new TList;
3375  fViewer3D->PadPaint(this);
3376  Modified(kFALSE);
3377  if (GetGLDevice()!=-1 && gVirtualPS) {
3378  TPad *padsav = (TPad*)gPad;
3379  gPad = this;
3380  gGLManager->PrintViewer(GetViewer3D());
3381  gPad = padsav;
3382  }
3383  return;
3384  }
3385 
3387 
3388  TPad *padsav = (TPad*)gPad;
3389 
3390  fPadPaint = 1;
3391  cd();
3392 
3394  PaintDate();
3395 
3397  TObject *obj;
3398 
3399  Bool_t began3DScene = kFALSE;
3400  while (lnk) {
3401  obj = lnk->GetObject();
3402 
3403  // Create a pad 3D viewer if none exists and we encounter a 3D shape
3404  if (!fViewer3D && obj->InheritsFrom(TAtt3D::Class())) {
3405  GetViewer3D("pad");
3406  }
3407 
3408  // Open a 3D scene if required
3409  if (fViewer3D && !fViewer3D->BuildingScene()) {
3410  fViewer3D->BeginScene();
3411  began3DScene = kTRUE;
3412  }
3413 
3414  obj->Paint(lnk->GetOption());
3415  lnk = (TObjOptLink*)lnk->Next();
3416  }
3417 
3418  if (padsav) padsav->cd();
3419  fPadPaint = 0;
3420  Modified(kFALSE);
3421 
3422  // Close the 3D scene if we opened it. This must be done after modified
3423  // flag is cleared, as some viewers will invoke another paint by marking pad modified again
3424  if (began3DScene) {
3425  fViewer3D->EndScene();
3426  }
3427 }
3428 
3429 ////////////////////////////////////////////////////////////////////////////////
3430 /// Paint the pad border.
3431 /// Draw first a box as a normal filled box
3432 
3434 {
3435  if(color >= 0) {
3436  TAttLine::Modify(); //Change line attributes only if necessary
3437  TAttFill::Modify(); //Change fill area attributes only if necessary
3438 
3439  //With Cocoa we have a transparency. But we also have
3440  //pixmaps, and if you just paint a new content over the old one
3441  //with alpha < 1., you'll be able to see the old content.
3442  if (!gROOT->IsBatch() && gVirtualX->InheritsFrom("TGCocoa") && GetPainter())
3444 
3445  PaintBox(fX1,fY1,fX2,fY2);
3446  }
3447  if (color < 0) color = -color;
3448  // then paint 3d frame (depending on bordermode)
3449  if (IsTransparent()) return;
3450  // Paint a 3D frame around the pad.
3451 
3452  if (fBorderMode == 0) return;
3453  Int_t bordersize = fBorderSize;
3454  if (bordersize <= 0) bordersize = 2;
3455 
3456  const Double_t realBsX = bordersize / (GetAbsWNDC() * GetWw()) * (fX2 - fX1);
3457  const Double_t realBsY = bordersize / (GetAbsHNDC() * GetWh()) * (fY2 - fY1);
3458 
3459  Short_t px1,py1,px2,py2;
3460  Double_t xl, xt, yl, yt;
3461 
3462  // GetDarkColor() and GetLightColor() use GetFillColor()
3463  Color_t oldcolor = GetFillColor();
3464  SetFillColor(color);
3465  TAttFill::Modify();
3466  Color_t light = 0, dark = 0;
3467  if (color != 0) {
3468  light = TColor::GetColorBright(color);
3469  dark = TColor::GetColorDark(color);
3470  }
3471 
3472  // Compute real left bottom & top right of the box in pixels
3473  px1 = XtoPixel(fX1); py1 = YtoPixel(fY1);
3474  px2 = XtoPixel(fX2); py2 = YtoPixel(fY2);
3475  if (px1 < px2) {xl = fX1; xt = fX2; }
3476  else {xl = fX2; xt = fX1;}
3477  if (py1 > py2) {yl = fY1; yt = fY2;}
3478  else {yl = fY2; yt = fY1;}
3479 
3480  Double_t frameXs[7] = {}, frameYs[7] = {};
3481 
3482  if (!IsBatch()) {
3483  // Draw top&left part of the box
3484  frameXs[0] = xl; frameYs[0] = yl;
3485  frameXs[1] = xl + realBsX; frameYs[1] = yl + realBsY;
3486  frameXs[2] = frameXs[1]; frameYs[2] = yt - realBsY;
3487  frameXs[3] = xt - realBsX; frameYs[3] = frameYs[2];
3488  frameXs[4] = xt; frameYs[4] = yt;
3489  frameXs[5] = xl; frameYs[5] = yt;
3490  frameXs[6] = xl; frameYs[6] = yl;
3491 
3492  if (fBorderMode == -1) GetPainter()->SetFillColor(dark);
3493  else GetPainter()->SetFillColor(light);
3494  GetPainter()->DrawFillArea(7, frameXs, frameYs);
3495 
3496  // Draw bottom&right part of the box
3497  frameXs[0] = xl; frameYs[0] = yl;
3498  frameXs[1] = xl + realBsX; frameYs[1] = yl + realBsY;
3499  frameXs[2] = xt - realBsX; frameYs[2] = frameYs[1];
3500  frameXs[3] = frameXs[2]; frameYs[3] = yt - realBsY;
3501  frameXs[4] = xt; frameYs[4] = yt;
3502  frameXs[5] = xt; frameYs[5] = yl;
3503  frameXs[6] = xl; frameYs[6] = yl;
3504 
3505  if (fBorderMode == -1) GetPainter()->SetFillColor(light);
3506  else GetPainter()->SetFillColor(dark);
3507  GetPainter()->DrawFillArea(7, frameXs, frameYs);
3508 
3509  // If this pad is a button, highlight it
3510  if (InheritsFrom(TButton::Class()) && fBorderMode == -1) {
3511  if (TestBit(kFraming)) { // bit set in TButton::SetFraming
3512  if (GetFillColor() != 2) GetPainter()->SetLineColor(2);
3513  else GetPainter()->SetLineColor(4);
3514  GetPainter()->DrawBox(xl + realBsX, yl + realBsY, xt - realBsX, yt - realBsY, TVirtualPadPainter::kHollow);
3515  }
3516  }
3517  GetPainter()->SetFillColor(-1);
3518  SetFillColor(oldcolor);
3519  }
3520 
3521  if (!tops) return;
3522 
3523  PaintBorderPS(xl, yl, xt, yt, fBorderMode, bordersize, dark, light);
3524 }
3525 
3526 ////////////////////////////////////////////////////////////////////////////////
3527 /// Paint a frame border with Postscript.
3528 
3529 void TPad::PaintBorderPS(Double_t xl,Double_t yl,Double_t xt,Double_t yt,Int_t bmode,Int_t bsize,Int_t dark,Int_t light)
3530 {
3531  if (!gVirtualPS) return;
3532  gVirtualPS->DrawFrame(xl, yl, xt, yt, bmode,bsize,dark,light);
3533 }
3534 
3535 ////////////////////////////////////////////////////////////////////////////////
3536 /// Paint the current date and time if the option date is on.
3537 
3539 {
3540  if (fCanvas == this && gStyle->GetOptDate()) {
3541  TDatime dt;
3542  const char *dates;
3543  char iso[16];
3544  if (gStyle->GetOptDate() < 10) {
3545  //by default use format like "Wed Sep 25 17:10:35 2002"
3546  dates = dt.AsString();
3547  } else if (gStyle->GetOptDate() < 20) {
3548  //use ISO format like 2002-09-25
3549  strlcpy(iso,dt.AsSQLString(),16);
3550  dates = iso;
3551  } else {
3552  //use ISO format like 2002-09-25 17:10:35
3553  dates = dt.AsSQLString();
3554  }
3555  TText tdate(gStyle->GetDateX(),gStyle->GetDateY(),dates);
3556  tdate.SetTextSize( gStyle->GetAttDate()->GetTextSize());
3557  tdate.SetTextFont( gStyle->GetAttDate()->GetTextFont());
3558  tdate.SetTextColor(gStyle->GetAttDate()->GetTextColor());
3559  tdate.SetTextAlign(gStyle->GetAttDate()->GetTextAlign());
3560  tdate.SetTextAngle(gStyle->GetAttDate()->GetTextAngle());
3561  tdate.SetNDC();
3562  tdate.Paint();
3563  }
3564 }
3565 
3566 ////////////////////////////////////////////////////////////////////////////////
3567 /// Paint histogram/graph frame.
3568 
3570 {
3571  if (!fPrimitives) fPrimitives = new TList;
3572  TList *glist = GetListOfPrimitives();
3573  TFrame *frame = GetFrame();
3574  frame->SetX1(xmin);
3575  frame->SetX2(xmax);
3576  frame->SetY1(ymin);
3577  frame->SetY2(ymax);
3578  if (!glist->FindObject(fFrame)) {
3579  glist->AddFirst(frame);
3581  }
3582  frame->Paint();
3583 }
3584 
3585 ////////////////////////////////////////////////////////////////////////////////
3586 /// Traverse pad hierarchy and (re)paint only modified pads.
3587 
3589 {
3591  if (IsModified()) {
3592  fViewer3D->PadPaint(this);
3593  Modified(kFALSE);
3594  }
3595  TList *pList = GetListOfPrimitives();
3596  TObjOptLink *lnk = 0;
3597  if (pList) lnk = (TObjOptLink*)pList->FirstLink();
3598  TObject *obj;
3599  while (lnk) {
3600  obj = lnk->GetObject();
3601  if (obj->InheritsFrom(TPad::Class()))
3602  ((TPad*)obj)->PaintModified();
3603  lnk = (TObjOptLink*)lnk->Next();
3604  }
3605  return;
3606  }
3607 
3609 
3610  TPad *padsav = (TPad*)gPad;
3611  TVirtualPS *saveps = gVirtualPS;
3612  if (gVirtualPS) {
3614  }
3615  fPadPaint = 1;
3616  cd();
3617  if (IsModified() || IsTransparent()) {
3618  if ((fFillStyle < 3026) && (fFillStyle > 3000)) {
3619  if (!gPad->IsBatch()) GetPainter()->ClearDrawable();
3620  }
3622  }
3623 
3624  PaintDate();
3625 
3626  TList *pList = GetListOfPrimitives();
3627  TObjOptLink *lnk = 0;
3628  if (pList) lnk = (TObjOptLink*)pList->FirstLink();
3629  TObject *obj;
3630 
3631  Bool_t began3DScene = kFALSE;
3632 
3633  while (lnk) {
3634  obj = lnk->GetObject();
3635  if (obj->InheritsFrom(TPad::Class())) {
3636  ((TPad*)obj)->PaintModified();
3637  } else if (IsModified() || IsTransparent()) {
3638 
3639  // Create a pad 3D viewer if none exists and we encounter a
3640  // 3D shape
3641  if (!fViewer3D && obj->InheritsFrom(TAtt3D::Class())) {
3642  GetViewer3D("pad");
3643  }
3644 
3645  // Open a 3D scene if required
3646  if (fViewer3D && !fViewer3D->BuildingScene()) {
3647  fViewer3D->BeginScene();
3648  began3DScene = kTRUE;
3649  }
3650 
3651  obj->Paint(lnk->GetOption());
3652  }
3653  lnk = (TObjOptLink*)lnk->Next();
3654  }
3655 
3656  if (padsav) padsav->cd();
3657  fPadPaint = 0;
3658  Modified(kFALSE);
3659 
3660  // This must be done after modified flag is cleared, as some
3661  // viewers will invoke another paint by marking pad modified again
3662  if (began3DScene) {
3663  fViewer3D->EndScene();
3664  }
3665 
3666  gVirtualPS = saveps;
3667 }
3668 
3669 ////////////////////////////////////////////////////////////////////////////////
3670 /// Paint box in CurrentPad World coordinates.
3671 ///
3672 /// - if option[0] = 's' the box is forced to be paint with style=0
3673 /// - if option[0] = 'l' the box contour is drawn
3674 
3676 {
3677  if (!gPad->IsBatch()) {
3678  Int_t style0 = GetPainter()->GetFillStyle();
3679  Int_t style = style0;
3680  if (option[0] == 's') {
3681  GetPainter()->SetFillStyle(0);
3682  style = 0;
3683  }
3684  if (style) {
3685  if (style > 3000 && style < 4000) {
3686  if (style < 3026) {
3687  // draw stipples with fFillColor foreground
3688  GetPainter()->DrawBox(x1, y1, x2, y2, TVirtualPadPainter::kFilled);
3689  }
3690 
3691  if (style >= 3100 && style < 4000) {
3692  Double_t xb[4], yb[4];
3693  xb[0] = x1; xb[1] = x1; xb[2] = x2; xb[3] = x2;
3694  yb[0] = y1; yb[1] = y2; yb[2] = y2; yb[3] = y1;
3695  PaintFillAreaHatches(4, xb, yb, style);
3696  return;
3697  }
3698  //special case for TAttFillCanvas
3699  if (GetPainter()->GetFillColor() == 10) {
3700  GetPainter()->SetFillColor(1);
3701  GetPainter()->DrawBox(x1, y1, x2, y2, TVirtualPadPainter::kFilled);
3702  GetPainter()->SetFillColor(10);
3703  }
3704  } else if (style >= 4000 && style <= 4100) {
3705  // For style >=4000 we make the window transparent.
3706  // From 4000 to 4100 the window is 100% transparent to 100% opaque
3707 
3708  //ignore this style option when this is the canvas itself
3709  if (this == fMother) {
3710  //It's clear, that virtual X checks a style (4000) and will render a hollow rect!
3711  const Style_t oldFillStyle = GetPainter()->GetFillStyle();
3712  if (gVirtualX->InheritsFrom("TGCocoa"))
3713  GetPainter()->SetFillStyle(1000);
3714  GetPainter()->DrawBox(x1, y1, x2, y2, TVirtualPadPainter::kFilled);
3715  if (gVirtualX->InheritsFrom("TGCocoa"))
3716  GetPainter()->SetFillStyle(oldFillStyle);
3717  } else {
3718  //draw background by blitting all bottom pads
3719  int px, py;
3720  XYtoAbsPixel(fX1, fY2, px, py);
3721 
3722  if (fMother) {
3723  fMother->CopyBackgroundPixmap(px, py);
3724  CopyBackgroundPixmaps(fMother, this, px, py);
3725  }
3726 
3727  GetPainter()->SetOpacity(style - 4000);
3728  }
3729  } else if (style >= 1000 && style <= 1999) {
3730  GetPainter()->DrawBox(x1, y1, x2, y2, TVirtualPadPainter::kFilled);
3731  } else {
3732  GetPainter()->DrawBox(x1, y1, x2, y2, TVirtualPadPainter::kHollow);
3733  }
3734  if (option[0] == 'l') GetPainter()->DrawBox(x1, y1, x2, y2, TVirtualPadPainter::kHollow);
3735  } else {
3736  GetPainter()->DrawBox(x1, y1, x2, y2, TVirtualPadPainter::kHollow);
3737  if (option[0] == 's') GetPainter()->SetFillStyle(style0);
3738  }
3739  }
3740 
3741  if (gVirtualPS) {
3742  Int_t style0 = gVirtualPS->GetFillStyle();
3743  if (option[0] == 's') {
3745  } else {
3746  if (style0 >= 3100 && style0 < 4000) {
3747  Double_t xb[4], yb[4];
3748  xb[0] = x1; xb[1] = x1; xb[2] = x2; xb[3] = x2;
3749  yb[0] = y1; yb[1] = y2; yb[2] = y2; yb[3] = y1;
3750  PaintFillAreaHatches(4, xb, yb, style0);
3751  return;
3752  }
3753  }
3754  gVirtualPS->DrawBox(x1, y1, x2, y2);
3755  if (option[0] == 'l') {
3757  gVirtualPS->DrawBox(x1, y1, x2, y2);
3758  }
3759  if (option[0] == 's' || option[0] == 'l') gVirtualPS->SetFillStyle(style0);
3760  }
3761 
3762  Modified();
3763 }
3764 
3765 ////////////////////////////////////////////////////////////////////////////////
3766 /// Copy pixmaps of pads laying below pad "stop" into pad "stop". This
3767 /// gives the effect of pad "stop" being transparent.
3768 
3770 {
3771  TObject *obj;
3772  if (!fPrimitives) fPrimitives = new TList;
3773  TIter next(start->GetListOfPrimitives());
3774  while ((obj = next())) {
3775  if (obj->InheritsFrom(TPad::Class())) {
3776  if (obj == stop) break;
3777  ((TPad*)obj)->CopyBackgroundPixmap(x, y);
3778  ((TPad*)obj)->CopyBackgroundPixmaps((TPad*)obj, stop, x, y);
3779  }
3780  }
3781 }
3782 
3783 ////////////////////////////////////////////////////////////////////////////////
3784 /// Copy pixmap of this pad as background of the current pad.
3785 
3787 {
3788  int px, py;
3789  XYtoAbsPixel(fX1, fY2, px, py);
3790  GetPainter()->CopyDrawable(GetPixmapID(), px-x, py-y);
3791 }
3792 
3793 ////////////////////////////////////////////////////////////////////////////////
3794 
3796 {
3797  Warning("TPad::PaintFillArea", "Float_t signature is obsolete. Use Double_t signature.");
3798 }
3799 
3800 ////////////////////////////////////////////////////////////////////////////////
3801 /// Paint fill area in CurrentPad World coordinates.
3802 
3804 {
3805  if (nn <3) return;
3806  Int_t n=0;
3808  if (TestBit(TGraph::kClipFrame)) {
3809  xmin = fUxmin; ymin = fUymin; xmax = fUxmax; ymax = fUymax;
3810  } else {
3811  xmin = fX1; ymin = fY1; xmax = fX2; ymax = fY2;
3812  }
3813 
3814  Int_t nc = 2*nn+1;
3815  Double_t *x = new Double_t[nc];
3816  Double_t *y = new Double_t[nc];
3817  memset(x,0,8*nc);
3818  memset(y,0,8*nc);
3819 
3820  n = ClipPolygon(nn, xx, yy, nc, x, y,xmin,ymin,xmax,ymax);
3821  if (!n) {
3822  delete [] x;
3823  delete [] y;
3824  return;
3825  }
3826 
3827  // Paint the fill area with hatches
3828  Int_t fillstyle = GetPainter()->GetFillStyle();
3829  if (gPad->IsBatch() && gVirtualPS) fillstyle = gVirtualPS->GetFillStyle();
3830  if (fillstyle >= 3100 && fillstyle < 4000) {
3831  PaintFillAreaHatches(nn, x, y, fillstyle);
3832  delete [] x;
3833  delete [] y;
3834  return;
3835  }
3836 
3837  if (!gPad->IsBatch())
3838  // invoke the graphics subsystem
3839  GetPainter()->DrawFillArea(n, x, y);
3840 
3841  if (gVirtualPS) {
3842  gVirtualPS->DrawPS(-n, x, y);
3843  }
3844  delete [] x;
3845  delete [] y;
3846  Modified();
3847 }
3848 
3849 ////////////////////////////////////////////////////////////////////////////////
3850 /// This function paints hatched fill area according to the FillStyle value
3851 /// The convention for the Hatch is the following:
3852 ///
3853 /// `FillStyle = 3ijk`
3854 ///
3855 /// - i (1-9) : specify the space between each hatch
3856 /// 1 = minimum 9 = maximum
3857 /// the final spacing is i*GetHatchesSpacing(). The hatches spacing
3858 /// is set by SetHatchesSpacing()
3859 /// - j (0-9) : specify angle between 0 and 90 degrees
3860 /// * 0 = 0
3861 /// * 1 = 10
3862 /// * 2 = 20
3863 /// * 3 = 30
3864 /// * 4 = 45
3865 /// * 5 = Not drawn
3866 /// * 6 = 60
3867 /// * 7 = 70
3868 /// * 8 = 80
3869 /// * 9 = 90
3870 /// - k (0-9) : specify angle between 90 and 180 degrees
3871 /// * 0 = 180
3872 /// * 1 = 170
3873 /// * 2 = 160
3874 /// * 3 = 150
3875 /// * 4 = 135
3876 /// * 5 = Not drawn
3877 /// * 6 = 120
3878 /// * 7 = 110
3879 /// * 8 = 100
3880 /// * 9 = 90
3881 
3883 {
3884  static Double_t ang1[10] = {0., 10., 20., 30., 45.,5., 60., 70., 80., 90.};
3885  static Double_t ang2[10] = {180.,170.,160.,150.,135.,5.,120.,110.,100., 90.};
3886 
3887  Int_t fasi = FillStyle%1000;
3888  Int_t idSPA = (Int_t)(fasi/100);
3889  Int_t iAng2 = (Int_t)((fasi-100*idSPA)/10);
3890  Int_t iAng1 = fasi%10;
3891  Double_t dy = 0.003*(Double_t)(idSPA)*gStyle->GetHatchesSpacing();
3893  Short_t lws = 0;
3894  Int_t lss = 0;
3895  Int_t lcs = 0;
3896 
3897  // Save the current line attributes
3898  if (!gPad->IsBatch()) {
3899  lws = GetPainter()->GetLineWidth();
3900  lss = GetPainter()->GetLineStyle();
3901  lcs = GetPainter()->GetLineColor();
3902  } else {
3903  if (gVirtualPS) {
3904  lws = gVirtualPS->GetLineWidth();
3905  lss = gVirtualPS->GetLineStyle();
3906  lcs = gVirtualPS->GetLineColor();
3907  }
3908  }
3909 
3910  // Change the current line attributes to draw the hatches
3911  if (!gPad->IsBatch()) {
3912  GetPainter()->SetLineStyle(1);
3915  }
3916  if (gVirtualPS) {
3920  }
3921 
3922  // Draw the hatches
3923  if (ang1[iAng1] != 5.) PaintHatches(dy, ang1[iAng1], nn, xx, yy);
3924  if (ang2[iAng2] != 5.) PaintHatches(dy, ang2[iAng2], nn, xx, yy);
3925 
3926  // Restore the line attributes
3927  if (!gPad->IsBatch()) {
3928  GetPainter()->SetLineStyle(lss);
3929  GetPainter()->SetLineWidth(lws);
3930  GetPainter()->SetLineColor(lcs);
3931  }
3932  if (gVirtualPS) {
3933  gVirtualPS->SetLineStyle(lss);
3934  gVirtualPS->SetLineWidth(lws);
3935  gVirtualPS->SetLineColor(lcs);
3936  }
3937 }
3938 
3939 ////////////////////////////////////////////////////////////////////////////////
3940 /// This routine draw hatches inclined with the
3941 /// angle "angle" and spaced of "dy" in normalized device
3942 /// coordinates in the surface defined by n,xx,yy.
3943 
3945  Int_t nn, Double_t *xx, Double_t *yy)
3946 {
3947  Int_t i, i1, i2, nbi, m, inv;
3948  Double_t ratiox, ratioy, ymin, ymax, yrot, ycur;
3949  const Double_t angr = TMath::Pi()*(180-angle)/180.;
3950  const Double_t epsil = 0.0001;
3951  const Int_t maxnbi = 100;
3952  Double_t xli[maxnbi], xlh[2], ylh[2], xt1, xt2, yt1, yt2;
3953  Double_t ll, x, y, x1, x2, y1, y2, a, b, xi, xip, xin, yi, yip;
3954 
3955  Double_t rwxmin = gPad->GetX1();
3956  Double_t rwxmax = gPad->GetX2();
3957  Double_t rwymin = gPad->GetY1();
3958  Double_t rwymax = gPad->GetY2();
3959  ratiox = 1/(rwxmax-rwxmin);
3960  ratioy = 1/(rwymax-rwymin);
3961 
3962  Double_t sina = TMath::Sin(angr), sinb;
3963  Double_t cosa = TMath::Cos(angr), cosb;
3964  if (TMath::Abs(cosa) <= epsil) cosa=0.;
3965  if (TMath::Abs(sina) <= epsil) sina=0.;
3966  sinb = -sina;
3967  cosb = cosa;
3968 
3969  // Values needed to compute the hatches in TRUE normalized space (NDC)
3970  Int_t iw = gPad->GetWw();
3971  Int_t ih = gPad->GetWh();
3972  Double_t x1p,y1p,x2p,y2p;
3973  gPad->GetPadPar(x1p,y1p,x2p,y2p);
3974  iw = (Int_t)(iw*x2p)-(Int_t)(iw*x1p);
3975  ih = (Int_t)(ih*y2p)-(Int_t)(ih*y1p);
3976  Double_t wndc = TMath::Min(1.,(Double_t)iw/(Double_t)ih);
3977  Double_t hndc = TMath::Min(1.,(Double_t)ih/(Double_t)iw);
3978 
3979  // Search ymin and ymax
3980  ymin = 1.;
3981  ymax = 0.;
3982  for (i=1; i<=nn; i++) {
3983  x = wndc*ratiox*(xx[i-1]-rwxmin);
3984  y = hndc*ratioy*(yy[i-1]-rwymin);
3985  yrot = sina*x+cosa*y;
3986  if (yrot > ymax) ymax = yrot;
3987  if (yrot < ymin) ymin = yrot;
3988  }
3989  ymax = (Double_t)((Int_t)(ymax/dy))*dy;
3990 
3991  for (ycur=ymax; ycur>=ymin; ycur=ycur-dy) {
3992  nbi = 0;
3993  for (i=2; i<=nn+1; i++) {
3994  i2 = i;
3995  i1 = i-1;
3996  if (i == nn+1) i2=1;
3997  x1 = wndc*ratiox*(xx[i1-1]-rwxmin);
3998  y1 = hndc*ratioy*(yy[i1-1]-rwymin);
3999  x2 = wndc*ratiox*(xx[i2-1]-rwxmin);
4000  y2 = hndc*ratioy*(yy[i2-1]-rwymin);
4001  xt1 = cosa*x1-sina*y1;
4002  yt1 = sina*x1+cosa*y1;
4003  xt2 = cosa*x2-sina*y2;
4004  yt2 = sina*x2+cosa*y2;
4005 
4006  // Line segment parallel to oy
4007  if (xt1 == xt2) {
4008  if (yt1 < yt2) {
4009  yi = yt1;
4010  yip = yt2;
4011  } else {
4012  yi = yt2;
4013  yip = yt1;
4014  }
4015  if ((yi <= ycur) && (ycur < yip)) {
4016  nbi++;
4017  if (nbi >= maxnbi) return;
4018  xli[nbi-1] = xt1;
4019  }
4020  continue;
4021  }
4022 
4023  // Line segment parallel to ox
4024  if (yt1 == yt2) {
4025  if (yt1 == ycur) {
4026  nbi++;
4027  if (nbi >= maxnbi) return;
4028  xli[nbi-1] = xt1;
4029  nbi++;
4030  if (nbi >= maxnbi) return;
4031  xli[nbi-1] = xt2;
4032  }
4033  continue;
4034  }
4035 
4036  // Other line segment
4037  a = (yt1-yt2)/(xt1-xt2);
4038  b = (yt2*xt1-xt2*yt1)/(xt1-xt2);
4039  if (xt1 < xt2) {
4040  xi = xt1;
4041  xip = xt2;
4042  } else {
4043  xi = xt2;
4044  xip = xt1;
4045  }
4046  xin = (ycur-b)/a;
4047  if ((xi <= xin) && (xin < xip) &&
4048  (TMath::Min(yt1,yt2) <= ycur) &&
4049  (ycur < TMath::Max(yt1,yt2))) {
4050  nbi++;
4051  if (nbi >= maxnbi) return;
4052  xli[nbi-1] = xin;
4053  }
4054  }
4055 
4056  // Sorting of the x coordinates intersections
4057  inv = 0;
4058  m = nbi-1;
4059 L30:
4060  for (i=1; i<=m; i++) {
4061  if (xli[i] < xli[i-1]) {
4062  inv++;
4063  ll = xli[i-1];
4064  xli[i-1] = xli[i];
4065  xli[i] = ll;
4066  }
4067  }
4068  m--;
4069  if (inv == 0) goto L50;
4070  inv = 0;
4071  goto L30;
4072 
4073  // Draw the hatches
4074 L50:
4075  if (nbi%2 != 0) continue;
4076 
4077  for (i=1; i<=nbi; i=i+2) {
4078  // Rotate back the hatches
4079  xlh[0] = cosb*xli[i-1]-sinb*ycur;
4080  ylh[0] = sinb*xli[i-1]+cosb*ycur;
4081  xlh[1] = cosb*xli[i] -sinb*ycur;
4082  ylh[1] = sinb*xli[i] +cosb*ycur;
4083  // Convert hatches' positions from true NDC to WC
4084  xlh[0] = (xlh[0]/wndc)*(rwxmax-rwxmin)+rwxmin;
4085  ylh[0] = (ylh[0]/hndc)*(rwymax-rwymin)+rwymin;
4086  xlh[1] = (xlh[1]/wndc)*(rwxmax-rwxmin)+rwxmin;
4087  ylh[1] = (ylh[1]/hndc)*(rwymax-rwymin)+rwymin;
4088  gPad->PaintLine(xlh[0], ylh[0], xlh[1], ylh[1]);
4089  }
4090  }
4091 }
4092 
4093 ////////////////////////////////////////////////////////////////////////////////
4094 /// Paint line in CurrentPad World coordinates.
4095 
4097 {
4098  Double_t x[2], y[2];
4099  x[0] = x1; x[1] = x2; y[0] = y1; y[1] = y2;
4100 
4101  //If line is totally clipped, return
4102  if (TestBit(TGraph::kClipFrame)) {
4103  if (Clip(x,y,fUxmin,fUymin,fUxmax,fUymax) == 2) return;
4104  } else {
4105  if (Clip(x,y,fX1,fY1,fX2,fY2) == 2) return;
4106  }
4107 
4108  if (!gPad->IsBatch())
4109  GetPainter()->DrawLine(x[0], y[0], x[1], y[1]);
4110 
4111  if (gVirtualPS) {
4112  gVirtualPS->DrawPS(2, x, y);
4113  }
4114 
4115  Modified();
4116 }
4117 
4118 ////////////////////////////////////////////////////////////////////////////////
4119 /// Paint line in normalized coordinates.
4120 
4122 {
4123  static Double_t xw[2], yw[2];
4124  if (!gPad->IsBatch())
4125  GetPainter()->DrawLineNDC(u1, v1, u2, v2);
4126 
4127  if (gVirtualPS) {
4128  xw[0] = fX1 + u1*(fX2 - fX1);
4129  xw[1] = fX1 + u2*(fX2 - fX1);
4130  yw[0] = fY1 + v1*(fY2 - fY1);
4131  yw[1] = fY1 + v2*(fY2 - fY1);
4132  gVirtualPS->DrawPS(2, xw, yw);
4133  }
4134 
4135  Modified();
4136 }
4137 
4138 ////////////////////////////////////////////////////////////////////////////////
4139 /// Paint 3-D line in the CurrentPad.
4140 
4142 {
4143  if (!fView) return;
4144 
4145  // convert from 3-D to 2-D pad coordinate system
4146  Double_t xpad[6];
4147  Double_t temp[3];
4148  Int_t i;
4149  for (i=0;i<3;i++) temp[i] = p1[i];
4150  fView->WCtoNDC(temp, &xpad[0]);
4151  for (i=0;i<3;i++) temp[i] = p2[i];
4152  fView->WCtoNDC(temp, &xpad[3]);
4153  PaintLine(xpad[0],xpad[1],xpad[3],xpad[4]);
4154 }
4155 
4156 ////////////////////////////////////////////////////////////////////////////////
4157 /// Paint 3-D line in the CurrentPad.
4158 
4160 {
4161  //take into account perspective view
4162  if (!fView) return;
4163  // convert from 3-D to 2-D pad coordinate system
4164  Double_t xpad[6];
4165  Double_t temp[3];
4166  Int_t i;
4167  for (i=0;i<3;i++) temp[i] = p1[i];
4168  fView->WCtoNDC(temp, &xpad[0]);
4169  for (i=0;i<3;i++) temp[i] = p2[i];
4170  fView->WCtoNDC(temp, &xpad[3]);
4171  PaintLine(xpad[0],xpad[1],xpad[3],xpad[4]);
4172 }
4173 
4174 ////////////////////////////////////////////////////////////////////////////////
4175 /// Paint polyline in CurrentPad World coordinates.
4176 
4178 {
4179  if (n < 2) return;
4180 
4182  if (TestBit(TGraph::kClipFrame)) {
4183  xmin = fUxmin; ymin = fUymin; xmax = fUxmax; ymax = fUymax;
4184  } else {
4185  xmin = fX1; ymin = fY1; xmax = fX2; ymax = fY2;
4186  }
4187  Int_t i, i1=-1,np=1;
4188  for (i=0; i<n-1; i++) {
4189  Double_t x1=x[i];
4190  Double_t y1=y[i];
4191  Double_t x2=x[i+1];
4192  Double_t y2=y[i+1];
4193  Int_t iclip = Clip(&x[i],&y[i],xmin,ymin,xmax,ymax);
4194  if (iclip == 2) {
4195  i1 = -1;
4196  continue;
4197  }
4198  np++;
4199  if (i1 < 0) i1 = i;
4200  if (iclip == 0 && i < n-2) continue;
4201  if (!gPad->IsBatch())
4202  GetPainter()->DrawPolyLine(np, &x[i1], &y[i1]);
4203  if (gVirtualPS) {
4204  gVirtualPS->DrawPS(np, &x[i1], &y[i1]);
4205  }
4206  if (iclip) {
4207  x[i] = x1;
4208  y[i] = y1;
4209  x[i+1] = x2;
4210  y[i+1] = y2;
4211  }
4212  i1 = -1;
4213  np = 1;
4214  }
4215 
4216  Modified();
4217 }
4218 
4219 ////////////////////////////////////////////////////////////////////////////////
4220 /// Paint polyline in CurrentPad World coordinates.
4221 ///
4222 /// If option[0] == 'C' no clipping
4223 
4225 {
4226  if (n < 2) return;
4227 
4229  Bool_t mustClip = kTRUE;
4230  if (TestBit(TGraph::kClipFrame)) {
4231  xmin = fUxmin; ymin = fUymin; xmax = fUxmax; ymax = fUymax;
4232  } else {
4233  xmin = fX1; ymin = fY1; xmax = fX2; ymax = fY2;
4234  if (option && (option[0] == 'C')) mustClip = kFALSE;
4235  }
4236 
4237  Int_t i, i1=-1, np=1, iclip=0;
4238 
4239  for (i=0; i < n-1; i++) {
4240  Double_t x1=x[i];
4241  Double_t y1=y[i];
4242  Double_t x2=x[i+1];
4243  Double_t y2=y[i+1];
4244  if (mustClip) {
4245  iclip = Clip(&x[i],&y[i],xmin,ymin,xmax,ymax);
4246  if (iclip == 2) {
4247  i1 = -1;
4248  continue;
4249  }
4250  }
4251  np++;
4252  if (i1 < 0) i1 = i;
4253  if (iclip == 0 && i < n-2) continue;
4254  if (!gPad->IsBatch())
4255  GetPainter()->DrawPolyLine(np, &x[i1], &y[i1]);
4256  if (gVirtualPS) {
4257  gVirtualPS->DrawPS(np, &x[i1], &y[i1]);
4258  }
4259  if (iclip) {
4260  x[i] = x1;
4261  y[i] = y1;
4262  x[i+1] = x2;
4263  y[i+1] = y2;
4264  }
4265  i1 = -1;
4266  np = 1;
4267  }
4268 
4269  Modified();
4270 }
4271 
4272 ////////////////////////////////////////////////////////////////////////////////
4273 /// Paint polyline in CurrentPad NDC coordinates.
4274 
4276 {
4277  if (n <=0) return;
4278 
4279  if (!gPad->IsBatch())
4280  GetPainter()->DrawPolyLineNDC(n, x, y);
4281 
4282  if (gVirtualPS) {
4283  Double_t *xw = new Double_t[n];
4284  Double_t *yw = new Double_t[n];
4285  for (Int_t i=0; i<n; i++) {
4286  xw[i] = fX1 + x[i]*(fX2 - fX1);
4287  yw[i] = fY1 + y[i]*(fY2 - fY1);
4288  }
4289  gVirtualPS->DrawPS(n, xw, yw);
4290  delete [] xw;
4291  delete [] yw;
4292  }
4293  Modified();
4294 }
4295 
4296 ////////////////////////////////////////////////////////////////////////////////
4297 /// Paint 3-D polyline in the CurrentPad.
4298 
4300 {
4301  if (!fView) return;
4302 
4303  // Loop on each individual line
4304  for (Int_t i = 1; i < n; i++)
4305  PaintLine3D(&p[3*i-3], &p[3*i]);
4306 
4307  Modified();
4308 }
4309 
4310 ////////////////////////////////////////////////////////////////////////////////
4311 /// Paint polymarker in CurrentPad World coordinates.
4312 
4314 {
4315  Int_t n = TMath::Abs(nn);
4317  if (nn > 0 || TestBit(TGraph::kClipFrame)) {
4318  xmin = fUxmin; ymin = fUymin; xmax = fUxmax; ymax = fUymax;
4319  } else {
4320  xmin = fX1; ymin = fY1; xmax = fX2; ymax = fY2;
4321  }
4322  Int_t i,i1=-1,np=0;
4323  for (i=0; i<n; i++) {
4324  if (x[i] >= xmin && x[i] <= xmax && y[i] >= ymin && y[i] <= ymax) {
4325  np++;
4326  if (i1 < 0) i1 = i;
4327  if (i < n-1) continue;
4328  }
4329  if (np == 0) continue;
4330  if (!gPad->IsBatch())
4331  GetPainter()->DrawPolyMarker(np, &x[i1], &y[i1]);
4332  if (gVirtualPS) {
4333  gVirtualPS->DrawPolyMarker(np, &x[i1], &y[i1]);
4334  }
4335  i1 = -1;
4336  np = 0;
4337  }
4338  Modified();
4339 }
4340 
4341 ////////////////////////////////////////////////////////////////////////////////
4342 /// Paint polymarker in CurrentPad World coordinates.
4343 
4345 {
4346  Int_t n = TMath::Abs(nn);
4348  if (nn > 0 || TestBit(TGraph::kClipFrame)) {
4349  xmin = fUxmin; ymin = fUymin; xmax = fUxmax; ymax = fUymax;
4350  } else {
4351  xmin = fX1; ymin = fY1; xmax = fX2; ymax = fY2;
4352  }
4353  Int_t i,i1=-1,np=0;
4354  for (i=0; i<n; i++) {
4355  if (x[i] >= xmin && x[i] <= xmax && y[i] >= ymin && y[i] <= ymax) {
4356  np++;
4357  if (i1 < 0) i1 = i;
4358  if (i < n-1) continue;
4359  }
4360  if (np == 0) continue;
4361  if (!gPad->IsBatch())
4362  GetPainter()->DrawPolyMarker(np, &x[i1], &y[i1]);
4363  if (gVirtualPS) {
4364  gVirtualPS->DrawPolyMarker(np, &x[i1], &y[i1]);
4365  }
4366  i1 = -1;
4367  np = 0;
4368  }
4369  Modified();
4370 }
4371 
4372 ////////////////////////////////////////////////////////////////////////////////
4373 /// Paint text in CurrentPad World coordinates.
4374 
4376 {
4377  Modified();
4378 
4379  if (!gPad->IsBatch())
4381 
4382  if (gVirtualPS) gVirtualPS->Text(x, y, text);
4383 }
4384 
4385 ////////////////////////////////////////////////////////////////////////////////
4386 /// Paint text in CurrentPad World coordinates.
4387 
4388 void TPad::PaintText(Double_t x, Double_t y, const wchar_t *text)
4389 {
4390  Modified();
4391 
4392  if (!gPad->IsBatch())
4394 
4395  if (gVirtualPS) gVirtualPS->Text(x, y, text);
4396 }
4397 
4398 ////////////////////////////////////////////////////////////////////////////////
4399 /// Paint text in CurrentPad NDC coordinates.
4400 
4402 {
4403  Modified();
4404 
4405  if (!gPad->IsBatch())
4407 
4408  if (gVirtualPS) {
4409  Double_t x = fX1 + u*(fX2 - fX1);
4410  Double_t y = fY1 + v*(fY2 - fY1);
4411  gVirtualPS->Text(x, y, text);
4412  }
4413 }
4414 
4415 ////////////////////////////////////////////////////////////////////////////////
4416 /// Paint text in CurrentPad NDC coordinates.
4417 
4418 void TPad::PaintTextNDC(Double_t u, Double_t v, const wchar_t *text)
4419 {
4420  Modified();
4421 
4422  if (!gPad->IsBatch())
4424 
4425  if (gVirtualPS) {
4426  Double_t x = fX1 + u*(fX2 - fX1);
4427  Double_t y = fY1 + v*(fY2 - fY1);
4428  gVirtualPS->Text(x, y, text);
4429  }
4430 }
4431 
4432 ////////////////////////////////////////////////////////////////////////////////
4433 /// Search for an object at pixel position px,py.
4434 ///
4435 /// Check if point is in this pad.
4436 ///
4437 /// If yes, check if it is in one of the sub-pads
4438 ///
4439 /// If found in the pad, compute closest distance of approach
4440 /// to each primitive.
4441 ///
4442 /// If one distance of approach is found to be within the limit Distancemaximum
4443 /// the corresponding primitive is selected and the routine returns.
4444 
4445 TPad *TPad::Pick(Int_t px, Int_t py, TObjLink *&pickobj)
4446 {
4447  //the two following statements are necessary under NT (multithreaded)
4448  //when a TCanvas object is being created and a thread calling TPad::Pick
4449  //before the TPad constructor has completed in the other thread
4450  if (gPad == 0) return 0; //Andy Haas
4451  if (GetListOfPrimitives() == 0) return 0; //Andy Haas
4452 
4453  Int_t dist;
4454  // Search if point is in pad itself
4455  Double_t x = AbsPixeltoX(px);
4456  Double_t y = AbsPixeltoY(py);
4457  if (this != gPad->GetCanvas()) {
4458  if (!((x >= fX1 && x <= fX2) && (y >= fY1 && y <= fY2))) return 0;
4459  }
4460 
4461  // search for a primitive in this pad or its sub-pads
4462  static TObjOptLink dummyLink(0,""); //place holder for when no link available
4463  TPad *padsav = (TPad*)gPad;
4464  gPad = this; // since no drawing will be done, don't use cd() for efficiency reasons
4465  TPad *pick = 0;
4466  TPad *picked = this;
4467  pickobj = 0;
4468  if (DistancetoPrimitive(px,py) < fgMaxPickDistance) {
4469  dummyLink.SetObject(this);
4470  pickobj = &dummyLink;
4471  }
4472 
4473  // Loop backwards over the list of primitives. The first non-pad primitive
4474  // found is the selected one. However, we have to keep going down the
4475  // list to see if there is maybe a pad overlaying the primitive. In that
4476  // case look into the pad for a possible primitive. Once a pad has been
4477  // found we can terminate the loop.
4478  Bool_t gotPrim = kFALSE; // true if found a non pad primitive
4480 
4481  //We can have 3d stuff in pad. If canvas prefers to draw
4482  //such stuff with OpenGL, the selection of 3d objects is
4483  //a gl viewer business so, in first cycle we do not
4484  //call DistancetoPrimitive for TAtt3D descendants.
4485  //In case of gl we first try to select 2d object first.
4486 
4487  while (lnk) {
4488  TObject *obj = lnk->GetObject();
4489 
4490  //If canvas prefers GL, all 3d objects must be drawn/selected by
4491  //gl viewer
4492  if (obj->InheritsFrom(TAtt3D::Class()) && fEmbeddedGL) {
4493  lnk = lnk->Prev();
4494  continue;
4495  }
4496 
4497  fPadPointer = obj;
4498  if (obj->InheritsFrom(TPad::Class())) {
4499  pick = ((TPad*)obj)->Pick(px, py, pickobj);
4500  if (pick) {
4501  picked = pick;
4502  break;
4503  }
4504  } else if (!gROOT->GetEditorMode()) {
4505  if (!gotPrim) {
4506  if (!obj->TestBit(kCannotPick)) {
4507  dist = obj->DistancetoPrimitive(px, py);
4508  if (dist < fgMaxPickDistance) {
4509  pickobj = lnk;
4510  gotPrim = kTRUE;
4511  if (dist == 0) break;
4512  }
4513  }
4514  }
4515  }
4516 
4517  lnk = lnk->Prev();
4518  }
4519 
4520  //if no primitive found, check if we have a TView
4521  //if yes, return the view except if you are in the lower or upper X range
4522  //of the pad.
4523  //In case canvas prefers gl, fView existence
4524  //automatically means viewer3d existence. (?)
4525 
4526  if (fView && !gotPrim) {
4527  Double_t dx = 0.05*(fUxmax-fUxmin);
4528  if ((x > fUxmin + dx) && (x < fUxmax-dx)) {
4529 
4530  if (fEmbeddedGL) {
4531  //No 2d stuff was selected, but we have gl-viewer. Let it select an object in
4532  //scene (or select itself). In any case it'll internally call
4533  //gPad->SetSelected(ptr) as, for example, hist painter does.
4534  py -= Int_t((1 - GetHNDC() - GetYlowNDC()) * GetWh());
4535  px -= Int_t(GetXlowNDC() * GetWw());
4536  fViewer3D->DistancetoPrimitive(px, py);
4537  }
4538  else
4539  dummyLink.SetObject(fView);
4540  }
4541  }
4542 
4543  if (picked->InheritsFrom(TButton::Class())) {
4544  TButton *button = (TButton*)picked;
4545  if (!button->IsEditable()) pickobj = 0;
4546  }
4547 
4548  if (TestBit(kCannotPick)) {
4549 
4550  if (picked == this) {
4551  // cannot pick pad itself!
4552  picked = 0;
4553  }
4554 
4555  }
4556 
4557  gPad = padsav;
4558  return picked;
4559 }
4560 
4561 ////////////////////////////////////////////////////////////////////////////////
4562 /// Pop pad to the top of the stack.
4563 
4565 {
4566  if (!fMother) return;
4567  if (!fPrimitives) fPrimitives = new TList;
4568  if (this == fMother->GetListOfPrimitives()->Last()) return;
4569 
4571  TObject *obj;
4572  while ((obj = next()))
4573  if (obj == this) {
4574  char *opt = StrDup(next.GetOption());
4576  fMother->GetListOfPrimitives()->AddLast(this, opt);
4577  delete [] opt;
4578  return;
4579  }
4580 }
4581 
4582 ////////////////////////////////////////////////////////////////////////////////
4583 /// Save Pad contents in a file in one of various formats.
4584 ///
4585 /// - if filename is "", the file produced is padname.ps
4586 /// - if filename starts with a dot, the padname is added in front
4587 /// - if filename contains .eps, an Encapsulated Postscript file is produced
4588 /// - if filename contains .gif, a GIF file is produced
4589 /// - if filename contains .gif+NN, an animated GIF file is produced
4590 /// See comments in TASImage::WriteImage for meaning of NN and other
4591 /// .gif suffix variants
4592 /// - if filename contains .C or .cxx, a C++ macro file is produced
4593 /// - if filename contains .root, a Root file is produced
4594 /// - if filename contains .xml, a XML file is produced
4595 /// - if filename contains .json, a JSON file is produced
4596 ///
4597 /// See comments in TPad::SaveAs or the TPad::Print function below
4598 
4599 void TPad::Print(const char *filename) const
4600 {
4601  ((TPad*)this)->SaveAs(filename);
4602 }
4603 
4604 ////////////////////////////////////////////////////////////////////////////////
4605 /// Auxiliary function. Returns kTRUE if list contains an object inherited
4606 /// from TImage
4607 
4609 {
4610  TIter next(li);
4611  TObject *obj;
4612 
4613  while ((obj = next())) {
4614  if (obj->InheritsFrom(TImage::Class())) {
4615  return kTRUE;
4616  } else if (obj->InheritsFrom(TPad::Class())) {
4617  if (ContainsTImage(((TPad*)obj)->GetListOfPrimitives())) {
4618  return kTRUE;
4619  }
4620  }
4621  }
4622  return kFALSE;
4623 }
4624 
4625 ////////////////////////////////////////////////////////////////////////////////
4626 /// Save Canvas contents in a file in one of various formats.
4627 ///
4628 /// option can be:
4629 /// - 0 as "ps"
4630 /// - "ps" Postscript file is produced (see special cases below)
4631 /// - "Portrait" Postscript file is produced (Portrait)
4632 /// - "Landscape" Postscript file is produced (Landscape)
4633 /// - "Title:" The character string after "Title:" becomes a table
4634 /// of content entry (for PDF files).
4635 /// - "eps" an Encapsulated Postscript file is produced
4636 /// - "Preview" an Encapsulated Postscript file with preview is produced.
4637 /// - "pdf" a PDF file is produced
4638 /// - "svg" a SVG file is produced
4639 /// - "tex" a TeX file is produced
4640 /// - "gif" a GIF file is produced
4641 /// - "gif+NN" an animated GIF file is produced, where NN is delay in 10ms units NOTE: See other variants for looping animation in TASImage::WriteImage
4642 /// - "xpm" a XPM file is produced
4643 /// - "png" a PNG file is produced
4644 /// - "jpg" a JPEG file is produced. NOTE: JPEG's lossy compression will make all sharp edges fuzzy.
4645 /// - "tiff" a TIFF file is produced
4646 /// - "cxx" a C++ macro file is produced
4647 /// - "xml" a XML file
4648 /// - "json" a JSON file
4649 /// - "root" a ROOT binary file
4650 ///
4651 /// filename = 0 - filename is defined by the GetName and its
4652 /// extension is defined with the option
4653 ///
4654 /// When Postscript output is selected (ps, eps), the canvas is saved
4655 /// to filename.ps or filename.eps. The aspect ratio of the canvas is preserved
4656 /// on the Postscript file. When the "ps" option is selected, the Postscript
4657 /// page will be landscape format if the canvas is in landscape format, otherwise
4658 /// portrait format is selected.
4659 ///
4660 /// The physical size of the Postscript page is the one selected in the
4661 /// current style. This size can be modified via TStyle::SetPaperSize.
4662 ///
4663 /// Examples:
4664 /// ~~~ {.cpp}
4665 /// gStyle->SetPaperSize(TStyle::kA4); //default
4666 /// gStyle->SetPaperSize(TStyle::kUSLetter);
4667 /// ~~~
4668 /// where TStyle::kA4 and TStyle::kUSLetter are defined in the enum
4669 /// EPaperSize in TStyle.h
4670 ///
4671 /// An alternative is to call:
4672 /// ~~~ {.cpp}
4673 /// gStyle->SetPaperSize(20,26); same as kA4
4674 /// or gStyle->SetPaperSize(20,24); same as kUSLetter
4675 /// ~~~
4676 /// The above numbers take into account some margins and are in centimeters.
4677 ///
4678 /// The "Preview" option allows to generate a preview (in the TIFF format) within
4679 /// the Encapsulated Postscript file. This preview can be used by programs like
4680 /// MSWord to visualize the picture on screen. The "Preview" option relies on the
4681 /// epstool command (http://www.cs.wisc.edu/~ghost/gsview/epstool.htm).
4682 ///
4683 /// Example:
4684 /// ~~~ {.cpp}
4685 /// canvas->Print("example.eps","Preview");
4686 /// ~~~
4687 /// To generate a Postscript file containing more than one picture, see
4688 /// class TPostScript.
4689 ///
4690 /// ### Writing several canvases to the same Postscript or PDF file:
4691 ///
4692 /// - if the Postscript or PDF file name finishes with "(", the file is not closed
4693 /// - if the Postscript or PDF file name finishes with ")" and the file has been opened
4694 /// with "(", the file is closed.
4695 ///
4696 /// Example:
4697 /// ~~~ {.cpp}
4698 /// {
4699 /// TCanvas c1("c1");
4700 /// h1.Draw();
4701 /// c1.Print("c1.ps("); //write canvas and keep the ps file open
4702 /// h2.Draw();
4703 /// c1.Print("c1.ps"); canvas is added to "c1.ps"
4704 /// h3.Draw();
4705 /// c1.Print("c1.ps)"); canvas is added to "c1.ps" and ps file is closed
4706 /// }
4707 /// ~~~
4708 /// In the previous example replacing "ps" by "pdf" will create a multi-pages PDF file.
4709 ///
4710 /// Note that the following sequence writes the canvas to "c1.ps" and closes the ps file.:
4711 /// ~~~ {.cpp}
4712 /// TCanvas c1("c1");
4713 /// h1.Draw();
4714 /// c1.Print("c1.ps");
4715 /// ~~~
4716 /// The TCanvas::Print("file.ps(") mechanism is very useful, but it can be
4717 /// a little inconvenient to have the action of opening/closing a file
4718 /// being atomic with printing a page. Particularly if pages are being
4719 /// generated in some loop one needs to detect the special cases of first
4720 /// and last page and then munge the argument to Print() accordingly.
4721 ///
4722 /// The "[" and "]" can be used instead of "(" and ")".
4723 ///
4724 /// Example:
4725 /// ~~~ {.cpp}
4726 /// c1.Print("file.ps["); // No actual print, just open file.ps
4727 /// for (int i=0; i<10; ++i) {
4728 /// // fill canvas for context i
4729 /// // ...
4730 ///
4731 /// c1.Print("file.ps"); // actually print canvas to file
4732 /// }// end loop
4733 /// c1.Print("file.ps]"); // No actual print, just close.
4734 /// ~~~
4735 /// As before, the same macro is valid for PDF files.
4736 ///
4737 /// It is possible to print a canvas into an animated GIF file by specifying the
4738 /// file name as "myfile.gif+" or "myfile.gif+NN", where NN*10ms is delay
4739 /// between the subimages' display. If NN is omitted the delay between
4740 /// subimages is zero. Each picture is added in the animation thanks to a loop
4741 /// similar to the following one:
4742 /// ~~~ {.cpp}
4743 /// for (int i=0; i<10; ++i) {
4744 /// // fill canvas for context i
4745 /// // ...
4746 ///
4747 /// c1.Print("file.gif+5"); // print canvas to GIF file with 50ms delays
4748 /// }// end loop
4749 /// ~~~
4750 /// The delay between each frame must be specified in each Print() statement.
4751 /// If the file "myfile.gif" already exists, the new frame are appended at
4752 /// the end of the file. To avoid this, delete it first with gSystem->Unlink(myfile.gif);
4753 /// If you want the gif file to repeat or loop forever, check TASImage::WriteImage documentation
4754 
4755 void TPad::Print(const char *filenam, Option_t *option)
4756 {
4757  TString psname, fs1, fs2;
4758  const char *filename;
4759 
4760  // "[" and "]" are special characters for ExpandPathName. When they are at the end
4761  // of the file name (see help) they must be removed before doing ExpandPathName.
4762  fs1 = filenam;
4763  if (fs1.EndsWith("[")) {
4764  fs1.Replace((fs1.Length()-1),1," ");
4765  fs2 = gSystem->ExpandPathName(fs1.Data());
4766  fs2.Replace((fs2.Length()-1),1,"[");
4767  } else if (fs1.EndsWith("]")) {
4768  fs1.Replace((fs1.Length()-1),1," ");
4769  fs2 = gSystem->ExpandPathName(fs1.Data());
4770  fs2.Replace((fs2.Length()-1),1,"]");
4771  } else {
4772  char* exppath = gSystem->ExpandPathName(fs1.Data());
4773  fs2 = exppath;
4774  delete [] exppath;
4775  }
4776  filename = fs2.Data();
4777 
4778  // Set the default option as "Postscript" (Should be a data member of TPad)
4779  const char *opt_default="ps";
4780 
4781  Int_t lenfil = filename ? strlen(filename) : 0;
4782  TString opt = (!option) ? opt_default : option;
4783  Bool_t image = kFALSE;
4784 
4785  if ( !lenfil ) {
4786  psname = GetName();
4787  psname += opt;
4788  } else {
4789  psname = filename;
4790  }
4791 
4792  // lines below protected against case like c1->SaveAs( "../ps/cs.ps" );
4793  if (psname.BeginsWith('.') && (psname.Contains('/') == 0)) {
4794  psname = GetName();
4795  psname.Append(filename);
4796  psname.Prepend("/");
4797  psname.Prepend(gEnv->GetValue("Canvas.PrintDirectory","."));
4798  }
4799  if (!gPad->IsBatch() && fCanvas)
4801 
4802  // Save pad/canvas in alternative formats
4804  if (strstr(opt, "gif+")) {
4805  gtype = TImage::kAnimGif;
4806  image = kTRUE;
4807  } else if (strstr(opt, "gif")) {
4808  gtype = TImage::kGif;
4809  image = kTRUE;
4810  } else if (strstr(opt, "png")) {
4811  gtype = TImage::kPng;
4812  image = kTRUE;
4813  } else if (strstr(opt, "jpg")) {
4814  gtype = TImage::kJpeg;
4815  image = kTRUE;
4816  } else if (strstr(opt, "tiff")) {
4817  gtype = TImage::kTiff;
4818  image = kTRUE;
4819  } else if (strstr(opt, "xpm")) {
4820  gtype = TImage::kXpm;
4821  image = kTRUE;
4822  } else if (strstr(opt, "bmp")) {
4823  gtype = TImage::kBmp;
4824  image = kTRUE;
4825  }
4826 
4827  Int_t wid = 0;
4828  if (!GetCanvas()) return;
4829  if (!gROOT->IsBatch() && image) {
4830  if ((gtype == TImage::kGif) && !ContainsTImage(fPrimitives)) {
4831  wid = (this == GetCanvas()) ? GetCanvas()->GetCanvasID() : GetPixmapID();
4832  Color_t hc = gPad->GetCanvas()->GetHighLightColor();
4833  gPad->GetCanvas()->SetHighLightColor(-1);
4834  gPad->Modified();
4835  gPad->Update();
4836  GetPainter()->SelectDrawable(wid);
4837  GetPainter()->SaveImage(this, psname.Data(), gtype);
4838  if (!gSystem->AccessPathName(psname.Data())) {
4839  Info("Print", "GIF file %s has been created", psname.Data());
4840  }
4841  gPad->GetCanvas()->SetHighLightColor(hc);
4842  return;
4843  }
4844  if (gtype != TImage::kUnknown) {
4845  Color_t hc = gPad->GetCanvas()->GetHighLightColor();
4846  gPad->GetCanvas()->SetHighLightColor(-1);
4847  gPad->Modified();
4848  gPad->Update();
4849  if (gVirtualX->InheritsFrom("TGQt")) {
4850  wid = (this == GetCanvas()) ? GetCanvas()->GetCanvasID() : GetPixmapID();
4851  gVirtualX->WritePixmap(wid,UtoPixel(1.),VtoPixel(0.),(char *)psname.Data());
4852  } else {
4853  Int_t saver = gErrorIgnoreLevel;
4855  gVirtualX->Update(1);
4856  gSystem->Sleep(30); // synchronize
4857  GetPainter()->SaveImage(this, psname, gtype);
4858  gErrorIgnoreLevel = saver;
4859  }
4860  if (!gSystem->AccessPathName(psname)) {
4861  Info("Print", "file %s has been created", psname.Data());
4862  }
4863  gPad->GetCanvas()->SetHighLightColor(hc);
4864  } else {
4865  Warning("Print", "Unsupported image format %s", psname.Data());
4866  }
4867  return;
4868  }
4869 
4870  //==============Save pad/canvas as a C++ script==============================
4871  if (strstr(opt,"cxx")) {
4872  GetCanvas()->SaveSource(psname, "");
4873  return;
4874  }
4875 
4876  //==============Save pad/canvas as a root file===============================
4877  if (strstr(opt,"root")) {
4878  if (gDirectory) gDirectory->SaveObjectAs(this,psname.Data(),"");
4879  return;
4880  }
4881 
4882  //==============Save pad/canvas as a XML file================================
4883  if (strstr(opt,"xml")) {
4884  // Plugin XML driver
4885  if (gDirectory) gDirectory->SaveObjectAs(this,psname.Data(),"");
4886  return;
4887  }
4888 
4889  //==============Save pad/canvas as a JSON file================================
4890  if (strstr(opt,"json")) {
4891  if (gDirectory) gDirectory->SaveObjectAs(this,psname.Data(),"");
4892  return;
4893  }
4894 
4895  //==============Save pad/canvas as a SVG file================================
4896  if (strstr(opt,"svg")) {
4897  gVirtualPS = (TVirtualPS*)gROOT->GetListOfSpecials()->FindObject(psname);
4898 
4899  Bool_t noScreen = kFALSE;
4900  if (!GetCanvas()->IsBatch() && GetCanvas()->GetCanvasID() == -1) {
4901  noScreen = kTRUE;
4902  GetCanvas()->SetBatch(kTRUE);
4903  }
4904 
4905  TPad *padsav = (TPad*)gPad;
4906  cd();
4907 
4908  if (!gVirtualPS) {
4909  // Plugin Postscript/SVG driver
4910  TPluginHandler *h;
4911  if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualPS", "svg"))) {
4912  if (h->LoadPlugin() == -1)
4913  return;
4914  h->ExecPlugin(0);
4915  }
4916  }
4917 
4918  // Create a new SVG file
4919  if (gVirtualPS) {
4920  gVirtualPS->SetName(psname);
4921  gVirtualPS->Open(psname);
4923  gVirtualPS->NewPage();
4924  }
4925  Paint();
4926  if (noScreen) GetCanvas()->SetBatch(kFALSE);
4927 
4928  if (!gSystem->AccessPathName(psname)) Info("Print", "SVG file %s has been created", psname.Data());
4929 
4930  delete gVirtualPS;
4931  gVirtualPS = 0;
4932  padsav->cd();
4933 
4934  return;
4935  }
4936 
4937  //==============Save pad/canvas as a TeX file================================
4938  if (strstr(opt,"tex")) {
4939  gVirtualPS = (TVirtualPS*)gROOT->GetListOfSpecials()->FindObject(psname);
4940 
4941  Bool_t noScreen = kFALSE;
4942  if (!GetCanvas()->IsBatch() && GetCanvas()->GetCanvasID() == -1) {
4943  noScreen = kTRUE;
4944  GetCanvas()->SetBatch(kTRUE);
4945  }
4946 
4947  TPad *padsav = (TPad*)gPad;
4948  cd();
4949 
4950  if (!gVirtualPS) {
4951  // Plugin Postscript/SVG driver
4952  TPluginHandler *h;
4953  if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualPS", "tex"))) {
4954  if (h->LoadPlugin() == -1)
4955  return;
4956  h->ExecPlugin(0);
4957  }
4958  }
4959 
4960  // Create a new TeX file
4961  if (gVirtualPS) {
4962  gVirtualPS->SetName(psname);
4963  gVirtualPS->Open(psname);
4965  gVirtualPS->NewPage();
4966  }
4967  Paint();
4968  if (noScreen) GetCanvas()->SetBatch(kFALSE);
4969 
4970  if (!gSystem->AccessPathName(psname)) Info("Print", "TeX file %s has been created", psname.Data());
4971 
4972  delete gVirtualPS;
4973  gVirtualPS = 0;
4974  padsav->cd();
4975 
4976  return;
4977  }
4978 
4979  //==============Save pad/canvas as a Postscript file=========================
4980 
4981  // in case we read directly from a Root file and the canvas
4982  // is not on the screen, set batch mode
4983 
4984  Bool_t mustOpen = kTRUE;
4985  Bool_t mustClose = kTRUE;
4986  Bool_t copen=kFALSE, cclose=kFALSE, copenb=kFALSE, ccloseb=kFALSE;
4987  if (!image) {
4988  // The parenthesis mechanism is only valid for PS and PDF files.
4989  copen = psname.EndsWith("("); if (copen) psname[psname.Length()-1] = 0;
4990  cclose = psname.EndsWith(")"); if (cclose) psname[psname.Length()-1] = 0;
4991  copenb = psname.EndsWith("["); if (copenb) psname[psname.Length()-1] = 0;
4992  ccloseb = psname.EndsWith("]"); if (ccloseb) psname[psname.Length()-1] = 0;
4993  }
4994  gVirtualPS = (TVirtualPS*)gROOT->GetListOfSpecials()->FindObject(psname);
4995  if (gVirtualPS) {mustOpen = kFALSE; mustClose = kFALSE;}
4996  if (copen || copenb) mustClose = kFALSE;
4997  if (cclose || ccloseb) mustClose = kTRUE;
4998 
4999  Bool_t noScreen = kFALSE;
5000  if (!GetCanvas()->IsBatch() && GetCanvas()->GetCanvasID() == -1) {
5001  noScreen = kTRUE;
5002  GetCanvas()->SetBatch(kTRUE);
5003  }
5004  Int_t pstype = 111;
5005  Double_t xcanvas = GetCanvas()->XtoPixel(GetCanvas()->GetX2());
5006  Double_t ycanvas = GetCanvas()->YtoPixel(GetCanvas()->GetY1());
5007  Double_t ratio = ycanvas/xcanvas;
5008  if (ratio < 1) pstype = 112;
5009  if (strstr(opt,"Portrait")) pstype = 111;
5010  if (strstr(opt,"Landscape")) pstype = 112;
5011  if (strstr(opt,"eps")) pstype = 113;
5012  if (strstr(opt,"Preview")) pstype = 113;
5013  TPad *padsav = (TPad*)gPad;
5014  cd();
5015  TVirtualPS *psave = gVirtualPS;
5016 
5017  if (!gVirtualPS || mustOpen) {
5018  // Plugin Postscript driver
5019  TPluginHandler *h;
5020  if (strstr(opt,"pdf") || strstr(opt,"Title:")) {
5021  if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualPS", "pdf"))) {
5022  if (h->LoadPlugin() == -1) return;
5023  h->ExecPlugin(0);
5024  }
5025  } else if (image) {
5026  // Plugin TImageDump driver
5027  if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualPS", "image"))) {
5028  if (h->LoadPlugin() == -1) return;
5029  h->ExecPlugin(0);
5030  }
5031  } else {
5032  if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualPS", "ps"))) {
5033  if (h->LoadPlugin() == -1) return;
5034  h->ExecPlugin(0);
5035  }
5036  }
5037 
5038  // Create a new Postscript, PDF or image file
5039  if (gVirtualPS) gVirtualPS->SetName(psname);
5040  const Ssiz_t titlePos = opt.Index("Title:");
5041  if (titlePos != kNPOS) {
5042  if (gVirtualPS) gVirtualPS->SetTitle(opt.Data()+titlePos+6);
5043  opt.Replace(titlePos,opt.Length(),"pdf");
5044  }
5045  if (gVirtualPS) gVirtualPS->Open(psname,pstype);
5047  if (!copenb) {
5048  if (!strstr(opt,"pdf") || image) {
5049  if (gVirtualPS) gVirtualPS->NewPage();
5050  }
5051  Paint();
5052  }
5053  if (noScreen) GetCanvas()->SetBatch(kFALSE);
5054 
5055  if (mustClose) {
5056  gROOT->GetListOfSpecials()->Remove(gVirtualPS);
5057  delete gVirtualPS;
5058  gVirtualPS = psave;
5059  } else {
5060  gROOT->GetListOfSpecials()->Add(gVirtualPS);
5061  gVirtualPS = 0;
5062  }
5063 
5064  if (!gSystem->AccessPathName(psname)) {
5065  if (!copen) Info("Print", "%s file %s has been created", opt.Data(), psname.Data());
5066  else Info("Print", "%s file %s has been created using the current canvas", opt.Data(), psname.Data());
5067  }
5068  } else {
5069  // Append to existing Postscript, PDF or GIF file
5070  if (!ccloseb) {
5071  gVirtualPS->NewPage();
5072  Paint();
5073  }
5074  const Ssiz_t titlePos = opt.Index("Title:");
5075  if (titlePos != kNPOS) {
5076  gVirtualPS->SetTitle(opt.Data()+titlePos+6);
5077  opt.Replace(titlePos,opt.Length(),"pdf");
5078  } else {
5079  gVirtualPS->SetTitle("PDF");
5080  }
5081  if (mustClose) {
5082  if (cclose) Info("Print", "Current canvas added to %s file %s and file closed", opt.Data(), psname.Data());
5083  else Info("Print", "%s file %s has been closed", opt.Data(), psname.Data());
5084  gROOT->GetListOfSpecials()->Remove(gVirtualPS);
5085  delete gVirtualPS;
5086  gVirtualPS = 0;
5087  } else {
5088  Info("Print", "Current canvas added to %s file %s", opt.Data(), psname.Data());
5089  gVirtualPS = 0;
5090  }
5091  }
5092 
5093  if (strstr(opt,"Preview")) gSystem->Exec(Form("epstool --quiet -t6p %s %s",psname.Data(),psname.Data()));
5094 
5095  padsav->cd();
5096 }
5097 
5098 ////////////////////////////////////////////////////////////////////////////////
5099 /// Set world coordinate system for the pad.
5100 /// Emits signal "RangeChanged()", in the slot get the range
5101 /// via GetRange().
5102 
5104 {
5105  if ((x1 >= x2) || (y1 >= y2)) {
5106  Error("Range", "illegal world coordinates range: x1=%f, y1=%f, x2=%f, y2=%f",x1,y1,x2,y2);
5107  return;
5108  }
5109 
5110  fUxmin = x1;
5111  fUxmax = x2;
5112  fUymin = y1;
5113  fUymax = y2;
5114 
5115  if (fX1 == x1 && fY1 == y1 && fX2 == x2 && fY2 == y2) return;
5116 
5117  fX1 = x1;
5118  fY1 = y1;
5119  fX2 = x2;
5120  fY2 = y2;
5121 
5122  // compute pad conversion coefficients
5123  ResizePad();
5124 
5125  if (gPad == this)
5126  GetPainter()->InvalidateCS();
5127 
5128  // emit signal
5129  RangeChanged();
5130 }
5131 
5132 ////////////////////////////////////////////////////////////////////////////////
5133 /// Set axis coordinate system for the pad.
5134 /// The axis coordinate system is a subset of the world coordinate system
5135 /// xmin,ymin is the origin of the current coordinate system,
5136 /// xmax is the end of the X axis, ymax is the end of the Y axis.
5137 /// By default a margin of 10 per cent is left on all sides of the pad
5138 /// Emits signal "RangeAxisChanged()", in the slot get the axis range
5139 /// via GetRangeAxis().
5140 
5142 {
5143  if ((xmin >= xmax) || (ymin >= ymax)) {
5144  Error("RangeAxis", "illegal axis coordinates range: xmin=%f, ymin=%f, xmax=%f, ymax=%f",
5145  xmin, ymin, xmax, ymax);
5146  return;
5147  }
5148 
5149  fUxmin = xmin;
5150  fUymin = ymin;
5151  fUxmax = xmax;
5152  fUymax = ymax;
5153 
5154  // emit signal
5155  RangeAxisChanged();
5156 }
5157 
5158 ////////////////////////////////////////////////////////////////////////////////
5159 /// Recursively remove object from a pad and its sub-pads.
5160 
5162 {
5163  if (obj == fCanvas->GetSelected()) fCanvas->SetSelected(0);
5164  if (obj == fCanvas->GetClickSelected()) fCanvas->SetClickSelected(0);
5165  if (obj == fView) fView = 0;
5166  if (!fPrimitives) return;
5167  Int_t nold = fPrimitives->GetSize();
5169  if (nold != fPrimitives->GetSize()) fModified = kTRUE;
5170 }
5171 
5172 ////////////////////////////////////////////////////////////////////////////////
5173 /// Redraw the frame axis
5174 /// Redrawing axis may be necessary in case of superimposed histograms
5175 /// when one or more histograms have a fill color
5176 /// Instead of calling this function, it may be more convenient
5177 /// to call directly h1->Draw("sameaxis") where h1 is the pointer
5178 /// to the first histogram drawn in the pad.
5179 ///
5180 /// By default, if the pad has the options gridx or/and gridy activated,
5181 /// the grid is not drawn by this function.
5182 /// if option="g" is specified, this will force the drawing of the grid
5183 /// on top of the picture
5184 
5186 {
5187  // get first histogram in the list of primitives
5188  TString opt = option;
5189  opt.ToLower();
5190 
5191  TPad *padsav = (TPad*)gPad;
5192  cd();
5193 
5194  if (!fPrimitives) fPrimitives = new TList;
5195  TIter next(fPrimitives);
5196  TObject *obj;
5197  while ((obj = next())) {
5198  if (obj->InheritsFrom(TH1::Class())) {
5199  TH1 *hobj = (TH1*)obj;
5200  if (opt.Contains("g")) hobj->DrawCopy("sameaxig");
5201  else hobj->DrawCopy("sameaxis");
5202  return;
5203  }
5204  if (obj->InheritsFrom(TMultiGraph::Class())) {
5205  TMultiGraph *mg = (TMultiGraph*)obj;
5206  if (mg) {
5207  TH1F *h1f = mg->GetHistogram();
5208  if (h1f) h1f->DrawCopy("sameaxis");
5209  }
5210  return;
5211  }
5212  if (obj->InheritsFrom(TGraph::Class())) {
5213  TGraph *g = (TGraph*)obj;
5214  if (g) g->GetHistogram()->DrawCopy("sameaxis");
5215  return;
5216  }
5217  if (obj->InheritsFrom(THStack::Class())) {
5218  THStack *hs = (THStack*)obj;
5219  if (hs) {
5220  TH1 *h1 = hs->GetHistogram();
5221  if (h1) h1->DrawCopy("sameaxis");
5222  }
5223  return;
5224  }
5225  }
5226 
5227  if (padsav) padsav->cd();
5228 }
5229 
5230 ////////////////////////////////////////////////////////////////////////////////
5231 /// Compute pad conversion coefficients.
5232 ///
5233 /// ### Conversion from x to px
5234 ///
5235 /// \f[\frac{x-xmin}{xrange} = \frac{px-pxlow}{pxrange}\f]
5236 /// with:
5237 /// \f[ xrange = xmax-xmin \f]
5238 /// \f[ pxrange = pxmax-pxmin \f]
5239 ///
5240 /// \f[
5241 /// \Rightarrow px = \frac{pxrange(x-xmin)}{xrange} + pxlow = fXtoPixelk + fXtoPixel \times x
5242 /// \f]
5243 ///
5244 /// \f[
5245 /// \Rightarrow fXtoPixelk = pxlow - pxrange \frac{xmin}{xrange}
5246 /// \f]
5247 /// \f[
5248 /// fXtoPixel = \frac{pxrange}{xrange}
5249 /// \f]
5250 /// where:
5251 /// \f[
5252 /// pxlow = fAbsXlowNDC \times fCw
5253 /// \f]
5254 /// \f[
5255 /// pxrange = fAbsWNDC \times fCw
5256 /// \f]
5257 ///
5258 /// ### Conversion from y to py
5259 ///
5260 /// \f[\frac{y-ymin}{yrange} = \frac{py-pylow}{pyrange}\f]
5261 /// with:
5262 /// \f[ yrange = ymax-ymin \f]
5263 /// \f[ pyrange = pymax-pymin \f]
5264 ///
5265 /// \f[
5266 /// \Rightarrow py = \frac{pyrange(y-xmin)}{yrange} + pylow = fYtoPixelk + fYtoPixel \times y
5267 /// \f]
5268 ///
5269 /// \f[
5270 /// \Rightarrow fYtoPixelk = pylow - pyrange \frac{ymin}{yrange}
5271 /// \f]
5272 /// \f[
5273 /// fYtoPixel = \frac{pyrange}{yrange}
5274 /// \f]
5275 /// where:
5276 /// \f[
5277 /// pylow = fAbsYlowNDC \times fCh
5278 /// \f]
5279 /// \f[
5280 /// pyrange = fAbsHNDC \times fCh
5281 /// \f]
5282 ///
5283 /// ### Conversion from px to x
5284 ///
5285 /// \f[
5286 /// \Rightarrow x = \frac{xrange(px-pxlow)}{pxrange}+ xmin = fPixeltoXk + fPixeltoX \times px
5287 /// \f]
5288 ///
5289 /// \f[
5290 /// \Rightarrow fPixeltoXk = xmin - pxlow \times\frac{xrange}{pxrange}
5291 /// \f]
5292 /// \f[
5293 /// fPixeltoX = \frac{xrange}{pxrange}
5294 /// \f]
5295 ///
5296 /// ### Conversion from py to y
5297 ///
5298 /// \f[
5299 /// \Rightarrow y = \frac{yrange(py-pylow)}{pyrange}+ ymin = fPixeltoYk + fPixeltoY \times py
5300 /// \f]
5301 ///
5302 /// \f[
5303 /// \Rightarrow fPixeltoYk = ymin - pylow \times\frac{yrange}{pyrange}
5304 /// \f]
5305 /// \f[
5306 /// fPixeltoY = \frac{yrange}{pyrange}
5307 /// \f]
5308 ///
5309 /// ### Computation of the coefficients in case of LOG scales
5310 ///
5311 /// #### Conversion from pixel coordinates to world coordinates
5312 ///
5313 /// \f[
5314 /// u = \frac{Log(x) - Log(xmin)}{Log(xmax) - Log(xmin)} = \frac{Log(x/xmin)}{Log(xmax/xmin)} = \frac{px - pxlow}{pxrange}
5315 /// \f]
5316 ///
5317 /// \f[ \Rightarrow Log(\frac{x}{xmin}) = u \times Log(\frac{xmax}{xmin}) \f]
5318 /// \f[ x = xmin \times e^{(u \times Log(\frac{xmax}{xmin})} \f]
5319 /// Let:
5320 /// \f[ alfa = \frac{Log(\frac{xmax}{xmin})}{fAbsWNDC} \f]
5321 ///
5322 /// \f[ x = xmin \times e^{(-alfa \times pxlow)} + e^{(alfa \times px)} \f]
5323 /// \f[ x = fPixeltoXk \times e^{(fPixeltoX \times px)} \f]
5324 /// \f[ ==> fPixeltoXk = xmin \times e^{(-alfa*pxlow)} \f]
5325 /// \f[ fPixeltoX = alfa \f]
5326 ///
5327 /// \f[
5328 /// v = \frac{Log(y) - Log(ymin)}{Log(ymax) - Log(ymin)} = \frac{Log(y/ymin)}{Log(ymax/ymin)} = \frac{py - pylow}{pyrange}
5329 /// \f]
5330 /// Let:
5331 /// \f[ beta = Log(\frac{ymax}{ymin}) \f]
5332 /// \f[ Log(\frac{y}{ymin}) = beta \times pylow - beta \times py \f]
5333 /// \f[ \frac{y}{ymin} = e^{(beta \times pylow - beta \times py)} \f]
5334 /// \f[ y = ymin \times e^{(beta \times pylow)} \times e^{(-beta \times py)}\f]
5335 /// \f[ \Rightarrow y = fPixeltoYk \times e^{(fPixeltoY \times py)} \f]
5336 /// \f[ fPixeltoYk = ymin \times e^{(beta \times pylow)} \f]
5337 /// \f[ fPixeltoY = -beta \f]
5338 ///
5339 /// #### Conversion from World coordinates to pixel coordinates
5340 ///
5341 /// \f[ px = pxlow + u*pxrange \f]
5342 /// \f[ = pxlow + Log(x/xmin)/alfa \f]
5343 /// \f[ = pxlow -Log(xmin)/alfa + Log(x)/alfa \f]
5344 /// \f[ = fXtoPixelk + fXtoPixel*Log(x) \f]
5345 /// \f[ \Rightarrow fXtoPixelk = pxlow -Log(xmin)/alfa \f]
5346 /// \f[ \Rightarrow fXtoPixel = 1/alfa \f]
5347 ///
5348 /// \f[ py = pylow - Log(y/ymin)/beta \f]
5349 /// \f[ = fYtoPixelk + fYtoPixel*Log(y) \f]
5350 /// \f[ \Rightarrow fYtoPixelk = pylow - Log(ymin)/beta \f]
5351 /// \f[ fYtoPixel = 1/beta \f]
5352 
5354 {
5355  // Recompute subpad positions in case pad has been moved/resized
5356  TPad *parent = fMother;
5357  if (this == gPad->GetCanvas()) {
5360  fAbsWNDC = fWNDC;
5361  fAbsHNDC = fHNDC;
5362  }
5363  else {
5364  fAbsXlowNDC = fXlowNDC*parent->GetAbsWNDC() + parent->GetAbsXlowNDC();
5365  fAbsYlowNDC = fYlowNDC*parent->GetAbsHNDC() + parent->GetAbsYlowNDC();
5366  fAbsWNDC = fWNDC*parent->GetAbsWNDC();
5367  fAbsHNDC = fHNDC*parent->GetAbsHNDC();
5368  }
5369 
5370  Double_t ww = (Double_t)gPad->GetWw();
5371  Double_t wh = (Double_t)gPad->GetWh();
5372  Double_t pxlow = fAbsXlowNDC*ww;
5373  Double_t pylow = (1-fAbsYlowNDC)*wh;
5374  Double_t pxrange = fAbsWNDC*ww;
5375  Double_t pyrange = -fAbsHNDC*wh;
5376 
5377  // Linear X axis
5378  Double_t rounding = 0.00005;
5379  Double_t xrange = fX2 - fX1;
5380  fXtoAbsPixelk = rounding + pxlow - pxrange*fX1/xrange; //origin at left
5381  fXtoPixelk = rounding + -pxrange*fX1/xrange;
5382  fXtoPixel = pxrange/xrange;
5383  fAbsPixeltoXk = fX1 - pxlow*xrange/pxrange;
5384  fPixeltoXk = fX1;
5385  fPixeltoX = xrange/pxrange;
5386  // Linear Y axis
5387  Double_t yrange = fY2 - fY1;
5388  fYtoAbsPixelk = rounding + pylow - pyrange*fY1/yrange; //origin at top
5389  fYtoPixelk = rounding + -pyrange - pyrange*fY1/yrange;
5390  fYtoPixel = pyrange/yrange;
5391  fAbsPixeltoYk = fY1 - pylow*yrange/pyrange;
5392  fPixeltoYk = fY1;
5393  fPixeltoY = yrange/pyrange;
5394 
5395  // Coefficients to convert from pad NDC coordinates to pixel coordinates
5396 
5397  fUtoAbsPixelk = rounding + pxlow;
5398  fUtoPixelk = rounding;
5399  fUtoPixel = pxrange;
5400  fVtoAbsPixelk = rounding + pylow;
5401  fVtoPixelk = -pyrange;
5402  fVtoPixel = pyrange;
5403 
5404  // Coefficients to convert from canvas pixels to pad world coordinates
5405 
5406  // Resize all sub-pads
5407  TObject *obj;
5408  if (!fPrimitives) fPrimitives = new TList;
5409  TIter next(GetListOfPrimitives());
5410  while ((obj = next())) {
5411  if (obj->InheritsFrom(TPad::Class()))
5412  ((TPad*)obj)->ResizePad(option);
5413  }
5414 
5415  // Reset all current sizes
5416  if (gPad->IsBatch())
5417  fPixmapID = 0;
5418  else {
5419  GetPainter()->SetLineWidth(-1);
5420  GetPainter()->SetTextSize(-1);
5421 
5422  // create or re-create off-screen pixmap
5423  if (fPixmapID) {
5424  int w = TMath::Abs(XtoPixel(fX2) - XtoPixel(fX1));
5425  int h = TMath::Abs(YtoPixel(fY2) - YtoPixel(fY1));
5426  //protection in case of wrong pad parameters.
5427  //without this protection, the OpenPixmap or ResizePixmap crashes with
5428  //the message "Error in <RootX11ErrorHandler>: BadValue (integer parameter out of range for operation)"
5429  //resulting in a frozen xterm
5430  if ( !(TMath::Finite(fX1)) || !(TMath::Finite(fX2))
5431  || !(TMath::Finite(fY1)) || !(TMath::Finite(fY2))
5432  || (TMath::IsNaN(fX1)) || (TMath::IsNaN(fX2))
5433  || (TMath::IsNaN(fY1)) || (TMath::IsNaN(fY2)))
5434  Warning("ResizePad", "Inf/NaN propagated to the pad. Check drawn objects.");
5435  if (w <= 0 || w > 10000) {
5436  Warning("ResizePad", "%s width changed from %d to %d\n",GetName(),w,10);
5437  w = 10;
5438  }
5439  if (h <= 0 || h > 10000) {
5440  Warning("ResizePad", "%s height changed from %d to %d\n",GetName(),h,10);
5441  h = 10;
5442  }
5443  if (fPixmapID == -1) { // this case is handled via the ctor
5444  fPixmapID = GetPainter()->CreateDrawable(w, h);
5445  } else {
5446  if (gVirtualX->ResizePixmap(fPixmapID, w, h)) {
5447  Resized();
5448  Modified(kTRUE);
5449  }
5450  }
5451  }
5452  }
5453  if (fView) {
5454  TPad *padsav = (TPad*)gPad;
5455  if (padsav == this) {
5456  fView->ResizePad();
5457  } else {
5458  cd();
5459  fView->ResizePad();
5460  padsav->cd();
5461  }
5462  }
5463 }
5464 
5465 ////////////////////////////////////////////////////////////////////////////////
5466 /// Save Pad contents in a file in one of various formats.
5467 ///
5468 /// - if filename is "", the file produced is padname.ps
5469 /// - if filename starts with a dot, the padname is added in front
5470 /// - if filename contains .eps, an Encapsulated Postscript file is produced
5471 /// - if filename contains .pdf, a PDF file is produced
5472 /// - if filename contains .svg, a SVG file is produced
5473 /// - if filename contains .tex, a TeX file is produced
5474 /// - if filename contains .gif, a GIF file is produced
5475 /// - if filename contains .gif+NN, an animated GIF file is produced See comments in TASImage::WriteImage for meaning of NN and other .gif sufix variants
5476 /// - if filename contains .xpm, a XPM file is produced
5477 /// - if filename contains .png, a PNG file is produced
5478 /// - if filename contains .jpg, a JPEG file is produced NOTE: JPEG's lossy compression will make all sharp edges fuzzy.
5479 /// - if filename contains .tiff, a TIFF file is produced
5480 /// - if filename contains .C or .cxx, a C++ macro file is produced
5481 /// - if filename contains .root, a Root file is produced
5482 /// - if filename contains .xml, a XML file is produced
5483 ///
5484 /// See comments in TPad::Print for the Postscript formats
5485 
5486 void TPad::SaveAs(const char *filename, Option_t * /*option*/) const
5487 {
5488  TString psname;
5489  Int_t lenfil = filename ? strlen(filename) : 0;
5490 
5491  if (!lenfil) { psname = GetName(); psname.Append(".ps"); }
5492  else psname = filename;
5493 
5494  // lines below protected against case like c1->SaveAs( "../ps/cs.ps" );
5495  if (psname.BeginsWith('.') && (psname.Contains('/') == 0)) {
5496  psname = GetName();
5497  psname.Append(filename);
5498  psname.Prepend("/");
5499  psname.Prepend(gEnv->GetValue("Canvas.PrintDirectory","."));
5500  }
5501 
5502  if (psname.EndsWith(".gif"))
5503  ((TPad*)this)->Print(psname,"gif");
5504  else if (psname.Contains(".gif+"))
5505  ((TPad*)this)->Print(psname,"gif+");
5506  else if (psname.EndsWith(".C") || psname.EndsWith(".cxx") || psname.EndsWith(".cpp"))
5507  ((TPad*)this)->Print(psname,"cxx");
5508  else if (psname.EndsWith(".root"))
5509  ((TPad*)this)->Print(psname,"root");
5510  else if (psname.EndsWith(".xml"))
5511  ((TPad*)this)->Print(psname,"xml");
5512  else if (psname.EndsWith(".json"))
5513  ((TPad*)this)->Print(psname,"json");
5514  else if (psname.EndsWith(".eps"))
5515  ((TPad*)this)->Print(psname,"eps");
5516  else if (psname.EndsWith(".pdf"))
5517  ((TPad*)this)->Print(psname,"pdf");
5518  else if (psname.EndsWith(".pdf["))
5519  ((TPad*)this)->Print(psname,"pdf");
5520  else if (psname.EndsWith(".pdf]"))
5521  ((TPad*)this)->Print(psname,"pdf");
5522  else if (psname.EndsWith(".pdf("))
5523  ((TPad*)this)->Print(psname,"pdf");
5524  else if (psname.EndsWith(".pdf)"))
5525  ((TPad*)this)->Print(psname,"pdf");
5526  else if (psname.EndsWith(".svg"))
5527  ((TPad*)this)->Print(psname,"svg");
5528  else if (psname.EndsWith(".tex"))
5529  ((TPad*)this)->Print(psname,"tex");
5530  else if (psname.EndsWith(".xpm"))
5531  ((TPad*)this)->Print(psname,"xpm");
5532  else if (psname.EndsWith(".png"))
5533  ((TPad*)this)->Print(psname,"png");
5534  else if (psname.EndsWith(".jpg"))
5535  ((TPad*)this)->Print(psname,"jpg");
5536  else if (psname.EndsWith(".jpeg"))
5537  ((TPad*)this)->Print(psname,"jpg");
5538  else if (psname.EndsWith(".bmp"))
5539  ((TPad*)this)->Print(psname,"bmp");
5540  else if (psname.EndsWith(".tiff"))
5541  ((TPad*)this)->Print(psname,"tiff");
5542  else
5543  ((TPad*)this)->Print(psname,"ps");
5544 }
5545 
5546 ////////////////////////////////////////////////////////////////////////////////
5547 /// Save primitives in this pad on the C++ source file out.
5548 
5549 void TPad::SavePrimitive(std::ostream &out, Option_t * /*= ""*/)
5550 {
5551  TPad *padsav = (TPad*)gPad;
5552  gPad = this;
5553  char quote='"';
5554  char lcname[10];
5555  const char *cname = GetName();
5556  Int_t nch = strlen(cname);
5557  if (nch < 10) {
5558  strlcpy(lcname,cname,10);
5559  for (Int_t k=1;k<=nch;k++) {if (lcname[nch-k] == ' ') lcname[nch-k] = 0;}
5560  if (lcname[0] == 0) {
5561  if (this == gPad->GetCanvas()) {strlcpy(lcname,"c1",10); nch = 2;}
5562  else {strlcpy(lcname,"pad",10); nch = 3;}
5563  }
5564  cname = lcname;
5565  }
5566 
5567  // Write pad parameters
5568  if (this != gPad->GetCanvas()) {
5569  out <<" "<<std::endl;
5570  out <<"// ------------>Primitives in pad: "<<GetName()<<std::endl;
5571 
5572  out<<" TPad *"<<cname<<" = new TPad("<<quote<<GetName()<<quote<<", "<<quote<<GetTitle()
5573  <<quote
5574  <<","<<fXlowNDC
5575  <<","<<fYlowNDC
5576  <<","<<fXlowNDC+fWNDC
5577  <<","<<fYlowNDC+fHNDC
5578  <<");"<<std::endl;
5579  out<<" "<<cname<<"->Draw();"<<std::endl;
5580  out<<" "<<cname<<"->cd();"<<std::endl;
5581  }
5582  out<<" "<<cname<<"->Range("<<fX1<<","<<fY1<<","<<fX2<<","<<fY2<<");"<<std::endl;
5583  TView *view = GetView();
5584  Double_t rmin[3], rmax[3];
5585  if (view) {
5586  view->GetRange(rmin, rmax);
5587  static Int_t viewNumber = 0;
5588  out<<" TView *view"<<++viewNumber<<" = TView::CreateView(1);"<<std::endl;
5589  out<<" view"<<viewNumber<<"->SetRange("<<rmin[0]<<","<<rmin[1]<<","<<rmin[2]<<","
5590  <<rmax[0]<<","<<rmax[1]<<","<<rmax[2]<<");"<<std::endl;
5591  }
5592  if (GetFillColor() != 19) {
5593  if (GetFillColor() > 228) {
5595  out<<" "<<cname<<"->SetFillColor(ci);" << std::endl;
5596  } else
5597  out<<" "<<cname<<"->SetFillColor("<<GetFillColor()<<");"<<std::endl;
5598  }
5599  if (GetFillStyle() != 1001) {
5600  out<<" "<<cname<<"->SetFillStyle("<<GetFillStyle()<<");"<<std::endl;
5601  }
5602  if (GetBorderMode() != 1) {
5603  out<<" "<<cname<<"->SetBorderMode("<<GetBorderMode()<<");"<<std::endl;
5604  }
5605  if (GetBorderSize() != 4) {
5606  out<<" "<<cname<<"->SetBorderSize("<<GetBorderSize()<<");"<<std::endl;
5607  }
5608  if (GetLogx()) {
5609  out<<" "<<cname<<"->SetLogx();"<<std::endl;
5610  }
5611  if (GetLogy()) {
5612  out<<" "<<cname<<"->SetLogy();"<<std::endl;
5613  }
5614  if (GetLogz()) {
5615  out<<" "<<cname<<"->SetLogz();"<<std::endl;
5616  }
5617  if (GetGridx()) {
5618  out<<" "<<cname<<"->SetGridx();"<<std::endl;
5619  }
5620  if (GetGridy()) {
5621  out<<" "<<cname<<"->SetGridy();"<<std::endl;
5622  }
5623  if (GetTickx()) {
5624  out<<" "<<cname<<"->SetTickx("<<GetTickx()<<");"<<std::endl;
5625  }
5626  if (GetTicky()) {
5627  out<<" "<<cname<<"->SetTicky("<<GetTicky()<<");"<<std::endl;
5628  }
5629  if (GetTheta() != 30) {
5630  out<<" "<<cname<<"->SetTheta("<<GetTheta()<<");"<<std::endl;
5631  }
5632  if (GetPhi() != 30) {
5633  out<<" "<<cname<<"->SetPhi("<<GetPhi()<<");"<<std::endl;
5634  }
5635  if (TMath::Abs(fLeftMargin-0.1) > 0.01) {
5636  out<<" "<<cname<<"->SetLeftMargin("<<GetLeftMargin()<<");"<<std::endl;
5637  }
5638  if (TMath::Abs(fRightMargin-0.1) > 0.01) {
5639  out<<" "<<cname<<"->SetRightMargin("<<GetRightMargin()<<");"<<std::endl;
5640  }
5641  if (TMath::Abs(fTopMargin-0.1) > 0.01) {
5642  out<<" "<<cname<<"->SetTopMargin("<<GetTopMargin()<<");"<<std::endl;
5643  }
5644  if (TMath::Abs(fBottomMargin-0.1) > 0.01) {
5645  out<<" "<<cname<<"->SetBottomMargin("<<GetBottomMargin()<<");"<<std::endl;
5646  }
5647 
5648  if (GetFrameFillColor() != GetFillColor()) {
5649  if (GetFrameFillColor() > 228) {
5651  out<<" "<<cname<<"->SetFrameFillColor(ci);" << std::endl;
5652  } else
5653  out<<" "<<cname<<"->SetFrameFillColor("<<GetFrameFillColor()<<");"<<std::endl;
5654  }
5655  if (GetFrameFillStyle() != 1001) {
5656  out<<" "<<cname<<"->SetFrameFillStyle("<<GetFrameFillStyle()<<");"<<std::endl;
5657  }
5658  if (GetFrameLineStyle() != 1) {
5659  out<<" "<<cname<<"->SetFrameLineStyle("<<GetFrameLineStyle()<<");"<<std::endl;
5660  }
5661  if (GetFrameLineColor() != 1) {
5662  if (GetFrameLineColor() > 228) {
5664  out<<" "<<cname<<"->SetFrameLineColor(ci);" << std::endl;
5665  } else
5666  out<<" "<<cname<<"->SetFrameLineColor("<<GetFrameLineColor()<<");"<<std::endl;
5667  }
5668  if (GetFrameLineWidth() != 1) {
5669  out<<" "<<cname<<"->SetFrameLineWidth("<<GetFrameLineWidth()<<");"<<std::endl;
5670  }
5671  if (GetFrameBorderMode() != 1) {
5672  out<<" "<<cname<<"->SetFrameBorderMode("<<GetFrameBorderMode()<<");"<<std::endl;
5673  }
5674  if (GetFrameBorderSize() != 1) {
5675  out<<" "<<cname<<"->SetFrameBorderSize("<<GetFrameBorderSize()<<");"<<std::endl;
5676  }
5677 
5678  TFrame *frame = fFrame;
5679  if (!frame) frame = (TFrame*)GetPrimitive("TFrame");
5680  if (frame) {
5681  if (frame->GetFillColor() != GetFillColor()) {
5682  if (frame->GetFillColor() > 228) {
5683  TColor::SaveColor(out, frame->GetFillColor());
5684  out<<" "<<cname<<"->SetFrameFillColor(ci);" << std::endl;
5685  } else
5686  out<<" "<<cname<<"->SetFrameFillColor("<<frame->GetFillColor()<<");"<<std::endl;
5687  }
5688  if (frame->GetFillStyle() != 1001) {
5689  out<<" "<<cname<<"->SetFrameFillStyle("<<frame->GetFillStyle()<<");"<<std::endl;
5690  }
5691  if (frame->GetLineStyle() != 1) {
5692  out<<" "<<cname<<"->SetFrameLineStyle("<<frame->GetLineStyle()<<");"<<std::endl;
5693  }
5694  if (frame->GetLineColor() != 1) {
5695  if (frame->GetLineColor() > 228) {
5696  TColor::SaveColor(out, frame->GetLineColor());
5697  out<<" "<<cname<<"->SetFrameLineColor(ci);" << std::endl;
5698  } else
5699  out<<" "<<cname<<"->SetFrameLineColor("<<frame->GetLineColor()<<");"<<std::endl;
5700  }
5701  if (frame->GetLineWidth() != 1) {
5702  out<<" "<<cname<<"->SetFrameLineWidth("<<frame->GetLineWidth()<<");"<<std::endl;
5703  }
5704  if (frame->GetBorderMode() != 1) {
5705  out<<" "<<cname<<"->SetFrameBorderMode("<<frame->GetBorderMode()<<");"<<std::endl;
5706  }
5707  if (frame->GetBorderSize() != 1) {
5708  out<<" "<<cname<<"->SetFrameBorderSize("<<frame->GetBorderSize()<<");"<<std::endl;
5709  }
5710  }
5711 
5712  TIter next(GetListOfPrimitives());
5713  TObject *obj;
5714  Int_t grnum = 0;
5715 
5716  while ((obj = next())) {
5717  if (obj->InheritsFrom(TGraph::Class()))
5718  if (!strcmp(obj->GetName(),"Graph")) ((TGraph*)obj)->SetName(Form("Graph%d",grnum++));
5719  obj->SavePrimitive(out, (Option_t *)next.GetOption());
5720  }
5721  out<<" "<<cname<<"->Modified();"<<std::endl;
5722  out<<" "<<GetMother()->GetName()<<"->cd();"<<std::endl;
5723  if (padsav) padsav->cd();
5724 }
5725 
5726 ////////////////////////////////////////////////////////////////////////////////
5727 /// Fix pad aspect ratio to current value if fixed is true.
5728 
5730 {
5731  if (fixed) {
5732  if (!fFixedAspectRatio) {
5733  if (fHNDC != 0.)
5734  fAspectRatio = fWNDC / fHNDC;
5735  else {
5736  Error("SetAspectRatio", "cannot fix aspect ratio, height of pad is 0");
5737  return;
5738  }
5740  }
5741  } else {
5743  fAspectRatio = 0;
5744  }
5745 }
5746 
5747 ////////////////////////////////////////////////////////////////////////////////
5748 /// Set pad editable yes/no
5749 /// If a pad is not editable:
5750 /// - one cannot modify the pad and its objects via the mouse.
5751 /// - one cannot add new objects to the pad
5752 
5754 {
5755  fEditable = mode;
5756 
5757  TObject *obj;
5758  if (!fPrimitives) fPrimitives = new TList;
5759  TIter next(GetListOfPrimitives());
5760  while ((obj = next())) {
5761  if (obj->InheritsFrom(TPad::Class())) {
5762  TPad *pad = (TPad*)obj;
5763  pad->SetEditable(mode);
5764  }
5765  }
5766 }
5767 
5768 ////////////////////////////////////////////////////////////////////////////////
5769 /// Override TAttFill::FillStyle for TPad because we want to handle style=0
5770 /// as style 4000.
5771 
5773 {
5774  if (fstyle == 0) fstyle = 4000;
5775  TAttFill::SetFillStyle(fstyle);
5776 }
5777 
5778 ////////////////////////////////////////////////////////////////////////////////
5779 /// Set Lin/Log scale for X
5780 /// - value = 0 X scale will be linear
5781 /// - value = 1 X scale will be logarithmic (base 10)
5782 /// - value > 1 reserved for possible support of base e or other
5783 
5785 {
5786  fLogx = value;
5787  delete fView; fView=0;
5788  Modified();
5789  RangeAxisChanged();
5790 }
5791 
5792 ////////////////////////////////////////////////////////////////////////////////
5793 /// Set Lin/Log scale for Y
5794 /// - value = 0 Y scale will be linear
5795 /// - value = 1 Y scale will be logarithmic (base 10)
5796 /// - value > 1 reserved for possible support of base e or other
5797 
5799 {
5800  fLogy = value;
5801  delete fView; fView=0;
5802  Modified();
5803  RangeAxisChanged();
5804 }
5805 
5806 ////////////////////////////////////////////////////////////////////////////////
5807 /// Set Lin/Log scale for Z
5808 
5810 {
5811  fLogz = value;
5812  delete fView; fView=0;
5813  Modified();
5814  RangeAxisChanged();
5815 }
5816 
5817 ////////////////////////////////////////////////////////////////////////////////
5818 /// Set canvas range for pad and resize the pad. If the aspect ratio
5819 /// was fixed before the call it will be un-fixed.
5820 
5821 void TPad::SetPad(Double_t xlow, Double_t ylow, Double_t xup, Double_t yup)
5822 {
5823  // Reorder points to make sure xlow,ylow is bottom left point and
5824  // xup,yup is top right point.
5825  if (xup < xlow) {
5826  Double_t x = xlow;
5827  xlow = xup;
5828  xup = x;
5829  }
5830  if (yup < ylow) {
5831  Double_t y = ylow;
5832  ylow = yup;
5833  yup = y;
5834  }
5835 
5836  fXlowNDC = xlow;
5837  fYlowNDC = ylow;
5838  fWNDC = xup - xlow;
5839  fHNDC = yup - ylow;
5840 
5842 
5843  ResizePad();
5844 }
5845 
5846 ////////////////////////////////////////////////////////////////////////////////
5847 /// Set all pad parameters.
5848 
5849 void TPad::SetPad(const char *name, const char *title,
5850  Double_t xlow, Double_t ylow, Double_t xup, Double_t yup,
5851  Color_t color, Short_t bordersize, Short_t bordermode)
5852 {
5853  fName = name;
5854  fTitle = title;
5855  SetFillStyle(1001);
5860  if (color >= 0) SetFillColor(color);
5861  else SetFillColor(gStyle->GetPadColor());
5862  if (bordersize < 0) fBorderSize = gStyle->GetPadBorderSize();
5863  else fBorderSize = bordersize;
5864  if (bordermode < -1) fBorderMode = gStyle->GetPadBorderMode();
5865  else fBorderMode = bordermode;
5866 
5867  SetPad(xlow, ylow, xup, yup);
5868 }
5869 
5870 ////////////////////////////////////////////////////////////////////////////////
5871 /// Set the current TView. Delete previous view if view=0
5872 
5874 {
5875  if (!view) delete fView;
5876  fView = view;
5877 }
5878 
5879 ////////////////////////////////////////////////////////////////////////////////
5880 /// Set postscript fill area attributes.
5881 
5883 {
5884  if (gVirtualPS) {
5885  gVirtualPS->SetFillColor(color);
5886  gVirtualPS->SetFillStyle(style);
5887  }
5888 }
5889 
5890 ////////////////////////////////////////////////////////////////////////////////
5891 /// Set postscript line attributes.
5892 
5894 {
5895  if (gVirtualPS) {
5896  gVirtualPS->SetLineColor(color);
5897  gVirtualPS->SetLineStyle(style);
5898  gVirtualPS->SetLineWidth(lwidth);
5899  }
5900 }
5901 
5902 ////////////////////////////////////////////////////////////////////////////////
5903 /// Set postscript marker attributes.
5904 
5906 {
5907  if (gVirtualPS) {
5908  gVirtualPS->SetMarkerColor(color);
5909  gVirtualPS->SetMarkerStyle(style);
5910  gVirtualPS->SetMarkerSize(msize);
5911  }
5912 }
5913 
5914 ////////////////////////////////////////////////////////////////////////////////
5915 /// Set postscript text attributes.
5916 
5917 void TPad::SetAttTextPS(Int_t align, Float_t angle, Color_t color, Style_t font, Float_t tsize)
5918 {
5919  if (gVirtualPS) {
5920  gVirtualPS->SetTextAlign(align);
5921  gVirtualPS->SetTextAngle(angle);
5922  gVirtualPS->SetTextColor(color);
5923  gVirtualPS->SetTextFont(font);
5924  if (font%10 > 2) {
5925  Float_t wh = (Float_t)gPad->XtoPixel(gPad->GetX2());
5926  Float_t hh = (Float_t)gPad->YtoPixel(gPad->GetY1());
5927  Float_t dy;
5928  if (wh < hh) {
5929  dy = AbsPixeltoX(Int_t(tsize)) - AbsPixeltoX(0);
5930  tsize = dy/(fX2-fX1);
5931  } else {
5932  dy = AbsPixeltoY(0) - AbsPixeltoY(Int_t(tsize));
5933  tsize = dy/(fY2-fY1);
5934  }
5935  }
5936  gVirtualPS->SetTextSize(tsize);
5937  }
5938 }
5939 
5940 ////////////////////////////////////////////////////////////////////////////////
5941 /// Draw Arrows to indicated equal distances of Objects with given BBoxes.
5942 /// Used by ShowGuidelines
5943 
5944 void TPad::DrawDist(Rectangle_t aBBox, Rectangle_t bBBox, char mode)
5945 {
5946  Int_t lineColor = TColor::GetColor(239, 202, 0);
5947  Int_t x1,x2,y1,y2;
5948  x1 = x2 = y1 = y2 = 0;
5949  if (mode == 'x') {
5950  if (aBBox.fX<bBBox.fX) {
5951  x1 = aBBox.fX+aBBox.fWidth;
5952  x2 = bBBox.fX;
5953  }
5954  else {
5955  x1 = bBBox.fX+bBBox.fWidth;
5956  x2 = aBBox.fX;
5957  }
5958 
5959  if ((aBBox.fY > bBBox.fY) && (aBBox.fY + aBBox.fHeight < bBBox.fY + bBBox.fHeight))
5960  y1 = y2 = aBBox.fY + TMath::Nint(0.5*(Double_t)(aBBox.fHeight))+1;
5961  else if ((bBBox.fY > aBBox.fY) && (bBBox.fY + bBBox.fHeight < aBBox.fY + aBBox.fHeight))
5962  y1 = y2 = bBBox.fY + TMath::Nint(0.5*(Double_t)(bBBox.fHeight))+1;
5963  else if (aBBox.fY>bBBox.fY) y1 = y2 = aBBox.fY-TMath::Nint(0.5*(Double_t)(aBBox.fY-(bBBox.fY+bBBox.fHeight)));
5964  else y1 = y2 = bBBox.fY-TMath::Nint(0.5*(Double_t)(bBBox.fY-(aBBox.fY+aBBox.fHeight)));
5965  }
5966  else if (mode == 'y') {
5967  if (aBBox.fY<bBBox.fY) {
5968  y1 = aBBox.fY+aBBox.fHeight;
5969  y2 = bBBox.fY;
5970  }
5971  else {
5972  y1 = bBBox.fY+bBBox.fHeight;
5973  y2 = aBBox.fY;
5974  }
5975  if ((aBBox.fX > bBBox.fX) && (aBBox.fX + aBBox.fWidth < bBBox.fX + bBBox.fWidth))
5976  x1 = x2 = aBBox.fX + TMath::Nint(0.5*(Double_t)(aBBox.fWidth))+1;
5977  else if ((bBBox.fX > aBBox.fX) && (bBBox.fX + bBBox.fWidth < aBBox.fX + aBBox.fWidth))
5978  x1 = x2 = bBBox.fX + TMath::Nint(0.5*(Double_t)(bBBox.fWidth))+1;
5979  else if (aBBox.fX>bBBox.fX) x1 = x2 = aBBox.fX+TMath::Nint(0.5*(Double_t)(bBBox.fX+bBBox.fWidth-aBBox.fX));
5980  else x1 = x2 = bBBox.fX+TMath::Nint(0.5*(Double_t)(aBBox.fX+aBBox.fWidth-bBBox.fX));
5981  }
5982 
5983  TArrow *A = new TArrow(gPad->PixeltoX(x1), gPad->PixeltoY(y1-gPad->VtoPixel(0)), gPad->PixeltoX(x2), gPad->PixeltoY(y2-gPad->VtoPixel(0)), 0.01, "<|>");
5984  A->SetBit(kCanDelete);
5985  A->SetFillColor(lineColor);
5986  A->SetLineWidth(1);
5987  A->SetLineColor(lineColor);
5988  A->Draw();
5989 
5990  return;
5991 }
5992 
5993 ////////////////////////////////////////////////////////////////////////////////
5994 /// struct used by ShowGuidelines to store the distance Field between objects
5995 /// in the canvas.
5996 
5997 struct dField {
5998  TAttBBox2D *fa;
5999  TAttBBox2D *fb;
6000  Int_t fdist;
6001  char fdir;
6002 
6003 
6004  dField()
6005  : fa(0), fb(0), fdist(0), fdir(' ')
6006  {}
6007 
6008  dField(TAttBBox2D *a, TAttBBox2D *b, Int_t dist, char direction)
6009  : fa(a), fb(b), fdist(dist), fdir(direction)
6010  {}
6011 };
6012 
6013 ////////////////////////////////////////////////////////////////////////////////
6014 /// Shows lines to indicate if a TAttBBox2D object is aligned to
6015 /// the center or to another object, shows distance arrows if two
6016 /// objects on screen have the same distance to another object
6017 /// Call from primitive in Execute Event, in ButtonMotion after
6018 /// the new coordinates have been set, to 'stick'
6019 /// once when button is up to delete lines
6020 ///
6021 /// modes: t (Top), b (bottom), l (left), r (right), i (inside)
6022 /// in resize modes (t,b,l,r) only size arrows are sticky
6023 ///
6024 /// in mode, the function gets the point on the element that is clicked to
6025 /// move (i) or resize (all others). The expected values are:
6026 /// \image html gpad_pad5.png
6027 
6028 void TPad::ShowGuidelines(TObject *object, const Int_t event, const char mode, const bool cling )
6029 {
6030  // When the object is moved with arrow or when the ShowGuideLines flag
6031  // is off we do show guide lines.
6032  if ((event == kArrowKeyRelease) || (event == kArrowKeyPress) ||
6033  !gEnv->GetValue("Canvas.ShowGuideLines", 0)) return;
6034 
6035  std::vector<dField> curDist;
6036  std::vector<dField> otherDist;
6037  Int_t pMX, pMY;
6038  Double_t MX, MY;
6039  Int_t threshold;
6040  TList *prims;
6041  UInt_t n;
6042  Rectangle_t aBBox, bBBox;
6043  aBBox = bBBox = Rectangle_t();
6044  TLine *L;
6045  TArrow *A;
6046  Int_t dSizeArrow = 12; // distance of arrows indicating same size from BBox in px
6047  Bool_t movedX, movedY; // make sure the current object is moved just once
6048  movedX = movedY = false;
6049  Bool_t resize = false; // indicates resize mode
6050  Bool_t log = gPad->GetLogx() || gPad->GetLogy();
6051  if (mode != 'i') resize = true;
6052 
6053  TPad *is_pad = dynamic_cast<TPad *>( object );
6054  TVirtualPad *padSave = 0;
6055  padSave = gPad;
6056  if (is_pad) is_pad->GetMother()->cd();
6057 
6058  static TPad * tmpGuideLinePad;
6059 
6060  //delete all existing Guidelines and create new invisible pad
6061  if (tmpGuideLinePad) {
6062  if (object == tmpGuideLinePad) { // in case of funny button click combination.
6063  tmpGuideLinePad->Delete();
6064  tmpGuideLinePad = 0;
6065  return;
6066  }
6067  tmpGuideLinePad->Delete();
6068  tmpGuideLinePad = 0;
6069  }
6070 
6071  // Get Primitives
6072  prims = gPad->GetListOfPrimitives();
6073  n = TMath::Min(15,prims->GetSize());
6074  Int_t lineColor = TColor::GetColor(239, 202, 0);
6075 
6076  TAttBBox2D *cur = dynamic_cast<TAttBBox2D *>( object );
6077  if (cur) {
6078  //create invisible TPad above gPad
6079  if (!tmpGuideLinePad){
6080  tmpGuideLinePad = new TPad("tmpGuideLinePad", "tmpGuideLinePad", 0, 0, 1, 1);
6081  Double_t x1, y1, x2, y2;
6082  gPad->GetRange(x1, y1, x2, y2);
6083  tmpGuideLinePad->Range(x1, y1, x2, y2);
6084  tmpGuideLinePad->SetFillStyle(0);
6085  tmpGuideLinePad->SetFillColor(0);
6086  tmpGuideLinePad->Draw();
6087  tmpGuideLinePad->cd();
6088  gPad->GetRange(x1, y1, x2, y2);
6089  }
6090  if (cling && !log) threshold = 7;
6091  else threshold = 1;
6092 
6093  Rectangle_t BBox = cur->GetBBox();
6094  TPoint center = cur->GetBBoxCenter();
6095 
6096  otherDist.clear();
6097  curDist.clear();
6098 
6099  switch (event) {
6100 
6101  case kButton1Down:
6102  case kButton1Motion:
6103  MX = gPad->GetX1() + 0.5 * (gPad->GetX2()-gPad->GetX1());
6104  MY = gPad->GetY1() + 0.5 * (gPad->GetY2()-gPad->GetY1());
6105  pMX = gPad->XtoPixel(MX);
6106  pMY = gPad->YtoPixel(MY);
6107  // Middlelines
6108  if (TMath::Abs(pMX-center.GetX())<threshold) {
6109  if (cling && (!resize)) {
6110  cur->SetBBoxCenterX(pMX);
6111  center = cur->GetBBoxCenter();
6112  BBox = cur->GetBBox();
6113  center = cur->GetBBoxCenter();
6114  }
6115  L = new TLine(MX, gPad->GetY1(), MX, gPad->GetY2());
6116  L->SetBit(kCanDelete);
6117  L->SetLineColor(lineColor);
6118  L->Draw();
6119  }
6120  if (TMath::Abs(pMY-center.GetY())<threshold) {
6121  if (cling && (!resize)) {
6122  cur->SetBBoxCenterY(pMY);
6123  center = cur->GetBBoxCenter();
6124  BBox = cur->GetBBox();
6125  center = cur->GetBBoxCenter();
6126  }
6127  L = new TLine(gPad->GetX1(), MY, gPad->GetX2(), MY);
6128  L->SetBit(kCanDelete);
6129  L->SetLineColor(lineColor);
6130  L->Draw();
6131  }
6132  // Alignment to other objects
6133  for (UInt_t i = 0; i<n; i++) {
6134  TAttBBox2D *other = dynamic_cast<TAttBBox2D *>( prims->At(i) );
6135  if (other) {
6136  if (other != cur) {
6137  TPoint centerOther = other->GetBBoxCenter();
6138  if (TMath::Abs(center.GetX()-centerOther.GetX())<threshold) {
6139  if (cling && (!resize)) {
6140  cur->SetBBoxCenterX(centerOther.GetX());
6141  BBox = cur->GetBBox();
6142  center = cur->GetBBoxCenter();
6143  }
6144  L = new TLine(gPad->PixeltoX(centerOther.GetX()), gPad->PixeltoY(center.GetY()-gPad->VtoPixel(0)),
6145  gPad->PixeltoX(centerOther.GetX()), gPad->PixeltoY(centerOther.GetY()-gPad->VtoPixel(0)));
6146  L->SetLineColor(lineColor);
6147  L->Draw();
6148  L->SetBit(kCanDelete);
6149  }
6150  if (TMath::Abs(center.GetY()-centerOther.GetY())<threshold) {
6151  if (cling && (!resize)) {
6152  cur->SetBBoxCenterY(centerOther.GetY());
6153  BBox = cur->GetBBox();
6154  center = cur->GetBBoxCenter();
6155  }
6156  L = new TLine(gPad->PixeltoX(center.GetX()), gPad->PixeltoY(centerOther.GetY()-gPad->VtoPixel(0)),
6157  gPad->PixeltoX(centerOther.GetX()), gPad->PixeltoY(centerOther.GetY()-gPad->VtoPixel(0)));
6158  L->SetBit(kCanDelete);
6159  L->SetLineColor(lineColor);
6160  L->Draw();
6161  }
6162  }
6163  }
6164  }
6165  // Get Distances between objects
6166  for (UInt_t i = 0; i<n; i++) {
6167  TAttBBox2D *a = dynamic_cast<TAttBBox2D *>( prims->At(i) );
6168  if (a) {
6169  aBBox = a->GetBBox();
6170  for (UInt_t j = i+1; j<n; j++) {
6171  TAttBBox2D *b = dynamic_cast<TAttBBox2D *>( prims->At(j) );
6172  if (b) {
6173  bBBox = b->GetBBox();
6174 
6175  //only when bounding boxes overlap in x or y direction
6176  if (((aBBox.fX<bBBox.fX)&&(bBBox.fX-aBBox.fX<=aBBox.fWidth))||((aBBox.fX>bBBox.fX)&&(aBBox.fX-bBBox.fX<=bBBox.fWidth))){ //BBoxes overlap in x direction
6177  if ((aBBox.fY+aBBox.fHeight<bBBox.fY)||(bBBox.fY+bBBox.fHeight<aBBox.fY)) {//No overlap in Y-direction required
6178  dField abDist = dField();
6179  if (aBBox.fY>bBBox.fY) abDist = dField(a, b, TMath::Abs(aBBox.fY-(bBBox.fY+bBBox.fHeight)), 'y');
6180  else abDist = dField(a, b, TMath::Abs(bBBox.fY-(aBBox.fY+aBBox.fHeight)), 'y');
6181  if ((b != cur)&&(a != cur)) otherDist.push_back(abDist);
6182  else curDist.push_back(abDist);
6183  }
6184  } else if (((aBBox.fY<bBBox.fY)&&(bBBox.fY-aBBox.fY<=aBBox.fHeight))||((aBBox.fY>bBBox.fY)&&(aBBox.fY-bBBox.fY<=bBBox.fHeight))) { //BBoxes overlap in y direction
6185  if ((aBBox.fX+aBBox.fWidth<bBBox.fX)||(bBBox.fX+bBBox.fWidth<aBBox.fX)) {//No overlap in x-direction required
6186  dField abDist = dField();
6187  if (aBBox.fX>bBBox.fX) abDist = dField(a, b, TMath::Abs(aBBox.fX-(bBBox.fX+bBBox.fWidth)), 'x');
6188  else abDist = dField(a, b, TMath::Abs(bBBox.fX-(aBBox.fX+aBBox.fWidth)), 'x');
6189  if ((b != cur)&&(a != cur)) otherDist.push_back(abDist);
6190  else curDist.push_back(abDist);
6191  }
6192  }
6193  }
6194  }
6195  }
6196  }
6197  // Show equal distances
6198  for (UInt_t i = 0; i<curDist.size(); i++) {
6199  for (UInt_t j = 0; j<otherDist.size(); j++) {
6200  if ((curDist[i].fdir == otherDist[j].fdir)&&(otherDist[j].fdir=='x')&&(TMath::Abs(curDist[i].fdist-otherDist[j].fdist)<threshold)) {
6201  if (cling && (!movedX) && (!resize)) {
6202  if ((cur->GetBBoxCenter().fX < curDist[i].fb->GetBBoxCenter().fX)||(cur->GetBBoxCenter().fX < curDist[i].fa->GetBBoxCenter().fX))
6203  cur->SetBBoxCenterX(cur->GetBBoxCenter().fX - otherDist[j].fdist + curDist[i].fdist);
6204  else cur->SetBBoxCenterX(cur->GetBBoxCenter().fX + otherDist[j].fdist - curDist[i].fdist);
6205  movedX = true;
6206  }
6207  DrawDist(curDist[i].fa->GetBBox(), curDist[i].fb->GetBBox(), 'x');
6208  DrawDist(otherDist[j].fa->GetBBox(), otherDist[j].fb->GetBBox(), 'x');
6209  }
6210  if ((curDist[i].fdir == otherDist[j].fdir)&&(otherDist[j].fdir=='y')&&(TMath::Abs(curDist[i].fdist-otherDist[j].fdist)<threshold)) {
6211  if (cling && (!movedY) && (!resize)) {
6212  if ((cur->GetBBoxCenter().fY < curDist[i].fb->GetBBoxCenter().fY)||(cur->GetBBoxCenter().fY < curDist[i].fa->GetBBoxCenter().fY))
6213  cur->SetBBoxCenterY(cur->GetBBoxCenter().fY - otherDist[j].fdist + curDist[i].fdist);
6214  else cur->SetBBoxCenterY(cur->GetBBoxCenter().fY + otherDist[j].fdist - curDist[i].fdist);
6215  movedY = true;
6216  }
6217  DrawDist(curDist[i].fa->GetBBox(), curDist[i].fb->GetBBox(), 'y');
6218  DrawDist(otherDist[j].fa->GetBBox(), otherDist[j].fb->GetBBox(), 'y');
6219  }
6220  }
6221  for (UInt_t j = i; j<curDist.size(); j++) {
6222  if (i!=j) {
6223  if ((curDist[i].fdir == curDist[j].fdir)&&(curDist[j].fdir=='x')&&(TMath::Abs(curDist[i].fdist-curDist[j].fdist)<threshold)) {
6224  if (cling && (!movedX) && (!resize)) {
6225  if ((cur->GetBBoxCenter().fX < curDist[i].fb->GetBBoxCenter().fX)||(cur->GetBBoxCenter().fX < curDist[i].fa->GetBBoxCenter().fX))
6226  cur->SetBBoxCenterX(cur->GetBBoxCenter().fX - floor(0.5*(curDist[j].fdist - curDist[i].fdist)));
6227  else cur->SetBBoxCenterX(cur->GetBBoxCenter().fX + floor(0.5*(curDist[j].fdist - curDist[i].fdist)));
6228  }
6229  DrawDist(curDist[i].fa->GetBBox(), curDist[i].fb->GetBBox(), 'x');
6230  DrawDist(curDist[j].fa->GetBBox(), curDist[j].fb->GetBBox(), 'x');
6231  }
6232 
6233  if ((curDist[i].fdir == curDist[j].fdir)&&(curDist[j].fdir=='y')&&(TMath::Abs(curDist[i].fdist-curDist[j].fdist)<threshold)) {
6234  if (cling && (!movedY) && (!resize)) {
6235  if ((cur->GetBBoxCenter().fY < curDist[i].fb->GetBBoxCenter().fY)||(cur->GetBBoxCenter().fY < curDist[i].fa->GetBBoxCenter().fY))
6236  cur->SetBBoxCenterY(cur->GetBBoxCenter().fY - floor(0.5*(curDist[j].fdist - curDist[i].fdist)));
6237  else cur->SetBBoxCenterY(cur->GetBBoxCenter().fY + floor(0.5*(curDist[j].fdist - curDist[i].fdist)));
6238  }
6239  DrawDist(curDist[i].fa->GetBBox(), curDist[i].fb->GetBBox(), 'y');
6240  DrawDist(curDist[j].fa->GetBBox(), curDist[j].fb->GetBBox(), 'y');
6241  }
6242  }
6243  }
6244  }
6245  if (resize) {
6246  // Show equal Sizes
6247  for (UInt_t i = 0; i<n; i++) {
6248  TAttBBox2D *a = dynamic_cast<TAttBBox2D *>( prims->At(i) );
6249  if (a && (cur != a)) {
6250  aBBox = a->GetBBox();
6251 
6252  if ((TMath::Abs(aBBox.fWidth - BBox.fWidth)<threshold) && (mode != 't') && (mode != 'b')) {
6253  if (cling) {
6254  if (mode == 'l') cur->SetBBoxX1(BBox.fX + BBox.fWidth - aBBox.fWidth);
6255  if (mode == 'r') cur->SetBBoxX2(BBox.fX + aBBox.fWidth);
6256  if ((mode == '1')||(mode == '4')) cur->SetBBoxX1(BBox.fX + BBox.fWidth - aBBox.fWidth);
6257  if ((mode == '2')||(mode == '3')) cur->SetBBoxX2(BBox.fX + aBBox.fWidth);
6258  BBox = cur->GetBBox();
6259  }
6260 
6261  A = new TArrow(gPad->PixeltoX(aBBox.fX), gPad->PixeltoY(aBBox.fY-dSizeArrow-gPad->VtoPixel(0)),
6262  gPad->PixeltoX(aBBox.fX+aBBox.fWidth), gPad->PixeltoY(aBBox.fY-dSizeArrow-gPad->VtoPixel(0)), 0.01, "<|>");
6263  A->SetBit(kCanDelete);
6264  A->SetLineColor(lineColor);
6265  A->SetFillColor(lineColor);
6266  A->Draw();
6267 
6268  A = new TArrow(gPad->PixeltoX(BBox.fX), gPad->PixeltoY(BBox.fY-dSizeArrow-gPad->VtoPixel(0)),
6269  gPad->PixeltoX(BBox.fX+BBox.fWidth), gPad->PixeltoY(BBox.fY-dSizeArrow-gPad->VtoPixel(0)), 0.01, "<|>");
6270  A->SetBit(kCanDelete);
6271  A->SetLineColor(lineColor);
6272  A->SetFillColor(lineColor);
6273  A->Draw();
6274  }
6275  if ((TMath::Abs(aBBox.fHeight - BBox.fHeight)<threshold) && (mode != 'r') && (mode != 'l')) {
6276  if (cling) {
6277  if (mode == 't') cur->SetBBoxY1(BBox.fY + BBox.fHeight - aBBox.fHeight);
6278  if (mode == 'b') cur->SetBBoxY2(BBox.fY + aBBox.fHeight);
6279  if ((mode == '1')||(mode == '2')) cur->SetBBoxY1(BBox.fY + BBox.fHeight - aBBox.fHeight);
6280  if ((mode == '3')||(mode == '4')) cur->SetBBoxY2(BBox.fY + aBBox.fHeight);
6281  BBox = cur->GetBBox();
6282  }
6283  A = new TArrow(gPad->PixeltoX(aBBox.fX-dSizeArrow), gPad->PixeltoY(aBBox.fY-gPad->VtoPixel(0)),
6284  gPad->PixeltoX(aBBox.fX-dSizeArrow), gPad->PixeltoY(aBBox.fY+aBBox.fHeight-gPad->VtoPixel(0)), 0.01, "<|>");
6285  A->SetBit(kCanDelete);
6286  A->SetLineColor(lineColor);
6287  A->SetFillColor(lineColor);
6288  A->Draw();
6289 
6290  A = new TArrow(gPad->PixeltoX(BBox.fX-dSizeArrow), gPad->PixeltoY(BBox.fY-gPad->VtoPixel(0)),
6291  gPad->PixeltoX(BBox.fX-dSizeArrow), gPad->PixeltoY(BBox.fY+BBox.fHeight-gPad->VtoPixel(0)), 0.01, "<|>");
6292  A->SetBit(kCanDelete);
6293  A->SetLineColor(lineColor);
6294  A->SetFillColor(lineColor);
6295  A->Draw();
6296  }
6297  }
6298  }
6299  }
6300 
6301  break;
6302 
6303  case kButton1Up:
6304  if (tmpGuideLinePad) {
6305  // All the arrows and lines in that pad are also deleted because
6306  // they all have the bit kCanDelete on.
6307  tmpGuideLinePad->Delete();
6308  tmpGuideLinePad = 0;
6309  }
6310  break;
6311  }
6312  }
6313 
6314  gPad->Modified(kTRUE);
6315  padSave->cd();
6316 }
6317 
6318 ////////////////////////////////////////////////////////////////////////////////
6319 /// Return kTRUE if the crosshair has been activated (via SetCrosshair).
6320 
6322 {
6323  return (Bool_t)GetCrosshair();
6324 }
6325 
6326 ////////////////////////////////////////////////////////////////////////////////
6327 /// Return the crosshair type (from the mother canvas)
6328 /// crosshair type = 0 means no crosshair.
6329 
6331 {
6332  if (this == (TPad*)fCanvas)
6333  return fCrosshair;
6334  return fCanvas ? fCanvas->GetCrosshair() : 0;
6335 }
6336 
6337 ////////////////////////////////////////////////////////////////////////////////
6338 /// Set crosshair active/inactive.
6339 /// - If crhair != 0, a crosshair will be drawn in the pad and its sub-pads.
6340 /// - If the canvas crhair = 1 , the crosshair spans the full canvas.
6341 /// - If the canvas crhair > 1 , the crosshair spans only the pad.
6342 
6344 {
6345  fCrosshair = crhair;
6346  fCrosshairPos = 0;
6347 
6348  if (this != (TPad*)fCanvas) fCanvas->SetCrosshair(crhair);
6349 }
6350 
6351 ////////////////////////////////////////////////////////////////////////////////
6352 /// static function to set the maximum Pick Distance fgMaxPickDistance
6353 /// This parameter is used in TPad::Pick to select an object if
6354 /// its DistancetoPrimitive returns a value < fgMaxPickDistance
6355 /// The default value is 5 pixels. Setting a smaller value will make
6356 /// picking more precise but also more difficult
6357 
6359 {
6360  fgMaxPickDistance = maxPick;
6361 }
6362 
6363 ////////////////////////////////////////////////////////////////////////////////
6364 /// Set tool tip text associated with this pad. The delay is in
6365 /// milliseconds (minimum 250). To remove tool tip call method with
6366 /// text = 0.
6367 
6368 void TPad::SetToolTipText(const char *text, Long_t delayms)
6369 {
6370  if (fTip) {
6372  fTip = 0;
6373  }
6374 
6375  if (text && strlen(text))
6376  fTip = CreateToolTip((TBox*)0, text, delayms);
6377 }
6378 
6379 ////////////////////////////////////////////////////////////////////////////////
6380 /// Set pad vertical (default) or horizontal
6381 
6383 {
6384  if (vert) ResetBit(kHori);
6385  else SetBit(kHori);
6386 }
6387 
6388 ////////////////////////////////////////////////////////////////////////////////
6389 /// Stream a class object.
6390 
6391 void TPad::Streamer(TBuffer &b)
6392 {
6393  UInt_t R__s, R__c;
6394  Int_t nch, nobjects;
6395  Float_t single;
6396  TObject *obj;
6397  if (b.IsReading()) {
6398  Version_t v = b.ReadVersion(&R__s, &R__c);
6399  if (v > 5) {
6400  if (!gPad) gPad = new TCanvas(GetName());
6401  TPad *padsave = (TPad*)gPad;
6402  fMother = (TPad*)gPad;
6403  if (fMother) fCanvas = fMother->GetCanvas();
6404  gPad = this;
6405  fPixmapID = -1; // -1 means pixmap will be created by ResizePad()
6406  gReadLevel++;
6407  gROOT->SetReadingObject(kTRUE);
6408 
6409  b.ReadClassBuffer(TPad::Class(), this, v, R__s, R__c);
6410 
6411  //Set the kCanDelete bit in all objects in the pad such that when the pad
6412  //is deleted all objects in the pad are deleted too.
6413  TIter next(fPrimitives);
6414  while ((obj = next())) {
6415  obj->SetBit(kCanDelete);
6416  }
6417 
6418  fModified = kTRUE;
6419  fPadPointer = 0;
6420  gReadLevel--;
6421  if (gReadLevel == 0 && IsA() == TPad::Class()) ResizePad();
6422  gROOT->SetReadingObject(kFALSE);
6423  gPad = padsave;
6424  return;
6425  }
6426 
6427  //====process old versions before automatic schema evolution
6428  if (v < 5) { //old TPad in single precision
6429  if (v < 3) { //old TPad derived from TWbox
6430  b.ReadVersion(); // TVirtualPad::Streamer(b)
6431  b.ReadVersion(); // TWbox::Streamer(b)
6432  b.ReadVersion(); // TBox::Streamer(b)
6433  TObject::Streamer(b);
6434  TAttLine::Streamer(b);
6435  TAttFill::Streamer(b);
6436  b >> single; fX1 = single;
6437  b >> single; fY1 = single;
6438  b >> single; fX2 = single;
6439  b >> single; fY2 = single;
6440  b >> fBorderSize;
6441  b >> fBorderMode;
6442  TAttPad::Streamer(b);
6443  } else { //new TPad
6444  TVirtualPad::Streamer(b);
6445  TAttPad::Streamer(b);
6446  b >> single; fX1 = single;
6447  b >> single; fY1 = single;
6448  b >> single; fX2 = single;
6449  b >> single; fY2 = single;
6450  b >> fBorderSize;
6451  b >> fBorderMode;
6452  }
6453  b >> fLogx;
6454  b >> fLogy;
6455  b >> fLogz;
6456  b >> single; fXtoAbsPixelk = single;
6457  b >> single; fXtoPixelk = single;
6458  b >> single; fXtoPixel = single;
6459  b >> single; fYtoAbsPixelk = single;
6460  b >> single; fYtoPixelk = single;
6461  b >> single; fYtoPixel = single;
6462  b >> single; fUtoAbsPixelk = single;
6463  b >> single; fUtoPixelk = single;
6464  b >> single; fUtoPixel = single;
6465  b >> single; fVtoAbsPixelk = single;
6466  b >> single; fVtoPixelk = single;
6467  b >> single; fVtoPixel = single;
6468  b >> single; fAbsPixeltoXk = single;
6469  b >> single; fPixeltoXk = single;
6470  b >> single; fPixeltoX = single;
6471  b >> single; fAbsPixeltoYk = single;
6472  b >> single; fPixeltoYk = single;
6473  b >> single; fPixeltoY = single;
6474  b >> single; fXlowNDC = single;
6475  b >> single; fYlowNDC = single;
6476  b >> single; fWNDC = single;
6477  b >> single; fHNDC = single;
6478  b >> single; fAbsXlowNDC = single;
6479  b >> single; fAbsYlowNDC = single;
6480  b >> single; fAbsWNDC = single;
6481  b >> single; fAbsHNDC = single;
6482  b >> single; fUxmin = single;
6483  b >> single; fUymin = single;
6484  b >> single; fUxmax = single;
6485  b >> single; fUymax = single;
6486  } else {
6487  TVirtualPad::Streamer(b);
6488  TAttPad::Streamer(b);
6489  b >> fX1;
6490  b >> fY1;
6491  b >> fX2;
6492  b >> fY2;
6493  b >> fBorderSize;
6494  b >> fBorderMode;
6495  b >> fLogx;
6496  b >> fLogy;
6497  b >> fLogz;
6498  b >> fXtoAbsPixelk;
6499  b >> fXtoPixelk;
6500  b >> fXtoPixel;
6501  b >> fYtoAbsPixelk;
6502  b >> fYtoPixelk;
6503  b >> fYtoPixel;
6504  b >> fUtoAbsPixelk;
6505  b >> fUtoPixelk;
6506  b >> fUtoPixel;
6507  b >> fVtoAbsPixelk;
6508  b >> fVtoPixelk;
6509  b >> fVtoPixel;
6510  b >> fAbsPixeltoXk;
6511  b >> fPixeltoXk;
6512  b >> fPixeltoX;
6513  b >> fAbsPixeltoYk;
6514  b >> fPixeltoYk;
6515  b >> fPixeltoY;
6516  b >> fXlowNDC;
6517  b >> fYlowNDC;
6518  b >> fWNDC;
6519  b >> fHNDC;
6520  b >> fAbsXlowNDC;
6521  b >> fAbsYlowNDC;
6522  b >> fAbsWNDC;
6523  b >> fAbsHNDC;
6524  b >> fUxmin;
6525  b >> fUymin;
6526  b >> fUxmax;
6527  b >> fUymax;
6528  }
6529 
6530  if (!gPad) gPad = new TCanvas(GetName());
6531  if (gReadLevel == 0) fMother = (TPad*)gROOT->GetSelectedPad();
6532  else fMother = (TPad*)gPad;
6533  if (!fMother) fMother = (TPad*)gPad;
6534  if (fMother) fCanvas = fMother->GetCanvas();
6535  gPad = fMother;
6536  fPixmapID = -1; // -1 means pixmap will be created by ResizePad()
6537  //-------------------------
6538  // read objects and their drawing options
6539  // b >> fPrimitives;
6540  gReadLevel++;
6541  gROOT->SetReadingObject(kTRUE);
6542  fPrimitives = new TList;
6543  b >> nobjects;
6544  if (nobjects > 0) {
6545  TPad *padsav = (TPad*)gPad;
6546  gPad = this;
6547  char drawoption[64];
6548  for (Int_t i = 0; i < nobjects; i++) {
6549  b >> obj;
6550  b >> nch;
6551  b.ReadFastArray(drawoption,nch);
6552  fPrimitives->AddLast(obj, drawoption);
6553  gPad = this; // gPad may be modified in b >> obj if obj is a pad
6554  }
6555  gPad = padsav;
6556  }
6557  gReadLevel--;
6558  gROOT->SetReadingObject(kFALSE);
6559  //////////////////////////////////////////////////////////////////////////
6560 
6561  if (v > 3) {
6562  b >> fExecs;
6563  }
6564  fName.Streamer(b);
6565  fTitle.Streamer(b);
6566  b >> fPadPaint;
6567  fModified = kTRUE;
6568  b >> fGridx;
6569  b >> fGridy;
6570  b >> fFrame;
6571  b >> fView;
6572  if (v < 5) {
6573  b >> single; fTheta = single;
6574  b >> single; fPhi = single;
6575  } else {
6576  b >> fTheta;
6577  b >> fPhi;
6578  }
6579  fPadPointer = 0;
6580  b >> fNumber;
6581  b >> fAbsCoord;
6582  if (v > 1) {
6583  b >> fTickx;
6584  b >> fTicky;
6585  } else {
6586  fTickx = fTicky = 0;
6587  }
6588  if (gReadLevel == 0 && IsA() == TPad::Class()) ResizePad();
6589  b.CheckByteCount(R__s, R__c, TPad::IsA());
6590  //====end of old versions
6591 
6592  } else {
6593  b.WriteClassBuffer(TPad::Class(),this);
6594  }
6595 }
6596 
6597 ////////////////////////////////////////////////////////////////////////////////
6598 /// Force a copy of current style for all objects in pad.
6599 
6601 {
6602  if (gStyle->IsReading()) {
6610  fGridx = gStyle->GetPadGridX();
6611  fGridy = gStyle->GetPadGridY();
6612  fTickx = gStyle->GetPadTickX();
6613  fTicky = gStyle->GetPadTickY();
6614  fLogx = gStyle->GetOptLogx();
6615  fLogy = gStyle->GetOptLogy();
6616  fLogz = gStyle->GetOptLogz();
6617  } else {
6629  gStyle->SetOptLogx (fLogx);
6630  gStyle->SetOptLogy (fLogy);
6631  gStyle->SetOptLogz (fLogz);
6632  }
6633 
6634  if (!fPrimitives) fPrimitives = new TList;
6635  TIter next(GetListOfPrimitives());
6636  TObject *obj;
6637 
6638  while ((obj = next())) {
6639  obj->UseCurrentStyle();
6640  }
6641 
6642  TPaveText *title = (TPaveText*)FindObject("title");
6643  if (title) {
6644  if (gStyle->IsReading()) {
6646  title->SetTextFont(gStyle->GetTitleFont(""));
6649  if (!gStyle->GetOptTitle()) delete title;
6650  } else {
6652  gStyle->SetTitleFont(title->GetTextFont());
6655  }
6656  }
6657  if (fFrame) fFrame->UseCurrentStyle();
6658 
6659  if (gStyle->IsReading()) Modified();
6660 }
6661 
6662 ////////////////////////////////////////////////////////////////////////////////
6663 /// Loop and sleep until a primitive with name=pname is found in the pad.
6664 ///
6665 /// If emode is given, the editor is automatically set to emode, ie
6666 /// it is not required to have the editor control bar.
6667 ///
6668 /// The possible values for emode are:
6669 /// - emode = "" (default). User will select the mode via the editor bar
6670 /// - emode = "Arc", "Line", "Arrow", "Button", "Diamond", "Ellipse",
6671 /// - emode = "Pad","pave", "PaveLabel","PaveText", "PavesText",
6672 /// - emode = "PolyLine", "CurlyLine", "CurlyArc", "Text", "Marker", "CutG"
6673 ///
6674 /// If emode is specified and it is not valid, "PolyLine" is assumed. If emode
6675 /// is not specified or ="", an attempt is to use pname[1...]
6676 ///
6677 /// for example if pname="TArc", emode="Arc" will be assumed.
6678 /// When this function is called within a macro, the macro execution
6679 /// is suspended until a primitive corresponding to the arguments
6680 /// is found in the pad.
6681 ///
6682 /// If CRTL/C is typed in the pad, the function returns 0.
6683 ///
6684 /// While this function is executing, one can use the mouse, interact
6685 /// with the graphics pads, use the Inspector, Browser, TreeViewer, etc.
6686 ///
6687 /// Examples:
6688 /// ~~~ {.cpp}
6689 /// c1.WaitPrimitive(); // Return the first created primitive
6690 /// // whatever it is.
6691 /// // If a double-click with the mouse is executed
6692 /// // in the pad or any key pressed, the function
6693 /// // returns 0.
6694 /// c1.WaitPrimitive("ggg"); // Set the editor in mode "PolyLine/Graph"
6695 /// // Create a polyline, then using the context
6696 /// // menu item "SetName", change the name
6697 /// // of the created TGraph to "ggg"
6698 /// c1.WaitPrimitive("TArc");// Set the editor in mode "Arc". Returns
6699 /// // as soon as a TArc object is created.
6700 /// c1.WaitPrimitive("lat","Text"); // Set the editor in Text/Latex mode.
6701 /// // Create a text object, then Set its name to "lat"
6702 /// ~~~
6703 /// The following macro waits for 10 primitives of any type to be created.
6704 ///
6705 /// ~~~ {.cpp}
6706 ///{
6707 /// TCanvas c1("c1");
6708 /// TObject *obj;
6709 /// for (Int_t i=0;i<10;i++) {
6710 /// obj = gPad->WaitPrimitive();
6711 /// if (!obj) break;
6712 /// printf("Loop i=%d, found objIsA=%s, name=%s\n",
6713 /// i,obj->ClassName(),obj->GetName());
6714 /// }
6715 ///}
6716 /// ~~~
6717 ///
6718 /// If ROOT runs in batch mode a call to this method does nothing.
6719 
6720 TObject *TPad::WaitPrimitive(const char *pname, const char *emode)
6721 {
6722  if (!gPad) return 0;
6723 
6724  if (strlen(emode)) gROOT->SetEditorMode(emode);
6725  if (gROOT->GetEditorMode() == 0 && strlen(pname) > 2) gROOT->SetEditorMode(&pname[1]);
6726 
6727  if (!fPrimitives) fPrimitives = new TList;
6729  TObject *oldlast = gPad->GetListOfPrimitives()->Last();
6730  TObject *obj = 0;
6731  Bool_t testlast = kFALSE;
6732  Bool_t hasname = strlen(pname) > 0;
6733  if (!pname[0] && !emode[0]) testlast = kTRUE;
6734  if (testlast) gROOT->SetEditorMode();
6735  while (!gSystem->ProcessEvents() && gROOT->GetSelectedPad()) {
6736  if (gROOT->GetEditorMode() == 0) {
6737  if (hasname) {
6738  obj = FindObject(pname);
6739  if (obj) return obj;
6740  }
6741  if (testlast) {
6742  obj = gPad->GetListOfPrimitives()->Last();
6743  if (obj != oldlast) return obj;
6744  Int_t event = GetEvent();
6745  if (event == kButton1Double || event == kKeyPress) {
6746  //the following statement is required against other loop executions
6747  //before returning
6748  fCanvas->HandleInput((EEventType)-1,0,0);
6749  return 0;
6750  }
6751  }
6752  }
6753  gSystem->Sleep(10);
6754  }
6755 
6756  return 0;
6757 }
6758 
6759 ////////////////////////////////////////////////////////////////////////////////
6760 /// Create a tool tip and return its pointer.
6761 
6762 TObject *TPad::CreateToolTip(const TBox *box, const char *text, Long_t delayms)
6763 {
6764  if (gPad->IsBatch()) return 0;
6765  return (TObject*)gROOT->ProcessLineFast(Form("new TGToolTip((TBox*)0x%lx,\"%s\",%d)",
6766  (Long_t)box,text,(Int_t)delayms));
6767 }
6768 
6769 ////////////////////////////////////////////////////////////////////////////////
6770 /// Delete tool tip object.
6771 
6773 {
6774  // delete tip;
6775  if (!tip) return;
6776  gROOT->ProcessLineFast(Form("delete (TGToolTip*)0x%lx", (Long_t)tip));
6777 }
6778 
6779 ////////////////////////////////////////////////////////////////////////////////
6780 /// Reset tool tip, i.e. within time specified in CreateToolTip the
6781 /// tool tip will pop up.
6782 
6784 {
6785  if (!tip) return;
6786  // tip->Reset(this);
6787  gROOT->ProcessLineFast(Form("((TGToolTip*)0x%lx)->Reset((TPad*)0x%lx)",
6788  (Long_t)tip,(Long_t)this));
6789 }
6790 
6791 ////////////////////////////////////////////////////////////////////////////////
6792 /// Hide tool tip.
6793 
6795 {
6796  if (!tip) return;
6797  // tip->Hide();
6798  gROOT->ProcessLineFast(Form("((TGToolTip*)0x%lx)->Hide()",(Long_t)tip));
6799 }
6800 
6801 ////////////////////////////////////////////////////////////////////////////////
6802 /// Deprecated: use TPad::GetViewer3D() instead
6803 
6805 {
6806  ::Info("TPad::x3d()", "This function is deprecated. Use %s->GetViewer3D(\"x3d\") instead",this->GetName());
6807 
6808  // Default on GetViewer3D is pad - for x3d it was x3d...
6809  if (!type || !type[0]) {
6810  type = "x3d";
6811  }
6812  GetViewer3D(type);
6813 }
6814 
6815 ////////////////////////////////////////////////////////////////////////////////
6816 /// Create/obtain handle to 3D viewer. Valid types are:
6817 /// - 'pad' - pad drawing via TViewer3DPad
6818 /// any others registered with plugin manager supporting TVirtualViewer3D
6819 /// If an invalid/null type is requested then the current viewer is returned
6820 /// (if any), otherwise a default 'pad' type is returned
6821 
6823 {
6824  Bool_t validType = kFALSE;
6825 
6826  if ( (!type || !type[0] || (strstr(type, "gl") && !strstr(type, "ogl"))) && !fCanvas->UseGL())
6827  type = "pad";
6828 
6829  if (type && type[0]) {
6830 
6831  if (gPluginMgr->FindHandler("TVirtualViewer3D", type))
6832  validType = kTRUE;
6833 
6834  }
6835 
6836  // Invalid/null type requested?
6837  if (!validType) {
6838  // Return current viewer if there is one
6839  if (fViewer3D) {
6840  return fViewer3D;
6841  }
6842  // otherwise default to the pad
6843  else {
6844  type = "pad";
6845  }
6846  }
6847 
6848  // Ensure we can create the new viewer before removing any existing one
6849  TVirtualViewer3D *newViewer = 0;
6850 
6851  Bool_t createdExternal = kFALSE;
6852 
6853  // External viewers need to be created via plugin manager via interface...
6854  if (!strstr(type,"pad")) {
6855  newViewer = TVirtualViewer3D::Viewer3D(this,type);
6856 
6857  if (!newViewer) {
6858  Warning("TPad::CreateViewer3D", "Cannot create 3D viewer of type: %s", type);
6859 
6860  // Return the existing viewer
6861  return fViewer3D;
6862  }
6863 
6864  if (strstr(type, "gl") && !strstr(type, "ogl"))
6866  else
6867  createdExternal = kTRUE;
6868 
6869  } else
6870  newViewer = new TViewer3DPad(*this);
6871 
6872  // If we had a previous viewer destroy it now
6873  // In this case we do take responsibility for destroying viewer
6874  // c.f. ReleaseViewer3D
6875  delete fViewer3D;
6876 
6877  // Set and return new viewer
6878  fViewer3D = newViewer;
6879 
6880  // Ensure any new external viewer is painted
6881  // For internal TViewer3DPad type we assume this is being
6882  // create on demand due to a paint - so this is not required
6883  if (createdExternal) {
6884  Modified();
6885  Update();
6886  }
6887 
6888  return fViewer3D;
6889 }
6890 
6891 ////////////////////////////////////////////////////////////////////////////////
6892 /// Release current (external) viewer
6893 
6895 {
6896  fViewer3D = 0;
6897 
6898  // We would like to ensure the pad is repainted
6899  // when external viewer is closed down. However
6900  // a modify/paint call here will repaint the pad
6901  // before the external viewer window actually closes.
6902  // So the pad would have to be redraw twice over.
6903  // Currently we just have to live with the pad staying blank
6904  // any click in pad will refresh.
6905 }
6906 
6907 ////////////////////////////////////////////////////////////////////////////////
6908 /// Get GL device.
6909 
6911 {
6912  return fGLDevice;
6913 }
6914 
6915 ////////////////////////////////////////////////////////////////////////////////
6916 /// Emit RecordPave() signal.
6917 
6918 void TPad::RecordPave(const TObject *obj)
6919 {
6920  Emit("RecordPave(const TObject*)", (Long_t)obj);
6921 }
6922 
6923 ////////////////////////////////////////////////////////////////////////////////
6924 /// Emit RecordLatex() signal.
6925 
6926 void TPad::RecordLatex(const TObject *obj)
6927 {
6928  Emit("RecordLatex(const TObject*)", (Long_t)obj);
6929 }
6930 
6931 ////////////////////////////////////////////////////////////////////////////////
6932 /// Get pad painter from TCanvas.
6933 
6935 {
6936  if (!fCanvas) return 0;
6937  return fCanvas->GetCanvasPainter();
6938 }
6939 
6940 ////////////////////////////////////////////////////////////////////////////////
6941 /// Return the bounding Box of the Pad
6942 
6944 {
6945  Rectangle_t BBox;
6946  BBox.fX = gPad->XtoPixel(fXlowNDC*(gPad->GetX2()-gPad->GetX1()) + gPad->GetX1());
6947  BBox.fY = gPad->YtoPixel((fYlowNDC+fHNDC)*(gPad->GetY2()-gPad->GetY1()) + gPad->GetY1());
6948  BBox.fWidth = gPad->XtoPixel((fXlowNDC+fWNDC)*(gPad->GetX2()-gPad->GetX1()) + gPad->GetX1()) - gPad->XtoPixel(fXlowNDC*(gPad->GetX2()-gPad->GetX1()) + gPad->GetX1());
6949  BBox.fHeight = gPad->YtoPixel((fYlowNDC)*(gPad->GetY2()-gPad->GetY1()) + gPad->GetY1()) - gPad->YtoPixel((fYlowNDC+fHNDC)*(gPad->GetY2()-gPad->GetY1()) + gPad->GetY1());
6950  return (BBox);
6951 }
6952 
6953 
6954 ////////////////////////////////////////////////////////////////////////////////
6955 /// Return the center of the Pad as TPoint in pixels
6956 
6958 {
6959  TPoint p;
6960  Double_t x = ((fXlowNDC+0.5*fWNDC)*(gPad->GetX2()-gPad->GetX1())) + gPad->GetX1();
6961  Double_t y = ((fYlowNDC+0.5*fHNDC)*(gPad->GetY2()-gPad->GetY1())) + gPad->GetY1();
6962 
6963  p.SetX(gPad->XtoPixel(x));
6964  p.SetY(gPad->YtoPixel(y));
6965  return(p);
6966 }
6967 
6968 ////////////////////////////////////////////////////////////////////////////////
6969 /// Set center of the Pad
6970 
6972 {
6973  fXlowNDC = (gPad->PixeltoX(p.GetX()) - gPad->GetX1())/(gPad->GetX2()-gPad->GetX1())-0.5*fWNDC;
6974  fYlowNDC = (gPad->PixeltoY(p.GetY()-gPad->VtoPixel(0)) - gPad->GetY1())/(gPad->GetY2()-gPad->GetY1())-0.5*fHNDC;
6975  ResizePad();
6976 }
6977 
6978 ////////////////////////////////////////////////////////////////////////////////
6979 /// Set X coordinate of the center of the Pad
6980 
6982 {
6983  fXlowNDC = (gPad->PixeltoX(x) - gPad->GetX1())/(gPad->GetX2()-gPad->GetX1())-0.5*fWNDC;
6984  ResizePad();
6985 }
6986 
6987 ////////////////////////////////////////////////////////////////////////////////
6988 /// Set Y coordinate of the center of the Pad
6989 
6991 {
6992  fYlowNDC = (gPad->PixeltoY(y-gPad->VtoPixel(0)) - gPad->GetY1())/(gPad->GetY2()-gPad->GetY1())-0.5*fHNDC;
6993  ResizePad();
6994 }
6995 
6996 ////////////////////////////////////////////////////////////////////////////////
6997 /// Set lefthandside of BoundingBox to a value
6998 /// (resize in x direction on left)
6999 
7001 {
7002  fXlowNDC = (gPad->PixeltoX(x) - gPad->GetX1())/(gPad->GetX2()-gPad->GetX1());
7003  fWNDC = fXUpNDC - fXlowNDC;
7004  ResizePad();
7005 }
7006 
7007 ////////////////////////////////////////////////////////////////////////////////
7008 /// Set right hand side of BoundingBox to a value
7009 /// (resize in x direction on right)
7010 
7012 {
7013  fWNDC = (gPad->PixeltoX(x) - gPad->GetX1())/(gPad->GetX2()-gPad->GetX1())-fXlowNDC;
7014  ResizePad();
7015 }
7016 
7017 ////////////////////////////////////////////////////////////////////////////////
7018 /// Set top of BoundingBox to a value (resize in y direction on top)
7019 
7021 {
7022  fHNDC = (gPad->PixeltoY(y-gPad->VtoPixel(0)) - gPad->GetY1())/(gPad->GetY2()-gPad->GetY1())-fYlowNDC;
7023  ResizePad();
7024 }
7025 
7026 ////////////////////////////////////////////////////////////////////////////////
7027 /// Set bottom of BoundingBox to a value
7028 /// (resize in y direction on bottom)
7029 
7031 {
7032  fYlowNDC = (gPad->PixeltoY(y-gPad->VtoPixel(0)) - gPad->GetY1())/(gPad->GetY2()-gPad->GetY1());
7033  fHNDC = fYUpNDC - fYlowNDC;
7034  ResizePad();
7035 }
7036 
Style_t GetFrameFillStyle() const
Definition: TAttPad.h:55
Bool_t Collide(Int_t i, Int_t j, Int_t w, Int_t h)
Check if a box of size w and h collide some primitives in the pad at position i,j.
Definition: TPad.cxx:3035
Bool_t fAbsCoord
Use absolute coordinates.
Definition: TPad.h:101
UShort_t fWidth
Definition: GuiTypes.h:362
void FillCollideGridTGraph(TObject *o)
Definition: TPad.cxx:3163
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
static Int_t gReadLevel
Definition: TPad.cxx:65
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition: TSystem.cxx:1276
Int_t GetNdata()
Return the number of data members of this class Note that in case the list of data members is not yet...
Definition: TClass.cxx:4375
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition: TAttLine.h:43
TVirtualPad * GetPadSave() const
Get save pad.
Definition: TPad.cxx:2696
Int_t VtoPixel(Double_t v) const
Definition: TPad.h:466
Double_t fPixeltoX
xworld = fPixeltoXk + fPixeltoX*xpixel
Definition: TPad.h:56
Bool_t IsReading() const
Definition: TBuffer.h:83
virtual void SetOpacity(Int_t percent)=0
Double_t GetY1() const
Definition: TPad.h:237
Double_t fUymin
Minimum value on the Y axis.
Definition: TPad.h:74
void FeedbackMode(Bool_t set)
Turn rubberband feedback mode on or off.
Definition: TCanvas.cxx:1071
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
virtual Double_t GetMaximum(Double_t maxval=FLT_MAX) const
Return maximum value smaller than maxval of bins in the range, unless the value has been overridden b...
Definition: TH1.cxx:7807
virtual void SetPad(const char *name, const char *title, Double_t xlow, Double_t ylow, Double_t xup, Double_t yup, Color_t color=35, Short_t bordersize=5, Short_t bordermode=-1)
Set all pad parameters.
Definition: TPad.cxx:5849
Style_t GetTitleFont(Option_t *axis="X") const
Return title font.
Definition: TStyle.cxx:843
void SetX(SCoord_t x)
Definition: TPoint.h:49
TList * GetListOfBases()
Return list containing the TBaseClass(es) of a class.
Definition: TClass.cxx:3507
virtual void SetAlpha(Float_t a)
Definition: TColor.h:66
Short_t fY
Definition: GuiTypes.h:361
void DrawCollideGrid()
This method draws the collide grid on top of the canvas.
Definition: TPad.cxx:3276
static Int_t DecreaseDirLevel()
Decrease the indentation level for ls().
Definition: TROOT.cxx:2683
float xmin
Definition: THbookFile.cxx:93
virtual void DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2)=0
virtual Bool_t ProcessEvents()
Process pending events (GUI, timers, sockets).
Definition: TSystem.cxx:424
static void PolyLine(Int_t event, Int_t px, Int_t py, Int_t mode)
Create a new PolyLine in gPad.
Float_t GetLeftMargin() const
Definition: TAttPad.h:44
void PaintLineNDC(Double_t u1, Double_t v1, Double_t u2, Double_t v2)
Paint line in normalized coordinates.
Definition: TPad.cxx:4121
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
virtual void DrawClassObject(const TObject *obj, Option_t *option="")
Draw class inheritance tree of the class to which obj belongs.
Definition: TPad.cxx:1305
Double_t GetAbsYlowNDC() const
Definition: TPad.h:216
void SetPadGridX(Bool_t gridx)
Definition: TStyle.h:336
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition: TH1.cxx:8397
EImageFileTypes
Definition: TImage.h:36
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:854
TList * fPrimitives
->List of primitives (subpads)
Definition: TPad.h:106
virtual void ResizePad(Option_t *option="")
Compute pad conversion coefficients.
Definition: TPad.cxx:5353
virtual void Draw(Option_t *option="")
Draw this pavetext with its current attributes.
Definition: TPaveText.cxx:234
Double_t Floor(Double_t x)
Definition: TMath.h:599
virtual void SetCursor(ECursor cursor)
Set cursor.
Definition: TCanvas.cxx:1891
void SetPadLeftMargin(Float_t margin=0.1)
Definition: TStyle.h:334
Float_t GetPadLeftMargin() const
Definition: TStyle.h:198
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition: TAxis.cxx:444
Double_t YtoPad(Double_t y) const
Convert y from Y to pad.
Definition: TPad.cxx:3359
ABC describing GUI independent main window (with menubar, scrollbars and a drawing area)...
Definition: TCanvasImp.h:30
virtual void DrawPolyLineNDC(Int_t n, const Double_t *u, const Double_t *v)=0
TVirtualPad * GetSelectedPad() const
Definition: TCanvas.h:152
UShort_t fHeight
Definition: GuiTypes.h:362
virtual TBox * DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Draw this box with new coordinates.
Definition: TBox.cxx:189
virtual void SetMaximum(Double_t maximum=-1111)
Definition: TH1.h:390
This class displays a legend box (TPaveText) containing several legend entries.
Definition: TLegend.h:23
Int_t UtoPixel(Double_t u) const
Definition: TPad.h:454
auto * m
Definition: textangle.C:8
TList * GetListOfPrimitives() const
Definition: TPad.h:240
TH1 * GetHistogram() const
Returns a pointer to the histogram used to draw the axis Takes into account the two following cases...
Definition: THStack.cxx:479
The Histogram stack class.
Definition: THStack.h:31
TString fTitle
Pad title.
Definition: TPad.h:109
R__EXTERN Int_t gErrorIgnoreLevel
Definition: TError.h:105
virtual void DrawCrosshair()
Function called to draw a crosshair in the canvas.
Definition: TPad.cxx:1506
virtual Short_t GetBorderSize() const
Definition: TPad.h:197
short Style_t
Definition: RtypesCore.h:76
virtual void SetLimits(Double_t xmin, Double_t xmax)
Definition: TAxis.h:154
virtual TVirtualPad * GetPad(Int_t subpadnumber) const
Get a pointer to subpadnumber of this pad.
Definition: TPad.cxx:2853
Double_t Log(Double_t x)
Definition: TMath.h:648
virtual TBox * AddBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Add a new graphics box to this pavetext.
Definition: TPaveText.cxx:157
Color_t GetTitleTextColor() const
Definition: TStyle.h:256
Double_t GetX2() const
Definition: TBox.h:53
short Version_t
Definition: RtypesCore.h:61
virtual void XYtoAbsPixel(Double_t x, Double_t y, Int_t &xpixel, Int_t &ypixel) const
Definition: TPad.h:522
virtual void SetBatch(Bool_t batch=kTRUE)
Set pad in batch mode.
Definition: TPad.cxx:2764
virtual Color_t GetTextColor() const
Return the text color.
Definition: TAttText.h:34
Bool_t fGridx
Set to true if grid along X.
Definition: TPad.h:99
Double_t fPhi
phi angle to view as lego/surface
Definition: TPad.h:79
Int_t GetNmethods()
Return the number of methods of this class Note that in case the list of methods is not yet created...
Definition: TClass.cxx:4394
TVirtualPadPainter * GetCanvasPainter()
Access and (probably) creation of pad painter.
Definition: TCanvas.cxx:2351
void CallRecursiveRemoveIfNeeded(TObject &obj)
call RecursiveRemove for obj if gROOT is valid and obj.TestBit(kMustCleanup) is true.
Definition: TROOT.h:391
virtual void WCtoNDC(const Float_t *pw, Float_t *pn)=0
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Computes distance from point (px,py) to the object.
Definition: TObject.cxx:186
float Float_t
Definition: RtypesCore.h:53
void ws()
Definition: ws.C:62
Int_t GetTickx() const
Definition: TPad.h:233
virtual void SetDirectory(TDirectory *dir)
By default when an histogram is created, it is added to the list of histogram objects in the current ...
Definition: TH1.cxx:8194
virtual Bool_t CanLoopOnPrimitives() const
float Size_t
Definition: RtypesCore.h:83
virtual void Paint(Option_t *option="")
Paint all primitives in pad.
Definition: TPad.cxx:3371
virtual void SetBorderMode(Short_t bordermode)
Definition: TWbox.h:49
virtual Short_t GetTextAlign() const
Return the text alignment.
Definition: TAttText.h:32
const char Option_t
Definition: RtypesCore.h:62
virtual TLine * AddLine(Double_t x1=0, Double_t y1=0, Double_t x2=0, Double_t y2=0)
Add a new graphics line to this pavetext.
Definition: TPaveText.cxx:170
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition: TAxis.cxx:504
Int_t YtoPixel(Double_t y) const
Definition: TPad.h:510
Definition: Rtypes.h:59
virtual void UseCurrentStyle()
Replace current frame attributes by current style.
Definition: TFrame.cxx:159
Int_t GetCanvasID() const
Get canvas identifier.
Definition: TCanvas.h:163
float ymin
Definition: THbookFile.cxx:93
All ROOT classes may have RTTI (run time type identification) support added.
Definition: TDataMember.h:31
void CopyBackgroundPixmaps(TPad *start, TPad *stop, Int_t x, Int_t y)
Copy pixmaps of pads laying below pad "stop" into pad "stop".
Definition: TPad.cxx:3769
Create a Box.
Definition: TBox.h:24
virtual Bool_t IsRetained() const
Is pad retained ?
Definition: TPad.cxx:2740
const Ssiz_t kNPOS
Definition: RtypesCore.h:111
Int_t GetPixmapID() const
Definition: TPad.h:261
virtual Double_t GetNormFactor() const
Definition: TH1.h:295
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:638
void PaintPadFrame(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax)
Paint histogram/graph frame.
Definition: TPad.cxx:3569
Definition: Buttons.h:33
static Int_t GetColorDark(Int_t color)
Static function: Returns the dark color number corresponding to n If the TColor object does not exist...
Definition: TColor.cxx:1922
Float_t GetBottomMargin() const
Definition: TAttPad.h:43
virtual void SetVertical(Bool_t vert=kTRUE)
Set pad vertical (default) or horizontal.
Definition: TPad.cxx:6382
TClass * GetClassPointer(Bool_t load=kTRUE)
Get pointer to the base class TClass.
Definition: TBaseClass.cxx:63
R__EXTERN TStyle * gStyle
Definition: TStyle.h:402
Float_t fBottomMargin
BottomMargin.
Definition: TAttPad.h:23
Int_t fNumPaletteColor
Number of objects with an automatic color.
Definition: TPad.h:115
void PaintFillArea(Int_t n, Float_t *x, Float_t *y, Option_t *option="")
Definition: TPad.cxx:3795
Clear after CR.
Definition: TPad.h:158
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
virtual void RangeChanged()
Definition: TPad.h:308
virtual void SetSelected(TObject *obj)
Set selected.
Definition: TPad.cxx:2796
virtual void Draw(Option_t *option="")
Draw this legend with its current attributes.
Definition: TLegend.cxx:452
THist< 1, float, THistStatContent, THistStatUncertainty > TH1F
Definition: THist.hxx:285
Definition: Rtypes.h:58
TH1 * h
Definition: legend2.C:5
static void SaveColor(std::ostream &out, Int_t ci)
Save a color with index > 228 as a C++ statement(s) on output stream out.
Definition: TColor.cxx:2095
void PaintPolyLineNDC(Int_t n, Double_t *x, Double_t *y, Option_t *option="")
Paint polyline in CurrentPad NDC coordinates.
Definition: TPad.cxx:4275
Short_t fBorderSize
pad bordersize in pixels
Definition: TPad.h:96
Int_t fCGnx
! Size of the collide grid along x
Definition: TPad.h:118
TH1F * DrawFrame(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax, const char *title="")
Draw an empty pad frame with X and Y axis.
Definition: TPad.cxx:1555
virtual void DrawPolyMarker(Int_t n, Float_t *x, Float_t *y)=0
TObject * GetSelected() const
Get selected.
Definition: TCanvas.h:147
virtual void SetBBoxCenter(const TPoint &p)
Set center of the Pad.
Definition: TPad.cxx:6971
Bool_t GetPadGridY() const
Definition: TStyle.h:201
virtual void SetFixedAspectRatio(Bool_t fixed=kTRUE)
Fix pad aspect ratio to current value if fixed is true.
Definition: TPad.cxx:5729
virtual Double_t GetSumOfWeights() const
Return the sum of weights excluding under/overflows.
Definition: TH1.cxx:7232
Int_t GetTicky() const
Definition: TPad.h:234
virtual void SetBorderMode(Short_t bordermode)
Definition: TPad.h:317
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4763
virtual Float_t GetTextAngle() const
Return the text angle.
Definition: TAttText.h:33
virtual TObject * Last() const
Return the last object in the list. Returns 0 when list is empty.
Definition: TList.cxx:689
A TMultiGraph is a collection of TGraph (or derived) objects.
Definition: TMultiGraph.h:35
virtual ~TPad()
Pad destructor.
Definition: TPad.cxx:374
virtual Color_t GetHighLightColor() const
Get highlight color.
Definition: TPad.cxx:2662
Double_t fAbsXlowNDC
Absolute X top left corner of pad in NDC [0,1].
Definition: TPad.h:68
virtual void AddFirst(TObject *obj)
Add object at the beginning of the list.
Definition: TList.cxx:97
See TView3D.
Definition: TView.h:25
virtual TText * AddText(Double_t x1, Double_t y1, const char *label)
Add a new Text line to this pavetext at given coordinates.
Definition: TPaveText.cxx:183
virtual Bool_t IsVertical() const
Definition: TPad.h:271
const Int_t kMAXLEVELS
Definition: TGeometry.h:27
SCoord_t fX
Definition: TPoint.h:35
void FillCollideGridTFrame(TObject *o)
Definition: TPad.cxx:3137
Buffer base class used for serializing objects.
Definition: TBuffer.h:40
TList * fExecs
List of commands to be executed when a pad event occurs.
Definition: TPad.h:107
virtual void CopyPixmap()
Copy the pixmap of the pad to the canvas.
Definition: TPad.cxx:1032
EEventType
Definition: Buttons.h:15
virtual TObject * FindObject(const char *name) const
Search if object named name is inside this pad or in pads inside this pad.
Definition: TPad.cxx:2574
TPluginHandler * FindHandler(const char *base, const char *uri=0)
Returns the handler if there exists a handler for the specified URI.
TVirtualPad * GetPadSave() const
Definition: TCanvas.h:145
Int_t XtoPixel(Double_t x) const
Definition: TPad.h:488
Double_t GetAbsXlowNDC() const
Definition: TPad.h:215
if object in a pad cannot be picked
Definition: TObject.h:63
Int_t GetLogz() const
Definition: TPad.h:253
virtual void SetMinimum(Double_t minimum=-1111)
Definition: TH1.h:391
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
#define gROOT
Definition: TROOT.h:402
TList * GetListOfDataMembers(Bool_t load=kTRUE)
Return list containing the TDataMembers of a class.
Definition: TClass.cxx:3617
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:585
virtual void DivideSquare(Int_t n, Float_t xmargin=0.01, Float_t ymargin=0.01, Int_t color=0)
"n" is the total number of sub-pads.
Definition: TPad.cxx:1252
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
virtual void GetRangeAxis(Double_t &xmin, Double_t &ymin, Double_t &xmax, Double_t &ymax)
Return pad axis coordinates range.
Definition: TPad.cxx:2896
Int_t GetPadTickY() const
Definition: TStyle.h:203
Double_t fUxmax
Maximum value on the X axis.
Definition: TPad.h:75
Int_t LoadPlugin()
Load the plugin library for this handler.
SCoord_t fY
Definition: TPoint.h:36
void PaintBorder(Color_t color, Bool_t tops)
Paint the pad border.
Definition: TPad.cxx:3433
void SetTitleFont(Style_t font=62, Option_t *axis="X")
Definition: TStyle.cxx:1402
static constexpr double ps
Basic string class.
Definition: TString.h:125
1-D histogram with a float per channel (see TH1 documentation)}
Definition: TH1.h:567
Int_t fCGny
! Size of the collide grid along y
Definition: TPad.h:119
Bool_t PlaceBox(TObject *o, Double_t w, Double_t h, Double_t &xl, Double_t &yb)
Place a box in NDC space.
Definition: TPad.cxx:3048
Double_t fUymax
Maximum value on the Y axis.
Definition: TPad.h:76
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:168
virtual void Update()
Update pad.
Definition: TPad.cxx:2804
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1099
virtual void SetBBoxY2(const Int_t y)=0
int Int_t
Definition: RtypesCore.h:41
virtual Int_t CreateDrawable(UInt_t w, UInt_t h)=0
bool Bool_t
Definition: RtypesCore.h:59
TVirtualPad * GetSelectedPad() const
Get selected pad.
Definition: TPad.cxx:2687
virtual void PaintModified()
Traverse pad hierarchy and (re)paint only modified pads.
Definition: TPad.cxx:3588
Double_t GetY2() const
Definition: TBox.h:55
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:57
SCoord_t GetY() const
Definition: TPoint.h:48
virtual TH1 * DrawCopy(Option_t *option="", const char *name_postfix="_copy") const
Copy this histogram and Draw in the current pad.
Definition: TH1.cxx:3016
virtual void Draw(Option_t *option="")
Default Draw method for all objects.
Definition: TObject.cxx:195
virtual void SetX1(Double_t x1)
Definition: TBox.h:63
virtual void SetFillStyle(Style_t fstyle)
Set the fill area style.
Definition: TAttFill.h:39
Double_t fVtoPixel
ypixel = fVtoPixelk + fVtoPixel*vndc
Definition: TPad.h:52
virtual void SetBBoxCenterX(const Int_t x)
Set X coordinate of the center of the Pad.
Definition: TPad.cxx:6981
TObject * GetClickSelected() const
Definition: TCanvas.h:148
Double_t GetUxmin() const
Returns the minimum x-coordinate value visible on the pad. If log axis the returned value is in decad...
Definition: TPad.h:223
TAttText * GetAttDate()
Definition: TStyle.h:156
The histogram statistics painter class.
Definition: TPaveStats.h:18
Double_t GetUxmax() const
Returns the maximum x-coordinate value visible on the pad. If log axis the returned value is in decad...
Definition: TPad.h:227
Bool_t IsNaN(Double_t x)
Definition: TMath.h:777
Option_t * GetOption() const
Definition: TCollection.h:249
Double_t fYUpNDC
Definition: TPad.h:64
Definition: Buttons.h:30
virtual void UseCurrentStyle()
Set current style settings in this object This function is called when either TCanvas::UseCurrentStyl...
Definition: TObject.cxx:715
#define NotFree(i, j)
Definition: TPad.cxx:3072
virtual void SetLineWidth(Width_t lwidth)=0
virtual TObject * GetParent() const
Definition: TAxis.h:123
virtual Int_t Clip(Float_t *x, Float_t *y, Float_t xclipl, Float_t yclipb, Float_t xclipr, Float_t yclipt)
Clipping routine: Cohen Sutherland algorithm.
Definition: TPad.cxx:664
SCoord_t GetX() const
Definition: TPoint.h:47
Int_t fPadPaint
Set to 1 while painting the pad.
Definition: TPad.h:93
Double_t fPixeltoXk
Conversion coefficient for pixel to X World.
Definition: TPad.h:55
Float_t fTopMargin
TopMargin.
Definition: TAttPad.h:24
TString & Prepend(const char *cs)
Definition: TString.h:607
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition: TH1.cxx:8408
ECursor
Definition: TVirtualX.h:44
virtual void Modify()
Change current line attributes if necessary.
Definition: TAttLine.cxx:232
virtual void SetX2(Double_t x2)
Definition: TBox.h:64
Frame is requested.
Definition: TPad.h:153
Bool_t IsModified() const
Definition: TPad.h:269
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition: fillpatterns.C:1
Double_t fAbsWNDC
Absolute Width of pad along X in NDC.
Definition: TPad.h:70
void ClearPadSave()
Definition: TCanvas.h:146
virtual Int_t GetEvent() const
Get Event.
Definition: TPad.cxx:2630
static double A[]
void SetPadBottomMargin(Float_t margin=0.1)
Definition: TStyle.h:332
Double_t fAbsPixeltoYk
Conversion coefficient for absolute pixel to Y World.
Definition: TPad.h:57
void SetY(SCoord_t y)
Definition: TPoint.h:50
Double_t GetXlowNDC() const
Definition: TPad.h:209
virtual void ShowGuidelines(TObject *object, const Int_t event, const char mode='i', const bool cling=true)
Shows lines to indicate if a TAttBBox2D object is aligned to the center or to another object...
Definition: TPad.cxx:6028
Short_t Abs(Short_t d)
Definition: TMathBase.h:108
bit set when zooming on Y axis
Definition: TH1.h:164
virtual TVirtualPad * cd(Int_t subpadnumber=0)=0
virtual Width_t GetLineWidth() const
Return the line width.
Definition: TAttLine.h:35
don&#39;t draw stats box
Definition: TH1.h:160
Iterator of linked list.
Definition: TList.h:197
virtual void RecursiveRemove(TObject *obj)
Recursively remove object from a pad and its sub-pads.
Definition: TPad.cxx:5161
void SetPadBorderSize(Width_t size=1)
Definition: TStyle.h:330
virtual void SetTopMargin(Float_t topmargin)
Set Pad top margin in fraction of the pad height.
Definition: TAttPad.cxx:130
virtual Bool_t IsEditable() const =0
virtual void DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2, EBoxMode mode)=0
virtual Double_t GetX1() const =0
Int_t fNumber
pad number identifier
Definition: TPad.h:87
virtual void AddLast(TObject *obj)
Add object at the end of the list.
Definition: TList.cxx:149
Int_t GetHatchesLineWidth() const
Definition: TStyle.h:186
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:627
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
static constexpr double mg
void PaintHatches(Double_t dy, Double_t angle, Int_t nn, Double_t *xx, Double_t *yy)
This routine draw hatches inclined with the angle "angle" and spaced of "dy" in normalized device coo...
Definition: TPad.cxx:3944
Double_t fAbsYlowNDC
Absolute Y top left corner of pad in NDC [0,1].
Definition: TPad.h:69
virtual TObject * FindObject(const char *name) const
Delete a TObjLink object.
Definition: TList.cxx:574
static void Text(Int_t event, Int_t px, Int_t py, Int_t mode)
Create a new TLatex at the cursor position in gPad.
if object in a list can be deleted
Definition: TObject.h:58
Definition: Buttons.h:30
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition: TAxis.cxx:514
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
Definition: TString.h:628
Double_t GetHatchesSpacing() const
Definition: TStyle.h:187
virtual void SetToolTipText(const char *text, Long_t delayms=1000)
Set tool tip text associated with this pad.
Definition: TPad.cxx:6368
void SetOptLogz(Int_t logz=1)
Definition: TStyle.h:306
virtual Style_t GetFillStyle() const =0
virtual void SaveImage(TVirtualPad *pad, const char *fileName, Int_t type) const =0
Double_t GetHNDC() const
Definition: TPad.h:212
virtual Int_t ClippingCode(Double_t x, Double_t y, Double_t xcl1, Double_t ycl1, Double_t xcl2, Double_t ycl2)
Compute the endpoint codes for TPad::Clip.
Definition: TPad.cxx:806
virtual void SetTextFont(Font_t tfont=62)
Set the text font.
Definition: TAttText.h:45
void SetClickSelected(TObject *obj)
Definition: TCanvas.h:209
virtual Style_t GetLineStyle() const
Return the line style.
Definition: TAttLine.h:34
virtual Int_t GetDimension() const
Definition: TH1.h:277
void SetTitleBorderSize(Width_t size=2)
Definition: TStyle.h:381
Int_t GetLogx() const
Definition: TPad.h:251
virtual TVirtualViewer3D * GetViewer3D(Option_t *type="")
Create/obtain handle to 3D viewer.
Definition: TPad.cxx:6822
#define SafeDelete(p)
Definition: RConfig.h:509
Provides 3D viewer interface (TVirtualViewer3D) support on a pad.
Definition: TViewer3DPad.h:20
virtual void DrawTextNDC(Double_t u, Double_t v, const char *text, ETextMode mode)=0
TVirtualPad * cd(Int_t subpadnumber=0)
Set Current pad.
Definition: TPad.cxx:585
static const double x2[5]
Double_t fYtoAbsPixelk
Conversion coefficient for Y World to absolute pixel.
Definition: TPad.h:43
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:128
Double_t x[n]
Definition: legend1.C:17
Int_t GetLogy() const
Definition: TPad.h:252
Int_t fNextPaletteColor
Next automatic color.
Definition: TPad.h:116
void PaintDate()
Paint the current date and time if the option date is on.
Definition: TPad.cxx:3538
virtual void Cleared(TVirtualPad *pad)
Emit pad Cleared signal.
Definition: TCanvas.cxx:740
virtual TVirtualPad * GetVirtCanvas() const
Get virtual canvas.
Definition: TPad.cxx:2654
virtual void Close(Option_t *option="")
Delete all primitives in pad and pad itself.
Definition: TPad.cxx:976
void Class()
Definition: Class.C:29
R__EXTERN Int_t(* gThreadXAR)(const char *xact, Int_t nb, void **ar, Int_t *iret)
Definition: TVirtualPad.h:287
Bool_t GetPadGridX() const
Definition: TStyle.h:200
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition: TSystem.cxx:445
virtual Bool_t IsBatch() const
Is pad in batch mode ?
Definition: TPad.cxx:2732
virtual const char * GetName() const =0
Returns name of object.
TFrame * GetFrame()
Get frame.
Definition: TPad.cxx:2812
virtual void DrawLineNDC(Double_t u1, Double_t v1, Double_t u2, Double_t v2)=0
Int_t GetPadTickX() const
Definition: TStyle.h:202
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
virtual Float_t GetTextSize() const
Return the text size.
Definition: TAttText.h:36
void HighLight(Color_t col=kRed, Bool_t set=kTRUE)
Highlight pad.
Definition: TPad.cxx:2908
virtual void Draw(Option_t *option="")
Draw this arrow with its current attributes.
Definition: TArrow.cxx:122
Int_t fLogx
(=0 if X linear scale, =1 if log scale)
Definition: TPad.h:90
virtual Width_t GetLineWidth() const =0
TFrame * fFrame
! Pointer to 2-D frame (if one exists)
Definition: TPad.h:110
UInt_t GetWindowHeight() const
Definition: TCanvas.h:168
static Int_t GetMaxPickDistance()
Static function (see also TPad::SetMaxPickDistance)
Definition: TPad.cxx:2670
Short_t GetBorderSize() const
Definition: TWbox.h:39
void PaintTextNDC(Double_t u, Double_t v, const char *text)
Paint text in CurrentPad NDC coordinates.
Definition: TPad.cxx:4401
virtual void Modify()
Change current fill area attributes if necessary.
Definition: TAttFill.cxx:209
Bool_t fEditable
True if canvas is editable.
Definition: TPad.h:102
const Int_t kFatal
Definition: TError.h:42
virtual void NewPage()=0
virtual void ExecuteEventAxis(Int_t event, Int_t px, Int_t py, TAxis *axis)
Execute action corresponding to one event for a TAxis object (called by TAxis::ExecuteEvent.) This member function is called when an axis is clicked with the locator.
Definition: TPad.cxx:2238
TCanvas * fCanvas
! Pointer to mother canvas
Definition: TPad.h:105
virtual void SetCrosshair(Int_t crhair=1)
Set crosshair active/inactive.
Definition: TPad.cxx:6343
const char * GetTitle() const
Returns title of object.
Definition: TPad.h:256
Double_t Log10(Double_t x)
Definition: TMath.h:651
UInt_t GetWw() const
Get Ww.
Definition: TCanvas.h:169
virtual void DrawText(Double_t x, Double_t y, const char *text, ETextMode mode)=0
static double p2(double t, double a, double b, double c)
TCanvasImp * GetCanvasImp() const
Get canvas implementation pointer if any.
Definition: TCanvas.h:164
void SetPadTickX(Int_t tickx)
Definition: TStyle.h:338
virtual void SetBBoxX1(const Int_t x)
Set lefthandside of BoundingBox to a value (resize in x direction on left)
Definition: TPad.cxx:7000
static const double x4[22]
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute distance from point px,py to a box.
Definition: TPad.cxx:1078
virtual void SetLineStyle(Style_t lstyle)=0
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
Definition: TAttMarker.h:38
Double_t fXUpNDC
Definition: TPad.h:63
TString & Append(const char *cs)
Definition: TString.h:495
void SetSelectedPad(TPad *pad)
Definition: TCanvas.h:210
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2231
static constexpr double L
virtual void ls(Option_t *option="") const
List all primitives in pad.
Definition: TPad.cxx:2943
static void DrawColorTable()
Static function to Display Color Table in a pad.
Definition: TPad.cxx:1600
Base class for several text objects.
Definition: TText.h:23
Int_t fCrosshairPos
Position of crosshair.
Definition: TPad.h:95
Abstract 3D shapes viewer.
void SetTitleTextColor(Color_t color=1)
Definition: TStyle.h:378
Int_t Finite(Double_t x)
Definition: TMath.h:654
Int_t GetOptDate() const
Definition: TStyle.h:226
Double_t fAbsHNDC
Absolute Height of pad along Y in NDC.
Definition: TPad.h:71
TH1F * GetHistogram()
Returns a pointer to the histogram used to draw the axis.
Int_t fLogz
(=0 if Z linear scale, =1 if log scale)
Definition: TPad.h:92
virtual void SetLogx(Int_t value=1)
Set Lin/Log scale for X.
Definition: TPad.cxx:5784
virtual Rectangle_t GetBBox()=0
TH1F * h1
Definition: legend1.C:5
virtual void SetFillColor(Color_t fcolor)=0
Int_t GetColorPalette(Int_t i) const
Return color number i in current palette.
Definition: TStyle.cxx:735
constexpr Double_t Pi()
Definition: TMath.h:40
virtual TObject * GetSelected() const
Get selected.
Definition: TPad.cxx:2678
virtual void RedrawAxis(Option_t *option="")
Redraw the frame axis Redrawing axis may be necessary in case of superimposed histograms when one or ...
Definition: TPad.cxx:5185
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition: TVirtualPad.h:49
void SaveSource(const char *filename="", Option_t *option="")
Save primitives in this canvas as a C++ macro file.
Definition: TCanvas.cxx:1711
virtual void SetBorderSize(Short_t bordersize)
Definition: TWbox.h:50
virtual TPad * Pick(Int_t px, Int_t py, TObjLink *&pickobj)
Search for an object at pixel position px,py.
Definition: TPad.cxx:4445
virtual void DestroyDrawable(Int_t device)=0
virtual void Draw(Option_t *option="")
Draw Pad in Current pad (re-parent pad if necessary).
Definition: TPad.cxx:1272
virtual void Text(Double_t x, Double_t y, const char *string)=0
Fixed position.
Definition: TPad.h:157
R__EXTERN TPluginManager * gPluginMgr
Double_t fYlowNDC
Y bottom left corner of pad in NDC [0,1].
Definition: TPad.h:62
object has not been deleted
Definition: TObject.h:78
Definition: Buttons.h:38
short Color_t
Definition: RtypesCore.h:79
virtual void SetEditable(Bool_t mode=kTRUE)
Set pad editable yes/no If a pad is not editable:
Definition: TPad.cxx:5753
Short_t fX
Definition: GuiTypes.h:361
Bool_t OpaqueMoving() const
Is pad moving in opaque mode ?
Definition: TCanvas.h:183
virtual void SetTextAlign(Short_t align=11)
Set the text alignment.
Definition: TAttText.h:41
virtual Short_t GetBorderSize() const =0
static Bool_t SupportAlpha()
Static function returning "true" if transparency is supported.
Definition: TCanvas.cxx:2235
Double_t fX2
X of upper X coordinate.
Definition: TPad.h:37
virtual Option_t * GetDrawOption() const
Get option used by the graphics system to draw this object.
Definition: TObject.cxx:341
Int_t GetEventX() const
Get X event.
Definition: TCanvas.h:142
Definition: TPoint.h:31
Int_t GetMaxIndex(Int_t dim) const
Return maximum index for array dimension "dim".
A doubly linked list.
Definition: TList.h:44
virtual void CopyPixmaps()
Copy the sub-pixmaps of the pad to the canvas.
Definition: TPad.cxx:1046
void SetOptLogx(Int_t logx=1)
Definition: TStyle.h:304
Double_t GetYlowNDC() const
Definition: TPad.h:210
Double_t fXtoPixel
xpixel = fXtoPixelk + fXtoPixel*xworld
Definition: TPad.h:42
Bool_t * fCollideGrid
! Grid used to find empty space when adding a box (Legend) in a pad
Definition: TPad.h:117
Double_t fPixeltoY
yworld = fPixeltoYk + fPixeltoY*ypixel
Definition: TPad.h:59
void PaintPolyLine(Int_t n, Float_t *x, Float_t *y, Option_t *option="")
Paint polyline in CurrentPad World coordinates.
Definition: TPad.cxx:4177
Int_t GetEvent() const
Get Event.
Definition: TCanvas.h:141
virtual void AddExec(const char *name, const char *command)
Add a new TExec object to the list of Execs.
Definition: TPad.cxx:437
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition: TAttLine.h:40
virtual Int_t UtoPixel(Double_t u) const =0
virtual void Delete(Option_t *option="")
Delete this object.
Definition: TObject.cxx:169
Using a TBrowser one can browse all ROOT objects.
Definition: TBrowser.h:37
TObject * fPadView3D
! 3D View of this TPad
Definition: TPad.h:113
virtual Double_t GetY2() const =0
static Int_t GetColorBright(Int_t color)
Static function: Returns the bright color number corresponding to n If the TColor object does not exi...
Definition: TColor.cxx:1890
Double_t fVtoPixelk
Conversion coefficient for V NDC to pixel.
Definition: TPad.h:51
Double_t fXtoAbsPixelk
Conversion coefficient for X World to absolute pixel.
Definition: TPad.h:40
virtual TCanvasImp * GetCanvasImp() const
Get canvas implementation pointer if any.
Definition: TPad.cxx:2622
Bool_t GetGridy() const
Definition: TPad.h:231
virtual void SetRange(Int_t first=0, Int_t last=0)
Set the viewing range for the axis from bin first to last.
Definition: TAxis.cxx:903
TPad * fMother
! pointer to mother of the list
Definition: TPad.h:104
float ymax
Definition: THbookFile.cxx:93
Double_t XtoPad(Double_t x) const
Convert x from X to pad.
Definition: TPad.cxx:3347
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute action corresponding to one event.
Definition: TPad.cxx:1663
virtual TVirtualPad * GetMother() const
Definition: TPad.h:254
Short_t GetBorderMode() const
Definition: TWbox.h:38
virtual void SetDoubleBuffer(Int_t mode=1)
Set double buffer mode ON or OFF.
Definition: TPad.cxx:2788
virtual Int_t GetPoint(Int_t i, Double_t &x, Double_t &y) const
Get x and y values for point number i.
Definition: TGraph.cxx:1580
virtual Int_t GetEventX() const
Get X event.
Definition: TPad.cxx:2638
virtual void SetAttLinePS(Color_t color, Style_t style, Width_t lwidth)
Set postscript line attributes.
Definition: TPad.cxx:5893
Int_t IncrementPaletteColor(Int_t i, TString opt)
Increment (i==1) or set (i>1) the number of autocolor in the pad.
Definition: TPad.cxx:2957
Definition: Buttons.h:33
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition: TObject.cxx:321
void SetPadBorderMode(Int_t mode=1)
Definition: TStyle.h:331
virtual void SetBottomMargin(Float_t bottommargin)
Set Pad bottom margin in fraction of the pad height.
Definition: TAttPad.cxx:100
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:655
TPaveText * pt
Int_t fPixmapID
! Off-screen pixmap identifier
Definition: TPad.h:83
virtual void DrawPolyLine(Int_t n, const Double_t *x, const Double_t *y)=0
ROOT::R::TRInterface & r
Definition: Object.C:4
virtual void SetCursor(ECursor cursor)
Set cursor type.
Definition: TPad.cxx:2780
Int_t GetLast() const
Return last bin on the axis i.e.
Definition: TAxis.cxx:455
virtual void DeleteToolTip(TObject *tip)
Delete tool tip object.
Definition: TPad.cxx:6772
virtual Bool_t HasCrosshair() const
Return kTRUE if the crosshair has been activated (via SetCrosshair).
Definition: TPad.cxx:6321
Class to manage histogram axis.
Definition: TAxis.h:30
R__EXTERN TSystem * gSystem
Definition: TSystem.h:540
virtual void CloseToolTip(TObject *tip)
Hide tool tip.
Definition: TPad.cxx:6794
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition: TH1.cxx:2969
Definition: Buttons.h:33
SVector< double, 2 > v
Definition: Dict.h:5
void SetPadColor(Color_t color=19)
Definition: TStyle.h:329
PS Printing.
Definition: TPad.h:156
Int_t GetPadBorderMode() const
Definition: TStyle.h:195
Int_t YtoAbsPixel(Double_t y) const
Definition: TPad.h:500
Bool_t OpaqueResizing() const
Is pad resizing in opaque mode ?
Definition: TCanvas.h:184
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:37
virtual void SetBBoxX1(const Int_t x)=0
void inv(rsa_NUMBER *, rsa_NUMBER *, rsa_NUMBER *)
Definition: rsaaux.cxx:949
virtual void Range(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Set world coordinate system for the pad.
Definition: TPad.cxx:5103
virtual Int_t XtoAbsPixel(Double_t x) const =0
auto * a
Definition: textangle.C:12
virtual void SetAttFillPS(Color_t color, Style_t style)
Set postscript fill area attributes.
Definition: TPad.cxx:5882
virtual void DrawLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2)=0
virtual void DeleteExec(const char *name)
Remove TExec name from the list of Execs.
Definition: TPad.cxx:1062
virtual Font_t GetTextFont() const
Return the text font.
Definition: TAttText.h:35
Long_t ExecPlugin(int nargs, const T &... params)
virtual TPoint GetBBoxCenter()
Return the center of the Pad as TPoint in pixels.
Definition: TPad.cxx:6957
virtual Bool_t IsEditable() const
Definition: TPad.h:267
Float_t GetPadBottomMargin() const
Definition: TStyle.h:196
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:818
UInt_t GetWh() const
Get Wh.
Definition: TCanvas.h:170
virtual void UseCurrentStyle()
Force a copy of current style for all objects in pad.
Definition: TPad.cxx:6600
Float_t GetPadRightMargin() const
Definition: TStyle.h:199
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:443
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:561
virtual void SetTextAngle(Float_t tangle=0)
Set the text angle.
Definition: TAttText.h:42
virtual TObject * GetPrimitive(const char *name) const
Get primitive.
Definition: TPad.cxx:2836
Double_t GetAbsWNDC() const
Definition: TPad.h:217
virtual void SetBBoxY2(const Int_t y)
Set bottom of BoundingBox to a value (resize in y direction on bottom)
Definition: TPad.cxx:7030
virtual UInt_t GetWh() const
Get Wh.
Definition: TPad.cxx:2705
TView * fView
! Pointer to 3-D view (if one exists)
Definition: TPad.h:111
void PaintPolyMarker(Int_t n, Float_t *x, Float_t *y, Option_t *option="")
Paint polymarker in CurrentPad World coordinates.
Definition: TPad.cxx:4313
const char * AsSQLString() const
Return the date & time in SQL compatible string format, like: 1997-01-15 20:16:28.
Definition: TDatime.cxx:151
void CopyBackgroundPixmap(Int_t x, Int_t y)
Copy pixmap of this pad as background of the current pad.
Definition: TPad.cxx:3786
virtual void SetView(TView *view=0)
Set the current TView. Delete previous view if view=0.
Definition: TPad.cxx:5873
unsigned int UInt_t
Definition: RtypesCore.h:42
Width_t fLineWidth
Line width.
Definition: TAttLine.h:23
static TVirtualViewer3D * Viewer3D(TVirtualPad *pad=0, Option_t *type="")
Create a Viewer 3D of specified type.
The most important graphics class in the ROOT system.
Definition: TPad.h:29
virtual void SetLineColor(Color_t lcolor)=0
virtual Bool_t BuildingScene() const =0
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
char * Form(const char *fmt,...)
Int_t GetOptLogy() const
Definition: TStyle.h:232
virtual void ResetToolTip(TObject *tip)
Reset tool tip, i.e.
Definition: TPad.cxx:6783
Ssiz_t Length() const
Definition: TString.h:386
A simple line.
Definition: TLine.h:23
double floor(double)
Int_t GetN() const
Definition: TGraph.h:122
virtual void Resized()
Definition: TPad.h:315
virtual void SetAttMarkerPS(Color_t color, Style_t style, Size_t msize)
Set postscript marker attributes.
Definition: TPad.cxx:5905
short Short_t
Definition: RtypesCore.h:35
void AbsCoordinates(Bool_t set)
Definition: TPad.h:166
static Int_t GetColor(const char *hexcolor)
Static method returning color number for color specified by hex color string of form: "#rrggbb"...
Definition: TColor.cxx:1751
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save primitives in this pad on the C++ source file out.
Definition: TPad.cxx:5549
static void IndentLevel()
Functions used by ls() to indent an object hierarchy.
Definition: TROOT.cxx:2746
Int_t GetArrayDim() const
Return number of array dimensions.
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:75
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
Definition: TAttMarker.h:40
void PaintLine3D(Float_t *p1, Float_t *p2)
Paint 3-D line in the CurrentPad.
Definition: TPad.cxx:4141
virtual Int_t GetNumber() const =0
TAxis * GetYaxis()
Definition: TH1.h:316
A TButton object is a user interface object.
Definition: TButton.h:19
virtual TObject * After(const TObject *obj) const
Returns the object after object obj.
Definition: TList.cxx:327
virtual Int_t Exec(const char *shellcmd)
Execute a command.
Definition: TSystem.cxx:661
static double p1(double t, double a, double b)
float xmax
Definition: THbookFile.cxx:93
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:354
Float_t fLeftMargin
LeftMargin.
Definition: TAttPad.h:21
virtual TCanvas * GetCanvas() const
Definition: TPad.h:257
Float_t GetDateX() const
Definition: TStyle.h:183
Int_t GetOptLogz() const
Definition: TStyle.h:233
virtual void Print(const char *filename="") const
Save Pad contents in a file in one of various formats.
Definition: TPad.cxx:4599
virtual void SetCanvasSize(UInt_t ww, UInt_t wh)
Set canvas size.
Definition: TPad.cxx:2772
Double_t fYtoPixel
ypixel = fYtoPixelk + fYtoPixel*yworld
Definition: TPad.h:45
virtual TVirtualPadPainter * GetPainter()
Get pad painter from TCanvas.
Definition: TPad.cxx:6934
virtual void ReadFastArray(Bool_t *b, Int_t n)=0
Int_t GetNumberOfColors() const
Return number of colors in the color palette.
Definition: TStyle.cxx:801
Bool_t fModified
Set to true when pad is modified.
Definition: TPad.h:98
virtual Int_t GetDistancetoAxis(Int_t axis, Int_t px, Int_t py, Double_t &ratio)=0
Int_t GetOptLogx() const
Definition: TStyle.h:231
if object destructor must call RecursiveRemove()
Definition: TObject.h:60
virtual void SetMarkerSize(Size_t msize=1)
Set the marker size.
Definition: TAttMarker.h:41
Int_t fCrosshair
Crosshair type (0 if no crosshair requested)
Definition: TPad.h:94
TGraphErrors * gr
Definition: legend1.C:25
#define gVirtualX
Definition: TVirtualX.h:350
Each class (see TClass) has a linked list of its base class(es).
Definition: TBaseClass.h:33
virtual Double_t GetY1() const =0
virtual TObjLink * FirstLink() const
Definition: TList.h:108
TPad()
Pad default constructor.
Definition: TPad.cxx:131
Define a Frame.
Definition: TFrame.h:19
void LineNotFree(Int_t x1, Int_t x2, Int_t y1, Int_t y2)
Mark as "not free" the cells along a line.
Definition: TPad.cxx:3077
Double_t Cos(Double_t)
Definition: TMath.h:550
Color_t GetTitleFillColor() const
Definition: TStyle.h:255
short Width_t
Definition: RtypesCore.h:78
Double_t fUtoAbsPixelk
Conversion coefficient for U NDC to absolute pixel.
Definition: TPad.h:47
virtual Double_t GetMinimum(Double_t minval=-FLT_MAX) const
Return minimum value larger than minval of bins in the range, unless the value has been overridden by...
Definition: TH1.cxx:7892
Color_t GetHighLightColor() const
Get highlight color.
Definition: TCanvas.h:144
virtual void DrawFrame(Double_t xl, Double_t yl, Double_t xt, Double_t yt, Int_t mode, Int_t border, Int_t dark, Int_t light)=0
virtual void SelectDrawable(Int_t device)=0
char * StrDup(const char *str)
Duplicate the string str.
Definition: TString.cxx:2544
const Bool_t kFALSE
Definition: RtypesCore.h:88
Double_t fY2
Y of upper Y coordinate.
Definition: TPad.h:38
virtual void ResizePad()=0
virtual void BeginScene()=0
Double_t fAspectRatio
ratio of w/h in case of fixed ratio
Definition: TPad.h:81
virtual Color_t GetLineColor() const
Return the line color.
Definition: TAttLine.h:33
virtual void SetY2(Double_t y2)
Definition: TBox.h:66
virtual Int_t YtoAbsPixel(Double_t y) const =0
virtual void PaintBorderPS(Double_t xl, Double_t yl, Double_t xt, Double_t yt, Int_t bmode, Int_t bsize, Int_t dark, Int_t light)
Paint a frame border with Postscript.
Definition: TPad.cxx:3529
virtual void DrawFillArea(Int_t n, const Double_t *x, const Double_t *y)=0
Bool_t GetGridx() const
Definition: TPad.h:230
long Long_t
Definition: RtypesCore.h:50
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
int Ssiz_t
Definition: RtypesCore.h:63
The Canvas class.
Definition: TCanvas.h:31
Width_t GetTitleBorderSize() const
Definition: TStyle.h:259
virtual void Paint(Option_t *option="")
This method must be overridden if a class wants to paint itself.
Definition: TObject.cxx:519
virtual void HideToolTip(Int_t event)
Hide tool tip depending on the event type.
Definition: TPad.cxx:2723
void PaintBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2, Option_t *option="")
Paint box in CurrentPad World coordinates.
Definition: TPad.cxx:3675
Double_t Exp(Double_t x)
Definition: TMath.h:621
void FillCollideGridTBox(TObject *o)
Definition: TPad.cxx:3120
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition: TH1.cxx:8419
static const double x1[5]
Double_t fVtoAbsPixelk
Conversion coefficient for V NDC to absolute pixel.
Definition: TPad.h:50
A Pave (see TPave) with text, lines or/and boxes inside.
Definition: TPaveText.h:21
void SetClickSelectedPad(TPad *pad)
Definition: TCanvas.h:211
Double_t fXtoPixelk
Conversion coefficient for X World to pixel.
Definition: TPad.h:41
Double_t GetX1() const
Definition: TBox.h:52
virtual Double_t GetBinErrorLow(Int_t bin) const
Return lower error associated to bin number bin.
Definition: TH1.cxx:8335
TH1F * GetHistogram() const
Returns a pointer to the histogram used to draw the axis Takes into account the two following cases...
Definition: TGraph.cxx:1469
double Double_t
Definition: RtypesCore.h:55
TLegendEntry * AddEntry(const TObject *obj, const char *label="", Option_t *option="lpf")
Add a new entry to this legend.
Definition: TLegend.cxx:359
Int_t GetGLDevice()
Get GL device.
Definition: TPad.cxx:6910
virtual void ls(Option_t *option="") const
List (ls) all objects in this collection.
virtual Int_t GetEventY() const
Get Y event.
Definition: TPad.cxx:2646
TText * text
TVirtualPad * GetClickSelectedPad() const
Definition: TCanvas.h:153
UInt_t GetWindowWidth() const
Definition: TCanvas.h:167
Bool_t fGridy
Set to true if grid along Y.
Definition: TPad.h:100
int type
Definition: TGX11.cxx:120
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
void SetCanvasSize(UInt_t ww, UInt_t wh)
Set Width and Height of canvas to ww and wh respectively.
Definition: TCanvas.cxx:1878
leg
Definition: legend1.C:34
Print a TSeq at the prompt:
Definition: TDatime.h:115
virtual void SetFillStyle(Style_t fstyle)
Override TAttFill::FillStyle for TPad because we want to handle style=0 as style 4000.
Definition: TPad.cxx:5772
Bool_t IsBatch() const
Is pad in batch mode ?
Definition: TCanvas.h:176
Bool_t fCopyGLDevice
!
Definition: TPad.h:85
Float_t GetPadTopMargin() const
Definition: TStyle.h:197
Definition: Buttons.h:31
static void Pad(Int_t event, Int_t px, Int_t py, Int_t)
Create a new pad in gPad.
TCanvas * style()
Definition: style.C:1
Double_t y[n]
Definition: legend1.C:17
Double_t fTheta
theta angle to view as lego/surface
Definition: TPad.h:78
virtual void SetTextSize(Float_t tsize=1)=0
Bool_t IsGrayscale()
Check whether this canvas is to be drawn in grayscale mode.
Definition: TCanvas.cxx:2307
virtual Color_t GetFillColor() const
Return the fill area color.
Definition: TAttFill.h:30
virtual void GetRange(Double_t &x1, Double_t &y1, Double_t &x2, Double_t &y2)
Return pad world coordinates range.
Definition: TPad.cxx:2885
#define gGLManager
Definition: TVirtualGL.h:162
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:570
The TH1 histogram class.
Definition: TH1.h:56
virtual void SetBBoxY1(const Int_t y)=0
const char * AsString() const
Return the date & time as a string (ctime() format).
Definition: TDatime.cxx:101
#define R__LOCKGUARD(mutex)
The color creation and management class.
Definition: TColor.h:19
void Browse(TBrowser *b)
Browse this collection (called by TBrowser).
virtual void SetBBoxY1(const Int_t y)
Set top of BoundingBox to a value (resize in y direction on top)
Definition: TPad.cxx:7020
void FillCollideGridTH1(TObject *o)
Definition: TPad.cxx:3194
Int_t fTickx
Set to 1 if tick marks along X.
Definition: TPad.h:88
virtual TPoint GetBBoxCenter()=0
Int_t GetCrosshair() const
Return the crosshair type (from the mother canvas) crosshair type = 0 means no crosshair.
Definition: TPad.cxx:6330
virtual void Clear(Option_t *option="")
Remove all objects from the list.
Definition: TList.cxx:399
virtual TObject * WaitPrimitive(const char *pname="", const char *emode="")
Loop and sleep until a primitive with name=pname is found in the pad.
Definition: TPad.cxx:6720
Pad is horizontal.
Definition: TPad.h:154
virtual void GetPadPar(Double_t &xlow, Double_t &ylow, Double_t &xup, Double_t &yup)
Return lower and upper bounds of the pad in NDC coordinates.
Definition: TPad.cxx:2874
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition: TAttLine.h:42
Width_t GetPadBorderSize() const
Definition: TStyle.h:194
void SetPadTopMargin(Float_t margin=0.1)
Definition: TStyle.h:333
TVirtualViewer3D * fViewer3D
! Current 3D viewer
Definition: TPad.h:122
Color_t GetFrameLineColor() const
Definition: TAttPad.h:54
virtual void SetBBoxX2(const Int_t x)
Set right hand side of BoundingBox to a value (resize in x direction on right)
Definition: TPad.cxx:7011
Double_t GetX2() const
Definition: TPad.h:236
virtual void Draw(Option_t *option="")
Draw this box with its current attributes.
Definition: TBox.cxx:180
Int_t GetEventY() const
Get Y event.
Definition: TCanvas.h:143
virtual void SetRightMargin(Float_t rightmargin)
Set Pad right margin in fraction of the pad width.
Definition: TAttPad.cxx:120
virtual Style_t GetLineStyle() const =0
Double_t fXlowNDC
X bottom left corner of pad in NDC [0,1].
Definition: TPad.h:61
Double_t GetAbsHNDC() const
Definition: TPad.h:218
TView * GetView() const
Definition: TPad.h:249
Float_t fRightMargin
RightMargin.
Definition: TAttPad.h:22
Mother of all ROOT objects.
Definition: TObject.h:37
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:405
Bool_t fFixedAspectRatio
True if fixed aspect ratio.
Definition: TPad.h:103
Bool_t IsReading() const
Definition: TStyle.h:274
void Clear(Option_t *option="")
Delete all pad primitives.
Definition: TPad.cxx:614
virtual Bool_t OpaqueMoving() const
Is pad moving in opaque mode ?
Definition: TPad.cxx:2748
virtual Int_t ClipPolygon(Int_t n, Double_t *x, Double_t *y, Int_t nn, Double_t *xc, Double_t *yc, Double_t xclipl, Double_t yclipb, Double_t xclipr, Double_t yclipt)
Clip polygon using the Sutherland-Hodgman algorithm.
Definition: TPad.cxx:855
static Int_t IncreaseDirLevel()
Increase the indentation level for ls().
Definition: TROOT.cxx:2738
virtual void SetDoubleBuffer(Int_t mode=1)
Set Double Buffer On/Off.
Definition: TCanvas.cxx:1900
Double_t GetPhi() const
Definition: TPad.h:220
Double_t GetUymax() const
Returns the maximum y-coordinate value visible on the pad. If log axis the returned value is in decad...
Definition: TPad.h:229
virtual void DrawPolyMarker(Int_t n, const Double_t *x, const Double_t *y)=0
virtual void Browse(TBrowser *b)
Browse pad.
Definition: TPad.cxx:462
virtual void RecordPave(const TObject *obj)
Emit RecordPave() signal.
Definition: TPad.cxx:6918
virtual TLegend * BuildLegend(Double_t x1=0.3, Double_t y1=0.21, Double_t x2=0.3, Double_t y2=0.21, const char *title="", Option_t *option="")
Build a legend from the graphical objects in the pad.
Definition: TPad.cxx:485
const char * GetName() const
Returns name of object.
Definition: TPad.h:255
Int_t XtoAbsPixel(Double_t x) const
Definition: TPad.h:478
Float_t GetTopMargin() const
Definition: TAttPad.h:46
Abstract base class for elements drawn in the editor.
Definition: TAttBBox2D.h:19
virtual void Divide(Int_t nx=1, Int_t ny=1, Float_t xmargin=0.01, Float_t ymargin=0.01, Int_t color=0)
Automatic pad generation by division.
Definition: TPad.cxx:1153
Float_t GetDateY() const
Definition: TStyle.h:184
#define ClassImpQ(name)
Definition: TQObject.h:283
virtual Int_t VtoPixel(Double_t v) const =0
Double_t GetTheta() const
Definition: TPad.h:221
virtual void Add(TObject *obj)
Definition: TList.h:87
auto * l
Definition: textangle.C:4
virtual void PadPaint(TVirtualPad *)
virtual void AutoExec()
Execute the list of Execs when a pad event occurs.
Definition: TPad.cxx:447
void SetTitleFillColor(Color_t color=1)
Definition: TStyle.h:377
virtual void RecursiveRemove(TObject *obj)
Remove object from this collection and recursively remove the object from all other objects (and coll...
Definition: TList.cxx:760
virtual void SetBBoxX2(const Int_t x)=0
virtual Int_t GetMinimumBin() const
Return location of bin with minimum value in the range.
Definition: TH1.cxx:7922
virtual void ReleaseViewer3D(Option_t *type="")
Release current (external) viewer.
Definition: TPad.cxx:6894
virtual void SetBBoxCenterX(const Int_t x)=0
TString fName
Pad name.
Definition: TPad.h:108
virtual UInt_t GetWw() const
Get Ww.
Definition: TPad.cxx:2713
virtual Double_t GetX2() const =0
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:200
virtual Int_t VtoAbsPixel(Double_t v) const =0
void SetSelected(TObject *obj)
Set selected canvas.
Definition: TCanvas.cxx:1947
Double_t fYtoPixelk
Conversion coefficient for Y World to pixel.
Definition: TPad.h:44
Width_t GetFrameBorderSize() const
Definition: TAttPad.h:58
Bool_t fResizing
Definition: TVirtualPad.h:53
void PaintPolyLine3D(Int_t n, Double_t *p)
Paint 3-D polyline in the CurrentPad.
Definition: TPad.cxx:4299
void MakeZombie()
Definition: TObject.h:49
virtual void Paint(Option_t *option="")
Paint this wbox with its current attributes.
Definition: TFrame.cxx:130
Each ROOT class (see TClass) has a linked list of methods.
Definition: TMethod.h:38
virtual void GetRange(Float_t *min, Float_t *max)=0
static void SetGrayscale(Bool_t set=kTRUE)
Set whether all colors should return grayscale values.
Definition: TColor.cxx:2141
virtual Short_t GetBorderMode() const
Definition: TPad.h:196
A Graph is a graphics object made of two arrays X and Y with npoints each.
Definition: TGraph.h:41
Double_t Sin(Double_t)
Definition: TMath.h:547
Int_t NextPaletteColor()
Get the next autocolor in the pad.
Definition: TPad.cxx:2971
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
void SetOptLogy(Int_t logy=1)
Definition: TStyle.h:305
Double_t Ceil(Double_t x)
Definition: TMath.h:593
Style_t GetFrameLineStyle() const
Definition: TAttPad.h:56
virtual void DrawPS(Int_t n, Float_t *xw, Float_t *yw)=0
Double_t fHNDC
Height of pad along Y in NDC.
Definition: TPad.h:66
#define snprintf
Definition: civetweb.c:822
R__EXTERN TVirtualPS * gVirtualPS
Definition: TVirtualPS.h:81
virtual void InvalidateCS()
Empty definition.
virtual TText * DrawText(Double_t x, Double_t y, const char *text)
Draw this text with new coordinates.
Definition: TText.cxx:176
#define gPad
Definition: TVirtualPad.h:285
Double_t AbsPixeltoX(Int_t px)
Definition: TPad.h:167
virtual void SetTextColor(Color_t tcolor=1)
Set the text color.
Definition: TAttText.h:43
virtual TObject * CreateToolTip(const TBox *b, const char *text, Long_t delayms)
Create a tool tip and return its pointer.
Definition: TPad.cxx:6762
Bool_t fEmbeddedGL
!
Definition: TPad.h:86
virtual void EndScene()=0
Double_t PadtoY(Double_t y) const
Convert y from pad to Y.
Definition: TPad.cxx:3338
virtual Double_t GetBinErrorUp(Int_t bin) const
Return upper error associated to bin number bin.
Definition: TH1.cxx:8366
virtual void Pop()
Pop pad to the top of the stack.
Definition: TPad.cxx:4564
virtual TObjLink * LastLink() const
Definition: TList.h:111
Double_t GetY1() const
Definition: TBox.h:54
Bool_t IsRetained() const
Is pad retained ?
Definition: TCanvas.h:180
virtual void SetAttTextPS(Int_t align, Float_t angle, Color_t color, Style_t font, Float_t tsize)
Set postscript text attributes.
Definition: TPad.cxx:5917
TObject * fPadPointer
! free pointer
Definition: TPad.h:112
virtual Rectangle_t GetBBox()
Return the bounding Box of the Pad.
Definition: TPad.cxx:6943
virtual Bool_t OpaqueResizing() const
Is pad resizing in opaque mode ?
Definition: TPad.cxx:2756
void SetPadTickY(Int_t ticky)
Definition: TStyle.h:339
#define gDirectory
Definition: TDirectory.h:213
Color_t GetFrameFillColor() const
Definition: TAttPad.h:53
Width_t GetFrameLineWidth() const
Definition: TAttPad.h:57
void SetBatch(Bool_t batch=kTRUE)
Toggle batch mode.
Definition: TCanvas.cxx:1862
void Emit(const char *signal, const T &arg)
Activate signal with single parameter.
Definition: TQObject.h:165
Double_t fUtoPixelk
Conversion coefficient for U NDC to pixel.
Definition: TPad.h:48
void ResetBit(UInt_t f)
Definition: TObject.h:171
virtual void RangeAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax)
Set axis coordinate system for the pad.
Definition: TPad.cxx:5141
static void Line(Int_t event, Int_t px, Int_t py, Int_t mode)
Create a new line/arrow in this gPad.
TVirtualPS is an abstract interface to Postscript, PDF, SVG.
Definition: TVirtualPS.h:30
virtual void SetNumber(Int_t number)
Definition: TPad.h:334
Double_t fPixeltoYk
Conversion coefficient for pixel to Y World.
Definition: TPad.h:58
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1254
TExec is a utility class that can be used to execute a C++ command when some event happens in a pad...
Definition: TExec.h:28
Definition: first.py:1
virtual void HandleInput(EEventType button, Int_t x, Int_t y)
Handle Input Events.
Definition: TCanvas.cxx:1168
Bool_t UseGL() const
Definition: TCanvas.h:226
virtual Int_t GetNbinsX() const
Definition: TH1.h:291
Double_t Sqrt(Double_t x)
Definition: TMath.h:590
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition: TAttFill.h:31
virtual void SetTextSize(Float_t tsize=1)
Set the text size.
Definition: TAttText.h:46
virtual void SaveAs(const char *filename="", Option_t *option="") const
Save Pad contents in a file in one of various formats.
Definition: TPad.cxx:5486
Int_t GetNbins() const
Definition: TAxis.h:121
virtual void Update()
Update canvas pad buffers.
Definition: TCanvas.cxx:2248
Double_t PadtoX(Double_t x) const
Convert x from pad to X.
Definition: TPad.cxx:3329
Draw all kinds of Arrows.
Definition: TArrow.h:29
Double_t fY1
Y of lower Y coordinate.
Definition: TPad.h:36
Int_t fGLDevice
! OpenGL off-screen pixmap identifier
Definition: TPad.h:84
virtual Bool_t IsTransparent() const
Definition: TAttFill.h:44
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:357
RooCmdArg FillStyle(Style_t style)
virtual Int_t GetSize() const
Definition: TCollection.h:180
void SetPadRightMargin(Float_t margin=0.1)
Definition: TStyle.h:335
static void SetMaxPickDistance(Int_t maxPick=5)
static function to set the maximum Pick Distance fgMaxPickDistance This parameter is used in TPad::Pi...
Definition: TPad.cxx:6358
virtual void ClearDrawable()=0
void PaintFillAreaHatches(Int_t n, Double_t *x, Double_t *y, Int_t FillStyle)
This function paints hatched fill area according to the FillStyle value The convention for the Hatch ...
Definition: TPad.cxx:3882
virtual void SetLogz(Int_t value=1)
Set Lin/Log scale for Z.
Definition: TPad.cxx:5809
Double_t fX1
X of lower X coordinate.
Definition: TPad.h:35
static void Pave(Int_t event, Int_t px, Int_t py, Int_t mode)
Create a new pavetext in gPad.
void SetPadGridY(Bool_t gridy)
Definition: TStyle.h:337
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
TList * GetListOfFunctions() const
Definition: TH1.h:238
TObject * fTip
! tool tip associated with box
Definition: TPad.h:32
TList * GetListOfMethods(Bool_t load=kTRUE)
Return list containing the TMethods of a class.
Definition: TClass.cxx:3666
virtual void SetFillStyle(Style_t fstyle)=0
virtual void SetY1(Double_t y1)
Definition: TBox.h:65
virtual void x3d(Option_t *type="")
Deprecated: use TPad::GetViewer3D() instead.
Definition: TPad.cxx:6804
static Bool_t ContainsTImage(TList *li)
Auxiliary function.
Definition: TPad.cxx:4608
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
void PaintLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Paint line in CurrentPad World coordinates.
Definition: TPad.cxx:4096
Double_t AbsPixeltoY(Int_t py)
Definition: TPad.h:168
const Bool_t kTRUE
Definition: RtypesCore.h:87
Int_t Nint(T x)
Definition: TMath.h:606
Double_t fUxmin
Minimum value on the X axis.
Definition: TPad.h:73
virtual void CopyDrawable(Int_t device, Int_t px, Int_t py)=0
Double_t ex[n]
Definition: legend1.C:17
virtual Int_t GetMaximumBin() const
Return location of bin with maximum value in the range.
Definition: TH1.cxx:7837
const Int_t n
Definition: legend1.C:16
Double_t GetUymin() const
Returns the minimum y-coordinate value visible on the pad. If log axis the returned value is in decad...
Definition: TPad.h:225
Double_t GetWNDC() const
Definition: TPad.h:211
Int_t fTicky
Set to 1 if tick marks along Y.
Definition: TPad.h:89
virtual void SetBBoxCenterY(const Int_t y)
Set Y coordinate of the center of the Pad.
Definition: TPad.cxx:6990
virtual void Open(const char *filename, Int_t type=-111)=0
clip to the frame boundary
Definition: TGraph.h:70
virtual void RangeAxisChanged()
Definition: TPad.h:310
virtual Color_t GetLineColor() const =0
Float_t GetRightMargin() const
Definition: TAttPad.h:45
void Modified(Bool_t flag=1)
Definition: TPad.h:414
Int_t GetFrameBorderMode() const
Definition: TAttPad.h:59
Bool_t HasFixedAspectRatio() const
Definition: TPad.h:265
To make it possible to use GL for 2D graphic in a TPad/TCanvas.
char name[80]
Definition: TGX11.cxx:109
static Int_t fgMaxPickDistance
Maximum Pick Distance.
Definition: TPad.h:114
double log(double)
static void Ellipse(Int_t event, Int_t px, Int_t py, Int_t mode)
Create a new arc/ellipse in this gPad.
virtual void Exec(const char *command="")
Execute the command referenced by this object.
Definition: TExec.cxx:143
virtual void Closed()
Definition: TPad.h:181
Double_t fUtoPixel
xpixel = fUtoPixelk + fUtoPixel*undc
Definition: TPad.h:49
void FillCollideGrid(TObject *o)
Initialise the grid used to find empty space when adding a box (Legend) in a pad. ...
Definition: TPad.cxx:2987
virtual void SetBorderSize(Int_t bordersize=4)
Definition: TPave.h:70
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
TAxis * GetXaxis()
Get the behaviour adopted by the object about the statoverflows. See EStatOverflows for more informat...
Definition: TH1.h:315
Short_t fBorderMode
Bordermode (-1=down, 0 = no border, 1=up)
Definition: TPad.h:97
Double_t fAbsPixeltoXk
Conversion coefficient for absolute pixel to X World.
Definition: TPad.h:54
Int_t fLogy
(=0 if Y linear scale, =1 if log scale)
Definition: TPad.h:91
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
void PaintText(Double_t x, Double_t y, const char *text)
Paint text in CurrentPad World coordinates.
Definition: TPad.cxx:4375
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
This class stores the date and time with a precision of one second in an unsigned 32 bit word (950130...
Definition: TDatime.h:37
Double_t fWNDC
Width of pad along X in NDC.
Definition: TPad.h:65
virtual void SetBBoxCenterY(const Int_t y)=0
Style_t fFillStyle
Fill area style.
Definition: TAttFill.h:23
virtual Int_t GetCanvasID() const
Get canvas identifier.
Definition: TPad.cxx:2614
virtual void RecordLatex(const TObject *obj)
Emit RecordLatex() signal.
Definition: TPad.cxx:6926
Int_t GetOptTitle() const
Definition: TStyle.h:230
virtual void SetLeftMargin(Float_t leftmargin)
Set Pad left margin in fraction of the pad width.
Definition: TAttPad.cxx:110
void DrawDist(Rectangle_t aBBox, Rectangle_t bBBox, char mode)
Draw Arrows to indicated equal distances of Objects with given BBoxes.
Definition: TPad.cxx:5944
Int_t GetBorderSize() const
Definition: TPave.h:51
Color_t GetPadColor() const
Definition: TStyle.h:193
const char * Data() const
Definition: TString.h:345
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition: TObject.cxx:664
virtual void SetLogy(Int_t value=1)
Set Lin/Log scale for Y.
Definition: TPad.cxx:5798
static constexpr double g