Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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 <cstdio>
19#include <cstring>
20
21#include "TList.h"
22#include "TROOT.h"
23#include "TString.h"
24
25namespace {
26
27std::mutex &GetHeldCanvasesMutex()
28{
29 static std::mutex sMutex;
30 return sMutex;
31}
32
33std::vector<std::shared_ptr<ROOT::Experimental::RCanvas>> &GetHeldCanvases()
34{
35 static std::vector<std::shared_ptr<ROOT::Experimental::RCanvas>> sCanvases;
36 return sCanvases;
37}
38
39
40} // namespace
41
42///////////////////////////////////////////////////////////////////////////////////////
43/// Returns list of created canvases
44
45const std::vector<std::shared_ptr<ROOT::Experimental::RCanvas>> ROOT::Experimental::RCanvas::GetCanvases()
46{
47 std::lock_guard<std::mutex> grd(GetHeldCanvasesMutex());
48
49 return GetHeldCanvases();
50}
51
52///////////////////////////////////////////////////////////////////////////////////////
53/// Release list of held canvases pointers
54/// If no other shared pointers exists on the canvas, object will be destroyed
55
57{
58 std::vector<std::shared_ptr<ROOT::Experimental::RCanvas>> vect;
59
60 {
61 std::lock_guard<std::mutex> grd(GetHeldCanvasesMutex());
62
63 std::swap(vect, GetHeldCanvases());
64 }
65}
66
67///////////////////////////////////////////////////////////////////////////////////////
68/// Returns true is canvas was modified since last painting
69
71{
72 return fPainter ? fPainter->IsCanvasModified(fModified) : fModified;
73}
74
75///////////////////////////////////////////////////////////////////////////////////////
76/// Update canvas
77
79{
80 fUpdated = true;
81
82 if (fPainter)
83 fPainter->CanvasUpdated(fModified, async, callback);
84}
85
86///////////////////////////////////////////////////////////////////////////////////////
87/// Create new canvas instance
88
89std::shared_ptr<ROOT::Experimental::RCanvas> ROOT::Experimental::RCanvas::Create(const std::string &title)
90{
91 auto pCanvas = std::make_shared<RCanvas>();
92 pCanvas->SetTitle(title);
93 {
94 std::lock_guard<std::mutex> grd(GetHeldCanvasesMutex());
95 GetHeldCanvases().emplace_back(pCanvas);
96 }
97
98 return pCanvas;
99}
100
101//////////////////////////////////////////////////////////////////////////
102/// Create new display for the canvas
103/// The parameter `where` specifies which program could be used for display creation
104/// Possible values:
105///
106/// - `cef` Chromium Embeded Framework, local display, local communication
107/// - `qt5` Qt5 WebEngine (when running via rootqt5), local display, local communication
108/// - `browser` default system web-browser, communication via random http port from range 8800 - 9800
109/// - `<prog>` any program name which will be started instead of default browser, like firefox or /usr/bin/opera
110/// one could also specify $url in program name, which will be replaced with canvas URL
111/// - `native` either any available local display or default browser
112///
113/// Canvas can be displayed in several different places
114
115void ROOT::Experimental::RCanvas::Show(const std::string &where)
116{
117 fShown = true;
118
119 // Do not display canvas in batch mode
120 if (gROOT->IsWebDisplayBatch())
121 return;
122
123 if (fPainter) {
124 bool isany = (fPainter->NumDisplays() > 0);
125
126 if (!where.empty())
127 fPainter->NewDisplay(where);
128
129 if (isany) return;
130 }
131
132 if (!fModified)
133 fModified = 1; // 0 is special value, means no changes and no drawings
134
135 if (!fPainter)
137
138 if (fPainter) {
139 fPainter->NewDisplay(where);
140 fPainter->CanvasUpdated(fModified, true, nullptr); // trigger async display
141 }
142}
143
144//////////////////////////////////////////////////////////////////////////
145/// Returns window name for canvas
146
148{
149 if (fPainter)
150 return fPainter->GetWindowAddr();
151
152 return "";
153}
154
155//////////////////////////////////////////////////////////////////////////
156/// Returns window URL which can be used for connection
157/// See \ref ROOT::RWebWindow::GetUrl docu for more details
158
160{
161 if (fPainter)
162 return fPainter->GetWindowUrl(remote);
163
164 return "";
165}
166
167
168//////////////////////////////////////////////////////////////////////////
169/// Hide all canvas displays
170
172{
173 if (fPainter)
174 fPainter = nullptr;
175}
176
177//////////////////////////////////////////////////////////////////////////
178/// Create image file for the canvas
179/// Supported SVG (extension .svg), JPEG (extension .jpg or .jpeg), PNG (extension .png) or JSON (extension .json)
180
182{
183 if (!fPainter)
185
186 if (!fPainter)
187 return false;
188
189 int width = GetWidth();
190 int height = GetHeight();
191
192 return fPainter->ProduceBatchOutput(filename, width > 1 ? width : 800, height > 1 ? height : 600);
193}
194
195//////////////////////////////////////////////////////////////////////////
196/// Return unique identifier for the canvas
197/// Used in iPython display
198
200{
201 const void *ptr = this;
202 auto hash = TString::Hash(&ptr, sizeof(void*));
203 TString fmt = TString::Format("rcanv_%x", hash);
204 return fmt.Data();
205}
206
207//////////////////////////////////////////////////////////////////////////
208/// Create JSON data for the canvas
209/// Can be used of offline display with JSROOT
210
212{
213 if (!fPainter)
215
216 if (!fPainter)
217 return "";
218
219 return fPainter->ProduceJSON();
220}
221
222//////////////////////////////////////////////////////////////////////////
223/// Remove canvas from global canvas lists, will be destroyed once last shared_ptr is disappear
224
226{
227 std::lock_guard<std::mutex> grd(GetHeldCanvasesMutex());
228 auto &held = GetHeldCanvases();
229 auto indx = held.size();
230 while (indx-- > 0) {
231 if (held[indx].get() == this)
232 held.erase(held.begin() + indx);
233 }
234}
235
236//////////////////////////////////////////////////////////////////////////////////////////////
237/// Set handle which will be cleared when connection is closed
238
239void ROOT::Experimental::RCanvas::ClearOnClose(const std::shared_ptr<void> &handle)
240{
241 if (fPainter)
242 fPainter->SetClearOnClose(handle);
243}
244
245//////////////////////////////////////////////////////////////////////////
246/// Run canvas functionality for the given time (in seconds)
247/// Used to process canvas-related actions in the appropriate thread context.
248/// Must be regularly called when canvas created and used in extra thread.
249/// Time parameter specifies minimal execution time in seconds - if default value 0 is used,
250/// just all pending actions will be performed.
251/// When canvas is not yet displayed - just performs sleep for given time interval.
252///
253/// Example of usage:
254///
255/// ~~~ {.cpp}
256/// void draw_canvas(bool &run_loop, std::make_shared<RH1D> hist)
257/// {
258/// auto canvas = RCanvas::Create("Canvas title");
259/// canvas->Draw(hist)->SetLineColor(RColor::kBlue);
260/// canvas->Show();
261/// while (run_loop) {
262/// pHist->Fill(1);
263/// canvas->Modified();
264/// canvas->Update();
265/// canvas->Run(0.1); // process canvas events
266/// }
267///
268/// canvas->Remove();
269/// }
270///
271/// int main()
272/// {
273/// RAxisConfig xaxis(100, -10., 10.);
274/// auto pHist = std::make_shared<RH1D>(xaxis);
275/// bool run_loop = true;
276///
277/// std::thread thrd(draw_canvas, run_loop, pHist);
278/// std::this_thread::sleep_for(std::chrono::seconds(100));
279/// run_loop = false;
280/// thrd.join();
281/// return 0;
282/// }
283/// ~~~
284
286{
287 if (fPainter) {
288 fPainter->Run(tm);
289 } else if (tm>0) {
290 std::this_thread::sleep_for(std::chrono::milliseconds(int(tm*1000)));
291 }
292}
293
294//////////////////////////////////////////////////////////////////////////
295/// To resolve problem with storing of shared pointers
296/// Call this method when reading canvas from the file
297/// Can be called many times - after reinitialization of shared pointers no changes will be performed
298
300{
302
303 CollectShared(vect);
304
305 for (unsigned n = 0; n < vect.size(); ++n) {
306 if (vect[n]->HasShared() || !vect[n]->GetIOPtr()) continue;
307
308 auto shrd_ptr = vect[n]->MakeShared();
309
310 for (auto n2 = n+1; n2 < vect.size(); ++n2) {
311 if (vect[n2]->GetIOPtr() == vect[n]->GetIOPtr()) {
312 if (vect[n2]->HasShared())
313 R__LOG_ERROR(GPadLog()) << "FATAL Shared pointer for same IO ptr already exists";
314 else
315 vect[n2]->SetShared(shrd_ptr);
316 }
317 }
318
319 }
320}
321
322
323/////////////////////////////////////////////////////////////////////////////////////////////////
324/// Apply attributes changes to the drawable
325/// Return mask with actions which were really applied
326
327std::unique_ptr<ROOT::Experimental::RDrawableReply> ROOT::Experimental::RChangeAttrRequest::Process()
328{
329 // suppress all changes coming from non-main connection
330 if (!GetContext().IsMainConn())
331 return nullptr;
332
333 auto canv = const_cast<ROOT::Experimental::RCanvas *>(GetContext().GetCanvas());
334 if (!canv) return nullptr;
335
336 if ((ids.size() != names.size()) || (ids.size() != values.size())) {
337 R__LOG_ERROR(GPadLog()) << "Mismatch of arrays size in RChangeAttrRequest";
338 return nullptr;
339 }
340
341 Version_t vers = 0;
342
343 for(int indx = 0; indx < (int) ids.size(); indx++) {
344 if (ids[indx] == "canvas") {
345 if (canv->GetAttrMap().Change(names[indx], values[indx].get())) {
346 if (!vers) vers = canv->IncModified();
347 canv->SetDrawableVersion(vers);
348 }
349 } else {
350 auto drawable = canv->FindPrimitiveByDisplayId(ids[indx]);
351 if (drawable && drawable->GetAttrMap().Change(names[indx], values[indx].get())) {
352 if (!vers) vers = canv->IncModified();
353 drawable->SetDrawableVersion(vers);
354 }
355 }
356 }
357
358 fNeedUpdate = (vers > 0) && update;
359
360 return nullptr; // no need for any reply
361}
362
#define R__LOG_ERROR(...)
Definition RLogger.hxx:362
static void update(gsl_integration_workspace *workspace, double a1, double b1, double area1, double error1, double a2, double b2, double area2, double error2)
short Version_t
Definition RtypesCore.h:65
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t width
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t height
#define gROOT
Definition TROOT.h:406
static std::unique_ptr< RVirtualCanvasPainter > Create(RCanvas &canv)
Loads the plugin that implements this class.
A window's topmost RPad.
Definition RCanvas.hxx:47
static const std::vector< std::shared_ptr< RCanvas > > GetCanvases()
Returns list of created canvases.
Definition RCanvas.cxx:45
static void ReleaseHeldCanvases()
Release list of held canvases pointers If no other shared pointers exists on the canvas,...
Definition RCanvas.cxx:56
bool SaveAs(const std::string &filename)
Save canvas in image file.
Definition RCanvas.cxx:181
std::string GetWindowUrl(bool remote)
Returns window URL which can be used for connection.
Definition RCanvas.cxx:159
bool IsModified() const
Returns true is canvas was modified since last painting.
Definition RCanvas.cxx:70
void Show(const std::string &where="")
Display the canvas.
Definition RCanvas.cxx:115
std::string GetWindowAddr() const
Returns window name used to display canvas.
Definition RCanvas.cxx:147
void Remove()
Remove canvas from global canvas lists, will be destroyed when shared_ptr will be removed.
Definition RCanvas.cxx:225
void ResolveSharedPtrs()
To resolve problem with storing of shared pointers Call this method when reading canvas from the file...
Definition RCanvas.cxx:299
void Run(double tm=0.)
Run canvas functionality for given time (in seconds)
Definition RCanvas.cxx:285
std::string GetUID() const
Return unique identifier for the canvas Used in iPython display.
Definition RCanvas.cxx:199
std::string CreateJSON()
Provide JSON which can be used for offline display.
Definition RCanvas.cxx:211
static std::shared_ptr< RCanvas > Create(const std::string &title)
Create new canvas instance.
Definition RCanvas.cxx:89
void ClearOnClose(const std::shared_ptr< void > &handle)
Set handle which will be cleared when connection is closed.
Definition RCanvas.cxx:239
void Update(bool async=false, CanvasCallback_t callback=nullptr)
update drawing
Definition RCanvas.cxx:78
void Hide()
Hide all canvas displays.
Definition RCanvas.cxx:171
std::unique_ptr< RDrawableReply > Process() override
Apply attributes changes to the drawable Return mask with actions which were really applied.
Definition RCanvas.cxx:327
Basic string class.
Definition TString.h:139
const char * Data() const
Definition TString.h:376
UInt_t Hash(ECaseCompare cmp=kExact) const
Return hash value.
Definition TString.cxx:677
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2378
const Int_t n
Definition legend1.C:16
std::vector< RIOSharedBase * > RIOSharedVector_t
Definition RDrawable.hxx:52
std::function< void(bool)> CanvasCallback_t
RLogChannel & GPadLog()
Log channel for GPad diagnostics.
Definition RAttrBase.cxx:17