Logo ROOT   6.18/05
Reference Guide
RCanvas.cxx
Go to the documentation of this file.
1/// \file RCanvas.cxx
2/// \ingroup Gpad ROOT7
3/// \author Axel Naumann <axel@cern.ch>
4/// \date 2015-07-10
5/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
6/// is welcome!
7
8/*************************************************************************
9 * Copyright (C) 1995-2015, Rene Brun and Fons Rademakers. *
10 * All rights reserved. *
11 * *
12 * For the licensing terms see $ROOTSYS/LICENSE. *
13 * For the list of contributors see $ROOTSYS/README/CREDITS. *
14 *************************************************************************/
15
16#include "ROOT/RCanvas.hxx"
17
18#include "ROOT/RLogger.hxx"
19
20#include <algorithm>
21#include <memory>
22#include <mutex>
23#include <thread>
24#include <chrono>
25#include <stdio.h>
26#include <string.h>
27
28#include "TROOT.h"
29
30namespace {
31
32static std::mutex &GetHeldCanvasesMutex()
33{
34 static std::mutex sMutex;
35 return sMutex;
36}
37
38static std::vector<std::shared_ptr<ROOT::Experimental::RCanvas>> &GetHeldCanvases()
39{
40 static std::vector<std::shared_ptr<ROOT::Experimental::RCanvas>> sCanvases;
41 return sCanvases;
42}
43
44
45} // namespace
46
47const std::vector<std::shared_ptr<ROOT::Experimental::RCanvas>> ROOT::Experimental::RCanvas::GetCanvases()
48{
49 std::lock_guard<std::mutex> grd(GetHeldCanvasesMutex());
50
51 return GetHeldCanvases();
52}
53
54// void ROOT::Experimental::RCanvas::Paint() {
55// for (auto&& drw: fPrimitives) {
56// drw->Paint(*this);
57// }
58// }
59
60///////////////////////////////////////////////////////////////////////////////////////
61/// Generates unique ID inside the canvas
62
64{
65 return std::to_string(fIdCounter++);
66}
67
68///////////////////////////////////////////////////////////////////////////////////////
69/// Returns true is canvas was modified since last painting
70
72{
73 return fPainter ? fPainter->IsCanvasModified(fModified) : fModified;
74}
75
77{
78 if (fPainter)
79 fPainter->CanvasUpdated(fModified, async, callback);
80
81 // SnapshotList_t lst;
82 // for (auto&& drw: fPrimitives) {
83 // TSnapshot *snap = drw->CreateSnapshot(*this);
84 // lst.push_back(std::unique_ptr<TSnapshot>(snap));
85 // }
86}
87
88std::shared_ptr<ROOT::Experimental::RCanvas> ROOT::Experimental::RCanvas::Create(const std::string &title)
89{
90 auto pCanvas = std::make_shared<RCanvas>();
91 pCanvas->SetTitle(title);
92 {
93 std::lock_guard<std::mutex> grd(GetHeldCanvasesMutex());
94 GetHeldCanvases().emplace_back(pCanvas);
95 }
96 return pCanvas;
97}
98
99//////////////////////////////////////////////////////////////////////////
100/// Create new display for the canvas
101/// Parameter \par where specifies which program could be used for display creation
102/// Possible values:
103///
104/// cef - Chromium Embeded Framework, local display, local communication
105/// qt5 - Qt5 WebEngine (when running via rootqt5), local display, local communication
106/// browser - default system web-browser, communication via random http port from range 8800 - 9800
107/// <prog> - any program name which will be started instead of default browser, like firefox or /usr/bin/opera
108/// one could also specify $url in program name, which will be replaced with canvas URL
109/// native - either any available local display or default browser
110///
111/// Canvas can be displayed in several different places
112
113void ROOT::Experimental::RCanvas::Show(const std::string &where)
114{
115 if (fPainter) {
116 bool isany = (fPainter->NumDisplays() > 0);
117
118 if (!where.empty())
119 fPainter->NewDisplay(where);
120
121 if (isany) return;
122 }
123
124 if (!fModified)
125 fModified = 1; // 0 is special value, means no changes and no drawings
126
127 if (!fPainter)
129
130 if (fPainter) {
131 fPainter->NewDisplay(where);
132 fPainter->CanvasUpdated(fModified, true, nullptr); // trigger async display
133 }
134}
135
136//////////////////////////////////////////////////////////////////////////
137/// Hide all canvas displays
138
140{
141 if (fPainter)
142 delete fPainter.release();
143}
144
145//////////////////////////////////////////////////////////////////////////
146/// Create image file for the canvas
147/// Supported SVG (extension .svg), JPEG (extension .jpg or .jpeg) and PNG (extension .png)
148/// \param async specifies if file can be created asynchronous to the caller thread
149/// When operation completed, callback function is called
150
151void ROOT::Experimental::RCanvas::SaveAs(const std::string &filename, bool async, CanvasCallback_t callback)
152{
153 if (!fPainter)
155
156 if (!fModified)
157 fModified = 1; // 0 is special value, means no changes and no drawings
158
159 // TODO: for the future one have to ensure only batch connection is updated
160 Update(); // ensure that snapshot is created
161
162 if (filename.find(".json") != std::string::npos) {
163 fPainter->DoWhenReady("JSON", filename, async, callback);
164 } else if (filename.find(".svg") != std::string::npos)
165 fPainter->DoWhenReady("SVG", filename, async, callback);
166 else if (filename.find(".png") != std::string::npos)
167 fPainter->DoWhenReady("PNG", filename, async, callback);
168 else if ((filename.find(".jpg") != std::string::npos) || (filename.find(".jpeg") != std::string::npos))
169 fPainter->DoWhenReady("JPEG", filename, async, callback);
170}
171
172//////////////////////////////////////////////////////////////////////////
173/// Remove canvas from global canvas lists, will be destroyed once last shared_ptr is disappear
174
176{
177 std::lock_guard<std::mutex> grd(GetHeldCanvasesMutex());
178 auto &held = GetHeldCanvases();
179 auto indx = held.size();
180 while (indx-- > 0) {
181 if (held[indx].get() == this)
182 held.erase(held.begin() + indx);
183 }
184}
185
186//////////////////////////////////////////////////////////////////////////
187/// Run canvas functionality for the given time (in seconds)
188/// Used to process canvas-related actions in the appropriate thread context.
189/// Must be regularly called when canvas created and used in extra thread.
190/// Time parameter specifies minimal execution time in seconds - if default value 0 is used,
191/// just all pending actions will be performed.
192/// When canvas is not yet displayed - just performs sleep for given time interval.
193///
194/// Example of usage:
195///
196/// ~~~ {.cpp}
197/// void draw_canvas(bool &run_loop, std::make_shared<RH1D> hist)
198/// {
199/// auto canvas = RCanvas::Create("Canvas title");
200/// canvas->Draw(hist)->SetLineColor(RColor::kBlue);
201/// canvas->Show();
202/// while (run_loop) {
203/// pHist->Fill(1);
204/// canvas->Modified();
205/// canvas->Update();
206/// canvas->Run(0.1); // process canvas events
207/// }
208///
209/// canvas->Remove();
210/// }
211///
212/// int main()
213/// {
214/// RAxisConfig xaxis(100, -10., 10.);
215/// auto pHist = std::make_shared<RH1D>(xaxis);
216/// bool run_loop = true;
217///
218/// std::thread thrd(draw_canvas, run_loop, pHist);
219/// std::this_thread::sleep_for(std::chrono::seconds(100));
220/// run_loop = false;
221/// thrd.join();
222/// return 0;
223/// }
224/// ~~~
225
227{
228 if (fPainter) {
229 fPainter->Run(tm);
230 } else if (tm>0) {
231 std::this_thread::sleep_for(std::chrono::milliseconds(int(tm*1000)));
232 }
233}
static std::unique_ptr< RVirtualCanvasPainter > Create(const RCanvas &canv)
Loads the plugin that implements this class.
static const std::vector< std::shared_ptr< RCanvas > > GetCanvases()
Definition: RCanvas.cxx:47
bool IsModified() const
Returns true is canvas was modified since last painting.
Definition: RCanvas.cxx:71
void Show(const std::string &where="")
Display the canvas.
Definition: RCanvas.cxx:113
void Remove()
Remove canvas from global canvas lists, will be destroyed when shared_ptr will be removed.
Definition: RCanvas.cxx:175
void Run(double tm=0.)
Run canvas functionality for given time (in seconds)
Definition: RCanvas.cxx:226
static std::shared_ptr< RCanvas > Create(const std::string &title)
Definition: RCanvas.cxx:88
void Update(bool async=false, CanvasCallback_t callback=nullptr)
update drawing
Definition: RCanvas.cxx:76
void SaveAs(const std::string &filename, bool async=false, CanvasCallback_t callback=nullptr)
Save canvas in image file.
Definition: RCanvas.cxx:151
std::string GenerateUniqueId()
Generates unique ID inside the canvas.
Definition: RCanvas.cxx:63
void Hide()
Hide all canvas displays.
Definition: RCanvas.cxx:139
std::function< void(bool)> CanvasCallback_t