diff Framework/Scene2DViewport/LineMeasureTool.cpp @ 865:a29c13497557

Added operators to ScenePoint2D + highlight support on MouseOver for measuring tools
author Benjamin Golinvaux <bgo@osimis.io>
date Tue, 25 Jun 2019 15:24:13 +0200
parents ff3559c489c9
children c71ef52602a0
line wrap: on
line diff
--- a/Framework/Scene2DViewport/LineMeasureTool.cpp	Mon Jun 24 19:07:34 2019 +0200
+++ b/Framework/Scene2DViewport/LineMeasureTool.cpp	Tue Jun 25 15:24:13 2019 +0200
@@ -33,6 +33,7 @@
     MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW)
     : MeasureTool(broker, controllerW)
     , layerHolder_(boost::make_shared<LayerHolder>(controllerW, 1, 5))
+    , lineHighlightArea_(LineHighlightArea_None)
   {
 
   }
@@ -72,26 +73,50 @@
     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.
-
-    // 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.
+    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;
 
-    // this threshold is defined as a constant value in CANVAS units.
-
+    const double sqDistanceFromPtSegment = ScenePoint2D::SquaredDistancePtSegment(start_, end_, p);
+    if (sqDistanceFromPtSegment <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD)
+      return LineHighlightArea_Segment;
 
-    // line equation from two points (non-normalized)
-    // (y0-y1)*x + (x1-x0)*xy + (x0*y1 - x1*y0) = 0
-    // 
-    return false;
+    return LineHighlightArea_None;
+  }
+
+  bool LineMeasureTool::HitTest(ScenePoint2D p) const
+  {
+    return LineHitTest(p) != LineHighlightArea_None;
   }
 
   void LineMeasureTool::RefreshScene()
@@ -112,11 +137,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 +160,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 +173,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);
             }
           }