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 }