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