Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
RPadBase.hxx
Go to the documentation of this file.
1 /*************************************************************************
2  * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
3  * All rights reserved. *
4  * *
5  * For the licensing terms see $ROOTSYS/LICENSE. *
6  * For the list of contributors see $ROOTSYS/README/CREDITS. *
7  *************************************************************************/
8 
9 #ifndef ROOT7_RPadBase
10 #define ROOT7_RPadBase
11 
12 #include "ROOT/RDrawable.hxx"
13 #include "ROOT/RFrame.hxx"
14 #include "ROOT/RPadExtent.hxx"
15 #include "ROOT/RPadPos.hxx"
16 #include "ROOT/RPadUserAxis.hxx"
17 #include "ROOT/TypeTraits.hxx"
18 
19 #include <memory>
20 #include <vector>
21 
22 namespace ROOT {
23 namespace Experimental {
24 
25 class RPad;
26 class RCanvas;
27 class RPadBaseDisplayItem;
28 
29 /** \class ROOT::Experimental::RPadBase
30 \ingroup GpadROOT7
31 \brief Base class for graphic containers for `RDrawable`-s.
32 \authors Axel Naumann <axel@cern.ch> Sergey Linev <s.linev@gsi.de>
33 \date 2019-10-02
34 \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback is welcome!
35 */
36 
37 class RPadBase : public RDrawable {
38 
39 private:
40 
41  using Primitive_t = Internal::RIOShared<RDrawable>;
42 
43  /// Content of the pad.
44 
45  std::vector<Primitive_t> fPrimitives;
46 
47  /// RFrame with user coordinate system, if used by this pad.
48  std::unique_ptr<RFrame> fFrame;
49 
50  /// Disable copy construction.
51  RPadBase(const RPadBase &) = delete;
52 
53  /// Disable assignment.
54  RPadBase &operator=(const RPadBase &) = delete;
55 
56 protected:
57  /// Allow derived classes to default construct a RPadBase.
58  RPadBase() : RDrawable("pad") {}
59 
60  void CollectShared(Internal::RIOSharedVector_t &) override;
61 
62  void DisplayPrimitives(RPadBaseDisplayItem &paditem) const;
63 
64 public:
65 
66  using Primitives_t = std::vector<std::shared_ptr<RDrawable>>;
67 
68  virtual ~RPadBase();
69 
70  void UseStyle(const std::shared_ptr<RStyle> &style) override;
71 
72  /// Divide this pad into a grid of subpads with padding in between.
73  /// \param nHoriz Number of horizontal pads.
74  /// \param nVert Number of vertical pads.
75  /// \param padding Padding between pads.
76  /// \returns vector of vector (ret[x][y]) of created pads.
77  std::vector<std::vector<std::shared_ptr<RPad>>> Divide(int nHoriz, int nVert, const RPadExtent &padding = {});
78 
79  /// Create drawable of specified class T
80  template<class T, class... ARGS>
81  auto Draw(ARGS... args)
82  {
83  auto drawable = std::make_shared<T>(args...);
84 
85  fPrimitives.emplace_back(drawable);
86 
87  return drawable;
88  }
89 
90  /// Add existing drawable instance to canvas
91  auto Draw(std::shared_ptr<RDrawable> &&drawable)
92  {
93  fPrimitives.emplace_back(std::move(drawable));
94 
95  return fPrimitives.back().get_shared();
96  }
97 
98  /// Add something to be painted.
99  /// The pad observes what's lifetime through a weak pointer.
100  /// Drawing options will be constructed through `args`, which can be empty for default-constructed options.
101  template <class T, class... ARGS>
102  auto Draw(const std::shared_ptr<T> &what, ARGS... args)
103  {
104  // Requires GetDrawable(what) to be known!
105  auto drawable = GetDrawable(what, args...);
106 
107  fPrimitives.emplace_back(drawable);
108 
109  return drawable;
110  }
111 
112  /// returns number of primitives in the pad
113  unsigned NumPrimitives() const { return fPrimitives.size(); }
114 
115  /// returns primitive of given number
116  std::shared_ptr<RDrawable> GetPrimitive(unsigned num) const
117  {
118  if (num >= fPrimitives.size()) return nullptr;
119  return fPrimitives[num].get_shared();
120  }
121 
122  std::shared_ptr<RDrawable> FindPrimitive(const std::string &id) const;
123 
124  std::shared_ptr<RDrawable> FindPrimitiveByDisplayId(const std::string &display_id) const;
125 
126  /// Get all primitives contained in the pad.
127  auto GetPrimitives() const
128  {
129  Primitives_t res;
130  for (auto &entry : fPrimitives)
131  res.emplace_back(entry.get_shared());
132  return res;
133  }
134 
135  /// Remove an object from the list of primitives.
136  bool Remove(const std::string &id)
137  {
138  auto iter = std::find_if(fPrimitives.begin(), fPrimitives.end(),
139  [&id](const Internal::RIOShared<RDrawable>& dr) { return dr->GetId() == id; });
140  if (iter == fPrimitives.end())
141  return false;
142  iter->reset();
143  fPrimitives.erase(iter);
144  return true;
145  }
146 
147  /// Remove drawable from list of primitives
148  bool Remove(const std::shared_ptr<RDrawable> &drawable)
149  {
150  auto iter = std::find_if(fPrimitives.begin(), fPrimitives.end(),
151  [&drawable](const Internal::RIOShared<RDrawable>& dr) { return drawable.get() == dr.get(); });
152  if (iter == fPrimitives.end())
153  return false;
154  iter->reset();
155  fPrimitives.erase(iter);
156  return true;
157  }
158 
159  /// Remove drawable at specified position
160  bool RemoveAt(unsigned indx)
161  {
162  if (indx >= fPrimitives.size()) return false;
163  fPrimitives[indx].reset();
164  fPrimitives.erase(fPrimitives.begin() + indx);
165  return true;
166  }
167 
168  /// Wipe the pad by clearing the list of primitives.
169  void Wipe() { fPrimitives.clear(); }
170 
171  void CreateFrameIfNeeded();
172 
173  RFrame *GetOrCreateFrame();
174  const RFrame *GetFrame() const { return fFrame.get(); }
175 
176  RPadUserAxisBase* GetOrCreateAxis(size_t dimension);
177  RPadUserAxisBase* GetAxis(size_t dimension) const;
178 
179  void SetAxisBounds(int dimension, double begin, double end);
180  void SetAxisBound(int dimension, RPadUserAxisBase::EAxisBoundsKind boundsKind, double bound);
181  void SetAxisAutoBounds(int dimension);
182 
183  void SetAllAxisBounds(const std::vector<std::array<double, 2>> &vecBeginAndEnd);
184 
185  /// Simple struct representing an axis bound.
186  struct BoundKindAndValue {
187  RPadUserAxisBase::EAxisBoundsKind fKind = RPadUserAxisBase::kAxisBoundsAuto;
188  double fBound = 0.;
189  };
190  void SetAllAxisBound(const std::vector<BoundKindAndValue> &vecBoundAndKind);
191  void SetAllAxisAutoBounds();
192 
193  /// Convert a `Pixel` position to Canvas-normalized positions.
194  virtual std::array<RPadLength::Normal, 2> PixelsToNormal(const std::array<RPadLength::Pixel, 2> &pos) const = 0;
195 
196  /// Access to the top-most canvas, if any (const version).
197  virtual const RCanvas *GetCanvas() const = 0;
198 
199  /// Access to the top-most canvas, if any (non-const version).
200  virtual RCanvas *GetCanvas() = 0;
201 
202  /// Convert user coordinates to normal coordinates.
203  std::array<RPadLength::Normal, 2> UserToNormal(const std::array<RPadLength::User, 2> &pos) const
204  {
205  return fFrame->UserToNormal(pos);
206  }
207 
208  void AssignAutoColors();
209 
210 };
211 
212 } // namespace Experimental
213 } // namespace ROOT
214 
215 #endif