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 }