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