diff Framework/Scene2DViewport/LineMeasureTool.cpp @ 880:9953f16c304d am-dev

Merge
author Alain Mazy <alain@mazy.be>
date Fri, 05 Jul 2019 15:33:02 +0200
parents c71ef52602a0
children 0aff28f15ea2
line wrap: on
line diff
--- a/Framework/Scene2DViewport/LineMeasureTool.cpp	Fri Jul 05 14:52:43 2019 +0200
+++ b/Framework/Scene2DViewport/LineMeasureTool.cpp	Fri Jul 05 15:33:02 2019 +0200
@@ -20,6 +20,7 @@
 
 #include "LineMeasureTool.h"
 #include "MeasureToolsToolbox.h"
+#include "EditLineMeasureTracker.h"
 #include "LayerHolder.h"
 
 #include <Core/Logging.h>
@@ -33,6 +34,7 @@
     MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW)
     : MeasureTool(broker, controllerW)
     , layerHolder_(boost::make_shared<LayerHolder>(controllerW, 1, 5))
+    , lineHighlightArea_(LineHighlightArea_None)
   {
 
   }
@@ -72,26 +74,88 @@
     RefreshScene();
   }
 
-  
+  void LineMeasureTool::SetLineHighlightArea(LineHighlightArea area)
+  {
+    if (lineHighlightArea_ != area)
+    {
+      lineHighlightArea_ = area;
+      RefreshScene();
+    }
+  }
 
-  bool LineMeasureTool::HitTest(ScenePoint2D p) const
+  void LineMeasureTool::ResetHighlightState()
+  {
+    SetLineHighlightArea(LineHighlightArea_None);
+  }
+ 
+  void LineMeasureTool::Highlight(ScenePoint2D p)
+  {
+    LineHighlightArea lineHighlightArea = LineHitTest(p);
+    SetLineHighlightArea(lineHighlightArea);
+  }
+
+  LineMeasureTool::LineHighlightArea LineMeasureTool::LineHitTest(ScenePoint2D p) const
   {
     const double pixelToScene =
       GetScene()->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;
 
-    // the hit test will return true if the supplied point (in scene coords)
-    // is close to the handle or to the line.
+    const double sqDistanceFromStart = ScenePoint2D::SquaredDistancePtPt(p, start_);
+    if (sqDistanceFromStart <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD)
+      return LineHighlightArea_Start;
+    
+    const double sqDistanceFromEnd = ScenePoint2D::SquaredDistancePtPt(p, end_);
+    if (sqDistanceFromEnd <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD)
+      return LineHighlightArea_End;
+
+    const double sqDistanceFromPtSegment = ScenePoint2D::SquaredDistancePtSegment(start_, end_, p);
+    if (sqDistanceFromPtSegment <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD)
+      return LineHighlightArea_Segment;
+
+    return LineHighlightArea_None;
+  }
 
-    // since the handle is small, a nice approximation is to defined this
-    // as a threshold on the distance between the point and the handle center.
+  bool LineMeasureTool::HitTest(ScenePoint2D p) const
+  {
+    return LineHitTest(p) != LineHighlightArea_None;
+  }
+
+  boost::shared_ptr<IFlexiblePointerTracker> LineMeasureTool::CreateEditionTracker(const PointerEvent& e)
+  {
+    ScenePoint2D scenePos = e.GetMainPosition().Apply(
+      GetScene()->GetCanvasToSceneTransform());
 
-    // this threshold is defined as a constant value in CANVAS units.
+    if (!HitTest(scenePos))
+      return boost::shared_ptr<IFlexiblePointerTracker>();
+
+    /**
+      new EditLineMeasureTracker(
+        boost::shared_ptr<LineMeasureTool> measureTool;
+        MessageBroker & broker,
+        boost::weak_ptr<ViewportController>          controllerW,
+        const PointerEvent & e);
+    */
+    boost::shared_ptr<EditLineMeasureTracker> editLineMeasureTracker(
+      new EditLineMeasureTracker(shared_from_this(), GetBroker(), GetController(), e));
+    return editLineMeasureTracker;
+  }
 
 
-    // line equation from two points (non-normalized)
-    // (y0-y1)*x + (x1-x0)*xy + (x0*y1 - x1*y0) = 0
-    // 
-    return false;
+  boost::shared_ptr<MeasureToolMemento> LineMeasureTool::GetMemento() const
+  {
+    boost::shared_ptr<LineMeasureToolMemento> memento(new LineMeasureToolMemento());
+    memento->start_ = start_;
+    memento->end_ = end_;
+    return memento;
+  }
+
+  void LineMeasureTool::SetMemento(boost::shared_ptr<MeasureToolMemento> mementoBase)
+  {
+    boost::shared_ptr<LineMeasureToolMemento> memento = boost::dynamic_pointer_cast<LineMeasureToolMemento>(mementoBase);
+    ORTHANC_ASSERT(memento.get() != NULL, "Internal error: wrong (or bad) memento");
+    start_ = memento->start_;
+    end_ = memento->end_;
+    RefreshScene();
   }
 
   void LineMeasureTool::RefreshScene()
@@ -112,11 +176,18 @@
                             TOOL_LINES_COLOR_GREEN, 
                             TOOL_LINES_COLOR_BLUE);
 
+          const Color highlightColor(TOOL_LINES_HL_COLOR_RED,
+                                     TOOL_LINES_HL_COLOR_GREEN,
+                                     TOOL_LINES_HL_COLOR_BLUE);
+
           {
             PolylineSceneLayer::Chain chain;
             chain.push_back(start_);
             chain.push_back(end_);
-            polylineLayer->AddChain(chain, false, color);
+            if(lineHighlightArea_ == LineHighlightArea_Segment)
+              polylineLayer->AddChain(chain, false, highlightColor);
+            else
+              polylineLayer->AddChain(chain, false, color);
           }
 
           // handles
@@ -128,7 +199,10 @@
               AddSquare(chain, GetScene(), start_, 
                 GetController()->GetHandleSideLengthS());
               
-              polylineLayer->AddChain(chain, true, color);
+              if (lineHighlightArea_ == LineHighlightArea_Start)
+                polylineLayer->AddChain(chain, true, highlightColor);
+              else
+                polylineLayer->AddChain(chain, true, color);
             }
 
             {
@@ -138,7 +212,10 @@
               AddSquare(chain, GetScene(), end_, 
                 GetController()->GetHandleSideLengthS());
               
-              polylineLayer->AddChain(chain, true, color);
+              if (lineHighlightArea_ == LineHighlightArea_End)
+                polylineLayer->AddChain(chain, true, highlightColor);
+              else
+                polylineLayer->AddChain(chain, true, color);
             }
           }
 
@@ -150,7 +227,7 @@
           double squareDist = deltaX * deltaX + deltaY * deltaY;
           double dist = sqrt(squareDist);
           char buf[64];
-          sprintf(buf, "%0.02f units", dist);
+          sprintf(buf, "%0.02f mm", dist);
 
           // TODO: for now we simply position the text overlay at the middle
           // of the measuring segment