Logo ROOT  
Reference Guide
RPadBase.cxx
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (C) 1995-2017, 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#include "ROOT/RPadBase.hxx"
10
11#include "ROOT/RLogger.hxx"
12#include "ROOT/RPadExtent.hxx"
13#include "ROOT/RPadPos.hxx"
14#include <ROOT/RPad.hxx>
15#include <ROOT/RCanvas.hxx>
17
18#include <cassert>
19#include <limits>
20
21using namespace std::string_literals;
22
24
25///////////////////////////////////////////////////////////////////////////
26/// Use provided style for pad and all primitives inside
27
28void ROOT::Experimental::RPadBase::UseStyle(const std::shared_ptr<RStyle> &style)
29{
31 for (auto &drawable : fPrimitives)
32 drawable->UseStyle(style);
33}
34
35///////////////////////////////////////////////////////////////////////////
36/// Find primitive with specified id
37
38std::shared_ptr<ROOT::Experimental::RDrawable> ROOT::Experimental::RPadBase::FindPrimitive(const std::string &id) const
39{
40 for (auto &drawable : fPrimitives) {
41
42 if (drawable->GetId() == id)
43 return drawable.get_shared();
44
45 const RPadBase *pad_draw = dynamic_cast<const RPadBase *> (drawable.get());
46
47 if (pad_draw) {
48 auto subelem = pad_draw->FindPrimitive(id);
49
50 if (subelem)
51 return subelem;
52 }
53 }
54
55 return nullptr;
56}
57
58///////////////////////////////////////////////////////////////////////////
59/// Find primitive with unique id, produce for RDisplayItem
60/// Such id used for client-server identification of objects
61
62std::shared_ptr<ROOT::Experimental::RDrawable> ROOT::Experimental::RPadBase::FindPrimitiveByDisplayId(const std::string &id) const
63{
64 auto p = id.find("_");
65 if (p == std::string::npos)
66 return nullptr;
67
68 auto prim = GetPrimitive(std::stoul(id.substr(0,p)));
69 if (!prim)
70 return nullptr;
71
72 auto subid = id.substr(p+1);
73
74 if (RDisplayItem::ObjectIDFromPtr(prim.get()) == subid)
75 return prim;
76
77 auto subpad = std::dynamic_pointer_cast<RPadBase>(prim);
78
79 return subpad ? subpad->FindPrimitiveByDisplayId(subid) : nullptr;
80}
81
82///////////////////////////////////////////////////////////////////////////
83/// Method collect existing colors and assign new values if required
84
86{
87 int cnt = 0;
88 RColor col;
89
90 for (auto &drawable : fPrimitives) {
91 for (auto &attr: drawable->fAttr) {
92 // only boolean attribute can return true
93 if (!attr.second->GetBool()) continue;
94 auto pos = attr.first.rfind("_color_auto");
95 if ((pos > 0) && (pos == attr.first.length() - 11)) {
96 // FIXME: dummy code to assign autocolors, later should use RPalette
97 switch (cnt++ % 3) {
98 case 0: col = RColor::kRed; break;
99 case 1: col = RColor::kGreen; break;
100 case 2: col = RColor::kBlue; break;
101 }
102 drawable->fAttr.AddString(attr.first.substr(0,pos) + "_color_rgb", col.GetHex());
103 }
104 }
105 }
106}
107
108///////////////////////////////////////////////////////////////////////////
109/// Create display items for all primitives in the pad
110/// Each display item gets its special id, which used later for client-server communication
111
113{
114 paditem.SetAttributes(&GetAttrMap());
115 paditem.SetFrame(GetFrame());
116
117 paditem.SetPadStyle(fStyle.lock());
118
119 unsigned indx = 0;
120
121 for (auto &drawable : fPrimitives) {
122 auto item = drawable->Display();
123 if (item) {
124 item->SetObjectIDAsPtr(drawable.get());
125 item->SetIndex(indx);
126 // add object with the style
127 paditem.Add(std::move(item), drawable->fStyle.lock());
128 }
129 ++indx;
130 }
131}
132
133///////////////////////////////////////////////////////////////////////////
134/// Divide pad on nHoriz X nVert subpads
135/// Return array of array of pads
136
137std::vector<std::vector<std::shared_ptr<ROOT::Experimental::RPad>>>
138ROOT::Experimental::RPadBase::Divide(int nHoriz, int nVert, const RPadExtent &padding)
139{
140 std::vector<std::vector<std::shared_ptr<RPad>>> ret;
141 if (!nHoriz)
142 R__ERROR_HERE("Gpad") << "Cannot divide into 0 horizontal sub-pads!";
143 if (!nVert)
144 R__ERROR_HERE("Gpad") << "Cannot divide into 0 vertical sub-pads!";
145 if (!nHoriz || !nVert)
146 return ret;
147
148 // Start with the whole (sub-)pad:
149 RPadExtent offset{1._normal, 1._normal};
150 /// We need n Pads plus n-1 padding. Thus each `(subPadSize + padding)` is `(parentPadSize + padding) / n`.
151 offset = (offset + padding);
152 offset *= {1. / nHoriz, 1. / nVert};
153 const RPadExtent size = offset - padding;
154
155 for (int iHoriz = 0; iHoriz < nHoriz; ++iHoriz) {
156 ret.emplace_back();
157 for (int iVert = 0; iVert < nVert; ++iVert) {
158 RPadPos subPos = offset;
159 subPos *= {1. * iHoriz, 1. * iVert};
160
161 auto subpad = Draw<RPad>(this, subPos, size);
162
163 ret.back().emplace_back(subpad);
164 // printf("Create subpad pos %5.2f %5.2f\n", subPos.fHoriz.fNormal.fVal, subPos.fVert.fNormal.fVal);
165 }
166 }
167 return ret;
168}
169
171{
172 CreateFrameIfNeeded();
173 return fFrame.get();
174}
175
177{
178 if (!fFrame)
179 fFrame = std::make_unique<ROOT::Experimental::RFrame>();
180}
181
182
183/////////////////////////////////////////////////////////////////////////////////////////////////
184/// Get a pad axis from the RFrame.
185/// \param dimension - Index of the dimension of the RFrame user coordinate system.
186
188{
189 if (fFrame && dimension < fFrame->GetNDimensions())
190 return &fFrame->GetUserAxis(dimension);
191 return nullptr;
192}
193
194/////////////////////////////////////////////////////////////////////////////////////////////////
195/// Get a pad axis from the RFrame.
196/// \param dimension - Index of the dimension of the RFrame user coordinate system.
197
199{
200 GetOrCreateFrame()->GrowToDimensions(dimension);
201 return &fFrame->GetUserAxis(dimension);
202}
203
204/////////////////////////////////////////////////////////////////////////////////////////////////
205/// Set the range of an axis as begin, end.
206
207void ROOT::Experimental::RPadBase::SetAxisBounds(int dimension, double begin, double end)
208{
209 GetOrCreateFrame()->GrowToDimensions(dimension);
210 GetAxis(dimension)->SetBounds(begin, end);
211}
212
213/////////////////////////////////////////////////////////////////////////////////////////////////
214/// Set the range of an axis as bound kind and bound (up or down).
215
217{
218 GetOrCreateFrame()->GrowToDimensions(dimension);
219 GetAxis(dimension)->SetBound(boundsKind, bound);
220}
221
222/////////////////////////////////////////////////////////////////////////////////////////////////
223/// Set the range of an axis as bound kind and bound (up or down).
224
226{
227 GetOrCreateFrame()->GrowToDimensions(dimension);
228 GetAxis(dimension)->SetAutoBounds();
229}
230
231/////////////////////////////////////////////////////////////////////////////////////////////////
232/// Set the range of an axis as bound kind and bound (up or down).
233
234void ROOT::Experimental::RPadBase::SetAllAxisBounds(const std::vector<std::array<double, 2>> &vecBeginAndEnd)
235{
236 GetOrCreateFrame()->GrowToDimensions(vecBeginAndEnd.size());
237 if (vecBeginAndEnd.size() != fFrame->GetNDimensions()) {
238 R__ERROR_HERE("Gpadv7")
239 << "Array of axis bound has wrong size " << vecBeginAndEnd.size()
240 << " versus numer of axes in frame " << fFrame->GetNDimensions();
241 return;
242 }
243
244 for (size_t i = 0, n = fFrame->GetNDimensions(); i < n; ++i)
245 fFrame->GetUserAxis(i).SetBounds(vecBeginAndEnd[i][0], vecBeginAndEnd[i][1]);
246}
247
248/////////////////////////////////////////////////////////////////////////////////////////////////
249/// Set the range of an axis as bound kind and bound (up or down).
250
251void ROOT::Experimental::RPadBase::SetAllAxisBound(const std::vector<BoundKindAndValue> &vecBoundAndKind)
252{
253 GetOrCreateFrame()->GrowToDimensions(vecBoundAndKind.size());
254 if (vecBoundAndKind.size() != fFrame->GetNDimensions()) {
255 R__ERROR_HERE("Gpadv7")
256 << "Array of axis bound has wrong size " << vecBoundAndKind.size()
257 << " versus numer of axes in frame " << fFrame->GetNDimensions();
258 return;
259 }
260
261 for (size_t i = 0, n = fFrame->GetNDimensions(); i < n; ++i)
262 fFrame->GetUserAxis(i).SetBound(vecBoundAndKind[i].fKind, vecBoundAndKind[i].fBound);
263}
264
265/////////////////////////////////////////////////////////////////////////////////////////////////
266/// Collect all shared items to resolve shared_ptr after IO
267
269{
270 for (auto &handle : fPrimitives) {
271 vect.emplace_back(&handle);
272 auto drawable = handle.get();
273 if (drawable) drawable->CollectShared(vect);
274 }
275}
276
277/////////////////////////////////////////////////////////////////////////////////////////////////
278/// Set the range of an axis as bound kind and bound (up or down).
279
281{
282 for (size_t i = 0, n = GetOrCreateFrame()->GetNDimensions(); i < n; ++i)
283 fFrame->GetUserAxis(i).SetAutoBounds();
284}
#define R__ERROR_HERE(GROUP)
Definition: RLogger.hxx:183
The color class.
Definition: RColor.hxx:32
static constexpr RGB_t kRed
Definition: RColor.hxx:182
static constexpr RGB_t kGreen
Definition: RColor.hxx:183
std::string GetHex() const
Return color as hex string like 00FF00.
Definition: RColor.hxx:81
static constexpr RGB_t kBlue
Definition: RColor.hxx:184
static std::string ObjectIDFromPtr(const void *ptr)
virtual void UseStyle(const std::shared_ptr< RStyle > &style)
Definition: RDrawable.hxx:137
Holds a user coordinate system with a palette.
Definition: RFrame.hxx:31
void SetPadStyle(std::shared_ptr< RStyle > &&style)
Assign style for the pad.
void Add(std::unique_ptr< RDisplayItem > &&item, std::shared_ptr< RStyle > &&style)
Add display item and style which should be used for it.
Base class for graphic containers for RDrawable-s.
Definition: RPadBase.hxx:37
void UseStyle(const std::shared_ptr< RStyle > &style) override
Use provided style for pad and all primitives inside.
Definition: RPadBase.cxx:28
void CollectShared(Internal::RIOSharedVector_t &) override
Collect all shared items to resolve shared_ptr after IO.
Definition: RPadBase.cxx:268
std::vector< std::vector< std::shared_ptr< RPad > > > Divide(int nHoriz, int nVert, const RPadExtent &padding={})
Divide this pad into a grid of subpads with padding in between.
Definition: RPadBase.cxx:138
void SetAllAxisBound(const std::vector< BoundKindAndValue > &vecBoundAndKind)
Set the range of an axis as bound kind and bound (up or down).
Definition: RPadBase.cxx:251
void SetAxisBounds(int dimension, double begin, double end)
Set the range of an axis as begin, end.
Definition: RPadBase.cxx:207
void SetAllAxisAutoBounds()
Set the range of an axis as bound kind and bound (up or down).
Definition: RPadBase.cxx:280
void SetAxisBound(int dimension, RPadUserAxisBase::EAxisBoundsKind boundsKind, double bound)
Set the range of an axis as bound kind and bound (up or down).
Definition: RPadBase.cxx:216
std::vector< Primitive_t > fPrimitives
Content of the pad.
Definition: RPadBase.hxx:45
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: RPadBase.cxx:234
RPadUserAxisBase * GetAxis(size_t dimension) const
Get a pad axis from the RFrame.
Definition: RPadBase.cxx:187
void AssignAutoColors()
Method collect existing colors and assign new values if required.
Definition: RPadBase.cxx:85
RPadUserAxisBase * GetOrCreateAxis(size_t dimension)
Get a pad axis from the RFrame.
Definition: RPadBase.cxx:198
void DisplayPrimitives(RPadBaseDisplayItem &paditem) const
Create display items for all primitives in the pad Each display item gets its special id,...
Definition: RPadBase.cxx:112
std::shared_ptr< RDrawable > FindPrimitiveByDisplayId(const std::string &display_id) const
Find primitive with unique id, produce for RDisplayItem Such id used for client-server identification...
Definition: RPadBase.cxx:62
void SetAxisAutoBounds(int dimension)
Set the range of an axis as bound kind and bound (up or down).
Definition: RPadBase.cxx:225
std::shared_ptr< RDrawable > FindPrimitive(const std::string &id) const
Find primitive with specified id.
Definition: RPadBase.cxx:38
An extent / size (horizontal and vertical) in a RPad.
Definition: RPadExtent.hxx:27
A position (horizontal and vertical) in a RPad.
Definition: RPadPos.hxx:28
Base class for user coordinates (e.g.
EAxisBoundsKind
Types of axis bounds to respect by the painter.
const Int_t n
Definition: legend1.C:16
std::vector< RIOSharedBase * > RIOSharedVector_t
Definition: RDrawable.hxx:48
const char * cnt
Definition: TXMLSetup.cxx:74
TCanvas * style()
Definition: style.C:1