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