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