# HG changeset patch # User Benjamin Golinvaux # Date 1558275977 -7200 # Node ID 059e1fd05fd69bff818c056ae0c1ba20552c67fe # Parent 5c551f078c18ddb09447765269595bfc2125f234 Introduced the ViewportController that sits between the application and the Scene2D to handle the trackers and measuring tools. This is a work in progress. The Scene2D is no longer an observable. Message sending is managed by the ViewportController. Move some refs to shared and weak to prevent lifetime issues. diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2D/IPointerTracker.h --- a/Framework/Scene2D/IPointerTracker.h Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2D/IPointerTracker.h Sun May 19 16:26:17 2019 +0200 @@ -21,6 +21,8 @@ #pragma once +#if 0 + #include "PointerEvent.h" namespace OrthancStone @@ -44,3 +46,5 @@ virtual void Release() = 0; }; } + +#endif diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2D/Internals/FixedPointAligner.cpp --- a/Framework/Scene2D/Internals/FixedPointAligner.cpp Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2D/Internals/FixedPointAligner.cpp Sun May 19 16:26:17 2019 +0200 @@ -18,29 +18,31 @@ * along with this program. If not, see . **/ - +#include #include "FixedPointAligner.h" namespace OrthancStone { namespace Internals { - FixedPointAligner::FixedPointAligner(Scene2D& scene, - const ScenePoint2D& p) : - scene_(scene), - canvas_(p) + FixedPointAligner::FixedPointAligner(ViewportControllerWPtr controllerW, + const ScenePoint2D& p) + : controllerW_(controllerW) + , canvas_(p) { - pivot_ = canvas_.Apply(scene_.GetCanvasToSceneTransform()); + ViewportControllerPtr controller = controllerW_.lock(); + pivot_ = canvas_.Apply(controller->GetCanvasToSceneTransform()); } void FixedPointAligner::Apply() { - ScenePoint2D p = canvas_.Apply(scene_.GetCanvasToSceneTransform()); + ViewportControllerPtr controller = controllerW_.lock(); + ScenePoint2D p = canvas_.Apply(controller->GetCanvasToSceneTransform()); - scene_.SetSceneToCanvasTransform( + controller->SetSceneToCanvasTransform( AffineTransform2D::Combine( - scene_.GetSceneToCanvasTransform(), + controller->GetSceneToCanvasTransform(), AffineTransform2D::CreateOffset(p.GetX() - pivot_.GetX(), p.GetY() - pivot_.GetY()))); } diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2D/Internals/FixedPointAligner.h --- a/Framework/Scene2D/Internals/FixedPointAligner.h Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2D/Internals/FixedPointAligner.h Sun May 19 16:26:17 2019 +0200 @@ -18,11 +18,10 @@ * along with this program. If not, see . **/ - #pragma once -#include "../Scene2D.h" -#include "../ScenePoint2D.h" +#include +#include namespace OrthancStone { @@ -33,12 +32,12 @@ class FixedPointAligner : public boost::noncopyable { private: - Scene2D& scene_; - ScenePoint2D pivot_; - ScenePoint2D canvas_; + ViewportControllerWPtr controllerW_; + ScenePoint2D pivot_; + ScenePoint2D canvas_; public: - FixedPointAligner(Scene2D& scene, + FixedPointAligner(ViewportControllerWPtr controllerW, const ScenePoint2D& p); void Apply(); diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2D/PanSceneTracker.cpp --- a/Framework/Scene2D/PanSceneTracker.cpp Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2D/PanSceneTracker.cpp Sun May 19 16:26:17 2019 +0200 @@ -20,27 +20,34 @@ #include "PanSceneTracker.h" +#include namespace OrthancStone { - PanSceneTracker::PanSceneTracker(Scene2D& scene, - const PointerEvent& event) : - scene_(scene), - originalSceneToCanvas_(scene_.GetSceneToCanvasTransform()), - originalCanvasToScene_(scene_.GetCanvasToSceneTransform()) + PanSceneTracker::PanSceneTracker(ViewportControllerWPtr controllerW, + const PointerEvent& event) + : OneGesturePointerTracker(controllerW) + , originalSceneToCanvas_(GetController()->GetSceneToCanvasTransform()) + , originalCanvasToScene_(GetController()->GetCanvasToSceneTransform()) { pivot_ = event.GetMainPosition().Apply(originalCanvasToScene_); } - void PanSceneTracker::Update(const PointerEvent& event) + void PanSceneTracker::PointerMove(const PointerEvent& event) { ScenePoint2D p = event.GetMainPosition().Apply(originalCanvasToScene_); - scene_.SetSceneToCanvasTransform( + GetController()->SetSceneToCanvasTransform( AffineTransform2D::Combine( originalSceneToCanvas_, AffineTransform2D::CreateOffset(p.GetX() - pivot_.GetX(), p.GetY() - pivot_.GetY()))); } + + void PanSceneTracker::Cancel() + { + GetController()->SetSceneToCanvasTransform(originalSceneToCanvas_); + } + } diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2D/PanSceneTracker.h --- a/Framework/Scene2D/PanSceneTracker.h Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2D/PanSceneTracker.h Sun May 19 16:26:17 2019 +0200 @@ -21,27 +21,25 @@ #pragma once -#include "IPointerTracker.h" -#include "Scene2D.h" +#include "../Scene2DViewport/OneGesturePointerTracker.h" namespace OrthancStone { - class PanSceneTracker : public IPointerTracker + class ViewportController; + + class PanSceneTracker : public OneGesturePointerTracker { - private: - Scene2D& scene_; - ScenePoint2D pivot_; - AffineTransform2D originalSceneToCanvas_; - AffineTransform2D originalCanvasToScene_; - public: - PanSceneTracker(Scene2D& scene, + PanSceneTracker(ViewportControllerWPtr controllerW, const PointerEvent& event); - virtual void Update(const PointerEvent& event); + virtual void PointerMove(const PointerEvent& event) ORTHANC_OVERRIDE; + virtual void Cancel() ORTHANC_OVERRIDE; - virtual void Release() - { - } + private: + ViewportControllerWPtr controllerW_; + ScenePoint2D pivot_; + AffineTransform2D originalSceneToCanvas_; + AffineTransform2D originalCanvasToScene_; }; } diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2D/RotateSceneTracker.cpp --- a/Framework/Scene2D/RotateSceneTracker.cpp Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2D/RotateSceneTracker.cpp Sun May 19 16:26:17 2019 +0200 @@ -18,23 +18,22 @@ * along with this program. If not, see . **/ - #include "RotateSceneTracker.h" +#include namespace OrthancStone { - RotateSceneTracker::RotateSceneTracker(Scene2D& scene, - const PointerEvent& event) : - scene_(scene), - click_(event.GetMainPosition()), - aligner_(scene, click_), - isFirst_(true), - originalSceneToCanvas_(scene.GetSceneToCanvasTransform()) + RotateSceneTracker::RotateSceneTracker(ViewportControllerWPtr controllerW, + const PointerEvent& event) + : OneGesturePointerTracker(controllerW) + , click_(event.GetMainPosition()) + , aligner_(controllerW, click_) + , isFirst_(true) + , originalSceneToCanvas_(GetController()->GetSceneToCanvasTransform()) { } - - - void RotateSceneTracker::Update(const PointerEvent& event) + + void RotateSceneTracker::PointerMove(const PointerEvent& event) { ScenePoint2D p = event.GetMainPosition(); double dx = p.GetX() - click_.GetX(); @@ -51,7 +50,7 @@ isFirst_ = false; } - scene_.SetSceneToCanvasTransform( + GetController()->SetSceneToCanvasTransform( AffineTransform2D::Combine( AffineTransform2D::CreateRotation(a - referenceAngle_), originalSceneToCanvas_)); @@ -59,4 +58,10 @@ aligner_.Apply(); } } + + void RotateSceneTracker::Cancel() + { + GetController()->SetSceneToCanvasTransform(originalSceneToCanvas_); + } + } diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2D/RotateSceneTracker.h --- a/Framework/Scene2D/RotateSceneTracker.h Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2D/RotateSceneTracker.h Sun May 19 16:26:17 2019 +0200 @@ -21,29 +21,27 @@ #pragma once -#include "IPointerTracker.h" +#include "../Scene2DViewport/OneGesturePointerTracker.h" #include "Internals/FixedPointAligner.h" namespace OrthancStone { - class RotateSceneTracker : public IPointerTracker + class ViewportController; + + class RotateSceneTracker : public OneGesturePointerTracker { - private: - Scene2D& scene_; - ScenePoint2D click_; - Internals::FixedPointAligner aligner_; - double referenceAngle_; - bool isFirst_; - AffineTransform2D originalSceneToCanvas_; - public: - RotateSceneTracker(Scene2D& scene, + RotateSceneTracker(ViewportControllerWPtr controllerW, const PointerEvent& event); - virtual void Update(const PointerEvent& event); + virtual void PointerMove(const PointerEvent& event) ORTHANC_OVERRIDE; + virtual void Cancel() ORTHANC_OVERRIDE; - virtual void Release() - { - } + private: + ScenePoint2D click_; + Internals::FixedPointAligner aligner_; + double referenceAngle_; + bool isFirst_; + AffineTransform2D originalSceneToCanvas_; }; } diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2D/Scene2D.cpp --- a/Framework/Scene2D/Scene2D.cpp Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2D/Scene2D.cpp Sun May 19 16:26:17 2019 +0200 @@ -76,8 +76,7 @@ Scene2D::Scene2D(const Scene2D& other) - : IObservable(other.GetBroker()) - , sceneToCanvas_(other.sceneToCanvas_) + : sceneToCanvas_(other.sceneToCanvas_) , canvasToScene_(other.canvasToScene_) , layerCounter_(0) { @@ -221,7 +220,6 @@ sceneToCanvas_ = transform; canvasToScene_ = inverse; - BroadcastMessage(SceneTransformChanged(*this)); } void Scene2D::FitContent(unsigned int canvasWidth, diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2D/Scene2D.h --- a/Framework/Scene2D/Scene2D.h Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2D/Scene2D.h Sun May 19 16:26:17 2019 +0200 @@ -30,11 +30,9 @@ namespace OrthancStone { - class Scene2D : public IObservable + class Scene2D : public boost::noncopyable { public: - ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, SceneTransformChanged, Scene2D); - class IVisitor : public boost::noncopyable { public: @@ -60,9 +58,7 @@ Scene2D(const Scene2D& other); public: - Scene2D(MessageBroker& broker) - : IObservable(broker) - , layerCounter_(0) + Scene2D() : layerCounter_(0) { } diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2D/ZoomSceneTracker.cpp --- a/Framework/Scene2D/ZoomSceneTracker.cpp Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2D/ZoomSceneTracker.cpp Sun May 19 16:26:17 2019 +0200 @@ -20,16 +20,17 @@ #include "ZoomSceneTracker.h" +#include namespace OrthancStone { - ZoomSceneTracker::ZoomSceneTracker(Scene2D& scene, + ZoomSceneTracker::ZoomSceneTracker(ViewportControllerWPtr controllerW, const PointerEvent& event, - unsigned int canvasHeight) : - scene_(scene), - clickY_(event.GetMainPosition().GetY()), - aligner_(scene, event.GetMainPosition()), - originalSceneToCanvas_(scene.GetSceneToCanvasTransform()) + unsigned int canvasHeight) + : OneGesturePointerTracker(controllerW) + , clickY_(event.GetMainPosition().GetY()) + , aligner_(controllerW, event.GetMainPosition()) + , originalSceneToCanvas_(GetController()->GetSceneToCanvasTransform()) { if (canvasHeight <= 3) { @@ -42,8 +43,7 @@ } } - - void ZoomSceneTracker::Update(const PointerEvent& event) + void ZoomSceneTracker::PointerMove(const PointerEvent& event) { static const double MIN_ZOOM = -4; static const double MAX_ZOOM = 4; @@ -51,7 +51,10 @@ if (active_) { double y = event.GetMainPosition().GetY(); - double dy = static_cast(y - clickY_) * normalization_; // In the range [-1,1] + + // In the range [-1,1] + double dy = static_cast(y - clickY_) * normalization_; + double z; // Linear interpolation from [-1, 1] to [MIN_ZOOM, MAX_ZOOM] @@ -70,7 +73,7 @@ double zoom = pow(2.0, z); - scene_.SetSceneToCanvasTransform( + GetController()->SetSceneToCanvasTransform( AffineTransform2D::Combine( AffineTransform2D::CreateScaling(zoom, zoom), originalSceneToCanvas_)); @@ -78,4 +81,9 @@ aligner_.Apply(); } } + + void ZoomSceneTracker::Cancel() + { + GetController()->SetSceneToCanvasTransform(originalSceneToCanvas_); + } } diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2D/ZoomSceneTracker.h --- a/Framework/Scene2D/ZoomSceneTracker.h Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2D/ZoomSceneTracker.h Sun May 19 16:26:17 2019 +0200 @@ -22,32 +22,29 @@ #pragma once -#include "IPointerTracker.h" +#include "../Scene2DViewport/OneGesturePointerTracker.h" #include "Internals/FixedPointAligner.h" namespace OrthancStone { class Scene2D; - class ZoomSceneTracker : public IPointerTracker + class ZoomSceneTracker : public OneGesturePointerTracker { + public: + ZoomSceneTracker(ViewportControllerWPtr controllerW, + const PointerEvent& event, + unsigned int canvasHeight); + + virtual void PointerMove(const PointerEvent& event) ORTHANC_OVERRIDE; + virtual void Cancel() ORTHANC_OVERRIDE; + private: - Scene2D& scene_; double clickY_; bool active_; double normalization_; Internals::FixedPointAligner aligner_; AffineTransform2D originalSceneToCanvas_; - public: - ZoomSceneTracker(Scene2D& scene, - const PointerEvent& event, - unsigned int canvasHeight); - - virtual void Update(const PointerEvent& event); - - virtual void Release() - { - } }; } diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2DViewport/AngleMeasureTool.h --- a/Framework/Scene2DViewport/AngleMeasureTool.h Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2DViewport/AngleMeasureTool.h Sun May 19 16:26:17 2019 +0200 @@ -38,8 +38,8 @@ class AngleMeasureTool : public MeasureTool { public: - AngleMeasureTool(MessageBroker& broker, Scene2DWPtr sceneW) - : MeasureTool(broker, sceneW) + AngleMeasureTool(MessageBroker& broker, ViewportControllerWPtr controllerW) + : MeasureTool(broker, controllerW) , layersCreated(false) , polylineZIndex_(-1) , textBaseZIndex_(-1) diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2DViewport/CreateAngleMeasureTracker.cpp --- a/Framework/Scene2DViewport/CreateAngleMeasureTracker.cpp Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2DViewport/CreateAngleMeasureTracker.cpp Sun May 19 16:26:17 2019 +0200 @@ -27,20 +27,19 @@ { CreateAngleMeasureTracker::CreateAngleMeasureTracker( MessageBroker& broker, - Scene2DWPtr sceneW, + ViewportControllerWPtr controllerW, std::vector& undoStack, MeasureToolList& measureTools, const PointerEvent& e) - : CreateMeasureTracker(sceneW, undoStack, measureTools) + : CreateMeasureTracker(controllerW, undoStack, measureTools) , state_(CreatingSide1) { - Scene2DPtr scene = sceneW.lock(); command_.reset( new CreateAngleMeasureCommand( broker, - sceneW, + controllerW, measureTools, - e.GetMainPosition().Apply(scene->GetCanvasToSceneTransform()))); + e.GetMainPosition().Apply(GetScene()->GetCanvasToSceneTransform()))); } CreateAngleMeasureTracker::~CreateAngleMeasureTracker() @@ -49,8 +48,9 @@ void CreateAngleMeasureTracker::PointerMove(const PointerEvent& event) { - Scene2DPtr scene = scene_.lock(); - if (!active_) + assert(GetScene()); + + if (!alive_) { throw OrthancException(ErrorCode_InternalError, "Internal error: wrong state in CreateAngleMeasureTracker::" @@ -58,7 +58,7 @@ } ScenePoint2D scenePos = event.GetMainPosition().Apply( - scene->GetCanvasToSceneTransform()); + GetScene()->GetCanvasToSceneTransform()); switch (state_) { @@ -113,7 +113,7 @@ break; case CreatingSide2: // we are done - active_ = false; + alive_ = false; break; default: throw OrthancException(ErrorCode_InternalError, diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2DViewport/CreateAngleMeasureTracker.h --- a/Framework/Scene2DViewport/CreateAngleMeasureTracker.h Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2DViewport/CreateAngleMeasureTracker.h Sun May 19 16:26:17 2019 +0200 @@ -39,7 +39,7 @@ */ CreateAngleMeasureTracker( MessageBroker& broker, - Scene2DWPtr scene, + ViewportControllerWPtr controllerW, std::vector& undoStack, MeasureToolList& measureTools, const PointerEvent& e); diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2DViewport/CreateLineMeasureTracker.cpp --- a/Framework/Scene2DViewport/CreateLineMeasureTracker.cpp Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2DViewport/CreateLineMeasureTracker.cpp Sun May 19 16:26:17 2019 +0200 @@ -27,19 +27,18 @@ { CreateLineMeasureTracker::CreateLineMeasureTracker( MessageBroker& broker, - Scene2DWPtr sceneW, + ViewportControllerWPtr controllerW, std::vector& undoStack, MeasureToolList& measureTools, const PointerEvent& e) - : CreateMeasureTracker(sceneW, undoStack, measureTools) + : CreateMeasureTracker(controllerW, undoStack, measureTools) { - Scene2DPtr scene = sceneW.lock(); command_.reset( new CreateLineMeasureCommand( broker, - sceneW, + controllerW, measureTools, - e.GetMainPosition().Apply(scene->GetCanvasToSceneTransform()))); + e.GetMainPosition().Apply(GetScene()->GetCanvasToSceneTransform()))); } CreateLineMeasureTracker::~CreateLineMeasureTracker() @@ -49,10 +48,9 @@ void CreateLineMeasureTracker::PointerMove(const PointerEvent& event) { - Scene2DPtr scene = scene_.lock(); - assert(scene); + assert(GetScene()); - if (!active_) + if (!alive_) { throw OrthancException(ErrorCode_InternalError, "Internal error: wrong state in CreateLineMeasureTracker::" @@ -60,7 +58,7 @@ } ScenePoint2D scenePos = event.GetMainPosition().Apply( - scene->GetCanvasToSceneTransform()); + GetScene()->GetCanvasToSceneTransform()); //LOG(TRACE) << "scenePos.GetX() = " << scenePos.GetX() << " " << // "scenePos.GetY() = " << scenePos.GetY(); @@ -78,7 +76,7 @@ // Unless we augment the PointerEvent structure with the button index, // we cannot really tell if this pointer up event matches the initial // pointer down event. Let's make it simple for now. - active_ = false; + alive_ = false; } void CreateLineMeasureTracker::PointerDown(const PointerEvent& e) diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2DViewport/CreateLineMeasureTracker.h --- a/Framework/Scene2DViewport/CreateLineMeasureTracker.h Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2DViewport/CreateLineMeasureTracker.h Sun May 19 16:26:17 2019 +0200 @@ -36,7 +36,7 @@ */ CreateLineMeasureTracker( MessageBroker& broker, - Scene2DWPtr scene, + ViewportControllerWPtr controllerW, std::vector& undoStack, MeasureToolList& measureTools, const PointerEvent& e); diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2DViewport/CreateSimpleTrackerAdapter.cpp --- a/Framework/Scene2DViewport/CreateSimpleTrackerAdapter.cpp Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2DViewport/CreateSimpleTrackerAdapter.cpp Sun May 19 16:26:17 2019 +0200 @@ -24,7 +24,8 @@ namespace OrthancStone { - namespace +#if 0 + namespace { class SimpleTrackerAdapter : public IFlexiblePointerTracker { @@ -74,4 +75,5 @@ { return FlexiblePointerTrackerPtr(new SimpleTrackerAdapter(t)); } +#endif } diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2DViewport/IFlexiblePointerTracker.h --- a/Framework/Scene2DViewport/IFlexiblePointerTracker.h Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2DViewport/IFlexiblePointerTracker.h Sun May 19 16:26:17 2019 +0200 @@ -61,7 +61,7 @@ the application) to check whether the tracker must keep on receiving interaction or if its job is done and it should be deleted. */ - virtual bool IsActive() const = 0; + virtual bool IsAlive() const = 0; /** This will be called if the tracker needs to be dismissed without committing diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2DViewport/LineMeasureTool.h --- a/Framework/Scene2DViewport/LineMeasureTool.h Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2DViewport/LineMeasureTool.h Sun May 19 16:26:17 2019 +0200 @@ -38,8 +38,8 @@ class LineMeasureTool : public MeasureTool { public: - LineMeasureTool(MessageBroker& broker, Scene2DWPtr sceneW) - : MeasureTool(broker, sceneW) + LineMeasureTool(MessageBroker& broker, ViewportControllerWPtr controllerW) + : MeasureTool(broker, controllerW) , layersCreated(false) , polylineZIndex_(-1) , textZIndex_(-1) diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2DViewport/MeasureCommands.cpp --- a/Framework/Scene2DViewport/MeasureCommands.cpp Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2DViewport/MeasureCommands.cpp Sun May 19 16:26:17 2019 +0200 @@ -34,8 +34,8 @@ } CreateMeasureCommand::CreateMeasureCommand( - Scene2DWPtr sceneW, MeasureToolList& measureTools) - : TrackerCommand(sceneW) + ViewportControllerWPtr controllerW, MeasureToolList& measureTools) + : TrackerCommand(controllerW) , measureTools_(measureTools) { @@ -48,12 +48,12 @@ } CreateLineMeasureCommand::CreateLineMeasureCommand( - MessageBroker& broker, - Scene2DWPtr sceneW, - MeasureToolList& measureTools, - ScenePoint2D point) - : CreateMeasureCommand(sceneW, measureTools) - , measureTool_(new LineMeasureTool(broker,sceneW)) + MessageBroker& broker, + ViewportControllerWPtr controllerW, + MeasureToolList& measureTools, + ScenePoint2D point) + : CreateMeasureCommand(controllerW, measureTools) + , measureTool_(new LineMeasureTool(broker, controllerW)) { measureTools_.push_back(measureTool_); measureTool_->Set(point, point); @@ -65,12 +65,12 @@ } CreateAngleMeasureCommand::CreateAngleMeasureCommand( - MessageBroker& broker, - Scene2DWPtr sceneW, - MeasureToolList& measureTools, - ScenePoint2D point) - : CreateMeasureCommand(sceneW, measureTools) - , measureTool_(new AngleMeasureTool(broker,sceneW)) + MessageBroker& broker, + ViewportControllerWPtr controllerW, + MeasureToolList& measureTools, + ScenePoint2D point) + : CreateMeasureCommand(controllerW, measureTools) + , measureTool_(new AngleMeasureTool(broker, controllerW)) { measureTools_.push_back(measureTool_); measureTool_->SetSide1End(point); diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2DViewport/MeasureCommands.h --- a/Framework/Scene2DViewport/MeasureCommands.h Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2DViewport/MeasureCommands.h Sun May 19 16:26:17 2019 +0200 @@ -34,25 +34,23 @@ class TrackerCommand : public boost::noncopyable { public: - TrackerCommand(Scene2DWPtr sceneW) : scene_(sceneW) + TrackerCommand(ViewportControllerWPtr controllerW) + : controllerW_(controllerW) { } virtual void Undo() = 0; virtual void Redo() = 0; - Scene2DPtr GetScene() - { - return scene_.lock(); - } protected: - Scene2DWPtr scene_; + ViewportControllerWPtr controllerW_; }; class CreateMeasureCommand : public TrackerCommand { public: - CreateMeasureCommand(Scene2DWPtr sceneW, MeasureToolList& measureTools); + CreateMeasureCommand( + ViewportControllerWPtr controllerW, MeasureToolList& measureTools); ~CreateMeasureCommand(); virtual void Undo() ORTHANC_OVERRIDE; virtual void Redo() ORTHANC_OVERRIDE; @@ -62,16 +60,15 @@ /** Must be implemented by the subclasses that create the actual tool */ virtual MeasureToolPtr GetMeasureTool() = 0; }; - - + class CreateLineMeasureCommand : public CreateMeasureCommand { public: CreateLineMeasureCommand( - MessageBroker& broker, - Scene2DWPtr scene, - MeasureToolList& measureTools, - ScenePoint2D point); + MessageBroker& broker, + ViewportControllerWPtr controllerW, + MeasureToolList& measureTools, + ScenePoint2D point); // the starting position is set in the ctor void SetEnd(ScenePoint2D scenePos); @@ -90,10 +87,10 @@ public: /** Ctor sets end of side 1*/ CreateAngleMeasureCommand( - MessageBroker& broker, - Scene2DWPtr scene, - MeasureToolList& measureTools, - ScenePoint2D point); + MessageBroker& broker, + ViewportControllerWPtr controllerW, + MeasureToolList& measureTools, + ScenePoint2D point); /** This method sets center*/ void SetCenter(ScenePoint2D scenePos); diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2DViewport/MeasureTools.cpp --- a/Framework/Scene2DViewport/MeasureTools.cpp Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2DViewport/MeasureTools.cpp Sun May 19 16:26:17 2019 +0200 @@ -22,7 +22,7 @@ #include #include -#include +#include #include @@ -53,26 +53,34 @@ return enabled_; } - OrthancStone::Scene2DPtr MeasureTool::GetScene() + + ViewportControllerPtr MeasureTool::GetController() { - Scene2DPtr scene = scene_.lock(); - if (!scene) - throw OrthancException(ErrorCode_InternalError, "Using dead object!"); - return scene; + ViewportControllerPtr controller = controllerW_.lock(); + if (!controller) + throw OrthancException(ErrorCode_InternalError, + "Using dead ViewportController object!"); + return controller; } - MeasureTool::MeasureTool(MessageBroker& broker, Scene2DWPtr sceneW) + OrthancStone::Scene2DPtr MeasureTool::GetScene() + { + return GetController()->GetScene(); + } + + MeasureTool::MeasureTool(MessageBroker& broker, + ViewportControllerWPtr controllerW) : IObserver(broker) - , scene_(sceneW) + , controllerW_(controllerW) , enabled_(true) { - GetScene()->RegisterObserverCallback( - new Callable + GetController()->RegisterObserverCallback( + new Callable (*this, &MeasureTool::OnSceneTransformChanged)); } void MeasureTool::OnSceneTransformChanged( - const Scene2D::SceneTransformChanged& message) + const ViewportController::SceneTransformChanged& message) { RefreshScene(); } diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2DViewport/MeasureTools.h --- a/Framework/Scene2DViewport/MeasureTools.h Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2DViewport/MeasureTools.h Sun May 19 16:26:17 2019 +0200 @@ -21,6 +21,7 @@ #pragma once #include +#include #include #include @@ -57,10 +58,11 @@ This method is called when the scene transform changes. It allows to recompute the visual elements whose content depend upon the scene transform */ - void OnSceneTransformChanged(const Scene2D::SceneTransformChanged& message); + void OnSceneTransformChanged( + const ViewportController::SceneTransformChanged& message); protected: - MeasureTool(MessageBroker& broker, Scene2DWPtr sceneW); + MeasureTool(MessageBroker& broker, ViewportControllerWPtr controllerW); /** This is the meat of the tool: this method must [create (if needed) and] @@ -69,8 +71,9 @@ */ virtual void RefreshScene() = 0; + ViewportControllerPtr GetController(); Scene2DPtr GetScene(); - + /** enabled_ is not accessible by subclasses because there is a state machine that we do not wanna mess with @@ -78,7 +81,7 @@ bool IsEnabled() const; private: - Scene2DWPtr scene_; + ViewportControllerWPtr controllerW_; bool enabled_; }; } diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2DViewport/MeasureTrackers.cpp --- a/Framework/Scene2DViewport/MeasureTrackers.cpp Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2DViewport/MeasureTrackers.cpp Sun May 19 16:26:17 2019 +0200 @@ -27,11 +27,11 @@ { CreateMeasureTracker::CreateMeasureTracker( - Scene2DWPtr sceneW, + ViewportControllerWPtr controllerW, std::vector& undoStack, std::vector& measureTools) - : scene_(sceneW) - , active_(true) + : controllerW_(controllerW) + , alive_(true) , undoStack_(undoStack) , measureTools_(measureTools) , commitResult_(true) @@ -41,12 +41,12 @@ void CreateMeasureTracker::Cancel() { commitResult_ = false; - active_ = false; + alive_ = false; } - bool CreateMeasureTracker::IsActive() const + bool CreateMeasureTracker::IsAlive() const { - return active_; + return alive_; } CreateMeasureTracker::~CreateMeasureTracker() @@ -60,6 +60,13 @@ else command_->Undo(); } + + + OrthancStone::Scene2DPtr CreateMeasureTracker::GetScene() + { + return controllerW_.lock()->GetScene(); + } + } diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2DViewport/MeasureTrackers.h --- a/Framework/Scene2DViewport/MeasureTrackers.h Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2DViewport/MeasureTrackers.h Sun May 19 16:26:17 2019 +0200 @@ -35,10 +35,10 @@ { public: virtual void Cancel() ORTHANC_OVERRIDE; - virtual bool IsActive() const ORTHANC_OVERRIDE; + virtual bool IsAlive() const ORTHANC_OVERRIDE; protected: CreateMeasureTracker( - Scene2DWPtr scene, + ViewportControllerWPtr controllerW, std::vector& undoStack, std::vector& measureTools); @@ -46,8 +46,10 @@ protected: CreateMeasureCommandPtr command_; - Scene2DWPtr scene_; - bool active_; + ViewportControllerWPtr controllerW_; + bool alive_; + Scene2DPtr GetScene(); + private: std::vector& undoStack_; std::vector& measureTools_; diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2DViewport/OneGesturePointerTracker.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Scene2DViewport/OneGesturePointerTracker.cpp Sun May 19 16:26:17 2019 +0200 @@ -0,0 +1,56 @@ +/** + * 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 . + **/ + +#pragma once + +#include "OneGesturePointerTracker.h" +#include + +using namespace Orthanc; + +namespace OrthancStone +{ + OneGesturePointerTracker::OneGesturePointerTracker( + ViewportControllerWPtr controllerW) + : controllerW_(controllerW) + , alive_(true) + { + } + + void OneGesturePointerTracker::PointerUp(const PointerEvent& event) + { + alive_ = false; + } + + void OneGesturePointerTracker::PointerDown(const PointerEvent& event) + { + throw OrthancException(ErrorCode_InternalError, "Wrong state in tracker"); + } + + bool OneGesturePointerTracker::IsAlive() const + { + return alive_; + } + + ViewportControllerPtr OneGesturePointerTracker::GetController() + { + return controllerW_.lock(); + } +} diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2DViewport/OneGesturePointerTracker.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Scene2DViewport/OneGesturePointerTracker.h Sun May 19 16:26:17 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 . + **/ + +#pragma once + +#include "IFlexiblePointerTracker.h" + +namespace OrthancStone +{ + /** + This base is class allows to write simple trackers that deal with single + drag gestures. It is *not* suitables for multi-state trackers where various + mouse operations need to be handled. + + In order to write such a tracker: + - subclass this class + - you may store the initial click/touch position in the constructor + - implement PointerMove to react to pointer/touch events + - implement Cancel to restore the state at initial tracker creation time + */ + class OneGesturePointerTracker : public IFlexiblePointerTracker + { + public: + OneGesturePointerTracker(ViewportControllerWPtr controllerW); + virtual void PointerUp(const PointerEvent& event) ORTHANC_OVERRIDE; + virtual void PointerDown(const PointerEvent& event) ORTHANC_OVERRIDE; + virtual bool IsAlive() const ORTHANC_OVERRIDE; + + protected: + ViewportControllerPtr GetController(); + + private: + ViewportControllerWPtr controllerW_; + bool alive_; + }; +} + diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2DViewport/PointerTypes.h --- a/Framework/Scene2DViewport/PointerTypes.h Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2DViewport/PointerTypes.h Sun May 19 16:26:17 2019 +0200 @@ -79,5 +79,5 @@ class ViewportController; typedef boost::shared_ptr ViewportControllerPtr; - + typedef boost::weak_ptr ViewportControllerWPtr; } diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2DViewport/ViewportController.cpp --- a/Framework/Scene2DViewport/ViewportController.cpp Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2DViewport/ViewportController.cpp Sun May 19 16:26:17 2019 +0200 @@ -22,28 +22,44 @@ #include +#include + using namespace Orthanc; namespace OrthancStone { - ViewportController::ViewportController(MessageBroker& broker) - : broker_(broker) + : IObservable(broker) { - + scene_ = boost::make_shared(); } Scene2DPtr ViewportController::GetScene() { - Scene2DPtr scene = scene_.lock(); - if (!scene) - throw OrthancException(ErrorCode_InternalError, "Using dead object!"); - return scene; + return scene_; } bool ViewportController::HandlePointerEvent(PointerEvent e) { throw StoneException(ErrorCode_NotImplemented); } + + const OrthancStone::AffineTransform2D& ViewportController::GetCanvasToSceneTransform() const + { + return scene_->GetCanvasToSceneTransform(); + } + + const OrthancStone::AffineTransform2D& ViewportController::GetSceneToCanvasTransform() const + { + return scene_->GetSceneToCanvasTransform(); + } + + void ViewportController::SetSceneToCanvasTransform( + const AffineTransform2D& transform) + { + scene_->SetSceneToCanvasTransform(transform); + BroadcastMessage(SceneTransformChanged(*this)); + } + } diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Scene2DViewport/ViewportController.h --- a/Framework/Scene2DViewport/ViewportController.h Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Scene2DViewport/ViewportController.h Sun May 19 16:26:17 2019 +0200 @@ -24,7 +24,6 @@ #include #include -#include #include namespace OrthancStone @@ -41,9 +40,12 @@ Each canvas or other GUI area where we want to display a 2D image, either directly or through slicing must be assigned a ViewportController. */ - class ViewportController : public boost::noncopyable + class ViewportController : public IObservable { public: + ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, \ + SceneTransformChanged, ViewportController); + ViewportController(MessageBroker& broker); Scene2DPtr GetScene(); @@ -67,9 +69,18 @@ */ void SetActiveTracker(FlexiblePointerTrackerPtr tracker); + /** Forwarded to the underlying scene */ + const AffineTransform2D& GetCanvasToSceneTransform() const; + + /** Forwarded to the underlying scene */ + const AffineTransform2D& GetSceneToCanvasTransform() const; + + /** Forwarded to the underlying scene, and broadcasted to the observers */ + void SetSceneToCanvasTransform(const AffineTransform2D& transform); + + private: - MessageBroker& broker_; - Scene2DWPtr scene_; + Scene2DPtr scene_; FlexiblePointerTrackerPtr tracker_; }; } diff -r 5c551f078c18 -r 059e1fd05fd6 Framework/Toolbox/ShearWarpProjectiveTransform.cpp --- a/Framework/Toolbox/ShearWarpProjectiveTransform.cpp Fri May 17 09:20:46 2019 +0200 +++ b/Framework/Toolbox/ShearWarpProjectiveTransform.cpp Sun May 19 16:26:17 2019 +0200 @@ -543,7 +543,8 @@ } else { - *p = *qacc / static_cast(*qcount); + *p = static_cast + (*qacc / static_cast(*qcount)); if (*p > maxValue) { diff -r 5c551f078c18 -r 059e1fd05fd6 Resources/CMake/OrthancStoneConfiguration.cmake --- a/Resources/CMake/OrthancStoneConfiguration.cmake Fri May 17 09:20:46 2019 +0200 +++ b/Resources/CMake/OrthancStoneConfiguration.cmake Sun May 19 16:26:17 2019 +0200 @@ -357,6 +357,8 @@ ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/MeasureToolsToolbox.h ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/MeasureTrackers.cpp ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/MeasureTrackers.h + ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/OneGesturePointerTracker.cpp + ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/OneGesturePointerTracker.h ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/PointerTypes.h ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/ViewportController.cpp ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/ViewportController.h diff -r 5c551f078c18 -r 059e1fd05fd6 Samples/Sdl/BasicScene.cpp --- a/Samples/Sdl/BasicScene.cpp Fri May 17 09:20:46 2019 +0200 +++ b/Samples/Sdl/BasicScene.cpp Sun May 19 16:26:17 2019 +0200 @@ -28,6 +28,8 @@ #include "../../Framework/Scene2D/RotateSceneTracker.h" #include "../../Framework/Scene2D/Scene2D.h" #include "../../Framework/Scene2D/ZoomSceneTracker.h" +#include "../../Framework/Scene2DViewport/ViewportController.h" + #include "../../Framework/StoneInitialization.h" #include "../../Framework/Messages/MessageBroker.h" @@ -44,11 +46,11 @@ static const unsigned int FONT_SIZE = 32; static const int LAYER_POSITION = 150; +using namespace OrthancStone; -void PrepareScene(OrthancStone::Scene2D& scene) +void PrepareScene(ViewportControllerPtr controller) { - using namespace OrthancStone; - + Scene2D& scene(*controller->GetScene()); // Texture of 2x2 size { Orthanc::Image i(Orthanc::PixelFormat_RGB24, 2, 2, false); @@ -137,12 +139,12 @@ void TakeScreenshot(const std::string& target, - const OrthancStone::Scene2D& scene, + const Scene2D& scene, unsigned int canvasWidth, unsigned int canvasHeight) { // Take a screenshot, then save it as PNG file - OrthancStone::CairoCompositor compositor(scene, canvasWidth, canvasHeight); + CairoCompositor compositor(scene, canvasWidth, canvasHeight); compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, FONT_SIZE, Orthanc::Encoding_Latin1); compositor.Refresh(); @@ -157,11 +159,12 @@ } -void HandleApplicationEvent(OrthancStone::Scene2D& scene, - const OrthancStone::OpenGLCompositor& compositor, +void HandleApplicationEvent(ViewportControllerPtr controller, + const OpenGLCompositor& compositor, const SDL_Event& event, - std::auto_ptr& activeTracker) + FlexiblePointerTrackerPtr& activeTracker) { + Scene2D& scene(*controller->GetScene()); if (event.type == SDL_MOUSEMOTION) { int scancodeCount = 0; @@ -173,28 +176,29 @@ { // The "left-ctrl" key is down, while no tracker is present - OrthancStone::PointerEvent e; + PointerEvent e; e.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y)); - OrthancStone::ScenePoint2D p = e.GetMainPosition().Apply(scene.GetCanvasToSceneTransform()); + ScenePoint2D p = e.GetMainPosition().Apply(scene.GetCanvasToSceneTransform()); char buf[64]; sprintf(buf, "(%0.02f,%0.02f)", p.GetX(), p.GetY()); if (scene.HasLayer(LAYER_POSITION)) { - OrthancStone::TextSceneLayer& layer = - dynamic_cast(scene.GetLayer(LAYER_POSITION)); + TextSceneLayer& layer = + dynamic_cast(scene.GetLayer(LAYER_POSITION)); layer.SetText(buf); layer.SetPosition(p.GetX(), p.GetY()); } else { - std::auto_ptr layer(new OrthancStone::TextSceneLayer); + std::auto_ptr + layer(new TextSceneLayer); layer->SetColor(0, 255, 0); layer->SetText(buf); layer->SetBorder(20); - layer->SetAnchor(OrthancStone::BitmapAnchor_BottomCenter); + layer->SetAnchor(BitmapAnchor_BottomCenter); layer->SetPosition(p.GetX(), p.GetY()); scene.SetLayer(LAYER_POSITION, layer.release()); } @@ -206,22 +210,24 @@ } else if (event.type == SDL_MOUSEBUTTONDOWN) { - OrthancStone::PointerEvent e; + PointerEvent e; e.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y)); switch (event.button.button) { case SDL_BUTTON_MIDDLE: - activeTracker.reset(new OrthancStone::PanSceneTracker(scene, e)); + activeTracker.reset(new PanSceneTracker( + controller, e)); break; case SDL_BUTTON_RIGHT: - activeTracker.reset(new OrthancStone::ZoomSceneTracker(scene, e, - compositor.GetCanvasHeight())); + activeTracker.reset(new ZoomSceneTracker( + controller, e, compositor.GetCanvasHeight())); break; case SDL_BUTTON_LEFT: - activeTracker.reset(new OrthancStone::RotateSceneTracker(scene, e)); + activeTracker.reset(new RotateSceneTracker( + controller, e)); break; default: @@ -269,20 +275,21 @@ } -void Run(OrthancStone::Scene2D& scene) +void Run(ViewportControllerPtr controller) { - OrthancStone::SdlOpenGLWindow window("Hello", 1024, 768); + SdlOpenGLWindow window("Hello", 1024, 768); - scene.FitContent(window.GetCanvasWidth(), window.GetCanvasHeight()); + controller->GetScene()->FitContent( + window.GetCanvasWidth(), window.GetCanvasHeight()); glEnable(GL_DEBUG_OUTPUT); glDebugMessageCallback(OpenGLMessageCallback, 0); - OrthancStone::OpenGLCompositor compositor(window, scene); + OpenGLCompositor compositor(window, *controller->GetScene()); compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, FONT_SIZE, Orthanc::Encoding_Latin1); - std::auto_ptr tracker; + FlexiblePointerTrackerPtr tracker; bool stop = false; while (!stop) @@ -300,25 +307,30 @@ } else if (event.type == SDL_MOUSEMOTION) { - if (tracker.get() != NULL) + if (tracker) { - OrthancStone::PointerEvent e; - e.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y)); - tracker->Update(e); + PointerEvent e; + e.AddPosition(compositor.GetPixelCenterCoordinates( + event.button.x, event.button.y)); + tracker->PointerMove(e); } } else if (event.type == SDL_MOUSEBUTTONUP) { - if (tracker.get() != NULL) + if (tracker) { - tracker->Release(); - tracker.reset(NULL); + PointerEvent e; + e.AddPosition(compositor.GetPixelCenterCoordinates( + event.button.x, event.button.y)); + tracker->PointerUp(e); + if(!tracker->IsAlive()) + tracker = NULL; } } else if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { - tracker.reset(NULL); + tracker = NULL; compositor.UpdateSize(); } else if (event.type == SDL_KEYDOWN && @@ -339,7 +351,7 @@ } } - HandleApplicationEvent(scene, compositor, event, tracker); + HandleApplicationEvent(controller, compositor, event, tracker); } SDL_Delay(1); @@ -356,22 +368,23 @@ **/ int main(int argc, char* argv[]) { - OrthancStone::StoneInitialize(); + StoneInitialize(); Orthanc::Logging::EnableInfoLevel(true); try { - OrthancStone::MessageBroker broker; - OrthancStone::Scene2D scene(broker); - PrepareScene(scene); - Run(scene); + MessageBroker broker; + ViewportControllerPtr controller( + new ViewportController(broker)); + PrepareScene(controller); + Run(controller); } catch (Orthanc::OrthancException& e) { LOG(ERROR) << "EXCEPTION: " << e.What(); } - OrthancStone::StoneFinalize(); + StoneFinalize(); return 0; } diff -r 5c551f078c18 -r 059e1fd05fd6 Samples/Sdl/TrackerSampleApp.cpp --- a/Samples/Sdl/TrackerSampleApp.cpp Fri May 17 09:20:46 2019 +0200 +++ b/Samples/Sdl/TrackerSampleApp.cpp Sun May 19 16:26:17 2019 +0200 @@ -70,7 +70,7 @@ Scene2DPtr TrackerSampleApp::GetScene() { - return controller_.GetScene(); + return controller_->GetScene(); } void TrackerSampleApp::SelectNextTool() @@ -192,7 +192,7 @@ // e.GetMainPosition().GetX() << " " << e.GetMainPosition().GetY(); activeTracker_->PointerMove(e); - if (!activeTracker_->IsActive()) + if (!activeTracker_->IsAlive()) activeTracker_ = NULL; } } @@ -204,7 +204,7 @@ PointerEvent e; e.AddPosition(compositor_->GetPixelCenterCoordinates(event.button.x, event.button.y)); activeTracker_->PointerUp(e); - if (!activeTracker_->IsActive()) + if (!activeTracker_->IsAlive()) activeTracker_ = NULL; } } @@ -216,7 +216,7 @@ if (activeTracker_) { activeTracker_->PointerDown(e); - if (!activeTracker_->IsActive()) + if (!activeTracker_->IsAlive()) activeTracker_ = NULL; } else @@ -234,7 +234,7 @@ if (activeTracker_) { activeTracker_->Cancel(); - if (!activeTracker_->IsActive()) + if (!activeTracker_->IsAlive()) activeTracker_ = NULL; } break; @@ -268,7 +268,8 @@ } - void TrackerSampleApp::OnSceneTransformChanged(const Scene2D::SceneTransformChanged& message) + void TrackerSampleApp::OnSceneTransformChanged( + const ViewportController::SceneTransformChanged& message) { DisplayInfoText(); } @@ -280,12 +281,12 @@ switch (event.button.button) { case SDL_BUTTON_MIDDLE: - return CreateSimpleTrackerAdapter(PointerTrackerPtr( - new PanSceneTracker(*GetScene(), e))); + return FlexiblePointerTrackerPtr(new PanSceneTracker + (controller_, e)); case SDL_BUTTON_RIGHT: - return CreateSimpleTrackerAdapter(PointerTrackerPtr( - new ZoomSceneTracker(*GetScene(), e, compositor_->GetCanvasHeight()))); + return FlexiblePointerTrackerPtr(new ZoomSceneTracker + (controller_, e, compositor_->GetCanvasHeight())); case SDL_BUTTON_LEFT: { @@ -310,14 +311,14 @@ { case GuiTool_Rotate: //LOG(TRACE) << "Creating RotateSceneTracker"; - return CreateSimpleTrackerAdapter(PointerTrackerPtr( - new RotateSceneTracker(*GetScene(), e))); + return FlexiblePointerTrackerPtr(new RotateSceneTracker( + controller_, e)); case GuiTool_Pan: - return CreateSimpleTrackerAdapter(PointerTrackerPtr( - new PanSceneTracker(*GetScene(), e))); + return FlexiblePointerTrackerPtr(new PanSceneTracker( + controller_, e)); case GuiTool_Zoom: - return CreateSimpleTrackerAdapter(PointerTrackerPtr( - new ZoomSceneTracker(*GetScene(), e, compositor_->GetCanvasHeight()))); + return FlexiblePointerTrackerPtr(new ZoomSceneTracker( + controller_, e, compositor_->GetCanvasHeight())); //case GuiTool_AngleMeasure: // return new AngleMeasureTracker(GetScene(), measureTools_, undoStack_, e); //case GuiTool_CircleMeasure: @@ -326,10 +327,10 @@ // return new EllipseMeasureTracker(GetScene(), measureTools_, undoStack_, e); case GuiTool_LineMeasure: return FlexiblePointerTrackerPtr(new CreateLineMeasureTracker( - IObserver::GetBroker(), GetScene(), undoStack_, measureTools_, e)); + IObserver::GetBroker(), controller_, undoStack_, measureTools_, e)); case GuiTool_AngleMeasure: return FlexiblePointerTrackerPtr(new CreateAngleMeasureTracker( - IObserver::GetBroker(), GetScene(), undoStack_, measureTools_, e)); + IObserver::GetBroker(), controller_, undoStack_, measureTools_, e)); return NULL; case GuiTool_CircleMeasure: LOG(ERROR) << "Not implemented yet!"; @@ -349,7 +350,6 @@ TrackerSampleApp::TrackerSampleApp(MessageBroker& broker) : IObserver(broker) - , scene_(broker) , currentTool_(GuiTool_Rotate) { controller_ = ViewportControllerPtr(new ViewportController(broker)); @@ -469,7 +469,7 @@ unsigned int canvasWidth, unsigned int canvasHeight) { - CairoCompositor compositor(GetScene(), canvasWidth, canvasHeight); + CairoCompositor compositor(*GetScene(), canvasWidth, canvasHeight); compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, FONT_SIZE_0, Orthanc::Encoding_Latin1); compositor.Refresh(); @@ -520,7 +520,7 @@ glEnable(GL_DEBUG_OUTPUT); glDebugMessageCallback(OpenGLMessageCallback, 0); - compositor_.reset(new OpenGLCompositor(window, GetScene())); + compositor_.reset(new OpenGLCompositor(window, *GetScene())); compositor_->SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, FONT_SIZE_0, Orthanc::Encoding_Latin1); @@ -565,6 +565,9 @@ } SDL_Delay(1); } + + // the following is paramount because the compositor holds a reference + // to the scene and we do not want this reference to become dangling compositor_.reset(NULL); } diff -r 5c551f078c18 -r 059e1fd05fd6 Samples/Sdl/TrackerSampleApp.h --- a/Samples/Sdl/TrackerSampleApp.h Fri May 17 09:20:46 2019 +0200 +++ b/Samples/Sdl/TrackerSampleApp.h Sun May 19 16:26:17 2019 +0200 @@ -74,7 +74,8 @@ This method is called when the scene transform changes. It allows to recompute the visual elements whose content depend upon the scene transform */ - void OnSceneTransformChanged(const Scene2D::SceneTransformChanged& message); + void OnSceneTransformChanged( + const ViewportController::SceneTransformChanged& message); private: void SelectNextTool();