diff Framework/Scene2DViewport/AngleMeasureTool.cpp @ 1305:a5326ce4f24b broker

Trackers and measuring tools now use the viewport instead of ViewportController, so that proper locks can be used
author Benjamin Golinvaux <bgo@osimis.io>
date Wed, 04 Mar 2020 09:45:38 +0100
parents 7ec8fea061b9
children 1f877e0846fe
line wrap: on
line diff
--- a/Framework/Scene2DViewport/AngleMeasureTool.cpp	Wed Mar 04 09:44:34 2020 +0100
+++ b/Framework/Scene2DViewport/AngleMeasureTool.cpp	Wed Mar 04 09:45:38 2020 +0100
@@ -42,12 +42,12 @@
   // the params in the LayerHolder ctor specify the number of polyline and text
   // layers
   AngleMeasureTool::AngleMeasureTool(
-    boost::weak_ptr<ViewportController> controllerW)
-    : MeasureTool(controllerW)
+    IViewport& viewport)
+    : MeasureTool(viewport)
 #if ORTHANC_STONE_ENABLE_OUTLINED_TEXT == 1
-    , layerHolder_(boost::make_shared<LayerHolder>(controllerW,1,5))
+    , layerHolder_(boost::make_shared<LayerHolder>(viewport,1,5))
 #else
-    , layerHolder_(boost::make_shared<LayerHolder>(controllerW, 1, 1))
+    , layerHolder_(boost::make_shared<LayerHolder>(viewport, 1, 1))
 #endif
     , angleHighlightArea_(AngleHighlightArea_None)
   {
@@ -108,7 +108,9 @@
   
   void AngleMeasureTool::SetMemento(boost::shared_ptr<MeasureToolMemento> mementoBase)
   {
-    boost::shared_ptr<AngleMeasureToolMemento> memento = boost::dynamic_pointer_cast<AngleMeasureToolMemento>(mementoBase);
+    boost::shared_ptr<AngleMeasureToolMemento> memento = 
+      boost::dynamic_pointer_cast<AngleMeasureToolMemento>(mementoBase);
+
     ORTHANC_ASSERT(memento.get() != NULL, "Internal error: wrong (or bad) memento");
     center_   = memento->center_;
     side1End_ = memento->side1End_;
@@ -119,7 +121,8 @@
   std::string AngleMeasureTool::GetDescription()
   {
     std::stringstream ss;
-    ss << "AngleMeasureTool. Center = " << center_ << " Side1End = " << side1End_ << " Side2End = " << side2End_;
+    ss << "AngleMeasureTool. Center = " << center_ << " Side1End = " 
+       << side1End_ << " Side2End = " << side2End_;
     return ss.str();
   }
 
@@ -131,36 +134,51 @@
 
   AngleMeasureTool::AngleHighlightArea AngleMeasureTool::AngleHitTest(ScenePoint2D p) const
   {
-    const double pixelToScene = GetController()->GetScene().GetCanvasToSceneTransform().ComputeZoom();
+    std::unique_ptr<IViewport::ILock> lock(viewport_.Lock());
+    ViewportController& controller = lock->GetController();
+    Scene2D& scene = controller.GetScene();
 
-    const double SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD = pixelToScene * HIT_TEST_MAX_DISTANCE_CANVAS_COORD * pixelToScene * HIT_TEST_MAX_DISTANCE_CANVAS_COORD;
+    const double pixelToScene = scene.GetCanvasToSceneTransform().ComputeZoom();
+
+    const double SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD = 
+      pixelToScene * HIT_TEST_MAX_DISTANCE_CANVAS_COORD * 
+      pixelToScene * HIT_TEST_MAX_DISTANCE_CANVAS_COORD;
 
     {
-      const double sqDistanceFromSide1End = ScenePoint2D::SquaredDistancePtPt(p, side1End_);
+      const double sqDistanceFromSide1End = 
+        ScenePoint2D::SquaredDistancePtPt(p, side1End_);
+
       if (sqDistanceFromSide1End <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD)
         return AngleHighlightArea_Side1End;
     }
 
     {
-      const double sqDistanceFromSide2End = ScenePoint2D::SquaredDistancePtPt(p, side2End_);
+      const double sqDistanceFromSide2End = 
+        ScenePoint2D::SquaredDistancePtPt(p, side2End_);
+
       if (sqDistanceFromSide2End <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD)
         return AngleHighlightArea_Side2End;
     }
 
     {
-      const double sqDistanceFromCenter = ScenePoint2D::SquaredDistancePtPt(p, center_);
+      const double sqDistanceFromCenter = 
+        ScenePoint2D::SquaredDistancePtPt(p, center_);
       if (sqDistanceFromCenter <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD)
         return AngleHighlightArea_Center;
     }
 
     {
-      const double sqDistanceFromSide1 = ScenePoint2D::SquaredDistancePtSegment(center_, side1End_, p);
+      const double sqDistanceFromSide1 = 
+        ScenePoint2D::SquaredDistancePtSegment(center_, side1End_, p);
+
       if (sqDistanceFromSide1 <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD)
         return AngleHighlightArea_Side1;
     }
 
     {
-      const double sqDistanceFromSide2 = ScenePoint2D::SquaredDistancePtSegment(center_, side2End_, p);
+      const double sqDistanceFromSide2 = 
+        ScenePoint2D::SquaredDistancePtSegment(center_, side2End_, p);
+
       if (sqDistanceFromSide2 <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD)
         return AngleHighlightArea_Side2;
     }
@@ -168,7 +186,7 @@
     return AngleHighlightArea_None;
   }
 
-  bool AngleMeasureTool::HitTest(ScenePoint2D p) const
+  bool AngleMeasureTool::HitTest(ScenePoint2D p)
   {
     return AngleHitTest(p) != AngleHighlightArea_None;
   }
@@ -176,8 +194,12 @@
 
   boost::shared_ptr<IFlexiblePointerTracker> AngleMeasureTool::CreateEditionTracker(const PointerEvent& e)
   {
+    std::unique_ptr<IViewport::ILock> lock(viewport_.Lock());
+    ViewportController& controller = lock->GetController();
+    Scene2D& scene = controller.GetScene();
+
     ScenePoint2D scenePos = e.GetMainPosition().Apply(
-      GetController()->GetScene().GetCanvasToSceneTransform());
+      scene.GetCanvasToSceneTransform());
 
     if (!HitTest(scenePos))
       return boost::shared_ptr<IFlexiblePointerTracker>();
@@ -186,12 +208,12 @@
       new EditLineMeasureTracker(
         boost::shared_ptr<LineMeasureTool> measureTool;
         MessageBroker & broker,
-        boost::weak_ptr<ViewportController>          controllerW,
+        IViewport&          viewport,
         const PointerEvent & e);
     */
 
     boost::shared_ptr<EditAngleMeasureTracker> editAngleMeasureTracker(
-      new EditAngleMeasureTracker(shared_from_this(), GetController(), e));
+      new EditAngleMeasureTracker(shared_from_this(), viewport_, e));
     return editAngleMeasureTracker;
   }
 
@@ -205,7 +227,10 @@
   {
     if (IsSceneAlive())
     {
-      boost::shared_ptr<ViewportController> controller = GetController();
+      std::unique_ptr<IViewport::ILock> lock(viewport_.Lock());
+      ViewportController& controller = lock->GetController();
+      Scene2D& scene = controller.GetScene();
+
       if (IsEnabled())
       {
         layerHolder_->CreateLayersIfNeeded();
@@ -217,8 +242,13 @@
           {
             polylineLayer->ClearAllChains();
 
-            const Color color(TOOL_ANGLE_LINES_COLOR_RED, TOOL_ANGLE_LINES_COLOR_GREEN, TOOL_ANGLE_LINES_COLOR_BLUE);
-            const Color highlightColor(TOOL_ANGLE_LINES_HL_COLOR_RED, TOOL_ANGLE_LINES_HL_COLOR_GREEN, TOOL_ANGLE_LINES_HL_COLOR_BLUE);
+            const Color color(TOOL_ANGLE_LINES_COLOR_RED, 
+                              TOOL_ANGLE_LINES_COLOR_GREEN, 
+                              TOOL_ANGLE_LINES_COLOR_BLUE);
+
+            const Color highlightColor(TOOL_ANGLE_LINES_HL_COLOR_RED, 
+                                       TOOL_ANGLE_LINES_HL_COLOR_GREEN, 
+                                       TOOL_ANGLE_LINES_HL_COLOR_BLUE);
 
             // sides
             {
@@ -227,19 +257,29 @@
                 chain.push_back(side1End_);
                 chain.push_back(center_);
 
-                if ((angleHighlightArea_ == AngleHighlightArea_Side1) || (angleHighlightArea_ == AngleHighlightArea_Side2))
+                if ((angleHighlightArea_ == AngleHighlightArea_Side1) ||
+                    (angleHighlightArea_ == AngleHighlightArea_Side2))
+                {
                   polylineLayer->AddChain(chain, false, highlightColor);
+                } 
                 else
+                {
                   polylineLayer->AddChain(chain, false, color);
+                }
               }
               {
                 PolylineSceneLayer::Chain chain;
                 chain.push_back(side2End_);
                 chain.push_back(center_);
-                if ((angleHighlightArea_ == AngleHighlightArea_Side1) || (angleHighlightArea_ == AngleHighlightArea_Side2))
+                if ((angleHighlightArea_ == AngleHighlightArea_Side1) ||
+                  (angleHighlightArea_ == AngleHighlightArea_Side2))
+                {
                   polylineLayer->AddChain(chain, false, highlightColor);
+                }
                 else
+                {
                   polylineLayer->AddChain(chain, false, color);
+                }
               }
             }
 
@@ -248,8 +288,8 @@
               {
                 PolylineSceneLayer::Chain chain;
                 //TODO: take DPI into account
-                AddSquare(chain, controller->GetScene(), side1End_, 
-                          GetController()->GetHandleSideLengthS());
+                AddSquare(chain, controller.GetScene(), side1End_, 
+                          controller.GetHandleSideLengthS());
               
                 if (angleHighlightArea_ == AngleHighlightArea_Side1End)
                   polylineLayer->AddChain(chain, true, highlightColor);
@@ -260,8 +300,8 @@
               {
                 PolylineSceneLayer::Chain chain;
                 //TODO: take DPI into account
-                AddSquare(chain, controller->GetScene(), side2End_, 
-                          GetController()->GetHandleSideLengthS());
+                AddSquare(chain, controller.GetScene(), side2End_, 
+                          controller.GetHandleSideLengthS());
 
                 if (angleHighlightArea_ == AngleHighlightArea_Side2End)
                   polylineLayer->AddChain(chain, true, highlightColor);
@@ -275,7 +315,7 @@
               PolylineSceneLayer::Chain chain;
 
               AddShortestArc(chain, side1End_, center_, side2End_,
-                             controller->GetAngleToolArcRadiusS());
+                             controller.GetAngleToolArcRadiusS());
               if (angleHighlightArea_ == AngleHighlightArea_Center)
                 polylineLayer->AddChain(chain, false, highlightColor);
               else
@@ -297,8 +337,8 @@
           double delta = NormalizeAngle(p2cAngle - p1cAngle);
           double theta = p1cAngle + delta / 2;
 
-          double ox = controller->GetAngleTopTextLabelDistanceS() * cos(theta);
-          double oy = controller->GetAngleTopTextLabelDistanceS() * sin(theta);
+          double ox = controller.GetAngleTopTextLabelDistanceS() * cos(theta);
+          double oy = controller.GetAngleTopTextLabelDistanceS() * sin(theta);
 
           double pointX = center_.GetX() + ox;
           double pointY = center_.GetY() + oy;
@@ -311,10 +351,10 @@
 
 #if ORTHANC_STONE_ENABLE_OUTLINED_TEXT == 1
           SetTextLayerOutlineProperties(
-            controller->GetScene(), layerHolder_, buf, ScenePoint2D(pointX, pointY), 0);
+            scene, layerHolder_, buf, ScenePoint2D(pointX, pointY), 0);
 #else
           SetTextLayerProperties(
-            controller->GetScene(), layerHolder_, buf, ScenePoint2D(pointX, pointY) , 0);
+            scene, layerHolder_, buf, ScenePoint2D(pointX, pointY) , 0);
 #endif
 
 #if 0
@@ -374,6 +414,7 @@
       {
         RemoveFromScene();
       }
+      lock->Invalidate();
     }
   }
 }