Mercurial > hg > orthanc-stone
changeset 644:f939f449482c
Ongoing tracker work.
line wrap: on
line diff
--- a/Framework/Scene2D/IPointerTracker.h Thu May 09 14:54:12 2019 +0200 +++ b/Framework/Scene2D/IPointerTracker.h Fri May 10 16:15:55 2019 +0200 @@ -38,8 +38,8 @@ virtual void Update(const PointerEvent& event) = 0; /** - This method will be called if the tracker is to be abandoned without - committing its result + This method will be called when the tracker should commit its result + before being destroyed. */ virtual void Release() = 0; };
--- a/Framework/Scene2D/Scene2D.cpp Thu May 09 14:54:12 2019 +0200 +++ b/Framework/Scene2D/Scene2D.cpp Fri May 10 16:15:55 2019 +0200 @@ -102,8 +102,8 @@ void Scene2D::SetLayer(int depth, ISceneLayer* layer) // Takes ownership { - LOG(INFO) << "SetLayer(" << depth << ", " << - reinterpret_cast<intptr_t>(layer) << ")"; + //LOG(INFO) << "SetLayer(" << depth << ", " << + // reinterpret_cast<intptr_t>(layer) << ")"; std::auto_ptr<Item> item(new Item(layer, layerCounter_++)); if (layer == NULL)
--- a/README.md Thu May 09 14:54:12 2019 +0200 +++ b/README.md Fri May 10 16:15:55 2019 +0200 @@ -244,3 +244,14 @@ ``` cmake -G "Visual Studio 15 2017 Win64" -DMSVC_MULTIPLE_PROCESSES=ON -DENABLE_OPENGL=ON -DSTATIC_BUILD=ON -DOPENSSL_NO_CAPIENG=ON -DORTHANC_FRAMEWORK_SOURCE=path -DORTHANC_FRAMEWORK_ROOT="$($pwd)\..\orthanc" -DALLOW_DOWNLOADS=ON -DENABLE_SDL=ON ../orthanc-stone/Samples/Sdl ``` + +And under Ubuntu (note the /mnt/c/osi/dev/orthanc folder): +``` +cmake -G "Ninja" -DENABLE_OPENGL=ON -DSTATIC_BUILD=OFF -DOPENSSL_NO_CAPIENG=ON -DORTHANC_FRAMEWORK_SOURCE=path -DORTHANC_FRAMEWORK_ROOT="/mnt/c/osi/dev/orthanc" -DALLOW_DOWNLOADS=ON -DENABLE_SDL=ON ../orthanc-stone/Samples/Sdl +``` + +TODO trackers: +- text overlay 50% --> ColorTextureLayer 50% +- angle tracker: draw arcs + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Samples/Common/CreateAngleMeasureTracker.cpp Fri May 10 16:15:55 2019 +0200 @@ -0,0 +1,23 @@ +/** + * 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/>. + **/ + +namespace OrthancStone +{ +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Samples/Common/CreateAngleMeasureTracker.h Fri May 10 16:15:55 2019 +0200 @@ -0,0 +1,25 @@ +/** + * 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 + +namespace OrthancStone +{ +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Samples/Common/CreateCircleMeasureTracker.cpp Fri May 10 16:15:55 2019 +0200 @@ -0,0 +1,23 @@ +/** + * 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/>. + **/ + +namespace OrthancStone +{ +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Samples/Common/CreateCircleMeasureTracker.h Fri May 10 16:15:55 2019 +0200 @@ -0,0 +1,25 @@ +/** + * 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 + +namespace OrthancStone +{ +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Samples/Common/CreateLineMeasureTracker.cpp Fri May 10 16:15:55 2019 +0200 @@ -0,0 +1,83 @@ +/** + * 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 "CreateLineMeasureTracker.h" +#include <Core/OrthancException.h> + +using namespace Orthanc; + +namespace OrthancStone +{ + CreateLineMeasureTracker::CreateLineMeasureTracker( + Scene2D& scene, + std::vector<TrackerCommandPtr>& undoStack, + std::vector<MeasureToolPtr>& measureTools, + const PointerEvent& e) + : CreateMeasureTracker(scene, undoStack, measureTools) + { + command_.reset( + new CreateLineMeasureCommand( + scene, + measureTools, + 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()); + + //LOG(TRACE) << "scenePos.GetX() = " << scenePos.GetX() << " " << + // "scenePos.GetY() = " << scenePos.GetY(); + + CreateLineMeasureTracker* concreteThis = + dynamic_cast<CreateLineMeasureTracker*>(this); + assert(concreteThis != NULL); + command_->Update(scenePos); + } + + void CreateLineMeasureTracker::PointerUp(const PointerEvent& e) + { + // TODO: the current app does not prevent multiple PointerDown AND + // PointerUp to be sent to the tracker. + // 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; + } + + void CreateLineMeasureTracker::PointerDown(const PointerEvent& e) + { + LOG(WARNING) << "Additional touches (fingers, pen, mouse buttons...) " + "are ignored when the line measure creation tracker is active"; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Samples/Common/CreateLineMeasureTracker.h Fri May 10 16:15:55 2019 +0200 @@ -0,0 +1,49 @@ +/** + * 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 CreateLineMeasureTracker : public CreateMeasureTracker + { + 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 + */ + CreateLineMeasureTracker( + Scene2D& scene, + std::vector<TrackerCommandPtr>& undoStack, + std::vector<MeasureToolPtr>& measureTools, + const PointerEvent& e); + + ~CreateLineMeasureTracker(); + + virtual void PointerMove(const PointerEvent& e) ORTHANC_OVERRIDE; + virtual void PointerUp(const PointerEvent& e) ORTHANC_OVERRIDE; + virtual void PointerDown(const PointerEvent& e) ORTHANC_OVERRIDE; + }; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Samples/Common/CreateMeasureTracker.cpp Fri May 10 16:15:55 2019 +0200 @@ -0,0 +1,20 @@ +/** + * 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/>. + **/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Samples/Common/CreateMeasureTracker.h Fri May 10 16:15:55 2019 +0200 @@ -0,0 +1,22 @@ +/** + * 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 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Samples/Common/CreateSimpleTrackerAdapter.cpp Fri May 10 16:15:55 2019 +0200 @@ -0,0 +1,77 @@ +/** + * 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 "IFlexiblePointerTracker.h" +#include <Framework/Scene2D/IPointerTracker.h> + + +namespace OrthancStone +{ + namespace + { + class SimpleTrackerAdapter : public IFlexiblePointerTracker + { + public: + SimpleTrackerAdapter(PointerTrackerPtr wrappedTracker) + : wrappedTracker_(wrappedTracker) + , active_(true) + { + } + + virtual void PointerMove(const PointerEvent& event) ORTHANC_OVERRIDE + { + if(active_) + wrappedTracker_->Update(event); + }; + virtual void PointerUp(const PointerEvent& event) ORTHANC_OVERRIDE + { + if (wrappedTracker_) + { + wrappedTracker_->Release(); + wrappedTracker_ = NULL; + } + active_ = false; + } + virtual void PointerDown(const PointerEvent& event) ORTHANC_OVERRIDE + { + // nothing to do atm + } + virtual bool IsActive() const ORTHANC_OVERRIDE + { + return active_; + } + + virtual void Cancel() ORTHANC_OVERRIDE + { + wrappedTracker_ = NULL; + active_ = false; + } + + private: + PointerTrackerPtr wrappedTracker_; + bool active_; + }; + } + + FlexiblePointerTrackerPtr CreateSimpleTrackerAdapter(PointerTrackerPtr t) + { + return FlexiblePointerTrackerPtr(new SimpleTrackerAdapter(t)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Samples/Common/EditAngleMeasureTracker.cpp Fri May 10 16:15:55 2019 +0200 @@ -0,0 +1,23 @@ +/** + * 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/>. + **/ + +namespace OrthancStone +{ +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Samples/Common/EditAngleMeasureTracker.h Fri May 10 16:15:55 2019 +0200 @@ -0,0 +1,25 @@ +/** + * 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 + +namespace OrthancStone +{ +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Samples/Common/EditCircleMeasureTracker.cpp Fri May 10 16:15:55 2019 +0200 @@ -0,0 +1,23 @@ +/** + * 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/>. + **/ + +namespace OrthancStone +{ +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Samples/Common/EditCircleMeasureTracker.h Fri May 10 16:15:55 2019 +0200 @@ -0,0 +1,25 @@ +/** + * 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 + +namespace OrthancStone +{ +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Samples/Common/EditLineMeasureTracker.cpp Fri May 10 16:15:55 2019 +0200 @@ -0,0 +1,23 @@ +/** + * 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/>. + **/ + +namespace OrthancStone +{ +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Samples/Common/EditLineMeasureTracker.h Fri May 10 16:15:55 2019 +0200 @@ -0,0 +1,25 @@ +/** + * 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 + +namespace OrthancStone +{ +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Samples/Common/IFlexiblePointerTracker.h Fri May 10 16:15:55 2019 +0200 @@ -0,0 +1,84 @@ +/** + * 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 <Framework/Scene2D/PointerEvent.h> +#include <boost/shared_ptr.hpp> + +namespace OrthancStone +{ + class IPointerTracker; + typedef boost::shared_ptr<IPointerTracker> PointerTrackerPtr; + + /** + This interface represents a flexible mouse tracker that can respond to + several events and is not automatically deleted upon mouse up or when touch + interaction is suspended : for instance, a stateful tracker with a two-step + interaction like: click & drag --> mouse up --> drag --> mouse click + (for instance, for an angle measuring tracker or an ellipse tracker) + */ + class IFlexiblePointerTracker : public boost::noncopyable + { + public: + virtual ~IFlexiblePointerTracker() {} + + /** + This method will be repeatedly called during user interaction + */ + virtual void PointerMove(const PointerEvent& event) = 0; + + /** + This method will be called when a touch/pointer is removed (mouse up, + pen lift, finger removed...) + */ + virtual void PointerUp(const PointerEvent& event) = 0; + + /** + This method will be called when a touch/pointer is added (mouse down, + pen or finger press) + */ + virtual void PointerDown(const PointerEvent& event) = 0; + + /** + This method will be repeatedly called by the tracker owner (for instance, + 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; + + /** + This will be called if the tracker needs to be dismissed without committing + its changes to the underlying model. If the model has been modified during + tracker lifetime, it must be restored to its initial value + */ + virtual void Cancel() = 0; + }; + + typedef boost::shared_ptr<IFlexiblePointerTracker> FlexiblePointerTrackerPtr; + + /** + This factory adopts the supplied simple tracker and creates a flexible + tracker wrapper around it. + */ + FlexiblePointerTrackerPtr CreateSimpleTrackerAdapter(PointerTrackerPtr); +} +
--- a/Samples/Common/MeasureCommands.cpp Thu May 09 14:54:12 2019 +0200 +++ b/Samples/Common/MeasureCommands.cpp Fri May 10 16:15:55 2019 +0200 @@ -62,4 +62,5 @@ measureTool_->SetEnd(scenePos); } + }
--- a/Samples/Common/MeasureCommands.h Thu May 09 14:54:12 2019 +0200 +++ b/Samples/Common/MeasureCommands.h Fri May 10 16:15:55 2019 +0200 @@ -71,7 +71,7 @@ class CreateLineMeasureCommand : public CreateMeasureCommand { public: - CreateLineMeasureCommand::CreateLineMeasureCommand( + CreateLineMeasureCommand( Scene2D& scene, MeasureToolList& measureTools, ScenePoint2D point); void Update(ScenePoint2D scenePos) ORTHANC_OVERRIDE;
--- a/Samples/Common/MeasureTools.cpp Thu May 09 14:54:12 2019 +0200 +++ b/Samples/Common/MeasureTools.cpp Fri May 10 16:15:55 2019 +0200 @@ -20,6 +20,7 @@ #include <Core/Logging.h> #include "MeasureTools.h" +#include <boost/math/constants/constants.hpp> namespace OrthancStone { @@ -92,6 +93,107 @@ return concreteLayer; } + namespace + { + /** + This function will create a square around the center point supplied in + scene coordinates, with a side length given in canvas coordinates. The + square sides are parallel to the canvas boundaries. + */ + void AddSquare(PolylineSceneLayer::Chain& chain, + const Scene2D& scene, + const ScenePoint2D& centerS, + const double& sideLength) + { + chain.clear(); + chain.reserve(4); + ScenePoint2D centerC = centerS.Apply(scene.GetSceneToCanvasTransform()); + //TODO: take DPI into account + double handleLX = centerC.GetX() - sideLength / 2; + double handleTY = centerC.GetY() - sideLength / 2; + double handleRX = centerC.GetX() + sideLength / 2; + double handleBY = centerC.GetY() + sideLength / 2; + ScenePoint2D LTC(handleLX, handleTY); + ScenePoint2D RTC(handleRX, handleTY); + ScenePoint2D RBC(handleRX, handleBY); + ScenePoint2D LBC(handleLX, handleBY); + + ScenePoint2D startLT = LTC.Apply(scene.GetCanvasToSceneTransform()); + ScenePoint2D startRT = RTC.Apply(scene.GetCanvasToSceneTransform()); + ScenePoint2D startRB = RBC.Apply(scene.GetCanvasToSceneTransform()); + ScenePoint2D startLB = LBC.Apply(scene.GetCanvasToSceneTransform()); + + chain.push_back(startLT); + chain.push_back(startRT); + chain.push_back(startRB); + chain.push_back(startLB); + } + + void AddCircle(PolylineSceneLayer::Chain& chain, + const Scene2D& scene, + const ScenePoint2D& centerS, + const double& radiusS) + { + chain.clear(); + chain.reserve(4); + //ScenePoint2D centerC = centerS.Apply(scene.GetSceneToCanvasTransform()); + //TODO: take DPI into account + + // TODO: automatically compute the number for segments for smooth + // display based on the radius in pixels. + int lineCount = 50; + + double angleIncr = (2.0 * boost::math::constants::pi<double>()) + / static_cast<double>(lineCount); + + double theta = 0; + for (int i = 0; i < lineCount; ++i) + { + double offsetX = radiusS * cos(theta); + double offsetY = radiusS * sin(theta); + double pointX = centerS.GetX() + offsetX; + double pointY = centerS.GetY() + offsetY; + chain.push_back(ScenePoint2D(pointX, pointY)); + theta += angleIncr; + } + } + +#if 0 + void AddEllipse(PolylineSceneLayer::Chain& chain, + const Scene2D& scene, + const ScenePoint2D& centerS, + const double& halfHAxis, + const double& halfVAxis) + { + chain.clear(); + chain.reserve(4); + ScenePoint2D centerC = centerS.Apply(scene.GetSceneToCanvasTransform()); + //TODO: take DPI into account + double handleLX = centerC.GetX() - sideLength / 2; + double handleTY = centerC.GetY() - sideLength / 2; + double handleRX = centerC.GetX() + sideLength / 2; + double handleBY = centerC.GetY() + sideLength / 2; + ScenePoint2D LTC(handleLX, handleTY); + ScenePoint2D RTC(handleRX, handleTY); + ScenePoint2D RBC(handleRX, handleBY); + ScenePoint2D LBC(handleLX, handleBY); + + ScenePoint2D startLT = LTC.Apply(scene.GetCanvasToSceneTransform()); + ScenePoint2D startRT = RTC.Apply(scene.GetCanvasToSceneTransform()); + ScenePoint2D startRB = RBC.Apply(scene.GetCanvasToSceneTransform()); + ScenePoint2D startLB = LBC.Apply(scene.GetCanvasToSceneTransform()); + + chain.push_back(startLT); + chain.push_back(startRT); + chain.push_back(startRB); + chain.push_back(startLB); + } +#endif + + + } + + void LineMeasureTool::RefreshScene() { if (IsEnabled()) @@ -103,13 +205,13 @@ assert(textZIndex_ == -1); { polylineZIndex_ = GetScene().GetMaxDepth() + 100; - LOG(INFO) << "set polylineZIndex_ to: " << polylineZIndex_; + //LOG(INFO) << "set polylineZIndex_ to: " << polylineZIndex_; std::auto_ptr<PolylineSceneLayer> layer(new PolylineSceneLayer()); GetScene().SetLayer(polylineZIndex_, layer.release()); } { textZIndex_ = GetScene().GetMaxDepth() + 100; - LOG(INFO) << "set textZIndex_ to: " << textZIndex_; + //LOG(INFO) << "set textZIndex_ to: " << textZIndex_; std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer()); GetScene().SetLayer(textZIndex_, layer.release()); } @@ -136,32 +238,44 @@ // handles { - ScenePoint2D startC = start_.Apply(GetScene().GetSceneToCanvasTransform()); - double squareSize = 10.0; //TODO: take DPI into account - double startHandleLX = startC.GetX() - squareSize/2; - double startHandleTY = startC.GetY() - squareSize / 2; - double startHandleRX = startC.GetX() + squareSize / 2; - double startHandleBY = startC.GetY() + squareSize / 2; - ScenePoint2D startLTC(startHandleLX, startHandleTY); - ScenePoint2D startRTC(startHandleRX, startHandleTY); - ScenePoint2D startRBC(startHandleRX, startHandleBY); - ScenePoint2D startLBC(startHandleLX, startHandleBY); + //void AddSquare(PolylineSceneLayer::Chain& chain,const Scene2D& scene,const ScenePoint2D& centerS,const double& sideLength) + + { + PolylineSceneLayer::Chain chain; + AddSquare(chain, GetScene(), start_, 10.0); //TODO: take DPI into account + polylineLayer->AddChain(chain, true); + } + + { + PolylineSceneLayer::Chain chain; + AddSquare(chain, GetScene(), end_, 10.0); //TODO: take DPI into account + polylineLayer->AddChain(chain, true); + } - ScenePoint2D startLT = startLTC.Apply(GetScene().GetCanvasToSceneTransform()); - ScenePoint2D startRT = startRTC.Apply(GetScene().GetCanvasToSceneTransform()); - ScenePoint2D startRB = startRBC.Apply(GetScene().GetCanvasToSceneTransform()); - ScenePoint2D startLB = startLBC.Apply(GetScene().GetCanvasToSceneTransform()); + //ScenePoint2D startC = start_.Apply(GetScene().GetSceneToCanvasTransform()); + //double squareSize = 10.0; + //double startHandleLX = startC.GetX() - squareSize/2; + //double startHandleTY = startC.GetY() - squareSize / 2; + //double startHandleRX = startC.GetX() + squareSize / 2; + //double startHandleBY = startC.GetY() + squareSize / 2; + //ScenePoint2D startLTC(startHandleLX, startHandleTY); + //ScenePoint2D startRTC(startHandleRX, startHandleTY); + //ScenePoint2D startRBC(startHandleRX, startHandleBY); + //ScenePoint2D startLBC(startHandleLX, startHandleBY); - PolylineSceneLayer::Chain chain; - chain.push_back(startLT); - chain.push_back(startRT); - chain.push_back(startRB); - chain.push_back(startLB); - polylineLayer->AddChain(chain, true); + //ScenePoint2D startLT = startLTC.Apply(GetScene().GetCanvasToSceneTransform()); + //ScenePoint2D startRT = startRTC.Apply(GetScene().GetCanvasToSceneTransform()); + //ScenePoint2D startRB = startRBC.Apply(GetScene().GetCanvasToSceneTransform()); + //ScenePoint2D startLB = startLBC.Apply(GetScene().GetCanvasToSceneTransform()); + + //PolylineSceneLayer::Chain chain; + //chain.push_back(startLT); + //chain.push_back(startRT); + //chain.push_back(startRB); + //chain.push_back(startLB); + //polylineLayer->AddChain(chain, true); } - - - + } { // Set the text layer proporeties
--- a/Samples/Common/MeasureTools.h Thu May 09 14:54:12 2019 +0200 +++ b/Samples/Common/MeasureTools.h Fri May 10 16:15:55 2019 +0200 @@ -25,6 +25,7 @@ #include <Framework/Scene2D/TextSceneLayer.h> #include <boost/shared_ptr.hpp> +#include <boost/weak_ptr.hpp> #include <vector> #include <cmath> @@ -50,7 +51,7 @@ void Disable(); protected: - MeasureTool(Scene2D& scene) + MeasureTool(Scene2D& scene) : scene_(scene) , enabled_(true) { @@ -65,7 +66,6 @@ */ virtual void RefreshScene() = 0; - Scene2D& GetScene() { return scene_;
--- a/Samples/Common/MeasureTrackers.cpp Thu May 09 14:54:12 2019 +0200 +++ b/Samples/Common/MeasureTrackers.cpp Fri May 10 16:15:55 2019 +0200 @@ -31,12 +31,24 @@ std::vector<TrackerCommandPtr>& undoStack, std::vector<MeasureToolPtr>& measureTools) : scene_(scene) + , active_(true) , undoStack_(undoStack) , measureTools_(measureTools) , commitResult_(true) { } + void CreateMeasureTracker::Cancel() + { + commitResult_ = false; + active_ = false; + } + + bool CreateMeasureTracker::IsActive() const + { + return active_; + } + CreateMeasureTracker::~CreateMeasureTracker() { // if the tracker completes successfully, we add the command @@ -49,44 +61,7 @@ command_->Undo(); } - CreateLineMeasureTracker::CreateLineMeasureTracker( - Scene2D& scene, - std::vector<TrackerCommandPtr>& undoStack, - std::vector<MeasureToolPtr>& measureTools, - const PointerEvent& e) - : CreateMeasureTracker(scene, undoStack, measureTools) - { - command_.reset( - new CreateLineMeasureCommand( - scene, - measureTools, - e.GetMainPosition().Apply(scene.GetCanvasToSceneTransform()))); - } - - CreateLineMeasureTracker::~CreateLineMeasureTracker() - { - } - - void CreateMeasureTracker::Update(const PointerEvent& event) - { - ScenePoint2D scenePos = event.GetMainPosition().Apply( - scene_.GetCanvasToSceneTransform()); - - LOG(TRACE) << "scenePos.GetX() = " << scenePos.GetX() << " " << - "scenePos.GetY() = " << scenePos.GetY(); - - CreateLineMeasureTracker* concreteThis = - dynamic_cast<CreateLineMeasureTracker*>(this); - assert(concreteThis != NULL); - command_->Update(scenePos); - } - - void CreateMeasureTracker::Release() - { - commitResult_ = false; - } - }
--- a/Samples/Common/MeasureTrackers.h Thu May 09 14:54:12 2019 +0200 +++ b/Samples/Common/MeasureTrackers.h Fri May 10 16:15:55 2019 +0200 @@ -20,8 +20,9 @@ #pragma once -#include "../../Framework/Scene2D/IPointerTracker.h" +#include "IFlexiblePointerTracker.h" #include "../../Framework/Scene2D/Scene2D.h" +#include "../../Framework/Scene2D/PointerEvent.h" #include "MeasureTools.h" #include "MeasureCommands.h" @@ -30,11 +31,11 @@ namespace OrthancStone { - class CreateMeasureTracker : public IPointerTracker + class CreateMeasureTracker : public IFlexiblePointerTracker { public: - virtual void Update(const PointerEvent& e) ORTHANC_OVERRIDE; - virtual void Release() ORTHANC_OVERRIDE; + virtual void Cancel() ORTHANC_OVERRIDE; + virtual bool IsActive() const ORTHANC_OVERRIDE; protected: CreateMeasureTracker( Scene2D& scene, @@ -43,32 +44,14 @@ ~CreateMeasureTracker(); + protected: + Scene2D& scene_; + CreateMeasureCommandPtr command_; + bool active_; private: - Scene2D& scene_; std::vector<TrackerCommandPtr>& undoStack_; std::vector<MeasureToolPtr>& measureTools_; bool commitResult_; - - protected: - CreateMeasureCommandPtr command_; }; - class CreateLineMeasureTracker : public CreateMeasureTracker - { - 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 - */ - CreateLineMeasureTracker( - Scene2D& scene, - std::vector<TrackerCommandPtr>& undoStack, - std::vector<MeasureToolPtr>& measureTools, - const PointerEvent& e); - - ~CreateLineMeasureTracker(); - }; }
--- a/Samples/Sdl/CMakeLists.txt Thu May 09 14:54:12 2019 +0200 +++ b/Samples/Sdl/CMakeLists.txt Fri May 10 16:15:55 2019 +0200 @@ -69,13 +69,42 @@ LIST(APPEND TRACKERSAMPLE_SOURCE "../../../SDL-Console/SDL_Console.h") endif() +LIST(APPEND TRACKERSAMPLE_SOURCE "../Common/CreateAngleMeasureTracker.cpp") +LIST(APPEND TRACKERSAMPLE_SOURCE "../Common/CreateAngleMeasureTracker.h") +LIST(APPEND TRACKERSAMPLE_SOURCE "../Common/CreateCircleMeasureTracker.cpp") +LIST(APPEND TRACKERSAMPLE_SOURCE "../Common/CreateCircleMeasureTracker.h") +LIST(APPEND TRACKERSAMPLE_SOURCE "../Common/CreateLineMeasureTracker.cpp") +LIST(APPEND TRACKERSAMPLE_SOURCE "../Common/CreateLineMeasureTracker.h") + +LIST(APPEND TRACKERSAMPLE_SOURCE "../Common/CreateMeasureTracker.cpp") +LIST(APPEND TRACKERSAMPLE_SOURCE "../Common/CreateMeasureTracker.h") + +LIST(APPEND TRACKERSAMPLE_SOURCE "../Common/CreateSimpleTrackerAdapter.cpp") + +LIST(APPEND TRACKERSAMPLE_SOURCE "../Common/EditAngleMeasureTracker.cpp") +LIST(APPEND TRACKERSAMPLE_SOURCE "../Common/EditAngleMeasureTracker.h") +LIST(APPEND TRACKERSAMPLE_SOURCE "../Common/EditCircleMeasureTracker.cpp") +LIST(APPEND TRACKERSAMPLE_SOURCE "../Common/EditCircleMeasureTracker.h") +LIST(APPEND TRACKERSAMPLE_SOURCE "../Common/EditLineMeasureTracker.cpp") +LIST(APPEND TRACKERSAMPLE_SOURCE "../Common/EditLineMeasureTracker.h") + +LIST(APPEND TRACKERSAMPLE_SOURCE "../Common/IFlexiblePointerTracker.h") + LIST(APPEND TRACKERSAMPLE_SOURCE "../Common/MeasureCommands.cpp") LIST(APPEND TRACKERSAMPLE_SOURCE "../Common/MeasureCommands.h") LIST(APPEND TRACKERSAMPLE_SOURCE "../Common/MeasureTools.cpp") LIST(APPEND TRACKERSAMPLE_SOURCE "../Common/MeasureTools.h") LIST(APPEND TRACKERSAMPLE_SOURCE "../Common/MeasureTrackers.cpp") LIST(APPEND TRACKERSAMPLE_SOURCE "../Common/MeasureTrackers.h") + + LIST(APPEND TRACKERSAMPLE_SOURCE "TrackerSample.cpp") +LIST(APPEND TRACKERSAMPLE_SOURCE "TrackerSampleApp.cpp") +LIST(APPEND TRACKERSAMPLE_SOURCE "TrackerSampleApp.h") + +if (MSVC AND MSVC_VERSION GREATER 1700) + LIST(APPEND TRACKERSAMPLE_SOURCE "cpp.hint") +endif() add_executable(TrackerSample ${TRACKERSAMPLE_SOURCE}
--- a/Samples/Sdl/TrackerSample.cpp Thu May 09 14:54:12 2019 +0200 +++ b/Samples/Sdl/TrackerSample.cpp Fri May 10 16:15:55 2019 +0200 @@ -18,24 +18,18 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. **/ +#include "TrackerSampleApp.h" // From Stone #include "../../Applications/Sdl/SdlOpenGLWindow.h" #include "../../Framework/Scene2D/CairoCompositor.h" #include "../../Framework/Scene2D/ColorTextureSceneLayer.h" #include "../../Framework/Scene2D/OpenGLCompositor.h" -#include "../../Framework/Scene2D/PanSceneTracker.h" -#include "../../Framework/Scene2D/RotateSceneTracker.h" -#include "../../Framework/Scene2D/Scene2D.h" -#include "../../Framework/Scene2D/ZoomSceneTracker.h" #include "../../Framework/StoneInitialization.h" -// From Orthanc framework #include <Core/Logging.h> #include <Core/OrthancException.h> -#include <Core/Images/Image.h> -#include <Core/Images/ImageProcessing.h> -#include <Core/Images/PngWriter.h> + #include <boost/shared_ptr.hpp> #include <boost/weak_ptr.hpp> @@ -43,11 +37,6 @@ #include <SDL.h> #include <stdio.h> - -// to be moved into Stone -#include "../Common/MeasureTrackers.h" -#include "../Common/MeasureCommands.h" - /* TODO: @@ -63,369 +52,6 @@ using namespace Orthanc; using namespace OrthancStone; -namespace OrthancStone -{ - enum GuiTool - { - GuiTool_Rotate = 0, - GuiTool_Pan, - GuiTool_Zoom, - GuiTool_LineMeasure, - GuiTool_CircleMeasure, - GuiTool_AngleMeasure, - GuiTool_EllipseMeasure, - GuiTool_LAST - }; - - const char* MeasureToolToString(size_t i) - { - static const char* descs[] = { - "GuiTool_Rotate", - "GuiTool_Pan", - "GuiTool_Zoom", - "GuiTool_LineMeasure", - "GuiTool_CircleMeasure", - "GuiTool_AngleMeasure", - "GuiTool_EllipseMeasure", - "GuiTool_LAST" - }; - if (i >= GuiTool_LAST) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, "Wrong tool index"); - } - return descs[i]; - } -} - -class TrackerSampleApp -{ -public: - // 12 because. - TrackerSampleApp() : currentTool_(GuiTool_Rotate) - { - TEXTURE_2x2_1_ZINDEX = 1; - TEXTURE_1x1_ZINDEX = 2; - TEXTURE_2x2_2_ZINDEX = 3; - LINESET_1_ZINDEX = 4; - LINESET_2_ZINDEX = 5; - INFOTEXT_LAYER_ZINDEX = 6; - } - void PrepareScene(); - void Run(); - -private: - Scene2D& GetScene() - { - return scene_; - } - - void SelectNextTool() - { - currentTool_ = static_cast<GuiTool>(currentTool_ + 1); - if (currentTool_ == GuiTool_LAST) - currentTool_ = static_cast<GuiTool>(0);; - printf("Current tool is now: %s\n", MeasureToolToString(currentTool_)); - } - - void HandleApplicationEvent( - const OpenGLCompositor& compositor, - const SDL_Event& event, - std::auto_ptr<IPointerTracker>& activeTracker); - - IPointerTracker* TrackerSampleApp::TrackerHitTest(const PointerEvent& e); - - IPointerTracker* CreateSuitableTracker( - const SDL_Event& event, - const PointerEvent& e, - const OpenGLCompositor& compositor); - - void TakeScreenshot( - const std::string& target, - unsigned int canvasWidth, - unsigned int canvasHeight); - - /** - This adds the command at the top of the undo stack - */ - void Commit(TrackerCommandPtr cmd); - void Undo(); - void Redo(); - -private: - static const unsigned int FONT_SIZE = 32; - - std::vector<TrackerCommandPtr> undoStack_; - - // we store the measure tools here so that they don't get deleted - std::vector<MeasureToolPtr> measureTools_; - - //static const int LAYER_POSITION = 150; -#if 0 - int TEXTURE_2x2_1_ZINDEX = 12; - int TEXTURE_1x1_ZINDEX = 13; - int TEXTURE_2x2_2_ZINDEX = 14; - int LINESET_1_ZINDEX = 50; - int LINESET_2_ZINDEX = 100; - int INFOTEXT_LAYER_ZINDEX = 150; -#else - int TEXTURE_2x2_1_ZINDEX; - int TEXTURE_1x1_ZINDEX; - int TEXTURE_2x2_2_ZINDEX; - int LINESET_1_ZINDEX; - int LINESET_2_ZINDEX; - int INFOTEXT_LAYER_ZINDEX; -#endif - Scene2D scene_; - GuiTool currentTool_; -}; - - -void TrackerSampleApp::PrepareScene() -{ - // Texture of 2x2 size - { - Orthanc::Image i(Orthanc::PixelFormat_RGB24, 2, 2, false); - - uint8_t *p = reinterpret_cast<uint8_t*>(i.GetRow(0)); - p[0] = 255; - p[1] = 0; - p[2] = 0; - - p[3] = 0; - p[4] = 255; - p[5] = 0; - - p = reinterpret_cast<uint8_t*>(i.GetRow(1)); - p[0] = 0; - p[1] = 0; - p[2] = 255; - - p[3] = 255; - p[4] = 0; - p[5] = 0; - - scene_.SetLayer(TEXTURE_2x2_1_ZINDEX, new ColorTextureSceneLayer(i)); - - std::auto_ptr<ColorTextureSceneLayer> l(new ColorTextureSceneLayer(i)); - l->SetOrigin(-3, 2); - l->SetPixelSpacing(1.5, 1); - l->SetAngle(20.0 / 180.0 * M_PI); - scene_.SetLayer(TEXTURE_2x2_2_ZINDEX, l.release()); - } - - // Texture of 1x1 size - { - Orthanc::Image i(Orthanc::PixelFormat_RGB24, 1, 1, false); - - uint8_t *p = reinterpret_cast<uint8_t*>(i.GetRow(0)); - p[0] = 255; - p[1] = 0; - p[2] = 0; - - std::auto_ptr<ColorTextureSceneLayer> l(new ColorTextureSceneLayer(i)); - l->SetOrigin(-2, 1); - l->SetAngle(20.0 / 180.0 * M_PI); - scene_.SetLayer(TEXTURE_1x1_ZINDEX, l.release()); - } - - // Some lines - { - std::auto_ptr<PolylineSceneLayer> layer(new PolylineSceneLayer); - - layer->SetThickness(1); - - PolylineSceneLayer::Chain chain; - chain.push_back(ScenePoint2D(0 - 0.5, 0 - 0.5)); - chain.push_back(ScenePoint2D(0 - 0.5, 2 - 0.5)); - chain.push_back(ScenePoint2D(2 - 0.5, 2 - 0.5)); - chain.push_back(ScenePoint2D(2 - 0.5, 0 - 0.5)); - layer->AddChain(chain, true); - - chain.clear(); - chain.push_back(ScenePoint2D(-5, -5)); - chain.push_back(ScenePoint2D(5, -5)); - chain.push_back(ScenePoint2D(5, 5)); - chain.push_back(ScenePoint2D(-5, 5)); - layer->AddChain(chain, true); - - double dy = 1.01; - chain.clear(); - chain.push_back(ScenePoint2D(-4, -4)); - chain.push_back(ScenePoint2D(4, -4 + dy)); - chain.push_back(ScenePoint2D(-4, -4 + 2.0 * dy)); - chain.push_back(ScenePoint2D(4, 2)); - layer->AddChain(chain, false); - - layer->SetColor(0, 255, 255); - scene_.SetLayer(LINESET_1_ZINDEX, layer.release()); - } - - // Some text - { - std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer); - layer->SetText("Hello"); - scene_.SetLayer(LINESET_2_ZINDEX, layer.release()); - } -} - - -void TrackerSampleApp::TakeScreenshot(const std::string& target, - unsigned int canvasWidth, - unsigned int canvasHeight) -{ - // Take a screenshot, then save it as PNG file - CairoCompositor compositor(scene_, canvasWidth, canvasHeight); - compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, FONT_SIZE, Orthanc::Encoding_Latin1); - compositor.Refresh(); - - Orthanc::ImageAccessor canvas; - compositor.GetCanvas().GetReadOnlyAccessor(canvas); - - Orthanc::Image png(Orthanc::PixelFormat_RGB24, canvas.GetWidth(), canvas.GetHeight(), false); - Orthanc::ImageProcessing::Convert(png, canvas); - - Orthanc::PngWriter writer; - writer.WriteToFile(target, png); -} - - -IPointerTracker* TrackerSampleApp::TrackerHitTest(const PointerEvent& e) -{ - // std::vector<MeasureToolPtr> measureTools_; - return nullptr; -} - -IPointerTracker* TrackerSampleApp::CreateSuitableTracker( - const SDL_Event& event, - const PointerEvent& e, - const OpenGLCompositor& compositor) -{ - switch (event.button.button) - { - case SDL_BUTTON_MIDDLE: - return new PanSceneTracker(scene_, e); - - case SDL_BUTTON_RIGHT: - return new ZoomSceneTracker( - scene_, e, compositor.GetCanvasHeight()); - - case SDL_BUTTON_LEFT: - { - // TODO: we need to iterate on the set of measuring tool and perform - // a hit test to check if a tracker needs to be created for edition. - // Otherwise, depending upon the active tool, we might want to create - // a "measuring tool creation" tracker - - // TODO: if there are conflicts, we should prefer a tracker that - // pertains to the type of measuring tool currently selected (TBD?) - IPointerTracker* hitTestTracker = TrackerHitTest(e); - - if (hitTestTracker != NULL) - { - return hitTestTracker; - } - else - { - switch (currentTool_) - { - case GuiTool_Rotate: - return new RotateSceneTracker(scene_, e); - case GuiTool_LineMeasure: - return new CreateLineMeasureTracker( - scene_, undoStack_, measureTools_, e); - //case GuiTool_AngleMeasure: - // return new AngleMeasureTracker(scene_, measureTools_, undoStack_, e); - //case GuiTool_CircleMeasure: - // return new CircleMeasureTracker(scene_, measureTools_, undoStack_, e); - //case GuiTool_EllipseMeasure: - // return new EllipseMeasureTracker(scene_, measureTools_, undoStack_, e); - default: - throw OrthancException(ErrorCode_InternalError, "Wrong tool!"); - } - } - } - default: - return NULL; - } -} - -void TrackerSampleApp::HandleApplicationEvent( - const OpenGLCompositor& compositor, - const SDL_Event& event, - std::auto_ptr<IPointerTracker>& activeTracker) -{ - if (event.type == SDL_MOUSEMOTION) - { - int scancodeCount = 0; - const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount); - - if (activeTracker.get() == NULL && - SDL_SCANCODE_LCTRL < scancodeCount && - keyboardState[SDL_SCANCODE_LCTRL]) - { - // The "left-ctrl" key is down, while no tracker is present - - PointerEvent e; - e.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y)); - - ScenePoint2D p = e.GetMainPosition().Apply(scene_.GetCanvasToSceneTransform()); - - char buf[64]; - sprintf(buf, "(%0.02f,%0.02f)", p.GetX(), p.GetY()); - - if (scene_.HasLayer(INFOTEXT_LAYER_ZINDEX)) - { - TextSceneLayer& layer = - dynamic_cast<TextSceneLayer&>(scene_.GetLayer(INFOTEXT_LAYER_ZINDEX)); - layer.SetText(buf); - layer.SetPosition(p.GetX(), p.GetY()); - } - else - { - std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer); - layer->SetColor(0, 255, 0); - layer->SetText(buf); - layer->SetBorder(20); - layer->SetAnchor(BitmapAnchor_BottomCenter); - layer->SetPosition(p.GetX(), p.GetY()); - scene_.SetLayer(INFOTEXT_LAYER_ZINDEX, layer.release()); - } - } - else - { - scene_.DeleteLayer(INFOTEXT_LAYER_ZINDEX); - } - } - else if (event.type == SDL_MOUSEBUTTONDOWN) - { - PointerEvent e; - e.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y)); - - activeTracker.reset(CreateSuitableTracker(event, e, compositor)); - } - else if (event.type == SDL_KEYDOWN && - event.key.repeat == 0 /* Ignore key bounce */) - { - switch (event.key.keysym.sym) - { - case SDLK_s: - scene_.FitContent(compositor.GetCanvasWidth(), - compositor.GetCanvasHeight()); - break; - - case SDLK_c: - TakeScreenshot( - "screenshot.png", - compositor.GetCanvasWidth(), - compositor.GetCanvasHeight()); - break; - - default: - break; - } - } -} - static void GLAPIENTRY OpenGLMessageCallback(GLenum source, @@ -446,23 +72,19 @@ bool g_stopApplication = false; -void TrackerSampleApp::Run() +void Run(TrackerSampleApp* app) { SdlOpenGLWindow window("Hello", 1024, 768); - scene_.FitContent(window.GetCanvasWidth(), window.GetCanvasHeight()); + app->GetScene().FitContent(window.GetCanvasWidth(), window.GetCanvasHeight()); glEnable(GL_DEBUG_OUTPUT); glDebugMessageCallback(OpenGLMessageCallback, 0); - OpenGLCompositor compositor(window, scene_); + OpenGLCompositor compositor(window, app->GetScene()); compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, FONT_SIZE, Orthanc::Encoding_Latin1); - // this will either be empty or contain the current tracker, if any - std::auto_ptr<IPointerTracker> tracker; - - while (!g_stopApplication) { compositor.Refresh(); @@ -475,29 +97,10 @@ g_stopApplication = true; break; } - else if (event.type == SDL_MOUSEMOTION) - { - if (tracker.get() != NULL) - { - PointerEvent e; - e.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y)); - LOG(TRACE) << "event.button.x = " << event.button.x << " " << - "event.button.y = " << event.button.y; - tracker->Update(e); - } - } - else if (event.type == SDL_MOUSEBUTTONUP) - { - if (tracker.get() != NULL) - { - tracker->Release(); - tracker.reset(NULL); - } - } else if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { - tracker.reset(NULL); + app->DisableTracker(); // was: tracker.reset(NULL); compositor.UpdateSize(); } else if (event.type == SDL_KEYDOWN && @@ -512,16 +115,11 @@ case SDLK_q: g_stopApplication = true; break; - - case SDLK_t: - SelectNextTool(); - break; - default: break; } } - HandleApplicationEvent(compositor, event, tracker); + app->HandleApplicationEvent(compositor, event); } SDL_Delay(1); } @@ -537,12 +135,14 @@ { StoneInitialize(); Orthanc::Logging::EnableInfoLevel(true); + Orthanc::Logging::EnableTraceLevel(true); + try { TrackerSampleApp app; app.PrepareScene(); - app.Run(); + Run(&app); } catch (Orthanc::OrthancException& e) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Samples/Sdl/TrackerSampleApp.cpp Fri May 10 16:15:55 2019 +0200 @@ -0,0 +1,421 @@ +/** + * 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 "TrackerSampleApp.h" + +#include "../Common/CreateLineMeasureTracker.h" + +#include "../../Applications/Sdl/SdlOpenGLWindow.h" + +#include "../../Framework/Scene2D/PanSceneTracker.h" +#include "../../Framework/Scene2D/RotateSceneTracker.h" +#include "../../Framework/Scene2D/Scene2D.h" +#include "../../Framework/Scene2D/ZoomSceneTracker.h" +#include "../../Framework/Scene2D/CairoCompositor.h" +#include "../../Framework/Scene2D/ColorTextureSceneLayer.h" +#include "../../Framework/Scene2D/OpenGLCompositor.h" +#include "../../Framework/StoneInitialization.h" + + // From Orthanc framework +#include <Core/Logging.h> +#include <Core/OrthancException.h> +#include <Core/Images/Image.h> +#include <Core/Images/ImageProcessing.h> +#include <Core/Images/PngWriter.h> + +#include <SDL.h> +#include <stdio.h> + +using namespace Orthanc; + +namespace OrthancStone +{ + const char* MeasureToolToString(size_t i) + { + static const char* descs[] = { + "GuiTool_Rotate", + "GuiTool_Pan", + "GuiTool_Zoom", + "GuiTool_LineMeasure", + "GuiTool_CircleMeasure", + "GuiTool_AngleMeasure", + "GuiTool_EllipseMeasure", + "GuiTool_LAST" + }; + if (i >= GuiTool_LAST) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, "Wrong tool index"); + } + return descs[i]; + } + + Scene2D& TrackerSampleApp::GetScene() + { + return scene_; + } + + void TrackerSampleApp::SelectNextTool() + { + currentTool_ = static_cast<GuiTool>(currentTool_ + 1); + if (currentTool_ == GuiTool_LAST) + currentTool_ = static_cast<GuiTool>(0);; + printf("Current tool is now: %s\n", MeasureToolToString(currentTool_)); + } + + void TrackerSampleApp::DisplayInfoText(const PointerEvent& e) + { + ScenePoint2D p = e.GetMainPosition().Apply(scene_.GetCanvasToSceneTransform()); + + char buf[64]; + sprintf(buf, "(%0.02f,%0.02f)", p.GetX(), p.GetY()); + + if (scene_.HasLayer(INFOTEXT_LAYER_ZINDEX)) + { + TextSceneLayer& layer = + dynamic_cast<TextSceneLayer&>(scene_.GetLayer(INFOTEXT_LAYER_ZINDEX)); + layer.SetText(buf); + layer.SetPosition(p.GetX(), p.GetY()); + } + else + { + std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer); + layer->SetColor(0, 255, 0); + layer->SetText(buf); + layer->SetBorder(20); + layer->SetAnchor(BitmapAnchor_BottomCenter); + layer->SetPosition(p.GetX(), p.GetY()); + scene_.SetLayer(INFOTEXT_LAYER_ZINDEX, layer.release()); + } + } + + void TrackerSampleApp::HideInfoText() + { + scene_.DeleteLayer(INFOTEXT_LAYER_ZINDEX); + } + + void TrackerSampleApp::HandleApplicationEvent( + const OpenGLCompositor & compositor, + const SDL_Event & event) + { + if (event.type == SDL_MOUSEMOTION) + { + int scancodeCount = 0; + const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount); + + if (activeTracker_.get() == NULL && + SDL_SCANCODE_LCTRL < scancodeCount && + keyboardState[SDL_SCANCODE_LCTRL]) + { + // The "left-ctrl" key is down, while no tracker is present + // Let's display the info text + PointerEvent e; + e.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y)); + DisplayInfoText(e); + } + else + { + HideInfoText(); + //LOG(TRACE) << "(event.type == SDL_MOUSEMOTION)"; + if (activeTracker_.get() != NULL) + { + //LOG(TRACE) << "(activeTracker_.get() != NULL)"; + PointerEvent e; + e.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y)); + //LOG(TRACE) << "event.button.x = " << event.button.x << " " << + // "event.button.y = " << event.button.y; + //LOG(TRACE) << "activeTracker_->PointerMove(e); " << + // e.GetMainPosition().GetX() << " " << e.GetMainPosition().GetY(); + activeTracker_->PointerMove(e); + if (!activeTracker_->IsActive()) + activeTracker_ = NULL; + } + } + } + else if (event.type == SDL_MOUSEBUTTONUP) + { + if (activeTracker_) + { + PointerEvent e; + e.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y)); + activeTracker_->PointerUp(e); + if (!activeTracker_->IsActive()) + activeTracker_ = NULL; + } + } + else if (event.type == SDL_MOUSEBUTTONDOWN) + { + PointerEvent e; + e.AddPosition(compositor.GetPixelCenterCoordinates(event.button.x, event.button.y)); + if (activeTracker_) + { + activeTracker_->PointerDown(e); + if (!activeTracker_->IsActive()) + activeTracker_ = NULL; + } + else + { + // we ATTEMPT to create a tracker if need be + activeTracker_ = CreateSuitableTracker(event, e, compositor); + } + } + else if (event.type == SDL_KEYDOWN && + event.key.repeat == 0 /* Ignore key bounce */) + { + switch (event.key.keysym.sym) + { + case SDLK_ESCAPE: + if (activeTracker_) + { + activeTracker_->Cancel(); + if (!activeTracker_->IsActive()) + activeTracker_ = NULL; + } + break; + + case SDLK_t: + if (!activeTracker_) + SelectNextTool(); + else + { + LOG(WARNING) << "You cannot change the active tool when an interaction" + " is taking place"; + } + break; + + case SDLK_s: + scene_.FitContent(compositor.GetCanvasWidth(), + compositor.GetCanvasHeight()); + break; + + case SDLK_c: + TakeScreenshot( + "screenshot.png", + compositor.GetCanvasWidth(), + compositor.GetCanvasHeight()); + break; + + default: + break; + } + } + } + + FlexiblePointerTrackerPtr TrackerSampleApp::CreateSuitableTracker( + const SDL_Event & event, + const PointerEvent & e, + const OpenGLCompositor & compositor) + { + switch (event.button.button) + { + case SDL_BUTTON_MIDDLE: + return CreateSimpleTrackerAdapter(PointerTrackerPtr( + new PanSceneTracker(scene_, e))); + + case SDL_BUTTON_RIGHT: + return CreateSimpleTrackerAdapter(PointerTrackerPtr( + new ZoomSceneTracker(scene_, e, compositor.GetCanvasHeight()))); + + case SDL_BUTTON_LEFT: + { + //LOG(TRACE) << "CreateSuitableTracker: case SDL_BUTTON_LEFT:"; + // TODO: we need to iterate on the set of measuring tool and perform + // a hit test to check if a tracker needs to be created for edition. + // Otherwise, depending upon the active tool, we might want to create + // a "measuring tool creation" tracker + + // TODO: if there are conflicts, we should prefer a tracker that + // pertains to the type of measuring tool currently selected (TBD?) + FlexiblePointerTrackerPtr hitTestTracker = TrackerHitTest(e); + + if (hitTestTracker != NULL) + { + //LOG(TRACE) << "hitTestTracker != NULL"; + return hitTestTracker; + } + else + { + switch (currentTool_) + { + case GuiTool_Rotate: + //LOG(TRACE) << "Creating RotateSceneTracker"; + return CreateSimpleTrackerAdapter(PointerTrackerPtr( + new RotateSceneTracker(scene_, e))); + case GuiTool_LineMeasure: + return FlexiblePointerTrackerPtr(new CreateLineMeasureTracker( + scene_, undoStack_, measureTools_, e)); + case GuiTool_Pan: + return CreateSimpleTrackerAdapter(PointerTrackerPtr( + new PanSceneTracker(scene_, e))); + case GuiTool_Zoom: + return CreateSimpleTrackerAdapter(PointerTrackerPtr( + new ZoomSceneTracker(scene_, e, compositor.GetCanvasHeight()))); + //case GuiTool_AngleMeasure: + // return new AngleMeasureTracker(scene_, measureTools_, undoStack_, e); + //case GuiTool_CircleMeasure: + // return new CircleMeasureTracker(scene_, measureTools_, undoStack_, e); + //case GuiTool_EllipseMeasure: + // return new EllipseMeasureTracker(scene_, measureTools_, undoStack_, e); + case GuiTool_AngleMeasure: + LOG(ERROR) << "Not implemented yet!"; + return NULL; + case GuiTool_CircleMeasure: + LOG(ERROR) << "Not implemented yet!"; + return NULL; + case GuiTool_EllipseMeasure: + LOG(ERROR) << "Not implemented yet!"; + return NULL; + default: + throw OrthancException(ErrorCode_InternalError, "Wrong tool!"); + } + } + } + default: + return NULL; + } + } + + + void TrackerSampleApp::PrepareScene() + { + // Texture of 2x2 size + { + Orthanc::Image i(Orthanc::PixelFormat_RGB24, 2, 2, false); + + uint8_t* p = reinterpret_cast<uint8_t*>(i.GetRow(0)); + p[0] = 255; + p[1] = 0; + p[2] = 0; + + p[3] = 0; + p[4] = 255; + p[5] = 0; + + p = reinterpret_cast<uint8_t*>(i.GetRow(1)); + p[0] = 0; + p[1] = 0; + p[2] = 255; + + p[3] = 255; + p[4] = 0; + p[5] = 0; + + scene_.SetLayer(TEXTURE_2x2_1_ZINDEX, new ColorTextureSceneLayer(i)); + + std::auto_ptr<ColorTextureSceneLayer> l(new ColorTextureSceneLayer(i)); + l->SetOrigin(-3, 2); + l->SetPixelSpacing(1.5, 1); + l->SetAngle(20.0 / 180.0 * M_PI); + scene_.SetLayer(TEXTURE_2x2_2_ZINDEX, l.release()); + } + + // Texture of 1x1 size + { + Orthanc::Image i(Orthanc::PixelFormat_RGB24, 1, 1, false); + + uint8_t* p = reinterpret_cast<uint8_t*>(i.GetRow(0)); + p[0] = 255; + p[1] = 0; + p[2] = 0; + + std::auto_ptr<ColorTextureSceneLayer> l(new ColorTextureSceneLayer(i)); + l->SetOrigin(-2, 1); + l->SetAngle(20.0 / 180.0 * M_PI); + scene_.SetLayer(TEXTURE_1x1_ZINDEX, l.release()); + } + + // Some lines + { + std::auto_ptr<PolylineSceneLayer> layer(new PolylineSceneLayer); + + layer->SetThickness(1); + + PolylineSceneLayer::Chain chain; + chain.push_back(ScenePoint2D(0 - 0.5, 0 - 0.5)); + chain.push_back(ScenePoint2D(0 - 0.5, 2 - 0.5)); + chain.push_back(ScenePoint2D(2 - 0.5, 2 - 0.5)); + chain.push_back(ScenePoint2D(2 - 0.5, 0 - 0.5)); + layer->AddChain(chain, true); + + chain.clear(); + chain.push_back(ScenePoint2D(-5, -5)); + chain.push_back(ScenePoint2D(5, -5)); + chain.push_back(ScenePoint2D(5, 5)); + chain.push_back(ScenePoint2D(-5, 5)); + layer->AddChain(chain, true); + + double dy = 1.01; + chain.clear(); + chain.push_back(ScenePoint2D(-4, -4)); + chain.push_back(ScenePoint2D(4, -4 + dy)); + chain.push_back(ScenePoint2D(-4, -4 + 2.0 * dy)); + chain.push_back(ScenePoint2D(4, 2)); + layer->AddChain(chain, false); + + layer->SetColor(0, 255, 255); + scene_.SetLayer(LINESET_1_ZINDEX, layer.release()); + } + + // Some text + { + std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer); + layer->SetText("Hello"); + scene_.SetLayer(LINESET_2_ZINDEX, layer.release()); + } + } + + + void TrackerSampleApp::DisableTracker() + { + if (activeTracker_) + { + activeTracker_->Cancel(); + activeTracker_ = NULL; + } + } + + void TrackerSampleApp::TakeScreenshot(const std::string& target, + unsigned int canvasWidth, + unsigned int canvasHeight) + { + // Take a screenshot, then save it as PNG file + CairoCompositor compositor(scene_, canvasWidth, canvasHeight); + compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, FONT_SIZE, Orthanc::Encoding_Latin1); + compositor.Refresh(); + + Orthanc::ImageAccessor canvas; + compositor.GetCanvas().GetReadOnlyAccessor(canvas); + + Orthanc::Image png(Orthanc::PixelFormat_RGB24, canvas.GetWidth(), canvas.GetHeight(), false); + Orthanc::ImageProcessing::Convert(png, canvas); + + Orthanc::PngWriter writer; + writer.WriteToFile(target, png); + } + + + FlexiblePointerTrackerPtr TrackerSampleApp::TrackerHitTest(const PointerEvent & e) + { + // std::vector<MeasureToolPtr> measureTools_; + return nullptr; + } + + + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Samples/Sdl/TrackerSampleApp.h Fri May 10 16:15:55 2019 +0200 @@ -0,0 +1,136 @@ +/** + * 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 <Framework/Scene2D/OpenGLCompositor.h> + +#include "../Common/IFlexiblePointerTracker.h" +#include "../Common/MeasureTools.h" + +#include <SDL.h> + +#include <boost/make_shared.hpp> +#include <boost/shared_ptr.hpp> + +namespace OrthancStone +{ + class TrackerCommand; + typedef boost::shared_ptr<TrackerCommand> TrackerCommandPtr; + + enum GuiTool + { + GuiTool_Rotate = 0, + GuiTool_Pan, + GuiTool_Zoom, + GuiTool_LineMeasure, + GuiTool_CircleMeasure, + GuiTool_AngleMeasure, + GuiTool_EllipseMeasure, + GuiTool_LAST + }; + + const char* MeasureToolToString(size_t i); + + static const unsigned int FONT_SIZE = 32; + + class Scene2D; + + class TrackerSampleApp + { + public: + // 12 because. + TrackerSampleApp() : currentTool_(GuiTool_Rotate) + { + TEXTURE_2x2_1_ZINDEX = 1; + TEXTURE_1x1_ZINDEX = 2; + TEXTURE_2x2_2_ZINDEX = 3; + LINESET_1_ZINDEX = 4; + LINESET_2_ZINDEX = 5; + INFOTEXT_LAYER_ZINDEX = 6; + } + void PrepareScene(); + + void DisableTracker(); + + Scene2D& GetScene(); + + void HandleApplicationEvent( + const OpenGLCompositor& compositor, + const SDL_Event& event); + + private: + void SelectNextTool(); + + + FlexiblePointerTrackerPtr TrackerHitTest(const PointerEvent& e); + + FlexiblePointerTrackerPtr CreateSuitableTracker( + const SDL_Event& event, + const PointerEvent& e, + const OpenGLCompositor& compositor); + + void TakeScreenshot( + const std::string& target, + unsigned int canvasWidth, + unsigned int canvasHeight); + + /** + This adds the command at the top of the undo stack + */ + void Commit(TrackerCommandPtr cmd); + void Undo(); + void Redo(); + + private: + void DisplayInfoText(const PointerEvent& e); + void HideInfoText(); + + private: + /** + WARNING: the measuring tools do store a reference to the scene, and it + paramount that the scene gets destroyed AFTER the measurement tools. + */ + Scene2D scene_; + + FlexiblePointerTrackerPtr activeTracker_; + std::vector<TrackerCommandPtr> undoStack_; + + // we store the measure tools here so that they don't get deleted + std::vector<MeasureToolPtr> measureTools_; + + //static const int LAYER_POSITION = 150; +#if 0 + int TEXTURE_2x2_1_ZINDEX = 12; + int TEXTURE_1x1_ZINDEX = 13; + int TEXTURE_2x2_2_ZINDEX = 14; + int LINESET_1_ZINDEX = 50; + int LINESET_2_ZINDEX = 100; + int INFOTEXT_LAYER_ZINDEX = 150; +#else + int TEXTURE_2x2_1_ZINDEX; + int TEXTURE_1x1_ZINDEX; + int TEXTURE_2x2_2_ZINDEX; + int LINESET_1_ZINDEX; + int LINESET_2_ZINDEX; + int INFOTEXT_LAYER_ZINDEX; +#endif + GuiTool currentTool_; + }; + +}