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