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