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