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