Logo ROOT   6.14/05
Reference Guide
TPad.cxx
Go to the documentation of this file.
1 /// \file TPad.cxx
2 /// \ingroup Gpad ROOT7
3 /// \author Axel Naumann <axel@cern.ch>
4 /// \date 2017-07-07
5 /// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
6 /// is welcome!
7 
8 /*************************************************************************
9  * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers. *
10  * All rights reserved. *
11  * *
12  * For the licensing terms see $ROOTSYS/LICENSE. *
13  * For the list of contributors see $ROOTSYS/README/CREDITS. *
14  *************************************************************************/
15 
16 #include "ROOT/TPad.hxx"
17 
18 #include "ROOT/TLogger.hxx"
19 #include "ROOT/TPadExtent.hxx"
20 #include "ROOT/TPadPos.hxx"
21 #include <ROOT/TPadDisplayItem.hxx>
22 #include <ROOT/TPadPainter.hxx>
23 #include <ROOT/TCanvas.hxx>
24 
25 #include <cassert>
26 #include <limits>
27 
29 
30 void ROOT::Experimental::TPadBase::AssignUniqueID(std::shared_ptr<TDrawable> &ptr)
31 {
32  if (!ptr)
33  return;
34 
35  TCanvas *canv = GetCanvas();
36  if (!canv) {
37  R__ERROR_HERE("Gpad") << "Cannot access canvas when unique object id should be assigned";
38  return;
39  }
40 
41  ptr->fId = canv->GenerateUniqueId();
42 }
43 
44 std::shared_ptr<ROOT::Experimental::TDrawable> ROOT::Experimental::TPadBase::FindDrawable(const std::string &id) const
45 {
46  for (auto &&drawable : GetPrimitives()) {
47 
48  if (drawable->GetId() == id)
49  return drawable;
50 
51  TPadDrawable *pad_draw = dynamic_cast<TPadDrawable *> (drawable.get());
52  if (!pad_draw || !pad_draw->Get()) continue;
53 
54  auto subelem = pad_draw->Get()->FindDrawable(id);
55 
56  if (!subelem) continue;
57 
58  return subelem;
59  }
60 
61  return nullptr;
62 }
63 
64 std::vector<std::vector<ROOT::Experimental::TPad *>>
65 ROOT::Experimental::TPadBase::Divide(int nHoriz, int nVert, const TPadExtent &padding /*= {}*/)
66 {
67  std::vector<std::vector<TPad *>> ret;
68  if (!nHoriz)
69  R__ERROR_HERE("Gpad") << "Cannot divide into 0 horizontal sub-pads!";
70  if (!nVert)
71  R__ERROR_HERE("Gpad") << "Cannot divide into 0 vertical sub-pads!";
72  if (!nHoriz || !nVert)
73  return ret;
74 
75  // Start with the whole (sub-)pad:
76  TPadExtent offset{1._normal, 1._normal};
77  /// We need n Pads plus n-1 padding. Thus each `(subPadSize + padding)` is `(parentPadSize + padding) / n`.
78  offset = (offset + padding);
79  offset *= {1. / nHoriz, 1. / nVert};
80  const TPadExtent size = offset - padding;
81 
82  printf("SIZES %5.2f %5.2f\n", size.fHoriz.fNormal.fVal, size.fVert.fNormal.fVal);
83 
84  ret.resize(nHoriz);
85  for (int iHoriz = 0; iHoriz < nHoriz; ++iHoriz) {
86  ret[iHoriz].resize(nVert);
87  for (int iVert = 0; iVert < nVert; ++iVert) {
88  TPadPos subPos = offset;
89  subPos *= {1. * iHoriz, 1. * iVert};
90  auto uniqPad = std::make_unique<TPad>(*this, size);
91  ret[iHoriz][iVert] = uniqPad.get();
92  Draw(std::move(uniqPad), subPos);
93 
94  printf("Create subpad pos %5.2f %5.2f\n", subPos.fHoriz.fNormal.fVal, subPos.fVert.fNormal.fVal);
95  }
96  }
97  return ret;
98 }
99 
101 {
103  return fFrame.get();
104 }
105 
107 {
108  if (!fFrame) {
109  fFrame = std::make_unique<ROOT::Experimental::TFrame>();
110  }
111 }
112 
113 
114 /////////////////////////////////////////////////////////////////////////////////////////////////
115 /// Get a pad axis from the TFrame.
116 /// \param dimension - Index of the dimension of the TFrame user coordinate system.
117 
119 {
120  if (fFrame && dimension < fFrame->GetNDimensions())
121  return &fFrame->GetUserAxis(dimension);
122  return nullptr;
123 }
124 
125 /////////////////////////////////////////////////////////////////////////////////////////////////
126 /// Get a pad axis from the TFrame.
127 /// \param dimension - Index of the dimension of the TFrame user coordinate system.
128 
130 {
131  GetOrCreateFrame()->GrowToDimensions(dimension);
132  return &fFrame->GetUserAxis(dimension);
133 }
134 
135 /////////////////////////////////////////////////////////////////////////////////////////////////
136 /// Set the range of an axis as begin, end.
137 
138 void ROOT::Experimental::TPadBase::SetAxisBounds(int dimension, double begin, double end)
139 {
140  GetOrCreateFrame()->GrowToDimensions(dimension);
141  GetAxis(dimension)->SetBounds(begin, end);
142 }
143 
144 /////////////////////////////////////////////////////////////////////////////////////////////////
145 /// Set the range of an axis as bound kind and bound (up or down).
146 
148 {
149  GetOrCreateFrame()->GrowToDimensions(dimension);
150  GetAxis(dimension)->SetBound(boundsKind, bound);
151 }
152 
153 /////////////////////////////////////////////////////////////////////////////////////////////////
154 /// Set the range of an axis as bound kind and bound (up or down).
155 
157 {
158  GetOrCreateFrame()->GrowToDimensions(dimension);
159  GetAxis(dimension)->SetAutoBounds();
160 }
161 
162 /////////////////////////////////////////////////////////////////////////////////////////////////
163 /// Set the range of an axis as bound kind and bound (up or down).
164 
165 void ROOT::Experimental::TPadBase::SetAllAxisBounds(const std::vector<std::array<double, 2>> &vecBeginAndEnd)
166 {
167  GetOrCreateFrame()->GrowToDimensions(vecBeginAndEnd.size());
168  if (vecBeginAndEnd.size() != fFrame->GetNDimensions()) {
169  R__ERROR_HERE("Gpadv7")
170  << "Array of axis bound has wrong size " << vecBeginAndEnd.size()
171  << " versus numer of axes in frame " << fFrame->GetNDimensions();
172  return;
173  }
174 
175  for (size_t i = 0, n = fFrame->GetNDimensions(); i < n; ++i)
176  fFrame->GetUserAxis(i).SetBounds(vecBeginAndEnd[i][0], vecBeginAndEnd[i][1]);
177 }
178 
179 /////////////////////////////////////////////////////////////////////////////////////////////////
180 /// Set the range of an axis as bound kind and bound (up or down).
181 
182 void ROOT::Experimental::TPadBase::SetAllAxisBound(const std::vector<BoundKindAndValue> &vecBoundAndKind)
183 {
184  GetOrCreateFrame()->GrowToDimensions(vecBoundAndKind.size());
185  if (vecBoundAndKind.size() != fFrame->GetNDimensions()) {
186  R__ERROR_HERE("Gpadv7")
187  << "Array of axis bound has wrong size " << vecBoundAndKind.size()
188  << " versus numer of axes in frame " << fFrame->GetNDimensions();
189  return;
190  }
191 
192  for (size_t i = 0, n = fFrame->GetNDimensions(); i < n; ++i)
193  fFrame->GetUserAxis(i).SetBound(vecBoundAndKind[i].fKind, vecBoundAndKind[i].fBound);
194 }
195 
196 /////////////////////////////////////////////////////////////////////////////////////////////////
197 /// Set the range of an axis as bound kind and bound (up or down).
198 
200 {
201  for (size_t i = 0, n = GetOrCreateFrame()->GetNDimensions(); i < n; ++i)
202  fFrame->GetUserAxis(i).SetAutoBounds();
203 }
204 
205 
206 /////////////////////////////////////////////////////////////////////////////////////////////////
207 
208 
210 
211 /////////////////////////////////////////////////////////////////////////////////////////////////
212 
213 ROOT::Experimental::TPadDrawable::TPadDrawable(std::shared_ptr<TPad> pPad, const TPadDrawingOpts &opts /*= {}*/)
214  : fPad(std::move(pPad)), fOpts(opts)
215 {
216 }
217 
218 /// Paint the pad.
220 {
221  Internal::TPadPainter painter;
222 
223  painter.PaintDrawables(*fPad.get());
224 
225  painter.fPadDisplayItem->SetDrawOpts(&GetOptions());
226 
227  painter.fPadDisplayItem->SetSize(&fPad->GetSize());
228 
229  toppad.AddDisplayItem(std::move(painter.fPadDisplayItem));
230 }
Draw a TPad, by drawing its contained graphical elements at the pad offset in the parent pad...
Definition: TPad.hxx:268
TPadUserAxisBase * GetOrCreateAxis(size_t dimension)
Get a pad axis from the TFrame.
Definition: TPad.cxx:129
std::vector< std::vector< TPad * > > Divide(int nHoriz, int nVert, const TPadExtent &padding={})
Divide this pad into a grid of subpads with padding in between.
Definition: TPad.cxx:65
TPadLength fVert
Vertical position.
Definition: TPadExtent.hxx:33
TPadUserAxisBase * GetAxis(size_t dimension) const
Get a pad axis from the TFrame.
Definition: TPad.cxx:118
std::string GenerateUniqueId()
Generates unique ID inside the canvas.
Definition: TCanvas.cxx:49
A window&#39;s topmost TPad.
Definition: TCanvas.hxx:33
virtual const TCanvas * GetCanvas() const =0
Access to the top-most canvas, if any (const version).
Drawing options for a TPad.
Definition: TPad.hxx:245
std::shared_ptr< TDrawable > FindDrawable(const std::string &id) const
Definition: TPad.cxx:44
void SetAllAxisBound(const std::vector< BoundKindAndValue > &vecBoundAndKind)
Set the range of an axis as bound kind and bound (up or down).
Definition: TPad.cxx:182
void SetBound(EAxisBoundsKind boundKind, double bound)
TPadLength fHoriz
Horizontal position.
Definition: TPadExtent.hxx:32
void PaintDrawables(const TPadBase &pad)
Definition: TPadPainter.cxx:27
std::unique_ptr< TFrame > fFrame
TFrame with user coordinate system, if used by this pad.
Definition: TPad.hxx:50
STL namespace.
void Paint(Internal::TPadPainter &) final
Paint primitives from the pad.
Definition: TPad.cxx:219
std::unique_ptr< TPadDisplayItem > fPadDisplayItem
! display items for all drawables in the pad
Definition: TPadPainter.hxx:43
virtual ~TPad()
Destructor to have a vtable.
A position (horizontal and vertical) in a TPad.
Definition: TPadPos.hxx:27
void AssignUniqueID(std::shared_ptr< TDrawable > &ptr)
Definition: TPad.cxx:30
XFontStruct * id
Definition: TGX11.cxx:108
const Primitives_t & GetPrimitives() const
Get the elements contained in the canvas.
Definition: TPad.hxx:158
Normal fNormal
The normalized coordinate summand.
Definition: TPadLength.hxx:96
const std::shared_ptr< TPad > fPad
The pad to be painted.
Definition: TPad.hxx:270
void GrowToDimensions(size_t nDimensions)
Create nDimensions default axes for the user coordinate system.
Definition: TFrame.cxx:27
void SetBounds(double begin, double end)
void SetAllAxisBounds(const std::vector< std::array< double, 2 >> &vecBeginAndEnd)
Set the range of an axis as bound kind and bound (up or down).
Definition: TPad.cxx:165
TFrame * GetOrCreateFrame()
Definition: TPad.cxx:100
EAxisBoundsKind
Types of axis bounds to respect by the painter.
void SetAxisAutoBounds(int dimension)
Set the range of an axis as bound kind and bound (up or down).
Definition: TPad.cxx:156
void SetAxisBound(int dimension, TPadUserAxisBase::EAxisBoundsKind boundsKind, double bound)
Set the range of an axis as bound kind and bound (up or down).
Definition: TPad.cxx:147
TPadDrawingOpts & GetOptions()
Drawing options.
Definition: TPad.hxx:283
Abstract interface for object painting on the pad/canvas.
Definition: TPadPainter.hxx:37
Holds a user coordinate system with a palette.
Definition: TFrame.hxx:35
void SetAllAxisAutoBounds()
Set the range of an axis as bound kind and bound (up or down).
Definition: TPad.cxx:199
virtual void AddDisplayItem(std::unique_ptr< TDisplayItem > &&item)
add display item to the canvas
Definition: TPadPainter.cxx:21
An extent / size (horizontal and vertical) in a TPad.
Definition: TPadExtent.hxx:44
TPadDrawable(std::shared_ptr< TPad > pPad, const TPadDrawingOpts &opts={})
Move a sub-pad into this (i.e. parent&#39;s) list of drawables.
Definition: TPad.cxx:213
const Int_t n
Definition: legend1.C:16
void SetAxisBounds(int dimension, double begin, double end)
Set the range of an axis as begin, end.
Definition: TPad.cxx:138
#define R__ERROR_HERE(GROUP)
Definition: TLogger.hxx:182
auto Draw(const std::shared_ptr< T > &what, ARGS... args)
Add something to be painted.
Definition: TPad.hxx:93