changeset 2333:01300fbbfad5 refactoring

cont
author Sebastien Jodogne <s.jodogne@gmail.com>
date Sat, 03 Oct 2026 11:22:32 +0200
parents d63042924e59
children ba5cde199312
files Applications/Samples/Common/ISingleViewportApplicationCore.h Applications/Samples/Common/SimpleViewerCore.cpp Applications/Samples/Common/SimpleViewerCore.h Applications/Samples/Sdl/SingleViewportSdlApplication.cpp
diffstat 4 files changed, 116 insertions(+), 97 deletions(-) [+]
line wrap: on
line diff
--- a/Applications/Samples/Common/ISingleViewportApplicationCore.h	Sat Oct 03 10:25:42 2026 +0200
+++ b/Applications/Samples/Common/ISingleViewportApplicationCore.h	Sat Oct 03 11:22:32 2026 +0200
@@ -24,7 +24,7 @@
 
 #include "../../../OrthancStone/Sources/StoneApplication.h"
 #include "../../../OrthancStone/Sources/Viewport/IViewport.h"
-#include "../../../OrthancStone/Sources/Scene2D/PointerEvent.h"
+#include "../../../OrthancStone/Sources/Viewport/IViewportInteractor.h"
 
 
 namespace OrthancStone
@@ -39,17 +39,11 @@
     virtual void CreateComponents(const boost::shared_ptr<StoneApplication::Context>& context,
                                   const boost::shared_ptr<IViewport>& viewport) = 0;
 
+    virtual IViewportInteractor* CreateMouseInteractor() = 0;
+
     virtual bool HandleKeyDown(const IEnvironment::ILock& environmentLock,
                                char key) = 0;
 
-    virtual void HandleMouseDown(const IEnvironment::ILock& environmentLock,
-                                 IViewport::ILock& viewportLock,
-                                 const PointerEvent& p) = 0;
-
-    virtual bool HandleMouseMove(const IEnvironment::ILock& environmentLock,
-                                 IViewport::ILock& viewportLock,
-                                 const PointerEvent& p) = 0;
-
     virtual void Render(const IEnvironment::ILock& environmentLock,
                         IViewport::ILock& viewportLock) = 0;
   };
--- a/Applications/Samples/Common/SimpleViewerCore.cpp	Sat Oct 03 10:25:42 2026 +0200
+++ b/Applications/Samples/Common/SimpleViewerCore.cpp	Sat Oct 03 11:22:32 2026 +0200
@@ -23,6 +23,7 @@
 #include "SimpleViewerCore.h"
 
 #include "../../../OrthancStone/Sources/Scene2DViewport/UndoStack.h"
+#include "../../../OrthancStone/Sources/Viewport/DefaultViewportInteractor.h"
 
 #include <boost/make_shared.hpp>
 
@@ -73,11 +74,12 @@
       // std::cout << message.GetResources()->GetSourceJson(0).toStyledString();
 
       LOG(INFO) << "Using millimeters units, as the DICOM instance contains the PixelSpacing tag";
-      units_ = Units_Millimeters;
+      annotations_->SetUnits(Units_Millimeters);
     }
     else
     {
       LOG(INFO) << "Using pixels units, as the DICOM instance does *not* contain the PixelSpacing tag";
+      annotations_->SetUnits(Units_Pixels);
     }
 
     //message.GetResources()->GetResource(0).Print(stdout);
@@ -110,6 +112,13 @@
   void SimpleViewerCore::CreateComponents(const boost::shared_ptr<StoneApplication::Context>& context,
                                           const boost::shared_ptr<IViewport>& viewport)
   {
+    if (context_ ||
+        viewport_ ||
+        annotations_)
+    {
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
+    }
+
     context_ = context;
     viewport_ = viewport;
 
@@ -120,10 +129,10 @@
     //dicomLoader_->TypedObservable<DicomResourcesLoadedMessage>::Register(shared_from_this());
     New::IObservable::Bind<DicomResourcesLoadedMessage>(dicomLoader_, shared_from_this());
 
-    annotations_.SetActiveTool(AnnotationsSceneLayer::Tool_Edit);
-    annotations_.SetProbedLayer(0);
-
-    interactor_.SetWindowingLayer(0);
+    annotations_.reset(new AnnotationsSceneLayer(10));
+    annotations_->SetUnits(Units_Millimeters);
+    annotations_->SetActiveTool(AnnotationsSceneLayer::Tool_Edit);
+    annotations_->SetProbedLayer(0);
 
     {
       std::unique_ptr<IViewport::ILock> viewportLock(viewport->Lock());
@@ -132,6 +141,67 @@
   }
 
 
+  class SimpleViewerCore::Interactor : public IViewportInteractor
+  {
+  private:
+    DefaultViewportInteractor                 default_;
+    boost::shared_ptr<AnnotationsSceneLayer>  annotations_;
+
+  public:
+    Interactor(const boost::shared_ptr<AnnotationsSceneLayer>& annotations) :
+      annotations_(annotations)
+    {
+      default_.SetWindowingLayer(0);
+    }
+
+    virtual IFlexiblePointerTracker* CreateTracker(boost::weak_ptr<IViewport> viewport,
+                                                   const PointerEvent& event,
+                                                   unsigned int viewportWidth,
+                                                   unsigned int viewportHeight) ORTHANC_OVERRIDE
+    {
+      annotations_->ClearHover();
+
+      if (event.GetMouseButton() == MouseButton_Left)
+      {
+        boost::shared_ptr<IViewport> lock(viewport);
+        if (lock)
+        {
+          std::unique_ptr<IViewport::ILock> viewportLock(lock->Lock());
+          return annotations_->CreateTracker(event.GetMainPosition(), viewportLock->GetController().GetScene());
+        }
+      }
+
+      return default_.CreateTracker(viewport, event, viewportWidth, viewportHeight);
+    }
+
+    virtual bool HasMouseHover() const ORTHANC_OVERRIDE
+    {
+      return true;
+    }
+
+    virtual void HandleMouseHover(IViewport& viewport,
+                                  const PointerEvent& event) ORTHANC_OVERRIDE
+    {
+      std::unique_ptr<IViewport::ILock> viewportLock(viewport.Lock());
+      annotations_->SetMouseHover(event.GetMainPosition(), viewportLock->GetController().GetScene());
+      viewportLock->Invalidate();
+    }
+  };
+
+
+  IViewportInteractor* SimpleViewerCore::CreateMouseInteractor()
+  {
+    if (annotations_.get() == NULL)
+    {
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
+    }
+    else
+    {
+      return new Interactor(annotations_);
+    }
+  }
+
+
   bool SimpleViewerCore::HandleKeyDown(const IEnvironment::ILock& environmentLock,
                                        char key)
   {
@@ -166,35 +236,35 @@
     }
 
     case 'c':
-      annotations_.SetActiveTool(AnnotationsSceneLayer::Tool_Circle);
+      annotations_->SetActiveTool(AnnotationsSceneLayer::Tool_Circle);
       break;
 
     case 'm':
-      annotations_.SetActiveTool(AnnotationsSceneLayer::Tool_Edit);
+      annotations_->SetActiveTool(AnnotationsSceneLayer::Tool_Edit);
       break;
 
     case 'd':
-      annotations_.SetActiveTool(AnnotationsSceneLayer::Tool_Remove);
+      annotations_->SetActiveTool(AnnotationsSceneLayer::Tool_Remove);
       break;
 
     case 'l':
-      annotations_.SetActiveTool(AnnotationsSceneLayer::Tool_Length);
+      annotations_->SetActiveTool(AnnotationsSceneLayer::Tool_Length);
       break;
 
     case 'a':
-      annotations_.SetActiveTool(AnnotationsSceneLayer::Tool_Angle);
+      annotations_->SetActiveTool(AnnotationsSceneLayer::Tool_Angle);
       break;
 
     case 'p':
-      annotations_.SetActiveTool(AnnotationsSceneLayer::Tool_PixelProbe);
+      annotations_->SetActiveTool(AnnotationsSceneLayer::Tool_PixelProbe);
       break;
 
     case 'e':
-      annotations_.SetActiveTool(AnnotationsSceneLayer::Tool_EllipseProbe);
+      annotations_->SetActiveTool(AnnotationsSceneLayer::Tool_EllipseProbe);
       break;
 
     case 'r':
-      annotations_.SetActiveTool(AnnotationsSceneLayer::Tool_RectangleProbe);
+      annotations_->SetActiveTool(AnnotationsSceneLayer::Tool_RectangleProbe);
       break;
 
     default:
@@ -205,69 +275,17 @@
   }
 
 
-  void SimpleViewerCore::HandleMouseDown(const IEnvironment::ILock& environmentLock,
-                                         IViewport::ILock& viewportLock,
-                                         const PointerEvent& p)
+  void SimpleViewerCore::Render(const IEnvironment::ILock& environmentLock,
+                                IViewport::ILock& viewportLock)
   {
-    annotations_.SetUnits(units_);
-
-    boost::shared_ptr<IFlexiblePointerTracker> t;
-
-    if (p.GetMouseButton() == MouseButton_Left)
+    if (!annotations_)
     {
-      t.reset(annotations_.CreateTracker(p.GetMainPosition(), viewportLock.GetController().GetScene()));
-    }
-
-    if (t.get() != NULL)
-    {
-      viewportLock.GetController().AcquireActiveTracker(t);
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
     }
     else
     {
-      viewportLock.GetController().HandleMousePress(interactor_, p,
-                                                    viewportLock.GetCompositor().GetCanvasWidth(),
-                                                    viewportLock.GetCompositor().GetCanvasHeight());
-    }
-
-    viewportLock.Invalidate();
-  }
-
-
-  bool SimpleViewerCore::HandleMouseMove(const IEnvironment::ILock& environmentLock,
-                                         IViewport::ILock& viewportLock,
-                                         const PointerEvent& p)
-  {
-    if (viewportLock.GetController().HandleMouseMove(p))
-    {
-      viewportLock.Invalidate();
-      if (annotations_.ClearHover())
-      {
-        return true;
-      }
+      annotations_->Render(viewportLock.GetController().GetScene());
     }
-    else
-    {
-      if (annotations_.SetMouseHover(p.GetMainPosition(), viewportLock.GetController().GetScene()))
-      {
-        return true;
-      }
-    }
-
-    return false;
-  }
-
-
-  void SimpleViewerCore::Render(const IEnvironment::ILock& environmentLock,
-                                IViewport::ILock& viewportLock)
-  {
-    annotations_.Render(viewportLock.GetController().GetScene());
-  }
-
-
-  SimpleViewerCore::SimpleViewerCore() :
-    annotations_(10),
-    units_(Units_Pixels)
-  {
   }
 
 
--- a/Applications/Samples/Common/SimpleViewerCore.h	Sat Oct 03 10:25:42 2026 +0200
+++ b/Applications/Samples/Common/SimpleViewerCore.h	Sat Oct 03 11:22:32 2026 +0200
@@ -26,7 +26,6 @@
 #include "../../../OrthancStone/Sources/Loaders/SeriesFramesLoader.h"
 #include "../../../OrthancStone/Sources/Scene2D/AnnotationsSceneLayer.h"
 #include "../../../OrthancStone/Sources/Scene2DViewport/ViewportController.h"
-#include "../../../OrthancStone/Sources/Viewport/DefaultViewportInteractor.h"
 #include "ISingleViewportApplicationCore.h"
 
 
@@ -43,11 +42,11 @@
     boost::shared_ptr<IViewport>                  viewport_;
 
   private:
-    AnnotationsSceneLayer                         annotations_;
-    DefaultViewportInteractor                     interactor_;
+    class Interactor;
+
+    boost::shared_ptr<AnnotationsSceneLayer>      annotations_;
     boost::shared_ptr<DicomResourcesLoader>       dicomLoader_;
     boost::shared_ptr<SeriesFramesLoader>         framesLoader_;
-    Units                                         units_;
 
   public:
     virtual void Handle(const New::IObservable& observable,
@@ -60,23 +59,15 @@
     virtual void CreateComponents(const boost::shared_ptr<StoneApplication::Context>& context,
                                   const boost::shared_ptr<IViewport>& viewport) ORTHANC_OVERRIDE;
 
+    virtual IViewportInteractor* CreateMouseInteractor() ORTHANC_OVERRIDE;
+
     virtual bool HandleKeyDown(const IEnvironment::ILock& environmentLock,
                                char key) ORTHANC_OVERRIDE;
 
-    virtual void HandleMouseDown(const IEnvironment::ILock& environmentLock,
-                                 IViewport::ILock& viewportLock,
-                                 const PointerEvent& p) ORTHANC_OVERRIDE;
-
-    virtual bool HandleMouseMove(const IEnvironment::ILock& environmentLock,
-                                 IViewport::ILock& viewportLock,
-                                 const PointerEvent& p) ORTHANC_OVERRIDE;
-
     virtual void Render(const IEnvironment::ILock& environmentLock,
                         IViewport::ILock& viewportLock) ORTHANC_OVERRIDE;
 
   public:
-    SimpleViewerCore();
-
     void LoadFrameFromOrthanc(const std::string& instanceId,
                               unsigned int frameIndex);
 
--- a/Applications/Samples/Sdl/SingleViewportSdlApplication.cpp	Sat Oct 03 10:25:42 2026 +0200
+++ b/Applications/Samples/Sdl/SingleViewportSdlApplication.cpp	Sat Oct 03 11:22:32 2026 +0200
@@ -37,6 +37,12 @@
     assert(core_.get() != NULL);
     core_->CreateComponents(context, viewport_);
 
+    std::unique_ptr<IViewportInteractor> interactor(core_->CreateMouseInteractor());
+    if (interactor.get() == NULL)
+    {
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
+    }
+
     if (startup_.get() != NULL)
     {
       startup_->Start(*core_);
@@ -113,15 +119,25 @@
             {
             case SDL_MOUSEBUTTONDOWN:
             {
-              std::unique_ptr<IEnvironment::ILock> environmentLock(context->GetEnvironment().AcquireLock());
-              core_->HandleMouseDown(*environmentLock, *viewportLock, p);
+              viewportLock->GetController().HandleMousePress(*interactor, p, viewportLock->GetCompositor().GetCanvasWidth(),
+                                                             viewportLock->GetCompositor().GetCanvasHeight());
+              viewportLock->Invalidate();
               break;
             }
 
             case SDL_MOUSEMOTION:
             {
-              std::unique_ptr<IEnvironment::ILock> environmentLock(context->GetEnvironment().AcquireLock());
-              paint = core_->HandleMouseMove(*environmentLock, *viewportLock, p);
+              if (viewportLock->GetController().HasActiveTracker())
+              {
+                if (viewportLock->GetController().HandleMouseMove(p))
+                {
+                  viewportLock->Invalidate();
+                }
+              }
+              else if (interactor->HasMouseHover())
+              {
+                interactor->HandleMouseHover(*viewport_, p);
+              }
               break;
             }