Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
webgui: let specify place where canvas should be shown
By defauly, ROOT will try to crate local window with CEF or Qt5.
If not available, default browser will be started.
If place is specified, it should be program name like:
   canvas->Show("/usr/bin/opera");
   canvas->Show("firefox");

One could show canvas in several different places.
  • Loading branch information
linev committed Jul 26, 2017
commit ccfbdd19b7c971b628e9683aed86015aca9ac903
4 changes: 2 additions & 2 deletions graf2d/gpad/v7/inc/ROOT/TCanvas.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ public:
/// Remove an object from the list of primitives.
// TODO: void Wipe();

/// Actually display the canvas.
void Show();
/// Display the canvas.
void Show(const std::string &where = "");

// Indicates that any object was modified
void Modified();
Expand Down
2 changes: 2 additions & 0 deletions graf2d/gpad/v7/inc/ROOT/TVirtualCanvasPainter.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ public:
/// perform special action when drawing is ready
virtual void DoWhenReady(const std::string &, const std::string &) = 0;

virtual void NewDisplay(const std::string &where) = 0;

/// Loads the plugin that implements this class.
static std::unique_ptr<TVirtualCanvasPainter> Create(const TCanvas &canv, bool batch_mode = false);
};
Expand Down
13 changes: 9 additions & 4 deletions graf2d/gpad/v7/src/TCanvas.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -73,17 +73,22 @@ std::shared_ptr<ROOT::Experimental::TCanvas> ROOT::Experimental::TCanvas::Create
return pCanvas;
}

void ROOT::Experimental::TCanvas::Show()
void ROOT::Experimental::TCanvas::Show(const std::string &where)
{
if (fPainter)
if (fPainter) {
if (!where.empty()) fPainter->NewDisplay(where);
return;
}

bool batch_mode = gROOT->IsBatch();
if (!fModified)
fModified = 1; // 0 is special value, means no changes and no drawings

fPainter = Internal::TVirtualCanvasPainter::Create(*this, batch_mode);
if (fPainter)
fPainter->CanvasUpdated(fModified, false);
if (fPainter) {
fPainter->NewDisplay(where);
fPainter->CanvasUpdated(fModified, true); // trigger async display
}
}

void ROOT::Experimental::TCanvas::SaveAs(const std::string &filename)
Expand Down
39 changes: 24 additions & 15 deletions gui/canvaspainter/v7/src/TCanvasPainter.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,6 @@ class TCanvasPainter : public THttpWSHandler,
ROOT::Experimental::Internal::TDrawable *FindDrawable(const ROOT::Experimental::TCanvas &can, const std::string &id);

void CreateHttpServer(Bool_t with_http = kFALSE);
void PopupBrowser();
void CheckDataToSend();

bool WaitWhenCanvasPainted(uint64_t ver);
Expand All @@ -222,7 +221,6 @@ class TCanvasPainter : public THttpWSHandler,
{
CreateHttpServer();
gServer->Register("/web7gui", this);
PopupBrowser();
}

virtual bool IsBatchMode() const { return fBatchMode; }
Expand All @@ -236,6 +234,9 @@ class TCanvasPainter : public THttpWSHandler,
/// perform special action when drawing is ready
virtual void DoWhenReady(const std::string &cmd, const std::string &arg) final;

// open new display for the canvas
virtual void NewDisplay(const std::string &where) override;

// void ReactToSocketNews(...) override { SendCanvas(); }

/** \class CanvasPainterGenerator
Expand Down Expand Up @@ -302,18 +303,18 @@ void TCanvasPainter::CreateHttpServer(Bool_t with_http)
gServer->CreateEngine(TString::Format("http:%s?websocket_timeout=10000", port).Data());
}

void TCanvasPainter::PopupBrowser()
void TCanvasPainter::NewDisplay(const std::string &where)
{
TString addr;

Func_t symbol_qt5 = gSystem->DynFindSymbol("*", "webgui_start_browser_in_qt5");
if (symbol_qt5) {
if (symbol_qt5 && (where.empty() || (where == "qt5") || (where == "native"))) {
typedef void (*FunctionQt5)(const char *, void *, bool);

addr.Form("://dummy:8080/web7gui/%s/draw.htm?longpollcanvas%s", GetName(), (IsBatchMode() ? "&batch_mode" : ""));
// addr.Form("example://localhost:8080/Canvases/%s/draw.htm", Canvas()->GetName());

Info("PopupBrowser", "Show canvas in Qt5 window: %s", addr.Data());
Info("NewDisplay", "Show canvas in Qt5 window: %s", addr.Data());

FunctionQt5 func = (FunctionQt5)symbol_qt5;
func(addr.Data(), gServer, IsBatchMode());
Expand All @@ -323,13 +324,14 @@ void TCanvasPainter::PopupBrowser()
Func_t symbol_cef = gSystem->DynFindSymbol("*", "webgui_start_browser_in_cef3");
const char *cef_path = gSystem->Getenv("CEF_PATH");
const char *rootsys = gSystem->Getenv("ROOTSYS");
if (symbol_cef && cef_path && !gSystem->AccessPathName(cef_path) && rootsys) {
if (symbol_cef && cef_path && !gSystem->AccessPathName(cef_path) && rootsys &&
(where.empty() || (where == "cef") || (where == "native"))) {
typedef void (*FunctionCef3)(const char *, void *, bool, const char *, const char *);

// addr.Form("/web7gui/%s/draw.htm?cef_canvas%s", GetName(), (IsBatchMode() ? "&batch_mode" : ""));
addr.Form("/web7gui/%s/draw.htm?cef_canvas%s", GetName(), (IsBatchMode() ? "&batch_mode" : ""));

Info("PopupBrowser", "Show canvas in CEF window: %s", addr.Data());
Info("NewDisplay", "Show canvas in CEF window: %s", addr.Data());

FunctionCef3 func = (FunctionCef3)symbol_cef;
func(addr.Data(), gServer, IsBatchMode(), rootsys, cef_path);
Expand All @@ -343,12 +345,14 @@ void TCanvasPainter::PopupBrowser()

TString exec;

if (gSystem->InheritsFrom("TMacOSXSystem"))
if (!where.empty() && (where != "native"))
exec.Form("%s %s", where.c_str(), addr.Data());
else if (gSystem->InheritsFrom("TMacOSXSystem"))
exec.Form("open %s", addr.Data());
else
exec.Form("xdg-open %s &", addr.Data());

Info("PopupBrowser", "Show canvas in browser with cmd: %s", exec.Data());
Info("NewDisplay", "Show canvas in browser with cmd: %s", exec.Data());

gSystem->Exec(exec);
}
Expand All @@ -360,7 +364,8 @@ void TCanvasPainter::CanvasUpdated(uint64_t ver, bool async)

CheckDataToSend();

if (!async) WaitWhenCanvasPainted(ver);
if (!async)
WaitWhenCanvasPainted(ver);
}

bool TCanvasPainter::WaitWhenCanvasPainted(uint64_t ver)
Expand All @@ -371,15 +376,19 @@ bool TCanvasPainter::WaitWhenCanvasPainted(uint64_t ver)
bool had_connection = false;

while (true) {
if (fWebConn.size() > 0) had_connection = true;
if ((fWebConn.size()==0) && (had_connection || (cnt>1000))) return false; // wait ~1 min if no new connection established
if (fSnapshotDelivered >= ver) { printf("PAINT READY!!!\n"); return true; }
if (fWebConn.size() > 0)
had_connection = true;
if ((fWebConn.size() == 0) && (had_connection || (cnt > 1000)))
return false; // wait ~1 min if no new connection established
if (fSnapshotDelivered >= ver) {
printf("PAINT READY!!!\n");
return true;
}
gSystem->ProcessEvents();
gSystem->Sleep((++cnt<500) ? 1 : 100); // increase sleep interval when do very often
gSystem->Sleep((++cnt < 500) ? 1 : 100); // increase sleep interval when do very often
}

return false;

}

void TCanvasPainter::DoWhenReady(const std::string &cmd, const std::string &arg)
Expand Down
4 changes: 3 additions & 1 deletion tutorials/v7/draw_v6.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ void draw_v6()
auto canvas = Experimental::TCanvas::Create("v7 TCanvas showing a v6 TGraph");
canvas->Draw(gr);

canvas->Show();
canvas->Show(); // one could use canvas->Show("/usr/bin/opera"); or canvas->Show("firefox");

canvas->Update(); // wait until painting is finished

canvas->SaveAs("draw.png"); // only .svg and .png are supported for the moment, asynchron
}