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