Mercurial > hg > orthanc-stone
changeset 891:0aff28f15ea2
new abstraction: IViewport
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Applications/Sdl/SdlOpenGLContext.cpp Wed Jul 10 18:18:42 2019 +0200 @@ -0,0 +1,122 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#include "SdlOpenGLContext.h" + +#if ORTHANC_ENABLE_SDL == 1 + +#if !defined(ORTHANC_ENABLE_GLEW) +# error Macro ORTHANC_ENABLE_GLEW must be defined +#endif + +#if ORTHANC_ENABLE_GLEW == 1 +# include <GL/glew.h> +#endif + +#include <Core/OrthancException.h> + +namespace OrthancStone +{ + SdlOpenGLContext::SdlOpenGLContext(const char* title, + unsigned int width, + unsigned int height, + bool allowDpiScaling) : + window_(title, width, height, true /* enable OpenGL */, allowDpiScaling) + { + context_ = SDL_GL_CreateContext(window_.GetObject()); + + if (context_ == NULL) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, + "Cannot initialize OpenGL"); + } + +#if ORTHANC_ENABLE_GLEW == 1 + // The initialization function of glew (i.e. "glewInit()") can + // only be called once an OpenGL is setup. + // https://stackoverflow.com/a/45033669/881731 + { + static boost::mutex mutex_; + static bool isGlewInitialized_ = false; + + boost::mutex::scoped_lock lock(mutex_); + + if (!isGlewInitialized_) + { + LOG(INFO) << "Initializing glew"; + + GLenum err = glewInit(); + if (GLEW_OK != err) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, + "Cannot initialize glew"); + } + + isGlewInitialized_ = true; + } + } +#endif + } + + + SdlOpenGLContext::~SdlOpenGLContext() + { + SDL_GL_DeleteContext(context_); + } + + + void SdlOpenGLContext::MakeCurrent() + { + if (SDL_GL_MakeCurrent(window_.GetObject(), context_) != 0) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, + "Cannot set current OpenGL context"); + } + + // This makes our buffer swap syncronized with the monitor's vertical refresh + SDL_GL_SetSwapInterval(1); + } + + + void SdlOpenGLContext::SwapBuffer() + { + // Swap our buffer to display the current contents of buffer on screen + SDL_GL_SwapWindow(window_.GetObject()); + } + + + unsigned int SdlOpenGLContext::GetCanvasWidth() const + { + int w = 0; + SDL_GL_GetDrawableSize(window_.GetObject(), &w, NULL); + return static_cast<unsigned int>(w); + } + + + unsigned int SdlOpenGLContext::GetCanvasHeight() const + { + int h = 0; + SDL_GL_GetDrawableSize(window_.GetObject(), NULL, &h); + return static_cast<unsigned int>(h); + } +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Applications/Sdl/SdlOpenGLContext.h Wed Jul 10 18:18:42 2019 +0200 @@ -0,0 +1,60 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#if ORTHANC_ENABLE_SDL == 1 + +#include "../../Framework/OpenGL/IOpenGLContext.h" +#include "SdlWindow.h" + +namespace OrthancStone +{ + class SdlOpenGLContext : public OpenGL::IOpenGLContext + { + private: + SdlWindow window_; + SDL_GLContext context_; + + public: + SdlOpenGLContext(const char* title, + unsigned int width, + unsigned int height, + bool allowDpiScaling = true); + + ~SdlOpenGLContext(); + + SdlWindow& GetWindow() + { + return window_; + } + + virtual void MakeCurrent(); + + virtual void SwapBuffer(); + + virtual unsigned int GetCanvasWidth() const; + + virtual unsigned int GetCanvasHeight() const; + }; +} + +#endif
--- a/Applications/Sdl/SdlOpenGLWindow.cpp Wed Jul 10 15:23:13 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,122 +0,0 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2019 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - **/ - - -#include "SdlOpenGLWindow.h" - -#if ORTHANC_ENABLE_SDL == 1 - -#if !defined(ORTHANC_ENABLE_GLEW) -# error Macro ORTHANC_ENABLE_GLEW must be defined -#endif - -#if ORTHANC_ENABLE_GLEW == 1 -# include <GL/glew.h> -#endif - -#include <Core/OrthancException.h> - -namespace OrthancStone -{ - SdlOpenGLWindow::SdlOpenGLWindow(const char* title, - unsigned int width, - unsigned int height, - bool allowDpiScaling) : - window_(title, width, height, true /* enable OpenGL */, allowDpiScaling) - { - context_ = SDL_GL_CreateContext(window_.GetObject()); - - if (context_ == NULL) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, - "Cannot initialize OpenGL"); - } - -#if ORTHANC_ENABLE_GLEW == 1 - // The initialization function of glew (i.e. "glewInit()") can - // only be called once an OpenGL is setup. - // https://stackoverflow.com/a/45033669/881731 - { - static boost::mutex mutex_; - static bool isGlewInitialized_ = false; - - boost::mutex::scoped_lock lock(mutex_); - - if (!isGlewInitialized_) - { - LOG(INFO) << "Initializing glew"; - - GLenum err = glewInit(); - if (GLEW_OK != err) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, - "Cannot initialize glew"); - } - - isGlewInitialized_ = true; - } - } -#endif - } - - - SdlOpenGLWindow::~SdlOpenGLWindow() - { - SDL_GL_DeleteContext(context_); - } - - - void SdlOpenGLWindow::MakeCurrent() - { - if (SDL_GL_MakeCurrent(window_.GetObject(), context_) != 0) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, - "Cannot set current OpenGL context"); - } - - // This makes our buffer swap syncronized with the monitor's vertical refresh - SDL_GL_SetSwapInterval(1); - } - - - void SdlOpenGLWindow::SwapBuffer() - { - // Swap our buffer to display the current contents of buffer on screen - SDL_GL_SwapWindow(window_.GetObject()); - } - - - unsigned int SdlOpenGLWindow::GetCanvasWidth() const - { - int w = 0; - SDL_GL_GetDrawableSize(window_.GetObject(), &w, NULL); - return static_cast<unsigned int>(w); - } - - - unsigned int SdlOpenGLWindow::GetCanvasHeight() const - { - int h = 0; - SDL_GL_GetDrawableSize(window_.GetObject(), NULL, &h); - return static_cast<unsigned int>(h); - } -} - -#endif
--- a/Applications/Sdl/SdlOpenGLWindow.h Wed Jul 10 15:23:13 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2019 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - **/ - - -#pragma once - -#if ORTHANC_ENABLE_SDL == 1 - -#include "../../Framework/OpenGL/IOpenGLContext.h" -#include "SdlWindow.h" - -namespace OrthancStone -{ - class SdlOpenGLWindow : public OpenGL::IOpenGLContext - { - private: - SdlWindow window_; - SDL_GLContext context_; - - public: - SdlOpenGLWindow(const char* title, - unsigned int width, - unsigned int height, - bool allowDpiScaling = true); - - ~SdlOpenGLWindow(); - - SdlWindow& GetWindow() - { - return window_; - } - - virtual void MakeCurrent(); - - virtual void SwapBuffer(); - - virtual unsigned int GetCanvasWidth() const; - - virtual unsigned int GetCanvasHeight() const; - }; -} - -#endif
--- a/Framework/OpenGL/WebAssemblyOpenGLContext.cpp Wed Jul 10 15:23:13 2019 +0200 +++ b/Framework/OpenGL/WebAssemblyOpenGLContext.cpp Wed Jul 10 18:18:42 2019 +0200 @@ -21,8 +21,6 @@ #include "WebAssemblyOpenGLContext.h" -#if ORTHANC_ENABLE_WASM == 1 - #include <Core/OrthancException.h> #include <emscripten/html5.h> @@ -175,5 +173,3 @@ } } } - -#endif
--- a/Framework/OpenGL/WebAssemblyOpenGLContext.h Wed Jul 10 15:23:13 2019 +0200 +++ b/Framework/OpenGL/WebAssemblyOpenGLContext.h Wed Jul 10 18:18:42 2019 +0200 @@ -25,7 +25,17 @@ # error Macro ORTHANC_ENABLE_WASM must be defined #endif -#if ORTHANC_ENABLE_WASM == 1 +#if ORTHANC_ENABLE_WASM != 1 +# error This file can only be used if targeting WebAssembly +#endif + +#if !defined(ORTHANC_ENABLE_OPENGL) +# error The macro ORTHANC_ENABLE_OPENGL must be defined +#endif + +#if ORTHANC_ENABLE_OPENGL != 1 +# error Support for OpenGL is disabled +#endif #include "IOpenGLContext.h" @@ -58,5 +68,3 @@ }; } } - -#endif
--- a/Framework/Scene2D/OpenGLCompositor.cpp Wed Jul 10 15:23:13 2019 +0200 +++ b/Framework/Scene2D/OpenGLCompositor.cpp Wed Jul 10 18:18:42 2019 +0200 @@ -200,12 +200,4 @@ SetFont(index, dict); } #endif - - - ScenePoint2D OpenGLCompositor::GetPixelCenterCoordinates(int x, int y) const - { - return ScenePoint2D( - static_cast<double>(x) + 0.5 - static_cast<double>(canvasWidth_) / 2.0, - static_cast<double>(y) + 0.5 - static_cast<double>(canvasHeight_) / 2.0); - } }
--- a/Framework/Scene2D/OpenGLCompositor.h Wed Jul 10 15:23:13 2019 +0200 +++ b/Framework/Scene2D/OpenGLCompositor.h Wed Jul 10 18:18:42 2019 +0200 @@ -77,8 +77,5 @@ { return canvasHeight_; } - - // TODO => REMOVE - ScenePoint2D GetPixelCenterCoordinates(int x, int y) const; }; }
--- a/Framework/Scene2DViewport/AngleMeasureTool.cpp Wed Jul 10 15:23:13 2019 +0200 +++ b/Framework/Scene2DViewport/AngleMeasureTool.cpp Wed Jul 10 18:18:42 2019 +0200 @@ -120,7 +120,7 @@ AngleMeasureTool::AngleHighlightArea AngleMeasureTool::AngleHitTest(ScenePoint2D p) const { const double pixelToScene = - GetScene()->GetCanvasToSceneTransform().ComputeZoom(); + GetController()->GetScene().GetCanvasToSceneTransform().ComputeZoom(); const double SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD = pixelToScene * HIT_TEST_MAX_DISTANCE_CANVAS_COORD * pixelToScene * HIT_TEST_MAX_DISTANCE_CANVAS_COORD; { @@ -165,7 +165,7 @@ boost::shared_ptr<IFlexiblePointerTracker> AngleMeasureTool::CreateEditionTracker(const PointerEvent& e) { ScenePoint2D scenePos = e.GetMainPosition().Apply( - GetScene()->GetCanvasToSceneTransform()); + GetController()->GetScene().GetCanvasToSceneTransform()); if (!HitTest(scenePos)) return boost::shared_ptr<IFlexiblePointerTracker>(); @@ -233,7 +233,7 @@ { PolylineSceneLayer::Chain chain; //TODO: take DPI into account - AddSquare(chain, GetScene(), side1End_, + AddSquare(chain, GetController()->GetScene(), side1End_, GetController()->GetHandleSideLengthS()); if (angleHighlightArea_ == AngleHighlightArea_Side1End) @@ -245,7 +245,7 @@ { PolylineSceneLayer::Chain chain; //TODO: take DPI into account - AddSquare(chain, GetScene(), side2End_, + AddSquare(chain, GetController()->GetScene(), side2End_, GetController()->GetHandleSideLengthS()); if (angleHighlightArea_ == AngleHighlightArea_Side2End) @@ -294,7 +294,7 @@ sprintf(buf, "%0.02f\xc2\xb0", angleDeg); SetTextLayerOutlineProperties( - GetScene(), layerHolder_, buf, ScenePoint2D(pointX, pointY)); + GetController()->GetScene(), layerHolder_, buf, ScenePoint2D(pointX, pointY)); #if 0 // TODO:make it togglable
--- a/Framework/Scene2DViewport/CreateAngleMeasureTracker.cpp Wed Jul 10 15:23:13 2019 +0200 +++ b/Framework/Scene2DViewport/CreateAngleMeasureTracker.cpp Wed Jul 10 18:18:42 2019 +0200 @@ -34,7 +34,7 @@ new CreateAngleMeasureCommand( broker, controllerW, - e.GetMainPosition().Apply(GetScene()->GetCanvasToSceneTransform()))); + e.GetMainPosition().Apply(GetScene().GetCanvasToSceneTransform()))); } CreateAngleMeasureTracker::~CreateAngleMeasureTracker() @@ -43,8 +43,6 @@ void CreateAngleMeasureTracker::PointerMove(const PointerEvent& event) { - assert(GetScene()); - if (!alive_) { throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, @@ -53,7 +51,7 @@ } ScenePoint2D scenePos = event.GetMainPosition().Apply( - GetScene()->GetCanvasToSceneTransform()); + GetScene().GetCanvasToSceneTransform()); switch (state_) {
--- a/Framework/Scene2DViewport/CreateLineMeasureTracker.cpp Wed Jul 10 15:23:13 2019 +0200 +++ b/Framework/Scene2DViewport/CreateLineMeasureTracker.cpp Wed Jul 10 18:18:42 2019 +0200 @@ -33,7 +33,7 @@ new CreateLineMeasureCommand( broker, controllerW, - e.GetMainPosition().Apply(GetScene()->GetCanvasToSceneTransform()))); + e.GetMainPosition().Apply(GetScene().GetCanvasToSceneTransform()))); } CreateLineMeasureTracker::~CreateLineMeasureTracker() @@ -43,8 +43,6 @@ void CreateLineMeasureTracker::PointerMove(const PointerEvent& event) { - assert(GetScene()); - if (!alive_) { throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, @@ -53,7 +51,7 @@ } ScenePoint2D scenePos = event.GetMainPosition().Apply( - GetScene()->GetCanvasToSceneTransform()); + GetScene().GetCanvasToSceneTransform()); //LOG(TRACE) << "scenePos.GetX() = " << scenePos.GetX() << " " << // "scenePos.GetY() = " << scenePos.GetY();
--- a/Framework/Scene2DViewport/EditAngleMeasureTracker.cpp Wed Jul 10 15:23:13 2019 +0200 +++ b/Framework/Scene2DViewport/EditAngleMeasureTracker.cpp Wed Jul 10 18:18:42 2019 +0200 @@ -30,7 +30,7 @@ : EditMeasureTracker(controllerW, e) { ScenePoint2D scenePos = e.GetMainPosition().Apply( - GetScene()->GetCanvasToSceneTransform()); + GetScene().GetCanvasToSceneTransform()); modifiedZone_ = measureTool->AngleHitTest(scenePos); @@ -45,7 +45,7 @@ void EditAngleMeasureTracker::PointerMove(const PointerEvent& e) { ScenePoint2D scenePos = e.GetMainPosition().Apply( - GetScene()->GetCanvasToSceneTransform()); + GetScene().GetCanvasToSceneTransform()); ScenePoint2D delta = scenePos - GetOriginalClickPosition();
--- a/Framework/Scene2DViewport/EditLineMeasureTracker.cpp Wed Jul 10 15:23:13 2019 +0200 +++ b/Framework/Scene2DViewport/EditLineMeasureTracker.cpp Wed Jul 10 18:18:42 2019 +0200 @@ -21,16 +21,16 @@ #include "EditLineMeasureTracker.h" namespace OrthancStone -{ +{ EditLineMeasureTracker::EditLineMeasureTracker( boost::shared_ptr<LineMeasureTool> measureTool, MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW, - const PointerEvent& e) + const PointerEvent& e) : EditMeasureTracker(controllerW, e) - { + { ScenePoint2D scenePos = e.GetMainPosition().Apply( - GetScene()->GetCanvasToSceneTransform()); + GetScene().GetCanvasToSceneTransform()); modifiedZone_ = measureTool->LineHitTest(scenePos); @@ -39,7 +39,7 @@ measureTool, broker, controllerW)); - } + } EditLineMeasureTracker::~EditLineMeasureTracker() { @@ -49,7 +49,7 @@ void EditLineMeasureTracker::PointerMove(const PointerEvent& e) { ScenePoint2D scenePos = e.GetMainPosition().Apply( - GetScene()->GetCanvasToSceneTransform()); + GetScene().GetCanvasToSceneTransform()); ScenePoint2D delta = scenePos - GetOriginalClickPosition(); @@ -104,4 +104,4 @@ return ret; } -} \ No newline at end of file +}
--- a/Framework/Scene2DViewport/LayerHolder.cpp Wed Jul 10 15:23:13 2019 +0200 +++ b/Framework/Scene2DViewport/LayerHolder.cpp Wed Jul 10 18:18:42 2019 +0200 @@ -43,18 +43,18 @@ { assert(baseLayerIndex_ == -1); - baseLayerIndex_ = GetScene()->GetMaxDepth() + 100; + baseLayerIndex_ = GetScene().GetMaxDepth() + 100; for (int i = 0; i < polylineLayerCount_; ++i) { std::auto_ptr<PolylineSceneLayer> layer(new PolylineSceneLayer()); - GetScene()->SetLayer(baseLayerIndex_ + i, layer.release()); + GetScene().SetLayer(baseLayerIndex_ + i, layer.release()); } for (int i = 0; i < textLayerCount_; ++i) { std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer()); - GetScene()->SetLayer( + GetScene().SetLayer( baseLayerIndex_ + polylineLayerCount_ + i, layer.release()); } @@ -72,7 +72,7 @@ return (baseLayerIndex_ != -1); } - boost::shared_ptr<Scene2D> LayerHolder::GetScene() + Scene2D& LayerHolder::GetScene() { boost::shared_ptr<ViewportController> controller = controllerW_.lock(); ORTHANC_ASSERT(controller.get() != 0, "Zombie attack!"); @@ -83,8 +83,8 @@ { for (int i = 0; i < textLayerCount_ + polylineLayerCount_; ++i) { - ORTHANC_ASSERT(GetScene()->HasLayer(baseLayerIndex_ + i), "No layer"); - GetScene()->DeleteLayer(baseLayerIndex_ + i); + ORTHANC_ASSERT(GetScene().HasLayer(baseLayerIndex_ + i), "No layer"); + GetScene().DeleteLayer(baseLayerIndex_ + i); } baseLayerIndex_ = -1; } @@ -93,9 +93,9 @@ { using namespace Orthanc; ORTHANC_ASSERT(baseLayerIndex_ != -1); - ORTHANC_ASSERT(GetScene()->HasLayer(GetPolylineLayerIndex(index))); + ORTHANC_ASSERT(GetScene().HasLayer(GetPolylineLayerIndex(index))); ISceneLayer* layer = - &(GetScene()->GetLayer(GetPolylineLayerIndex(index))); + &(GetScene().GetLayer(GetPolylineLayerIndex(index))); PolylineSceneLayer* concreteLayer = dynamic_cast<PolylineSceneLayer*>(layer); @@ -108,9 +108,9 @@ { using namespace Orthanc; ORTHANC_ASSERT(baseLayerIndex_ != -1); - ORTHANC_ASSERT(GetScene()->HasLayer(GetTextLayerIndex(index))); + ORTHANC_ASSERT(GetScene().HasLayer(GetTextLayerIndex(index))); ISceneLayer* layer = - &(GetScene()->GetLayer(GetTextLayerIndex(index))); + &(GetScene().GetLayer(GetTextLayerIndex(index))); TextSceneLayer* concreteLayer = dynamic_cast<TextSceneLayer*>(layer);
--- a/Framework/Scene2DViewport/LayerHolder.h Wed Jul 10 15:23:13 2019 +0200 +++ b/Framework/Scene2DViewport/LayerHolder.h Wed Jul 10 18:18:42 2019 +0200 @@ -89,7 +89,7 @@ private: int GetPolylineLayerIndex(int index = 0); int GetTextLayerIndex(int index = 0); - boost::shared_ptr<Scene2D> GetScene(); + Scene2D& GetScene(); int textLayerCount_; int polylineLayerCount_;
--- a/Framework/Scene2DViewport/LineMeasureTool.cpp Wed Jul 10 15:23:13 2019 +0200 +++ b/Framework/Scene2DViewport/LineMeasureTool.cpp Wed Jul 10 18:18:42 2019 +0200 @@ -97,7 +97,7 @@ LineMeasureTool::LineHighlightArea LineMeasureTool::LineHitTest(ScenePoint2D p) const { const double pixelToScene = - GetScene()->GetCanvasToSceneTransform().ComputeZoom(); + GetController()->GetScene().GetCanvasToSceneTransform().ComputeZoom(); const double SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD = pixelToScene * HIT_TEST_MAX_DISTANCE_CANVAS_COORD * pixelToScene * HIT_TEST_MAX_DISTANCE_CANVAS_COORD; const double sqDistanceFromStart = ScenePoint2D::SquaredDistancePtPt(p, start_); @@ -123,7 +123,7 @@ boost::shared_ptr<IFlexiblePointerTracker> LineMeasureTool::CreateEditionTracker(const PointerEvent& e) { ScenePoint2D scenePos = e.GetMainPosition().Apply( - GetScene()->GetCanvasToSceneTransform()); + GetController()->GetScene().GetCanvasToSceneTransform()); if (!HitTest(scenePos)) return boost::shared_ptr<IFlexiblePointerTracker>(); @@ -196,7 +196,7 @@ PolylineSceneLayer::Chain chain; //TODO: take DPI into account - AddSquare(chain, GetScene(), start_, + AddSquare(chain, GetController()->GetScene(), start_, GetController()->GetHandleSideLengthS()); if (lineHighlightArea_ == LineHighlightArea_Start) @@ -209,7 +209,7 @@ PolylineSceneLayer::Chain chain; //TODO: take DPI into account - AddSquare(chain, GetScene(), end_, + AddSquare(chain, GetController()->GetScene(), end_, GetController()->GetHandleSideLengthS()); if (lineHighlightArea_ == LineHighlightArea_End) @@ -235,7 +235,7 @@ double midY = 0.5 * (end_.GetY() + start_.GetY()); SetTextLayerOutlineProperties( - GetScene(), layerHolder_, buf, ScenePoint2D(midX, midY)); + GetController()->GetScene(), layerHolder_, buf, ScenePoint2D(midX, midY)); } } else
--- a/Framework/Scene2DViewport/MeasureTool.cpp Wed Jul 10 15:23:13 2019 +0200 +++ b/Framework/Scene2DViewport/MeasureTool.cpp Wed Jul 10 18:18:42 2019 +0200 @@ -76,16 +76,6 @@ #endif } - boost::shared_ptr<Scene2D> MeasureTool::GetScene() - { - return GetController()->GetScene(); - } - - boost::shared_ptr<const Scene2D> MeasureTool::GetScene() const - { - return GetController()->GetScene(); - } - MeasureTool::MeasureTool(MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW) : IObserver(broker)
--- a/Framework/Scene2DViewport/MeasureTool.h Wed Jul 10 15:23:13 2019 +0200 +++ b/Framework/Scene2DViewport/MeasureTool.h Wed Jul 10 18:18:42 2019 +0200 @@ -125,9 +125,6 @@ boost::shared_ptr<const ViewportController> GetController() const; boost::shared_ptr<ViewportController> GetController(); - boost::shared_ptr<const Scene2D> GetScene() const; - boost::shared_ptr<Scene2D> GetScene(); - /** enabled_ is not accessible by subclasses because there is a state machine that we do not wanna mess with
--- a/Framework/Scene2DViewport/MeasureToolsToolbox.h Wed Jul 10 15:23:13 2019 +0200 +++ b/Framework/Scene2DViewport/MeasureToolsToolbox.h Wed Jul 10 18:18:42 2019 +0200 @@ -31,9 +31,9 @@ square sides are parallel to the canvas boundaries. */ void AddSquare(PolylineSceneLayer::Chain& chain, - boost::shared_ptr<const Scene2D> scene, - const ScenePoint2D& centerS, - const double& sideLengthS); + const Scene2D& scene, + const ScenePoint2D& centerS, + const double& sideLengthS); /** Creates an arc centered on c that goes @@ -180,10 +180,11 @@ from layerIndex, up to (and not including) layerIndex+5. */ void SetTextLayerOutlineProperties( - boost::shared_ptr<Scene2D> scene, boost::shared_ptr<LayerHolder> layerHolder, - const char* text, ScenePoint2D p); + Scene2D& scene, + boost::shared_ptr<LayerHolder> layerHolder, + const char* text, + ScenePoint2D p); - - std::ostream& operator<<(std::ostream& os, const ScenePoint2D& p); + std::ostream& operator<<(std::ostream& os, const ScenePoint2D& p); }
--- a/Framework/Scene2DViewport/MeasureTrackers.cpp Wed Jul 10 15:23:13 2019 +0200 +++ b/Framework/Scene2DViewport/MeasureTrackers.cpp Wed Jul 10 18:18:42 2019 +0200 @@ -53,7 +53,7 @@ command_->Undo(); } - boost::shared_ptr<Scene2D> CreateMeasureTracker::GetScene() + Scene2D& CreateMeasureTracker::GetScene() { return controllerW_.lock()->GetScene(); } @@ -64,10 +64,10 @@ , commitResult_(true) { boost::shared_ptr<ViewportController> controller = controllerW.lock(); - originalClickPosition_ = e.GetMainPosition().Apply(controller->GetScene()->GetCanvasToSceneTransform()); + originalClickPosition_ = e.GetMainPosition().Apply(controller->GetScene().GetCanvasToSceneTransform()); } - boost::shared_ptr<Scene2D> EditMeasureTracker::GetScene() + Scene2D& EditMeasureTracker::GetScene() { return controllerW_.lock()->GetScene(); }
--- a/Framework/Scene2DViewport/MeasureTrackers.h Wed Jul 10 15:23:13 2019 +0200 +++ b/Framework/Scene2DViewport/MeasureTrackers.h Wed Jul 10 18:18:42 2019 +0200 @@ -45,7 +45,7 @@ boost::shared_ptr<CreateMeasureCommand> command_; boost::weak_ptr<ViewportController> controllerW_; bool alive_; - boost::shared_ptr<Scene2D> GetScene(); + Scene2D& GetScene(); private: bool commitResult_; @@ -65,8 +65,8 @@ boost::shared_ptr<EditMeasureCommand> command_; boost::weak_ptr<ViewportController> controllerW_; bool alive_; - boost::shared_ptr<Scene2D> GetScene(); - + Scene2D& GetScene(); + ScenePoint2D GetOriginalClickPosition() const { return originalClickPosition_;
--- a/Framework/Scene2DViewport/ViewportController.cpp Wed Jul 10 15:23:13 2019 +0200 +++ b/Framework/Scene2DViewport/ViewportController.cpp Wed Jul 10 18:18:42 2019 +0200 @@ -29,12 +29,15 @@ namespace OrthancStone { - ViewportController::ViewportController(boost::weak_ptr<UndoStack> undoStackW, MessageBroker& broker) + ViewportController::ViewportController(boost::weak_ptr<UndoStack> undoStackW, + MessageBroker& broker, + IViewport& viewport) : IObservable(broker) , undoStackW_(undoStackW) , canvasToSceneFactor_(0.0) + , viewport_(viewport) + , scene_(viewport.GetScene()) { - scene_ = boost::make_shared<Scene2D>(); } boost::shared_ptr<UndoStack> ViewportController::GetUndoStack() @@ -72,16 +75,6 @@ return GetUndoStack()->CanRedo(); } - boost::shared_ptr<const Scene2D> ViewportController::GetScene() const - { - return scene_; - } - - boost::shared_ptr<Scene2D> ViewportController::GetScene() - { - return scene_; - } - bool ViewportController::HandlePointerEvent(PointerEvent e) { throw StoneException(ErrorCode_NotImplemented); @@ -111,18 +104,18 @@ const OrthancStone::AffineTransform2D& ViewportController::GetCanvasToSceneTransform() const { - return scene_->GetCanvasToSceneTransform(); + return GetScene().GetCanvasToSceneTransform(); } const OrthancStone::AffineTransform2D& ViewportController::GetSceneToCanvasTransform() const { - return scene_->GetSceneToCanvasTransform(); + return GetScene().GetSceneToCanvasTransform(); } void ViewportController::SetSceneToCanvasTransform( const AffineTransform2D& transform) { - scene_->SetSceneToCanvasTransform(transform); + viewport_.GetScene().SetSceneToCanvasTransform(transform); BroadcastMessage(SceneTransformChanged(*this)); // update the canvas to scene factor @@ -133,7 +126,7 @@ void ViewportController::FitContent( unsigned int canvasWidth, unsigned int canvasHeight) { - scene_->FitContent(canvasWidth, canvasHeight); + viewport_.GetScene().FitContent(canvasWidth, canvasHeight); BroadcastMessage(SceneTransformChanged(*this)); } @@ -159,7 +152,7 @@ if (canvasToSceneFactor_ == 0) { canvasToSceneFactor_ = - GetScene()->GetCanvasToSceneTransform().ComputeZoom(); + GetScene().GetCanvasToSceneTransform().ComputeZoom(); } return canvasToSceneFactor_; }
--- a/Framework/Scene2DViewport/ViewportController.h Wed Jul 10 15:23:13 2019 +0200 +++ b/Framework/Scene2DViewport/ViewportController.h Wed Jul 10 18:18:42 2019 +0200 @@ -22,7 +22,7 @@ #include "PredeclaredTypes.h" -#include "../Scene2D/Scene2D.h" +#include "../Viewport/IViewport.h" #include "../Scene2D/PointerEvent.h" #include "../Scene2DViewport/IFlexiblePointerTracker.h" @@ -80,10 +80,9 @@ ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, \ SceneTransformChanged, ViewportController); - ViewportController(boost::weak_ptr<UndoStack> undoStackW, MessageBroker& broker); - - boost::shared_ptr<const Scene2D> GetScene() const; - boost::shared_ptr<Scene2D> GetScene(); + ViewportController(boost::weak_ptr<UndoStack> undoStackW, + MessageBroker& broker, + IViewport& viewport); /** This method is called by the GUI system and should update/delete the @@ -170,6 +169,20 @@ /** forwarded to the UndoStack */ bool CanRedo() const; + IViewport& GetViewport() + { + return viewport_; + } + + Scene2D& GetScene() + { + return viewport_.GetScene(); + } + + const Scene2D& GetScene() const + { + return scene_; + } private: double GetCanvasToSceneFactor() const; @@ -180,10 +193,14 @@ boost::shared_ptr<const UndoStack> GetUndoStack() const; std::vector<boost::shared_ptr<MeasureTool> > measureTools_; - boost::shared_ptr<Scene2D> scene_; boost::shared_ptr<IFlexiblePointerTracker> tracker_; // this is cached mutable double canvasToSceneFactor_; + + + // Refactoring on 2019-07-10: Removing shared_ptr from scene + IViewport& viewport_; + const Scene2D& scene_; // As long as the viewport exists, its associated scene too }; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Viewport/IViewport.h Wed Jul 10 18:18:42 2019 +0200 @@ -0,0 +1,52 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + +#pragma once + +#include "../Scene2D/Scene2D.h" +#include "../Scene2D/ScenePoint2D.h" + +namespace OrthancStone +{ + /** + * Class that combines a Scene2D with a canvas where to draw the + * scene. A call to "Refresh()" will update the content of the + * canvas. + **/ + class IViewport : public boost::noncopyable + { + public: + virtual ~IViewport() + { + } + + virtual Scene2D& GetScene() = 0; + + virtual void Refresh() = 0; + + virtual unsigned int GetCanvasWidth() const = 0; + + virtual unsigned int GetCanvasHeight() const = 0; + + virtual const std::string& GetCanvasIdentifier() const = 0; + + virtual ScenePoint2D GetPixelCenterCoordinates(int x, int y) const = 0; + }; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Viewport/SdlViewport.cpp Wed Jul 10 18:18:42 2019 +0200 @@ -0,0 +1,47 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + +#include "SdlViewport.h" + +#include <Core/OrthancException.h> + +#include <boost/make_shared.hpp> + +namespace OrthancStone +{ + SdlViewport::SdlViewport(const char* title, + unsigned int width, + unsigned int height) : + ViewportBase(title), + context_(title, width, height), + compositor_(context_, GetScene()) + { + } + + SdlViewport::SdlViewport(const char* title, + unsigned int width, + unsigned int height, + boost::shared_ptr<Scene2D>& scene) : + ViewportBase(title, scene), + context_(title, width, height), + compositor_(context_, GetScene()) + { + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Viewport/SdlViewport.h Wed Jul 10 18:18:42 2019 +0200 @@ -0,0 +1,86 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + +#pragma once + +#if !defined(ORTHANC_ENABLE_SDL) +# error Macro ORTHANC_ENABLE_SDL must be defined +#endif + +#if ORTHANC_ENABLE_SDL != 1 +# error SDL must be enabled to use this file +#endif + +#if !defined(ORTHANC_ENABLE_OPENGL) +# error The macro ORTHANC_ENABLE_OPENGL must be defined +#endif + +#if ORTHANC_ENABLE_OPENGL != 1 +# error Support for OpenGL is disabled +#endif + +#include "../../Applications/Sdl/SdlOpenGLContext.h" +#include "../Scene2D/OpenGLCompositor.h" +#include "ViewportBase.h" + +namespace OrthancStone +{ + class SdlViewport : public ViewportBase + { + private: + SdlOpenGLContext context_; + OpenGLCompositor compositor_; + + public: + SdlViewport(const char* title, + unsigned int width, + unsigned int height); + + SdlViewport(const char* title, + unsigned int width, + unsigned int height, + boost::shared_ptr<Scene2D>& scene); + + virtual void Refresh() + { + compositor_.Refresh(); + } + + virtual unsigned int GetCanvasWidth() const + { + return compositor_.GetCanvasWidth(); + } + + virtual unsigned int GetCanvasHeight() const + { + return compositor_.GetCanvasHeight(); + } + + OpenGLCompositor& GetCompositor() + { + return compositor_; + } + + SdlOpenGLContext& GetContext() + { + return context_; + } + }; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Viewport/ViewportBase.cpp Wed Jul 10 18:18:42 2019 +0200 @@ -0,0 +1,54 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + +#include "ViewportBase.h" + +#include <Core/OrthancException.h> + +#include <boost/make_shared.hpp> + +namespace OrthancStone +{ + ViewportBase::ViewportBase(const std::string& identifier) : + identifier_(identifier), + scene_(boost::make_shared<Scene2D>()) + { + } + + + ViewportBase::ViewportBase(const std::string& identifier, + boost::shared_ptr<Scene2D>& scene) : + identifier_(identifier), + scene_(scene) + { + if (scene.get() == NULL) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); + } + } + + + ScenePoint2D ViewportBase::GetPixelCenterCoordinates(int x, int y) const + { + return ScenePoint2D( + static_cast<double>(x) + 0.5 - static_cast<double>(GetCanvasWidth()) / 2.0, + static_cast<double>(y) + 0.5 - static_cast<double>(GetCanvasHeight()) / 2.0); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Viewport/ViewportBase.h Wed Jul 10 18:18:42 2019 +0200 @@ -0,0 +1,53 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + +#pragma once + +#include "IViewport.h" + +#include <boost/shared_ptr.hpp> + +namespace OrthancStone +{ + class ViewportBase : public IViewport + { + private: + std::string identifier_; + boost::shared_ptr<Scene2D> scene_; + + public: + ViewportBase(const std::string& identifier); + + ViewportBase(const std::string& identifier, + boost::shared_ptr<Scene2D>& scene); + + virtual Scene2D& GetScene() + { + return *scene_; + } + + virtual const std::string& GetCanvasIdentifier() const + { + return identifier_; + } + + virtual ScenePoint2D GetPixelCenterCoordinates(int x, int y) const; + }; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Viewport/WebAssemblyViewport.cpp Wed Jul 10 18:18:42 2019 +0200 @@ -0,0 +1,48 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#include "WebAssemblyViewport.h" + +namespace OrthancStone +{ + WebAssemblyViewport::WebAssemblyViewport(const std::string& canvas) : + ViewportBase(canvas), + context_(canvas), + compositor_(context_, GetScene()) + { + } + + + WebAssemblyViewport::WebAssemblyViewport(const std::string& canvas, + boost::shared_ptr<Scene2D>& scene) : + ViewportBase(canvas, scene), + context_(canvas), + compositor_(context_, GetScene()) + { + } + + + void WebAssemblyViewport::UpdateSize() + { + context_.UpdateSize(); // First read the size of the canvas + compositor_.Refresh(); // Then refresh the content of the canvas + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Viewport/WebAssemblyViewport.h Wed Jul 10 18:18:42 2019 +0200 @@ -0,0 +1,65 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include "../OpenGL/WebAssemblyOpenGLContext.h" +#include "../Scene2D/OpenGLCompositor.h" +#include "ViewportBase.h" + +namespace OrthancStone +{ + class WebAssemblyViewport : public ViewportBase + { + private: + OpenGL::WebAssemblyOpenGLContext context_; + OpenGLCompositor compositor_; + + public: + WebAssemblyViewport(const std::string& canvas); + + WebAssemblyViewport(const std::string& canvas, + boost::shared_ptr<Scene2D>& scene); + + virtual void Refresh() + { + compositor_.Refresh(); + } + + virtual unsigned int GetCanvasWidth() const + { + return context_.GetCanvasWidth(); + } + + virtual unsigned int GetCanvasHeight() const + { + return context_.GetCanvasHeight(); + } + + // This function must be called each time the browser window is resized + void UpdateSize(); + + OpenGLCompositor& GetCompositor() + { + return compositor_; + } + }; +}
--- a/Resources/CMake/OrthancStoneConfiguration.cmake Wed Jul 10 15:23:13 2019 +0200 +++ b/Resources/CMake/OrthancStoneConfiguration.cmake Wed Jul 10 18:18:42 2019 +0200 @@ -276,11 +276,17 @@ list(APPEND APPLICATIONS_SOURCES ${ORTHANC_STONE_ROOT}/Applications/Sdl/SdlCairoSurface.cpp ${ORTHANC_STONE_ROOT}/Applications/Sdl/SdlEngine.cpp - ${ORTHANC_STONE_ROOT}/Applications/Sdl/SdlOpenGLWindow.cpp ${ORTHANC_STONE_ROOT}/Applications/Sdl/SdlOrthancSurface.cpp ${ORTHANC_STONE_ROOT}/Applications/Sdl/SdlStoneApplicationRunner.cpp ${ORTHANC_STONE_ROOT}/Applications/Sdl/SdlWindow.cpp ) + + if (ENABLE_OPENGL) + list(APPEND APPLICATIONS_SOURCES + ${ORTHANC_STONE_ROOT}/Applications/Sdl/SdlOpenGLContext.cpp + ${ORTHANC_STONE_ROOT}/Framework/Viewport/SdlViewport.cpp + ) + endif() endif() endif() elseif (ENABLE_WASM) @@ -518,6 +524,7 @@ ${ORTHANC_STONE_ROOT}/Framework/Toolbox/ShearWarpProjectiveTransform.cpp ${ORTHANC_STONE_ROOT}/Framework/Toolbox/SlicesSorter.cpp ${ORTHANC_STONE_ROOT}/Framework/Toolbox/UndoRedoStack.cpp + ${ORTHANC_STONE_ROOT}/Framework/Viewport/ViewportBase.cpp ${ORTHANC_STONE_ROOT}/Framework/Volumes/DicomVolumeImage.cpp ${ORTHANC_STONE_ROOT}/Framework/Volumes/DicomVolumeImageMPRSlicer.cpp ${ORTHANC_STONE_ROOT}/Framework/Volumes/DicomVolumeImageReslicer.cpp @@ -590,6 +597,7 @@ if (ENABLE_WASM) list(APPEND ORTHANC_STONE_SOURCES ${ORTHANC_STONE_ROOT}/Framework/OpenGL/WebAssemblyOpenGLContext.cpp + ${ORTHANC_STONE_ROOT}/Framework/Viewport/WebAssemblyViewport.cpp ) endif() endif()
--- a/Samples/Sdl/BasicScene.cpp Wed Jul 10 15:23:13 2019 +0200 +++ b/Samples/Sdl/BasicScene.cpp Wed Jul 10 18:18:42 2019 +0200 @@ -20,13 +20,12 @@ // From Stone -#include "../../Applications/Sdl/SdlOpenGLWindow.h" +#include "../../Framework/Viewport/SdlViewport.h" #include "../../Framework/Scene2D/CairoCompositor.h" #include "../../Framework/Scene2D/ColorTextureSceneLayer.h" #include "../../Framework/Scene2D/OpenGLCompositor.h" #include "../../Framework/Scene2D/PanSceneTracker.h" #include "../../Framework/Scene2D/RotateSceneTracker.h" -#include "../../Framework/Scene2D/Scene2D.h" #include "../../Framework/Scene2D/ZoomSceneTracker.h" #include "../../Framework/Scene2DViewport/ViewportController.h" #include "../../Framework/Scene2DViewport/UndoStack.h" @@ -42,7 +41,6 @@ #include <Core/Images/PngWriter.h> #include <boost/make_shared.hpp> -#include <boost/ref.hpp> #include <SDL.h> #include <stdio.h> @@ -50,10 +48,11 @@ static const unsigned int FONT_SIZE = 32; static const int LAYER_POSITION = 150; -void PrepareScene(boost::shared_ptr<OrthancStone::ViewportController> controller) + +void PrepareScene(OrthancStone::Scene2D& scene) { using namespace OrthancStone; - Scene2D& scene(*controller->GetScene()); + // Texture of 2x2 size { Orthanc::Image i(Orthanc::PixelFormat_RGB24, 2, 2, false); @@ -162,13 +161,15 @@ } -void HandleApplicationEvent(boost::shared_ptr<OrthancStone::ViewportController> controller, - const OrthancStone::OpenGLCompositor& compositor, - const SDL_Event& event, +void HandleApplicationEvent(const SDL_Event& event, + boost::shared_ptr<OrthancStone::ViewportController>& controller, boost::shared_ptr<OrthancStone::IFlexiblePointerTracker>& activeTracker) { using namespace OrthancStone; - Scene2D& scene(*controller->GetScene()); + + Scene2D& scene = controller->GetScene(); + IViewport& viewport = controller->GetViewport(); + if (event.type == SDL_MOUSEMOTION) { int scancodeCount = 0; @@ -181,7 +182,7 @@ // The "left-ctrl" key is down, while no tracker is present PointerEvent e; - e.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y)); + e.AddPosition(viewport.GetPixelCenterCoordinates(event.button.x, event.button.y)); ScenePoint2D p = e.GetMainPosition().Apply(scene.GetCanvasToSceneTransform()); @@ -215,7 +216,7 @@ else if (event.type == SDL_MOUSEBUTTONDOWN) { PointerEvent e; - e.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y)); + e.AddPosition(viewport.GetPixelCenterCoordinates(event.button.x, event.button.y)); switch (event.button.button) { @@ -224,8 +225,8 @@ break; case SDL_BUTTON_RIGHT: - activeTracker = boost::make_shared<ZoomSceneTracker>(controller, - e, compositor.GetCanvasHeight()); + activeTracker = boost::make_shared<ZoomSceneTracker> + (controller, e, viewport.GetCanvasHeight()); break; case SDL_BUTTON_LEFT: @@ -242,14 +243,14 @@ switch (event.key.keysym.sym) { case SDLK_s: - controller->FitContent(compositor.GetCanvasWidth(), - compositor.GetCanvasHeight()); + controller->FitContent(viewport.GetCanvasWidth(), + viewport.GetCanvasHeight()); break; case SDLK_c: TakeScreenshot("screenshot.png", scene, - compositor.GetCanvasWidth(), - compositor.GetCanvasHeight()); + viewport.GetCanvasWidth(), + viewport.GetCanvasHeight()); break; default: @@ -277,26 +278,24 @@ } -void Run(boost::shared_ptr<OrthancStone::ViewportController> controller) +void Run(OrthancStone::MessageBroker& broker, + OrthancStone::SdlViewport& viewport) { using namespace OrthancStone; - SdlOpenGLWindow window("Hello", 1024, 768); - - controller->FitContent(window.GetCanvasWidth(), window.GetCanvasHeight()); + + boost::shared_ptr<ViewportController> controller( + new ViewportController(boost::make_shared<UndoStack>(), broker, viewport)); glEnable(GL_DEBUG_OUTPUT); glDebugMessageCallback(OpenGLMessageCallback, 0); - OpenGLCompositor compositor(window, *controller->GetScene()); - compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, - FONT_SIZE, Orthanc::Encoding_Latin1); - boost::shared_ptr<IFlexiblePointerTracker> tracker; + bool firstShown = true; bool stop = false; while (!stop) { - compositor.Refresh(); + viewport.Refresh(); SDL_Event event; while (!stop && @@ -312,7 +311,7 @@ if (tracker) { PointerEvent e; - e.AddPosition(compositor.GetPixelCenterCoordinates( + e.AddPosition(viewport.GetPixelCenterCoordinates( event.button.x, event.button.y)); tracker->PointerMove(e); } @@ -322,17 +321,34 @@ if (tracker) { PointerEvent e; - e.AddPosition(compositor.GetPixelCenterCoordinates( + e.AddPosition(viewport.GetPixelCenterCoordinates( event.button.x, event.button.y)); tracker->PointerUp(e); if(!tracker->IsAlive()) tracker.reset(); } } - else if (event.type == SDL_WINDOWEVENT && - event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) + else if (event.type == SDL_WINDOWEVENT) { - tracker.reset(); + switch (event.window.event) + { + case SDL_WINDOWEVENT_SIZE_CHANGED: + tracker.reset(); + break; + + case SDL_WINDOWEVENT_SHOWN: + if (firstShown) + { + // Once the window is first shown, fit the content to its size + controller->FitContent(viewport.GetCanvasWidth(), viewport.GetCanvasHeight()); + firstShown = false; + } + + break; + + default: + break; + } } else if (event.type == SDL_KEYDOWN && event.key.repeat == 0 /* Ignore key bounce */) @@ -340,7 +356,7 @@ switch (event.key.keysym.sym) { case SDLK_f: - window.GetWindow().ToggleMaximize(); + viewport.GetContext().GetWindow().ToggleMaximize(); break; case SDLK_q: @@ -352,7 +368,7 @@ } } - HandleApplicationEvent(controller, compositor, event, tracker); + HandleApplicationEvent(event, controller, tracker); } SDL_Delay(1); @@ -369,25 +385,26 @@ **/ int main(int argc, char* argv[]) { - using namespace OrthancStone; - StoneInitialize(); + OrthancStone::StoneInitialize(); Orthanc::Logging::EnableInfoLevel(true); try { - MessageBroker broker; - boost::shared_ptr<UndoStack> undoStack(new UndoStack); - boost::shared_ptr<ViewportController> controller = boost::make_shared<ViewportController>( - undoStack, boost::ref(broker)); - PrepareScene(controller); - Run(controller); + OrthancStone::SdlViewport viewport("Hello", 1024, 768); + PrepareScene(viewport.GetScene()); + + viewport.GetCompositor().SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, + FONT_SIZE, Orthanc::Encoding_Latin1); + + OrthancStone::MessageBroker broker; + Run(broker, viewport); } catch (Orthanc::OrthancException& e) { LOG(ERROR) << "EXCEPTION: " << e.What(); } - StoneFinalize(); + OrthancStone::StoneFinalize(); return 0; }
--- a/Samples/Sdl/FusionMprSdl.cpp Wed Jul 10 15:23:13 2019 +0200 +++ b/Samples/Sdl/FusionMprSdl.cpp Wed Jul 10 18:18:42 2019 +0200 @@ -20,7 +20,7 @@ #include "FusionMprSdl.h" -#include "../../Applications/Sdl/SdlOpenGLWindow.h" +#include "../../Applications/Sdl/SdlOpenGLContext.h" #include "../../Framework/StoneInitialization.h" @@ -587,7 +587,7 @@ { // False means we do NOT let Windows treat this as a legacy application // that needs to be scaled - SdlOpenGLWindow window("Hello", 1024, 1024, false); + SdlOpenGLContext window("Hello", 1024, 1024, false); controller_->FitContent(window.GetCanvasWidth(), window.GetCanvasHeight());
--- a/Samples/Sdl/TrackerSample.cpp Wed Jul 10 15:23:13 2019 +0200 +++ b/Samples/Sdl/TrackerSample.cpp Wed Jul 10 18:18:42 2019 +0200 @@ -21,7 +21,7 @@ #include "TrackerSampleApp.h" // From Stone -#include "../../Applications/Sdl/SdlOpenGLWindow.h" +#include "../../Applications/Sdl/SdlOpenGLContext.h" #include "../../Framework/Scene2D/CairoCompositor.h" #include "../../Framework/Scene2D/ColorTextureSceneLayer.h" #include "../../Framework/Scene2D/OpenGLCompositor.h"
--- a/Samples/Sdl/TrackerSampleApp.cpp Wed Jul 10 15:23:13 2019 +0200 +++ b/Samples/Sdl/TrackerSampleApp.cpp Wed Jul 10 18:18:42 2019 +0200 @@ -20,7 +20,7 @@ #include "TrackerSampleApp.h" -#include "../../Applications/Sdl/SdlOpenGLWindow.h" +#include "../../Applications/Sdl/SdlOpenGLContext.h" #include "../../Framework/Scene2D/CairoCompositor.h" #include "../../Framework/Scene2D/ColorTextureSceneLayer.h" @@ -68,16 +68,6 @@ return descs[i]; } - boost::shared_ptr<Scene2D> TrackerSampleApp::GetScene() - { - return controller_->GetScene(); - } - - boost::shared_ptr<const Scene2D> TrackerSampleApp::GetScene() const - { - return controller_->GetScene(); - } - void TrackerSampleApp::SelectNextTool() { currentTool_ = static_cast<GuiTool>(currentTool_ + 1); @@ -102,10 +92,10 @@ std::string msgS = msg.str(); TextSceneLayer* layerP = NULL; - if (GetScene()->HasLayer(FIXED_INFOTEXT_LAYER_ZINDEX)) + if (controller_->GetScene().HasLayer(FIXED_INFOTEXT_LAYER_ZINDEX)) { TextSceneLayer& layer = dynamic_cast<TextSceneLayer&>( - GetScene()->GetLayer(FIXED_INFOTEXT_LAYER_ZINDEX)); + controller_->GetScene().GetLayer(FIXED_INFOTEXT_LAYER_ZINDEX)); layerP = &layer; } else @@ -117,29 +107,29 @@ layer->SetBorder(20); layer->SetAnchor(BitmapAnchor_TopLeft); //layer->SetPosition(0,0); - GetScene()->SetLayer(FIXED_INFOTEXT_LAYER_ZINDEX, layer.release()); + controller_->GetScene().SetLayer(FIXED_INFOTEXT_LAYER_ZINDEX, layer.release()); } // position the fixed info text in the upper right corner layerP->SetText(msgS.c_str()); double cX = compositor_->GetCanvasWidth() * (-0.5); double cY = compositor_->GetCanvasHeight() * (-0.5); - GetScene()->GetCanvasToSceneTransform().Apply(cX,cY); + controller_->GetScene().GetCanvasToSceneTransform().Apply(cX,cY); layerP->SetPosition(cX, cY); } void TrackerSampleApp::DisplayFloatingCtrlInfoText(const PointerEvent& e) { - ScenePoint2D p = e.GetMainPosition().Apply(GetScene()->GetCanvasToSceneTransform()); + ScenePoint2D p = e.GetMainPosition().Apply(controller_->GetScene().GetCanvasToSceneTransform()); char buf[128]; sprintf(buf, "S:(%0.02f,%0.02f) C:(%0.02f,%0.02f)", p.GetX(), p.GetY(), e.GetMainPosition().GetX(), e.GetMainPosition().GetY()); - if (GetScene()->HasLayer(FLOATING_INFOTEXT_LAYER_ZINDEX)) + if (controller_->GetScene().HasLayer(FLOATING_INFOTEXT_LAYER_ZINDEX)) { TextSceneLayer& layer = - dynamic_cast<TextSceneLayer&>(GetScene()->GetLayer(FLOATING_INFOTEXT_LAYER_ZINDEX)); + dynamic_cast<TextSceneLayer&>(controller_->GetScene().GetLayer(FLOATING_INFOTEXT_LAYER_ZINDEX)); layer.SetText(buf); layer.SetPosition(p.GetX(), p.GetY()); } @@ -151,13 +141,13 @@ layer->SetBorder(20); layer->SetAnchor(BitmapAnchor_BottomCenter); layer->SetPosition(p.GetX(), p.GetY()); - GetScene()->SetLayer(FLOATING_INFOTEXT_LAYER_ZINDEX, layer.release()); + controller_->GetScene().SetLayer(FLOATING_INFOTEXT_LAYER_ZINDEX, layer.release()); } } void TrackerSampleApp::HideInfoText() { - GetScene()->DeleteLayer(FLOATING_INFOTEXT_LAYER_ZINDEX); + controller_->GetScene().DeleteLayer(FLOATING_INFOTEXT_LAYER_ZINDEX); } ScenePoint2D TrackerSampleApp::GetRandomPointInScene() const @@ -179,7 +169,7 @@ ScenePoint2D p = compositor_->GetPixelCenterCoordinates(x, y); LOG(TRACE) << "--> p.GetX() = " << p.GetX() << " p.GetY() = " << p.GetY(); - ScenePoint2D r = p.Apply(GetScene()->GetCanvasToSceneTransform()); + ScenePoint2D r = p.Apply(controller_->GetScene().GetCanvasToSceneTransform()); LOG(TRACE) << "--> r.GetX() = " << r.GetX() << " r.GetY() = " << r.GetY(); return r; } @@ -276,7 +266,7 @@ e.AddPosition(compositor_->GetPixelCenterCoordinates(event.button.x, event.button.y)); ScenePoint2D scenePos = e.GetMainPosition().Apply( - controller_->GetScene()->GetCanvasToSceneTransform()); + controller_->GetScene().GetCanvasToSceneTransform()); //auto measureTools = GetController()->HitTestMeasureTools(scenePos); //LOG(TRACE) << "# of hit tests: " << measureTools.size(); @@ -527,13 +517,13 @@ p[4] = 0; p[5] = 0; - GetScene()->SetLayer(TEXTURE_2x2_1_ZINDEX, new ColorTextureSceneLayer(i)); + controller_->GetScene().SetLayer(TEXTURE_2x2_1_ZINDEX, new ColorTextureSceneLayer(i)); std::auto_ptr<ColorTextureSceneLayer> l(new ColorTextureSceneLayer(i)); l->SetOrigin(-3, 2); l->SetPixelSpacing(1.5, 1); l->SetAngle(20.0 / 180.0 * M_PI); - GetScene()->SetLayer(TEXTURE_2x2_2_ZINDEX, l.release()); + controller_->GetScene().SetLayer(TEXTURE_2x2_2_ZINDEX, l.release()); } // Texture of 1x1 size @@ -548,7 +538,7 @@ std::auto_ptr<ColorTextureSceneLayer> l(new ColorTextureSceneLayer(i)); l->SetOrigin(-2, 1); l->SetAngle(20.0 / 180.0 * M_PI); - GetScene()->SetLayer(TEXTURE_1x1_ZINDEX, l.release()); + controller_->GetScene().SetLayer(TEXTURE_1x1_ZINDEX, l.release()); } // Some lines @@ -579,14 +569,14 @@ chain.push_back(ScenePoint2D(4, 2)); layer->AddChain(chain, false, 0, 0, 255); - GetScene()->SetLayer(LINESET_1_ZINDEX, layer.release()); + controller_->GetScene().SetLayer(LINESET_1_ZINDEX, layer.release()); } // Some text { std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer); layer->SetText("Hello"); - GetScene()->SetLayer(LINESET_2_ZINDEX, layer.release()); + controller_->GetScene().SetLayer(LINESET_2_ZINDEX, layer.release()); } } @@ -623,7 +613,7 @@ { // std::vector<boost::shared_ptr<MeasureTool>> measureTools_; ScenePoint2D scenePos = e.GetMainPosition().Apply( - controller_->GetScene()->GetCanvasToSceneTransform()); + controller_->GetScene().GetCanvasToSceneTransform()); std::vector<boost::shared_ptr<MeasureTool> > measureTools = controller_->HitTestMeasureTools(scenePos); @@ -657,7 +647,7 @@ { // False means we do NOT let Windows treat this as a legacy application // that needs to be scaled - SdlOpenGLWindow window("Hello", 1024, 1024, false); + SdlOpenGLContext window("Hello", 1024, 1024, false); controller_->FitContent(window.GetCanvasWidth(), window.GetCanvasHeight());
--- a/Samples/Sdl/TrackerSampleApp.h Wed Jul 10 15:23:13 2019 +0200 +++ b/Samples/Sdl/TrackerSampleApp.h Wed Jul 10 18:18:42 2019 +0200 @@ -65,9 +65,6 @@ void SetInfoDisplayMessage(std::string key, std::string value); void DisableTracker(); - boost::shared_ptr<Scene2D> GetScene(); - boost::shared_ptr<const Scene2D> GetScene() const; - void HandleApplicationEvent(const SDL_Event& event); /**
--- a/Samples/WebAssembly/BasicScene.cpp Wed Jul 10 15:23:13 2019 +0200 +++ b/Samples/WebAssembly/BasicScene.cpp Wed Jul 10 18:18:42 2019 +0200 @@ -129,7 +129,11 @@ std::auto_ptr<OrthancStone::WebAssemblyViewport> viewport1_; std::auto_ptr<OrthancStone::WebAssemblyViewport> viewport2_; std::auto_ptr<OrthancStone::WebAssemblyViewport> viewport3_; -OrthancStone::MessageBroker broker_; +boost::shared_ptr<OrthancStone::ViewportController> controller1_; +boost::shared_ptr<OrthancStone::ViewportController> controller2_; +boost::shared_ptr<OrthancStone::ViewportController> controller3_; +OrthancStone::MessageBroker broker_; + EM_BOOL OnWindowResize( int eventType, const EmscriptenUiEvent *uiEvent, void *userData) @@ -165,21 +169,33 @@ EMSCRIPTEN_KEEPALIVE void Initialize() { - viewport1_.reset( - new OrthancStone::WebAssemblyViewport(broker_, "mycanvas1")); + viewport1_.reset(new OrthancStone::WebAssemblyViewport("mycanvas1")); PrepareScene(viewport1_->GetScene()); viewport1_->UpdateSize(); - viewport2_.reset( - new OrthancStone::WebAssemblyViewport(broker_, "mycanvas2")); + viewport2_.reset(new OrthancStone::WebAssemblyViewport("mycanvas2")); PrepareScene(viewport2_->GetScene()); viewport2_->UpdateSize(); - viewport3_.reset( - new OrthancStone::WebAssemblyViewport(broker_, "mycanvas3")); + viewport3_.reset(new OrthancStone::WebAssemblyViewport("mycanvas3")); PrepareScene(viewport3_->GetScene()); viewport3_->UpdateSize(); + viewport1_->GetCompositor().SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, + FONT_SIZE, Orthanc::Encoding_Latin1); + viewport2_->GetCompositor().SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, + FONT_SIZE, Orthanc::Encoding_Latin1); + viewport3_->GetCompositor().SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, + FONT_SIZE, Orthanc::Encoding_Latin1); + + controller1_.reset(new OrthancStone::ViewportController(boost::make_shared<OrthancStone::UndoStack>(), broker_, *viewport1_)); + controller2_.reset(new OrthancStone::ViewportController(boost::make_shared<OrthancStone::UndoStack>(), broker_, *viewport2_)); + controller3_.reset(new OrthancStone::ViewportController(boost::make_shared<OrthancStone::UndoStack>(), broker_, *viewport3_)); + + SetupEvents("mycanvas1", controller1_); + SetupEvents("mycanvas2", controller2_); + SetupEvents("mycanvas3", controller3_); + emscripten_set_resize_callback("#window", NULL, false, OnWindowResize); } }
--- a/Samples/WebAssembly/dev.h Wed Jul 10 15:23:13 2019 +0200 +++ b/Samples/WebAssembly/dev.h Wed Jul 10 18:18:42 2019 +0200 @@ -21,7 +21,7 @@ #pragma once -#include "../../Framework/OpenGL/WebAssemblyOpenGLContext.h" +#include "../../Framework/Viewport/WebAssemblyViewport.h" #include "../../Framework/Scene2D/OpenGLCompositor.h" #include "../../Framework/Scene2D/PanSceneTracker.h" #include "../../Framework/Scene2D/RotateSceneTracker.h" @@ -38,78 +38,6 @@ namespace OrthancStone { - class WebAssemblyViewport : public boost::noncopyable - { - private: - // the construction order is important because compositor_ - // will hold a reference to the scene that belong to the - // controller_ object - OpenGL::WebAssemblyOpenGLContext context_; - boost::shared_ptr<ViewportController> controller_; - OpenGLCompositor compositor_; - - void SetupEvents(const std::string& canvas); - - public: - WebAssemblyViewport(MessageBroker& broker, - const std::string& canvas) : - context_(canvas), - controller_(new ViewportController(boost::make_shared<UndoStack>(), broker)), - compositor_(context_, *controller_->GetScene()) - { - compositor_.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, - FONT_SIZE, Orthanc::Encoding_Latin1); - SetupEvents(canvas); - } - - Scene2D& GetScene() - { - return *controller_->GetScene(); - } - - const boost::shared_ptr<ViewportController>& GetController() - { - return controller_; - } - - void UpdateSize() - { - context_.UpdateSize(); - //compositor_.UpdateSize(); - Refresh(); - } - - void Refresh() - { - compositor_.Refresh(); - } - - void FitContent() - { - GetScene().FitContent(context_.GetCanvasWidth(), context_.GetCanvasHeight()); - } - - const std::string& GetCanvasIdentifier() const - { - return context_.GetCanvasIdentifier(); - } - - ScenePoint2D GetPixelCenterCoordinates(int x, int y) const - { - return compositor_.GetPixelCenterCoordinates(x, y); - } - - unsigned int GetCanvasWidth() const - { - return context_.GetCanvasWidth(); - } - - unsigned int GetCanvasHeight() const - { - return context_.GetCanvasHeight(); - } - }; - class ActiveTracker : public boost::noncopyable { private: @@ -119,9 +47,9 @@ public: ActiveTracker(const boost::shared_ptr<IFlexiblePointerTracker>& tracker, - const WebAssemblyViewport& viewport) : + const std::string& canvasId) : tracker_(tracker), - canvasIdentifier_(viewport.GetCanvasIdentifier()), + canvasIdentifier_(canvasId), insideCanvas_(true) { if (tracker_.get() == NULL) @@ -149,13 +77,13 @@ static OrthancStone::PointerEvent* ConvertMouseEvent( const EmscriptenMouseEvent& source, - OrthancStone::WebAssemblyViewport& viewport) + OrthancStone::IViewport& viewport) { std::auto_ptr<OrthancStone::PointerEvent> target( new OrthancStone::PointerEvent); target->AddPosition(viewport.GetPixelCenterCoordinates( - source.targetX, source.targetY)); + source.targetX, source.targetY)); target->SetAltModifier(source.altKey); target->SetControlModifier(source.ctrlKey); target->SetShiftModifier(source.shiftKey); @@ -172,8 +100,8 @@ if (mouseEvent != NULL && userData != NULL) { - OrthancStone::WebAssemblyViewport& viewport = - *reinterpret_cast<OrthancStone::WebAssemblyViewport*>(userData); + boost::shared_ptr<OrthancStone::ViewportController>& controller = + *reinterpret_cast<boost::shared_ptr<OrthancStone::ViewportController>*>(userData); switch (eventType) { @@ -185,8 +113,8 @@ std::auto_ptr<OrthancStone::TextSceneLayer> layer(new OrthancStone::TextSceneLayer); layer->SetText(buf); - viewport.GetScene().SetLayer(100, layer.release()); - viewport.Refresh(); + controller->GetViewport().GetScene().SetLayer(100, layer.release()); + controller->GetViewport().Refresh(); break; } @@ -196,27 +124,27 @@ { std::auto_ptr<OrthancStone::PointerEvent> event( - ConvertMouseEvent(*mouseEvent, viewport)); + ConvertMouseEvent(*mouseEvent, controller->GetViewport())); switch (mouseEvent->button) { case 0: // Left button emscripten_console_log("Creating RotateSceneTracker"); t.reset(new OrthancStone::RotateSceneTracker( - viewport.GetController(), *event)); + controller, *event)); break; case 1: // Middle button emscripten_console_log("Creating PanSceneTracker"); LOG(INFO) << "Creating PanSceneTracker" ; t.reset(new OrthancStone::PanSceneTracker( - viewport.GetController(), *event)); + controller, *event)); break; case 2: // Right button emscripten_console_log("Creating ZoomSceneTracker"); t.reset(new OrthancStone::ZoomSceneTracker( - viewport.GetController(), *event, viewport.GetCanvasWidth())); + controller, *event, controller->GetViewport().GetCanvasWidth())); break; default: @@ -227,8 +155,8 @@ if (t.get() != NULL) { tracker_.reset( - new OrthancStone::ActiveTracker(t, viewport)); - viewport.Refresh(); + new OrthancStone::ActiveTracker(t, controller->GetViewport().GetCanvasIdentifier())); + controller->GetViewport().Refresh(); } break; @@ -238,9 +166,9 @@ if (tracker_.get() != NULL) { std::auto_ptr<OrthancStone::PointerEvent> event( - ConvertMouseEvent(*mouseEvent, viewport)); + ConvertMouseEvent(*mouseEvent, controller->GetViewport())); tracker_->PointerMove(*event); - viewport.Refresh(); + controller->GetViewport().Refresh(); } break; @@ -248,9 +176,9 @@ if (tracker_.get() != NULL) { std::auto_ptr<OrthancStone::PointerEvent> event( - ConvertMouseEvent(*mouseEvent, viewport)); + ConvertMouseEvent(*mouseEvent, controller->GetViewport())); tracker_->PointerUp(*event); - viewport.Refresh(); + controller->GetViewport().Refresh(); if (!tracker_->IsAlive()) tracker_.reset(); } @@ -265,9 +193,10 @@ } -void OrthancStone::WebAssemblyViewport::SetupEvents(const std::string& canvas) +void SetupEvents(const std::string& canvas, + boost::shared_ptr<OrthancStone::ViewportController>& controller) { - emscripten_set_mousedown_callback(canvas.c_str(), this, false, OnMouseEvent); - emscripten_set_mousemove_callback(canvas.c_str(), this, false, OnMouseEvent); - emscripten_set_mouseup_callback(canvas.c_str(), this, false, OnMouseEvent); + emscripten_set_mousedown_callback(canvas.c_str(), &controller, false, OnMouseEvent); + emscripten_set_mousemove_callback(canvas.c_str(), &controller, false, OnMouseEvent); + emscripten_set_mouseup_callback(canvas.c_str(), &controller, false, OnMouseEvent); }