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