# HG changeset patch # User Benjamin Golinvaux # Date 1557834660 -7200 # Node ID 462a5074f9144d13cfc3aa1d2f21ab301a1b5bcc # Parent 4eccf698e52ff0e463a6752fe3e930c39bab7d28 Turned the scene into an observable to be able to dynamically react to scene to canvas transform changes --> now the handles and angle measure adornments are immune to zoom changes diff -r 4eccf698e52f -r 462a5074f914 Framework/Scene2D/Scene2D.cpp --- a/Framework/Scene2D/Scene2D.cpp Tue May 14 13:49:12 2019 +0200 +++ b/Framework/Scene2D/Scene2D.cpp Tue May 14 13:51:00 2019 +0200 @@ -75,10 +75,11 @@ }; - Scene2D::Scene2D(const Scene2D& other) : - sceneToCanvas_(other.sceneToCanvas_), - canvasToScene_(other.canvasToScene_), - layerCounter_(0) + Scene2D::Scene2D(const Scene2D& other) + : IObservable(other.GetBroker()) + , sceneToCanvas_(other.sceneToCanvas_) + , canvasToScene_(other.canvasToScene_) + , layerCounter_(0) { for (Content::const_iterator it = other.content_.begin(); it != other.content_.end(); ++it) @@ -220,9 +221,9 @@ sceneToCanvas_ = transform; canvasToScene_ = inverse; + BroadcastMessage(SceneTransformChanged(*this)); } - void Scene2D::FitContent(unsigned int canvasWidth, unsigned int canvasHeight) { diff -r 4eccf698e52f -r 462a5074f914 Framework/Scene2D/Scene2D.h --- a/Framework/Scene2D/Scene2D.h Tue May 14 13:49:12 2019 +0200 +++ b/Framework/Scene2D/Scene2D.h Tue May 14 13:51:00 2019 +0200 @@ -23,13 +23,18 @@ #include "ISceneLayer.h" #include "../Toolbox/AffineTransform2D.h" +#include +#include + #include namespace OrthancStone { - class Scene2D : public boost::noncopyable + class Scene2D : public IObservable { public: + ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, SceneTransformChanged, Scene2D); + class IVisitor : public boost::noncopyable { public: @@ -55,8 +60,9 @@ Scene2D(const Scene2D& other); public: - Scene2D() : - layerCounter_(0) + Scene2D(MessageBroker& broker) + : IObservable(broker) + , layerCounter_(0) { } diff -r 4eccf698e52f -r 462a5074f914 Samples/Common/AngleMeasureTool.cpp --- a/Samples/Common/AngleMeasureTool.cpp Tue May 14 13:49:12 2019 +0200 +++ b/Samples/Common/AngleMeasureTool.cpp Tue May 14 13:51:00 2019 +0200 @@ -145,13 +145,13 @@ { PolylineSceneLayer::Chain chain; - AddSquare(chain, GetScene(), side1End_, 10.0); //TODO: take DPI into account + AddSquare(chain, GetScene(), side1End_, 10.0* pixelToScene); //TODO: take DPI into account polylineLayer->AddChain(chain, true); } { PolylineSceneLayer::Chain chain; - AddSquare(chain, GetScene(), side2End_, 10.0); //TODO: take DPI into account + AddSquare(chain, GetScene(), side2End_, 10.0* pixelToScene); //TODO: take DPI into account polylineLayer->AddChain(chain, true); } } diff -r 4eccf698e52f -r 462a5074f914 Samples/Common/AngleMeasureTool.h --- a/Samples/Common/AngleMeasureTool.h Tue May 14 13:49:12 2019 +0200 +++ b/Samples/Common/AngleMeasureTool.h Tue May 14 13:51:00 2019 +0200 @@ -38,8 +38,8 @@ class AngleMeasureTool : public MeasureTool { public: - AngleMeasureTool(Scene2D& scene) - : MeasureTool(scene) + AngleMeasureTool(MessageBroker& broker, Scene2D& scene) + : MeasureTool(broker, scene) , layersCreated(false) , polylineZIndex_(-1) , textZIndex_(-1) @@ -69,6 +69,6 @@ }; typedef boost::shared_ptr AngleMeasureToolPtr; -} - - +} + + diff -r 4eccf698e52f -r 462a5074f914 Samples/Common/CreateAngleMeasureTracker.cpp --- a/Samples/Common/CreateAngleMeasureTracker.cpp Tue May 14 13:49:12 2019 +0200 +++ b/Samples/Common/CreateAngleMeasureTracker.cpp Tue May 14 13:51:00 2019 +0200 @@ -26,15 +26,17 @@ namespace OrthancStone { CreateAngleMeasureTracker::CreateAngleMeasureTracker( + MessageBroker& broker, Scene2D& scene, std::vector& undoStack, std::vector& measureTools, const PointerEvent& e) : CreateMeasureTracker(scene, undoStack, measureTools) , state_(CreatingSide1) - { + { command_.reset( new CreateAngleMeasureCommand( + broker, scene, measureTools, e.GetMainPosition().Apply(scene.GetCanvasToSceneTransform()))); @@ -44,35 +46,35 @@ { } - void CreateAngleMeasureTracker::PointerMove(const PointerEvent& event) - { - if (!active_) - { - throw OrthancException(ErrorCode_InternalError, - "Internal error: wrong state in CreateAngleMeasureTracker::" - "PointerMove: active_ == false"); - } - - ScenePoint2D scenePos = event.GetMainPosition().Apply( - scene_.GetCanvasToSceneTransform()); - - switch (state_) - { - case CreatingSide1: - GetCommand()->SetCenter(scenePos); - break; - case CreatingSide2: - GetCommand()->SetSide2End(scenePos); - break; - default: - throw OrthancException(ErrorCode_InternalError, - "Wrong state in CreateAngleMeasureTracker::" - "PointerMove: state_ invalid"); - } + void CreateAngleMeasureTracker::PointerMove(const PointerEvent& event) + { + if (!active_) + { + throw OrthancException(ErrorCode_InternalError, + "Internal error: wrong state in CreateAngleMeasureTracker::" + "PointerMove: active_ == false"); + } + + ScenePoint2D scenePos = event.GetMainPosition().Apply( + scene_.GetCanvasToSceneTransform()); + + switch (state_) + { + case CreatingSide1: + GetCommand()->SetCenter(scenePos); + break; + case CreatingSide2: + GetCommand()->SetSide2End(scenePos); + break; + default: + throw OrthancException(ErrorCode_InternalError, + "Wrong state in CreateAngleMeasureTracker::" + "PointerMove: state_ invalid"); + } //LOG(TRACE) << "scenePos.GetX() = " << scenePos.GetX() << " " << // "scenePos.GetY() = " << scenePos.GetY(); - } - + } + void CreateAngleMeasureTracker::PointerUp(const PointerEvent& e) { // TODO: the current app does not prevent multiple PointerDown AND @@ -80,42 +82,42 @@ // 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. - - switch (state_) - { - case CreatingSide1: - state_ = CreatingSide2; - break; - case CreatingSide2: - throw OrthancException(ErrorCode_InternalError, - "Wrong state in CreateAngleMeasureTracker::" - "PointerUp: state_ == CreatingSide2 ; this should not happen"); - break; - default: - throw OrthancException(ErrorCode_InternalError, - "Wrong state in CreateAngleMeasureTracker::" - "PointerMove: state_ invalid"); - } + + switch (state_) + { + case CreatingSide1: + state_ = CreatingSide2; + break; + case CreatingSide2: + throw OrthancException(ErrorCode_InternalError, + "Wrong state in CreateAngleMeasureTracker::" + "PointerUp: state_ == CreatingSide2 ; this should not happen"); + break; + default: + throw OrthancException(ErrorCode_InternalError, + "Wrong state in CreateAngleMeasureTracker::" + "PointerMove: state_ invalid"); + } } void CreateAngleMeasureTracker::PointerDown(const PointerEvent& e) { - switch (state_) - { - case CreatingSide1: - throw OrthancException(ErrorCode_InternalError, - "Wrong state in CreateAngleMeasureTracker::" - "PointerDown: state_ == CreatingSide1 ; this should not happen"); - break; - case CreatingSide2: - // we are done - active_ = false; - break; - default: - throw OrthancException(ErrorCode_InternalError, - "Wrong state in CreateAngleMeasureTracker::" - "PointerMove: state_ invalid"); - } + switch (state_) + { + case CreatingSide1: + throw OrthancException(ErrorCode_InternalError, + "Wrong state in CreateAngleMeasureTracker::" + "PointerDown: state_ == CreatingSide1 ; this should not happen"); + break; + case CreatingSide2: + // we are done + active_ = false; + break; + default: + throw OrthancException(ErrorCode_InternalError, + "Wrong state in CreateAngleMeasureTracker::" + "PointerMove: state_ invalid"); + } } CreateAngleMeasureCommandPtr CreateAngleMeasureTracker::GetCommand() diff -r 4eccf698e52f -r 462a5074f914 Samples/Common/CreateAngleMeasureTracker.h --- a/Samples/Common/CreateAngleMeasureTracker.h Tue May 14 13:49:12 2019 +0200 +++ b/Samples/Common/CreateAngleMeasureTracker.h Tue May 14 13:51:00 2019 +0200 @@ -38,6 +38,7 @@ must be supplied, too */ CreateAngleMeasureTracker( + MessageBroker& broker, Scene2D& scene, std::vector& undoStack, std::vector& measureTools, diff -r 4eccf698e52f -r 462a5074f914 Samples/Common/CreateLineMeasureTracker.cpp --- a/Samples/Common/CreateLineMeasureTracker.cpp Tue May 14 13:49:12 2019 +0200 +++ b/Samples/Common/CreateLineMeasureTracker.cpp Tue May 14 13:51:00 2019 +0200 @@ -26,45 +26,47 @@ namespace OrthancStone { CreateLineMeasureTracker::CreateLineMeasureTracker( + MessageBroker& broker, Scene2D& scene, std::vector& undoStack, std::vector& measureTools, const PointerEvent& e) : CreateMeasureTracker(scene, undoStack, measureTools) - { + { command_.reset( new CreateLineMeasureCommand( + broker, scene, measureTools, - e.GetMainPosition().Apply(scene.GetCanvasToSceneTransform()))); - } - + e.GetMainPosition().Apply(scene.GetCanvasToSceneTransform()))); + } + CreateLineMeasureTracker::~CreateLineMeasureTracker() { } - void CreateLineMeasureTracker::PointerMove(const PointerEvent& event) - { - if (!active_) - { - throw OrthancException(ErrorCode_InternalError, - "Internal error: wrong state in CreateLineMeasureTracker::" - "PointerMove: active_ == false"); - } - - ScenePoint2D scenePos = event.GetMainPosition().Apply( - scene_.GetCanvasToSceneTransform()); - + void CreateLineMeasureTracker::PointerMove(const PointerEvent& event) + { + if (!active_) + { + throw OrthancException(ErrorCode_InternalError, + "Internal error: wrong state in CreateLineMeasureTracker::" + "PointerMove: active_ == false"); + } + + ScenePoint2D scenePos = event.GetMainPosition().Apply( + scene_.GetCanvasToSceneTransform()); + //LOG(TRACE) << "scenePos.GetX() = " << scenePos.GetX() << " " << // "scenePos.GetY() = " << scenePos.GetY(); - + CreateLineMeasureTracker* concreteThis = dynamic_cast(this); assert(concreteThis != NULL); - GetCommand()->SetEnd(scenePos); - } - + GetCommand()->SetEnd(scenePos); + } + void CreateLineMeasureTracker::PointerUp(const PointerEvent& e) { // TODO: the current app does not prevent multiple PointerDown AND @@ -72,7 +74,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; + active_ = false; } void CreateLineMeasureTracker::PointerDown(const PointerEvent& e) diff -r 4eccf698e52f -r 462a5074f914 Samples/Common/CreateLineMeasureTracker.h --- a/Samples/Common/CreateLineMeasureTracker.h Tue May 14 13:49:12 2019 +0200 +++ b/Samples/Common/CreateLineMeasureTracker.h Tue May 14 13:51:00 2019 +0200 @@ -35,6 +35,7 @@ must be supplied, too */ CreateLineMeasureTracker( + MessageBroker& broker, Scene2D& scene, std::vector& undoStack, std::vector& measureTools, diff -r 4eccf698e52f -r 462a5074f914 Samples/Common/LineMeasureTool.h --- a/Samples/Common/LineMeasureTool.h Tue May 14 13:49:12 2019 +0200 +++ b/Samples/Common/LineMeasureTool.h Tue May 14 13:51:00 2019 +0200 @@ -38,8 +38,8 @@ class LineMeasureTool : public MeasureTool { public: - LineMeasureTool(Scene2D& scene) - : MeasureTool(scene) + LineMeasureTool(MessageBroker& broker, Scene2D& scene) + : MeasureTool(broker, scene) , layersCreated(false) , polylineZIndex_(-1) , textZIndex_(-1) @@ -68,5 +68,5 @@ }; typedef boost::shared_ptr LineMeasureToolPtr; -} - +} + diff -r 4eccf698e52f -r 462a5074f914 Samples/Common/MeasureCommands.cpp --- a/Samples/Common/MeasureCommands.cpp Tue May 14 13:49:12 2019 +0200 +++ b/Samples/Common/MeasureCommands.cpp Tue May 14 13:51:00 2019 +0200 @@ -48,9 +48,12 @@ } CreateLineMeasureCommand::CreateLineMeasureCommand( - Scene2D& scene, MeasureToolList& measureTools, ScenePoint2D point) + MessageBroker& broker, + Scene2D& scene, + MeasureToolList& measureTools, + ScenePoint2D point) : CreateMeasureCommand(scene, measureTools) - , measureTool_(new LineMeasureTool(scene)) + , measureTool_(new LineMeasureTool(broker,scene)) { measureTools_.push_back(measureTool_); measureTool_->Set(point, point); @@ -62,9 +65,12 @@ } CreateAngleMeasureCommand::CreateAngleMeasureCommand( - Scene2D& scene, MeasureToolList& measureTools, ScenePoint2D point) + MessageBroker& broker, + Scene2D& scene, + MeasureToolList& measureTools, + ScenePoint2D point) : CreateMeasureCommand(scene, measureTools) - , measureTool_(new AngleMeasureTool(scene)) + , measureTool_(new AngleMeasureTool(broker,scene)) { measureTools_.push_back(measureTool_); measureTool_->SetSide1End(point); diff -r 4eccf698e52f -r 462a5074f914 Samples/Common/MeasureCommands.h --- a/Samples/Common/MeasureCommands.h Tue May 14 13:49:12 2019 +0200 +++ b/Samples/Common/MeasureCommands.h Tue May 14 13:51:00 2019 +0200 @@ -77,7 +77,7 @@ { public: CreateLineMeasureCommand( - Scene2D& scene, MeasureToolList& measureTools, ScenePoint2D point); + MessageBroker& broker, Scene2D& scene, MeasureToolList& measureTools, ScenePoint2D point); // the starting position is set in the ctor void SetEnd(ScenePoint2D scenePos); @@ -97,7 +97,7 @@ public: /** Ctor sets end of side 1*/ CreateAngleMeasureCommand( - Scene2D& scene, MeasureToolList& measureTools, ScenePoint2D point); + MessageBroker& broker, Scene2D& scene, MeasureToolList& measureTools, ScenePoint2D point); /** This method sets center*/ void SetCenter(ScenePoint2D scenePos); diff -r 4eccf698e52f -r 462a5074f914 Samples/Common/MeasureTools.cpp --- a/Samples/Common/MeasureTools.cpp Tue May 14 13:49:12 2019 +0200 +++ b/Samples/Common/MeasureTools.cpp Tue May 14 13:51:00 2019 +0200 @@ -26,6 +26,12 @@ namespace OrthancStone { + + MeasureTool::~MeasureTool() + { + + } + void MeasureTool::Enable() { enabled_ = true; @@ -37,5 +43,33 @@ enabled_ = false; RefreshScene(); } + + bool MeasureTool::IsEnabled() const + { + return enabled_; + } + + OrthancStone::Scene2D& MeasureTool::GetScene() + { + return scene_; + } + + MeasureTool::MeasureTool(MessageBroker& broker, Scene2D& scene) + : IObserver(broker) + , scene_(scene) + , enabled_(true) + { + scene_.RegisterObserverCallback( + new Callable + (*this, &MeasureTool::OnSceneTransformChanged)); + } + + void MeasureTool::OnSceneTransformChanged( + const Scene2D::SceneTransformChanged& message) + { + RefreshScene(); + } + + } diff -r 4eccf698e52f -r 462a5074f914 Samples/Common/MeasureTools.h --- a/Samples/Common/MeasureTools.h Tue May 14 13:49:12 2019 +0200 +++ b/Samples/Common/MeasureTools.h Tue May 14 13:51:00 2019 +0200 @@ -33,10 +33,10 @@ namespace OrthancStone { - class MeasureTool + class MeasureTool : public IObserver { public: - virtual ~MeasureTool() {} + virtual ~MeasureTool(); /** Enabled tools are rendered in the scene. @@ -51,15 +51,15 @@ */ void Disable(); + /** + 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); + protected: - MeasureTool(Scene2D& scene) - : scene_(scene) - , enabled_(true) - { - } - - - + MeasureTool(MessageBroker& broker, Scene2D& scene); + /** This is the meat of the tool: this method must [create (if needed) and] update the layers and their data according to the measure tool kind and @@ -67,19 +67,13 @@ */ virtual void RefreshScene() = 0; - Scene2D& GetScene() - { - return scene_; - } + Scene2D& GetScene(); /** enabled_ is not accessible by subclasses because there is a state machine that we do not wanna mess with */ - bool IsEnabled() const - { - return enabled_; - } + bool IsEnabled() const; private: Scene2D& scene_; diff -r 4eccf698e52f -r 462a5074f914 Samples/Common/MeasureToolsToolbox.cpp --- a/Samples/Common/MeasureToolsToolbox.cpp Tue May 14 13:49:12 2019 +0200 +++ b/Samples/Common/MeasureToolsToolbox.cpp Tue May 14 13:51:00 2019 +0200 @@ -43,7 +43,7 @@ chain.clear(); chain.reserve(4); ScenePoint2D centerC = centerS.Apply(scene.GetSceneToCanvasTransform()); - //TODO: take DPI into account + //TODO: take DPI into account double handleLX = centerC.GetX() - sideLength / 2; double handleTY = centerC.GetY() - sideLength / 2; double handleRX = centerC.GetX() + sideLength / 2; diff -r 4eccf698e52f -r 462a5074f914 Samples/Sdl/BasicScene.cpp --- a/Samples/Sdl/BasicScene.cpp Tue May 14 13:49:12 2019 +0200 +++ b/Samples/Sdl/BasicScene.cpp Tue May 14 13:51:00 2019 +0200 @@ -29,6 +29,7 @@ #include "../../Framework/Scene2D/Scene2D.h" #include "../../Framework/Scene2D/ZoomSceneTracker.h" #include "../../Framework/StoneInitialization.h" +#include "../../Framework/Messages/MessageBroker.h" // From Orthanc framework #include @@ -360,7 +361,8 @@ try { - OrthancStone::Scene2D scene; + OrthancStone::MessageBroker broker; + OrthancStone::Scene2D scene(broker); PrepareScene(scene); Run(scene); } diff -r 4eccf698e52f -r 462a5074f914 Samples/Sdl/TrackerSample.cpp --- a/Samples/Sdl/TrackerSample.cpp Tue May 14 13:49:12 2019 +0200 +++ b/Samples/Sdl/TrackerSample.cpp Tue May 14 13:51:00 2019 +0200 @@ -140,7 +140,8 @@ try { - TrackerSampleApp app; + MessageBroker broker; + TrackerSampleApp app(broker); app.PrepareScene(); Run(&app); } diff -r 4eccf698e52f -r 462a5074f914 Samples/Sdl/TrackerSampleApp.cpp --- a/Samples/Sdl/TrackerSampleApp.cpp Tue May 14 13:49:12 2019 +0200 +++ b/Samples/Sdl/TrackerSampleApp.cpp Tue May 14 13:51:00 2019 +0200 @@ -273,10 +273,10 @@ // return new EllipseMeasureTracker(scene_, measureTools_, undoStack_, e); case GuiTool_LineMeasure: return FlexiblePointerTrackerPtr(new CreateLineMeasureTracker( - scene_, undoStack_, measureTools_, e)); + IObserver::GetBroker(), scene_, undoStack_, measureTools_, e)); case GuiTool_AngleMeasure: return FlexiblePointerTrackerPtr(new CreateAngleMeasureTracker( - scene_, undoStack_, measureTools_, e)); + IObserver::GetBroker(), scene_, undoStack_, measureTools_, e)); return NULL; case GuiTool_CircleMeasure: LOG(ERROR) << "Not implemented yet!"; diff -r 4eccf698e52f -r 462a5074f914 Samples/Sdl/TrackerSampleApp.h --- a/Samples/Sdl/TrackerSampleApp.h Tue May 14 13:49:12 2019 +0200 +++ b/Samples/Sdl/TrackerSampleApp.h Tue May 14 13:51:00 2019 +0200 @@ -19,6 +19,7 @@ **/ #include +#include #include "../Common/IFlexiblePointerTracker.h" #include "../Common/MeasureTools.h" @@ -51,11 +52,14 @@ class Scene2D; - class TrackerSampleApp + class TrackerSampleApp : public IObserver { public: // 12 because. - TrackerSampleApp() : currentTool_(GuiTool_Rotate) + TrackerSampleApp(MessageBroker& broker) + : IObserver(broker) + , currentTool_(GuiTool_Rotate) + , scene_(broker) { TEXTURE_2x2_1_ZINDEX = 1; TEXTURE_1x1_ZINDEX = 2; diff -r 4eccf698e52f -r 462a5074f914 Samples/Sdl/cpp.hint --- a/Samples/Sdl/cpp.hint Tue May 14 13:49:12 2019 +0200 +++ b/Samples/Sdl/cpp.hint Tue May 14 13:51:00 2019 +0200 @@ -1,1 +1,2 @@ #define ORTHANC_OVERRIDE +#define ORTHANC_STONE_DEFINE_EMPTY_MESSAGE(FILE, LINE, NAME) class NAME : public ::OrthancStone::IMessage {};