Logo ROOT   6.18/05
Reference Guide
RPad.cxx
Go to the documentation of this file.
1/// \file RPad.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/RPad.hxx"
17
18#include "ROOT/RLogger.hxx"
19#include "ROOT/RPadExtent.hxx"
20#include "ROOT/RPadPos.hxx"
22#include <ROOT/RPadPainter.hxx>
23#include <ROOT/RCanvas.hxx>
24
25#include <cassert>
26#include <limits>
27
29
30void ROOT::Experimental::RPadBase::AssignUniqueID(std::shared_ptr<RDrawable> &ptr)
31{
32 if (!ptr)
33 return;
34
35 RCanvas *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
44std::shared_ptr<ROOT::Experimental::RDrawable> ROOT::Experimental::RPadBase::FindDrawable(const std::string &id) const
45{
46 for (auto &&drawable : GetPrimitives()) {
47
48 if (drawable->GetId() == id)
49 return drawable;
50
51 RPadDrawable *pad_draw = dynamic_cast<RPadDrawable *> (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
64std::vector<std::vector<ROOT::Experimental::RPad *>>
65ROOT::Experimental::RPadBase::Divide(int nHoriz, int nVert, const RPadExtent &padding /*= {}*/)
66{
67 std::vector<std::vector<RPad *>> 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 RPadExtent 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 RPadExtent size = offset - padding;
81
82 ret.resize(nHoriz);
83 for (int iHoriz = 0; iHoriz < nHoriz; ++iHoriz) {
84 ret[iHoriz].resize(nVert);
85 for (int iVert = 0; iVert < nVert; ++iVert) {
86 RPadPos subPos = offset;
87 subPos *= {1. * iHoriz, 1. * iVert};
88 auto uniqPad = std::make_unique<RPad>(*this, subPos, size);
89 ret[iHoriz][iVert] = uniqPad.get();
90 Draw(std::move(uniqPad), subPos, size);
91 // printf("Create subpad pos %5.2f %5.2f\n", subPos.fHoriz.fNormal.fVal, subPos.fVert.fNormal.fVal);
92 }
93 }
94 return ret;
95}
96
98{
99 CreateFrameIfNeeded();
100 return fFrame.get();
101}
102
104{
105 if (!fFrame) {
106 fFrame = std::make_unique<ROOT::Experimental::RFrame>();
107 }
108}
109
110
111/////////////////////////////////////////////////////////////////////////////////////////////////
112/// Get a pad axis from the RFrame.
113/// \param dimension - Index of the dimension of the RFrame user coordinate system.
114
116{
117 if (fFrame && dimension < fFrame->GetNDimensions())
118 return &fFrame->GetUserAxis(dimension);
119 return nullptr;
120}
121
122/////////////////////////////////////////////////////////////////////////////////////////////////
123/// Get a pad axis from the RFrame.
124/// \param dimension - Index of the dimension of the RFrame user coordinate system.
125
127{
128 GetOrCreateFrame()->GrowToDimensions(dimension);
129 return &fFrame->GetUserAxis(dimension);
130}
131
132/////////////////////////////////////////////////////////////////////////////////////////////////
133/// Set the range of an axis as begin, end.
134
135void ROOT::Experimental::RPadBase::SetAxisBounds(int dimension, double begin, double end)
136{
137 GetOrCreateFrame()->GrowToDimensions(dimension);
138 GetAxis(dimension)->SetBounds(begin, end);
139}
140
141/////////////////////////////////////////////////////////////////////////////////////////////////
142/// Set the range of an axis as bound kind and bound (up or down).
143
145{
146 GetOrCreateFrame()->GrowToDimensions(dimension);
147 GetAxis(dimension)->SetBound(boundsKind, bound);
148}
149
150/////////////////////////////////////////////////////////////////////////////////////////////////
151/// Set the range of an axis as bound kind and bound (up or down).
152
154{
155 GetOrCreateFrame()->GrowToDimensions(dimension);
156 GetAxis(dimension)->SetAutoBounds();
157}
158
159/////////////////////////////////////////////////////////////////////////////////////////////////
160/// Set the range of an axis as bound kind and bound (up or down).
161
162void ROOT::Experimental::RPadBase::SetAllAxisBounds(const std::vector<std::array<double, 2>> &vecBeginAndEnd)
163{
164 GetOrCreateFrame()->GrowToDimensions(vecBeginAndEnd.size());
165 if (vecBeginAndEnd.size() != fFrame->GetNDimensions()) {
166 R__ERROR_HERE("Gpadv7")
167 << "Array of axis bound has wrong size " << vecBeginAndEnd.size()
168 << " versus numer of axes in frame " << fFrame->GetNDimensions();
169 return;
170 }
171
172 for (size_t i = 0, n = fFrame->GetNDimensions(); i < n; ++i)
173 fFrame->GetUserAxis(i).SetBounds(vecBeginAndEnd[i][0], vecBeginAndEnd[i][1]);
174}
175
176/////////////////////////////////////////////////////////////////////////////////////////////////
177/// Set the range of an axis as bound kind and bound (up or down).
178
179void ROOT::Experimental::RPadBase::SetAllAxisBound(const std::vector<BoundKindAndValue> &vecBoundAndKind)
180{
181 GetOrCreateFrame()->GrowToDimensions(vecBoundAndKind.size());
182 if (vecBoundAndKind.size() != fFrame->GetNDimensions()) {
183 R__ERROR_HERE("Gpadv7")
184 << "Array of axis bound has wrong size " << vecBoundAndKind.size()
185 << " versus numer of axes in frame " << fFrame->GetNDimensions();
186 return;
187 }
188
189 for (size_t i = 0, n = fFrame->GetNDimensions(); i < n; ++i)
190 fFrame->GetUserAxis(i).SetBound(vecBoundAndKind[i].fKind, vecBoundAndKind[i].fBound);
191}
192
193/////////////////////////////////////////////////////////////////////////////////////////////////
194/// Set the range of an axis as bound kind and bound (up or down).
195
197{
198 for (size_t i = 0, n = GetOrCreateFrame()->GetNDimensions(); i < n; ++i)
199 fFrame->GetUserAxis(i).SetAutoBounds();
200}
201
202
203/////////////////////////////////////////////////////////////////////////////////////////////////
204
205
207
208/////////////////////////////////////////////////////////////////////////////////////////////////
209
210ROOT::Experimental::RPadDrawable::RPadDrawable(const std::shared_ptr<RPad> &pPad, const RPad::DrawingOpts &opts /*= {}*/)
211 : fPad(std::move(pPad))
212{
213 if (fPad)
214 fPad->GetDrawingOpts() = opts;
215}
216
217/// Paint the pad.
219{
220 Internal::RPadPainter painter;
221
222 painter.PaintDrawables(*fPad.get());
223
224 painter.fPadDisplayItem->SetDrawOpts(&GetOptions());
225
226 painter.fPadDisplayItem->SetPos(&fPad->GetPos());
227
228 painter.fPadDisplayItem->SetSize(&fPad->GetSize());
229
230 toppad.AddDisplayItem(std::move(painter.fPadDisplayItem));
231}
#define R__ERROR_HERE(GROUP)
Definition: RLogger.hxx:183
Abstract interface for object painting on the pad/canvas.
Definition: RPadPainter.hxx:37
void PaintDrawables(const RPadBase &pad)
Definition: RPadPainter.cxx:27
virtual void AddDisplayItem(std::unique_ptr< RDisplayItem > &&item)
add display item to the canvas
Definition: RPadPainter.cxx:21
std::unique_ptr< RPadDisplayItem > fPadDisplayItem
! display items for all drawables in the pad
Definition: RPadPainter.hxx:43
A window's topmost RPad.
Definition: RCanvas.hxx:33
std::string GenerateUniqueId()
Generates unique ID inside the canvas.
Definition: RCanvas.cxx:63
Holds a user coordinate system with a palette.
Definition: RFrame.hxx:33
void SetAllAxisBound(const std::vector< BoundKindAndValue > &vecBoundAndKind)
Set the range of an axis as bound kind and bound (up or down).
Definition: RPad.cxx:179
void SetAxisBounds(int dimension, double begin, double end)
Set the range of an axis as begin, end.
Definition: RPad.cxx:135
virtual const RCanvas * GetCanvas() const =0
Access to the top-most canvas, if any (const version).
void SetAllAxisAutoBounds()
Set the range of an axis as bound kind and bound (up or down).
Definition: RPad.cxx:196
void SetAxisBound(int dimension, RPadUserAxisBase::EAxisBoundsKind boundsKind, double bound)
Set the range of an axis as bound kind and bound (up or down).
Definition: RPad.cxx:144
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: RPad.cxx:162
RPadUserAxisBase * GetAxis(size_t dimension) const
Get a pad axis from the RFrame.
Definition: RPad.cxx:115
RPadUserAxisBase * GetOrCreateAxis(size_t dimension)
Get a pad axis from the RFrame.
Definition: RPad.cxx:126
RFrame * GetOrCreateFrame()
Definition: RPad.cxx:97
void AssignUniqueID(std::shared_ptr< RDrawable > &ptr)
Definition: RPad.cxx:30
void SetAxisAutoBounds(int dimension)
Set the range of an axis as bound kind and bound (up or down).
Definition: RPad.cxx:153
std::vector< std::vector< RPad * > > Divide(int nHoriz, int nVert, const RPadExtent &padding={})
Divide this pad into a grid of subpads with padding in between.
Definition: RPad.cxx:65
std::shared_ptr< RDrawable > FindDrawable(const std::string &id) const
Definition: RPad.cxx:44
Draw a RPad, by drawing its contained graphical elements at the pad offset in the parent pad.
Definition: RPad.hxx:283
void Paint(Internal::RPadPainter &) final
Paint primitives from the pad.
Definition: RPad.cxx:218
RPadDrawable(const std::shared_ptr< RPad > &pPad, const RPad::DrawingOpts &opts={})
Move a sub-pad into this (i.e. parent's) list of drawables.
Definition: RPad.cxx:210
const std::shared_ptr< RPad > fPad
The pad to be painted.
Definition: RPad.hxx:285
EAxisBoundsKind
Types of axis bounds to respect by the painter.
Drawing options for a RPad.
Definition: RPad.hxx:188
virtual ~RPad()
Destructor to have a vtable.
const Int_t n
Definition: legend1.C:16
An extent / size (horizontal and vertical) in a RPad.
Definition: RPadExtent.hxx:47
A position (horizontal and vertical) in a RPad.
Definition: RPadPos.hxx:27
th1 Draw()