Logo ROOT   6.16/01
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/TLogger.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 printf("SIZES %5.2f %5.2f\n", size.fHoriz.fNormal.fVal, size.fVert.fNormal.fVal);
83
84 ret.resize(nHoriz);
85 for (int iHoriz = 0; iHoriz < nHoriz; ++iHoriz) {
86 ret[iHoriz].resize(nVert);
87 for (int iVert = 0; iVert < nVert; ++iVert) {
88 RPadPos subPos = offset;
89 subPos *= {1. * iHoriz, 1. * iVert};
90 auto uniqPad = std::make_unique<RPad>(*this, size);
91 ret[iHoriz][iVert] = uniqPad.get();
92 Draw(std::move(uniqPad), subPos);
93
94 printf("Create subpad pos %5.2f %5.2f\n", subPos.fHoriz.fNormal.fVal, subPos.fVert.fNormal.fVal);
95 }
96 }
97 return ret;
98}
99
101{
102 CreateFrameIfNeeded();
103 return fFrame.get();
104}
105
107{
108 if (!fFrame) {
109 fFrame = std::make_unique<ROOT::Experimental::RFrame>();
110 }
111}
112
113
114/////////////////////////////////////////////////////////////////////////////////////////////////
115/// Get a pad axis from the RFrame.
116/// \param dimension - Index of the dimension of the RFrame user coordinate system.
117
119{
120 if (fFrame && dimension < fFrame->GetNDimensions())
121 return &fFrame->GetUserAxis(dimension);
122 return nullptr;
123}
124
125/////////////////////////////////////////////////////////////////////////////////////////////////
126/// Get a pad axis from the RFrame.
127/// \param dimension - Index of the dimension of the RFrame user coordinate system.
128
130{
131 GetOrCreateFrame()->GrowToDimensions(dimension);
132 return &fFrame->GetUserAxis(dimension);
133}
134
135/////////////////////////////////////////////////////////////////////////////////////////////////
136/// Set the range of an axis as begin, end.
137
138void ROOT::Experimental::RPadBase::SetAxisBounds(int dimension, double begin, double end)
139{
140 GetOrCreateFrame()->GrowToDimensions(dimension);
141 GetAxis(dimension)->SetBounds(begin, end);
142}
143
144/////////////////////////////////////////////////////////////////////////////////////////////////
145/// Set the range of an axis as bound kind and bound (up or down).
146
148{
149 GetOrCreateFrame()->GrowToDimensions(dimension);
150 GetAxis(dimension)->SetBound(boundsKind, bound);
151}
152
153/////////////////////////////////////////////////////////////////////////////////////////////////
154/// Set the range of an axis as bound kind and bound (up or down).
155
157{
158 GetOrCreateFrame()->GrowToDimensions(dimension);
159 GetAxis(dimension)->SetAutoBounds();
160}
161
162/////////////////////////////////////////////////////////////////////////////////////////////////
163/// Set the range of an axis as bound kind and bound (up or down).
164
165void ROOT::Experimental::RPadBase::SetAllAxisBounds(const std::vector<std::array<double, 2>> &vecBeginAndEnd)
166{
167 GetOrCreateFrame()->GrowToDimensions(vecBeginAndEnd.size());
168 if (vecBeginAndEnd.size() != fFrame->GetNDimensions()) {
169 R__ERROR_HERE("Gpadv7")
170 << "Array of axis bound has wrong size " << vecBeginAndEnd.size()
171 << " versus numer of axes in frame " << fFrame->GetNDimensions();
172 return;
173 }
174
175 for (size_t i = 0, n = fFrame->GetNDimensions(); i < n; ++i)
176 fFrame->GetUserAxis(i).SetBounds(vecBeginAndEnd[i][0], vecBeginAndEnd[i][1]);
177}
178
179/////////////////////////////////////////////////////////////////////////////////////////////////
180/// Set the range of an axis as bound kind and bound (up or down).
181
182void ROOT::Experimental::RPadBase::SetAllAxisBound(const std::vector<BoundKindAndValue> &vecBoundAndKind)
183{
184 GetOrCreateFrame()->GrowToDimensions(vecBoundAndKind.size());
185 if (vecBoundAndKind.size() != fFrame->GetNDimensions()) {
186 R__ERROR_HERE("Gpadv7")
187 << "Array of axis bound has wrong size " << vecBoundAndKind.size()
188 << " versus numer of axes in frame " << fFrame->GetNDimensions();
189 return;
190 }
191
192 for (size_t i = 0, n = fFrame->GetNDimensions(); i < n; ++i)
193 fFrame->GetUserAxis(i).SetBound(vecBoundAndKind[i].fKind, vecBoundAndKind[i].fBound);
194}
195
196/////////////////////////////////////////////////////////////////////////////////////////////////
197/// Set the range of an axis as bound kind and bound (up or down).
198
200{
201 for (size_t i = 0, n = GetOrCreateFrame()->GetNDimensions(); i < n; ++i)
202 fFrame->GetUserAxis(i).SetAutoBounds();
203}
204
205
206/////////////////////////////////////////////////////////////////////////////////////////////////
207
208
210
211/////////////////////////////////////////////////////////////////////////////////////////////////
212
213ROOT::Experimental::RPadDrawable::RPadDrawable(std::shared_ptr<RPad> pPad, const RPadDrawingOpts &opts /*= {}*/)
214 : fPad(std::move(pPad)), fOpts(opts)
215{
216}
217
218/// Paint the pad.
220{
221 Internal::RPadPainter painter;
222
223 painter.PaintDrawables(*fPad.get());
224
225 painter.fPadDisplayItem->SetDrawOpts(&GetOptions());
226
227 painter.fPadDisplayItem->SetSize(&fPad->GetSize());
228
229 toppad.AddDisplayItem(std::move(painter.fPadDisplayItem));
230}
#define R__ERROR_HERE(GROUP)
Definition: TLogger.hxx:182
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:35
void SetAllAxisBound(const std::vector< BoundKindAndValue > &vecBoundAndKind)
Set the range of an axis as bound kind and bound (up or down).
Definition: RPad.cxx:182
void SetAxisBounds(int dimension, double begin, double end)
Set the range of an axis as begin, end.
Definition: RPad.cxx:138
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:199
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:147
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:165
RPadUserAxisBase * GetAxis(size_t dimension) const
Get a pad axis from the RFrame.
Definition: RPad.cxx:118
RPadUserAxisBase * GetOrCreateAxis(size_t dimension)
Get a pad axis from the RFrame.
Definition: RPad.cxx:129
RFrame * GetOrCreateFrame()
Definition: RPad.cxx:100
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:156
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:268
void Paint(Internal::RPadPainter &) final
Paint primitives from the pad.
Definition: RPad.cxx:219
RPadDrawable(std::shared_ptr< RPad > pPad, const RPadDrawingOpts &opts={})
Move a sub-pad into this (i.e. parent's) list of drawables.
Definition: RPad.cxx:213
Drawing options for a RPad.
Definition: RPad.hxx:245
Normal fNormal
The normalized coordinate summand.
Definition: RPadLength.hxx:98
EAxisBoundsKind
Types of axis bounds to respect by the painter.
virtual ~RPad()
Destructor to have a vtable.
const Int_t n
Definition: legend1.C:16
STL namespace.
RPadLength fHoriz
Horizontal position.
Definition: RPadExtent.hxx:33
RPadLength fVert
Vertical position.
Definition: RPadExtent.hxx:34
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()