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