Mercurial > hg > orthanc-stone
comparison Applications/Samples/Sdl/SingleFrameViewer/SdlSimpleViewer.cpp @ 1803:d1849468729b
added messages to AnnotationsLayer
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 20 May 2021 14:15:00 +0200 |
parents | 64dad1d7aca4 |
children | 5a872e69c74f |
comparison
equal
deleted
inserted
replaced
1802:757987cb5a68 | 1803:d1849468729b |
---|---|
66 static const char* const VALUE_SEGMENT = "segment"; | 66 static const char* const VALUE_SEGMENT = "segment"; |
67 | 67 |
68 | 68 |
69 namespace OrthancStone | 69 namespace OrthancStone |
70 { | 70 { |
71 class AnnotationsOverlay : public boost::noncopyable | 71 class AnnotationsLayer : public IObservable |
72 { | 72 { |
73 public: | 73 public: |
74 ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, AnnotationAddedMessage, AnnotationsLayer); | |
75 ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, AnnotationRemovedMessage, AnnotationsLayer); | |
76 | |
74 enum Tool | 77 enum Tool |
75 { | 78 { |
76 Tool_Edit, | 79 Tool_Edit, |
77 Tool_None, | 80 Tool_None, |
78 Tool_Segment, | 81 Tool_Segment, |
186 class Annotation : public boost::noncopyable | 189 class Annotation : public boost::noncopyable |
187 { | 190 { |
188 private: | 191 private: |
189 typedef std::list<GeometricPrimitive*> GeometricPrimitives; | 192 typedef std::list<GeometricPrimitive*> GeometricPrimitives; |
190 | 193 |
191 AnnotationsOverlay& that_; | 194 AnnotationsLayer& that_; |
192 GeometricPrimitives primitives_; | 195 GeometricPrimitives primitives_; |
193 | 196 |
194 public: | 197 public: |
195 Annotation(AnnotationsOverlay& that) : | 198 Annotation(AnnotationsLayer& that) : |
196 that_(that) | 199 that_(that) |
197 { | 200 { |
198 that.AddAnnotation(this); | 201 that.AddAnnotation(this); |
199 } | 202 } |
200 | 203 |
634 | 637 |
635 | 638 |
636 class Text : public GeometricPrimitive | 639 class Text : public GeometricPrimitive |
637 { | 640 { |
638 private: | 641 private: |
639 AnnotationsOverlay& that_; | 642 AnnotationsLayer& that_; |
640 bool first_; | 643 bool first_; |
641 size_t subLayer_; | 644 size_t subLayer_; |
642 std::unique_ptr<TextSceneLayer> content_; | 645 std::unique_ptr<TextSceneLayer> content_; |
643 | 646 |
644 public: | 647 public: |
645 Text(AnnotationsOverlay& that, | 648 Text(AnnotationsLayer& that, |
646 Annotation& parentAnnotation) : | 649 Annotation& parentAnnotation) : |
647 GeometricPrimitive(parentAnnotation, 2), | 650 GeometricPrimitive(parentAnnotation, 2), |
648 that_(that), | 651 that_(that), |
649 first_(true) | 652 first_(true) |
650 { | 653 { |
796 label_.SetContent(content); | 799 label_.SetContent(content); |
797 } | 800 } |
798 } | 801 } |
799 | 802 |
800 public: | 803 public: |
801 SegmentAnnotation(AnnotationsOverlay& that, | 804 SegmentAnnotation(AnnotationsLayer& that, |
802 bool showLabel, | 805 bool showLabel, |
803 const ScenePoint2D& p1, | 806 const ScenePoint2D& p1, |
804 const ScenePoint2D& p2) : | 807 const ScenePoint2D& p2) : |
805 Annotation(that), | 808 Annotation(that), |
806 showLabel_(showLabel), | 809 showLabel_(showLabel), |
847 target[KEY_Y1] = handle1_.GetCenter().GetY(); | 850 target[KEY_Y1] = handle1_.GetCenter().GetY(); |
848 target[KEY_X2] = handle2_.GetCenter().GetX(); | 851 target[KEY_X2] = handle2_.GetCenter().GetX(); |
849 target[KEY_Y2] = handle2_.GetCenter().GetY(); | 852 target[KEY_Y2] = handle2_.GetCenter().GetY(); |
850 } | 853 } |
851 | 854 |
852 static void Unserialize(AnnotationsOverlay& target, | 855 static void Unserialize(AnnotationsLayer& target, |
853 const Json::Value& source) | 856 const Json::Value& source) |
854 { | 857 { |
855 if (source.isMember(KEY_X1) && | 858 if (source.isMember(KEY_X1) && |
856 source.isMember(KEY_Y1) && | 859 source.isMember(KEY_Y1) && |
857 source.isMember(KEY_X2) && | 860 source.isMember(KEY_X2) && |
913 | 916 |
914 label_.SetContent(content); | 917 label_.SetContent(content); |
915 } | 918 } |
916 | 919 |
917 public: | 920 public: |
918 AngleAnnotation(AnnotationsOverlay& that, | 921 AngleAnnotation(AnnotationsLayer& that, |
919 const ScenePoint2D& start, | 922 const ScenePoint2D& start, |
920 const ScenePoint2D& middle, | 923 const ScenePoint2D& middle, |
921 const ScenePoint2D& end) : | 924 const ScenePoint2D& end) : |
922 Annotation(that), | 925 Annotation(that), |
923 startHandle_(AddTypedPrimitive<Handle>(new Handle(*this, start))), | 926 startHandle_(AddTypedPrimitive<Handle>(new Handle(*this, start))), |
985 target[KEY_Y2] = middleHandle_.GetCenter().GetY(); | 988 target[KEY_Y2] = middleHandle_.GetCenter().GetY(); |
986 target[KEY_X3] = endHandle_.GetCenter().GetX(); | 989 target[KEY_X3] = endHandle_.GetCenter().GetX(); |
987 target[KEY_Y3] = endHandle_.GetCenter().GetY(); | 990 target[KEY_Y3] = endHandle_.GetCenter().GetY(); |
988 } | 991 } |
989 | 992 |
990 static void Unserialize(AnnotationsOverlay& target, | 993 static void Unserialize(AnnotationsLayer& target, |
991 const Json::Value& source) | 994 const Json::Value& source) |
992 { | 995 { |
993 if (source.isMember(KEY_X1) && | 996 if (source.isMember(KEY_X1) && |
994 source.isMember(KEY_Y1) && | 997 source.isMember(KEY_Y1) && |
995 source.isMember(KEY_X2) && | 998 source.isMember(KEY_X2) && |
1062 | 1065 |
1063 label_.SetContent(content); | 1066 label_.SetContent(content); |
1064 } | 1067 } |
1065 | 1068 |
1066 public: | 1069 public: |
1067 CircleAnnotation(AnnotationsOverlay& that, | 1070 CircleAnnotation(AnnotationsLayer& that, |
1068 const ScenePoint2D& p1, | 1071 const ScenePoint2D& p1, |
1069 const ScenePoint2D& p2) : | 1072 const ScenePoint2D& p2) : |
1070 Annotation(that), | 1073 Annotation(that), |
1071 handle1_(AddTypedPrimitive<Handle>(new Handle(*this, p1))), | 1074 handle1_(AddTypedPrimitive<Handle>(new Handle(*this, p1))), |
1072 handle2_(AddTypedPrimitive<Handle>(new Handle(*this, p2))), | 1075 handle2_(AddTypedPrimitive<Handle>(new Handle(*this, p2))), |
1109 target[KEY_Y1] = handle1_.GetCenter().GetY(); | 1112 target[KEY_Y1] = handle1_.GetCenter().GetY(); |
1110 target[KEY_X2] = handle2_.GetCenter().GetX(); | 1113 target[KEY_X2] = handle2_.GetCenter().GetX(); |
1111 target[KEY_Y2] = handle2_.GetCenter().GetY(); | 1114 target[KEY_Y2] = handle2_.GetCenter().GetY(); |
1112 } | 1115 } |
1113 | 1116 |
1114 static void Unserialize(AnnotationsOverlay& target, | 1117 static void Unserialize(AnnotationsLayer& target, |
1115 const Json::Value& source) | 1118 const Json::Value& source) |
1116 { | 1119 { |
1117 if (source.isMember(KEY_X1) && | 1120 if (source.isMember(KEY_X1) && |
1118 source.isMember(KEY_Y1) && | 1121 source.isMember(KEY_Y1) && |
1119 source.isMember(KEY_X2) && | 1122 source.isMember(KEY_X2) && |
1136 | 1139 |
1137 | 1140 |
1138 class CreateSegmentOrCircleTracker : public IFlexiblePointerTracker | 1141 class CreateSegmentOrCircleTracker : public IFlexiblePointerTracker |
1139 { | 1142 { |
1140 private: | 1143 private: |
1141 AnnotationsOverlay& that_; | 1144 AnnotationsLayer& that_; |
1142 Annotation* annotation_; | 1145 Annotation* annotation_; |
1143 AffineTransform2D canvasToScene_; | 1146 AffineTransform2D canvasToScene_; |
1144 Handle* handle2_; | 1147 Handle* handle2_; |
1145 | 1148 |
1146 public: | 1149 public: |
1147 CreateSegmentOrCircleTracker(AnnotationsOverlay& that, | 1150 CreateSegmentOrCircleTracker(AnnotationsLayer& that, |
1148 bool isCircle, | 1151 bool isCircle, |
1149 const ScenePoint2D& sceneClick, | 1152 const ScenePoint2D& sceneClick, |
1150 const AffineTransform2D& canvasToScene) : | 1153 const AffineTransform2D& canvasToScene) : |
1151 that_(that), | 1154 that_(that), |
1152 annotation_(NULL), | 1155 annotation_(NULL), |
1179 } | 1182 } |
1180 | 1183 |
1181 virtual void PointerUp(const PointerEvent& event) ORTHANC_OVERRIDE | 1184 virtual void PointerUp(const PointerEvent& event) ORTHANC_OVERRIDE |
1182 { | 1185 { |
1183 annotation_ = NULL; // IsAlive() becomes false | 1186 annotation_ = NULL; // IsAlive() becomes false |
1187 | |
1188 that_.BroadcastMessage(AnnotationAddedMessage(that_)); | |
1184 } | 1189 } |
1185 | 1190 |
1186 virtual void PointerDown(const PointerEvent& event) ORTHANC_OVERRIDE | 1191 virtual void PointerDown(const PointerEvent& event) ORTHANC_OVERRIDE |
1187 { | 1192 { |
1188 } | 1193 } |
1204 | 1209 |
1205 | 1210 |
1206 class CreateAngleTracker : public IFlexiblePointerTracker | 1211 class CreateAngleTracker : public IFlexiblePointerTracker |
1207 { | 1212 { |
1208 private: | 1213 private: |
1209 AnnotationsOverlay& that_; | 1214 AnnotationsLayer& that_; |
1210 SegmentAnnotation* segment_; | 1215 SegmentAnnotation* segment_; |
1211 AngleAnnotation* angle_; | 1216 AngleAnnotation* angle_; |
1212 AffineTransform2D canvasToScene_; | 1217 AffineTransform2D canvasToScene_; |
1213 | 1218 |
1214 public: | 1219 public: |
1215 CreateAngleTracker(AnnotationsOverlay& that, | 1220 CreateAngleTracker(AnnotationsLayer& that, |
1216 const ScenePoint2D& sceneClick, | 1221 const ScenePoint2D& sceneClick, |
1217 const AffineTransform2D& canvasToScene) : | 1222 const AffineTransform2D& canvasToScene) : |
1218 that_(that), | 1223 that_(that), |
1219 segment_(NULL), | 1224 segment_(NULL), |
1220 angle_(NULL), | 1225 angle_(NULL), |
1252 segment_ = NULL; | 1257 segment_ = NULL; |
1253 } | 1258 } |
1254 else | 1259 else |
1255 { | 1260 { |
1256 angle_ = NULL; // IsAlive() becomes false | 1261 angle_ = NULL; // IsAlive() becomes false |
1262 | |
1263 that_.BroadcastMessage(AnnotationAddedMessage(that_)); | |
1257 } | 1264 } |
1258 } | 1265 } |
1259 | 1266 |
1260 virtual void PointerDown(const PointerEvent& event) ORTHANC_OVERRIDE | 1267 virtual void PointerDown(const PointerEvent& event) ORTHANC_OVERRIDE |
1261 { | 1268 { |
1359 assert(subLayersToRemove_.find(subLayerIndex) == subLayersToRemove_.end()); | 1366 assert(subLayersToRemove_.find(subLayerIndex) == subLayersToRemove_.end()); |
1360 subLayersToRemove_.insert(subLayerIndex); | 1367 subLayersToRemove_.insert(subLayerIndex); |
1361 } | 1368 } |
1362 | 1369 |
1363 public: | 1370 public: |
1364 AnnotationsOverlay(size_t macroLayerIndex) : | 1371 AnnotationsLayer(size_t macroLayerIndex) : |
1365 activeTool_(Tool_Edit), | 1372 activeTool_(Tool_Edit), |
1366 macroLayerIndex_(macroLayerIndex), | 1373 macroLayerIndex_(macroLayerIndex), |
1367 polylineSubLayer_(0) // dummy initialization | 1374 polylineSubLayer_(0) // dummy initialization |
1368 { | 1375 { |
1369 annotations_.insert(new SegmentAnnotation(*this, true /* show label */, ScenePoint2D(0, 0), ScenePoint2D(100, 100))); | 1376 annotations_.insert(new SegmentAnnotation(*this, true /* show label */, ScenePoint2D(0, 0), ScenePoint2D(100, 100))); |
1370 annotations_.insert(new AngleAnnotation(*this, ScenePoint2D(100, 50), ScenePoint2D(150, 40), ScenePoint2D(200, 50))); | 1377 annotations_.insert(new AngleAnnotation(*this, ScenePoint2D(100, 50), ScenePoint2D(150, 40), ScenePoint2D(200, 50))); |
1371 annotations_.insert(new CircleAnnotation(*this, ScenePoint2D(50, 200), ScenePoint2D(100, 250))); | 1378 annotations_.insert(new CircleAnnotation(*this, ScenePoint2D(50, 200), ScenePoint2D(100, 250))); |
1372 } | 1379 } |
1373 | 1380 |
1374 ~AnnotationsOverlay() | 1381 ~AnnotationsLayer() |
1375 { | 1382 { |
1376 Clear(); | 1383 Clear(); |
1377 } | 1384 } |
1378 | 1385 |
1379 void Clear() | 1386 void Clear() |
1515 if (bestHit != NULL) | 1522 if (bestHit != NULL) |
1516 { | 1523 { |
1517 if (activeTool_ == Tool_Erase) | 1524 if (activeTool_ == Tool_Erase) |
1518 { | 1525 { |
1519 DeleteAnnotation(&bestHit->GetParentAnnotation()); | 1526 DeleteAnnotation(&bestHit->GetParentAnnotation()); |
1527 BroadcastMessage(AnnotationRemovedMessage(*this)); | |
1520 return new EraseTracker; | 1528 return new EraseTracker; |
1521 } | 1529 } |
1522 else | 1530 else |
1523 { | 1531 { |
1524 return new EditPrimitiveTracker(*bestHit, s, scene.GetCanvasToSceneTransform()); | 1532 return new EditPrimitiveTracker(*bestHit, s, scene.GetCanvasToSceneTransform()); |
1749 | 1757 |
1750 boost::shared_ptr<OrthancStone::AngleMeasureTool> angleMeasureTool(OrthancStone::AngleMeasureTool::Create(viewport)); | 1758 boost::shared_ptr<OrthancStone::AngleMeasureTool> angleMeasureTool(OrthancStone::AngleMeasureTool::Create(viewport)); |
1751 bool angleMeasureFirst = true; | 1759 bool angleMeasureFirst = true; |
1752 angleMeasureTool->Disable(); | 1760 angleMeasureTool->Disable(); |
1753 | 1761 |
1754 OrthancStone::AnnotationsOverlay overlay(10); | 1762 OrthancStone::AnnotationsLayer annotations(10); |
1755 overlay.SetActiveTool(OrthancStone::AnnotationsOverlay::Tool_Angle); | 1763 annotations.SetActiveTool(OrthancStone::AnnotationsLayer::Tool_Angle); |
1756 | 1764 |
1757 { | 1765 { |
1758 Json::Value v; | 1766 Json::Value v; |
1759 overlay.Serialize(v); | 1767 annotations.Serialize(v); |
1760 std::cout << v.toStyledString() << std::endl; | 1768 std::cout << v.toStyledString() << std::endl; |
1761 overlay.Clear(); | 1769 annotations.Clear(); |
1762 overlay.Unserialize(v); | 1770 annotations.Unserialize(v); |
1763 } | 1771 } |
1764 | 1772 |
1765 boost::shared_ptr<SdlSimpleViewerApplication> application( | 1773 boost::shared_ptr<SdlSimpleViewerApplication> application( |
1766 SdlSimpleViewerApplication::Create(context, viewport)); | 1774 SdlSimpleViewerApplication::Create(context, viewport)); |
1767 | 1775 |
1924 { | 1932 { |
1925 boost::shared_ptr<OrthancStone::IFlexiblePointerTracker> t; | 1933 boost::shared_ptr<OrthancStone::IFlexiblePointerTracker> t; |
1926 | 1934 |
1927 if (p.GetMouseButton() == OrthancStone::MouseButton_Left) | 1935 if (p.GetMouseButton() == OrthancStone::MouseButton_Left) |
1928 { | 1936 { |
1929 t.reset(overlay.CreateTracker(p.GetMainPosition(), lock->GetController().GetScene())); | 1937 t.reset(annotations.CreateTracker(p.GetMainPosition(), lock->GetController().GetScene())); |
1930 } | 1938 } |
1931 | 1939 |
1932 if (t.get() == NULL) | 1940 if (t.get() == NULL) |
1933 { | 1941 { |
1934 switch (activeTool) | 1942 switch (activeTool) |
1965 | 1973 |
1966 case SDL_MOUSEMOTION: | 1974 case SDL_MOUSEMOTION: |
1967 if (lock->GetController().HandleMouseMove(p)) | 1975 if (lock->GetController().HandleMouseMove(p)) |
1968 { | 1976 { |
1969 lock->Invalidate(); | 1977 lock->Invalidate(); |
1970 if (overlay.ClearHover()) | 1978 if (annotations.ClearHover()) |
1971 { | 1979 { |
1972 paint = true; | 1980 paint = true; |
1973 } | 1981 } |
1974 } | 1982 } |
1975 else | 1983 else |
1976 { | 1984 { |
1977 if (overlay.SetMouseHover(p.GetMainPosition(), lock->GetController().GetScene())) | 1985 if (annotations.SetMouseHover(p.GetMainPosition(), lock->GetController().GetScene())) |
1978 { | 1986 { |
1979 paint = true; | 1987 paint = true; |
1980 } | 1988 } |
1981 } | 1989 } |
1982 break; | 1990 break; |
1995 | 2003 |
1996 if (paint) | 2004 if (paint) |
1997 { | 2005 { |
1998 { | 2006 { |
1999 std::unique_ptr<OrthancStone::IViewport::ILock> lock(viewport->Lock()); | 2007 std::unique_ptr<OrthancStone::IViewport::ILock> lock(viewport->Lock()); |
2000 overlay.Render(lock->GetController().GetScene()); | 2008 annotations.Render(lock->GetController().GetScene()); |
2001 } | 2009 } |
2002 | 2010 |
2003 viewport->Paint(); | 2011 viewport->Paint(); |
2004 } | 2012 } |
2005 | 2013 |