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//////////////////////////////////////////////////////////////////////////
157/// Hide all canvas displays
158
160{
161 if (fPainter)
162 fPainter = nullptr;
163}
164
165//////////////////////////////////////////////////////////////////////////
166/// Create image file for the canvas
167/// Supported SVG (extension .svg), JPEG (extension .jpg or .jpeg), PNG (extension .png) or JSON (extension .json)
168
170{
171 if (!fPainter)
173
174 if (!fPainter)
175 return false;
176
177 int width = GetWidth();
178 int height = GetHeight();
179
180 return fPainter->ProduceBatchOutput(filename, width > 1 ? width : 800, height > 1 ? height : 600);
181}
182
183//////////////////////////////////////////////////////////////////////////
184/// Return unique identifier for the canvas
185/// Used in iPython display
186
188{
189 const void *ptr = this;
190 auto hash = TString::Hash(&ptr, sizeof(void*));
191 TString fmt = TString::Format("rcanv_%x", hash);
192 return fmt.Data();
193}
194
195//////////////////////////////////////////////////////////////////////////
196/// Create JSON data for the canvas
197/// Can be used of offline display with JSROOT
198
200{
201 if (!fPainter)
203
204 if (!fPainter)
205 return "";
206
207 return fPainter->ProduceJSON();
208}
209
210//////////////////////////////////////////////////////////////////////////
211/// Remove canvas from global canvas lists, will be destroyed once last shared_ptr is disappear
212
214{
215 std::lock_guard<std::mutex> grd(GetHeldCanvasesMutex());
216 auto &held = GetHeldCanvases();
217 auto indx = held.size();
218 while (indx-- > 0) {
219 if (held[indx].get() == this)
220 held.erase(held.begin() + indx);
221 }
222}
223
224//////////////////////////////////////////////////////////////////////////////////////////////
225/// Set handle which will be cleared when connection is closed
226
227void ROOT::Experimental::RCanvas::ClearOnClose(const std::shared_ptr<void> &handle)
228{
229 if (fPainter)
230 fPainter->SetClearOnClose(handle);
231}
232
233//////////////////////////////////////////////////////////////////////////
234/// Run canvas functionality for the given time (in seconds)
235/// Used to process canvas-related actions in the appropriate thread context.
236/// Must be regularly called when canvas created and used in extra thread.
237/// Time parameter specifies minimal execution time in seconds - if default value 0 is used,
238/// just all pending actions will be performed.
239/// When canvas is not yet displayed - just performs sleep for given time interval.
240///
241/// Example of usage:
242///
243/// ~~~ {.cpp}
244/// void draw_canvas(bool &run_loop, std::make_shared<RH1D> hist)
245/// {
246/// auto canvas = RCanvas::Create("Canvas title");
247/// canvas->Draw(hist)->SetLineColor(RColor::kBlue);
248/// canvas->Show();
249/// while (run_loop) {
250/// pHist->Fill(1);
251/// canvas->Modified();
252/// canvas->Update();
253/// canvas->Run(0.1); // process canvas events
254/// }
255///
256/// canvas->Remove();
257/// }
258///
259/// int main()
260/// {
261/// RAxisConfig xaxis(100, -10., 10.);
262/// auto pHist = std::make_shared<RH1D>(xaxis);
263/// bool run_loop = true;
264///
265/// std::thread thrd(draw_canvas, run_loop, pHist);
266/// std::this_thread::sleep_for(std::chrono::seconds(100));
267/// run_loop = false;
268/// thrd.join();
269/// return 0;
270/// }
271/// ~~~
272
274{
275 if (fPainter) {
276 fPainter->Run(tm);
277 } else if (tm>0) {
278 std::this_thread::sleep_for(std::chrono::milliseconds(int(tm*1000)));
279 }
280}
281
282//////////////////////////////////////////////////////////////////////////
283/// To resolve problem with storing of shared pointers
284/// Call this method when reading canvas from the file
285/// Can be called many times - after reinitialization of shared pointers no changes will be performed
286
288{
290
291 CollectShared(vect);
292
293 for (unsigned n = 0; n < vect.size(); ++n) {
294 if (vect[n]->HasShared() || !vect[n]->GetIOPtr()) continue;
295
296 auto shrd_ptr = vect[n]->MakeShared();
297
298 for (auto n2 = n+1; n2 < vect.size(); ++n2) {
299 if (vect[n2]->GetIOPtr() == vect[n]->GetIOPtr()) {
300 if (vect[n2]->HasShared())
301 R__LOG_ERROR(GPadLog()) << "FATAL Shared pointer for same IO ptr already exists";
302 else
303 vect[n2]->SetShared(shrd_ptr);
304 }
305 }
306
307 }
308}
309
310
311/////////////////////////////////////////////////////////////////////////////////////////////////
312/// Apply attributes changes to the drawable
313/// Return mask with actions which were really applied
314
315std::unique_ptr<ROOT::Experimental::RDrawableReply> ROOT::Experimental::RChangeAttrRequest::Process()
316{
317 // suppress all changes coming from non-main connection
318 if (!GetContext().IsMainConn())
319 return nullptr;
320
321 auto canv = const_cast<ROOT::Experimental::RCanvas *>(GetContext().GetCanvas());
322 if (!canv) return nullptr;
323
324 if ((ids.size() != names.size()) || (ids.size() != values.size())) {
325 R__LOG_ERROR(GPadLog()) << "Mismatch of arrays size in RChangeAttrRequest";
326 return nullptr;
327 }
328
329 Version_t vers = 0;
330
331 for(int indx = 0; indx < (int) ids.size(); indx++) {
332 if (ids[indx] == "canvas") {
333 if (canv->GetAttrMap().Change(names[indx], values[indx].get())) {
334 if (!vers) vers = canv->IncModified();
335 canv->SetDrawableVersion(vers);
336 }
337 } else {
338 auto drawable = canv->FindPrimitiveByDisplayId(ids[indx]);
339 if (drawable && drawable->GetAttrMap().Change(names[indx], values[indx].get())) {
340 if (!vers) vers = canv->IncModified();
341 drawable->SetDrawableVersion(vers);
342 }
343 }
344 }
345
346 fNeedUpdate = (vers > 0) && update;
347
348 return nullptr; // no need for any reply
349}
350
#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:169
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:213
void ResolveSharedPtrs()
To resolve problem with storing of shared pointers Call this method when reading canvas from the file...
Definition RCanvas.cxx:287
void Run(double tm=0.)
Run canvas functionality for given time (in seconds)
Definition RCanvas.cxx:273
std::string GetUID() const
Return unique identifier for the canvas Used in iPython display.
Definition RCanvas.cxx:187
std::string CreateJSON()
Provide JSON which can be used for offline display.
Definition RCanvas.cxx:199
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:227
void Update(bool async=false, CanvasCallback_t callback=nullptr)
update drawing
Definition RCanvas.cxx:78
void Hide()
Hide all canvas displays.
Definition RCanvas.cxx:159
std::unique_ptr< RDrawableReply > Process() override
Apply attributes changes to the drawable Return mask with actions which were really applied.
Definition RCanvas.cxx:315
Basic string class.
Definition TString.h:139
const char * Data() const
Definition TString.h:377
UInt_t Hash(ECaseCompare cmp=kExact) const
Return hash value.
Definition TString.cxx:671
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:2357
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