Mercurial > hg > orthanc-stone
changeset 866:c71ef52602a0 toa2019062501
Added the ability to edit existing measuring tools (demo not updated yet)
line wrap: on
line diff
--- a/Framework/Scene2D/ScenePoint2D.h Tue Jun 25 15:24:13 2019 +0200 +++ b/Framework/Scene2D/ScenePoint2D.h Tue Jun 25 17:54:46 2019 +0200 @@ -73,6 +73,15 @@ return v; } + const ScenePoint2D operator+(const ScenePoint2D& a) const + { + ScenePoint2D v; + v.x_ = x_ + a.x_; + v.y_ = y_ + a.y_; + + return v; + } + const ScenePoint2D operator*(double a) const { ScenePoint2D v;
--- a/Framework/Scene2DViewport/AngleMeasureTool.cpp Tue Jun 25 15:24:13 2019 +0200 +++ b/Framework/Scene2DViewport/AngleMeasureTool.cpp Tue Jun 25 17:54:46 2019 +0200 @@ -20,6 +20,7 @@ #include "AngleMeasureTool.h" #include "MeasureToolsToolbox.h" +#include "EditAngleMeasureTracker.h" #include "LayerHolder.h" #include <Core/Logging.h> @@ -90,6 +91,26 @@ SetAngleHighlightArea(AngleHighlightArea_None); } + + boost::shared_ptr<OrthancStone::MeasureToolMemento> AngleMeasureTool::GetMemento() const + { + boost::shared_ptr<AngleMeasureToolMemento> memento(new AngleMeasureToolMemento()); + memento->center_ = center_; + memento->side1End_ = side1End_; + memento->side2End_ = side2End_; + return memento; + } + + void AngleMeasureTool::SetMemento(boost::shared_ptr<MeasureToolMemento> mementoBase) + { + boost::shared_ptr<AngleMeasureToolMemento> memento = boost::dynamic_pointer_cast<AngleMeasureToolMemento>(mementoBase); + ORTHANC_ASSERT(memento.get() != NULL, "Internal error: wrong (or bad) memento"); + center_ = memento->center_; + side1End_ = memento->side1End_; + side2End_ = memento->side2End_; + RefreshScene(); + } + void AngleMeasureTool::Highlight(ScenePoint2D p) { AngleHighlightArea angleHighlightArea = AngleHitTest(p); @@ -140,6 +161,27 @@ return AngleHitTest(p) != AngleHighlightArea_None; } + + boost::shared_ptr<IFlexiblePointerTracker> AngleMeasureTool::CreateEditionTracker(const PointerEvent& e) + { + ScenePoint2D scenePos = e.GetMainPosition().Apply( + GetScene()->GetCanvasToSceneTransform()); + + if (!HitTest(scenePos)) + return boost::shared_ptr<IFlexiblePointerTracker>(); + + /** + new EditLineMeasureTracker( + boost::shared_ptr<LineMeasureTool> measureTool; + MessageBroker & broker, + boost::weak_ptr<ViewportController> controllerW, + const PointerEvent & e); + */ + boost::shared_ptr<EditAngleMeasureTracker> editAngleMeasureTracker( + new EditAngleMeasureTracker(shared_from_this(), GetBroker(), GetController(), e)); + return editAngleMeasureTracker; + } + void AngleMeasureTool::SetCenter(ScenePoint2D pt) { center_ = pt;
--- a/Framework/Scene2DViewport/AngleMeasureTool.h Tue Jun 25 15:24:13 2019 +0200 +++ b/Framework/Scene2DViewport/AngleMeasureTool.h Tue Jun 25 17:54:46 2019 +0200 @@ -30,13 +30,14 @@ #include <boost/shared_ptr.hpp> #include <boost/weak_ptr.hpp> +#include <boost/enable_shared_from_this.hpp> #include <vector> #include <cmath> namespace OrthancStone { - class AngleMeasureTool : public MeasureTool + class AngleMeasureTool : public MeasureTool, public boost::enable_shared_from_this<AngleMeasureTool> { public: AngleMeasureTool(MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW); @@ -50,6 +51,9 @@ virtual bool HitTest(ScenePoint2D p) const ORTHANC_OVERRIDE; virtual void Highlight(ScenePoint2D p) ORTHANC_OVERRIDE; virtual void ResetHighlightState() ORTHANC_OVERRIDE; + virtual boost::shared_ptr<IFlexiblePointerTracker> CreateEditionTracker(const PointerEvent& e) ORTHANC_OVERRIDE; + virtual boost::shared_ptr<MeasureToolMemento> GetMemento() const ORTHANC_OVERRIDE; + virtual void SetMemento(boost::shared_ptr<MeasureToolMemento>) ORTHANC_OVERRIDE; enum AngleHighlightArea { @@ -76,6 +80,14 @@ boost::shared_ptr<LayerHolder> layerHolder_; AngleHighlightArea angleHighlightArea_; }; + + class AngleMeasureToolMemento : public MeasureToolMemento + { + public: + ScenePoint2D side1End_; + ScenePoint2D side2End_; + ScenePoint2D center_; + }; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Scene2DViewport/EditAngleMeasureTracker.cpp Tue Jun 25 17:54:46 2019 +0200 @@ -0,0 +1,112 @@ +/** + * 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 "EditAngleMeasureTracker.h" + +namespace OrthancStone +{ + EditAngleMeasureTracker::EditAngleMeasureTracker( + boost::shared_ptr<AngleMeasureTool> measureTool, + MessageBroker& broker, + boost::weak_ptr<ViewportController> controllerW, + const PointerEvent& e) + : EditMeasureTracker(controllerW, e) + { + ScenePoint2D scenePos = e.GetMainPosition().Apply( + GetScene()->GetCanvasToSceneTransform()); + + modifiedZone_ = measureTool->AngleHitTest(scenePos); + + command_.reset(new EditAngleMeasureCommand(measureTool, broker, controllerW)); + } + + EditAngleMeasureTracker::~EditAngleMeasureTracker() + { + + } + + void EditAngleMeasureTracker::PointerMove(const PointerEvent& e) + { + ScenePoint2D scenePos = e.GetMainPosition().Apply( + GetScene()->GetCanvasToSceneTransform()); + + ScenePoint2D delta = scenePos - GetOriginalClickPosition(); + + boost::shared_ptr<AngleMeasureToolMemento> memento = + boost::dynamic_pointer_cast<AngleMeasureToolMemento>(command_->mementoOriginal_); + + ORTHANC_ASSERT(memento.get() != NULL); + + switch (modifiedZone_) + { + case AngleMeasureTool::AngleHighlightArea_Center: + { + ScenePoint2D newCenter = memento->center_ + delta; + GetCommand()->SetCenter(newCenter); + } + break; + case AngleMeasureTool::AngleHighlightArea_Side1: + case AngleMeasureTool::AngleHighlightArea_Side2: + { + ScenePoint2D newCenter = memento->center_ + delta; + ScenePoint2D newSide1End = memento->side1End_ + delta; + ScenePoint2D newSide2End = memento->side2End_ + delta; + GetCommand()->SetCenter(newCenter); + GetCommand()->SetSide1End(newSide1End); + GetCommand()->SetSide2End(newSide2End); + } + break; + case AngleMeasureTool::AngleHighlightArea_Side1End: + { + ScenePoint2D newSide1End = memento->side1End_ + delta; + GetCommand()->SetSide1End(newSide1End); + } + break; + case AngleMeasureTool::AngleHighlightArea_Side2End: + { + ScenePoint2D newSide2End = memento->side2End_ + delta; + GetCommand()->SetSide2End(newSide2End); + } + break; + default: + LOG(WARN) << "Warning: please retry the measuring tool editing operation!"; + break; + } + } + + void EditAngleMeasureTracker::PointerUp(const PointerEvent& e) + { + alive_ = false; + } + + void EditAngleMeasureTracker::PointerDown(const PointerEvent& e) + { + LOG(WARNING) << "Additional touches (fingers, pen, mouse buttons...) " + "are ignored when the edit angle tracker is active"; + } + + boost::shared_ptr<EditAngleMeasureCommand> EditAngleMeasureTracker::GetCommand() + { + boost::shared_ptr<EditAngleMeasureCommand> ret = boost::dynamic_pointer_cast<EditAngleMeasureCommand>(command_); + ORTHANC_ASSERT(ret.get() != NULL, "Internal error in EditAngleMeasureTracker::GetCommand()"); + return ret; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Scene2DViewport/EditAngleMeasureTracker.h Tue Jun 25 17:54:46 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/>. + **/ + +#pragma once + +#include "MeasureTrackers.h" + +namespace OrthancStone +{ + class EditAngleMeasureTracker : public EditMeasureTracker + { + public: + /** + When you create this tracker, you need to supply it with the undo stack + where it will store the commands that perform the actual measure tool + creation and modification. + In turn, a container for these commands to store the actual measuring + must be supplied, too + */ + EditAngleMeasureTracker( + boost::shared_ptr<AngleMeasureTool> measureTool, + MessageBroker& broker, + boost::weak_ptr<ViewportController> controllerW, + const PointerEvent& e); + + ~EditAngleMeasureTracker(); + + virtual void PointerMove(const PointerEvent& e) ORTHANC_OVERRIDE; + virtual void PointerUp(const PointerEvent& e) ORTHANC_OVERRIDE; + virtual void PointerDown(const PointerEvent& e) ORTHANC_OVERRIDE; + + private: + AngleMeasureTool::AngleHighlightArea modifiedZone_; + + boost::shared_ptr<EditAngleMeasureCommand> GetCommand(); + }; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Scene2DViewport/EditLineMeasureTracker.cpp Tue Jun 25 17:54:46 2019 +0200 @@ -0,0 +1,107 @@ +/** + * 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 "EditLineMeasureTracker.h" + +namespace OrthancStone +{ + EditLineMeasureTracker::EditLineMeasureTracker( + boost::shared_ptr<LineMeasureTool> measureTool, + MessageBroker& broker, + boost::weak_ptr<ViewportController> controllerW, + const PointerEvent& e) + : EditMeasureTracker(controllerW, e) + { + ScenePoint2D scenePos = e.GetMainPosition().Apply( + GetScene()->GetCanvasToSceneTransform()); + + modifiedZone_ = measureTool->LineHitTest(scenePos); + + command_.reset( + new EditLineMeasureCommand( + measureTool, + broker, + controllerW)); + } + + EditLineMeasureTracker::~EditLineMeasureTracker() + { + + } + + void EditLineMeasureTracker::PointerMove(const PointerEvent& e) + { + ScenePoint2D scenePos = e.GetMainPosition().Apply( + GetScene()->GetCanvasToSceneTransform()); + + ScenePoint2D delta = scenePos - GetOriginalClickPosition(); + + boost::shared_ptr<LineMeasureToolMemento> memento = + boost::dynamic_pointer_cast<LineMeasureToolMemento>(command_->mementoOriginal_); + + ORTHANC_ASSERT(memento.get() != NULL); + + switch (modifiedZone_) + { + case LineMeasureTool::LineHighlightArea_Start: + { + ScenePoint2D newStart = memento->start_ + delta; + GetCommand()->SetStart(newStart); + } + break; + case LineMeasureTool::LineHighlightArea_End: + { + ScenePoint2D newEnd = memento->end_ + delta; + GetCommand()->SetEnd(newEnd); + } + break; + case LineMeasureTool::LineHighlightArea_Segment: + { + ScenePoint2D newStart = memento->start_ + delta; + ScenePoint2D newEnd = memento->end_ + delta; + GetCommand()->SetStart(newStart); + GetCommand()->SetEnd(newEnd); + } + break; + default: + LOG(WARN) << "Warning: please retry the measuring tool editing operation!"; + break; + } + } + + void EditLineMeasureTracker::PointerUp(const PointerEvent& e) + { + alive_ = false; + } + + void EditLineMeasureTracker::PointerDown(const PointerEvent& e) + { + LOG(WARNING) << "Additional touches (fingers, pen, mouse buttons...) " + "are ignored when the edit line tracker is active"; + } + + boost::shared_ptr<EditLineMeasureCommand> EditLineMeasureTracker::GetCommand() + { + boost::shared_ptr<EditLineMeasureCommand> ret = boost::dynamic_pointer_cast<EditLineMeasureCommand>(command_); + ORTHANC_ASSERT(ret.get() != NULL, "Internal error in EditLineMeasureTracker::GetCommand()"); + return ret; + } + +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Scene2DViewport/EditLineMeasureTracker.h Tue Jun 25 17:54:46 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/>. + **/ + +#pragma once + +#include "MeasureTrackers.h" + +namespace OrthancStone +{ + class EditLineMeasureTracker : public EditMeasureTracker + { + public: + /** + When you create this tracker, you need to supply it with the undo stack + where it will store the commands that perform the actual measure tool + creation and modification. + In turn, a container for these commands to store the actual measuring + must be supplied, too + */ + EditLineMeasureTracker( + boost::shared_ptr<LineMeasureTool> measureTool, + MessageBroker& broker, + boost::weak_ptr<ViewportController> controllerW, + const PointerEvent& e); + + ~EditLineMeasureTracker(); + + virtual void PointerMove(const PointerEvent& e) ORTHANC_OVERRIDE; + virtual void PointerUp(const PointerEvent& e) ORTHANC_OVERRIDE; + virtual void PointerDown(const PointerEvent& e) ORTHANC_OVERRIDE; + + private: + LineMeasureTool::LineHighlightArea modifiedZone_; + + boost::shared_ptr<EditLineMeasureCommand> GetCommand(); + }; +}
--- a/Framework/Scene2DViewport/LineMeasureTool.cpp Tue Jun 25 15:24:13 2019 +0200 +++ b/Framework/Scene2DViewport/LineMeasureTool.cpp Tue Jun 25 17:54:46 2019 +0200 @@ -20,6 +20,7 @@ #include "LineMeasureTool.h" #include "MeasureToolsToolbox.h" +#include "EditLineMeasureTracker.h" #include "LayerHolder.h" #include <Core/Logging.h> @@ -119,6 +120,44 @@ return LineHitTest(p) != LineHighlightArea_None; } + boost::shared_ptr<IFlexiblePointerTracker> LineMeasureTool::CreateEditionTracker(const PointerEvent& e) + { + ScenePoint2D scenePos = e.GetMainPosition().Apply( + GetScene()->GetCanvasToSceneTransform()); + + if (!HitTest(scenePos)) + return boost::shared_ptr<IFlexiblePointerTracker>(); + + /** + new EditLineMeasureTracker( + boost::shared_ptr<LineMeasureTool> measureTool; + MessageBroker & broker, + boost::weak_ptr<ViewportController> controllerW, + const PointerEvent & e); + */ + boost::shared_ptr<EditLineMeasureTracker> editLineMeasureTracker( + new EditLineMeasureTracker(shared_from_this(), GetBroker(), GetController(), e)); + return editLineMeasureTracker; + } + + + boost::shared_ptr<MeasureToolMemento> LineMeasureTool::GetMemento() const + { + boost::shared_ptr<LineMeasureToolMemento> memento(new LineMeasureToolMemento()); + memento->start_ = start_; + memento->end_ = end_; + return memento; + } + + void LineMeasureTool::SetMemento(boost::shared_ptr<MeasureToolMemento> mementoBase) + { + boost::shared_ptr<LineMeasureToolMemento> memento = boost::dynamic_pointer_cast<LineMeasureToolMemento>(mementoBase); + ORTHANC_ASSERT(memento.get() != NULL, "Internal error: wrong (or bad) memento"); + start_ = memento->start_; + end_ = memento->end_; + RefreshScene(); + } + void LineMeasureTool::RefreshScene() { if (IsSceneAlive())
--- a/Framework/Scene2DViewport/LineMeasureTool.h Tue Jun 25 15:24:13 2019 +0200 +++ b/Framework/Scene2DViewport/LineMeasureTool.h Tue Jun 25 17:54:46 2019 +0200 @@ -28,13 +28,14 @@ #include <boost/shared_ptr.hpp> #include <boost/weak_ptr.hpp> +#include <boost/enable_shared_from_this.hpp> #include <vector> #include <cmath> namespace OrthancStone { - class LineMeasureTool : public MeasureTool + class LineMeasureTool : public MeasureTool, public boost::enable_shared_from_this<LineMeasureTool> { public: LineMeasureTool(MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW); @@ -49,6 +50,9 @@ virtual bool HitTest(ScenePoint2D p) const ORTHANC_OVERRIDE; virtual void Highlight(ScenePoint2D p) ORTHANC_OVERRIDE; virtual void ResetHighlightState() ORTHANC_OVERRIDE; + virtual boost::shared_ptr<IFlexiblePointerTracker> CreateEditionTracker(const PointerEvent& e) ORTHANC_OVERRIDE; + virtual boost::shared_ptr<MeasureToolMemento> GetMemento() const ORTHANC_OVERRIDE; + virtual void SetMemento(boost::shared_ptr<MeasureToolMemento>) ORTHANC_OVERRIDE; enum LineHighlightArea { @@ -76,5 +80,12 @@ LineHighlightArea lineHighlightArea_; }; + class LineMeasureToolMemento : public MeasureToolMemento + { + public: + ScenePoint2D start_; + ScenePoint2D end_; + }; + }
--- a/Framework/Scene2DViewport/MeasureCommands.cpp Tue Jun 25 15:24:13 2019 +0200 +++ b/Framework/Scene2DViewport/MeasureCommands.cpp Tue Jun 25 17:54:46 2019 +0200 @@ -50,6 +50,30 @@ // we thus leave it as is } + EditMeasureCommand::EditMeasureCommand(boost::shared_ptr<MeasureTool> measureTool, boost::weak_ptr<ViewportController> controllerW) + : TrackerCommand(controllerW) + , mementoOriginal_(measureTool->GetMemento()) + , mementoModified_(measureTool->GetMemento()) + { + + } + + EditMeasureCommand::~EditMeasureCommand() + { + + } + + void EditMeasureCommand::Undo() + { + // simply disable the measure tool upon undo + GetMeasureTool()->SetMemento(mementoOriginal_); + } + + void EditMeasureCommand::Redo() + { + GetMeasureTool()->SetMemento(mementoModified_); + } + CreateLineMeasureCommand::CreateLineMeasureCommand( MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW, @@ -67,6 +91,29 @@ measureTool_->SetEnd(scenePos); } + EditLineMeasureCommand::EditLineMeasureCommand( + boost::shared_ptr<LineMeasureTool> measureTool, + MessageBroker& broker, + boost::weak_ptr<ViewportController> controllerW) + : EditMeasureCommand(measureTool,controllerW) + , measureTool_(measureTool) + { + } + + + void EditLineMeasureCommand::SetStart(ScenePoint2D scenePos) + { + measureTool_->SetStart(scenePos); + mementoModified_ = measureTool_->GetMemento(); + } + + + void EditLineMeasureCommand::SetEnd(ScenePoint2D scenePos) + { + measureTool_->SetEnd(scenePos); + mementoModified_ = measureTool_->GetMemento(); + } + CreateAngleMeasureCommand::CreateAngleMeasureCommand( MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW, @@ -99,4 +146,34 @@ assert(controller); // accessing dead object? return controller; } + + EditAngleMeasureCommand::EditAngleMeasureCommand( + boost::shared_ptr<AngleMeasureTool> measureTool, + MessageBroker& broker, + boost::weak_ptr<ViewportController> controllerW) + : EditMeasureCommand(measureTool, controllerW) + , measureTool_(measureTool) + { + } + + void EditAngleMeasureCommand::SetCenter(ScenePoint2D scenePos) + { + measureTool_->SetCenter(scenePos); + mementoModified_ = measureTool_->GetMemento(); + } + + + void EditAngleMeasureCommand::SetSide1End(ScenePoint2D scenePos) + { + measureTool_->SetSide1End(scenePos); + mementoModified_ = measureTool_->GetMemento(); + } + + + void EditAngleMeasureCommand::SetSide2End(ScenePoint2D scenePos) + { + measureTool_->SetSide2End(scenePos); + mementoModified_ = measureTool_->GetMemento(); + } + }
--- a/Framework/Scene2DViewport/MeasureCommands.h Tue Jun 25 15:24:13 2019 +0200 +++ b/Framework/Scene2DViewport/MeasureCommands.h Tue Jun 25 17:54:46 2019 +0200 @@ -42,6 +42,8 @@ } virtual void Undo() = 0; virtual void Redo() = 0; + + virtual ~TrackerCommand() {}; protected: boost::shared_ptr<ViewportController> GetController(); @@ -52,7 +54,7 @@ { public: CreateMeasureCommand(boost::weak_ptr<ViewportController> controllerW); - ~CreateMeasureCommand(); + virtual ~CreateMeasureCommand(); virtual void Undo() ORTHANC_OVERRIDE; virtual void Redo() ORTHANC_OVERRIDE; private: @@ -60,6 +62,27 @@ virtual boost::shared_ptr<MeasureTool> GetMeasureTool() = 0; }; + class EditMeasureCommand : public TrackerCommand + { + public: + EditMeasureCommand(boost::shared_ptr<MeasureTool> measureTool, boost::weak_ptr<ViewportController> controllerW); + virtual ~EditMeasureCommand(); + virtual void Undo() ORTHANC_OVERRIDE; + virtual void Redo() ORTHANC_OVERRIDE; + + /** This memento is the original object state */ + boost::shared_ptr<MeasureToolMemento> mementoOriginal_; + + private: + /** Must be implemented by the subclasses that edit the actual tool */ + virtual boost::shared_ptr<MeasureTool> GetMeasureTool() = 0; + + protected: + + /** This memento is updated by the subclasses upon modifications */ + boost::shared_ptr<MeasureToolMemento> mementoModified_; + }; + class CreateLineMeasureCommand : public CreateMeasureCommand { public: @@ -80,6 +103,26 @@ }; + class EditLineMeasureCommand : public EditMeasureCommand + { + public: + EditLineMeasureCommand( + boost::shared_ptr<LineMeasureTool> measureTool, + MessageBroker& broker, + boost::weak_ptr<ViewportController> controllerW); + + void SetStart(ScenePoint2D scenePos); + void SetEnd(ScenePoint2D scenePos); + + private: + virtual boost::shared_ptr<MeasureTool> GetMeasureTool() ORTHANC_OVERRIDE + { + return measureTool_; + } + boost::shared_ptr<LineMeasureTool> measureTool_; + }; + + class CreateAngleMeasureCommand : public CreateMeasureCommand { public: @@ -103,5 +146,31 @@ boost::shared_ptr<AngleMeasureTool> measureTool_; }; + class EditAngleMeasureCommand : public EditMeasureCommand + { + public: + /** Ctor sets end of side 1*/ + EditAngleMeasureCommand( + boost::shared_ptr<AngleMeasureTool> measureTool, + MessageBroker& broker, + boost::weak_ptr<ViewportController> controllerW); + + /** This method sets center*/ + void SetCenter(ScenePoint2D scenePos); + + /** This method sets end of side 1*/ + void SetSide1End(ScenePoint2D scenePos); + + /** This method sets end of side 2*/ + void SetSide2End(ScenePoint2D scenePos); + + private: + virtual boost::shared_ptr<MeasureTool> GetMeasureTool() ORTHANC_OVERRIDE + { + return measureTool_; + } + boost::shared_ptr<AngleMeasureTool> measureTool_; + }; + }
--- a/Framework/Scene2DViewport/MeasureTool.h Tue Jun 25 15:24:13 2019 +0200 +++ b/Framework/Scene2DViewport/MeasureTool.h Tue Jun 25 17:54:46 2019 +0200 @@ -35,6 +35,9 @@ namespace OrthancStone { + class IFlexiblePointerTracker; + class MeasureToolMemento; + class MeasureTool : public IObserver { public: @@ -73,6 +76,25 @@ virtual bool HitTest(ScenePoint2D p) const = 0; /** + This method must return a memento the captures the tool state (not including + the highlighting state + */ + virtual boost::shared_ptr<MeasureToolMemento> GetMemento() const = 0; + + /** + This method must apply the supplied memento (this requires RTTI to check + the type) + */ + virtual void SetMemento(boost::shared_ptr<MeasureToolMemento>) = 0; + + /** + This must create an edition tracker suitable for the supplied click position, + or an empty pointer if no hit test (although this should have been checked + first) + */ + virtual boost::shared_ptr<IFlexiblePointerTracker> CreateEditionTracker(const PointerEvent& e) = 0; + + /** Will change the measuring tool to provide visual feedback on the GUI element that is in the pointer hit zone */ @@ -116,6 +138,13 @@ boost::weak_ptr<ViewportController> controllerW_; bool enabled_; }; + + class MeasureToolMemento + { + public: + virtual ~MeasureToolMemento() {}; + }; + } extern void TrackerSample_SetInfoDisplayMessage(
--- a/Framework/Scene2DViewport/MeasureTrackers.cpp Tue Jun 25 15:24:13 2019 +0200 +++ b/Framework/Scene2DViewport/MeasureTrackers.cpp Tue Jun 25 17:54:46 2019 +0200 @@ -46,7 +46,6 @@ { // if the tracker completes successfully, we add the command // to the undo stack - // otherwise, we simply undo it if (commitResult_) controllerW_.lock()->PushCommand(command_); @@ -59,6 +58,41 @@ return controllerW_.lock()->GetScene(); } + EditMeasureTracker::EditMeasureTracker(boost::weak_ptr<ViewportController> controllerW, const PointerEvent& e) + : controllerW_(controllerW) + , alive_(true) + , commitResult_(true) + { + boost::shared_ptr<ViewportController> controller = controllerW.lock(); + originalClickPosition_ = e.GetMainPosition().Apply(controller->GetScene()->GetCanvasToSceneTransform()); + } + + boost::shared_ptr<Scene2D> EditMeasureTracker::GetScene() + { + return controllerW_.lock()->GetScene(); + } + + void EditMeasureTracker::Cancel() + { + commitResult_ = false; + alive_ = false; + } + + bool EditMeasureTracker::IsAlive() const + { + return alive_; + } + + EditMeasureTracker::~EditMeasureTracker() + { + // if the tracker completes successfully, we add the command + // to the undo stack + // otherwise, we simply undo it + if (commitResult_) + controllerW_.lock()->PushCommand(command_); + else + command_->Undo(); + } }
--- a/Framework/Scene2DViewport/MeasureTrackers.h Tue Jun 25 15:24:13 2019 +0200 +++ b/Framework/Scene2DViewport/MeasureTrackers.h Tue Jun 25 17:54:46 2019 +0200 @@ -50,5 +50,30 @@ private: bool commitResult_; }; + + class EditMeasureTracker : public IFlexiblePointerTracker + { + public: + virtual void Cancel() ORTHANC_OVERRIDE; + virtual bool IsAlive() const ORTHANC_OVERRIDE; + protected: + EditMeasureTracker(boost::weak_ptr<ViewportController> controllerW, const PointerEvent& e); + + ~EditMeasureTracker(); + + protected: + boost::shared_ptr<EditMeasureCommand> command_; + boost::weak_ptr<ViewportController> controllerW_; + bool alive_; + boost::shared_ptr<Scene2D> GetScene(); + + ScenePoint2D GetOriginalClickPosition() const + { + return originalClickPosition_; + } + private: + ScenePoint2D originalClickPosition_; + bool commitResult_; + }; }
--- a/Resources/CMake/OrthancStoneConfiguration.cmake Tue Jun 25 15:24:13 2019 +0200 +++ b/Resources/CMake/OrthancStoneConfiguration.cmake Tue Jun 25 17:54:46 2019 +0200 @@ -474,6 +474,14 @@ ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/CreateMeasureTracker.cpp ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/CreateMeasureTracker.h ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/CreateSimpleTrackerAdapter.cpp + ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/EditAngleMeasureCommand.cpp + ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/EditAngleMeasureCommand.h + ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/EditAngleMeasureTracker.cpp + ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/EditAngleMeasureTracker.h + ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/EditLineMeasureCommand.cpp + ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/EditLineMeasureCommand.h + ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/EditLineMeasureTracker.cpp + ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/EditLineMeasureTracker.h ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/IFlexiblePointerTracker.h ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/LayerHolder.cpp ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/LayerHolder.h