Mercurial > hg > orthanc-stone
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 } |