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