comparison OrthancStone/Sources/Scene2D/AnnotationsSceneLayer.cpp @ 1981:c074c75cf416

moved drawing primitives from AnnotationsSceneLayer to PolylineSceneLayer
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 31 Oct 2022 08:22:31 +0100
parents 0aac8f552d89
children 20fa913272b7
comparison
equal deleted inserted replaced
1980:0aac8f552d89 1981:c074c75cf416
148 148
149 const Color& GetHoverColor() const 149 const Color& GetHoverColor() const
150 { 150 {
151 return hoverColor_; 151 return hoverColor_;
152 } 152 }
153
154 Color GetActiveColor() const
155 {
156 return (IsHover() ? GetHoverColor() : GetColor());
157 }
153 158
154 virtual bool IsHit(const ScenePoint2D& p, 159 virtual bool IsHit(const ScenePoint2D& p,
155 const Scene2D& scene) const = 0; 160 const Scene2D& scene) const = 0;
156 161
157 // Always called, even if not modified 162 // Always called, even if not modified
235 class AnnotationsSceneLayer::Handle : public GeometricPrimitive 240 class AnnotationsSceneLayer::Handle : public GeometricPrimitive
236 { 241 {
237 public: 242 public:
238 enum Shape { 243 enum Shape {
239 Shape_Square, 244 Shape_Square,
240 Shape_CrossedSquare 245 Shape_CrossedSquare,
246 Shape_Circle,
247 Shape_CrossedCircle
241 }; 248 };
242 249
243 private: 250 private:
244 Shape shape_; 251 Shape shape_;
245 ScenePoint2D center_; 252 ScenePoint2D center_;
246 ScenePoint2D delta_; 253 ScenePoint2D delta_;
247 254
248 void AddChain(PolylineSceneLayer& polyline,
249 const PolylineSceneLayer::Chain& chain) const
250 {
251 if (IsHover())
252 {
253 polyline.AddChain(chain, true /* closed */, GetHoverColor());
254 }
255 else
256 {
257 polyline.AddChain(chain, true /* closed */, GetColor());
258 }
259 }
260
261 void AddRectangle(PolylineSceneLayer& polyline,
262 double x1,
263 double y1,
264 double x2,
265 double y2)
266 {
267 PolylineSceneLayer::Chain chain;
268 chain.resize(4);
269 chain[0] = ScenePoint2D(x1, y1);
270 chain[1] = ScenePoint2D(x2, y1);
271 chain[2] = ScenePoint2D(x2, y2);
272 chain[3] = ScenePoint2D(x1, y2);
273 AddChain(polyline, chain);
274 }
275
276 void AddCross(PolylineSceneLayer& polyline, 255 void AddCross(PolylineSceneLayer& polyline,
277 double x1, 256 double x1,
278 double y1, 257 double y1,
279 double x2, 258 double x2,
280 double y2) 259 double y2)
281 { 260 {
282 const double halfX = (x1 + x2) / 2.0; 261 const double halfX = (x1 + x2) / 2.0;
283 const double halfY = (y1 + y2) / 2.0; 262 const double halfY = (y1 + y2) / 2.0;
284 263 polyline.AddSegment(x1, halfY, x2, halfY, GetActiveColor());
285 PolylineSceneLayer::Chain chain; 264 polyline.AddSegment(halfX, y1, halfX, y2, GetActiveColor());
286 chain.resize(2);
287
288 chain[0] = ScenePoint2D(x1, halfY);
289 chain[1] = ScenePoint2D(x2, halfY);
290 AddChain(polyline, chain);
291
292 chain[0] = ScenePoint2D(halfX, y1);
293 chain[1] = ScenePoint2D(halfX, y2);
294 AddChain(polyline, chain);
295 } 265 }
296 266
297 public: 267 public:
298 explicit Handle(Annotation& parentAnnotation, 268 explicit Handle(Annotation& parentAnnotation,
299 Shape shape, 269 Shape shape,
328 const double zoom = scene.GetSceneToCanvasTransform().ComputeZoom(); 298 const double zoom = scene.GetSceneToCanvasTransform().ComputeZoom();
329 299
330 double dx = (center_.GetX() + delta_.GetX() - p.GetX()) * zoom; 300 double dx = (center_.GetX() + delta_.GetX() - p.GetX()) * zoom;
331 double dy = (center_.GetY() + delta_.GetY() - p.GetY()) * zoom; 301 double dy = (center_.GetY() + delta_.GetY() - p.GetY()) * zoom;
332 302
333 switch (shape_) 303 return (std::abs(dx) <= HANDLE_SIZE / 2.0 &&
334 { 304 std::abs(dy) <= HANDLE_SIZE / 2.0);
335 case Shape_Square:
336 case Shape_CrossedSquare:
337 return (std::abs(dx) <= HANDLE_SIZE / 2.0 &&
338 std::abs(dy) <= HANDLE_SIZE / 2.0);
339
340 default:
341 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
342 }
343 } 305 }
344 306
345 virtual void RenderPolylineLayer(PolylineSceneLayer& polyline, 307 virtual void RenderPolylineLayer(PolylineSceneLayer& polyline,
346 const Scene2D& scene) ORTHANC_OVERRIDE 308 const Scene2D& scene) ORTHANC_OVERRIDE
347 { 309 {
310 static unsigned int NUM_SEGMENTS = 16;
311
348 const double zoom = scene.GetSceneToCanvasTransform().ComputeZoom(); 312 const double zoom = scene.GetSceneToCanvasTransform().ComputeZoom();
349 313
350 // TODO: take DPI into account 314 // TODO: take DPI into account
351 double x1 = center_.GetX() + delta_.GetX() - (HANDLE_SIZE / 2.0) / zoom; 315 const double unzoomedHandleSize = (HANDLE_SIZE / 2.0) / zoom;
352 double y1 = center_.GetY() + delta_.GetY() - (HANDLE_SIZE / 2.0) / zoom; 316 const double x = center_.GetX() + delta_.GetX();
353 double x2 = center_.GetX() + delta_.GetX() + (HANDLE_SIZE / 2.0) / zoom; 317 const double y = center_.GetY() + delta_.GetY();
354 double y2 = center_.GetY() + delta_.GetY() + (HANDLE_SIZE / 2.0) / zoom; 318 const double x1 = x - unzoomedHandleSize;
319 const double y1 = y - unzoomedHandleSize;
320 const double x2 = x + unzoomedHandleSize;
321 const double y2 = y + unzoomedHandleSize;
355 322
356 switch (shape_) 323 switch (shape_)
357 { 324 {
358 case Shape_Square: 325 case Shape_Square:
359 AddRectangle(polyline, x1, y1, x2, y2); 326 polyline.AddRectangle(x1, y1, x2, y2, GetActiveColor());
360 break; 327 break;
361 328
362 case Shape_CrossedSquare: 329 case Shape_CrossedSquare:
363 AddRectangle(polyline, x1, y1, x2, y2); 330 polyline.AddRectangle(x1, y1, x2, y2, GetActiveColor());
331 AddCross(polyline, x1, y1, x2, y2);
332 break;
333
334 case Shape_Circle:
335 polyline.AddCircle(x, y, unzoomedHandleSize, GetActiveColor(), NUM_SEGMENTS);
336 break;
337
338 case Shape_CrossedCircle:
339 polyline.AddCircle(x, y, unzoomedHandleSize, GetActiveColor(), NUM_SEGMENTS);
364 AddCross(polyline, x1, y1, x2, y2); 340 AddCross(polyline, x1, y1, x2, y2);
365 break; 341 break;
366 342
367 default: 343 default:
368 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); 344 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
439 } 415 }
440 416
441 virtual void RenderPolylineLayer(PolylineSceneLayer& polyline, 417 virtual void RenderPolylineLayer(PolylineSceneLayer& polyline,
442 const Scene2D& scene) ORTHANC_OVERRIDE 418 const Scene2D& scene) ORTHANC_OVERRIDE
443 { 419 {
444 PolylineSceneLayer::Chain chain; 420 polyline.AddSegment(p1_ + delta_, p2_ + delta_, GetActiveColor());
445 chain.resize(2);
446 chain[0] = p1_ + delta_;
447 chain[1] = p2_ + delta_;
448
449 if (IsHover())
450 {
451 polyline.AddChain(chain, false /* closed */, GetHoverColor());
452 }
453 else
454 {
455 polyline.AddChain(chain, false /* closed */, GetColor());
456 }
457 } 421 }
458 422
459 virtual void RenderOtherLayers(MacroSceneLayer& macro, 423 virtual void RenderOtherLayers(MacroSceneLayer& macro,
460 const Scene2D& scene) ORTHANC_OVERRIDE 424 const Scene2D& scene) ORTHANC_OVERRIDE
461 { 425 {
535 virtual void RenderPolylineLayer(PolylineSceneLayer& polyline, 499 virtual void RenderPolylineLayer(PolylineSceneLayer& polyline,
536 const Scene2D& scene) ORTHANC_OVERRIDE 500 const Scene2D& scene) ORTHANC_OVERRIDE
537 { 501 {
538 static unsigned int NUM_SEGMENTS = 128; 502 static unsigned int NUM_SEGMENTS = 128;
539 503
540 ScenePoint2D middle((p1_.GetX() + p2_.GetX()) / 2.0, 504 ScenePoint2D center((p1_.GetX() + p2_.GetX()) / 2.0,
541 (p1_.GetY() + p2_.GetY()) / 2.0); 505 (p1_.GetY() + p2_.GetY()) / 2.0);
542 506
543 const double radius = ScenePoint2D::DistancePtPt(middle, p1_); 507 const double radius = ScenePoint2D::DistancePtPt(center, p1_);
544 508
545 double increment = 2.0 * PI / static_cast<double>(NUM_SEGMENTS - 1); 509 polyline.AddCircle(center, radius, GetActiveColor(), NUM_SEGMENTS);
546
547 PolylineSceneLayer::Chain chain;
548 chain.resize(NUM_SEGMENTS);
549
550 double theta = 0;
551 for (unsigned int i = 0; i < NUM_SEGMENTS; i++)
552 {
553 chain[i] = ScenePoint2D(delta_.GetX() + middle.GetX() + radius * cos(theta),
554 delta_.GetY() + middle.GetY() + radius * sin(theta));
555 theta += increment;
556 }
557
558 if (IsHover())
559 {
560 polyline.AddChain(chain, false /* closed */, GetHoverColor());
561 }
562 else
563 {
564 polyline.AddChain(chain, false /* closed */, GetColor());
565 }
566 } 510 }
567 511
568 virtual void RenderOtherLayers(MacroSceneLayer& macro, 512 virtual void RenderOtherLayers(MacroSceneLayer& macro,
569 const Scene2D& scene) ORTHANC_OVERRIDE 513 const Scene2D& scene) ORTHANC_OVERRIDE
570 { 514 {
677 const double radius = radius_ / scene.GetSceneToCanvasTransform().ComputeZoom(); 621 const double radius = radius_ / scene.GetSceneToCanvasTransform().ComputeZoom();
678 622
679 double fullAngle, startAngle, endAngle; 623 double fullAngle, startAngle, endAngle;
680 ComputeAngles(fullAngle, startAngle, endAngle); 624 ComputeAngles(fullAngle, startAngle, endAngle);
681 625
682 double increment = fullAngle / static_cast<double>(NUM_SEGMENTS - 1); 626 polyline.AddArc(middle_, radius, radius, startAngle, endAngle, GetActiveColor(), NUM_SEGMENTS);
683
684 PolylineSceneLayer::Chain chain;
685 chain.resize(NUM_SEGMENTS);
686
687 double theta = startAngle;
688 for (unsigned int i = 0; i < NUM_SEGMENTS; i++)
689 {
690 chain[i] = ScenePoint2D(middle_.GetX() + radius * cos(theta),
691 middle_.GetY() + radius * sin(theta));
692 theta += increment;
693 }
694
695 if (IsHover())
696 {
697 polyline.AddChain(chain, false /* closed */, GetHoverColor());
698 }
699 else
700 {
701 polyline.AddChain(chain, false /* closed */, GetColor());
702 }
703 } 627 }
704 628
705 virtual void RenderOtherLayers(MacroSceneLayer& macro, 629 virtual void RenderOtherLayers(MacroSceneLayer& macro,
706 const Scene2D& scene) ORTHANC_OVERRIDE 630 const Scene2D& scene) ORTHANC_OVERRIDE
707 { 631 {
796 { 720 {
797 if (content_.get() != NULL) 721 if (content_.get() != NULL)
798 { 722 {
799 std::unique_ptr<TextSceneLayer> layer(reinterpret_cast<TextSceneLayer*>(content_->Clone())); 723 std::unique_ptr<TextSceneLayer> layer(reinterpret_cast<TextSceneLayer*>(content_->Clone()));
800 724
801 layer->SetColor(IsHover() ? GetHoverColor() : GetColor()); 725 layer->SetColor(GetActiveColor());
802 726
803 if (first_) 727 if (first_)
804 { 728 {
805 subLayer_ = macro.AddLayer(layer.release()); 729 subLayer_ = macro.AddLayer(layer.release());
806 first_ = false; 730 first_ = false;