Mercurial > hg > orthanc-stone
changeset 1693:eafb10992e73
synchronized browsing
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 26 Nov 2020 13:46:50 +0100 |
parents | e787b52d025f |
children | 7226b68e2742 |
files | Applications/StoneWebViewer/WebApplication/app.js Applications/StoneWebViewer/WebApplication/index.html Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp |
diffstat | 3 files changed, 88 insertions(+), 36 deletions(-) [+] |
line wrap: on
line diff
--- a/Applications/StoneWebViewer/WebApplication/app.js Wed Nov 25 18:11:42 2020 +0100 +++ b/Applications/StoneWebViewer/WebApplication/app.js Thu Nov 26 13:46:50 2020 +0100 @@ -260,6 +260,7 @@ activeViewport: 0, showInfo: true, showReferenceLines: true, + synchronizedBrowsing: false, modalWarning: false, modalNotDiagnostic: false, @@ -333,6 +334,9 @@ showReferenceLines: function(newVal, oldVal) { stone.ShowReferenceLines(newVal ? 1 : 0); }, + synchronizedBrowsing: function(newVal, oldVal) { + stone.SetSynchronizedBrowsingEnabled(newVal ? 1 : 0); + }, settingNotDiagnostic: function(newVal, oldVal) { localStorage.settingNotDiagnostic = (newVal ? '1' : '0'); },
--- a/Applications/StoneWebViewer/WebApplication/index.html Wed Nov 25 18:11:42 2020 +0100 +++ b/Applications/StoneWebViewer/WebApplication/index.html Thu Nov 26 13:46:50 2020 +0100 @@ -446,10 +446,10 @@ <div class="ng-scope inline-object"> <button class="wvButton--underline text-center" - data-toggle="tooltip" data-title="Show image information" - v-bind:class="{ 'active' : showInfo }" - v-on:click="showInfo = !showInfo"> - <i class="fa fa-info-circle"></i> + data-toggle="tooltip" data-title="Synchronized browsing" + v-bind:class="{ 'active' : synchronizedBrowsing }" + v-on:click="synchronizedBrowsing = !synchronizedBrowsing"> + <i class="fa fa-link"></i> </button> </div> @@ -464,6 +464,15 @@ <div class="ng-scope inline-object"> <button class="wvButton--underline text-center" + data-toggle="tooltip" data-title="Show image information" + v-bind:class="{ 'active' : showInfo }" + v-on:click="showInfo = !showInfo"> + <i class="fa fa-info-circle"></i> + </button> + </div> + + <div class="ng-scope inline-object"> + <button class="wvButton--underline text-center" data-toggle="tooltip" data-title="User preferences" v-on:click="modalPreferences = true"> <i class="fa fa-user"></i>
--- a/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Wed Nov 25 18:11:42 2020 +0100 +++ b/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Thu Nov 26 13:46:50 2020 +0100 @@ -1033,7 +1033,8 @@ size_t countFrames, DisplayedFrameQuality quality) = 0; - virtual void SignalCrosshair(const OrthancStone::Vector& click) = 0; + virtual void SignalCrosshair(const ViewerViewport& viewport, + const OrthancStone::Vector& click) = 0; }; private: @@ -1397,9 +1398,10 @@ bool flipX_; bool flipY_; bool fitNextContent_; - bool isCtrlDown_; std::list<PrefetchItem> prefetchQueue_; bool serverSideTranscoding_; + OrthancStone::Vector synchronizationOffset_; + bool synchronizationEnabled_; bool hasFocusOnInstance_; @@ -1782,11 +1784,12 @@ source_(source), framesCache_(cache), fitNextContent_(true), - isCtrlDown_(false), flipX_(false), flipY_(false), hasFocusOnInstance_(false), - focusFrameNumber_(0) + focusFrameNumber_(0), + synchronizationOffset_(OrthancStone::LinearAlgebra::CreateVector(0, 0, 0)), + synchronizationEnabled_(false) { if (!framesCache_) { @@ -1812,26 +1815,10 @@ } emscripten_set_wheel_callback(viewport_->GetCanvasCssSelector().c_str(), this, true, OnWheel); - emscripten_set_keydown_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, this, false, OnKey); - emscripten_set_keyup_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, this, false, OnKey); SetWindowingPreset(); } - static EM_BOOL OnKey(int eventType, - const EmscriptenKeyboardEvent *event, - void *userData) - { - /** - * WARNING: There is a problem with Firefox 71 that seems to mess - * the "ctrlKey" value. - **/ - - ViewerViewport& that = *reinterpret_cast<ViewerViewport*>(userData); - that.isCtrlDown_ = event->ctrlKey; - return false; - } - static EM_BOOL OnWheel(int eventType, const EmscriptenWheelEvent *wheelEvent, @@ -1839,15 +1826,41 @@ { ViewerViewport& that = *reinterpret_cast<ViewerViewport*>(userData); - if (that.cursor_.get() != NULL) + if (that.frames_.get() != NULL && + that.cursor_.get() != NULL) { + const bool isCtrl = wheelEvent->mouse.ctrlKey; + const bool isShift = wheelEvent->mouse.shiftKey; + + const size_t previousCursorIndex = that.cursor_->GetCurrentIndex(); + if (wheelEvent->deltaY < 0) { - that.ChangeFrame(that.isCtrlDown_ ? SeriesCursor::Action_FastMinus : SeriesCursor::Action_Minus, false /* not circular */); + that.ChangeFrame(isCtrl ? SeriesCursor::Action_FastMinus : + SeriesCursor::Action_Minus, false /* not circular */); } else if (wheelEvent->deltaY > 0) { - that.ChangeFrame(that.isCtrlDown_ ? SeriesCursor::Action_FastPlus : SeriesCursor::Action_Plus, false /* not circular */); + that.ChangeFrame(isCtrl ? SeriesCursor::Action_FastPlus : + SeriesCursor::Action_Plus, false /* not circular */); + } + + if (that.synchronizationEnabled_) + { + const size_t currentCursorIndex = that.cursor_->GetCurrentIndex(); + + const OrthancStone::CoordinateSystem3D current = + that.frames_->GetFrameGeometry(currentCursorIndex); + + if (isShift && + previousCursorIndex != currentCursorIndex) + { + const OrthancStone::CoordinateSystem3D previous = + that.frames_->GetFrameGeometry(previousCursorIndex); + that.synchronizationOffset_ += previous.GetOrigin() - current.GetOrigin(); + } + + that.observer_->SignalCrosshair(that, current.GetOrigin() + that.synchronizationOffset_); } } @@ -1876,8 +1889,6 @@ // has been destroyed. "WebAssemblyViewport::CreateObjectCookie()" // provides a more advanced alternative. emscripten_set_wheel_callback(viewport_->GetCanvasCssSelector().c_str(), this, true, NULL); - emscripten_set_keydown_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, this, false, NULL); - emscripten_set_keyup_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, this, false, NULL); } static boost::shared_ptr<ViewerViewport> Create(OrthancStone::WebAssemblyLoadersContext& context, @@ -1919,6 +1930,7 @@ cineRate_ = DEFAULT_CINE_RATE; inverted_ = false; serverSideTranscoding_ = false; + OrthancStone::LinearAlgebra::AssignVector(synchronizationOffset_, 0, 0, 0); frames_.reset(frames); cursor_.reset(new SeriesCursor(frames_->GetFramesCount())); @@ -2281,7 +2293,7 @@ OrthancStone::Vector click = plane.MapSliceToWorldCoordinates(x, y); if (viewer_.observer_.get() != NULL) { - viewer_.observer_->SignalCrosshair(click); + viewer_.observer_->SignalCrosshair(viewer_, click); } } @@ -2384,14 +2396,22 @@ Json::Value preset = Json::objectValue; preset["name"] = name; - preset["info"] = ("C " + boost::lexical_cast<std::string>(boost::math::iround(c)) + - ", W " + boost::lexical_cast<std::string>(boost::math::iround(w))); preset["center"] = c; preset["width"] = w; - + preset["info"] = + ("C " + boost::lexical_cast<std::string>(static_cast<int>(boost::math::iround<double>(c))) + + ", W " + boost::lexical_cast<std::string>(static_cast<int>(boost::math::iround<double>(w)))); + target.append(preset); } } + + + void SetSynchronizedBrowsingEnabled(int enabled) + { + OrthancStone::LinearAlgebra::AssignVector(synchronizationOffset_, 0, 0, 0); + synchronizationEnabled_ = enabled; + } }; @@ -2510,12 +2530,16 @@ UpdateReferenceLines(); } - virtual void SignalCrosshair(const OrthancStone::Vector& click) ORTHANC_OVERRIDE + virtual void SignalCrosshair(const ViewerViewport& viewport, + const OrthancStone::Vector& click) ORTHANC_OVERRIDE { for (Viewports::const_iterator it = allViewports_.begin(); it != allViewports_.end(); ++it) { - assert(it->second != NULL); - it->second->FocusOnPoint(click); + assert(it->second.get() != NULL); + if (it->second.get() != &viewport) + { + it->second->FocusOnPoint(click); + } } } @@ -3084,4 +3108,19 @@ } EXTERN_CATCH_EXCEPTIONS; } + + + EMSCRIPTEN_KEEPALIVE + void SetSynchronizedBrowsingEnabled(int enabled) + { + try + { + for (Viewports::iterator it = allViewports_.begin(); it != allViewports_.end(); ++it) + { + assert(it->second != NULL); + it->second->SetSynchronizedBrowsingEnabled(enabled); + } + } + EXTERN_CATCH_EXCEPTIONS; + } }