comparison OrthancStone/Sources/Scene2D/AnnotationsSceneLayer.cpp @ 1975:5a434f5889f8

starting pixel probe
author Sebastien Jodogne <s.jodogne@gmail.com>
date Sat, 29 Oct 2022 11:57:00 +0200
parents 9c0adcc8feec
children d71acf30970a
comparison
equal deleted inserted replaced
1974:446e0d3e9019 1975:5a434f5889f8
24 #include "AnnotationsSceneLayer.h" 24 #include "AnnotationsSceneLayer.h"
25 25
26 #include "MacroSceneLayer.h" 26 #include "MacroSceneLayer.h"
27 #include "PolylineSceneLayer.h" 27 #include "PolylineSceneLayer.h"
28 #include "TextSceneLayer.h" 28 #include "TextSceneLayer.h"
29 #include "TextureBaseSceneLayer.h" // TODO REMOVE
29 30
30 #include <OrthancException.h> 31 #include <OrthancException.h>
31 32
32 #include <boost/math/constants/constants.hpp> 33 #include <boost/math/constants/constants.hpp>
33 #include <list> 34 #include <list>
35 static const double HANDLE_SIZE = 10.0; 36 static const double HANDLE_SIZE = 10.0;
36 static const double PI = boost::math::constants::pi<double>(); 37 static const double PI = boost::math::constants::pi<double>();
37 38
38 static const char* const KEY_ANNOTATIONS = "annotations"; 39 static const char* const KEY_ANNOTATIONS = "annotations";
39 static const char* const KEY_TYPE = "type"; 40 static const char* const KEY_TYPE = "type";
41 static const char* const KEY_X = "x";
42 static const char* const KEY_Y = "y";
40 static const char* const KEY_X1 = "x1"; 43 static const char* const KEY_X1 = "x1";
41 static const char* const KEY_Y1 = "y1"; 44 static const char* const KEY_Y1 = "y1";
42 static const char* const KEY_X2 = "x2"; 45 static const char* const KEY_X2 = "x2";
43 static const char* const KEY_Y2 = "y2"; 46 static const char* const KEY_Y2 = "y2";
44 static const char* const KEY_X3 = "x3"; 47 static const char* const KEY_X3 = "x3";
48 static const char* const VALUE_ANGLE = "angle"; 51 static const char* const VALUE_ANGLE = "angle";
49 static const char* const VALUE_CIRCLE = "circle"; 52 static const char* const VALUE_CIRCLE = "circle";
50 static const char* const VALUE_SEGMENT = "segment"; 53 static const char* const VALUE_SEGMENT = "segment";
51 static const char* const VALUE_MILLIMETERS = "millimeters"; 54 static const char* const VALUE_MILLIMETERS = "millimeters";
52 static const char* const VALUE_PIXELS = "pixels"; 55 static const char* const VALUE_PIXELS = "pixels";
56 static const char* const VALUE_PIXEL_PROBE = "pixel-probe";
53 57
54 #if 0 58 #if 0
55 static OrthancStone::Color COLOR_PRIMITIVES(192, 192, 192); 59 static OrthancStone::Color COLOR_PRIMITIVES(192, 192, 192);
56 static OrthancStone::Color COLOR_HOVER(0, 255, 0); 60 static OrthancStone::Color COLOR_HOVER(0, 255, 0);
57 static OrthancStone::Color COLOR_TEXT(255, 0, 0); 61 static OrthancStone::Color COLOR_TEXT(255, 0, 0);
155 159
156 // Only called if modified 160 // Only called if modified
157 virtual void RenderOtherLayers(MacroSceneLayer& macro, 161 virtual void RenderOtherLayers(MacroSceneLayer& macro,
158 const Scene2D& scene) = 0; 162 const Scene2D& scene) = 0;
159 163
160 virtual void MovePreview(const ScenePoint2D& delta) = 0; 164 virtual void MovePreview(const ScenePoint2D& delta,
161 165 const Scene2D& scene) = 0;
162 virtual void MoveDone(const ScenePoint2D& delta) = 0; 166
167 virtual void MoveDone(const ScenePoint2D& delta,
168 const Scene2D& scene) = 0;
163 }; 169 };
164 170
165 171
166 class AnnotationsSceneLayer::Annotation : public boost::noncopyable 172 class AnnotationsSceneLayer::Annotation : public boost::noncopyable
167 { 173 {
214 { 220 {
215 AddPrimitive(primitive); 221 AddPrimitive(primitive);
216 return *primitive; 222 return *primitive;
217 } 223 }
218 224
219 virtual void SignalMove(GeometricPrimitive& primitive) = 0; 225 virtual void SignalMove(GeometricPrimitive& primitive,
226 const Scene2D& scene) = 0;
220 227
221 virtual void Serialize(Json::Value& target) = 0; 228 virtual void Serialize(Json::Value& target) = 0;
222 }; 229 };
223 230
224 231
297 virtual void RenderOtherLayers(MacroSceneLayer& macro, 304 virtual void RenderOtherLayers(MacroSceneLayer& macro,
298 const Scene2D& scene) ORTHANC_OVERRIDE 305 const Scene2D& scene) ORTHANC_OVERRIDE
299 { 306 {
300 } 307 }
301 308
302 virtual void MovePreview(const ScenePoint2D& delta) ORTHANC_OVERRIDE 309 virtual void MovePreview(const ScenePoint2D& delta,
310 const Scene2D& scene) ORTHANC_OVERRIDE
303 { 311 {
304 SetModified(true); 312 SetModified(true);
305 delta_ = delta; 313 delta_ = delta;
306 GetParentAnnotation().SignalMove(*this); 314 GetParentAnnotation().SignalMove(*this, scene);
307 } 315 }
308 316
309 virtual void MoveDone(const ScenePoint2D& delta) ORTHANC_OVERRIDE 317 virtual void MoveDone(const ScenePoint2D& delta,
318 const Scene2D& scene) ORTHANC_OVERRIDE
310 { 319 {
311 SetModified(true); 320 SetModified(true);
312 center_ = center_ + delta; 321 center_ = center_ + delta;
313 delta_ = ScenePoint2D(0, 0); 322 delta_ = ScenePoint2D(0, 0);
314 GetParentAnnotation().SignalMove(*this); 323 GetParentAnnotation().SignalMove(*this, scene);
315 } 324 }
316 }; 325 };
317 326
318 327
319 class AnnotationsSceneLayer::Segment : public GeometricPrimitive 328 class AnnotationsSceneLayer::Segment : public GeometricPrimitive
382 virtual void RenderOtherLayers(MacroSceneLayer& macro, 391 virtual void RenderOtherLayers(MacroSceneLayer& macro,
383 const Scene2D& scene) ORTHANC_OVERRIDE 392 const Scene2D& scene) ORTHANC_OVERRIDE
384 { 393 {
385 } 394 }
386 395
387 virtual void MovePreview(const ScenePoint2D& delta) ORTHANC_OVERRIDE 396 virtual void MovePreview(const ScenePoint2D& delta,
397 const Scene2D& scene) ORTHANC_OVERRIDE
388 { 398 {
389 SetModified(true); 399 SetModified(true);
390 delta_ = delta; 400 delta_ = delta;
391 GetParentAnnotation().SignalMove(*this); 401 GetParentAnnotation().SignalMove(*this, scene);
392 } 402 }
393 403
394 virtual void MoveDone(const ScenePoint2D& delta) ORTHANC_OVERRIDE 404 virtual void MoveDone(const ScenePoint2D& delta,
405 const Scene2D& scene) ORTHANC_OVERRIDE
395 { 406 {
396 SetModified(true); 407 SetModified(true);
397 p1_ = p1_ + delta; 408 p1_ = p1_ + delta;
398 p2_ = p2_ + delta; 409 p2_ = p2_ + delta;
399 delta_ = ScenePoint2D(0, 0); 410 delta_ = ScenePoint2D(0, 0);
400 GetParentAnnotation().SignalMove(*this); 411 GetParentAnnotation().SignalMove(*this, scene);
401 } 412 }
402 }; 413 };
403 414
404 415
405 class AnnotationsSceneLayer::Circle : public GeometricPrimitive 416 class AnnotationsSceneLayer::Circle : public GeometricPrimitive
489 virtual void RenderOtherLayers(MacroSceneLayer& macro, 500 virtual void RenderOtherLayers(MacroSceneLayer& macro,
490 const Scene2D& scene) ORTHANC_OVERRIDE 501 const Scene2D& scene) ORTHANC_OVERRIDE
491 { 502 {
492 } 503 }
493 504
494 virtual void MovePreview(const ScenePoint2D& delta) ORTHANC_OVERRIDE 505 virtual void MovePreview(const ScenePoint2D& delta,
506 const Scene2D& scene) ORTHANC_OVERRIDE
495 { 507 {
496 SetModified(true); 508 SetModified(true);
497 delta_ = delta; 509 delta_ = delta;
498 GetParentAnnotation().SignalMove(*this); 510 GetParentAnnotation().SignalMove(*this, scene);
499 } 511 }
500 512
501 virtual void MoveDone(const ScenePoint2D& delta) ORTHANC_OVERRIDE 513 virtual void MoveDone(const ScenePoint2D& delta,
514 const Scene2D& scene) ORTHANC_OVERRIDE
502 { 515 {
503 SetModified(true); 516 SetModified(true);
504 p1_ = p1_ + delta; 517 p1_ = p1_ + delta;
505 p2_ = p2_ + delta; 518 p2_ = p2_ + delta;
506 delta_ = ScenePoint2D(0, 0); 519 delta_ = ScenePoint2D(0, 0);
507 GetParentAnnotation().SignalMove(*this); 520 GetParentAnnotation().SignalMove(*this, scene);
508 } 521 }
509 }; 522 };
510 523
511 524
512 class AnnotationsSceneLayer::Arc : public GeometricPrimitive 525 class AnnotationsSceneLayer::Arc : public GeometricPrimitive
624 virtual void RenderOtherLayers(MacroSceneLayer& macro, 637 virtual void RenderOtherLayers(MacroSceneLayer& macro,
625 const Scene2D& scene) ORTHANC_OVERRIDE 638 const Scene2D& scene) ORTHANC_OVERRIDE
626 { 639 {
627 } 640 }
628 641
629 virtual void MovePreview(const ScenePoint2D& delta) ORTHANC_OVERRIDE 642 virtual void MovePreview(const ScenePoint2D& delta,
643 const Scene2D& scene) ORTHANC_OVERRIDE
630 { 644 {
631 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); // No hit is possible 645 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); // No hit is possible
632 } 646 }
633 647
634 virtual void MoveDone(const ScenePoint2D& delta) ORTHANC_OVERRIDE 648 virtual void MoveDone(const ScenePoint2D& delta,
649 const Scene2D& scene) ORTHANC_OVERRIDE
635 { 650 {
636 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); // No hit is possible 651 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); // No hit is possible
637 } 652 }
638 }; 653 };
639 654
700 macro.UpdateLayer(subLayer_, layer.release()); 715 macro.UpdateLayer(subLayer_, layer.release());
701 } 716 }
702 } 717 }
703 } 718 }
704 719
705 virtual void MovePreview(const ScenePoint2D& delta) ORTHANC_OVERRIDE 720 virtual void MovePreview(const ScenePoint2D& delta,
721 const Scene2D& scene) ORTHANC_OVERRIDE
706 { 722 {
707 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); // No hit is possible 723 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); // No hit is possible
708 } 724 }
709 725
710 virtual void MoveDone(const ScenePoint2D& delta) ORTHANC_OVERRIDE 726 virtual void MoveDone(const ScenePoint2D& delta,
727 const Scene2D& scene) ORTHANC_OVERRIDE
711 { 728 {
712 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); // No hit is possible 729 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); // No hit is possible
713 } 730 }
714 }; 731 };
715 732
737 } 754 }
738 755
739 virtual void PointerMove(const PointerEvent& event, 756 virtual void PointerMove(const PointerEvent& event,
740 const Scene2D& scene) ORTHANC_OVERRIDE 757 const Scene2D& scene) ORTHANC_OVERRIDE
741 { 758 {
742 primitive_.MovePreview(event.GetMainPosition().Apply(canvasToScene_) - sceneClick_); 759 primitive_.MovePreview(event.GetMainPosition().Apply(canvasToScene_) - sceneClick_, scene);
743 that_.BroadcastMessage(AnnotationChangedMessage(that_)); 760 that_.BroadcastMessage(AnnotationChangedMessage(that_));
744 } 761 }
745 762
746 virtual void PointerUp(const PointerEvent& event, 763 virtual void PointerUp(const PointerEvent& event,
747 const Scene2D& scene) ORTHANC_OVERRIDE 764 const Scene2D& scene) ORTHANC_OVERRIDE
748 { 765 {
749 primitive_.MoveDone(event.GetMainPosition().Apply(canvasToScene_) - sceneClick_); 766 primitive_.MoveDone(event.GetMainPosition().Apply(canvasToScene_) - sceneClick_, scene);
750 alive_ = false; 767 alive_ = false;
751 that_.BroadcastMessage(AnnotationChangedMessage(that_)); 768 that_.BroadcastMessage(AnnotationChangedMessage(that_));
752 } 769 }
753 770
754 virtual void PointerDown(const PointerEvent& event, 771 virtual void PointerDown(const PointerEvent& event,
759 virtual bool IsAlive() const ORTHANC_OVERRIDE 776 virtual bool IsAlive() const ORTHANC_OVERRIDE
760 { 777 {
761 return alive_; 778 return alive_;
762 } 779 }
763 780
764 virtual void Cancel() ORTHANC_OVERRIDE 781 virtual void Cancel(const Scene2D& scene) ORTHANC_OVERRIDE
765 { 782 {
766 primitive_.MoveDone(ScenePoint2D(0, 0)); 783 //primitive_.MoveDone(ScenePoint2D(0, 0), scene);
784 primitive_.MoveDone(sceneClick_, scene); // TODO Check this
767 } 785 }
768 }; 786 };
769 787
770 788
771 class AnnotationsSceneLayer::SegmentAnnotation : public Annotation 789 class AnnotationsSceneLayer::SegmentAnnotation : public Annotation
850 Handle& GetHandle2() const 868 Handle& GetHandle2() const
851 { 869 {
852 return handle2_; 870 return handle2_;
853 } 871 }
854 872
855 virtual void SignalMove(GeometricPrimitive& primitive) ORTHANC_OVERRIDE 873 virtual void SignalMove(GeometricPrimitive& primitive,
874 const Scene2D& scene) ORTHANC_OVERRIDE
856 { 875 {
857 if (&primitive == &handle1_ || 876 if (&primitive == &handle1_ ||
858 &primitive == &handle2_) 877 &primitive == &handle2_)
859 { 878 {
860 segment_.SetPosition(handle1_.GetCenter(), handle2_.GetCenter()); 879 segment_.SetPosition(handle1_.GetCenter(), handle2_.GetCenter());
896 ScenePoint2D(source[KEY_X2].asDouble(), source[KEY_Y2].asDouble())); 915 ScenePoint2D(source[KEY_X2].asDouble(), source[KEY_Y2].asDouble()));
897 } 916 }
898 else 917 else
899 { 918 {
900 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat, "Cannot unserialize an segment annotation"); 919 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat, "Cannot unserialize an segment annotation");
920 }
921 }
922 };
923
924
925 class AnnotationsSceneLayer::PixelProbeAnnotation : public Annotation
926 {
927 private:
928 int probedLayer_;
929 Handle& handle_;
930 Text& label_;
931
932 void UpdateLabel(const Scene2D& scene)
933 {
934 TextSceneLayer content;
935
936 content.SetPosition(handle_.GetCenter().GetX(), handle_.GetCenter().GetY());
937 content.SetAnchor(BitmapAnchor_CenterLeft);
938 content.SetBorder(10);
939
940 if (scene.HasLayer(probedLayer_))
941 {
942 const TextureBaseSceneLayer& layer = dynamic_cast<TextureBaseSceneLayer&>(scene.GetLayer(probedLayer_));
943 const AffineTransform2D sceneToTexture = AffineTransform2D::Invert(layer.GetTransform());
944
945 double x = handle_.GetCenter().GetX();
946 double y = handle_.GetCenter().GetY();
947 sceneToTexture.Apply(x, y);
948
949 int textureX = static_cast<int>(std::floor(x));
950 int textureY = static_cast<int>(std::floor(y));
951
952 char buf[64];
953 sprintf(buf, "Hello %d x %d / (%d,%d)\n", layer.GetTexture().GetWidth(), layer.GetTexture().GetHeight(),
954 textureX, textureY);
955 content.SetText(buf);
956 }
957 else
958 {
959 content.SetText("????");
960 }
961
962 label_.SetContent(content);
963 }
964
965 public:
966 PixelProbeAnnotation(AnnotationsSceneLayer& that,
967 Units units,
968 const ScenePoint2D& p,
969 const Scene2D& scene,
970 int probedLayer) :
971 Annotation(that, units),
972 probedLayer_(probedLayer),
973 handle_(AddTypedPrimitive<Handle>(new Handle(*this, p))),
974 label_(AddTypedPrimitive<Text>(new Text(that, *this)))
975 {
976 label_.SetColor(COLOR_TEXT);
977 UpdateLabel(scene);
978 }
979
980 Handle& GetHandle() const
981 {
982 return handle_;
983 }
984
985 virtual void SignalMove(GeometricPrimitive& primitive,
986 const Scene2D& scene) ORTHANC_OVERRIDE
987 {
988 UpdateLabel(scene);
989 }
990
991 virtual void Serialize(Json::Value& target) ORTHANC_OVERRIDE
992 {
993 target = Json::objectValue;
994 target[KEY_TYPE] = VALUE_PIXEL_PROBE;
995 target[KEY_X] = handle_.GetCenter().GetX();
996 target[KEY_Y] = handle_.GetCenter().GetY();
997 }
998
999 static void Unserialize(AnnotationsSceneLayer& target,
1000 Units units,
1001 int probedLayer,
1002 const Json::Value& source)
1003 {
1004 if (source.isMember(KEY_X) &&
1005 source.isMember(KEY_Y) &&
1006 source[KEY_X].isNumeric() &&
1007 source[KEY_Y].isNumeric())
1008 {
1009 Scene2D dummyScene; // TODO
1010 new PixelProbeAnnotation(target, units,
1011 ScenePoint2D(source[KEY_X].asDouble(), source[KEY_Y].asDouble()),
1012 dummyScene, probedLayer);
1013 }
1014 else
1015 {
1016 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat, "Cannot unserialize a pixel probe");
901 } 1017 }
902 } 1018 }
903 }; 1019 };
904 1020
905 1021
966 Handle& GetEndHandle() const 1082 Handle& GetEndHandle() const
967 { 1083 {
968 return endHandle_; 1084 return endHandle_;
969 } 1085 }
970 1086
971 virtual void SignalMove(GeometricPrimitive& primitive) ORTHANC_OVERRIDE 1087 virtual void SignalMove(GeometricPrimitive& primitive,
1088 const Scene2D& scene) ORTHANC_OVERRIDE
972 { 1089 {
973 if (&primitive == &startHandle_) 1090 if (&primitive == &startHandle_)
974 { 1091 {
975 segment1_.SetPosition(startHandle_.GetCenter(), middleHandle_.GetCenter()); 1092 segment1_.SetPosition(startHandle_.GetCenter(), middleHandle_.GetCenter());
976 arc_.SetStart(startHandle_.GetCenter()); 1093 arc_.SetStart(startHandle_.GetCenter());
1129 Handle& GetHandle2() const 1246 Handle& GetHandle2() const
1130 { 1247 {
1131 return handle2_; 1248 return handle2_;
1132 } 1249 }
1133 1250
1134 virtual void SignalMove(GeometricPrimitive& primitive) ORTHANC_OVERRIDE 1251 virtual void SignalMove(GeometricPrimitive& primitive,
1252 const Scene2D& scene) ORTHANC_OVERRIDE
1135 { 1253 {
1136 if (&primitive == &handle1_ || 1254 if (&primitive == &handle1_ ||
1137 &primitive == &handle2_) 1255 &primitive == &handle2_)
1138 { 1256 {
1139 segment_.SetPosition(handle1_.GetCenter(), handle2_.GetCenter()); 1257 segment_.SetPosition(handle1_.GetCenter(), handle2_.GetCenter());
1229 { 1347 {
1230 if (annotation_ != NULL) 1348 if (annotation_ != NULL)
1231 { 1349 {
1232 assert(handle2_ != NULL); 1350 assert(handle2_ != NULL);
1233 handle2_->SetCenter(event.GetMainPosition().Apply(canvasToScene_)); 1351 handle2_->SetCenter(event.GetMainPosition().Apply(canvasToScene_));
1234 annotation_->SignalMove(*handle2_); 1352 annotation_->SignalMove(*handle2_, scene);
1235 1353
1236 that_.BroadcastMessage(AnnotationChangedMessage(that_)); 1354 that_.BroadcastMessage(AnnotationChangedMessage(that_));
1237 } 1355 }
1238 } 1356 }
1239 1357
1253 virtual bool IsAlive() const ORTHANC_OVERRIDE 1371 virtual bool IsAlive() const ORTHANC_OVERRIDE
1254 { 1372 {
1255 return (annotation_ != NULL); 1373 return (annotation_ != NULL);
1256 } 1374 }
1257 1375
1258 virtual void Cancel() ORTHANC_OVERRIDE 1376 virtual void Cancel(const Scene2D& scene) ORTHANC_OVERRIDE
1259 { 1377 {
1260 if (annotation_ != NULL) 1378 if (annotation_ != NULL)
1261 { 1379 {
1262 that_.DeleteAnnotation(annotation_); 1380 that_.DeleteAnnotation(annotation_);
1263 annotation_ = NULL; 1381 annotation_ = NULL;
1291 const Scene2D& scene) ORTHANC_OVERRIDE 1409 const Scene2D& scene) ORTHANC_OVERRIDE
1292 { 1410 {
1293 if (segment_ != NULL) 1411 if (segment_ != NULL)
1294 { 1412 {
1295 segment_->GetHandle2().SetCenter(event.GetMainPosition().Apply(canvasToScene_)); 1413 segment_->GetHandle2().SetCenter(event.GetMainPosition().Apply(canvasToScene_));
1296 segment_->SignalMove(segment_->GetHandle2()); 1414 segment_->SignalMove(segment_->GetHandle2(), scene);
1297 that_.BroadcastMessage(AnnotationChangedMessage(that_)); 1415 that_.BroadcastMessage(AnnotationChangedMessage(that_));
1298 } 1416 }
1299 1417
1300 if (angle_ != NULL) 1418 if (angle_ != NULL)
1301 { 1419 {
1302 angle_->GetEndHandle().SetCenter(event.GetMainPosition().Apply(canvasToScene_)); 1420 angle_->GetEndHandle().SetCenter(event.GetMainPosition().Apply(canvasToScene_));
1303 angle_->SignalMove(angle_->GetEndHandle()); 1421 angle_->SignalMove(angle_->GetEndHandle(), scene);
1304 that_.BroadcastMessage(AnnotationChangedMessage(that_)); 1422 that_.BroadcastMessage(AnnotationChangedMessage(that_));
1305 } 1423 }
1306 } 1424 }
1307 1425
1308 virtual void PointerUp(const PointerEvent& event, 1426 virtual void PointerUp(const PointerEvent& event,
1338 { 1456 {
1339 return (segment_ != NULL || 1457 return (segment_ != NULL ||
1340 angle_ != NULL); 1458 angle_ != NULL);
1341 } 1459 }
1342 1460
1343 virtual void Cancel() ORTHANC_OVERRIDE 1461 virtual void Cancel(const Scene2D& scene) ORTHANC_OVERRIDE
1344 { 1462 {
1345 if (segment_ != NULL) 1463 if (segment_ != NULL)
1346 { 1464 {
1347 that_.DeleteAnnotation(segment_); 1465 that_.DeleteAnnotation(segment_);
1348 segment_ = NULL; 1466 segment_ = NULL;
1351 if (angle_ != NULL) 1469 if (angle_ != NULL)
1352 { 1470 {
1353 that_.DeleteAnnotation(angle_); 1471 that_.DeleteAnnotation(angle_);
1354 angle_ = NULL; 1472 angle_ = NULL;
1355 } 1473 }
1474 }
1475 };
1476
1477
1478 class AnnotationsSceneLayer::CreatePixelProbeTracker : public IFlexiblePointerTracker
1479 {
1480 private:
1481 AnnotationsSceneLayer& that_;
1482
1483 public:
1484 CreatePixelProbeTracker(AnnotationsSceneLayer& that,
1485 Units units,
1486 const ScenePoint2D& sceneClick,
1487 const Scene2D& scene,
1488 int probedLayer) :
1489 that_(that)
1490 {
1491 new PixelProbeAnnotation(that, units, sceneClick, scene, probedLayer);
1492 }
1493
1494 virtual void PointerMove(const PointerEvent& event,
1495 const Scene2D& scene) ORTHANC_OVERRIDE
1496 {
1497 }
1498
1499 virtual void PointerUp(const PointerEvent& event,
1500 const Scene2D& scene) ORTHANC_OVERRIDE
1501 {
1502 that_.BroadcastMessage(AnnotationAddedMessage(that_));
1503 }
1504
1505 virtual void PointerDown(const PointerEvent& event,
1506 const Scene2D& scene) ORTHANC_OVERRIDE
1507 {
1508 }
1509
1510 virtual bool IsAlive() const ORTHANC_OVERRIDE
1511 {
1512 return false;
1513 }
1514
1515 virtual void Cancel(const Scene2D& scene) ORTHANC_OVERRIDE
1516 {
1356 } 1517 }
1357 }; 1518 };
1358 1519
1359 1520
1360 // Dummy tracker that is only used for deletion, in order to warn 1521 // Dummy tracker that is only used for deletion, in order to warn
1384 virtual bool IsAlive() const ORTHANC_OVERRIDE 1545 virtual bool IsAlive() const ORTHANC_OVERRIDE
1385 { 1546 {
1386 return false; 1547 return false;
1387 } 1548 }
1388 1549
1389 virtual void Cancel() ORTHANC_OVERRIDE 1550 virtual void Cancel(const Scene2D& scene) ORTHANC_OVERRIDE
1390 { 1551 {
1391 } 1552 }
1392 }; 1553 };
1393 1554
1394 1555
1431 1592
1432 AnnotationsSceneLayer::AnnotationsSceneLayer(size_t macroLayerIndex) : 1593 AnnotationsSceneLayer::AnnotationsSceneLayer(size_t macroLayerIndex) :
1433 activeTool_(Tool_Edit), 1594 activeTool_(Tool_Edit),
1434 macroLayerIndex_(macroLayerIndex), 1595 macroLayerIndex_(macroLayerIndex),
1435 polylineSubLayer_(0), // dummy initialization 1596 polylineSubLayer_(0), // dummy initialization
1436 units_(Units_Pixels) 1597 units_(Units_Pixels),
1598 probedLayer_(0)
1437 { 1599 {
1438 } 1600 }
1439 1601
1440 1602
1441 void AnnotationsSceneLayer::Clear() 1603 void AnnotationsSceneLayer::Clear()
1629 return new CreateSegmentOrCircleTracker(*this, units_, true /* circle */, s, scene.GetCanvasToSceneTransform()); 1791 return new CreateSegmentOrCircleTracker(*this, units_, true /* circle */, s, scene.GetCanvasToSceneTransform());
1630 1792
1631 case Tool_Angle: 1793 case Tool_Angle:
1632 return new CreateAngleTracker(*this, units_, s, scene.GetCanvasToSceneTransform()); 1794 return new CreateAngleTracker(*this, units_, s, scene.GetCanvasToSceneTransform());
1633 1795
1796 case Tool_PixelProbe:
1797 return new CreatePixelProbeTracker(*this, units_, s, scene, probedLayer_);
1798
1634 default: 1799 default:
1635 return NULL; 1800 return NULL;
1636 } 1801 }
1637 } 1802 }
1638 } 1803 }
1722 } 1887 }
1723 else if (type == VALUE_SEGMENT) 1888 else if (type == VALUE_SEGMENT)
1724 { 1889 {
1725 SegmentAnnotation::Unserialize(*this, units_, annotations[i]); 1890 SegmentAnnotation::Unserialize(*this, units_, annotations[i]);
1726 } 1891 }
1892 else if (type == VALUE_PIXEL_PROBE)
1893 {
1894 PixelProbeAnnotation::Unserialize(*this, units_, probedLayer_, annotations[i]);
1895 }
1727 else 1896 else
1728 { 1897 {
1729 LOG(ERROR) << "Cannot unserialize unknown type of annotation: " << type; 1898 LOG(ERROR) << "Cannot unserialize unknown type of annotation: " << type;
1730 } 1899 }
1731 } 1900 }