comparison Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp @ 1815:b81775f1b196

New tools for annotations: segment length, circle, angle and eraser
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 25 May 2021 18:07:52 +0200
parents 53f3411bf94b
children dccdc7e59929
comparison
equal deleted inserted replaced
1814:53f3411bf94b 1815:b81775f1b196
128 }; 128 };
129 129
130 130
131 enum STONE_WEB_VIEWER_EXPORT WebViewerAction 131 enum STONE_WEB_VIEWER_EXPORT WebViewerAction
132 { 132 {
133 WebViewerAction_Windowing, 133 WebViewerAction_None,
134
135 WebViewerAction_Windowing,
134 WebViewerAction_Zoom, 136 WebViewerAction_Zoom,
135 WebViewerAction_Pan, 137 WebViewerAction_Pan,
136 WebViewerAction_Rotate, 138 WebViewerAction_Rotate,
137 WebViewerAction_Crosshair, 139 WebViewerAction_Crosshair,
138 140
139 WebViewerAction_CreateAngle, 141 WebViewerAction_CreateAngle,
140 WebViewerAction_CreateCircle, 142 WebViewerAction_CreateCircle,
141 WebViewerAction_CreateSegment, 143 WebViewerAction_CreateSegment,
142 WebViewerAction_DeleteMeasure 144 WebViewerAction_RemoveMeasure
143 }; 145 };
144 146
145 147
146 148
147 static OrthancStone::MouseAction ConvertWebViewerAction(int action) 149 static OrthancStone::MouseAction ConvertWebViewerAction(int action)
158 return OrthancStone::MouseAction_Pan; 160 return OrthancStone::MouseAction_Pan;
159 161
160 case WebViewerAction_Rotate: 162 case WebViewerAction_Rotate:
161 return OrthancStone::MouseAction_Rotate; 163 return OrthancStone::MouseAction_Rotate;
162 164
165 case WebViewerAction_None:
163 case WebViewerAction_Crosshair: 166 case WebViewerAction_Crosshair:
164 case WebViewerAction_CreateAngle: 167 case WebViewerAction_CreateAngle:
165 case WebViewerAction_CreateCircle: 168 case WebViewerAction_CreateCircle:
166 case WebViewerAction_CreateSegment: 169 case WebViewerAction_CreateSegment:
167 case WebViewerAction_DeleteMeasure: 170 case WebViewerAction_RemoveMeasure:
168 return OrthancStone::MouseAction_None; 171 return OrthancStone::MouseAction_None;
169 172
170 default: 173 default:
171 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); 174 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
172 } 175 }
1321 double windowingWidth) = 0; 1324 double windowingWidth) = 0;
1322 1325
1323 virtual void SignalStoneAnnotationsChanged(const ViewerViewport& viewport, 1326 virtual void SignalStoneAnnotationsChanged(const ViewerViewport& viewport,
1324 const std::string& sopInstanceUid, 1327 const std::string& sopInstanceUid,
1325 size_t frame) = 0; 1328 size_t frame) = 0;
1329
1330 virtual void SignalStoneAnnotationAdded(const ViewerViewport& viewport) = 0;
1331
1332 virtual void SignalStoneAnnotationRemoved(const ViewerViewport& viewport) = 0;
1326 }; 1333 };
1327 1334
1328 private: 1335 private:
1329 static const int LAYER_TEXTURE = 0; 1336 static const int LAYER_TEXTURE = 0;
1330 static const int LAYER_REFERENCE_LINES = 1; 1337 static const int LAYER_REFERENCE_LINES = 1;
2285 } 2292 }
2286 2293
2287 void Handle(const OrthancStone::AnnotationsSceneLayer::AnnotationAddedMessage& message) 2294 void Handle(const OrthancStone::AnnotationsSceneLayer::AnnotationAddedMessage& message)
2288 { 2295 {
2289 RefreshAnnotations(true /* save */); 2296 RefreshAnnotations(true /* save */);
2297
2298 if (observer_.get() != NULL)
2299 {
2300 observer_->SignalStoneAnnotationAdded(*this);
2301 }
2290 } 2302 }
2291 2303
2292 void Handle(const OrthancStone::AnnotationsSceneLayer::AnnotationRemovedMessage& message) 2304 void Handle(const OrthancStone::AnnotationsSceneLayer::AnnotationRemovedMessage& message)
2293 { 2305 {
2294 RefreshAnnotations(true /* save */); 2306 RefreshAnnotations(true /* save */);
2307
2308 if (observer_.get() != NULL)
2309 {
2310 observer_->SignalStoneAnnotationRemoved(*this);
2311 }
2295 } 2312 }
2296 2313
2297 public: 2314 public:
2298 virtual ~ViewerViewport() 2315 virtual ~ViewerViewport()
2299 { 2316 {
2769 2786
2770 return NULL; // No need for a tracker, this is just a click 2787 return NULL; // No need for a tracker, this is just a click
2771 } 2788 }
2772 else 2789 else
2773 { 2790 {
2791 // Only the left mouse button can be used to edit/create/remove annotations
2792 if (event.GetMouseButton() == OrthancStone::MouseButton_Left)
2774 { 2793 {
2775 std::unique_ptr<OrthancStone::IViewport::ILock> lock2(lock1->Lock()); 2794 switch (leftAction_)
2776
2777 std::unique_ptr<OrthancStone::IFlexiblePointerTracker> t;
2778 t.reset(viewer_.stoneAnnotations_->CreateTracker(event.GetMainPosition(), lock2->GetController().GetScene()));
2779
2780 if (t.get() != NULL)
2781 { 2795 {
2782 return t.release(); 2796 case WebViewerAction_CreateAngle:
2797 viewer_.stoneAnnotations_->SetActiveTool(OrthancStone::AnnotationsSceneLayer::Tool_Angle);
2798 break;
2799
2800 case WebViewerAction_CreateCircle:
2801 viewer_.stoneAnnotations_->SetActiveTool(OrthancStone::AnnotationsSceneLayer::Tool_Circle);
2802 break;
2803
2804 case WebViewerAction_CreateSegment:
2805 viewer_.stoneAnnotations_->SetActiveTool(OrthancStone::AnnotationsSceneLayer::Tool_Segment);
2806 break;
2807
2808 case WebViewerAction_RemoveMeasure:
2809 viewer_.stoneAnnotations_->SetActiveTool(OrthancStone::AnnotationsSceneLayer::Tool_Remove);
2810 break;
2811
2812 default:
2813 viewer_.stoneAnnotations_->SetActiveTool(OrthancStone::AnnotationsSceneLayer::Tool_Edit);
2814 break;
2815 }
2816
2817 {
2818 std::unique_ptr<OrthancStone::IViewport::ILock> lock2(lock1->Lock());
2819
2820 std::unique_ptr<OrthancStone::IFlexiblePointerTracker> t;
2821 t.reset(viewer_.stoneAnnotations_->CreateTracker(event.GetMainPosition(), lock2->GetController().GetScene()));
2822
2823 if (t.get() != NULL)
2824 {
2825 return t.release();
2826 }
2783 } 2827 }
2784 } 2828 }
2785 2829
2786 return DefaultViewportInteractor::CreateTracker( 2830 return DefaultViewportInteractor::CreateTracker(
2787 viewport, event, viewportWidth, viewportHeight); 2831 viewport, event, viewportWidth, viewportHeight);
3163 if (it->second.get() != &viewport) 3207 if (it->second.get() != &viewport)
3164 { 3208 {
3165 it->second->SignalStoneAnnotationsChanged(sopInstanceUid, frame); 3209 it->second->SignalStoneAnnotationsChanged(sopInstanceUid, frame);
3166 } 3210 }
3167 } 3211 }
3212 }
3213
3214 virtual void SignalStoneAnnotationAdded(const ViewerViewport& viewport) ORTHANC_OVERRIDE
3215 {
3216 EM_ASM({
3217 const customEvent = document.createEvent("CustomEvent");
3218 customEvent.initCustomEvent("StoneAnnotationAdded", false, false,
3219 { "canvasId" : UTF8ToString($0) });
3220 window.dispatchEvent(customEvent);
3221 },
3222 viewport.GetCanvasId().c_str());
3223 }
3224
3225 virtual void SignalStoneAnnotationRemoved(const ViewerViewport& viewport) ORTHANC_OVERRIDE
3226 {
3227 EM_ASM({
3228 const customEvent = document.createEvent("CustomEvent");
3229 customEvent.initCustomEvent("StoneAnnotationRemoved", false, false,
3230 { "canvasId" : UTF8ToString($0) });
3231 window.dispatchEvent(customEvent);
3232 },
3233 viewport.GetCanvasId().c_str());
3168 } 3234 }
3169 }; 3235 };
3170 3236
3171 3237
3172 3238
3697 EXTERN_CATCH_EXCEPTIONS; 3763 EXTERN_CATCH_EXCEPTIONS;
3698 } 3764 }
3699 3765
3700 3766
3701 EMSCRIPTEN_KEEPALIVE 3767 EMSCRIPTEN_KEEPALIVE
3768 int GetLeftMouseButtonAction()
3769 {
3770 return static_cast<int>(leftButtonAction_);
3771 }
3772
3773
3774 EMSCRIPTEN_KEEPALIVE
3775 int GetMiddleMouseButtonAction()
3776 {
3777 return static_cast<int>(middleButtonAction_);
3778 }
3779
3780
3781 EMSCRIPTEN_KEEPALIVE
3782 int GetRightMouseButtonAction()
3783 {
3784 return static_cast<int>(rightButtonAction_);
3785 }
3786
3787
3788 EMSCRIPTEN_KEEPALIVE
3702 void FitForPrint() 3789 void FitForPrint()
3703 { 3790 {
3704 try 3791 try
3705 { 3792 {
3706 for (Viewports::iterator it = allViewports_.begin(); it != allViewports_.end(); ++it) 3793 for (Viewports::iterator it = allViewports_.begin(); it != allViewports_.end(); ++it)