changeset 332:50e5ec1bdd46 am-2

separating ZoomMouseTracker and PanMouseTracker from WorldSceneWidget
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 17 Oct 2018 19:38:39 +0200
parents 7ccf919faff0
children 08683537a227
files Framework/Layers/CircleMeasureTracker.cpp Framework/Layers/CircleMeasureTracker.h Framework/Layers/LineMeasureTracker.cpp Framework/Layers/LineMeasureTracker.h Framework/Toolbox/ViewportGeometry.cpp Framework/Toolbox/ViewportGeometry.h Framework/Widgets/IWorldSceneMouseTracker.h Framework/Widgets/PanMouseTracker.cpp Framework/Widgets/PanMouseTracker.h Framework/Widgets/WorldSceneWidget.cpp Framework/Widgets/WorldSceneWidget.h Framework/Widgets/ZoomMouseTracker.cpp Framework/Widgets/ZoomMouseTracker.h Resources/CMake/OrthancStoneConfiguration.cmake
diffstat 14 files changed, 375 insertions(+), 172 deletions(-) [+]
line wrap: on
line diff
--- a/Framework/Layers/CircleMeasureTracker.cpp	Wed Oct 17 15:18:48 2018 +0200
+++ b/Framework/Layers/CircleMeasureTracker.cpp	Wed Oct 17 19:38:39 2018 +0200
@@ -99,7 +99,9 @@
     return buf;
   }
 
-  void CircleMeasureTracker::MouseMove(double x,
+  void CircleMeasureTracker::MouseMove(int displayX,
+                                       int displayY,
+                                       double x,
                                        double y)
   {
     x2_ = x;
--- a/Framework/Layers/CircleMeasureTracker.h	Wed Oct 17 15:18:48 2018 +0200
+++ b/Framework/Layers/CircleMeasureTracker.h	Wed Oct 17 19:38:39 2018 +0200
@@ -50,6 +50,11 @@
                          uint8_t blue,
                          unsigned int fontSize);
     
+    virtual bool HasRender() const
+    {
+      return true;
+    }
+
     virtual void Render(CairoContext& context,
                         double zoom);
     
@@ -62,7 +67,9 @@
       // Possibly create a new landmark "volume" with the circle in subclasses
     }
 
-    virtual void MouseMove(double x,
+    virtual void MouseMove(int displayX,
+                           int displayY,
+                           double x,
                            double y);
   };
 }
--- a/Framework/Layers/LineMeasureTracker.cpp	Wed Oct 17 15:18:48 2018 +0200
+++ b/Framework/Layers/LineMeasureTracker.cpp	Wed Oct 17 19:38:39 2018 +0200
@@ -86,7 +86,9 @@
     return buf;
   }
 
-  void LineMeasureTracker::MouseMove(double x,
+  void LineMeasureTracker::MouseMove(int displayX,
+                                     int displayY,
+                                     double x,
                                      double y)
   {
     x2_ = x;
--- a/Framework/Layers/LineMeasureTracker.h	Wed Oct 17 15:18:48 2018 +0200
+++ b/Framework/Layers/LineMeasureTracker.h	Wed Oct 17 19:38:39 2018 +0200
@@ -49,7 +49,12 @@
                        uint8_t green,
                        uint8_t blue,
                        unsigned int fontSize);
-    
+
+    virtual bool HasRender() const
+    {
+      return true;
+    }
+
     virtual void Render(CairoContext& context,
                         double zoom);
     
@@ -62,7 +67,9 @@
       // Possibly create a new landmark "volume" with the line in subclasses
     }
 
-    virtual void MouseMove(double x,
+    virtual void MouseMove(int displayX,
+                           int displayY,
+                           double x,
                            double y);
   };
 }
--- a/Framework/Toolbox/ViewportGeometry.cpp	Wed Oct 17 15:18:48 2018 +0200
+++ b/Framework/Toolbox/ViewportGeometry.cpp	Wed Oct 17 19:38:39 2018 +0200
@@ -121,6 +121,18 @@
   }
 
 
+  void ViewportGeometry::MapPixelCenterToScene(double& sceneX,
+                                               double& sceneY,
+                                               int x,
+                                               int y) const
+  {
+    // Take the center of the pixel
+    MapDisplayToScene(sceneX, sceneY,
+                      static_cast<double>(x) + 0.5,
+                      static_cast<double>(y) + 0.5);
+  }
+
+
   void ViewportGeometry::FitContent()
   {
     if (width_ > 0 &&
--- a/Framework/Toolbox/ViewportGeometry.h	Wed Oct 17 15:18:48 2018 +0200
+++ b/Framework/Toolbox/ViewportGeometry.h	Wed Oct 17 19:38:39 2018 +0200
@@ -63,6 +63,11 @@
                            double x,
                            double y) const;
 
+    void MapPixelCenterToScene(double& sceneX /* out */,
+                               double& sceneY /* out */,
+                               int x,
+                               int y) const;
+
     void MapSceneToDisplay(int& displayX /* out */,
                            int& displayY /* out */,
                            double x,
--- a/Framework/Widgets/IWorldSceneMouseTracker.h	Wed Oct 17 15:18:48 2018 +0200
+++ b/Framework/Widgets/IWorldSceneMouseTracker.h	Wed Oct 17 19:38:39 2018 +0200
@@ -32,15 +32,20 @@
   class IWorldSceneMouseTracker : public boost::noncopyable
   {
   public:
-    virtual ~IWorldSceneMouseTracker() {
+    virtual ~IWorldSceneMouseTracker()
+    {
     }
 
+    virtual bool HasRender() const = 0;
+
     virtual void Render(CairoContext& context,
                         double zoom) = 0;
 
     virtual void MouseUp() = 0;
 
-    virtual void MouseMove(double x,
-                           double y) = 0;
+    virtual void MouseMove(int displayX,
+                           int displayY,
+                           double sceneX,
+                           double sceneY) = 0;
   };
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Framework/Widgets/PanMouseTracker.cpp	Wed Oct 17 19:38:39 2018 +0200
@@ -0,0 +1,55 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2018 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "PanMouseTracker.h"
+
+#include <Core/Logging.h>
+
+namespace OrthancStone
+{
+  PanMouseTracker::PanMouseTracker(WorldSceneWidget& that,
+                                   int x,
+                                   int y) :
+    that_(that)
+  {
+    that.GetView().GetPan(originalPanX_, originalPanY_);
+    that.GetView().MapPixelCenterToScene(downX_, downY_, x, y);
+  }
+    
+
+  void PanMouseTracker::Render(CairoContext& context,
+                               double zoom)
+  {
+    throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
+  }
+
+
+  void PanMouseTracker::MouseMove(int displayX,
+                                  int displayY,
+                                  double x,
+                                  double y)
+  {
+    ViewportGeometry view = that_.GetView();
+    view.SetPan(originalPanX_ + (x - downX_) * view.GetZoom(),
+                originalPanY_ + (y - downY_) * view.GetZoom());
+    that_.SetView(view);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Framework/Widgets/PanMouseTracker.h	Wed Oct 17 19:38:39 2018 +0200
@@ -0,0 +1,59 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2018 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include "WorldSceneWidget.h"
+
+namespace OrthancStone
+{
+  class PanMouseTracker : public IWorldSceneMouseTracker
+  {
+  private:
+    WorldSceneWidget&  that_;
+    double             originalPanX_;
+    double             originalPanY_;
+    double             downX_;
+    double             downY_;
+    
+  public:
+    PanMouseTracker(WorldSceneWidget& that,
+                    int x,
+                    int y);
+    
+    virtual bool HasRender() const
+    {
+      return false;
+    }
+
+    virtual void MouseUp()
+    {
+    }
+
+    virtual void Render(CairoContext& context,
+                        double zoom);
+
+    virtual void MouseMove(int displayX,
+                           int displayY,
+                           double x,
+                           double y);
+  };
+}
--- a/Framework/Widgets/WorldSceneWidget.cpp	Wed Oct 17 15:18:48 2018 +0200
+++ b/Framework/Widgets/WorldSceneWidget.cpp	Wed Oct 17 19:38:39 2018 +0200
@@ -21,28 +21,17 @@
 
 #include "WorldSceneWidget.h"
 
+#include "PanMouseTracker.h"
+#include "ZoomMouseTracker.h"
+
+#include <Core/Logging.h>
+
 #include <math.h>
 #include <memory>
 #include <cassert>
-#include "Core/Logging.h"
 
 namespace OrthancStone
 {
-  static void MapMouseToScene(double& sceneX,
-                              double& sceneY,
-                              const ViewportGeometry& view,
-                              int mouseX,
-                              int mouseY)
-  {
-    // Take the center of the pixel
-    double x, y;
-    x = static_cast<double>(mouseX) + 0.5;
-    y = static_cast<double>(mouseY) + 0.5;
-
-    view.MapDisplayToScene(sceneX, sceneY, x, y);
-  }
-
-
   // this is an adapter between a IWorldSceneMouseTracker
   // that is tracking a mouse in scene coordinates/mm and
   // an IMouseTracker that is tracking a mouse
@@ -50,7 +39,7 @@
   class WorldSceneWidget::SceneMouseTracker : public IMouseTracker
   {
   private:
-    ViewportGeometry                       view_;
+    ViewportGeometry                        view_;
     std::auto_ptr<IWorldSceneMouseTracker>  tracker_;
 
   public:
@@ -59,15 +48,21 @@
       view_(view),
       tracker_(tracker)
     {
-      assert(tracker != NULL);
+      if (tracker == NULL)
+      {
+        throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
+      }
     }
 
     virtual void Render(Orthanc::ImageAccessor& target)
     {
-      CairoSurface surface(target);
-      CairoContext context(surface);
-      view_.ApplyTransform(context);
-      tracker_->Render(context, view_.GetZoom());
+      if (tracker_->HasRender())
+      {
+        CairoSurface surface(target);
+        CairoContext context(surface);
+        view_.ApplyTransform(context);
+        tracker_->Render(context, view_.GetZoom());
+      }
     }
 
     virtual void MouseUp()
@@ -79,87 +74,12 @@
                            int y)
     {
       double sceneX, sceneY;
-      MapMouseToScene(sceneX, sceneY, view_, x, y);
-      tracker_->MouseMove(sceneX, sceneY);
+      view_.MapPixelCenterToScene(sceneX, sceneY, x, y);
+      tracker_->MouseMove(x, y, sceneX, sceneY);
     }
   };
 
 
-  WorldSceneWidget::PanMouseTracker::PanMouseTracker(WorldSceneWidget& that,
-                                                     int x,
-                                                     int y) :
-    that_(that),
-    downX_(x),
-    downY_(y)
-  {
-    that_.view_.GetPan(previousPanX_, previousPanY_);
-  }
-
-  
-  void WorldSceneWidget::PanMouseTracker::MouseMove(int x, int y)
-  {
-    that_.view_.SetPan(previousPanX_ + x - downX_,
-                       previousPanY_ + y - downY_);
-  }
-
-  
-  WorldSceneWidget::ZoomMouseTracker::ZoomMouseTracker(WorldSceneWidget&  that,
-                                                       int x,
-                                                       int y) :
-    that_(that),
-    downX_(x),
-    downY_(y)
-  {
-    oldZoom_ = that_.view_.GetZoom();
-    MapMouseToScene(centerX_, centerY_, that_.view_, downX_, downY_);
-  }
-
-  void WorldSceneWidget::ZoomMouseTracker::MouseMove(int x,
-                                                     int y)
-  {
-    static const double MIN_ZOOM = -4;
-    static const double MAX_ZOOM = 4;
-
-    if (that_.view_.GetDisplayHeight() <= 3)
-    {
-      LOG(WARNING) << "image is too small to zoom (current height = " << that_.view_.GetDisplayHeight() << ")";
-      return;
-    }
-
-    double dy = (static_cast<double>(y - downY_) /
-                 static_cast<double>(that_.view_.GetDisplayHeight() - 1)); // In the range [-1,1]
-    double z;
-
-    // Linear interpolation from [-1, 1] to [MIN_ZOOM, MAX_ZOOM]
-    if (dy < -1.0)
-    {
-      z = MIN_ZOOM;
-    }
-    else if (dy > 1.0)
-    {
-      z = MAX_ZOOM;
-    }
-    else
-    {
-      z = MIN_ZOOM + (MAX_ZOOM - MIN_ZOOM) * (dy + 1.0) / 2.0;
-    }
-
-    z = pow(2.0, z);
-
-    that_.view_.SetZoom(oldZoom_ * z);
-
-    // Correct the pan so that the original click point is kept at
-    // the same location on the display
-    double panX, panY;
-    that_.view_.GetPan(panX, panY);
-
-    int tx, ty;
-    that_.view_.MapSceneToDisplay(tx, ty, centerX_, centerY_);
-    that_.view_.SetPan(panX + static_cast<double>(downX_ - tx),
-                       panY + static_cast<double>(downY_ - ty));
-  }
-
-
   bool WorldSceneWidget::RenderCairo(CairoContext& context)
   {
     view_.ApplyTransform(context);
@@ -175,7 +95,7 @@
     view.ApplyTransform(context);
 
     double sceneX, sceneY;
-    MapMouseToScene(sceneX, sceneY, view, x, y);
+    view.MapPixelCenterToScene(sceneX, sceneY, x, y);
 
     if (interactor_)
     {
@@ -221,19 +141,13 @@
   }
 
 
-  ViewportGeometry WorldSceneWidget::GetView()
-  {
-    return view_;
-  }
-
-
   IMouseTracker* WorldSceneWidget::CreateMouseTracker(MouseButton button,
                                                       int x,
                                                       int y,
                                                       KeyboardModifiers modifiers)
   {
     double sceneX, sceneY;
-    MapMouseToScene(sceneX, sceneY, view_, x, y);
+    view_.MapPixelCenterToScene(sceneX, sceneY, x, y);
 
     // asks the Widget Interactor to provide a mouse tracker
     std::auto_ptr<IWorldSceneMouseTracker> tracker;
@@ -251,14 +165,14 @@
     //TODO: allow Interactor to create Pan & Zoom
     switch (button)
     {
-    case MouseButton_Middle:
-      return new PanMouseTracker(*this, x, y);
+      case MouseButton_Middle:
+        return new SceneMouseTracker(view_, new PanMouseTracker(*this, x, y));
 
-    case MouseButton_Right:
-      return new ZoomMouseTracker(*this, x, y);
+      case MouseButton_Right:
+        return new SceneMouseTracker(view_, new ZoomMouseTracker(*this, x, y));
 
-    default:
-      return NULL;
+      default:
+        return NULL;
     }
   }
 
--- a/Framework/Widgets/WorldSceneWidget.h	Wed Oct 17 15:18:48 2018 +0200
+++ b/Framework/Widgets/WorldSceneWidget.h	Wed Oct 17 19:38:39 2018 +0200
@@ -31,46 +31,6 @@
 {
   class WorldSceneWidget : public CairoWidget
   {
-  public:
-    class PanMouseTracker : public IMouseTracker
-    {
-    private:
-      WorldSceneWidget&  that_;
-      double             previousPanX_;
-      double             previousPanY_;
-      double             downX_;
-      double             downY_;
-
-    public:
-      PanMouseTracker(WorldSceneWidget& that, int x, int y);
-
-      virtual void Render(Orthanc::ImageAccessor& surface) {}
-
-      virtual void MouseUp() {}
-
-      virtual void MouseMove(int x, int y);
-    };
-
-    class ZoomMouseTracker : public IMouseTracker
-    {
-    private:
-      WorldSceneWidget&  that_;
-      int                downX_;
-      int                downY_;
-      double             centerX_;
-      double             centerY_;
-      double             oldZoom_;
-
-    public:
-      ZoomMouseTracker(WorldSceneWidget&  that, int x, int y);
-
-      void Render(Orthanc::ImageAccessor& surface) {}
-
-      virtual void MouseUp() {}
-
-      virtual void MouseMove(int x, int y);
-    };
-
   private:
     class SceneMouseTracker;
 
@@ -104,7 +64,10 @@
 
     void SetView(const ViewportGeometry& view);
 
-    ViewportGeometry GetView();
+    const ViewportGeometry& GetView() const
+    {
+      return view_;
+    }
 
     virtual void SetSize(unsigned int width,
                          unsigned int height);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Framework/Widgets/ZoomMouseTracker.cpp	Wed Oct 17 19:38:39 2018 +0200
@@ -0,0 +1,107 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2018 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "ZoomMouseTracker.h"
+
+#include <Core/Logging.h>
+
+namespace OrthancStone
+{
+  ZoomMouseTracker::ZoomMouseTracker(WorldSceneWidget& that,
+                                     int x,
+                                     int y) :
+    that_(that),
+    originalZoom_(that.GetView().GetZoom()),
+    downX_(x),
+    downY_(y)
+  {
+    that.GetView().MapPixelCenterToScene(centerX_, centerY_, x, y);
+
+    unsigned int height = that.GetView().GetDisplayHeight();
+      
+    if (height <= 3)
+    {
+      idle_ = true;
+      LOG(WARNING) << "image is too small to zoom (current height = " << height << ")";
+    }
+    else
+    {
+      idle_ = false;
+      normalization_ = 1.0 / static_cast<double>(height - 1);
+    }
+  }
+    
+
+  void ZoomMouseTracker::Render(CairoContext& context,
+                                double zoom)
+  {
+    throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
+  }
+
+
+  void ZoomMouseTracker::MouseMove(int displayX,
+                                   int displayY,
+                                   double x,
+                                   double y)
+  {
+    static const double MIN_ZOOM = -4;
+    static const double MAX_ZOOM = 4;
+
+      
+    if (!idle_)
+    {
+      double dy = static_cast<double>(displayY - downY_) * normalization_;  // In the range [-1,1]
+      double z;
+
+      // Linear interpolation from [-1, 1] to [MIN_ZOOM, MAX_ZOOM]
+      if (dy < -1.0)
+      {
+        z = MIN_ZOOM;
+      }
+      else if (dy > 1.0)
+      {
+        z = MAX_ZOOM;
+      }
+      else
+      {
+        z = MIN_ZOOM + (MAX_ZOOM - MIN_ZOOM) * (dy + 1.0) / 2.0;
+      }
+
+      z = pow(2.0, z);
+
+      ViewportGeometry view = that_.GetView();
+        
+      view.SetZoom(z * originalZoom_);
+        
+      // Correct the pan so that the original click point is kept at
+      // the same location on the display
+      double panX, panY;
+      view.GetPan(panX, panY);
+
+      int tx, ty;
+      view.MapSceneToDisplay(tx, ty, centerX_, centerY_);
+      view.SetPan(panX + static_cast<double>(downX_ - tx),
+                  panY + static_cast<double>(downY_ - ty));
+        
+      that_.SetView(view);
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Framework/Widgets/ZoomMouseTracker.h	Wed Oct 17 19:38:39 2018 +0200
@@ -0,0 +1,62 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2018 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include "WorldSceneWidget.h"
+
+namespace OrthancStone
+{
+  class ZoomMouseTracker : public IWorldSceneMouseTracker
+  {
+  private:
+    WorldSceneWidget&  that_;
+    double             originalZoom_;
+    int                downX_;
+    int                downY_;
+    double             centerX_;
+    double             centerY_;
+    bool               idle_;
+    double             normalization_;
+    
+  public:
+    ZoomMouseTracker(WorldSceneWidget& that,
+                     int x,
+                     int y);
+    
+    virtual bool HasRender() const
+    {
+      return false;
+    }
+
+    virtual void MouseUp()
+    {
+    }
+
+    virtual void Render(CairoContext& context,
+                        double zoom);
+
+    virtual void MouseMove(int displayX,
+                           int displayY,
+                           double x,
+                           double y);
+  };
+}
--- a/Resources/CMake/OrthancStoneConfiguration.cmake	Wed Oct 17 15:18:48 2018 +0200
+++ b/Resources/CMake/OrthancStoneConfiguration.cmake	Wed Oct 17 19:38:39 2018 +0200
@@ -225,10 +225,7 @@
   #${ORTHANC_STONE_ROOT}/Framework/Layers/SeriesFrameRendererFactory.cpp
   #${ORTHANC_STONE_ROOT}/Framework/Layers/SiblingSliceLocationFactory.cpp
   #${ORTHANC_STONE_ROOT}/Framework/Layers/SingleFrameRendererFactory.cpp
-  ${ORTHANC_STONE_ROOT}/Framework/StoneEnumerations.cpp
-  ${ORTHANC_STONE_ROOT}/Framework/SmartLoader.cpp
-  ${ORTHANC_STONE_ROOT}/Framework/dev.h
-  ${ORTHANC_STONE_ROOT}/Framework/StoneException.h
+
   ${ORTHANC_STONE_ROOT}/Framework/Layers/CircleMeasureTracker.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Layers/ColorFrameRenderer.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Layers/DicomStructureSetRendererFactory.cpp
@@ -241,6 +238,9 @@
   ${ORTHANC_STONE_ROOT}/Framework/Layers/OrthancFrameLayerSource.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Layers/RenderStyle.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Layers/SliceOutlineRenderer.cpp
+  ${ORTHANC_STONE_ROOT}/Framework/SmartLoader.cpp
+  ${ORTHANC_STONE_ROOT}/Framework/StoneEnumerations.cpp
+  ${ORTHANC_STONE_ROOT}/Framework/StoneException.h
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/CoordinateSystem3D.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/DicomFrameConverter.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/DicomStructureSet.cpp
@@ -248,13 +248,13 @@
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/Extent2D.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/FiniteProjectiveCamera.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/GeometryToolbox.cpp
+  ${ORTHANC_STONE_ROOT}/Framework/Toolbox/IWebService.h
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/ImageGeometry.cpp
-  ${ORTHANC_STONE_ROOT}/Framework/Toolbox/IWebService.h
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/LinearAlgebra.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/MessagingToolbox.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/OrientedBoundingBox.cpp
+  ${ORTHANC_STONE_ROOT}/Framework/Toolbox/OrthancApiClient.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/OrthancSlicesLoader.cpp
-  ${ORTHANC_STONE_ROOT}/Framework/Toolbox/OrthancApiClient.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/ParallelSlices.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/ParallelSlicesCursor.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Toolbox/ShearWarpProjectiveTransform.cpp
@@ -264,8 +264,8 @@
   ${ORTHANC_STONE_ROOT}/Framework/Viewport/CairoContext.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Viewport/CairoFont.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Viewport/CairoSurface.cpp
+  ${ORTHANC_STONE_ROOT}/Framework/Viewport/IStatusBar.h
   ${ORTHANC_STONE_ROOT}/Framework/Viewport/IViewport.h
-  ${ORTHANC_STONE_ROOT}/Framework/Viewport/IStatusBar.h
   ${ORTHANC_STONE_ROOT}/Framework/Viewport/WidgetViewport.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Volumes/ImageBuffer3D.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Volumes/SlicedVolumeBase.cpp
@@ -275,14 +275,17 @@
   ${ORTHANC_STONE_ROOT}/Framework/Widgets/CairoWidget.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Widgets/EmptyWidget.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Widgets/IWidget.h
+  ${ORTHANC_STONE_ROOT}/Framework/Widgets/IWorldSceneInteractor.h
   ${ORTHANC_STONE_ROOT}/Framework/Widgets/IWorldSceneMouseTracker.h
-  ${ORTHANC_STONE_ROOT}/Framework/Widgets/IWorldSceneInteractor.h
   ${ORTHANC_STONE_ROOT}/Framework/Widgets/LayerWidget.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Widgets/LayoutWidget.cpp
+  ${ORTHANC_STONE_ROOT}/Framework/Widgets/PanMouseTracker.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Widgets/TestCairoWidget.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Widgets/TestWorldSceneWidget.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Widgets/WidgetBase.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Widgets/WorldSceneWidget.cpp
+  ${ORTHANC_STONE_ROOT}/Framework/Widgets/ZoomMouseTracker.cpp
+  ${ORTHANC_STONE_ROOT}/Framework/dev.h
 
   ${ORTHANC_STONE_ROOT}/Framework/Messages/ICallable.h
   ${ORTHANC_STONE_ROOT}/Framework/Messages/IMessage.h
@@ -293,10 +296,10 @@
   ${ORTHANC_STONE_ROOT}/Framework/Messages/MessageType.h
   ${ORTHANC_STONE_ROOT}/Framework/Messages/Promise.h
 
+  ${ORTHANC_ROOT}/Plugins/Samples/Common/DicomDatasetReader.cpp
   ${ORTHANC_ROOT}/Plugins/Samples/Common/DicomPath.cpp
+  ${ORTHANC_ROOT}/Plugins/Samples/Common/FullOrthancDataset.cpp
   ${ORTHANC_ROOT}/Plugins/Samples/Common/IOrthancConnection.cpp
-  ${ORTHANC_ROOT}/Plugins/Samples/Common/DicomDatasetReader.cpp
-  ${ORTHANC_ROOT}/Plugins/Samples/Common/FullOrthancDataset.cpp
   
   ${PLATFORM_SOURCES}
   ${APPLICATIONS_SOURCES}