diff Samples/WebAssembly/BasicMPR.cpp @ 826:2de01660debe

reorganization
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 29 May 2019 16:48:56 +0200
parents 9a6c7a5dcb76
children d71cf8504159
line wrap: on
line diff
--- a/Samples/WebAssembly/BasicMPR.cpp	Wed May 29 15:45:15 2019 +0200
+++ b/Samples/WebAssembly/BasicMPR.cpp	Wed May 29 16:48:56 2019 +0200
@@ -20,273 +20,21 @@
 
 
 
+#include "dev.h"
+
 #include <emscripten.h>
-#include <emscripten/fetch.h>
-#include <emscripten/html5.h>
 
 #include "../../Framework/Loaders/OrthancSeriesVolumeProgressiveLoader.h"
-#include "../../Framework/OpenGL/WebAssemblyOpenGLContext.h"
 #include "../../Framework/Oracle/SleepOracleCommand.h"
 #include "../../Framework/Oracle/WebAssemblyOracle.h"
 #include "../../Framework/Scene2D/GrayscaleStyleConfigurator.h"
-#include "../../Framework/Scene2D/OpenGLCompositor.h"
-#include "../../Framework/Scene2D/PanSceneTracker.h"
-#include "../../Framework/Scene2D/RotateSceneTracker.h"
-#include "../../Framework/Scene2D/ZoomSceneTracker.h"
-#include "../../Framework/Scene2DViewport/IFlexiblePointerTracker.h"
-#include "../../Framework/Scene2DViewport/ViewportController.h"
 #include "../../Framework/StoneInitialization.h"
 #include "../../Framework/Volumes/VolumeSceneLayerSource.h"
 
-#include <Core/OrthancException.h>
-#include <Core/Toolbox.h>
-
-
-static const unsigned int FONT_SIZE = 32;
-
 
 namespace OrthancStone
 {
-  class WebAssemblyViewport : public boost::noncopyable
-  {
-  private:
-    // the construction order is important because compositor_
-    // will hold a reference to the scene that belong to the 
-    // controller_ object
-    OpenGL::WebAssemblyOpenGLContext       context_;
-    boost::shared_ptr<ViewportController>  controller_;
-    OpenGLCompositor                       compositor_;
-
-    void SetupEvents(const std::string& canvas);
-
-  public:
-    WebAssemblyViewport(MessageBroker& broker,
-                        const std::string& canvas) :
-      context_(canvas),
-      controller_(new ViewportController(broker)),
-      compositor_(context_, *controller_->GetScene())
-    {
-      compositor_.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, 
-                          FONT_SIZE, Orthanc::Encoding_Latin1);
-      SetupEvents(canvas);
-    }
-
-    Scene2D& GetScene()
-    {
-      return *controller_->GetScene();
-    }
-
-    const boost::shared_ptr<ViewportController>& GetController()
-    {
-      return controller_;
-    }
-
-    void UpdateSize()
-    {
-      context_.UpdateSize();
-      compositor_.UpdateSize();
-      Refresh();
-    }
-
-    void Refresh()
-    {
-      compositor_.Refresh();
-    }
-
-    void FitContent()
-    {
-      GetScene().FitContent(context_.GetCanvasWidth(), context_.GetCanvasHeight());
-    }
-
-    const std::string& GetCanvasIdentifier() const
-    {
-      return context_.GetCanvasIdentifier();
-    }
-
-    ScenePoint2D GetPixelCenterCoordinates(int x, int y) const
-    {
-      return compositor_.GetPixelCenterCoordinates(x, y);
-    }
-
-    unsigned int GetCanvasWidth() const
-    {
-      return context_.GetCanvasWidth();
-    }
-
-    unsigned int GetCanvasHeight() const
-    {
-      return context_.GetCanvasHeight();
-    }
-  };
-
-  class ActiveTracker : public boost::noncopyable
-  {
-  private:
-    boost::shared_ptr<IFlexiblePointerTracker> tracker_;
-    std::string                             canvasIdentifier_;
-    bool                                    insideCanvas_;
-    
-  public:
-    ActiveTracker(const boost::shared_ptr<IFlexiblePointerTracker>& tracker,
-                  const WebAssemblyViewport& viewport) :
-      tracker_(tracker),
-      canvasIdentifier_(viewport.GetCanvasIdentifier()),
-      insideCanvas_(true)
-    {
-      if (tracker_.get() == NULL)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
-      }
-    }
-
-    bool IsAlive() const
-    {
-      return tracker_->IsAlive();
-    }
-
-    void PointerMove(const PointerEvent& event)
-    {
-      tracker_->PointerMove(event);
-    }
-
-    void PointerUp(const PointerEvent& event)
-    {
-      tracker_->PointerUp(event);
-    }
-  };
-}
-
-static OrthancStone::PointerEvent* ConvertMouseEvent(
-  const EmscriptenMouseEvent&        source,
-  OrthancStone::WebAssemblyViewport& viewport)
-{
-  std::auto_ptr<OrthancStone::PointerEvent> target(
-    new OrthancStone::PointerEvent);
-
-  target->AddPosition(viewport.GetPixelCenterCoordinates(
-    source.targetX, source.targetY));
-  target->SetAltModifier(source.altKey);
-  target->SetControlModifier(source.ctrlKey);
-  target->SetShiftModifier(source.shiftKey);
-
-  return target.release();
-}
-
-std::auto_ptr<OrthancStone::ActiveTracker> tracker_;
-
-EM_BOOL OnMouseEvent(int eventType, 
-                     const EmscriptenMouseEvent *mouseEvent, 
-                     void *userData)
-{
-  if (mouseEvent != NULL &&
-      userData != NULL)
-  {
-    OrthancStone::WebAssemblyViewport& viewport = 
-      *reinterpret_cast<OrthancStone::WebAssemblyViewport*>(userData);
-
-    switch (eventType)
-    {
-      case EMSCRIPTEN_EVENT_CLICK:
-      {
-        static unsigned int count = 0;
-        char buf[64];
-        sprintf(buf, "click %d", count++);
-
-        std::auto_ptr<OrthancStone::TextSceneLayer> layer(new OrthancStone::TextSceneLayer);
-        layer->SetText(buf);
-        viewport.GetScene().SetLayer(100, layer.release());
-        viewport.Refresh();
-        break;
-      }
-
-      case EMSCRIPTEN_EVENT_MOUSEDOWN:
-      {
-        boost::shared_ptr<OrthancStone::IFlexiblePointerTracker> t;
-
-        {
-          std::auto_ptr<OrthancStone::PointerEvent> event(
-            ConvertMouseEvent(*mouseEvent, viewport));
-
-          switch (mouseEvent->button)
-          {
-            case 0:  // Left button
-              emscripten_console_log("Creating RotateSceneTracker");
-              t.reset(new OrthancStone::RotateSceneTracker(
-                viewport.GetController(), *event));
-              break;
-
-            case 1:  // Middle button
-              emscripten_console_log("Creating PanSceneTracker");
-              LOG(INFO) << "Creating PanSceneTracker" ;
-              t.reset(new OrthancStone::PanSceneTracker(
-                viewport.GetController(), *event));
-              break;
-
-            case 2:  // Right button
-              emscripten_console_log("Creating ZoomSceneTracker");
-              t.reset(new OrthancStone::ZoomSceneTracker(
-                viewport.GetController(), *event, viewport.GetCanvasWidth()));
-              break;
-
-            default:
-              break;
-          }
-        }
-
-        if (t.get() != NULL)
-        {
-          tracker_.reset(
-            new OrthancStone::ActiveTracker(t, viewport));
-          viewport.Refresh();
-        }
-
-        break;
-      }
-
-      case EMSCRIPTEN_EVENT_MOUSEMOVE:
-        if (tracker_.get() != NULL)
-        {
-          std::auto_ptr<OrthancStone::PointerEvent> event(
-            ConvertMouseEvent(*mouseEvent, viewport));
-          tracker_->PointerMove(*event);
-          viewport.Refresh();
-        }
-        break;
-
-      case EMSCRIPTEN_EVENT_MOUSEUP:
-        if (tracker_.get() != NULL)
-        {
-          std::auto_ptr<OrthancStone::PointerEvent> event(
-            ConvertMouseEvent(*mouseEvent, viewport));
-          tracker_->PointerUp(*event);
-          viewport.Refresh();
-          if (!tracker_->IsAlive())
-            tracker_.reset();
-        }
-        break;
-
-      default:
-        break;
-    }
-  }
-
-  return true;
-}
-
-
-void OrthancStone::WebAssemblyViewport::SetupEvents(const std::string& canvas)
-{
-  emscripten_set_mousedown_callback(canvas.c_str(), this, false, OnMouseEvent);
-  emscripten_set_mousemove_callback(canvas.c_str(), this, false, OnMouseEvent);
-  emscripten_set_mouseup_callback(canvas.c_str(), this, false, OnMouseEvent);
-}
-
-
-
-
-namespace OrthancStone
-{
-  class VolumeSlicerViewport : public IObserver
+  class VolumeSlicerWidget : public IObserver
   {
   private:
     OrthancStone::WebAssemblyViewport      viewport_;
@@ -317,7 +65,7 @@
     }
     
   public:
-    VolumeSlicerViewport(MessageBroker& broker,
+    VolumeSlicerWidget(MessageBroker& broker,
                          const std::string& canvas,
                          VolumeProjection projection) :
       IObserver(broker),
@@ -344,8 +92,8 @@
       }
       
       loader.RegisterObserverCallback(
-        new Callable<VolumeSlicerViewport, DicomVolumeImage::GeometryReadyMessage>
-        (*this, &VolumeSlicerViewport::Handle));
+        new Callable<VolumeSlicerWidget, DicomVolumeImage::GeometryReadyMessage>
+        (*this, &VolumeSlicerWidget::Handle));
 
       source_.reset(new VolumeSceneLayerSource(viewport_.GetScene(), layerDepth, slicer));
 
@@ -365,6 +113,11 @@
       }
     }
 
+    size_t GetSlicesCount() const
+    {
+      return planes_.size();
+    }
+
     void Scroll(int delta)
     {
       if (!planes_.empty())
@@ -402,9 +155,9 @@
 
 boost::shared_ptr<OrthancStone::OrthancSeriesVolumeProgressiveLoader>  loader_;
 
-std::auto_ptr<OrthancStone::VolumeSlicerViewport>  viewport1_;
-std::auto_ptr<OrthancStone::VolumeSlicerViewport>  viewport2_;
-std::auto_ptr<OrthancStone::VolumeSlicerViewport>  viewport3_;
+std::auto_ptr<OrthancStone::VolumeSlicerWidget>  widget1_;
+std::auto_ptr<OrthancStone::VolumeSlicerWidget>  widget2_;
+std::auto_ptr<OrthancStone::VolumeSlicerWidget>  widget3_;
 
 OrthancStone::MessageBroker  broker_;
 OrthancStone::WebAssemblyOracle  oracle_(broker_);
@@ -414,19 +167,19 @@
 {
   try
   {
-    if (viewport1_.get() != NULL)
+    if (widget1_.get() != NULL)
     {
-      viewport1_->UpdateSize();
+      widget1_->UpdateSize();
     }
   
-    if (viewport2_.get() != NULL)
+    if (widget2_.get() != NULL)
     {
-      viewport2_->UpdateSize();
+      widget2_->UpdateSize();
     }
   
-    if (viewport3_.get() != NULL)
+    if (widget3_.get() != NULL)
     {
-      viewport3_->UpdateSize();
+      widget3_->UpdateSize();
     }
   }
   catch (Orthanc::OrthancException& e)
@@ -444,19 +197,19 @@
 {
   try
   {
-    if (viewport1_.get() != NULL)
+    if (widget1_.get() != NULL)
     {
-      viewport1_->Refresh();
+      widget1_->Refresh();
     }
   
-    if (viewport2_.get() != NULL)
+    if (widget2_.get() != NULL)
     {
-      viewport2_->Refresh();
+      widget2_->Refresh();
     }
   
-    if (viewport3_.get() != NULL)
+    if (widget3_.get() != NULL)
     {
-      viewport3_->Refresh();
+      widget3_->Refresh();
     }
 
     return true;
@@ -492,12 +245,15 @@
         delta = 1;
       }
 
+      OrthancStone::VolumeSlicerWidget& widget =
+        *reinterpret_cast<OrthancStone::VolumeSlicerWidget*>(userData);
+      
       if (ctrlDown_)
       {
-        delta *= 10;
+        delta *= static_cast<int>(widget.GetSlicesCount() / 10);
       }
-           
-      reinterpret_cast<OrthancStone::VolumeSlicerViewport*>(userData)->Scroll(delta);
+
+      widget.Scroll(delta);
     }
   }
   catch (Orthanc::OrthancException& e)
@@ -509,15 +265,24 @@
 }
 
 
-EM_BOOL OnKey(int eventType,
-              const EmscriptenKeyboardEvent *keyEvent,
-              void *userData)
+EM_BOOL OnKeyDown(int eventType,
+                  const EmscriptenKeyboardEvent *keyEvent,
+                  void *userData)
 {
   ctrlDown_ = keyEvent->ctrlKey;
   return false;
 }
 
 
+EM_BOOL OnKeyUp(int eventType,
+                const EmscriptenKeyboardEvent *keyEvent,
+                void *userData)
+{
+  ctrlDown_ = false;
+  return false;
+}
+
+
 
 
 namespace OrthancStone
@@ -574,26 +339,26 @@
     {
       loader_.reset(new OrthancStone::OrthancSeriesVolumeProgressiveLoader(ct_, oracle_, oracle_));
     
-      viewport1_.reset(new OrthancStone::VolumeSlicerViewport(broker_, "mycanvas1", OrthancStone::VolumeProjection_Axial));
-      viewport1_->SetSlicer(0, loader_, *loader_, new OrthancStone::GrayscaleStyleConfigurator);
-      viewport1_->UpdateSize();
+      widget1_.reset(new OrthancStone::VolumeSlicerWidget(broker_, "mycanvas1", OrthancStone::VolumeProjection_Axial));
+      widget1_->SetSlicer(0, loader_, *loader_, new OrthancStone::GrayscaleStyleConfigurator);
+      widget1_->UpdateSize();
 
-      viewport2_.reset(new OrthancStone::VolumeSlicerViewport(broker_, "mycanvas2", OrthancStone::VolumeProjection_Coronal));
-      viewport2_->SetSlicer(0, loader_, *loader_, new OrthancStone::GrayscaleStyleConfigurator);
-      viewport2_->UpdateSize();
+      widget2_.reset(new OrthancStone::VolumeSlicerWidget(broker_, "mycanvas2", OrthancStone::VolumeProjection_Coronal));
+      widget2_->SetSlicer(0, loader_, *loader_, new OrthancStone::GrayscaleStyleConfigurator);
+      widget2_->UpdateSize();
 
-      viewport3_.reset(new OrthancStone::VolumeSlicerViewport(broker_, "mycanvas3", OrthancStone::VolumeProjection_Sagittal));
-      viewport3_->SetSlicer(0, loader_, *loader_, new OrthancStone::GrayscaleStyleConfigurator);
-      viewport3_->UpdateSize();
+      widget3_.reset(new OrthancStone::VolumeSlicerWidget(broker_, "mycanvas3", OrthancStone::VolumeProjection_Sagittal));
+      widget3_->SetSlicer(0, loader_, *loader_, new OrthancStone::GrayscaleStyleConfigurator);
+      widget3_->UpdateSize();
 
       emscripten_set_resize_callback("#window", NULL, false, OnWindowResize);
 
-      emscripten_set_wheel_callback("mycanvas1", viewport1_.get(), false, OnMouseWheel);
-      emscripten_set_wheel_callback("mycanvas2", viewport2_.get(), false, OnMouseWheel);
-      emscripten_set_wheel_callback("mycanvas3", viewport3_.get(), false, OnMouseWheel);
+      emscripten_set_wheel_callback("mycanvas1", widget1_.get(), false, OnMouseWheel);
+      emscripten_set_wheel_callback("mycanvas2", widget2_.get(), false, OnMouseWheel);
+      emscripten_set_wheel_callback("mycanvas3", widget3_.get(), false, OnMouseWheel);
 
-      emscripten_set_keydown_callback("#window", NULL, false, OnKey);
-      emscripten_set_keyup_callback("#window", NULL, false, OnKey);
+      emscripten_set_keydown_callback("#window", NULL, false, OnKeyDown);
+      emscripten_set_keyup_callback("#window", NULL, false, OnKeyUp);
     
       emscripten_request_animation_frame_loop(OnAnimationFrame, NULL);