# HG changeset patch # User Sebastien Jodogne # Date 1558537538 -7200 # Node ID 8c97c381f242e9230ee9267eca9388a97dab5fac # Parent f7c236894c1a2a4767d18883867bec29dfcd757c# Parent 46403ab629f68f20adeaf80b1d6a5091f3b27949 merge diff -r f7c236894c1a -r 8c97c381f242 .hgignore --- a/.hgignore Wed May 22 17:05:14 2019 +0200 +++ b/.hgignore Wed May 22 17:05:38 2019 +0200 @@ -34,3 +34,6 @@ Samples/Sdl/ThirdPartyDownloads/ Samples/Sdl/CMakeLists.txt.orig +Samples/WebAssembly/build/ +Samples/WebAssembly/ThirdPartyDownloads/ +Samples/WebAssembly/installDir/ diff -r f7c236894c1a -r 8c97c381f242 Framework/Scene2DViewport/AngleMeasureTool.cpp --- a/Framework/Scene2DViewport/AngleMeasureTool.cpp Wed May 22 17:05:14 2019 +0200 +++ b/Framework/Scene2DViewport/AngleMeasureTool.cpp Wed May 22 17:05:38 2019 +0200 @@ -20,15 +20,33 @@ #include "AngleMeasureTool.h" #include "MeasureToolsToolbox.h" +#include "LayerHolder.h" #include #include +#include -extern void TrackerSample_SetInfoDisplayMessage(std::string key, std::string value); +// +// REMOVE THIS +#ifndef NDEBUG +extern void +TrackerSample_SetInfoDisplayMessage(std::string key, std::string value); +#endif +// namespace OrthancStone { + // the params in the LayerHolder ctor specify the number of polyline and text + // layers + AngleMeasureTool::AngleMeasureTool( + MessageBroker& broker, ViewportControllerWPtr controllerW) + : MeasureTool(broker, controllerW) + , layerHolder_(boost::make_shared(controllerW,1,5)) + { + + } + AngleMeasureTool::~AngleMeasureTool() { // this measuring tool is a RABI for the corresponding visual layers @@ -39,12 +57,9 @@ void AngleMeasureTool::RemoveFromScene() { - if (layersCreated) + if (layerHolder_->AreLayersCreated() && IsSceneAlive()) { - assert(GetScene()->HasLayer(polylineZIndex_)); - assert(GetScene()->HasLayer(textBaseZIndex_)); - GetScene()->DeleteLayer(polylineZIndex_); - GetScene()->DeleteLayer(textBaseZIndex_); + layerHolder_->DeleteLayers(); } } @@ -66,79 +81,25 @@ RefreshScene(); } - PolylineSceneLayer* AngleMeasureTool::GetPolylineLayer() - { - assert(GetScene()->HasLayer(polylineZIndex_)); - ISceneLayer* layer = &(GetScene()->GetLayer(polylineZIndex_)); - PolylineSceneLayer* concreteLayer = dynamic_cast(layer); - assert(concreteLayer != NULL); - return concreteLayer; - } - void AngleMeasureTool::RefreshScene() { if (IsSceneAlive()) { - if (IsEnabled()) { // get the scaling factor const double pixelToScene = GetScene()->GetCanvasToSceneTransform().ComputeZoom(); - if (!layersCreated) - { - // Create the layers if need be - - assert(textBaseZIndex_ == -1); - { - polylineZIndex_ = GetScene()->GetMaxDepth() + 100; - //LOG(INFO) << "set polylineZIndex_ to: " << polylineZIndex_; - std::auto_ptr layer(new PolylineSceneLayer()); - GetScene()->SetLayer(polylineZIndex_, layer.release()); + layerHolder_->CreateLayersIfNeeded(); - } - { - textBaseZIndex_ = GetScene()->GetMaxDepth() + 100; - // create the four text background layers - { - std::auto_ptr layer(new TextSceneLayer()); - GetScene()->SetLayer(textBaseZIndex_, layer.release()); - } - { - std::auto_ptr layer(new TextSceneLayer()); - GetScene()->SetLayer(textBaseZIndex_ + 1, layer.release()); - } - { - std::auto_ptr layer(new TextSceneLayer()); - GetScene()->SetLayer(textBaseZIndex_ + 2, layer.release()); - } - { - std::auto_ptr layer(new TextSceneLayer()); - GetScene()->SetLayer(textBaseZIndex_ + 3, layer.release()); - } - - // and the text layer itself - { - std::auto_ptr layer(new TextSceneLayer()); - GetScene()->SetLayer(textBaseZIndex_ + 4, layer.release()); - } - - } - layersCreated = true; - } - else { - assert(GetScene()->HasLayer(polylineZIndex_)); - assert(GetScene()->HasLayer(textBaseZIndex_)); - } - { - // Fill the polyline layer with the measurement line - - PolylineSceneLayer* polylineLayer = GetPolylineLayer(); + // Fill the polyline layer with the measurement lines + PolylineSceneLayer* polylineLayer = layerHolder_->GetPolylineLayer(0); polylineLayer->ClearAllChains(); polylineLayer->SetColor(0, 183, 17); + // sides { { @@ -155,30 +116,29 @@ } } - // handles + // Create the handles { - //void AddSquare(PolylineSceneLayer::Chain& chain,const Scene2D& scene,const ScenePoint2D& centerS,const double& sideLength) - { PolylineSceneLayer::Chain chain; - AddSquare(chain, *GetScene(), side1End_, 10.0 * pixelToScene); //TODO: take DPI into account + //TODO: take DPI into account + AddSquare(chain, GetScene(), side1End_, 10.0 * pixelToScene); polylineLayer->AddChain(chain, true); } - { PolylineSceneLayer::Chain chain; - AddSquare(chain, *GetScene(), side2End_, 10.0 * pixelToScene); //TODO: take DPI into account + //TODO: take DPI into account + AddSquare(chain, GetScene(), side2End_, 10.0 * pixelToScene); polylineLayer->AddChain(chain, true); } } - // arc + // Create the arc { PolylineSceneLayer::Chain chain; const double ARC_RADIUS_CANVAS_COORD = 30.0; - AddShortestArc(chain, *GetScene(), side1End_, center_, side2End_, - ARC_RADIUS_CANVAS_COORD * pixelToScene); + AddShortestArc(chain, side1End_, center_, side2End_, + ARC_RADIUS_CANVAS_COORD * pixelToScene); polylineLayer->AddChain(chain, false); } } @@ -189,21 +149,16 @@ side1End_.GetY() - center_.GetY(), side1End_.GetX() - center_.GetX()); - double p2cAngle = atan2( side2End_.GetY() - center_.GetY(), side2End_.GetX() - center_.GetX()); double delta = NormalizeAngle(p2cAngle - p1cAngle); - - double theta = p1cAngle + delta / 2; - const double TEXT_CENTER_DISTANCE_CANVAS_COORD = 90; double offsetX = TEXT_CENTER_DISTANCE_CANVAS_COORD * cos(theta); - double offsetY = TEXT_CENTER_DISTANCE_CANVAS_COORD * sin(theta); double pointX = center_.GetX() + offsetX * pixelToScene; @@ -216,7 +171,7 @@ sprintf(buf, "%0.02f\xc2\xb0", angleDeg); SetTextLayerOutlineProperties( - *GetScene(), textBaseZIndex_, buf, ScenePoint2D(pointX, pointY)); + GetScene(), layerHolder_, buf, ScenePoint2D(pointX, pointY)); // TODO:make it togglable bool enableInfoDisplay = false; @@ -267,18 +222,11 @@ TrackerSample_SetInfoDisplayMessage("angleDeg", boost::lexical_cast(angleDeg)); } - - - } } else { - if (layersCreated) - { - RemoveFromScene(); - layersCreated = false; - } + RemoveFromScene(); } } } diff -r f7c236894c1a -r 8c97c381f242 Framework/Scene2DViewport/AngleMeasureTool.h --- a/Framework/Scene2DViewport/AngleMeasureTool.h Wed May 22 17:05:14 2019 +0200 +++ b/Framework/Scene2DViewport/AngleMeasureTool.h Wed May 22 17:05:38 2019 +0200 @@ -21,6 +21,8 @@ #pragma once #include "MeasureTools.h" + +#include "../Scene2DViewport/LayerHolder.h" #include "../Scene2D/Scene2D.h" #include "../Scene2D/ScenePoint2D.h" #include "../Scene2D/PolylineSceneLayer.h" @@ -37,14 +39,7 @@ class AngleMeasureTool : public MeasureTool { public: - AngleMeasureTool(MessageBroker& broker, ViewportControllerWPtr controllerW) - : MeasureTool(broker, controllerW) - , layersCreated(false) - , polylineZIndex_(-1) - , textBaseZIndex_(-1) - { - - } + AngleMeasureTool(MessageBroker& broker, ViewportControllerWPtr controllerW); ~AngleMeasureTool(); @@ -53,23 +48,15 @@ void SetSide2End(ScenePoint2D start); private: - PolylineSceneLayer* GetPolylineLayer(); - - // 0 --> 3 are for the text background (outline) - // 4 is for the actual text - TextSceneLayer* GetTextLayer(int index); virtual void RefreshScene() ORTHANC_OVERRIDE; void RemoveFromScene(); private: - ScenePoint2D side1End_; - ScenePoint2D side2End_; - ScenePoint2D center_; - bool layersCreated; - int polylineZIndex_; - int textBaseZIndex_; + ScenePoint2D side1End_; + ScenePoint2D side2End_; + ScenePoint2D center_; + LayerHolderPtr layerHolder_; }; - } diff -r f7c236894c1a -r 8c97c381f242 Framework/Scene2DViewport/LayerHolder.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Scene2DViewport/LayerHolder.cpp Wed May 22 17:05:38 2019 +0200 @@ -0,0 +1,137 @@ +/** + * 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 . + **/ + +#include "LayerHolder.h" +#include "../Scene2D/TextSceneLayer.h" +#include "../Scene2D/PolylineSceneLayer.h" +#include "../Scene2D/Scene2D.h" +#include "../Scene2DViewport/ViewportController.h" +#include "../StoneException.h" + +using namespace Orthanc; + +namespace OrthancStone +{ + LayerHolder::LayerHolder( + ViewportControllerWPtr controllerW, + int polylineLayerCount, + int textLayerCount) + : textLayerCount_(textLayerCount) + , polylineLayerCount_(polylineLayerCount) + , controllerW_(controllerW) + , baseLayerIndex_(-1) + { + + } + + void LayerHolder::CreateLayers() + { + assert(baseLayerIndex_ == -1); + + baseLayerIndex_ = GetScene()->GetMaxDepth() + 100; + + for (int i = 0; i < polylineLayerCount_; ++i) + { + std::auto_ptr layer(new PolylineSceneLayer()); + GetScene()->SetLayer(baseLayerIndex_ + i, layer.release()); + } + + for (int i = 0; i < textLayerCount_; ++i) + { + std::auto_ptr layer(new TextSceneLayer()); + GetScene()->SetLayer( + baseLayerIndex_ + polylineLayerCount_ + i, + layer.release()); + } + + } + + void LayerHolder::CreateLayersIfNeeded() + { + if (baseLayerIndex_ == -1) + CreateLayers(); + } + + bool LayerHolder::AreLayersCreated() const + { + return (baseLayerIndex_ != -1); + } + + OrthancStone::Scene2DPtr LayerHolder::GetScene() + { + ViewportControllerPtr controller = controllerW_.lock(); + ORTHANC_ASSERT(controller.get() != 0, "Zombie attack!"); + return controller->GetScene(); + } + + void LayerHolder::DeleteLayers() + { + for (int i = 0; i < textLayerCount_ + polylineLayerCount_; ++i) + { + ORTHANC_ASSERT(GetScene()->HasLayer(baseLayerIndex_ + i), "No layer"); + GetScene()->DeleteLayer(baseLayerIndex_ + i); + } + baseLayerIndex_ = -1; + } + + PolylineSceneLayer* LayerHolder::GetPolylineLayer(int index /*= 0*/) + { + ORTHANC_ASSERT(baseLayerIndex_ != -1); + ORTHANC_ASSERT(GetScene()->HasLayer(GetPolylineLayerIndex(index))); + ISceneLayer* layer = + &(GetScene()->GetLayer(GetPolylineLayerIndex(index))); + + PolylineSceneLayer* concreteLayer = + dynamic_cast(layer); + + ORTHANC_ASSERT(concreteLayer != NULL); + return concreteLayer; + } + + TextSceneLayer* LayerHolder::GetTextLayer(int index /*= 0*/) + { + ORTHANC_ASSERT(baseLayerIndex_ != -1); + ORTHANC_ASSERT(GetScene()->HasLayer(GetTextLayerIndex(index))); + ISceneLayer* layer = + &(GetScene()->GetLayer(GetTextLayerIndex(index))); + + TextSceneLayer* concreteLayer = + dynamic_cast(layer); + + ORTHANC_ASSERT(concreteLayer != NULL); + return concreteLayer; + } + + int LayerHolder::GetPolylineLayerIndex(int index /*= 0*/) + { + ORTHANC_ASSERT(index < polylineLayerCount_); + return baseLayerIndex_ + index; + } + + + int LayerHolder::GetTextLayerIndex(int index /*= 0*/) + { + ORTHANC_ASSERT(index < textLayerCount_); + + // the text layers are placed right after the polyline layers + // this means they are drawn ON TOP + return baseLayerIndex_ + polylineLayerCount_ + index; + } +} diff -r f7c236894c1a -r 8c97c381f242 Framework/Scene2DViewport/LayerHolder.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Scene2DViewport/LayerHolder.h Wed May 22 17:05:38 2019 +0200 @@ -0,0 +1,99 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + +#pragma once + +#include "PointerTypes.h" +#include "boost/noncopyable.hpp" + +namespace OrthancStone +{ + class PolylineSceneLayer; + class TextSceneLayer; + + /** + This class holds the indices of a set a layer and supplies + getters to the concrete layer objects. Sounds very ad hoc, and it is. + */ + class LayerHolder : public boost::noncopyable + { + public: + /** + This ctor merely stores the scene and layer counts. No layer creation + performed at this time + */ + LayerHolder( + ViewportControllerWPtr controllerW, + int polylineLayerCount, int textLayerCount); + + /** + This actually creates the layers + */ + void CreateLayers(); + + /** + This creates the layers if they are not created yet. Can be useful in + some scenarios + */ + void CreateLayersIfNeeded(); + + /** + Whether the various text and polylines layers have all been created or + none at all + */ + bool AreLayersCreated() const; + + /** + This removes the layers from the scene + */ + void DeleteLayers(); + + /** + Please note that the returned pointer belongs to the scene.Don't you dare + storing or deleting it, you fool! + + This throws if the index is not valid or if the layers are not created or + have been deleted + */ + PolylineSceneLayer* GetPolylineLayer(int index = 0); + + /** + Please note that the returned pointer belongs to the scene. Don't you dare + storing or deleting it, you fool! + + This throws if the index is not valid or if the layers are not created or + have been deleted + */ + TextSceneLayer* GetTextLayer(int index = 0); + + private: + int GetPolylineLayerIndex(int index = 0); + int GetTextLayerIndex(int index = 0); + Scene2DPtr GetScene(); + + int textLayerCount_; + int polylineLayerCount_; + ViewportControllerWPtr controllerW_; + int baseLayerIndex_; + }; + + typedef boost::shared_ptr LayerHolderPtr; +} + diff -r f7c236894c1a -r 8c97c381f242 Framework/Scene2DViewport/LineMeasureTool.cpp --- a/Framework/Scene2DViewport/LineMeasureTool.cpp Wed May 22 17:05:14 2019 +0200 +++ b/Framework/Scene2DViewport/LineMeasureTool.cpp Wed May 22 17:05:38 2019 +0200 @@ -20,12 +20,23 @@ #include "LineMeasureTool.h" #include "MeasureToolsToolbox.h" +#include "LayerHolder.h" #include +#include namespace OrthancStone { + + LineMeasureTool::LineMeasureTool( + MessageBroker& broker, ViewportControllerWPtr controllerW) + : MeasureTool(broker, controllerW) + , layerHolder_(boost::make_shared(controllerW, 1, 5)) + { + + } + LineMeasureTool::~LineMeasureTool() { // this measuring tool is a RABI for the corresponding visual layers @@ -36,16 +47,12 @@ void LineMeasureTool::RemoveFromScene() { - if (layersCreated) + if (layerHolder_->AreLayersCreated() && IsSceneAlive()) { - assert(GetScene()->HasLayer(polylineZIndex_)); - assert(GetScene()->HasLayer(textZIndex_)); - GetScene()->DeleteLayer(polylineZIndex_); - GetScene()->DeleteLayer(textZIndex_); + layerHolder_->DeleteLayers(); } } - - + void LineMeasureTool::SetStart(ScenePoint2D start) { start_ = start; @@ -65,58 +72,22 @@ RefreshScene(); } - PolylineSceneLayer* LineMeasureTool::GetPolylineLayer() - { - assert(GetScene()->HasLayer(polylineZIndex_)); - ISceneLayer* layer = &(GetScene()->GetLayer(polylineZIndex_)); - PolylineSceneLayer* concreteLayer = dynamic_cast(layer); - assert(concreteLayer != NULL); - return concreteLayer; - } - - TextSceneLayer* LineMeasureTool::GetTextLayer() - { - assert(GetScene()->HasLayer(textZIndex_)); - ISceneLayer* layer = &(GetScene()->GetLayer(textZIndex_)); - TextSceneLayer* concreteLayer = dynamic_cast(layer); - assert(concreteLayer != NULL); - return concreteLayer; - } - void LineMeasureTool::RefreshScene() { if (IsSceneAlive()) { if (IsEnabled()) { - if (!layersCreated) - { - // Create the layers if need be + // get the scaling factor + const double pixelToScene = + GetScene()->GetCanvasToSceneTransform().ComputeZoom(); - assert(textZIndex_ == -1); - { - polylineZIndex_ = GetScene()->GetMaxDepth() + 100; - //LOG(INFO) << "set polylineZIndex_ to: " << polylineZIndex_; - std::auto_ptr layer(new PolylineSceneLayer()); - GetScene()->SetLayer(polylineZIndex_, layer.release()); - } - { - textZIndex_ = GetScene()->GetMaxDepth() + 100; - //LOG(INFO) << "set textZIndex_ to: " << textZIndex_; - std::auto_ptr layer(new TextSceneLayer()); - GetScene()->SetLayer(textZIndex_, layer.release()); - } - layersCreated = true; - } - else - { - assert(GetScene()->HasLayer(polylineZIndex_)); - assert(GetScene()->HasLayer(textZIndex_)); - } + layerHolder_->CreateLayersIfNeeded(); + { // Fill the polyline layer with the measurement line - PolylineSceneLayer* polylineLayer = GetPolylineLayer(); + PolylineSceneLayer* polylineLayer = layerHolder_->GetPolylineLayer(0); polylineLayer->ClearAllChains(); polylineLayer->SetColor(0, 223, 21); @@ -133,68 +104,46 @@ { PolylineSceneLayer::Chain chain; - AddSquare(chain, *GetScene(), start_, 10.0); //TODO: take DPI into account + + //TODO: take DPI into account + AddSquare(chain, GetScene(), start_, 10.0 * pixelToScene); + polylineLayer->AddChain(chain, true); } { PolylineSceneLayer::Chain chain; - AddSquare(chain, *GetScene(), end_, 10.0); //TODO: take DPI into account + + //TODO: take DPI into account + AddSquare(chain, GetScene(), end_, 10.0 * pixelToScene); + polylineLayer->AddChain(chain, true); } - - //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); - - //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 - TextSceneLayer* textLayer = GetTextLayer(); double deltaX = end_.GetX() - start_.GetX(); double deltaY = end_.GetY() - start_.GetY(); double squareDist = deltaX * deltaX + deltaY * deltaY; double dist = sqrt(squareDist); char buf[64]; sprintf(buf, "%0.02f units", dist); - textLayer->SetText(buf); - textLayer->SetColor(0, 223, 21); // TODO: for now we simply position the text overlay at the middle // of the measuring segment double midX = 0.5 * (end_.GetX() + start_.GetX()); double midY = 0.5 * (end_.GetY() + start_.GetY()); - textLayer->SetPosition(midX, midY); + + SetTextLayerOutlineProperties( + GetScene(), layerHolder_, buf, ScenePoint2D(midX, midY)); } } else { - if (layersCreated) - { - RemoveFromScene(); - layersCreated = false; - } + RemoveFromScene(); } } } diff -r f7c236894c1a -r 8c97c381f242 Framework/Scene2DViewport/LineMeasureTool.h --- a/Framework/Scene2DViewport/LineMeasureTool.h Wed May 22 17:05:14 2019 +0200 +++ b/Framework/Scene2DViewport/LineMeasureTool.h Wed May 22 17:05:38 2019 +0200 @@ -37,14 +37,7 @@ class LineMeasureTool : public MeasureTool { public: - LineMeasureTool(MessageBroker& broker, ViewportControllerWPtr controllerW) - : MeasureTool(broker, controllerW) - , layersCreated(false) - , polylineZIndex_(-1) - , textZIndex_(-1) - { - - } + LineMeasureTool(MessageBroker& broker, ViewportControllerWPtr controllerW); ~LineMeasureTool(); @@ -53,17 +46,14 @@ void Set(ScenePoint2D start, ScenePoint2D end); private: - PolylineSceneLayer* GetPolylineLayer(); - TextSceneLayer* GetTextLayer(); virtual void RefreshScene() ORTHANC_OVERRIDE; void RemoveFromScene(); private: - ScenePoint2D start_; - ScenePoint2D end_; - bool layersCreated; - int polylineZIndex_; - int textZIndex_; + ScenePoint2D start_; + ScenePoint2D end_; + LayerHolderPtr layerHolder_; + int baseLayerIndex_; }; } diff -r f7c236894c1a -r 8c97c381f242 Framework/Scene2DViewport/MeasureCommands.cpp --- a/Framework/Scene2DViewport/MeasureCommands.cpp Wed May 22 17:05:14 2019 +0200 +++ b/Framework/Scene2DViewport/MeasureCommands.cpp Wed May 22 17:05:38 2019 +0200 @@ -28,11 +28,13 @@ void CreateMeasureCommand::Undo() { // simply disable the measure tool upon undo + GetMeasureTool()->Disable(); GetController()->RemoveMeasureTool(GetMeasureTool()); } void CreateMeasureCommand::Redo() { + GetMeasureTool()->Enable(); GetController()->AddMeasureTool(GetMeasureTool()); } diff -r f7c236894c1a -r 8c97c381f242 Framework/Scene2DViewport/MeasureTools.h --- a/Framework/Scene2DViewport/MeasureTools.h Wed May 22 17:05:14 2019 +0200 +++ b/Framework/Scene2DViewport/MeasureTools.h Wed May 22 17:05:38 2019 +0200 @@ -92,6 +92,5 @@ }; } - extern void TrackerSample_SetInfoDisplayMessage( std::string key, std::string value); diff -r f7c236894c1a -r 8c97c381f242 Framework/Scene2DViewport/MeasureToolsToolbox.cpp --- a/Framework/Scene2DViewport/MeasureToolsToolbox.cpp Wed May 22 17:05:14 2019 +0200 +++ b/Framework/Scene2DViewport/MeasureToolsToolbox.cpp Wed May 22 17:05:38 2019 +0200 @@ -19,8 +19,11 @@ **/ #include "MeasureToolsToolbox.h" +#include "PointerTypes.h" +#include "LayerHolder.h" #include "../Scene2D/TextSceneLayer.h" +#include "../Scene2D/Scene2D.h" #include @@ -31,6 +34,24 @@ namespace OrthancStone { + void GetPositionOnBisectingLine( + ScenePoint2D& result + , const ScenePoint2D& p1 + , const ScenePoint2D& c + , const ScenePoint2D& p2 + , const double d) + { + // TODO: fix correct half-plane + double p1cAngle = atan2(p1.GetY() - c.GetY(), p1.GetX() - c.GetX()); + double p2cAngle = atan2(p2.GetY() - c.GetY(), p2.GetX() - c.GetX()); + double angle = 0.5 * (p1cAngle + p2cAngle); + double unitVectorX = cos(angle); + double unitVectorY = sin(angle); + double posX = c.GetX() + d * unitVectorX; + double posY = c.GetX() + d * unitVectorY; + result = ScenePoint2D(posX, posY); + } + double RadiansToDegrees(double angleRad) { static const double factor = 180.0 / g_pi; @@ -38,27 +59,31 @@ } void AddSquare(PolylineSceneLayer::Chain& chain, - const Scene2D& scene, + Scene2DConstPtr scene, const ScenePoint2D& centerS, - const double& sideLength) + const double& sideLengthS) { + // get the scaling factor + const double sceneToCanvas = + scene->GetSceneToCanvasTransform().ComputeZoom(); + chain.clear(); chain.reserve(4); - ScenePoint2D centerC = centerS.Apply(scene.GetSceneToCanvasTransform()); + 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; + double handleLX = centerC.GetX() - sideLengthS * sceneToCanvas * 0.5; + double handleTY = centerC.GetY() - sideLengthS * sceneToCanvas * 0.5; + double handleRX = centerC.GetX() + sideLengthS * sceneToCanvas * 0.5; + double handleBY = centerC.GetY() + sideLengthS * sceneToCanvas * 0.5; 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()); + 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); @@ -86,7 +111,6 @@ void AddShortestArc( PolylineSceneLayer::Chain& chain - , const Scene2D& scene , const ScenePoint2D& p1 , const ScenePoint2D& c , const ScenePoint2D& p2 @@ -96,30 +120,11 @@ double p1cAngle = atan2(p1.GetY() - c.GetY(), p1.GetX() - c.GetX()); double p2cAngle = atan2(p2.GetY() - c.GetY(), p2.GetX() - c.GetX()); AddShortestArc( - chain, scene, c, radiusS, p1cAngle, p2cAngle, subdivisionsCount); + chain, c, radiusS, p1cAngle, p2cAngle, subdivisionsCount); } - void GetPositionOnBisectingLine( - ScenePoint2D& result - , const ScenePoint2D& p1 - , const ScenePoint2D& c - , const ScenePoint2D& p2 - , const double d) - { - // TODO: fix correct half-plane - double p1cAngle = atan2(p1.GetY() - c.GetY(), p1.GetX() - c.GetX()); - double p2cAngle = atan2(p2.GetY() - c.GetY(), p2.GetX() - c.GetX()); - double angle = 0.5*(p1cAngle + p2cAngle); - double unitVectorX = cos(angle); - double unitVectorY = sin(angle); - double posX = c.GetX() + d * unitVectorX; - double posY = c.GetX() + d * unitVectorY; - result = ScenePoint2D(posX, posY); - } - void AddShortestArc( PolylineSceneLayer::Chain& chain - , const Scene2D& scene , const ScenePoint2D& centerS , const double& radiusS , const double startAngleRad @@ -197,7 +202,6 @@ #endif void AddCircle(PolylineSceneLayer::Chain& chain, - const Scene2D& scene, const ScenePoint2D& centerS, const double& radiusS, const int numSubdivisions) @@ -278,38 +282,25 @@ #endif - namespace - { - /** - Helper function for outlined text rendering - */ - TextSceneLayer* GetOutlineTextLayer( - Scene2D& scene, int baseLayerIndex, int index) - { - assert(scene.HasLayer(baseLayerIndex)); - assert(index >= 0); - assert(index < 5); - - ISceneLayer * layer = &(scene.GetLayer(baseLayerIndex + index)); - TextSceneLayer * concreteLayer = dynamic_cast(layer); - assert(concreteLayer != NULL); - return concreteLayer; - } - } - + /** + This utility function assumes that the layer holder contains 5 text layers + and will use the first four ones for the text background and the fifth one + for the actual text + */ void SetTextLayerOutlineProperties( - Scene2D& scene, int baseLayerIndex, const char* text, ScenePoint2D p) + Scene2DPtr scene, LayerHolderPtr layerHolder, + const char* text, ScenePoint2D p) { double xoffsets[5] = { 2, 0, -2, 0, 0 }; double yoffsets[5] = { 0, -2, 0, 2, 0 }; // get the scaling factor const double pixelToScene = - scene.GetCanvasToSceneTransform().ComputeZoom(); + scene->GetCanvasToSceneTransform().ComputeZoom(); for (int i = 0; i < 5; ++i) { - TextSceneLayer* textLayer = GetOutlineTextLayer(scene, baseLayerIndex, i); + TextSceneLayer* textLayer = layerHolder->GetTextLayer(i); textLayer->SetText(text); if (i == 4) diff -r f7c236894c1a -r 8c97c381f242 Framework/Scene2DViewport/MeasureToolsToolbox.h --- a/Framework/Scene2DViewport/MeasureToolsToolbox.h Wed May 22 17:05:14 2019 +0200 +++ b/Framework/Scene2DViewport/MeasureToolsToolbox.h Wed May 22 17:05:38 2019 +0200 @@ -18,6 +18,7 @@ * along with this program. If not, see . **/ +#include "PointerTypes.h" #include "../Scene2D/PolylineSceneLayer.h" #include "../Scene2D/Scene2D.h" @@ -30,10 +31,9 @@ square sides are parallel to the canvas boundaries. */ void AddSquare(PolylineSceneLayer::Chain& chain, - const Scene2D& scene, + Scene2DConstPtr scene, const ScenePoint2D& centerS, - const double& sideLength); - + const double& sideLengthS); /** Creates an arc centered on c that goes @@ -49,7 +49,6 @@ */ void AddShortestArc( PolylineSceneLayer::Chain& chain - , const Scene2D& scene , const ScenePoint2D& p1 , const ScenePoint2D& c , const ScenePoint2D& p2 @@ -64,7 +63,6 @@ */ void AddShortestArc( PolylineSceneLayer::Chain& chain - , const Scene2D& scene , const ScenePoint2D& centerS , const double& radiusS , const double startAngleRad @@ -182,6 +180,6 @@ from layerIndex, up to (and not including) layerIndex+5. */ void SetTextLayerOutlineProperties( - Scene2D& scene, int baseLayerIndex, const char* text, ScenePoint2D p); - + Scene2DPtr scene, LayerHolderPtr layerHolder, + const char* text, ScenePoint2D p); } diff -r f7c236894c1a -r 8c97c381f242 Framework/Scene2DViewport/PointerTypes.h --- a/Framework/Scene2DViewport/PointerTypes.h Wed May 22 17:05:14 2019 +0200 +++ b/Framework/Scene2DViewport/PointerTypes.h Wed May 22 17:05:38 2019 +0200 @@ -29,6 +29,7 @@ { class Scene2D; typedef boost::shared_ptr Scene2DPtr; + typedef boost::shared_ptr Scene2DConstPtr; typedef boost::weak_ptr Scene2DWPtr; @@ -69,13 +70,13 @@ typedef boost::shared_ptr CreateAngleMeasureCommandPtr; - - typedef boost::shared_ptr Scene2DPtr; - class TrackerCommand; typedef boost::shared_ptr TrackerCommandPtr; class ViewportController; typedef boost::shared_ptr ViewportControllerPtr; typedef boost::weak_ptr ViewportControllerWPtr; + + class LayerHolder; + typedef boost::shared_ptr LayerHolderPtr; } diff -r f7c236894c1a -r 8c97c381f242 Framework/Scene2DViewport/ViewportController.cpp --- a/Framework/Scene2DViewport/ViewportController.cpp Wed May 22 17:05:14 2019 +0200 +++ b/Framework/Scene2DViewport/ViewportController.cpp Wed May 22 17:05:38 2019 +0200 @@ -128,8 +128,9 @@ { ORTHANC_ASSERT(std::find(measureTools_.begin(), measureTools_.end(), measureTool) != measureTools_.end(), "Measure tool not found"); - measureTools_.push_back(measureTool); + measureTools_.erase( + std::remove(measureTools_.begin(), measureTools_.end(), measureTool), + measureTools_.end()); } - } diff -r f7c236894c1a -r 8c97c381f242 Framework/StoneException.h --- a/Framework/StoneException.h Wed May 22 17:05:14 2019 +0200 +++ b/Framework/StoneException.h Wed May 22 17:05:38 2019 +0200 @@ -115,7 +115,7 @@ // See https://isocpp.org/wiki/faq/misc-technical-issues#macros-with-multi-stmts // (or google "Multiple lines macro C++ faq lite" if link is dead) -#define ORTHANC_ASSERT(cond,streamChainMessage) \ +#define ORTHANC_ASSERT2(cond,streamChainMessage) \ if (!(cond)) { \ std::stringstream sst; \ sst << "Assertion failed. Condition = \"" #cond "\" Message = \"" << streamChainMessage << "\""; \ @@ -123,3 +123,38 @@ throw ::Orthanc::OrthancException(::Orthanc::ErrorCode_InternalError,sstr.c_str()); \ } else (void)0 +#define ORTHANC_ASSERT1(cond) \ + if (!(cond)) { \ + std::stringstream sst; \ + sst << "Assertion failed. Condition = \"" #cond "\""; \ + std::string sstr = sst.str(); \ + throw OrthancException(ErrorCode_InternalError,sstr.c_str()); \ + } else (void)0 + + + +# define ORTHANC_EXPAND( x ) x +# define GET_ORTHANC_ASSERT(_1,_2,NAME,...) NAME +# define ORTHANC_ASSERT(...) ORTHANC_EXPAND(GET_ORTHANC_ASSERT(__VA_ARGS__, ORTHANC_ASSERT2, ORTHANC_ASSERT1, UNUSED)(__VA_ARGS__)) + +/* +Explanation: + +ORTHANC_ASSERT(a) +ORTHANC_EXPAND(GET_ORTHANC_ASSERT(a, ORTHANC_ASSERT2, ORTHANC_ASSERT1, UNUSED)(a)) +ORTHANC_EXPAND(ORTHANC_ASSERT1(a)) +ORTHANC_ASSERT1(a) + +ORTHANC_ASSERT(a,b) +ORTHANC_EXPAND(GET_ORTHANC_ASSERT(a, b, ORTHANC_ASSERT2, ORTHANC_ASSERT1, UNUSED)(a,b)) +ORTHANC_EXPAND(ORTHANC_ASSERT2(a,b)) +ORTHANC_ASSERT2(a,b) + +Note: ORTHANC_EXPAND is required for some older compilers (MS v100 cl.exe ) +*/ + + + + + + diff -r f7c236894c1a -r 8c97c381f242 Resources/CMake/OrthancStoneConfiguration.cmake --- a/Resources/CMake/OrthancStoneConfiguration.cmake Wed May 22 17:05:14 2019 +0200 +++ b/Resources/CMake/OrthancStoneConfiguration.cmake Wed May 22 17:05:38 2019 +0200 @@ -392,7 +392,6 @@ ${ORTHANC_STONE_ROOT}/Framework/Scene2D/TextSceneLayer.cpp ${ORTHANC_STONE_ROOT}/Framework/Scene2D/TextureBaseSceneLayer.cpp ${ORTHANC_STONE_ROOT}/Framework/Scene2D/ZoomSceneTracker.cpp - ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/AngleMeasureTool.cpp ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/AngleMeasureTool.h ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/CreateAngleMeasureTracker.cpp @@ -411,6 +410,8 @@ ${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 ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/LineMeasureTool.cpp ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/LineMeasureTool.h ${ORTHANC_STONE_ROOT}/Framework/Scene2DViewport/MeasureCommands.cpp diff -r f7c236894c1a -r 8c97c381f242 Samples/Sdl/TrackerSampleApp.cpp --- a/Samples/Sdl/TrackerSampleApp.cpp Wed May 22 17:05:14 2019 +0200 +++ b/Samples/Sdl/TrackerSampleApp.cpp Wed May 22 17:05:38 2019 +0200 @@ -158,14 +158,18 @@ { DisplayInfoText(); + // we seed the random number generator for random measure tool + // generation + srand(42); + 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]) + SDL_SCANCODE_LALT < scancodeCount && + keyboardState[SDL_SCANCODE_LALT]) { // The "left-ctrl" key is down, while no tracker is present // Let's display the info text @@ -249,11 +253,48 @@ } break; + case SDLK_m: + // let's create a random measuring tool + + + case SDLK_s: controller_->FitContent(compositor_->GetCanvasWidth(), compositor_->GetCanvasHeight()); break; + case SDLK_z: + LOG(INFO) << "SDLK_z has been pressed. event.key.keysym.mod == " << event.key.keysym.mod; + if (event.key.keysym.mod & KMOD_CTRL) + { + if (controller_->CanUndo()) + { + LOG(INFO) << "Undoing..."; + controller_->Undo(); + } + else + { + LOG(WARNING) << "Nothing to undo!!!"; + } + } + break; + + case SDLK_y: + LOG(INFO) << "SDLK_y has been pressed. event.key.keysym.mod == " << event.key.keysym.mod; + if (event.key.keysym.mod & KMOD_CTRL) + { + if (controller_->CanRedo()) + { + LOG(INFO) << "Redoing..."; + controller_->Redo(); + } + else + { + LOG(WARNING) << "Nothing to redo!!!"; + } + } + break; + case SDLK_c: TakeScreenshot( "screenshot.png", diff -r f7c236894c1a -r 8c97c381f242 Samples/WebAssembly/BasicScene.cpp --- a/Samples/WebAssembly/BasicScene.cpp Wed May 22 17:05:14 2019 +0200 +++ b/Samples/WebAssembly/BasicScene.cpp Wed May 22 17:05:38 2019 +0200 @@ -32,6 +32,7 @@ #include "../../Framework/Scene2D/RotateSceneTracker.h" #include "../../Framework/Scene2D/Scene2D.h" #include "../../Framework/Scene2D/ZoomSceneTracker.h" +#include "../../Framework/Scene2DViewport/ViewportController.h" #include "../../Framework/StoneInitialization.h" #include "../../Framework/OpenGL/WebAssemblyOpenGLContext.h" @@ -40,12 +41,16 @@ #include #include +#include + #include static const unsigned int FONT_SIZE = 32; +using boost::shared_ptr; +using boost::make_shared; -void PrepareScene(OrthancStone::Scene2D& scene) +void PrepareScene(OrthancStone::Scene2DPtr scene) { using namespace OrthancStone; @@ -72,13 +77,13 @@ p[4] = 0; p[5] = 0; - scene.SetLayer(12, new ColorTextureSceneLayer(i)); + scene->SetLayer(12, new ColorTextureSceneLayer(i)); std::auto_ptr l(new ColorTextureSceneLayer(i)); l->SetOrigin(-3, 2); l->SetPixelSpacing(1.5, 1); l->SetAngle(20.0 / 180.0 * M_PI); - scene.SetLayer(14, l.release()); + scene->SetLayer(14, l.release()); } // Texture of 1x1 size @@ -94,7 +99,7 @@ std::auto_ptr l(new ColorTextureSceneLayer(i)); l->SetOrigin(-2, 1); l->SetAngle(20.0 / 180.0 * M_PI); - scene.SetLayer(13, l.release()); + scene->SetLayer(13, l.release()); } // Some lines @@ -126,7 +131,7 @@ layer->AddChain(chain, false); layer->SetColor(0,255, 255); - scene.SetLayer(50, layer.release()); + scene->SetLayer(50, layer.release()); } // Some text @@ -134,37 +139,43 @@ { std::auto_ptr layer(new TextSceneLayer); layer->SetText("Hello"); - scene.SetLayer(100, layer.release()); + scene->SetLayer(100, layer.release()); } } - - - namespace OrthancStone { class WebAssemblyViewport : public boost::noncopyable { private: + // the construction order is important because compositor_ + // will hold a reference to the scene that belong to the + // controller_ object OpenGL::WebAssemblyOpenGLContext context_; - Scene2D scene_; + ViewportControllerPtr controller_; OpenGLCompositor compositor_; void SetupEvents(const std::string& canvas); public: - WebAssemblyViewport(const std::string& canvas) : + WebAssemblyViewport(MessageBroker& broker, const std::string& canvas) : context_(canvas), - compositor_(context_, scene_) + controller_(make_shared(broker)), + compositor_(context_, *controller_->GetScene()) { compositor_.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, FONT_SIZE, Orthanc::Encoding_Latin1); SetupEvents(canvas); } - Scene2D& GetScene() + Scene2DPtr GetScene() { - return scene_; + return controller_->GetScene(); + } + + ViewportControllerPtr GetController() + { + return controller_; } void UpdateSize() @@ -200,17 +211,15 @@ } }; - - class ActiveTracker : public boost::noncopyable { private: - std::auto_ptr tracker_; - std::string canvasIdentifier_; - bool insideCanvas_; + OrthancStone::FlexiblePointerTrackerPtr tracker_; + std::string canvasIdentifier_; + bool insideCanvas_; public: - ActiveTracker(IPointerTracker* tracker, + ActiveTracker(FlexiblePointerTrackerPtr tracker, const WebAssemblyViewport& viewport) : tracker_(tracker), canvasIdentifier_(viewport.GetCanvasIdentifier()), @@ -222,26 +231,32 @@ } } - void Update(const PointerEvent& event) + bool IsAlive() const { - tracker_->Update(event); + return tracker_->IsAlive(); } - void Release() + void PointerMove(const PointerEvent& event) { - tracker_->Release(); + tracker_->PointerMove(event); + } + + void PointerUp(const PointerEvent& event) + { + tracker_->PointerUp(event); } }; } - +static OrthancStone::PointerEvent* ConvertMouseEvent( + const EmscriptenMouseEvent& source, + OrthancStone::WebAssemblyViewport& viewport) +{ + std::auto_ptr target( + new OrthancStone::PointerEvent); -static OrthancStone::PointerEvent* ConvertMouseEvent(const EmscriptenMouseEvent& source, - OrthancStone::WebAssemblyViewport& viewport) -{ - std::auto_ptr target(new OrthancStone::PointerEvent); - - target->AddPosition(viewport.GetPixelCenterCoordinates(source.targetX, source.targetY)); + target->AddPosition(viewport.GetPixelCenterCoordinates( + source.targetX, source.targetY)); target->SetAltModifier(source.altKey); target->SetControlModifier(source.ctrlKey); target->SetShiftModifier(source.shiftKey); @@ -249,9 +264,7 @@ return target.release(); } - -std::auto_ptr tracker_; - +std::auto_ptr tracker_; EM_BOOL OnMouseEvent(int eventType, const EmscriptenMouseEvent *mouseEvent, @@ -273,31 +286,38 @@ std::auto_ptr layer(new OrthancStone::TextSceneLayer); layer->SetText(buf); - viewport.GetScene().SetLayer(100, layer.release()); + viewport.GetScene()->SetLayer(100, layer.release()); viewport.Refresh(); break; } case EMSCRIPTEN_EVENT_MOUSEDOWN: { - std::auto_ptr t; + OrthancStone::FlexiblePointerTrackerPtr t; { - std::auto_ptr event(ConvertMouseEvent(*mouseEvent, viewport)); + std::auto_ptr event( + ConvertMouseEvent(*mouseEvent, viewport)); switch (mouseEvent->button) { case 0: // Left button - t.reset(new OrthancStone::RotateSceneTracker(viewport.GetScene(), *event)); + emscripten_console_log("Creating RotateSceneTracker"); + t.reset(new OrthancStone::RotateSceneTracker( + viewport.GetController(), *event)); break; case 1: // Middle button - t.reset(new OrthancStone::PanSceneTracker(viewport.GetScene(), *event)); + emscripten_console_log("Creating PanSceneTracker"); + LOG(INFO) << "Creating PanSceneTracker" ; + t.reset(new OrthancStone::PanSceneTracker( + viewport.GetController(), *event)); break; case 2: // Right button - t.reset(new OrthancStone::ZoomSceneTracker - (viewport.GetScene(), *event, viewport.GetCanvasWidth())); + emscripten_console_log("Creating ZoomSceneTracker"); + t.reset(new OrthancStone::ZoomSceneTracker( + viewport.GetController(), *event, viewport.GetCanvasWidth())); break; default: @@ -307,7 +327,8 @@ if (t.get() != NULL) { - tracker_.reset(new OrthancStone::ActiveTracker(t.release(), viewport)); + tracker_.reset( + new OrthancStone::ActiveTracker(t, viewport)); viewport.Refresh(); } @@ -317,8 +338,9 @@ case EMSCRIPTEN_EVENT_MOUSEMOVE: if (tracker_.get() != NULL) { - std::auto_ptr event(ConvertMouseEvent(*mouseEvent, viewport)); - tracker_->Update(*event); + std::auto_ptr event( + ConvertMouseEvent(*mouseEvent, viewport)); + tracker_->PointerMove(*event); viewport.Refresh(); } break; @@ -326,9 +348,12 @@ case EMSCRIPTEN_EVENT_MOUSEUP: if (tracker_.get() != NULL) { - tracker_->Release(); + std::auto_ptr event( + ConvertMouseEvent(*mouseEvent, viewport)); + tracker_->PointerUp(*event); viewport.Refresh(); - tracker_.reset(); + if (!tracker_->IsAlive()) + tracker_.reset(); } break; @@ -343,27 +368,22 @@ void OrthancStone::WebAssemblyViewport::SetupEvents(const std::string& canvas) { - if (0) - { - emscripten_set_click_callback(canvas.c_str(), this, false, OnMouseEvent); - } - else - { - emscripten_set_mousedown_callback(canvas.c_str(), this, false, OnMouseEvent); - emscripten_set_mousemove_callback(canvas.c_str(), this, false, OnMouseEvent); - emscripten_set_mouseup_callback(canvas.c_str(), this, false, OnMouseEvent); - } +#if 0 + emscripten_set_click_callback(canvas.c_str(), this, false, OnMouseEvent); +#else + emscripten_set_mousedown_callback(canvas.c_str(), this, false, OnMouseEvent); + emscripten_set_mousemove_callback(canvas.c_str(), this, false, OnMouseEvent); + emscripten_set_mouseup_callback(canvas.c_str(), this, false, OnMouseEvent); +#endif } - - - std::auto_ptr viewport1_; std::auto_ptr viewport2_; std::auto_ptr viewport3_; - +OrthancStone::MessageBroker broker_; -EM_BOOL OnWindowResize(int eventType, const EmscriptenUiEvent *uiEvent, void *userData) +EM_BOOL OnWindowResize( + int eventType, const EmscriptenUiEvent *uiEvent, void *userData) { if (viewport1_.get() != NULL) { @@ -383,28 +403,31 @@ return true; } - - extern "C" { int main(int argc, char const *argv[]) { OrthancStone::StoneInitialize(); + // Orthanc::Logging::EnableInfoLevel(true); + // Orthanc::Logging::EnableTraceLevel(true); EM_ASM(window.dispatchEvent(new CustomEvent("WebAssemblyLoaded"));); } EMSCRIPTEN_KEEPALIVE void Initialize() { - viewport1_.reset(new OrthancStone::WebAssemblyViewport("mycanvas1")); + viewport1_.reset( + new OrthancStone::WebAssemblyViewport(broker_, "mycanvas1")); PrepareScene(viewport1_->GetScene()); viewport1_->UpdateSize(); - viewport2_.reset(new OrthancStone::WebAssemblyViewport("mycanvas2")); + viewport2_.reset( + new OrthancStone::WebAssemblyViewport(broker_, "mycanvas2")); PrepareScene(viewport2_->GetScene()); viewport2_->UpdateSize(); - viewport3_.reset(new OrthancStone::WebAssemblyViewport("mycanvas3")); + viewport3_.reset( + new OrthancStone::WebAssemblyViewport(broker_, "mycanvas3")); PrepareScene(viewport3_->GetScene()); viewport3_->UpdateSize(); diff -r f7c236894c1a -r 8c97c381f242 Samples/WebAssembly/NOTES.txt --- a/Samples/WebAssembly/NOTES.txt Wed May 22 17:05:14 2019 +0200 +++ b/Samples/WebAssembly/NOTES.txt Wed May 22 17:05:38 2019 +0200 @@ -2,3 +2,13 @@ $ cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=${EMSCRIPTEN}/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_BUILD_TYPE=Release -DALLOW_DOWNLOADS=ON .. -DCMAKE_INSTALL_PREFIX=/tmp/stone $ ninja install $ sudo docker run -p 4242:4242 -p 8042:8042 --rm -v /tmp/stone:/root/stone:ro jodogne/orthanc-plugins:1.5.6 /root/stone/Configuration.json --verbose + +notes BGO : +source ~/apps/emsdk/emsdk_env.sh +cd /mnt/c/osi/dev/orthanc-stone/Samples/WebAssembly +mkdir build +cd build +cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=${EMSCRIPTEN}/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_BUILD_TYPE=Release -DALLOW_DOWNLOADS=ON .. -DCMAKE_INSTALL_PREFIX=/mnt/c/osi/dev/orthanc-stone/Samples/WebAssembly/installDir +ninja install + +docker run -p 4242:4242 -p 8042:8042 --rm -v "C:/osi/dev/orthanc-stone/Samples/WebAssembly/installDir:/root/stone:ro" jodogne/orthanc-plugins:1.5.6 /root/stone/Configuration.json --verbose \ No newline at end of file