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
23using namespace ROOT::Experimental;
24
25RPadBase::~RPadBase() = default;
26
27///////////////////////////////////////////////////////////////////////////
28/// Use provided style for pad and all primitives inside
29
30void RPadBase::UseStyle(const std::shared_ptr<RStyle> &style)
31{
33 for (auto &drawable : fPrimitives)
34 drawable->UseStyle(style);
35}
36
37///////////////////////////////////////////////////////////////////////////
38/// Find primitive with specified id
39
40std::shared_ptr<RDrawable> RPadBase::FindPrimitive(const std::string &id) const
41{
42 for (auto &drawable : fPrimitives) {
43
44 if (drawable->GetId() == id)
45 return drawable.get_shared();
46
47 const RPadBase *pad_draw = dynamic_cast<const RPadBase *> (drawable.get());
48
49 if (pad_draw) {
50 auto subelem = pad_draw->FindPrimitive(id);
51
52 if (subelem)
53 return subelem;
54 }
55 }
56
57 return nullptr;
58}
59
60///////////////////////////////////////////////////////////////////////////
61/// Find primitive with unique id, produce for RDisplayItem
62/// Such id used for client-server identification of objects
63
64std::shared_ptr<RDrawable> RPadBase::FindPrimitiveByDisplayId(const std::string &id) const
65{
66 auto p = id.find("_");
67 if (p == std::string::npos)
68 return nullptr;
69
70 auto prim = GetPrimitive(std::stoul(id.substr(0,p)));
71 if (!prim)
72 return nullptr;
73
74 auto subid = id.substr(p+1);
75
76 if (RDisplayItem::ObjectIDFromPtr(prim.get()) == subid)
77 return prim;
78
79 auto subpad = std::dynamic_pointer_cast<RPadBase>(prim);
80
81 return subpad ? subpad->FindPrimitiveByDisplayId(subid) : nullptr;
82}
83
84///////////////////////////////////////////////////////////////////////////
85/// Find subpad which contains primitive with given display id
86
87const RPadBase *RPadBase::FindPadForPrimitiveWithDisplayId(const std::string &id) const
88{
89 auto p = id.find("_");
90 if (p == std::string::npos)
91 return nullptr;
92
93 auto prim = GetPrimitive(std::stoul(id.substr(0,p)));
94 if (!prim)
95 return nullptr;
96
97 auto subid = id.substr(p+1);
98
99 if (RDisplayItem::ObjectIDFromPtr(prim.get()) == subid)
100 return this;
101
102 auto subpad = std::dynamic_pointer_cast<RPadBase>(prim);
103
104 return subpad ? subpad->FindPadForPrimitiveWithDisplayId(subid) : nullptr;
105}
106
107///////////////////////////////////////////////////////////////////////////
108/// Create display items for all primitives in the pad
109/// Each display item gets its special id, which used later for client-server communication
110/// Second parameter is version id which already delivered to the client
111
113{
114 paditem.SetAttributes(&GetAttrMap());
115 paditem.SetPadStyle(fStyle.lock());
116
117 unsigned indx = 0;
118
119 for (auto &drawable : fPrimitives) {
120
121 ctxt.SetDrawable(drawable.get(), indx++);
122
123 auto item = drawable->Display(ctxt);
124
125 if (!item)
126 item = std::make_unique<RDisplayItem>(true);
127
128 item->SetObjectIDAsPtr(drawable.get());
129 item->SetIndex(ctxt.GetIndex());
130 // add object with the style
131 paditem.Add(std::move(item), drawable->fStyle.lock());
132 }
133}
134
135///////////////////////////////////////////////////////////////////////////
136/// Add subpad
137
138std::shared_ptr<RPad> RPadBase::AddPad(const RPadPos &pos, const RPadExtent &extent)
139{
140 auto pad = new RPad(pos, extent);
141
142 pad->SetParent(this);
143 std::shared_ptr<RPad> pshared(pad);
144
145 fPrimitives.emplace_back(pshared);
146 return pshared;
147}
148
149///////////////////////////////////////////////////////////////////////////
150/// Divide pad on nHoriz X nVert subpads
151/// Return array of array of pads
152
153std::vector<std::vector<std::shared_ptr<RPad>>>
154RPadBase::Divide(int nHoriz, int nVert, const RPadExtent &padding)
155{
156 std::vector<std::vector<std::shared_ptr<RPad>>> ret;
157 if (!nHoriz)
158 R__LOG_ERROR(GPadLog()) << "Cannot divide into 0 horizontal sub-pads!";
159 if (!nVert)
160 R__LOG_ERROR(GPadLog()) << "Cannot divide into 0 vertical sub-pads!";
161 if (!nHoriz || !nVert)
162 return ret;
163
164 // Start with the whole (sub-)pad:
165 RPadExtent offset{1._normal, 1._normal};
166 /// We need n Pads plus n-1 padding. Thus each `(subPadSize + padding)` is `(parentPadSize + padding) / n`.
167 offset = (offset + padding);
168 offset *= {1. / nHoriz, 1. / nVert};
169 const RPadExtent size = offset - padding;
170
171 for (int iHoriz = 0; iHoriz < nHoriz; ++iHoriz) {
172 ret.emplace_back();
173 for (int iVert = 0; iVert < nVert; ++iVert) {
174 RPadPos subPos = offset;
175 subPos *= {1. * iHoriz, 1. * iVert};
176
177 auto subpad = AddPad(subPos, size);
178
179 ret.back().emplace_back(subpad);
180 }
181 }
182 return ret;
183}
184
185/////////////////////////////////////////////////////////////////////////////////////////////////
186/// Add a frame object for the pad.
187/// If frame already exists - just return it
188
189std::shared_ptr<RFrame> RPadBase::AddFrame()
190{
191 auto frame = GetFrame();
192 if (!frame) {
193 frame.reset(new RFrame);
194 fPrimitives.emplace_back(frame);
195 }
196 return frame;
197}
198
199/////////////////////////////////////////////////////////////////////////////////////////////////
200/// Get a frame object if exists
201
202const std::shared_ptr<RFrame> RPadBase::GetFrame() const
203{
204 for (auto &drawable : fPrimitives) {
205 if (const std::shared_ptr<RFrame> frame = std::dynamic_pointer_cast<RFrame>(drawable.get_shared()))
206 return frame;
207 }
208 return nullptr;
209}
210
211/////////////////////////////////////////////////////////////////////////////////////////////////
212/// Get a frame object if exists
213
214std::shared_ptr<RFrame> RPadBase::GetFrame()
215{
216 for (auto &drawable : fPrimitives) {
217 if (std::shared_ptr<RFrame> frame = std::dynamic_pointer_cast<RFrame>(drawable.get_shared()))
218 return frame;
219 }
220 return nullptr;
221}
222
223/////////////////////////////////////////////////////////////////////////////////////////////////
224/// Collect all shared items to resolve shared_ptr after IO
225
227{
228 for (auto &handle : fPrimitives) {
229 vect.emplace_back(&handle);
230 auto drawable = handle.get();
231 if (drawable) drawable->CollectShared(vect);
232 }
233}
234
235/////////////////////////////////////////////////////////////////////////////////////////////////
236/// Assign drawable version - for pad itself and all primitives
237
239{
241
242 for (auto &drawable : fPrimitives)
243 drawable->SetDrawableVersion(vers);
244}
#define R__LOG_ERROR(...)
Definition: RLogger.hxx:362
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
static std::string ObjectIDFromPtr(const void *ptr)
Construct fillid using pointer value.
void SetDrawable(RDrawable *dr, unsigned indx)
Set drawable and its index in list of primitives.
Definition: RDrawable.hxx:148
std::weak_ptr< RStyle > fStyle
! style applied for RDrawable, not stored when canvas is saved
Definition: RDrawable.hxx:173
virtual void SetDrawableVersion(Version_t vers)
Definition: RDrawable.hxx:196
virtual void UseStyle(const std::shared_ptr< RStyle > &style)
Definition: RDrawable.hxx:212
Holds an area where drawing on user coordinate-system can be performed.
Definition: RFrame.hxx:38
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 DisplayPrimitives(RPadBaseDisplayItem &paditem, RDisplayContext &ctxt)
Create display items for all primitives in the pad Each display item gets its special id,...
Definition: RPadBase.cxx:112
void SetDrawableVersion(Version_t vers) override
Assign drawable version - for pad itself and all primitives.
Definition: RPadBase.cxx:238
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:64
const RPadBase * FindPadForPrimitiveWithDisplayId(const std::string &display_id) const
Find subpad which contains primitive with given display id.
Definition: RPadBase.cxx:87
std::shared_ptr< RDrawable > GetPrimitive(unsigned num) const
returns primitive of given number
Definition: RPadBase.hxx:135
std::shared_ptr< RFrame > GetFrame()
Get a frame object if exists.
Definition: RPadBase.cxx:214
std::shared_ptr< RPad > AddPad(const RPadPos &, const RPadExtent &)
Add subpad.
Definition: RPadBase.cxx:138
std::shared_ptr< RDrawable > FindPrimitive(const std::string &id) const
Find primitive with specified id.
Definition: RPadBase.cxx:40
void CollectShared(Internal::RIOSharedVector_t &) override
Collect all shared items to resolve shared_ptr after IO.
Definition: RPadBase.cxx:226
std::vector< Primitive_t > fPrimitives
Content of the pad.
Definition: RPadBase.hxx:45
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:154
std::shared_ptr< RFrame > AddFrame()
Add a frame object for the pad.
Definition: RPadBase.cxx:189
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
Graphic container for RDrawable-s.
Definition: RPad.hxx:25
std::vector< RIOSharedBase * > RIOSharedVector_t
Definition: RDrawable.hxx:52
RLogChannel & GPadLog()
Log channel for GPad diagnostics.
Definition: RAttrBase.cxx:17
TCanvas * style()
Definition: style.C:1