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