Mercurial > hg > orthanc-stone
comparison 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 |
comparison
equal
deleted
inserted
replaced
1304:b7fa67bf87fa | 1305:a5326ce4f24b |
---|---|
40 namespace OrthancStone | 40 namespace OrthancStone |
41 { | 41 { |
42 // the params in the LayerHolder ctor specify the number of polyline and text | 42 // the params in the LayerHolder ctor specify the number of polyline and text |
43 // layers | 43 // layers |
44 AngleMeasureTool::AngleMeasureTool( | 44 AngleMeasureTool::AngleMeasureTool( |
45 boost::weak_ptr<ViewportController> controllerW) | 45 IViewport& viewport) |
46 : MeasureTool(controllerW) | 46 : MeasureTool(viewport) |
47 #if ORTHANC_STONE_ENABLE_OUTLINED_TEXT == 1 | 47 #if ORTHANC_STONE_ENABLE_OUTLINED_TEXT == 1 |
48 , layerHolder_(boost::make_shared<LayerHolder>(controllerW,1,5)) | 48 , layerHolder_(boost::make_shared<LayerHolder>(viewport,1,5)) |
49 #else | 49 #else |
50 , layerHolder_(boost::make_shared<LayerHolder>(controllerW, 1, 1)) | 50 , layerHolder_(boost::make_shared<LayerHolder>(viewport, 1, 1)) |
51 #endif | 51 #endif |
52 , angleHighlightArea_(AngleHighlightArea_None) | 52 , angleHighlightArea_(AngleHighlightArea_None) |
53 { | 53 { |
54 RefreshScene(); | 54 RefreshScene(); |
55 } | 55 } |
106 return memento; | 106 return memento; |
107 } | 107 } |
108 | 108 |
109 void AngleMeasureTool::SetMemento(boost::shared_ptr<MeasureToolMemento> mementoBase) | 109 void AngleMeasureTool::SetMemento(boost::shared_ptr<MeasureToolMemento> mementoBase) |
110 { | 110 { |
111 boost::shared_ptr<AngleMeasureToolMemento> memento = boost::dynamic_pointer_cast<AngleMeasureToolMemento>(mementoBase); | 111 boost::shared_ptr<AngleMeasureToolMemento> memento = |
112 boost::dynamic_pointer_cast<AngleMeasureToolMemento>(mementoBase); | |
113 | |
112 ORTHANC_ASSERT(memento.get() != NULL, "Internal error: wrong (or bad) memento"); | 114 ORTHANC_ASSERT(memento.get() != NULL, "Internal error: wrong (or bad) memento"); |
113 center_ = memento->center_; | 115 center_ = memento->center_; |
114 side1End_ = memento->side1End_; | 116 side1End_ = memento->side1End_; |
115 side2End_ = memento->side2End_; | 117 side2End_ = memento->side2End_; |
116 RefreshScene(); | 118 RefreshScene(); |
117 } | 119 } |
118 | 120 |
119 std::string AngleMeasureTool::GetDescription() | 121 std::string AngleMeasureTool::GetDescription() |
120 { | 122 { |
121 std::stringstream ss; | 123 std::stringstream ss; |
122 ss << "AngleMeasureTool. Center = " << center_ << " Side1End = " << side1End_ << " Side2End = " << side2End_; | 124 ss << "AngleMeasureTool. Center = " << center_ << " Side1End = " |
125 << side1End_ << " Side2End = " << side2End_; | |
123 return ss.str(); | 126 return ss.str(); |
124 } | 127 } |
125 | 128 |
126 void AngleMeasureTool::Highlight(ScenePoint2D p) | 129 void AngleMeasureTool::Highlight(ScenePoint2D p) |
127 { | 130 { |
129 SetAngleHighlightArea(angleHighlightArea); | 132 SetAngleHighlightArea(angleHighlightArea); |
130 } | 133 } |
131 | 134 |
132 AngleMeasureTool::AngleHighlightArea AngleMeasureTool::AngleHitTest(ScenePoint2D p) const | 135 AngleMeasureTool::AngleHighlightArea AngleMeasureTool::AngleHitTest(ScenePoint2D p) const |
133 { | 136 { |
134 const double pixelToScene = GetController()->GetScene().GetCanvasToSceneTransform().ComputeZoom(); | 137 std::unique_ptr<IViewport::ILock> lock(viewport_.Lock()); |
135 | 138 ViewportController& controller = lock->GetController(); |
136 const double SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD = pixelToScene * HIT_TEST_MAX_DISTANCE_CANVAS_COORD * pixelToScene * HIT_TEST_MAX_DISTANCE_CANVAS_COORD; | 139 Scene2D& scene = controller.GetScene(); |
137 | 140 |
138 { | 141 const double pixelToScene = scene.GetCanvasToSceneTransform().ComputeZoom(); |
139 const double sqDistanceFromSide1End = ScenePoint2D::SquaredDistancePtPt(p, side1End_); | 142 |
143 const double SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD = | |
144 pixelToScene * HIT_TEST_MAX_DISTANCE_CANVAS_COORD * | |
145 pixelToScene * HIT_TEST_MAX_DISTANCE_CANVAS_COORD; | |
146 | |
147 { | |
148 const double sqDistanceFromSide1End = | |
149 ScenePoint2D::SquaredDistancePtPt(p, side1End_); | |
150 | |
140 if (sqDistanceFromSide1End <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD) | 151 if (sqDistanceFromSide1End <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD) |
141 return AngleHighlightArea_Side1End; | 152 return AngleHighlightArea_Side1End; |
142 } | 153 } |
143 | 154 |
144 { | 155 { |
145 const double sqDistanceFromSide2End = ScenePoint2D::SquaredDistancePtPt(p, side2End_); | 156 const double sqDistanceFromSide2End = |
157 ScenePoint2D::SquaredDistancePtPt(p, side2End_); | |
158 | |
146 if (sqDistanceFromSide2End <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD) | 159 if (sqDistanceFromSide2End <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD) |
147 return AngleHighlightArea_Side2End; | 160 return AngleHighlightArea_Side2End; |
148 } | 161 } |
149 | 162 |
150 { | 163 { |
151 const double sqDistanceFromCenter = ScenePoint2D::SquaredDistancePtPt(p, center_); | 164 const double sqDistanceFromCenter = |
165 ScenePoint2D::SquaredDistancePtPt(p, center_); | |
152 if (sqDistanceFromCenter <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD) | 166 if (sqDistanceFromCenter <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD) |
153 return AngleHighlightArea_Center; | 167 return AngleHighlightArea_Center; |
154 } | 168 } |
155 | 169 |
156 { | 170 { |
157 const double sqDistanceFromSide1 = ScenePoint2D::SquaredDistancePtSegment(center_, side1End_, p); | 171 const double sqDistanceFromSide1 = |
172 ScenePoint2D::SquaredDistancePtSegment(center_, side1End_, p); | |
173 | |
158 if (sqDistanceFromSide1 <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD) | 174 if (sqDistanceFromSide1 <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD) |
159 return AngleHighlightArea_Side1; | 175 return AngleHighlightArea_Side1; |
160 } | 176 } |
161 | 177 |
162 { | 178 { |
163 const double sqDistanceFromSide2 = ScenePoint2D::SquaredDistancePtSegment(center_, side2End_, p); | 179 const double sqDistanceFromSide2 = |
180 ScenePoint2D::SquaredDistancePtSegment(center_, side2End_, p); | |
181 | |
164 if (sqDistanceFromSide2 <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD) | 182 if (sqDistanceFromSide2 <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD) |
165 return AngleHighlightArea_Side2; | 183 return AngleHighlightArea_Side2; |
166 } | 184 } |
167 | 185 |
168 return AngleHighlightArea_None; | 186 return AngleHighlightArea_None; |
169 } | 187 } |
170 | 188 |
171 bool AngleMeasureTool::HitTest(ScenePoint2D p) const | 189 bool AngleMeasureTool::HitTest(ScenePoint2D p) |
172 { | 190 { |
173 return AngleHitTest(p) != AngleHighlightArea_None; | 191 return AngleHitTest(p) != AngleHighlightArea_None; |
174 } | 192 } |
175 | 193 |
176 | 194 |
177 boost::shared_ptr<IFlexiblePointerTracker> AngleMeasureTool::CreateEditionTracker(const PointerEvent& e) | 195 boost::shared_ptr<IFlexiblePointerTracker> AngleMeasureTool::CreateEditionTracker(const PointerEvent& e) |
178 { | 196 { |
197 std::unique_ptr<IViewport::ILock> lock(viewport_.Lock()); | |
198 ViewportController& controller = lock->GetController(); | |
199 Scene2D& scene = controller.GetScene(); | |
200 | |
179 ScenePoint2D scenePos = e.GetMainPosition().Apply( | 201 ScenePoint2D scenePos = e.GetMainPosition().Apply( |
180 GetController()->GetScene().GetCanvasToSceneTransform()); | 202 scene.GetCanvasToSceneTransform()); |
181 | 203 |
182 if (!HitTest(scenePos)) | 204 if (!HitTest(scenePos)) |
183 return boost::shared_ptr<IFlexiblePointerTracker>(); | 205 return boost::shared_ptr<IFlexiblePointerTracker>(); |
184 | 206 |
185 /** | 207 /** |
186 new EditLineMeasureTracker( | 208 new EditLineMeasureTracker( |
187 boost::shared_ptr<LineMeasureTool> measureTool; | 209 boost::shared_ptr<LineMeasureTool> measureTool; |
188 MessageBroker & broker, | 210 MessageBroker & broker, |
189 boost::weak_ptr<ViewportController> controllerW, | 211 IViewport& viewport, |
190 const PointerEvent & e); | 212 const PointerEvent & e); |
191 */ | 213 */ |
192 | 214 |
193 boost::shared_ptr<EditAngleMeasureTracker> editAngleMeasureTracker( | 215 boost::shared_ptr<EditAngleMeasureTracker> editAngleMeasureTracker( |
194 new EditAngleMeasureTracker(shared_from_this(), GetController(), e)); | 216 new EditAngleMeasureTracker(shared_from_this(), viewport_, e)); |
195 return editAngleMeasureTracker; | 217 return editAngleMeasureTracker; |
196 } | 218 } |
197 | 219 |
198 void AngleMeasureTool::SetCenter(ScenePoint2D pt) | 220 void AngleMeasureTool::SetCenter(ScenePoint2D pt) |
199 { | 221 { |
203 | 225 |
204 void AngleMeasureTool::RefreshScene() | 226 void AngleMeasureTool::RefreshScene() |
205 { | 227 { |
206 if (IsSceneAlive()) | 228 if (IsSceneAlive()) |
207 { | 229 { |
208 boost::shared_ptr<ViewportController> controller = GetController(); | 230 std::unique_ptr<IViewport::ILock> lock(viewport_.Lock()); |
231 ViewportController& controller = lock->GetController(); | |
232 Scene2D& scene = controller.GetScene(); | |
233 | |
209 if (IsEnabled()) | 234 if (IsEnabled()) |
210 { | 235 { |
211 layerHolder_->CreateLayersIfNeeded(); | 236 layerHolder_->CreateLayersIfNeeded(); |
212 | 237 |
213 { | 238 { |
215 PolylineSceneLayer* polylineLayer = layerHolder_->GetPolylineLayer(0); | 240 PolylineSceneLayer* polylineLayer = layerHolder_->GetPolylineLayer(0); |
216 if (polylineLayer) | 241 if (polylineLayer) |
217 { | 242 { |
218 polylineLayer->ClearAllChains(); | 243 polylineLayer->ClearAllChains(); |
219 | 244 |
220 const Color color(TOOL_ANGLE_LINES_COLOR_RED, TOOL_ANGLE_LINES_COLOR_GREEN, TOOL_ANGLE_LINES_COLOR_BLUE); | 245 const Color color(TOOL_ANGLE_LINES_COLOR_RED, |
221 const Color highlightColor(TOOL_ANGLE_LINES_HL_COLOR_RED, TOOL_ANGLE_LINES_HL_COLOR_GREEN, TOOL_ANGLE_LINES_HL_COLOR_BLUE); | 246 TOOL_ANGLE_LINES_COLOR_GREEN, |
247 TOOL_ANGLE_LINES_COLOR_BLUE); | |
248 | |
249 const Color highlightColor(TOOL_ANGLE_LINES_HL_COLOR_RED, | |
250 TOOL_ANGLE_LINES_HL_COLOR_GREEN, | |
251 TOOL_ANGLE_LINES_HL_COLOR_BLUE); | |
222 | 252 |
223 // sides | 253 // sides |
224 { | 254 { |
225 { | 255 { |
226 PolylineSceneLayer::Chain chain; | 256 PolylineSceneLayer::Chain chain; |
227 chain.push_back(side1End_); | 257 chain.push_back(side1End_); |
228 chain.push_back(center_); | 258 chain.push_back(center_); |
229 | 259 |
230 if ((angleHighlightArea_ == AngleHighlightArea_Side1) || (angleHighlightArea_ == AngleHighlightArea_Side2)) | 260 if ((angleHighlightArea_ == AngleHighlightArea_Side1) || |
261 (angleHighlightArea_ == AngleHighlightArea_Side2)) | |
262 { | |
231 polylineLayer->AddChain(chain, false, highlightColor); | 263 polylineLayer->AddChain(chain, false, highlightColor); |
264 } | |
232 else | 265 else |
266 { | |
233 polylineLayer->AddChain(chain, false, color); | 267 polylineLayer->AddChain(chain, false, color); |
268 } | |
234 } | 269 } |
235 { | 270 { |
236 PolylineSceneLayer::Chain chain; | 271 PolylineSceneLayer::Chain chain; |
237 chain.push_back(side2End_); | 272 chain.push_back(side2End_); |
238 chain.push_back(center_); | 273 chain.push_back(center_); |
239 if ((angleHighlightArea_ == AngleHighlightArea_Side1) || (angleHighlightArea_ == AngleHighlightArea_Side2)) | 274 if ((angleHighlightArea_ == AngleHighlightArea_Side1) || |
275 (angleHighlightArea_ == AngleHighlightArea_Side2)) | |
276 { | |
240 polylineLayer->AddChain(chain, false, highlightColor); | 277 polylineLayer->AddChain(chain, false, highlightColor); |
278 } | |
241 else | 279 else |
280 { | |
242 polylineLayer->AddChain(chain, false, color); | 281 polylineLayer->AddChain(chain, false, color); |
282 } | |
243 } | 283 } |
244 } | 284 } |
245 | 285 |
246 // Create the handles | 286 // Create the handles |
247 { | 287 { |
248 { | 288 { |
249 PolylineSceneLayer::Chain chain; | 289 PolylineSceneLayer::Chain chain; |
250 //TODO: take DPI into account | 290 //TODO: take DPI into account |
251 AddSquare(chain, controller->GetScene(), side1End_, | 291 AddSquare(chain, controller.GetScene(), side1End_, |
252 GetController()->GetHandleSideLengthS()); | 292 controller.GetHandleSideLengthS()); |
253 | 293 |
254 if (angleHighlightArea_ == AngleHighlightArea_Side1End) | 294 if (angleHighlightArea_ == AngleHighlightArea_Side1End) |
255 polylineLayer->AddChain(chain, true, highlightColor); | 295 polylineLayer->AddChain(chain, true, highlightColor); |
256 else | 296 else |
257 polylineLayer->AddChain(chain, true, color); | 297 polylineLayer->AddChain(chain, true, color); |
258 | 298 |
259 } | 299 } |
260 { | 300 { |
261 PolylineSceneLayer::Chain chain; | 301 PolylineSceneLayer::Chain chain; |
262 //TODO: take DPI into account | 302 //TODO: take DPI into account |
263 AddSquare(chain, controller->GetScene(), side2End_, | 303 AddSquare(chain, controller.GetScene(), side2End_, |
264 GetController()->GetHandleSideLengthS()); | 304 controller.GetHandleSideLengthS()); |
265 | 305 |
266 if (angleHighlightArea_ == AngleHighlightArea_Side2End) | 306 if (angleHighlightArea_ == AngleHighlightArea_Side2End) |
267 polylineLayer->AddChain(chain, true, highlightColor); | 307 polylineLayer->AddChain(chain, true, highlightColor); |
268 else | 308 else |
269 polylineLayer->AddChain(chain, true, color); | 309 polylineLayer->AddChain(chain, true, color); |
273 // Create the arc | 313 // Create the arc |
274 { | 314 { |
275 PolylineSceneLayer::Chain chain; | 315 PolylineSceneLayer::Chain chain; |
276 | 316 |
277 AddShortestArc(chain, side1End_, center_, side2End_, | 317 AddShortestArc(chain, side1End_, center_, side2End_, |
278 controller->GetAngleToolArcRadiusS()); | 318 controller.GetAngleToolArcRadiusS()); |
279 if (angleHighlightArea_ == AngleHighlightArea_Center) | 319 if (angleHighlightArea_ == AngleHighlightArea_Center) |
280 polylineLayer->AddChain(chain, false, highlightColor); | 320 polylineLayer->AddChain(chain, false, highlightColor); |
281 else | 321 else |
282 polylineLayer->AddChain(chain, false, color); | 322 polylineLayer->AddChain(chain, false, color); |
283 } | 323 } |
295 side2End_.GetX() - center_.GetX()); | 335 side2End_.GetX() - center_.GetX()); |
296 | 336 |
297 double delta = NormalizeAngle(p2cAngle - p1cAngle); | 337 double delta = NormalizeAngle(p2cAngle - p1cAngle); |
298 double theta = p1cAngle + delta / 2; | 338 double theta = p1cAngle + delta / 2; |
299 | 339 |
300 double ox = controller->GetAngleTopTextLabelDistanceS() * cos(theta); | 340 double ox = controller.GetAngleTopTextLabelDistanceS() * cos(theta); |
301 double oy = controller->GetAngleTopTextLabelDistanceS() * sin(theta); | 341 double oy = controller.GetAngleTopTextLabelDistanceS() * sin(theta); |
302 | 342 |
303 double pointX = center_.GetX() + ox; | 343 double pointX = center_.GetX() + ox; |
304 double pointY = center_.GetY() + oy; | 344 double pointY = center_.GetY() + oy; |
305 | 345 |
306 char buf[64]; | 346 char buf[64]; |
309 // http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=00B0&mode=hex | 349 // http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=00B0&mode=hex |
310 sprintf(buf, "%0.02f\xc2\xb0", angleDeg); | 350 sprintf(buf, "%0.02f\xc2\xb0", angleDeg); |
311 | 351 |
312 #if ORTHANC_STONE_ENABLE_OUTLINED_TEXT == 1 | 352 #if ORTHANC_STONE_ENABLE_OUTLINED_TEXT == 1 |
313 SetTextLayerOutlineProperties( | 353 SetTextLayerOutlineProperties( |
314 controller->GetScene(), layerHolder_, buf, ScenePoint2D(pointX, pointY), 0); | 354 scene, layerHolder_, buf, ScenePoint2D(pointX, pointY), 0); |
315 #else | 355 #else |
316 SetTextLayerProperties( | 356 SetTextLayerProperties( |
317 controller->GetScene(), layerHolder_, buf, ScenePoint2D(pointX, pointY) , 0); | 357 scene, layerHolder_, buf, ScenePoint2D(pointX, pointY) , 0); |
318 #endif | 358 #endif |
319 | 359 |
320 #if 0 | 360 #if 0 |
321 // TODO:make it togglable | 361 // TODO:make it togglable |
322 bool enableInfoDisplay = true; | 362 bool enableInfoDisplay = true; |
372 } | 412 } |
373 else | 413 else |
374 { | 414 { |
375 RemoveFromScene(); | 415 RemoveFromScene(); |
376 } | 416 } |
417 lock->Invalidate(); | |
377 } | 418 } |
378 } | 419 } |
379 } | 420 } |