Logo ROOT  
Reference Guide
RCanvas.cxx
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (C) 1995-2015, 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/RCanvas.hxx"
10
11#include "ROOT/RLogger.hxx"
12
13#include <algorithm>
14#include <memory>
15#include <mutex>
16#include <thread>
17#include <chrono>
18#include <stdio.h>
19#include <string.h>
20
21#include "TROOT.h"
22
23namespace {
24
25static std::mutex &GetHeldCanvasesMutex()
26{
27 static std::mutex sMutex;
28 return sMutex;
29}
30
31static std::vector<std::shared_ptr<ROOT::Experimental::RCanvas>> &GetHeldCanvases()
32{
33 static std::vector<std::shared_ptr<ROOT::Experimental::RCanvas>> sCanvases;
34 return sCanvases;
35}
36
37
38} // namespace
39
40///////////////////////////////////////////////////////////////////////////////////////
41/// Returns list of created canvases
42
43const std::vector<std::shared_ptr<ROOT::Experimental::RCanvas>> ROOT::Experimental::RCanvas::GetCanvases()
44{
45 std::lock_guard<std::mutex> grd(GetHeldCanvasesMutex());
46
47 return GetHeldCanvases();
48}
49
50///////////////////////////////////////////////////////////////////////////////////////
51/// Returns true is canvas was modified since last painting
52
54{
55 return fPainter ? fPainter->IsCanvasModified(fModified) : fModified;
56}
57
58///////////////////////////////////////////////////////////////////////////////////////
59/// Update canvas
60
62{
63 if (fPainter)
64 fPainter->CanvasUpdated(fModified, async, callback);
65}
66
67///////////////////////////////////////////////////////////////////////////////////////
68/// Create new canvas instance
69
70std::shared_ptr<ROOT::Experimental::RCanvas> ROOT::Experimental::RCanvas::Create(const std::string &title)
71{
72 auto pCanvas = std::make_shared<RCanvas>();
73 pCanvas->SetTitle(title);
74 {
75 std::lock_guard<std::mutex> grd(GetHeldCanvasesMutex());
76 GetHeldCanvases().emplace_back(pCanvas);
77 }
78 return pCanvas;
79}
80
81//////////////////////////////////////////////////////////////////////////
82/// Create new display for the canvas
83/// The parameter `where` specifies which program could be used for display creation
84/// Possible values:
85///
86/// - `cef` Chromium Embeded Framework, local display, local communication
87/// - `qt5` Qt5 WebEngine (when running via rootqt5), local display, local communication
88/// - `browser` default system web-browser, communication via random http port from range 8800 - 9800
89/// - `<prog>` any program name which will be started instead of default browser, like firefox or /usr/bin/opera
90/// one could also specify $url in program name, which will be replaced with canvas URL
91/// - `native` either any available local display or default browser
92///
93/// Canvas can be displayed in several different places
94
95void ROOT::Experimental::RCanvas::Show(const std::string &where)
96{
97 if (fPainter) {
98 bool isany = (fPainter->NumDisplays() > 0);
99
100 if (!where.empty())
101 fPainter->NewDisplay(where);
102
103 if (isany) return;
104 }
105
106 if (!fModified)
107 fModified = 1; // 0 is special value, means no changes and no drawings
108
109 if (!fPainter)
111
112 if (fPainter) {
113 fPainter->NewDisplay(where);
114 fPainter->CanvasUpdated(fModified, true, nullptr); // trigger async display
115 }
116}
117
118//////////////////////////////////////////////////////////////////////////
119/// Returns window name for canvas
120
122{
123 if (fPainter)
124 return fPainter->GetWindowAddr();
125
126 return "";
127}
128
129
130//////////////////////////////////////////////////////////////////////////
131/// Hide all canvas displays
132
134{
135 if (fPainter)
136 delete fPainter.release();
137}
138
139//////////////////////////////////////////////////////////////////////////
140/// Create image file for the canvas
141/// Supported SVG (extension .svg), JPEG (extension .jpg or .jpeg) and PNG (extension .png)
142
143bool ROOT::Experimental::RCanvas::SaveAs(const std::string &filename)
144{
145 if (!fPainter)
147
148 if (!fPainter)
149 return false;
150
151 auto width = fSize[0].fVal;
152 auto height = fSize[1].fVal;
153
154 return fPainter->ProduceBatchOutput(filename, width > 1 ? (int) width : 800, height > 1 ? (int) height : 600);
155}
156
157//////////////////////////////////////////////////////////////////////////
158/// Remove canvas from global canvas lists, will be destroyed once last shared_ptr is disappear
159
161{
162 std::lock_guard<std::mutex> grd(GetHeldCanvasesMutex());
163 auto &held = GetHeldCanvases();
164 auto indx = held.size();
165 while (indx-- > 0) {
166 if (held[indx].get() == this)
167 held.erase(held.begin() + indx);
168 }
169}
170
171//////////////////////////////////////////////////////////////////////////
172/// Run canvas functionality for the given time (in seconds)
173/// Used to process canvas-related actions in the appropriate thread context.
174/// Must be regularly called when canvas created and used in extra thread.
175/// Time parameter specifies minimal execution time in seconds - if default value 0 is used,
176/// just all pending actions will be performed.
177/// When canvas is not yet displayed - just performs sleep for given time interval.
178///
179/// Example of usage:
180///
181/// ~~~ {.cpp}
182/// void draw_canvas(bool &run_loop, std::make_shared<RH1D> hist)
183/// {
184/// auto canvas = RCanvas::Create("Canvas title");
185/// canvas->Draw(hist)->SetLineColor(RColor::kBlue);
186/// canvas->Show();
187/// while (run_loop) {
188/// pHist->Fill(1);
189/// canvas->Modified();
190/// canvas->Update();
191/// canvas->Run(0.1); // process canvas events
192/// }
193///
194/// canvas->Remove();
195/// }
196///
197/// int main()
198/// {
199/// RAxisConfig xaxis(100, -10., 10.);
200/// auto pHist = std::make_shared<RH1D>(xaxis);
201/// bool run_loop = true;
202///
203/// std::thread thrd(draw_canvas, run_loop, pHist);
204/// std::this_thread::sleep_for(std::chrono::seconds(100));
205/// run_loop = false;
206/// thrd.join();
207/// return 0;
208/// }
209/// ~~~
210
212{
213 if (fPainter) {
214 fPainter->Run(tm);
215 } else if (tm>0) {
216 std::this_thread::sleep_for(std::chrono::milliseconds(int(tm*1000)));
217 }
218}
219
220//////////////////////////////////////////////////////////////////////////
221/// To resolve problem with storing of shared pointers
222/// Call this method when reading canvas from the file
223/// Can be called many times - after reinitialization of shared pointers no changes will be performed
224
226{
228
229 CollectShared(vect);
230
231 for (unsigned n = 0; n < vect.size(); ++n) {
232 if (vect[n]->HasShared() || !vect[n]->GetIOPtr()) continue;
233
234 auto shrd_ptr = vect[n]->MakeShared();
235
236 for (auto n2 = n+1; n2 < vect.size(); ++n2) {
237 if (vect[n2]->GetIOPtr() == vect[n]->GetIOPtr()) {
238 if (vect[n2]->HasShared())
239 R__ERROR_HERE("Gpadv7") << "FATAL Shared pointer for same IO ptr already exists";
240 else
241 vect[n2]->SetShared(shrd_ptr);
242 }
243 }
244
245 }
246}
247
248
249/////////////////////////////////////////////////////////////////////////////////////////////////
250/// Apply attributes changes to the drawable
251/// Return mask with actions which were really applied
252
253std::unique_ptr<ROOT::Experimental::RDrawableReply> ROOT::Experimental::RChangeAttrRequest::Process()
254{
255 auto canv = const_cast<ROOT::Experimental::RCanvas *>(GetContext().GetCanvas());
256 if (!canv) return nullptr;
257
258 if ((ids.size() != names.size()) || (ids.size() != values.size())) {
259 R__ERROR_HERE("Gpadv7") << "Mismatch of arrays size in RChangeAttrRequest";
260 return nullptr;
261 }
262
263 Version_t vers = 0;
264
265 for(int indx = 0; indx < (int) ids.size(); indx++) {
266 if (ids[indx] == "canvas") {
267 if (canv->GetAttrMap().Change(names[indx], values[indx].get())) {
268 if (!vers) vers = canv->IncModified();
269 canv->SetDrawableVersion(vers);
270 }
271 } else {
272 auto drawable = canv->FindPrimitiveByDisplayId(ids[indx]);
273 if (drawable && drawable->GetAttrMap().Change(names[indx], values[indx].get())) {
274 if (!vers) vers = canv->IncModified();
275 drawable->SetDrawableVersion(vers);
276 }
277 }
278 }
279
280 fNeedUpdate = (vers > 0);
281
282 return nullptr; // no need for any reply
283}
size_t fSize
#define R__ERROR_HERE(GROUP)
Definition: RLogger.hxx:183
short Version_t
Definition: RtypesCore.h:63
include TDocParser_001 C image html pict1_TDocParser_001 png width
Definition: TDocParser.cxx:121
static std::unique_ptr< RVirtualCanvasPainter > Create(RCanvas &canv)
Loads the plugin that implements this class.
A window's topmost RPad.
Definition: RCanvas.hxx:46
static const std::vector< std::shared_ptr< RCanvas > > GetCanvases()
Returns list of created canvases.
Definition: RCanvas.cxx:43
bool SaveAs(const std::string &filename)
Save canvas in image file.
Definition: RCanvas.cxx:143
bool IsModified() const
Returns true is canvas was modified since last painting.
Definition: RCanvas.cxx:53
void Show(const std::string &where="")
Display the canvas.
Definition: RCanvas.cxx:95
std::string GetWindowAddr() const
Returns window name used to display canvas.
Definition: RCanvas.cxx:121
void Remove()
Remove canvas from global canvas lists, will be destroyed when shared_ptr will be removed.
Definition: RCanvas.cxx:160
void ResolveSharedPtrs()
To resolve problem with storing of shared pointers Call this method when reading canvas from the file...
Definition: RCanvas.cxx:225
void Run(double tm=0.)
Run canvas functionality for given time (in seconds)
Definition: RCanvas.cxx:211
static std::shared_ptr< RCanvas > Create(const std::string &title)
Create new canvas instance.
Definition: RCanvas.cxx:70
void Update(bool async=false, CanvasCallback_t callback=nullptr)
update drawing
Definition: RCanvas.cxx:61
void Hide()
Hide all canvas displays.
Definition: RCanvas.cxx:133
std::unique_ptr< RDrawableReply > Process() override
Apply attributes changes to the drawable Return mask with actions which were really applied.
Definition: RCanvas.cxx:253
const Int_t n
Definition: legend1.C:16
std::vector< RIOSharedBase * > RIOSharedVector_t
Definition: RDrawable.hxx:51
std::function< void(bool)> CanvasCallback_t