Logo ROOT   6.12/07
Reference Guide
TPad.hxx
Go to the documentation of this file.
1 /// \file ROOT/TPad.hxx
2 /// \ingroup Gpad ROOT7
3 /// \author Axel Naumann <axel@cern.ch>
4 /// \date 2017-07-06
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 #ifndef ROOT7_TPad
17 #define ROOT7_TPad
18 
19 #include <memory>
20 #include <vector>
21 
22 #include "ROOT/TDrawable.hxx"
23 #include "ROOT/TFrame.hxx"
24 #include "ROOT/TPadExtent.hxx"
25 #include "ROOT/TPadPos.hxx"
26 #include "ROOT/TypeTraits.hxx"
27 
28 namespace ROOT {
29 namespace Experimental {
30 
31 class TPad;
32 
33 namespace Internal {
34 class TVirtualCanvasPainter;
35 }
36 
37 /** \class ROOT::Experimental::TPadBase
38  Base class for graphic containers for `TDrawable`-s.
39  */
40 
41 class TPadBase {
42 public:
43  using Primitives_t = std::vector<std::unique_ptr<TDrawable>>;
44 
45 private:
46  /// Content of the pad.
48 
49  /// TFrame with user coordinate system, if used by this pad.
50  std::unique_ptr<TFrame> fFrame;
51 
52  /// Disable copy construction.
53  TPadBase(const TPadBase &) = delete;
54 
55  /// Disable assignment.
56  TPadBase &operator=(const TPadBase &) = delete;
57 
58  /// Adds a `DRAWABLE` to `fPrimitives`, returning the drawing options as given by `DRAWABLE::Options()`.
59  template <class DRAWABLE>
60  auto &AddDrawable(std::unique_ptr<DRAWABLE> &&uPtr)
61  {
62  DRAWABLE &drw = *uPtr;
63  fPrimitives.emplace_back(std::move(uPtr));
64  return drw.GetOptions();
65  }
66 
67 protected:
68  /// Allow derived classes to default construct a TPadBase.
69  TPadBase() = default;
70 
71 public:
72  virtual ~TPadBase();
73 
74  /// Divide this pad into a grid of subpad with padding in between.
75  /// \param nHoriz Number of horizontal pads.
76  /// \param nVert Number of vertical pads.
77  /// \param padding Padding between pads.
78  /// \returns vector of vector (ret[x][y]) of created pads.
79  std::vector<std::vector<TPad *>> Divide(int nHoriz, int nVert, const TPadExtent &padding = {});
80 
81  /// Add something to be painted.
82  /// The pad observes what's lifetime through a weak pointer.
83  template <class T>
84  auto &Draw(const std::shared_ptr<T> &what)
85  {
86  // Requires GetDrawable(what) to be known!
87  return AddDrawable(GetDrawable(what, *this));
88  }
89 
90  /// Add something to be painted. The pad claims ownership.
91  template <class T>
92  auto &Draw(std::unique_ptr<T> &&what)
93  {
94  // Requires GetDrawable(what) to be known!
95  return AddDrawable(GetDrawable(std::move(what), *this));
96  }
97 
98  /// Add a copy of something to be painted.
99  template <class T, class = typename std::enable_if<!ROOT::TypeTraits::IsSmartOrDumbPtr<T>::value>::type>
100  auto &Draw(const T &what)
101  {
102  // Requires GetDrawable(what) to be known!
103  return Draw(std::make_unique<T>(what));
104  }
105 
106  /// Remove an object from the list of primitives.
107  // TODO: void Wipe(???);
108 
109  /// Wipe the pad by clearing the list of primitives.
110  void Wipe()
111  {
112  fPrimitives.clear();
113  }
114 
115  /// Get the elements contained in the canvas.
116  const Primitives_t &GetPrimitives() const { return fPrimitives; }
117 
118  /// Convert a `Pixel` position to Canvas-normalized positions.
119  virtual std::array<TPadCoord::Normal, 2> PixelsToNormal(const std::array<TPadCoord::Pixel, 2> &pos) const = 0;
120 
121  /// Access to the top-most canvas, if any (const version).
122  virtual const TCanvas &GetCanvas() const = 0;
123 
124  /// Access to the top-most canvas, if any (non-const version).
125  virtual TCanvas &GetCanvas() = 0;
126 
127  /// Convert user coordinates to normal coordinates.
128  std::array<TPadCoord::Normal, 2> UserToNormal(const std::array<TPadCoord::User, 2> &pos) const
129  {
130  return fFrame->UserToNormal(pos);
131  }
132 };
133 
134 class TPadDrawable;
135 
136 /** \class ROOT::Experimental::TPad
137  Graphic container for `TDrawable`-s.
138  */
139 
140 class TPad: public TPadBase {
141 private:
142  /// Pad containing this pad as a sub-pad.
143  TPadBase *fParent = nullptr; //-> This must never be nullptr!
144 
145  /// Size of the pad in the parent's (!) coordinate system.
147 
148 public:
149  friend std::unique_ptr<TPadDrawable> GetDrawable(std::unique_ptr<TPad> &&pad, const TPadBase &parent);
150 
151  /// Create a child pad.
152  TPad(TPadBase &parent, const TPadExtent &size): fParent(&parent), fSize(size) {}
153 
154  /// Destructor to have a vtable.
155  virtual ~TPad();
156 
157  /// Access to the parent pad (const version).
158  const TPadBase &GetParent() const { return *fParent; }
159 
160  /// Access to the parent pad (non-const version).
161  TPadBase &GetParent() { return *fParent; }
162 
163  /// Access to the top-most canvas (const version).
164  const TCanvas &GetCanvas() const override { return fParent->GetCanvas(); }
165 
166  /// Access to the top-most canvas (non-const version).
167  TCanvas &GetCanvas() override { return fParent->GetCanvas(); }
168 
169  /// Get the size of the pad in parent (!) coordinates.
170  const TPadExtent &GetSize() const { return fSize; }
171 
172  /// Convert a `Pixel` position to Canvas-normalized positions.
173  std::array<TPadCoord::Normal, 2> PixelsToNormal(const std::array<TPadCoord::Pixel, 2> &pos) const override
174  {
175  std::array<TPadCoord::Normal, 2> posInParentNormal = fParent->PixelsToNormal(pos);
176  std::array<TPadCoord::Normal, 2> myPixelInNormal =
177  fParent->PixelsToNormal({{fSize.fHoriz.fPixel, fSize.fVert.fPixel}});
178  std::array<TPadCoord::Normal, 2> myUserInNormal =
179  fParent->UserToNormal({{fSize.fHoriz.fUser, fSize.fVert.fUser}});
180  // If the parent says pos is at 0.6 in normal coords, and our size converted to normal is 0.2, then pos in our
181  // coord system is 3.0!
182  return {{posInParentNormal[0] / (fSize.fHoriz.fNormal + myPixelInNormal[0] + myUserInNormal[0]),
183  posInParentNormal[1] / (fSize.fVert.fNormal + myPixelInNormal[1] + myUserInNormal[1])}};
184  }
185 
186  /// Convert a TPadPos to [x, y] of normalized coordinates.
187  std::array<TPadCoord::Normal, 2> ToNormal(const Internal::TPadHorizVert &pos) const
188  {
189  std::array<TPadCoord::Normal, 2> pixelsInNormal = PixelsToNormal({{pos.fHoriz.fPixel, pos.fVert.fPixel}});
190  std::array<TPadCoord::Normal, 2> userInNormal = UserToNormal({{pos.fHoriz.fUser, pos.fVert.fUser}});
191  return {{pos.fHoriz.fNormal + pixelsInNormal[0] + userInNormal[0],
192  pos.fVert.fNormal + pixelsInNormal[1] + userInNormal[1]}};
193  }
194 };
195 
196 /** \class TPadDrawingOpts
197  Drawing options for a TPad
198  */
199 
200 class TPadDrawingOpts: public TDrawingOptsBase<TPadDrawingOpts> {
201  TPadPos fPos; ///< Offset with respect to parent TPad.
202 public:
204 
205  /// Set the position of this pad with respect to the parent pad.
207  {
208  fPos = pos;
209  return *this;
210  }
211 };
212 
213 /** \class TPadDrawable
214  Draw a TPad, by drawing its contained graphical elements at the pad offset in the parent pad.'
215  */
216 class TPadDrawable: public TDrawable {
217 private:
218  const std::unique_ptr<TPad> fPad; ///< The pad to be painted
219  TPadDrawingOpts fOpts; ///< The drawing options.
220 
221 public:
222  /// Move a sub-pad into this (i.e. parent's) list of drawables.
223  TPadDrawable(std::unique_ptr<TPad> &&pPad, TPadBase &parent);
224 
225  /// Paint the pad.
226  void Paint(Internal::TVirtualCanvasPainter & /*canv*/) final
227  {
228  // FIXME: and then what? Something with fPad.GetListOfPrimitives()?
229  }
230 
231  TPad *Get() const { return fPad.get(); }
232 
233  /// Drawing options.
234  TPadDrawingOpts &GetOptions() { return fOpts; }
235 };
236 
237 inline std::unique_ptr<TPadDrawable> GetDrawable(std::unique_ptr<TPad> &&pad, TPadBase &parent)
238 {
239  return std::make_unique<TPadDrawable>(std::move(pad), parent);
240 }
241 
242 } // namespace Experimental
243 } // namespace ROOT
244 
245 #endif
Draw a TPad, by drawing its contained graphical elements at the pad offset in the parent pad...
Definition: TPad.hxx:216
virtual std::array< TPadCoord::Normal, 2 > PixelsToNormal(const std::array< TPadCoord::Pixel, 2 > &pos) const =0
Convert a Pixel position to Canvas-normalized positions.
Base class for drawable entities: objects that can be painted on a TPad.
Definition: TDrawable.hxx:36
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
TPadExtent fSize
Size of the pad in the parent&#39;s (!) coordinate system.
Definition: TPad.hxx:146
double T(double x)
Definition: ChebyshevPol.h:34
A window&#39;s topmost TPad.
Definition: TCanvas.hxx:39
std::array< TPadCoord::Normal, 2 > PixelsToNormal(const std::array< TPadCoord::Pixel, 2 > &pos) const override
Convert a Pixel position to Canvas-normalized positions.
Definition: TPad.hxx:173
Base class for drawing options.
Drawing options for a TPad.
Definition: TPad.hxx:200
TPad(TPadBase &parent, const TPadExtent &size)
Create a child pad.
Definition: TPad.hxx:152
TPadPos fPos
Offset with respect to parent TPad.
Definition: TPad.hxx:201
auto & Draw(const T &what)
Add a copy of something to be painted.
Definition: TPad.hxx:100
TPadDrawingOpts & At(const TPadPos &pos)
Set the position of this pad with respect to the parent pad.
Definition: TPad.hxx:206
Normal fNormal
The normalized coordinate summand.
Definition: TPadCoord.hxx:93
std::unique_ptr< TFrame > fFrame
TFrame with user coordinate system, if used by this pad.
Definition: TPad.hxx:50
virtual const TCanvas & GetCanvas() const =0
Access to the top-most canvas, if any (const version).
void Wipe()
Remove an object from the list of primitives.
Definition: TPad.hxx:110
const TPadExtent & GetSize() const
Get the size of the pad in parent (!) coordinates.
Definition: TPad.hxx:170
Primitives_t fPrimitives
Content of the pad.
Definition: TPad.hxx:47
A position (horizontal and vertical) in a TPad.
Definition: TPadPos.hxx:27
Base class for graphic containers for TDrawable-s.
Definition: TPad.hxx:41
const Primitives_t & GetPrimitives() const
Get the elements contained in the canvas.
Definition: TPad.hxx:116
TPadDrawingOpts(TPadBase &parent)
Definition: TPad.hxx:203
auto & Draw(const std::shared_ptr< T > &what)
Add something to be painted.
Definition: TPad.hxx:84
th1 Draw()
auto & Draw(std::unique_ptr< T > &&what)
Add something to be painted. The pad claims ownership.
Definition: TPad.hxx:92
TCanvas & GetCanvas() override
Access to the top-most canvas (non-const version).
Definition: TPad.hxx:167
Pixel fPixel
The pixel coordinate summand.
Definition: TPadCoord.hxx:96
const TCanvas & GetCanvas() const override
Access to the top-most canvas (const version).
Definition: TPad.hxx:164
std::array< TPadCoord::Normal, 2 > UserToNormal(const std::array< TPadCoord::User, 2 > &pos) const
Convert user coordinates to normal coordinates.
Definition: TPad.hxx:128
const TPadBase & GetParent() const
Access to the parent pad (const version).
Definition: TPad.hxx:158
The most important graphics class in the ROOT system.
Definition: TPad.h:29
auto & AddDrawable(std::unique_ptr< DRAWABLE > &&uPtr)
Adds a DRAWABLE to fPrimitives, returning the drawing options as given by DRAWABLE::Options().
Definition: TPad.hxx:60
std::vector< std::unique_ptr< TDrawable > > Primitives_t
Definition: TPad.hxx:43
Abstract interface for painting a canvas.
TPadDrawingOpts & GetOptions()
Drawing options.
Definition: TPad.hxx:234
std::array< TPadCoord::Normal, 2 > ToNormal(const Internal::TPadHorizVert &pos) const
Convert a TPadPos to [x, y] of normalized coordinates.
Definition: TPad.hxx:187
int type
Definition: TGX11.cxx:120
TPadCoord fVert
Vertical position.
Definition: TPadExtent.hxx:33
Binding & operator=(OUT(*fun)(void))
An extent / size (horizontal and vertical) in a TPad.
Definition: TPadExtent.hxx:44
User fUser
The user coordinate summand.
Definition: TPadCoord.hxx:99
TPadCoord fHoriz
Horizontal position.
Definition: TPadExtent.hxx:32
TPadBase & GetParent()
Access to the parent pad (non-const version).
Definition: TPad.hxx:161
void Paint(Internal::TVirtualCanvasPainter &) final
Paint the pad.
Definition: TPad.hxx:226
std::unique_ptr< TPadDrawable > GetDrawable(std::unique_ptr< TPad > &&pad, TPadBase &parent)
Definition: TPad.hxx:237
const std::unique_ptr< TPad > fPad
The pad to be painted.
Definition: TPad.hxx:218
Graphic container for TDrawable-s.
Definition: TPad.hxx:140
TPadDrawingOpts fOpts
The drawing options.
Definition: TPad.hxx:219
A 2D (horizontal and vertical) combination of TPadCoords.
Definition: TPadExtent.hxx:31