Mercurial > hg > orthanc-stone
comparison Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp @ 1561:cf652990abb1
tunable mouse actions
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 20 Aug 2020 17:44:35 +0200 |
parents | 314b6dc507d9 |
children | e731e62692a9 |
comparison
equal
deleted
inserted
replaced
1560:b4ccd4963d37 | 1561:cf652990abb1 |
---|---|
77 #include <Scene2DViewport/ViewportController.h> | 77 #include <Scene2DViewport/ViewportController.h> |
78 #include <StoneException.h> | 78 #include <StoneException.h> |
79 #include <Toolbox/DicomInstanceParameters.h> | 79 #include <Toolbox/DicomInstanceParameters.h> |
80 #include <Toolbox/GeometryToolbox.h> | 80 #include <Toolbox/GeometryToolbox.h> |
81 #include <Toolbox/SortedFrames.h> | 81 #include <Toolbox/SortedFrames.h> |
82 #include <Viewport/DefaultViewportInteractor.h> | |
82 #include <Viewport/WebAssemblyCairoViewport.h> | 83 #include <Viewport/WebAssemblyCairoViewport.h> |
83 #include <Viewport/WebGLViewport.h> | 84 #include <Viewport/WebGLViewport.h> |
84 | 85 |
85 #include <boost/make_shared.hpp> | 86 #include <boost/make_shared.hpp> |
86 #include <stdio.h> | 87 #include <stdio.h> |
97 }; | 98 }; |
98 | 99 |
99 | 100 |
100 enum EMSCRIPTEN_KEEPALIVE DisplayedFrameQuality | 101 enum EMSCRIPTEN_KEEPALIVE DisplayedFrameQuality |
101 { | 102 { |
102 DisplayedFrameQuality_None, | 103 DisplayedFrameQuality_None, |
103 DisplayedFrameQuality_Low, | 104 DisplayedFrameQuality_Low, |
104 DisplayedFrameQuality_High | 105 DisplayedFrameQuality_High |
105 }; | 106 }; |
107 | |
108 | |
109 enum EMSCRIPTEN_KEEPALIVE MouseAction | |
110 { | |
111 MouseAction_GrayscaleWindowing, | |
112 MouseAction_Zoom, | |
113 MouseAction_Pan, | |
114 MouseAction_Rotate | |
115 }; | |
106 | 116 |
107 | 117 |
108 | 118 |
109 static const int PRIORITY_HIGH = -100; | 119 static const int PRIORITY_HIGH = -100; |
110 static const int PRIORITY_LOW = 100; | 120 static const int PRIORITY_LOW = 100; |
1370 //lock->GetCompositor().Refresh(lock->GetController().GetScene()); | 1380 //lock->GetCompositor().Refresh(lock->GetController().GetScene()); |
1371 lock->Invalidate(); | 1381 lock->Invalidate(); |
1372 } | 1382 } |
1373 } | 1383 } |
1374 | 1384 |
1385 | |
1386 void SaveCurrentWindowing() | |
1387 { | |
1388 // Save the current windowing (that could have been altered by | |
1389 // GrayscaleWindowingSceneTracker), so that it can be reused | |
1390 // by the next frames | |
1391 | |
1392 std::unique_ptr<OrthancStone::IViewport::ILock> lock(viewport_->Lock()); | |
1393 | |
1394 OrthancStone::Scene2D& scene = lock->GetController().GetScene(); | |
1395 | |
1396 if (scene.HasLayer(LAYER_TEXTURE) && | |
1397 scene.GetLayer(LAYER_TEXTURE).GetType() == OrthancStone::ISceneLayer::Type_FloatTexture) | |
1398 { | |
1399 OrthancStone::FloatTextureSceneLayer& layer = | |
1400 dynamic_cast<OrthancStone::FloatTextureSceneLayer&>(scene.GetLayer(LAYER_TEXTURE)); | |
1401 layer.GetWindowing(windowingCenter_, windowingWidth_); | |
1402 } | |
1403 } | |
1404 | |
1405 | |
1375 bool DisplayFrame(unsigned int& quality, | 1406 bool DisplayFrame(unsigned int& quality, |
1376 size_t index) | 1407 size_t index) |
1377 { | 1408 { |
1378 if (frames_.get() == NULL) | 1409 if (frames_.get() == NULL) |
1379 { | 1410 { |
1384 unsigned int frame = frames_->GetFrameIndex(index); | 1415 unsigned int frame = frames_->GetFrameIndex(index); |
1385 | 1416 |
1386 FramesCache::Accessor accessor(*cache_, sopInstanceUid, frame); | 1417 FramesCache::Accessor accessor(*cache_, sopInstanceUid, frame); |
1387 if (accessor.IsValid()) | 1418 if (accessor.IsValid()) |
1388 { | 1419 { |
1389 { | 1420 SaveCurrentWindowing(); |
1390 std::unique_ptr<OrthancStone::IViewport::ILock> lock(viewport_->Lock()); | |
1391 | |
1392 OrthancStone::Scene2D& scene = lock->GetController().GetScene(); | |
1393 | |
1394 // Save the current windowing (that could have been altered by | |
1395 // GrayscaleWindowingSceneTracker), so that it can be reused | |
1396 // by the next frames | |
1397 if (scene.HasLayer(LAYER_TEXTURE) && | |
1398 scene.GetLayer(LAYER_TEXTURE).GetType() == OrthancStone::ISceneLayer::Type_FloatTexture) | |
1399 { | |
1400 OrthancStone::FloatTextureSceneLayer& layer = | |
1401 dynamic_cast<OrthancStone::FloatTextureSceneLayer&>(scene.GetLayer(LAYER_TEXTURE)); | |
1402 layer.GetWindowing(windowingCenter_, windowingWidth_); | |
1403 } | |
1404 } | |
1405 | 1421 |
1406 quality = accessor.GetQuality(); | 1422 quality = accessor.GetQuality(); |
1407 | 1423 |
1408 std::unique_ptr<OrthancStone::TextureBaseSceneLayer> layer; | 1424 std::unique_ptr<OrthancStone::TextureBaseSceneLayer> layer; |
1409 | 1425 |
1840 } | 1856 } |
1841 | 1857 |
1842 void FlipX() | 1858 void FlipX() |
1843 { | 1859 { |
1844 flipX_ = !flipX_; | 1860 flipX_ = !flipX_; |
1861 SaveCurrentWindowing(); | |
1845 UpdateCurrentTextureParameters(); | 1862 UpdateCurrentTextureParameters(); |
1846 } | 1863 } |
1847 | 1864 |
1848 void FlipY() | 1865 void FlipY() |
1849 { | 1866 { |
1850 flipY_ = !flipY_; | 1867 flipY_ = !flipY_; |
1868 SaveCurrentWindowing(); | |
1851 UpdateCurrentTextureParameters(); | 1869 UpdateCurrentTextureParameters(); |
1852 } | 1870 } |
1853 | 1871 |
1854 void Invert() | 1872 void Invert() |
1855 { | 1873 { |
1870 // compatibility with MONOCHROME1 images | 1888 // compatibility with MONOCHROME1 images |
1871 layer.SetInverted(!layer.IsInverted()); | 1889 layer.SetInverted(!layer.IsInverted()); |
1872 lock->Invalidate(); | 1890 lock->Invalidate(); |
1873 } | 1891 } |
1874 } | 1892 } |
1893 } | |
1894 | |
1895 void SetMouseButtonActions(OrthancStone::MouseAction leftAction, | |
1896 OrthancStone::MouseAction middleAction, | |
1897 OrthancStone::MouseAction rightAction) | |
1898 { | |
1899 std::unique_ptr<OrthancStone::DefaultViewportInteractor> interactor( | |
1900 new OrthancStone::DefaultViewportInteractor); | |
1901 | |
1902 interactor->SetLeftButtonAction(leftAction); | |
1903 interactor->SetMiddleButtonAction(middleAction); | |
1904 interactor->SetRightButtonAction(rightAction); | |
1905 | |
1906 assert(viewport_ != NULL); | |
1907 viewport_->AcquireInteractor(interactor.release()); | |
1875 } | 1908 } |
1876 }; | 1909 }; |
1877 | 1910 |
1878 | 1911 |
1879 | 1912 |
1979 static OrthancStone::DicomSource source_; | 2012 static OrthancStone::DicomSource source_; |
1980 static boost::shared_ptr<FramesCache> cache_; | 2013 static boost::shared_ptr<FramesCache> cache_; |
1981 static boost::shared_ptr<OrthancStone::WebAssemblyLoadersContext> context_; | 2014 static boost::shared_ptr<OrthancStone::WebAssemblyLoadersContext> context_; |
1982 static std::string stringBuffer_; | 2015 static std::string stringBuffer_; |
1983 static bool softwareRendering_ = false; | 2016 static bool softwareRendering_ = false; |
1984 | 2017 static OrthancStone::MouseAction leftButtonAction_ = OrthancStone::MouseAction_GrayscaleWindowing; |
2018 static OrthancStone::MouseAction middleButtonAction_ = OrthancStone::MouseAction_Pan; | |
2019 static OrthancStone::MouseAction rightButtonAction_ = OrthancStone::MouseAction_Zoom; | |
1985 | 2020 |
1986 | 2021 |
1987 static void FormatTags(std::string& target, | 2022 static void FormatTags(std::string& target, |
1988 const Orthanc::DicomMap& tags) | 2023 const Orthanc::DicomMap& tags) |
1989 { | 2024 { |
2025 if (found == allViewports_.end()) | 2060 if (found == allViewports_.end()) |
2026 { | 2061 { |
2027 std::unique_ptr<OrthancStone::ILoadersContext::ILock> lock(context_->Lock()); | 2062 std::unique_ptr<OrthancStone::ILoadersContext::ILock> lock(context_->Lock()); |
2028 boost::shared_ptr<ViewerViewport> viewport( | 2063 boost::shared_ptr<ViewerViewport> viewport( |
2029 ViewerViewport::Create(*lock, source_, canvas, cache_, softwareRendering_)); | 2064 ViewerViewport::Create(*lock, source_, canvas, cache_, softwareRendering_)); |
2065 viewport->SetMouseButtonActions(leftButtonAction_, middleButtonAction_, rightButtonAction_); | |
2030 viewport->AcquireObserver(new WebAssemblyObserver); | 2066 viewport->AcquireObserver(new WebAssemblyObserver); |
2031 allViewports_[canvas] = viewport; | 2067 allViewports_[canvas] = viewport; |
2032 return viewport; | 2068 return viewport; |
2033 } | 2069 } |
2034 else | 2070 else |
2035 { | 2071 { |
2036 return found->second; | 2072 return found->second; |
2037 } | 2073 } |
2038 } | 2074 } |
2075 | |
2076 | |
2077 | |
2078 static OrthancStone::MouseAction ConvertMouseAction(int action) | |
2079 { | |
2080 switch (action) | |
2081 { | |
2082 case MouseAction_GrayscaleWindowing: | |
2083 return OrthancStone::MouseAction_GrayscaleWindowing; | |
2084 | |
2085 case MouseAction_Zoom: | |
2086 return OrthancStone::MouseAction_Zoom; | |
2087 | |
2088 case MouseAction_Pan: | |
2089 return OrthancStone::MouseAction_Pan; | |
2090 | |
2091 case MouseAction_Rotate: | |
2092 return OrthancStone::MouseAction_Rotate; | |
2093 | |
2094 default: | |
2095 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
2096 } | |
2097 } | |
2098 | |
2039 | 2099 |
2040 | 2100 |
2041 extern "C" | 2101 extern "C" |
2042 { | 2102 { |
2043 int main(int argc, char const *argv[]) | 2103 int main(int argc, char const *argv[]) |
2375 EMSCRIPTEN_KEEPALIVE | 2435 EMSCRIPTEN_KEEPALIVE |
2376 int IsSoftwareRendering() | 2436 int IsSoftwareRendering() |
2377 { | 2437 { |
2378 return softwareRendering_; | 2438 return softwareRendering_; |
2379 } | 2439 } |
2440 | |
2441 | |
2442 EMSCRIPTEN_KEEPALIVE | |
2443 void SetMouseButtonActions(int leftAction, | |
2444 int middleAction, | |
2445 int rightAction) | |
2446 { | |
2447 try | |
2448 { | |
2449 leftButtonAction_ = ConvertMouseAction(leftAction); | |
2450 middleButtonAction_ = ConvertMouseAction(middleAction); | |
2451 rightButtonAction_ = ConvertMouseAction(rightAction); | |
2452 | |
2453 for (Viewports::iterator it = allViewports_.begin(); it != allViewports_.end(); ++it) | |
2454 { | |
2455 assert(it->second != NULL); | |
2456 it->second->SetMouseButtonActions(leftButtonAction_, middleButtonAction_, rightButtonAction_); | |
2457 } | |
2458 } | |
2459 EXTERN_CATCH_EXCEPTIONS; | |
2460 } | |
2380 } | 2461 } |