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