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