comparison Applications/Samples/Sdl/SingleFrameViewer/SdlSimpleViewer.cpp @ 1799:1125793d82d3

serialization of annotations
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 20 May 2021 11:49:21 +0200
parents 41f3872bd7d2
children 2c0497d61a5d
comparison
equal deleted inserted replaced
1798:41f3872bd7d2 1799:1125793d82d3
49 49
50 #include <boost/math/constants/constants.hpp> 50 #include <boost/math/constants/constants.hpp>
51 51
52 static const double HANDLE_SIZE = 10.0; 52 static const double HANDLE_SIZE = 10.0;
53 static const double PI = boost::math::constants::pi<double>(); 53 static const double PI = boost::math::constants::pi<double>();
54 54
55 static const char* const KEY_ANNOTATIONS = "annotations";
56 static const char* const KEY_TYPE = "type";
57 static const char* const KEY_X1 = "x1";
58 static const char* const KEY_Y1 = "y1";
59 static const char* const KEY_X2 = "x2";
60 static const char* const KEY_Y2 = "y2";
61 static const char* const KEY_X3 = "x3";
62 static const char* const KEY_Y3 = "y3";
63
64 static const char* const VALUE_ANGLE = "angle";
65 static const char* const VALUE_CIRCLE = "circle";
66 static const char* const VALUE_SEGMENT = "segment";
67
68
55 namespace OrthancStone 69 namespace OrthancStone
56 { 70 {
57 class AnnotationsOverlay : public boost::noncopyable 71 class AnnotationsOverlay : public boost::noncopyable
58 { 72 {
59 public: 73 public:
66 Tool_Circle, 80 Tool_Circle,
67 Tool_Erase 81 Tool_Erase
68 }; 82 };
69 83
70 private: 84 private:
71 class Measure; 85 class Annotation;
72 86
73 class Primitive : public boost::noncopyable 87 class Primitive : public boost::noncopyable
74 { 88 {
75 private: 89 private:
76 bool modified_; 90 bool modified_;
77 Measure& parentMeasure_; 91 Annotation& parentAnnotation_;
78 Color color_; 92 Color color_;
79 Color hoverColor_; 93 Color hoverColor_;
80 bool isHover_; 94 bool isHover_;
81 int depth_; 95 int depth_;
82 96
83 public: 97 public:
84 Primitive(Measure& parentMeasure, 98 Primitive(Annotation& parentAnnotation,
85 int depth) : 99 int depth) :
86 modified_(true), 100 modified_(true),
87 parentMeasure_(parentMeasure), 101 parentAnnotation_(parentAnnotation),
88 color_(192, 192, 192), 102 color_(192, 192, 192),
89 hoverColor_(0, 255, 0), 103 hoverColor_(0, 255, 0),
90 isHover_(false), 104 isHover_(false),
91 depth_(depth) 105 depth_(depth)
92 { 106 {
94 108
95 virtual ~Primitive() 109 virtual ~Primitive()
96 { 110 {
97 } 111 }
98 112
99 Measure& GetParentMeasure() const 113 Annotation& GetParentAnnotation() const
100 { 114 {
101 return parentMeasure_; 115 return parentAnnotation_;
102 } 116 }
103 117
104 int GetDepth() const 118 int GetDepth() const
105 { 119 {
106 return depth_; 120 return depth_;
167 181
168 virtual void MoveDone(const ScenePoint2D& delta) = 0; 182 virtual void MoveDone(const ScenePoint2D& delta) = 0;
169 }; 183 };
170 184
171 185
172 class Measure : public boost::noncopyable 186 class Annotation : public boost::noncopyable
173 { 187 {
174 private: 188 private:
175 typedef std::list<Primitive*> Primitives; 189 typedef std::list<Primitive*> Primitives;
176 190
177 AnnotationsOverlay& that_; 191 AnnotationsOverlay& that_;
178 Primitives primitives_; 192 Primitives primitives_;
179 193
180 public: 194 public:
181 Measure(AnnotationsOverlay& that) : 195 Annotation(AnnotationsOverlay& that) :
182 that_(that) 196 that_(that)
183 { 197 {
184 that.AddMeasure(this); 198 that.AddAnnotation(this);
185 } 199 }
186 200
187 virtual ~Measure() 201 virtual ~Annotation()
188 { 202 {
189 for (Primitives::iterator it = primitives_.begin(); it != primitives_.end(); ++it) 203 for (Primitives::iterator it = primitives_.begin(); it != primitives_.end(); ++it)
190 { 204 {
191 that_.DeletePrimitive(*it); 205 that_.DeletePrimitive(*it);
192 } 206 }
213 AddPrimitive(primitive); 227 AddPrimitive(primitive);
214 return *primitive; 228 return *primitive;
215 } 229 }
216 230
217 virtual void SignalMove(Primitive& primitive) = 0; 231 virtual void SignalMove(Primitive& primitive) = 0;
232
233 virtual void Serialize(Json::Value& target) = 0;
218 }; 234 };
219 235
220 236
221 class Handle : public Primitive 237 class Handle : public Primitive
222 { 238 {
223 private: 239 private:
224 ScenePoint2D center_; 240 ScenePoint2D center_;
225 ScenePoint2D delta_; 241 ScenePoint2D delta_;
226 242
227 public: 243 public:
228 explicit Handle(Measure& parentMeasure, 244 explicit Handle(Annotation& parentAnnotation,
229 const ScenePoint2D& center) : 245 const ScenePoint2D& center) :
230 Primitive(parentMeasure, 0), // Highest priority 246 Primitive(parentAnnotation, 0), // Highest priority
231 center_(center), 247 center_(center),
232 delta_(0, 0) 248 delta_(0, 0)
233 { 249 {
234 } 250 }
235 251
297 313
298 virtual void MovePreview(const ScenePoint2D& delta) ORTHANC_OVERRIDE 314 virtual void MovePreview(const ScenePoint2D& delta) ORTHANC_OVERRIDE
299 { 315 {
300 SetModified(true); 316 SetModified(true);
301 delta_ = delta; 317 delta_ = delta;
302 GetParentMeasure().SignalMove(*this); 318 GetParentAnnotation().SignalMove(*this);
303 } 319 }
304 320
305 virtual void MoveDone(const ScenePoint2D& delta) ORTHANC_OVERRIDE 321 virtual void MoveDone(const ScenePoint2D& delta) ORTHANC_OVERRIDE
306 { 322 {
307 SetModified(true); 323 SetModified(true);
308 center_ = center_ + delta; 324 center_ = center_ + delta;
309 delta_ = ScenePoint2D(0, 0); 325 delta_ = ScenePoint2D(0, 0);
310 GetParentMeasure().SignalMove(*this); 326 GetParentAnnotation().SignalMove(*this);
311 } 327 }
312 }; 328 };
313 329
314 330
315 class Segment : public Primitive 331 class Segment : public Primitive
318 ScenePoint2D p1_; 334 ScenePoint2D p1_;
319 ScenePoint2D p2_; 335 ScenePoint2D p2_;
320 ScenePoint2D delta_; 336 ScenePoint2D delta_;
321 337
322 public: 338 public:
323 Segment(Measure& parentMeasure, 339 Segment(Annotation& parentAnnotation,
324 const ScenePoint2D& p1, 340 const ScenePoint2D& p1,
325 const ScenePoint2D& p2) : 341 const ScenePoint2D& p2) :
326 Primitive(parentMeasure, 1), // Can only be selected if no handle matches 342 Primitive(parentAnnotation, 1), // Can only be selected if no handle matches
327 p1_(p1), 343 p1_(p1),
328 p2_(p2), 344 p2_(p2),
329 delta_(0, 0) 345 delta_(0, 0)
330 { 346 {
331 } 347 }
382 398
383 virtual void MovePreview(const ScenePoint2D& delta) ORTHANC_OVERRIDE 399 virtual void MovePreview(const ScenePoint2D& delta) ORTHANC_OVERRIDE
384 { 400 {
385 SetModified(true); 401 SetModified(true);
386 delta_ = delta; 402 delta_ = delta;
387 GetParentMeasure().SignalMove(*this); 403 GetParentAnnotation().SignalMove(*this);
388 } 404 }
389 405
390 virtual void MoveDone(const ScenePoint2D& delta) ORTHANC_OVERRIDE 406 virtual void MoveDone(const ScenePoint2D& delta) ORTHANC_OVERRIDE
391 { 407 {
392 SetModified(true); 408 SetModified(true);
393 p1_ = p1_ + delta; 409 p1_ = p1_ + delta;
394 p2_ = p2_ + delta; 410 p2_ = p2_ + delta;
395 delta_ = ScenePoint2D(0, 0); 411 delta_ = ScenePoint2D(0, 0);
396 GetParentMeasure().SignalMove(*this); 412 GetParentAnnotation().SignalMove(*this);
397 } 413 }
398 }; 414 };
399 415
400 416
401 class Circle : public Primitive 417 class Circle : public Primitive
403 private: 419 private:
404 ScenePoint2D p1_; 420 ScenePoint2D p1_;
405 ScenePoint2D p2_; 421 ScenePoint2D p2_;
406 422
407 public: 423 public:
408 Circle(Measure& parentMeasure, 424 Circle(Annotation& parentAnnotation,
409 const ScenePoint2D& p1, 425 const ScenePoint2D& p1,
410 const ScenePoint2D& p2) : 426 const ScenePoint2D& p2) :
411 Primitive(parentMeasure, 2), 427 Primitive(parentAnnotation, 2),
412 p1_(p1), 428 p1_(p1),
413 p2_(p2) 429 p2_(p2)
414 { 430 {
415 } 431 }
416 432
522 fullAngle -= 2.0 * PI; 538 fullAngle -= 2.0 * PI;
523 } 539 }
524 } 540 }
525 541
526 public: 542 public:
527 Arc(Measure& parentMeasure, 543 Arc(Annotation& parentAnnotation,
528 const ScenePoint2D& start, 544 const ScenePoint2D& start,
529 const ScenePoint2D& middle, 545 const ScenePoint2D& middle,
530 const ScenePoint2D& end) : 546 const ScenePoint2D& end) :
531 Primitive(parentMeasure, 2), 547 Primitive(parentAnnotation, 2),
532 start_(start), 548 start_(start),
533 middle_(middle), 549 middle_(middle),
534 end_(end), 550 end_(end),
535 radius_(20) 551 radius_(20)
536 { 552 {
625 size_t subLayer_; 641 size_t subLayer_;
626 std::unique_ptr<TextSceneLayer> content_; 642 std::unique_ptr<TextSceneLayer> content_;
627 643
628 public: 644 public:
629 Text(AnnotationsOverlay& that, 645 Text(AnnotationsOverlay& that,
630 Measure& parentMeasure) : 646 Annotation& parentAnnotation) :
631 Primitive(parentMeasure, 2), 647 Primitive(parentAnnotation, 2),
632 that_(that), 648 that_(that),
633 first_(true) 649 first_(true)
634 { 650 {
635 } 651 }
636 652
736 primitive_.MoveDone(ScenePoint2D(0, 0)); 752 primitive_.MoveDone(ScenePoint2D(0, 0));
737 } 753 }
738 }; 754 };
739 755
740 756
741 class SegmentMeasure : public Measure 757 class SegmentAnnotation : public Annotation
742 { 758 {
743 private: 759 private:
744 bool showLabel_; 760 bool showLabel_;
745 Handle& handle1_; 761 Handle& handle1_;
746 Handle& handle2_; 762 Handle& handle2_;
780 label_.SetContent(content); 796 label_.SetContent(content);
781 } 797 }
782 } 798 }
783 799
784 public: 800 public:
785 SegmentMeasure(AnnotationsOverlay& that, 801 SegmentAnnotation(AnnotationsOverlay& that,
786 bool showLabel, 802 bool showLabel,
787 const ScenePoint2D& p1, 803 const ScenePoint2D& p1,
788 const ScenePoint2D& p2) : 804 const ScenePoint2D& p2) :
789 Measure(that), 805 Annotation(that),
790 showLabel_(showLabel), 806 showLabel_(showLabel),
791 handle1_(AddTypedPrimitive<Handle>(new Handle(*this, p1))), 807 handle1_(AddTypedPrimitive<Handle>(new Handle(*this, p1))),
792 handle2_(AddTypedPrimitive<Handle>(new Handle(*this, p2))), 808 handle2_(AddTypedPrimitive<Handle>(new Handle(*this, p2))),
793 segment_(AddTypedPrimitive<Segment>(new Segment(*this, p1, p2))), 809 segment_(AddTypedPrimitive<Segment>(new Segment(*this, p1, p2))),
794 label_(AddTypedPrimitive<Text>(new Text(that, *this))) 810 label_(AddTypedPrimitive<Text>(new Text(that, *this)))
820 handle2_.SetCenter(segment_.GetPosition2()); 836 handle2_.SetCenter(segment_.GetPosition2());
821 } 837 }
822 838
823 UpdateLabel(); 839 UpdateLabel();
824 } 840 }
841
842 virtual void Serialize(Json::Value& target) ORTHANC_OVERRIDE
843 {
844 target = Json::objectValue;
845 target[KEY_TYPE] = VALUE_SEGMENT;
846 target[KEY_X1] = handle1_.GetCenter().GetX();
847 target[KEY_Y1] = handle1_.GetCenter().GetY();
848 target[KEY_X2] = handle2_.GetCenter().GetX();
849 target[KEY_Y2] = handle2_.GetCenter().GetY();
850 }
825 }; 851 };
826 852
827 853
828 class AngleMeasure : public Measure 854 class AngleAnnotation : public Annotation
829 { 855 {
830 private: 856 private:
831 Handle& startHandle_; 857 Handle& startHandle_;
832 Handle& middleHandle_; 858 Handle& middleHandle_;
833 Handle& endHandle_; 859 Handle& endHandle_;
865 891
866 label_.SetContent(content); 892 label_.SetContent(content);
867 } 893 }
868 894
869 public: 895 public:
870 AngleMeasure(AnnotationsOverlay& that, 896 AngleAnnotation(AnnotationsOverlay& that,
871 const ScenePoint2D& start, 897 const ScenePoint2D& start,
872 const ScenePoint2D& middle, 898 const ScenePoint2D& middle,
873 const ScenePoint2D& end) : 899 const ScenePoint2D& end) :
874 Measure(that), 900 Annotation(that),
875 startHandle_(AddTypedPrimitive<Handle>(new Handle(*this, start))), 901 startHandle_(AddTypedPrimitive<Handle>(new Handle(*this, start))),
876 middleHandle_(AddTypedPrimitive<Handle>(new Handle(*this, middle))), 902 middleHandle_(AddTypedPrimitive<Handle>(new Handle(*this, middle))),
877 endHandle_(AddTypedPrimitive<Handle>(new Handle(*this, end))), 903 endHandle_(AddTypedPrimitive<Handle>(new Handle(*this, end))),
878 segment1_(AddTypedPrimitive<Segment>(new Segment(*this, start, middle))), 904 segment1_(AddTypedPrimitive<Segment>(new Segment(*this, start, middle))),
879 segment2_(AddTypedPrimitive<Segment>(new Segment(*this, middle, end))), 905 segment2_(AddTypedPrimitive<Segment>(new Segment(*this, middle, end))),
924 arc_.SetEnd(segment2_.GetPosition2()); 950 arc_.SetEnd(segment2_.GetPosition2());
925 } 951 }
926 952
927 UpdateLabel(); 953 UpdateLabel();
928 } 954 }
955
956 virtual void Serialize(Json::Value& target) ORTHANC_OVERRIDE
957 {
958 target = Json::objectValue;
959 target[KEY_TYPE] = VALUE_ANGLE;
960 target[KEY_X1] = startHandle_.GetCenter().GetX();
961 target[KEY_Y1] = startHandle_.GetCenter().GetY();
962 target[KEY_X2] = middleHandle_.GetCenter().GetX();
963 target[KEY_Y2] = middleHandle_.GetCenter().GetY();
964 target[KEY_X3] = endHandle_.GetCenter().GetX();
965 target[KEY_Y3] = endHandle_.GetCenter().GetY();
966 }
929 }; 967 };
930 968
931 969
932 class CircleMeasure : public Measure 970 class CircleAnnotation : public Annotation
933 { 971 {
934 private: 972 private:
935 Handle& handle1_; 973 Handle& handle1_;
936 Handle& handle2_; 974 Handle& handle2_;
937 Segment& segment_; 975 Segment& segment_;
975 1013
976 label_.SetContent(content); 1014 label_.SetContent(content);
977 } 1015 }
978 1016
979 public: 1017 public:
980 CircleMeasure(AnnotationsOverlay& that, 1018 CircleAnnotation(AnnotationsOverlay& that,
981 const ScenePoint2D& p1, 1019 const ScenePoint2D& p1,
982 const ScenePoint2D& p2) : 1020 const ScenePoint2D& p2) :
983 Measure(that), 1021 Annotation(that),
984 handle1_(AddTypedPrimitive<Handle>(new Handle(*this, p1))), 1022 handle1_(AddTypedPrimitive<Handle>(new Handle(*this, p1))),
985 handle2_(AddTypedPrimitive<Handle>(new Handle(*this, p2))), 1023 handle2_(AddTypedPrimitive<Handle>(new Handle(*this, p2))),
986 segment_(AddTypedPrimitive<Segment>(new Segment(*this, p1, p2))), 1024 segment_(AddTypedPrimitive<Segment>(new Segment(*this, p1, p2))),
987 circle_(AddTypedPrimitive<Circle>(new Circle(*this, p1, p2))), 1025 circle_(AddTypedPrimitive<Circle>(new Circle(*this, p1, p2))),
988 label_(AddTypedPrimitive<Text>(new Text(that, *this))) 1026 label_(AddTypedPrimitive<Text>(new Text(that, *this)))
1011 circle_.SetPosition(segment_.GetPosition1(), segment_.GetPosition2()); 1049 circle_.SetPosition(segment_.GetPosition1(), segment_.GetPosition2());
1012 } 1050 }
1013 1051
1014 UpdateLabel(); 1052 UpdateLabel();
1015 } 1053 }
1054
1055 virtual void Serialize(Json::Value& target) ORTHANC_OVERRIDE
1056 {
1057 target = Json::objectValue;
1058 target[KEY_TYPE] = VALUE_CIRCLE;
1059 target[KEY_X1] = handle1_.GetCenter().GetX();
1060 target[KEY_Y1] = handle1_.GetCenter().GetY();
1061 target[KEY_X2] = handle2_.GetCenter().GetX();
1062 target[KEY_Y2] = handle2_.GetCenter().GetY();
1063 }
1016 }; 1064 };
1017 1065
1018 1066
1019 class CreateSegmentOrCircleTracker : public IFlexiblePointerTracker 1067 class CreateSegmentOrCircleTracker : public IFlexiblePointerTracker
1020 { 1068 {
1021 private: 1069 private:
1022 AnnotationsOverlay& that_; 1070 AnnotationsOverlay& that_;
1023 Measure* measure_; 1071 Annotation* annotation_;
1024 AffineTransform2D canvasToScene_; 1072 AffineTransform2D canvasToScene_;
1025 Handle* handle2_; 1073 Handle* handle2_;
1026 1074
1027 public: 1075 public:
1028 CreateSegmentOrCircleTracker(AnnotationsOverlay& that, 1076 CreateSegmentOrCircleTracker(AnnotationsOverlay& that,
1029 bool isCircle, 1077 bool isCircle,
1030 const ScenePoint2D& sceneClick, 1078 const ScenePoint2D& sceneClick,
1031 const AffineTransform2D& canvasToScene) : 1079 const AffineTransform2D& canvasToScene) :
1032 that_(that), 1080 that_(that),
1033 measure_(NULL), 1081 annotation_(NULL),
1034 canvasToScene_(canvasToScene), 1082 canvasToScene_(canvasToScene),
1035 handle2_(NULL) 1083 handle2_(NULL)
1036 { 1084 {
1037 if (isCircle) 1085 if (isCircle)
1038 { 1086 {
1039 measure_ = new CircleMeasure(that, sceneClick, sceneClick); 1087 annotation_ = new CircleAnnotation(that, sceneClick, sceneClick);
1040 handle2_ = &dynamic_cast<CircleMeasure*>(measure_)->GetHandle2(); 1088 handle2_ = &dynamic_cast<CircleAnnotation*>(annotation_)->GetHandle2();
1041 } 1089 }
1042 else 1090 else
1043 { 1091 {
1044 measure_ = new SegmentMeasure(that, true /* show label */, sceneClick, sceneClick); 1092 annotation_ = new SegmentAnnotation(that, true /* show label */, sceneClick, sceneClick);
1045 handle2_ = &dynamic_cast<SegmentMeasure*>(measure_)->GetHandle2(); 1093 handle2_ = &dynamic_cast<SegmentAnnotation*>(annotation_)->GetHandle2();
1046 } 1094 }
1047 1095
1048 assert(measure_ != NULL && 1096 assert(annotation_ != NULL &&
1049 handle2_ != NULL); 1097 handle2_ != NULL);
1050 } 1098 }
1051 1099
1052 virtual void PointerMove(const PointerEvent& event) ORTHANC_OVERRIDE 1100 virtual void PointerMove(const PointerEvent& event) ORTHANC_OVERRIDE
1053 { 1101 {
1054 if (measure_ != NULL) 1102 if (annotation_ != NULL)
1055 { 1103 {
1056 assert(handle2_ != NULL); 1104 assert(handle2_ != NULL);
1057 handle2_->SetCenter(event.GetMainPosition().Apply(canvasToScene_)); 1105 handle2_->SetCenter(event.GetMainPosition().Apply(canvasToScene_));
1058 measure_->SignalMove(*handle2_); 1106 annotation_->SignalMove(*handle2_);
1059 } 1107 }
1060 } 1108 }
1061 1109
1062 virtual void PointerUp(const PointerEvent& event) ORTHANC_OVERRIDE 1110 virtual void PointerUp(const PointerEvent& event) ORTHANC_OVERRIDE
1063 { 1111 {
1064 measure_ = NULL; // IsAlive() becomes false 1112 annotation_ = NULL; // IsAlive() becomes false
1065 } 1113 }
1066 1114
1067 virtual void PointerDown(const PointerEvent& event) ORTHANC_OVERRIDE 1115 virtual void PointerDown(const PointerEvent& event) ORTHANC_OVERRIDE
1068 { 1116 {
1069 } 1117 }
1070 1118
1071 virtual bool IsAlive() const ORTHANC_OVERRIDE 1119 virtual bool IsAlive() const ORTHANC_OVERRIDE
1072 { 1120 {
1073 return (measure_ != NULL); 1121 return (annotation_ != NULL);
1074 } 1122 }
1075 1123
1076 virtual void Cancel() ORTHANC_OVERRIDE 1124 virtual void Cancel() ORTHANC_OVERRIDE
1077 { 1125 {
1078 if (measure_ != NULL) 1126 if (annotation_ != NULL)
1079 { 1127 {
1080 that_.DeleteMeasure(measure_); 1128 that_.DeleteAnnotation(annotation_);
1081 measure_ = NULL; 1129 annotation_ = NULL;
1082 } 1130 }
1083 } 1131 }
1084 }; 1132 };
1085 1133
1086 1134
1087 class CreateAngleTracker : public IFlexiblePointerTracker 1135 class CreateAngleTracker : public IFlexiblePointerTracker
1088 { 1136 {
1089 private: 1137 private:
1090 AnnotationsOverlay& that_; 1138 AnnotationsOverlay& that_;
1091 SegmentMeasure* segment_; 1139 SegmentAnnotation* segment_;
1092 AngleMeasure* angle_; 1140 AngleAnnotation* angle_;
1093 AffineTransform2D canvasToScene_; 1141 AffineTransform2D canvasToScene_;
1094 1142
1095 public: 1143 public:
1096 CreateAngleTracker(AnnotationsOverlay& that, 1144 CreateAngleTracker(AnnotationsOverlay& that,
1097 const ScenePoint2D& sceneClick, 1145 const ScenePoint2D& sceneClick,
1099 that_(that), 1147 that_(that),
1100 segment_(NULL), 1148 segment_(NULL),
1101 angle_(NULL), 1149 angle_(NULL),
1102 canvasToScene_(canvasToScene) 1150 canvasToScene_(canvasToScene)
1103 { 1151 {
1104 segment_ = new SegmentMeasure(that, false /* no length label */, sceneClick, sceneClick); 1152 segment_ = new SegmentAnnotation(that, false /* no length label */, sceneClick, sceneClick);
1105 } 1153 }
1106 1154
1107 virtual void PointerMove(const PointerEvent& event) ORTHANC_OVERRIDE 1155 virtual void PointerMove(const PointerEvent& event) ORTHANC_OVERRIDE
1108 { 1156 {
1109 if (segment_ != NULL) 1157 if (segment_ != NULL)
1123 { 1171 {
1124 if (segment_ != NULL) 1172 if (segment_ != NULL)
1125 { 1173 {
1126 // End of first step: The first segment is available, now create the angle 1174 // End of first step: The first segment is available, now create the angle
1127 1175
1128 angle_ = new AngleMeasure(that_, segment_->GetHandle1().GetCenter(), 1176 angle_ = new AngleAnnotation(that_, segment_->GetHandle1().GetCenter(),
1129 segment_->GetHandle2().GetCenter(), 1177 segment_->GetHandle2().GetCenter(),
1130 segment_->GetHandle2().GetCenter()); 1178 segment_->GetHandle2().GetCenter());
1131 1179
1132 that_.DeleteMeasure(segment_); 1180 that_.DeleteAnnotation(segment_);
1133 segment_ = NULL; 1181 segment_ = NULL;
1134 } 1182 }
1135 else 1183 else
1136 { 1184 {
1137 angle_ = NULL; // IsAlive() becomes false 1185 angle_ = NULL; // IsAlive() becomes false
1150 1198
1151 virtual void Cancel() ORTHANC_OVERRIDE 1199 virtual void Cancel() ORTHANC_OVERRIDE
1152 { 1200 {
1153 if (segment_ != NULL) 1201 if (segment_ != NULL)
1154 { 1202 {
1155 that_.DeleteMeasure(segment_); 1203 that_.DeleteAnnotation(segment_);
1156 segment_ = NULL; 1204 segment_ = NULL;
1157 } 1205 }
1158 1206
1159 if (angle_ != NULL) 1207 if (angle_ != NULL)
1160 { 1208 {
1161 that_.DeleteMeasure(angle_); 1209 that_.DeleteAnnotation(angle_);
1162 angle_ = NULL; 1210 angle_ = NULL;
1163 } 1211 }
1164 } 1212 }
1165 }; 1213 };
1166 1214
1195 { 1243 {
1196 } 1244 }
1197 }; 1245 };
1198 1246
1199 1247
1200 typedef std::set<Primitive*> Primitives; 1248 typedef std::set<Primitive*> Primitives;
1201 typedef std::set<Measure*> Measures; 1249 typedef std::set<Annotation*> Annotations;
1202 typedef std::set<size_t> SubLayers; 1250 typedef std::set<size_t> SubLayers;
1203 1251
1204 Tool activeTool_; 1252 Tool activeTool_;
1205 size_t macroLayerIndex_; 1253 size_t macroLayerIndex_;
1206 size_t polylineSubLayer_; 1254 size_t polylineSubLayer_;
1207 Primitives primitives_; 1255 Primitives primitives_;
1208 Measures measures_; 1256 Annotations annotations_;
1209 SubLayers subLayersToRemove_; 1257 SubLayers subLayersToRemove_;
1210 1258
1211 void AddMeasure(Measure* measure) 1259 void AddAnnotation(Annotation* annotation)
1212 { 1260 {
1213 assert(measure != NULL); 1261 assert(annotation != NULL);
1214 assert(measures_.find(measure) == measures_.end()); 1262 assert(annotations_.find(annotation) == annotations_.end());
1215 measures_.insert(measure); 1263 annotations_.insert(annotation);
1216 } 1264 }
1217 1265
1218 void DeleteMeasure(Measure* measure) 1266 void DeleteAnnotation(Annotation* annotation)
1219 { 1267 {
1220 if (measure != NULL) 1268 if (annotation != NULL)
1221 { 1269 {
1222 assert(measures_.find(measure) != measures_.end()); 1270 assert(annotations_.find(annotation) != annotations_.end());
1223 measures_.erase(measure); 1271 annotations_.erase(annotation);
1224 delete measure; 1272 delete annotation;
1225 } 1273 }
1226 } 1274 }
1227 1275
1228 void DeletePrimitive(Primitive* primitive) 1276 void DeletePrimitive(Primitive* primitive)
1229 { 1277 {
1245 AnnotationsOverlay(size_t macroLayerIndex) : 1293 AnnotationsOverlay(size_t macroLayerIndex) :
1246 activeTool_(Tool_Edit), 1294 activeTool_(Tool_Edit),
1247 macroLayerIndex_(macroLayerIndex), 1295 macroLayerIndex_(macroLayerIndex),
1248 polylineSubLayer_(0) // dummy initialization 1296 polylineSubLayer_(0) // dummy initialization
1249 { 1297 {
1250 measures_.insert(new SegmentMeasure(*this, true /* show label */, ScenePoint2D(0, 0), ScenePoint2D(100, 100))); 1298 annotations_.insert(new SegmentAnnotation(*this, true /* show label */, ScenePoint2D(0, 0), ScenePoint2D(100, 100)));
1251 measures_.insert(new AngleMeasure(*this, ScenePoint2D(100, 50), ScenePoint2D(150, 40), ScenePoint2D(200, 50))); 1299 annotations_.insert(new AngleAnnotation(*this, ScenePoint2D(100, 50), ScenePoint2D(150, 40), ScenePoint2D(200, 50)));
1252 measures_.insert(new CircleMeasure(*this, ScenePoint2D(50, 200), ScenePoint2D(100, 250))); 1300 annotations_.insert(new CircleAnnotation(*this, ScenePoint2D(50, 200), ScenePoint2D(100, 250)));
1253 } 1301 }
1254 1302
1255 ~AnnotationsOverlay() 1303 ~AnnotationsOverlay()
1256 { 1304 {
1257 for (Measures::iterator it = measures_.begin(); it != measures_.end(); ++it) 1305 Clear();
1306 }
1307
1308 void Clear()
1309 {
1310 for (Annotations::iterator it = annotations_.begin(); it != annotations_.end(); ++it)
1258 { 1311 {
1259 assert(*it != NULL); 1312 assert(*it != NULL);
1260 delete *it; 1313 delete *it;
1261 } 1314 }
1262 1315
1263 measures_.clear(); 1316 annotations_.clear();
1264 } 1317 }
1265 1318
1266 void SetActiveTool(Tool tool) 1319 void SetActiveTool(Tool tool)
1267 { 1320 {
1268 activeTool_ = tool; 1321 activeTool_ = tool;
1390 1443
1391 if (bestHit != NULL) 1444 if (bestHit != NULL)
1392 { 1445 {
1393 if (activeTool_ == Tool_Erase) 1446 if (activeTool_ == Tool_Erase)
1394 { 1447 {
1395 DeleteMeasure(&bestHit->GetParentMeasure()); 1448 DeleteAnnotation(&bestHit->GetParentAnnotation());
1396 return new EraseTracker; 1449 return new EraseTracker;
1397 } 1450 }
1398 else 1451 else
1399 { 1452 {
1400 return new EditPrimitiveTracker(*bestHit, s, scene.GetCanvasToSceneTransform()); 1453 return new EditPrimitiveTracker(*bestHit, s, scene.GetCanvasToSceneTransform());
1417 return NULL; 1470 return NULL;
1418 } 1471 }
1419 } 1472 }
1420 } 1473 }
1421 } 1474 }
1475
1476
1477 void Serialize(Json::Value& target) const
1478 {
1479 Json::Value annotations = Json::arrayValue;
1480
1481 for (Annotations::const_iterator it = annotations_.begin(); it != annotations_.end(); ++it)
1482 {
1483 assert(*it != NULL);
1484
1485 Json::Value item;
1486 (*it)->Serialize(item);
1487 annotations.append(item);
1488 }
1489
1490 target = Json::objectValue;
1491 target[KEY_ANNOTATIONS] = annotations;
1492 }
1422 }; 1493 };
1423 } 1494 }
1424 #endif 1495 #endif
1425 1496
1426 1497
1450 ; 1521 ;
1451 1522
1452 std::cout << desc << std::endl; 1523 std::cout << desc << std::endl;
1453 1524
1454 std::cout << std::endl << "Keyboard shorcuts:" << std::endl 1525 std::cout << std::endl << "Keyboard shorcuts:" << std::endl
1455 << " a\tEnable/disable the angle measure tool" << std::endl 1526 << " a\tEnable/disable the angle annotation tool" << std::endl
1456 << " f\tToggle fullscreen display" << std::endl 1527 << " f\tToggle fullscreen display" << std::endl
1457 << " l\tEnable/disable the line measure tool" << std::endl 1528 << " l\tEnable/disable the line annotation tool" << std::endl
1458 << " q\tExit" << std::endl 1529 << " q\tExit" << std::endl
1459 << " r\tRedo the last edit to the measure tools" << std::endl 1530 << " r\tRedo the last edit to the annotation tools" << std::endl
1460 << " s\tFit the viewpoint to the image" << std::endl 1531 << " s\tFit the viewpoint to the image" << std::endl
1461 << " u\tUndo the last edit to the measure tools" << std::endl 1532 << " u\tUndo the last edit to the annotation tools" << std::endl
1462 << std::endl << "Mouse buttons:" << std::endl 1533 << std::endl << "Mouse buttons:" << std::endl
1463 << " left \tChange windowing, or edit measure" << std::endl 1534 << " left \tChange windowing, or edit annotation" << std::endl
1464 << " center\tMove the viewpoint, or edit measure" << std::endl 1535 << " center\tMove the viewpoint, or edit annotation" << std::endl
1465 << " right \tZoom, or edit measure" << std::endl 1536 << " right \tZoom, or edit annotation" << std::endl
1466 << std::endl; 1537 << std::endl;
1467 1538
1468 po::variables_map vm; 1539 po::variables_map vm;
1469 try 1540 try
1470 { 1541 {
1550 std::string font; 1621 std::string font;
1551 Orthanc::EmbeddedResources::GetFileResource(font, Orthanc::EmbeddedResources::UBUNTU_FONT); 1622 Orthanc::EmbeddedResources::GetFileResource(font, Orthanc::EmbeddedResources::UBUNTU_FONT);
1552 1623
1553 std::unique_ptr<OrthancStone::IViewport::ILock> lock(viewport->Lock()); 1624 std::unique_ptr<OrthancStone::IViewport::ILock> lock(viewport->Lock());
1554 lock->GetCompositor().SetFont(0, font, 16, Orthanc::Encoding_Latin1); 1625 lock->GetCompositor().SetFont(0, font, 16, Orthanc::Encoding_Latin1);
1555 lock->GetController().SetUndoStack(undoStack); 1626 //lock->GetController().SetUndoStack(undoStack);
1556 } 1627 }
1557 1628
1558 ActiveTool activeTool = ActiveTool_None; 1629 ActiveTool activeTool = ActiveTool_None;
1559 1630
1560 boost::shared_ptr<OrthancStone::LineMeasureTool> lineMeasureTool(OrthancStone::LineMeasureTool::Create(viewport)); 1631 boost::shared_ptr<OrthancStone::LineMeasureTool> lineMeasureTool(OrthancStone::LineMeasureTool::Create(viewport));
1565 bool angleMeasureFirst = true; 1636 bool angleMeasureFirst = true;
1566 angleMeasureTool->Disable(); 1637 angleMeasureTool->Disable();
1567 1638
1568 OrthancStone::AnnotationsOverlay overlay(10); 1639 OrthancStone::AnnotationsOverlay overlay(10);
1569 overlay.SetActiveTool(OrthancStone::AnnotationsOverlay::Tool_Angle); 1640 overlay.SetActiveTool(OrthancStone::AnnotationsOverlay::Tool_Angle);
1641
1642 {
1643 Json::Value v;
1644 overlay.Serialize(v);
1645 std::cout << v.toStyledString() << std::endl;
1646 }
1570 1647
1571 boost::shared_ptr<SdlSimpleViewerApplication> application( 1648 boost::shared_ptr<SdlSimpleViewerApplication> application(
1572 SdlSimpleViewerApplication::Create(context, viewport)); 1649 SdlSimpleViewerApplication::Create(context, viewport));
1573 1650
1574 OrthancStone::DicomSource source; 1651 OrthancStone::DicomSource source;
1728 { 1805 {
1729 case SDL_MOUSEBUTTONDOWN: 1806 case SDL_MOUSEBUTTONDOWN:
1730 { 1807 {
1731 boost::shared_ptr<OrthancStone::IFlexiblePointerTracker> t; 1808 boost::shared_ptr<OrthancStone::IFlexiblePointerTracker> t;
1732 1809
1733 t.reset(overlay.CreateTracker(p.GetMainPosition(), lock->GetController().GetScene())); 1810 if (p.GetMouseButton() == OrthancStone::MouseButton_Left)
1811 {
1812 t.reset(overlay.CreateTracker(p.GetMainPosition(), lock->GetController().GetScene()));
1813 }
1814
1734 if (t.get() == NULL) 1815 if (t.get() == NULL)
1735 { 1816 {
1736 switch (activeTool) 1817 switch (activeTool)
1737 { 1818 {
1738 case ActiveTool_Angle: 1819 case ActiveTool_Angle: