comparison 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
comparison
equal deleted inserted replaced
864:ae3eccd0f545 865:a29c13497557
31 31
32 LineMeasureTool::LineMeasureTool( 32 LineMeasureTool::LineMeasureTool(
33 MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW) 33 MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW)
34 : MeasureTool(broker, controllerW) 34 : MeasureTool(broker, controllerW)
35 , layerHolder_(boost::make_shared<LayerHolder>(controllerW, 1, 5)) 35 , layerHolder_(boost::make_shared<LayerHolder>(controllerW, 1, 5))
36 , lineHighlightArea_(LineHighlightArea_None)
36 { 37 {
37 38
38 } 39 }
39 40
40 LineMeasureTool::~LineMeasureTool() 41 LineMeasureTool::~LineMeasureTool()
70 start_ = start; 71 start_ = start;
71 end_ = end; 72 end_ = end;
72 RefreshScene(); 73 RefreshScene();
73 } 74 }
74 75
75 76 void LineMeasureTool::SetLineHighlightArea(LineHighlightArea area)
76 77 {
77 bool LineMeasureTool::HitTest(ScenePoint2D p) const 78 if (lineHighlightArea_ != area)
79 {
80 lineHighlightArea_ = area;
81 RefreshScene();
82 }
83 }
84
85 void LineMeasureTool::ResetHighlightState()
86 {
87 SetLineHighlightArea(LineHighlightArea_None);
88 }
89
90 void LineMeasureTool::Highlight(ScenePoint2D p)
91 {
92 LineHighlightArea lineHighlightArea = LineHitTest(p);
93 SetLineHighlightArea(lineHighlightArea);
94 }
95
96 LineMeasureTool::LineHighlightArea LineMeasureTool::LineHitTest(ScenePoint2D p) const
78 { 97 {
79 const double pixelToScene = 98 const double pixelToScene =
80 GetScene()->GetCanvasToSceneTransform().ComputeZoom(); 99 GetScene()->GetCanvasToSceneTransform().ComputeZoom();
81 100 const double SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD = pixelToScene * HIT_TEST_MAX_DISTANCE_CANVAS_COORD * pixelToScene * HIT_TEST_MAX_DISTANCE_CANVAS_COORD;
82 // the hit test will return true if the supplied point (in scene coords) 101
83 // is close to the handle or to the line. 102 const double sqDistanceFromStart = ScenePoint2D::SquaredDistancePtPt(p, start_);
84 103 if (sqDistanceFromStart <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD)
85 // since the handle is small, a nice approximation is to defined this 104 return LineHighlightArea_Start;
86 // as a threshold on the distance between the point and the handle center. 105
87 106 const double sqDistanceFromEnd = ScenePoint2D::SquaredDistancePtPt(p, end_);
88 // this threshold is defined as a constant value in CANVAS units. 107 if (sqDistanceFromEnd <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD)
89 108 return LineHighlightArea_End;
90 109
91 // line equation from two points (non-normalized) 110 const double sqDistanceFromPtSegment = ScenePoint2D::SquaredDistancePtSegment(start_, end_, p);
92 // (y0-y1)*x + (x1-x0)*xy + (x0*y1 - x1*y0) = 0 111 if (sqDistanceFromPtSegment <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD)
93 // 112 return LineHighlightArea_Segment;
94 return false; 113
114 return LineHighlightArea_None;
115 }
116
117 bool LineMeasureTool::HitTest(ScenePoint2D p) const
118 {
119 return LineHitTest(p) != LineHighlightArea_None;
95 } 120 }
96 121
97 void LineMeasureTool::RefreshScene() 122 void LineMeasureTool::RefreshScene()
98 { 123 {
99 if (IsSceneAlive()) 124 if (IsSceneAlive())
110 135
111 const Color color(TOOL_LINES_COLOR_RED, 136 const Color color(TOOL_LINES_COLOR_RED,
112 TOOL_LINES_COLOR_GREEN, 137 TOOL_LINES_COLOR_GREEN,
113 TOOL_LINES_COLOR_BLUE); 138 TOOL_LINES_COLOR_BLUE);
114 139
140 const Color highlightColor(TOOL_LINES_HL_COLOR_RED,
141 TOOL_LINES_HL_COLOR_GREEN,
142 TOOL_LINES_HL_COLOR_BLUE);
143
115 { 144 {
116 PolylineSceneLayer::Chain chain; 145 PolylineSceneLayer::Chain chain;
117 chain.push_back(start_); 146 chain.push_back(start_);
118 chain.push_back(end_); 147 chain.push_back(end_);
119 polylineLayer->AddChain(chain, false, color); 148 if(lineHighlightArea_ == LineHighlightArea_Segment)
149 polylineLayer->AddChain(chain, false, highlightColor);
150 else
151 polylineLayer->AddChain(chain, false, color);
120 } 152 }
121 153
122 // handles 154 // handles
123 { 155 {
124 { 156 {
126 158
127 //TODO: take DPI into account 159 //TODO: take DPI into account
128 AddSquare(chain, GetScene(), start_, 160 AddSquare(chain, GetScene(), start_,
129 GetController()->GetHandleSideLengthS()); 161 GetController()->GetHandleSideLengthS());
130 162
131 polylineLayer->AddChain(chain, true, color); 163 if (lineHighlightArea_ == LineHighlightArea_Start)
164 polylineLayer->AddChain(chain, true, highlightColor);
165 else
166 polylineLayer->AddChain(chain, true, color);
132 } 167 }
133 168
134 { 169 {
135 PolylineSceneLayer::Chain chain; 170 PolylineSceneLayer::Chain chain;
136 171
137 //TODO: take DPI into account 172 //TODO: take DPI into account
138 AddSquare(chain, GetScene(), end_, 173 AddSquare(chain, GetScene(), end_,
139 GetController()->GetHandleSideLengthS()); 174 GetController()->GetHandleSideLengthS());
140 175
141 polylineLayer->AddChain(chain, true, color); 176 if (lineHighlightArea_ == LineHighlightArea_End)
177 polylineLayer->AddChain(chain, true, highlightColor);
178 else
179 polylineLayer->AddChain(chain, true, color);
142 } 180 }
143 } 181 }
144 182
145 } 183 }
146 { 184 {