changeset 602:03c4b998fcd0

display scene positions in the basic sample
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 29 Apr 2019 14:40:01 +0200
parents 6129b1e5ba42
children 70992b38aa8a
files Framework/Scene2D/Internals/CompositorHelper.cpp Framework/Scene2D/Internals/CompositorHelper.h Framework/Scene2D/Scene2D.cpp Framework/Scene2D/Scene2D.h Framework/Scene2D/TextSceneLayer.cpp Framework/Scene2D/TextSceneLayer.h Samples/Sdl/BasicScene.cpp
diffstat 7 files changed, 209 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/Framework/Scene2D/Internals/CompositorHelper.cpp	Sat Apr 27 12:38:25 2019 +0200
+++ b/Framework/Scene2D/Internals/CompositorHelper.cpp	Mon Apr 29 14:40:01 2019 +0200
@@ -32,13 +32,16 @@
     private:
       std::auto_ptr<ILayerRenderer>  renderer_;
       const ISceneLayer&             layer_;
+      uint64_t                       layerIdentifier_;
       uint64_t                       lastRevision_;
 
     public:
       Item(ILayerRenderer* renderer,     // Takes ownership
-           const ISceneLayer& layer) :
+           const ISceneLayer& layer,
+           uint64_t layerIdentifier) :
         renderer_(renderer),
         layer_(layer),
+        layerIdentifier_(layerIdentifier),
         lastRevision_(layer.GetRevision())
       {
         if (renderer == NULL)
@@ -58,6 +61,11 @@
         return layer_;
       }
 
+      uint64_t GetLayerIdentifier() const
+      {
+        return layerIdentifier_;
+      }
+
       uint64_t GetLastRevision() const
       {
         return lastRevision_;
@@ -73,15 +81,19 @@
 
 
     void CompositorHelper::Visit(const ISceneLayer& layer,
+                                 uint64_t layerIdentifier,
                                  int depth)
     {
+      // "Visit()" is only applied to layers existing in the scene
+      assert(scene_.HasLayer(depth)); 
+
       Content::iterator found = content_.find(depth);
 
       assert(found == content_.end() ||
              found->second != NULL);
 
       if (found == content_.end() ||
-          &found->second->GetLayer() != &layer)
+          found->second->GetLayerIdentifier() != layerIdentifier)
       {
         // This is the first time this layer is rendered, or the layer
         // is not the same as before
@@ -96,12 +108,14 @@
         if (renderer.get() != NULL)
         {
           renderer->Render(sceneTransform_);
-          content_[depth] = new Item(renderer.release(), layer);
+          content_[depth] = new Item(renderer.release(), layer, layerIdentifier);
         }
       }
       else
       {
         // This layer has already been rendered
+        assert(found->second->GetLastRevision() <= layer.GetRevision());
+        
         if (found->second->GetLastRevision() < layer.GetRevision())
         {
           found->second->UpdateRenderer();
@@ -112,7 +126,7 @@
 
       // Check invariants
       assert(content_.find(depth) == content_.end() ||
-             (&content_[depth]->GetLayer() == &layer &&
+             (content_[depth]->GetLayerIdentifier() == layerIdentifier &&
               content_[depth]->GetLastRevision() == layer.GetRevision()));
     }
 
--- a/Framework/Scene2D/Internals/CompositorHelper.h	Sat Apr 27 12:38:25 2019 +0200
+++ b/Framework/Scene2D/Internals/CompositorHelper.h	Mon Apr 29 14:40:01 2019 +0200
@@ -65,6 +65,7 @@
 
     protected:
       virtual void Visit(const ISceneLayer& layer,
+                         uint64_t layerIdentifier,
                          int depth);
 
     public:
--- a/Framework/Scene2D/Scene2D.cpp	Sat Apr 27 12:38:25 2019 +0200
+++ b/Framework/Scene2D/Scene2D.cpp	Mon Apr 29 14:40:01 2019 +0200
@@ -26,14 +26,46 @@
 
 namespace OrthancStone
 {
+  class Scene2D::Item
+  {
+  private:
+    std::auto_ptr<ISceneLayer>  layer_;
+    uint64_t                    identifier_;
+
+  public:
+    Item(ISceneLayer* layer,
+         uint64_t identifier) :
+      layer_(layer),
+      identifier_(identifier)
+    {
+      if (layer == NULL)
+      {
+        throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
+      }
+    }
+
+    ISceneLayer& GetLayer() const
+    {
+      assert(layer_.get() != NULL);
+      return *layer_;
+    }
+
+    uint64_t GetIdentifier() const
+    {
+      return identifier_;
+    }
+  };
+  
+  
   Scene2D::Scene2D(const Scene2D& other) :
     sceneToCanvas_(other.sceneToCanvas_),
-    canvasToScene_(other.canvasToScene_)
+    canvasToScene_(other.canvasToScene_),
+    layerCounter_(0)
   {
     for (Content::const_iterator it = other.content_.begin();
          it != other.content_.end(); ++it)
     {
-      content_[it->first] = it->second->Clone();
+      content_[it->first] = new Item(it->second->GetLayer().Clone(), layerCounter_++);
     }
   }
 
@@ -52,7 +84,7 @@
   void Scene2D::SetLayer(int depth,
                          ISceneLayer* layer)  // Takes ownership
   {
-    std::auto_ptr<ISceneLayer> protection(layer);
+    std::auto_ptr<Item> item(new Item(layer, layerCounter_++));
 
     if (layer == NULL)
     {
@@ -63,13 +95,13 @@
 
     if (found == content_.end())
     {
-      content_[depth] = protection.release();
+      content_[depth] = item.release();
     }
     else
     {
       assert(found->second != NULL);
       delete found->second;
-      found->second = protection.release();
+      found->second = item.release();
     }
   }
 
@@ -87,13 +119,35 @@
   }
 
   
+  bool Scene2D::HasLayer(int depth) const
+  {
+    return (content_.find(depth) != content_.end());
+  }
+
+
+  ISceneLayer& Scene2D::GetLayer(int depth) const
+  {
+    Content::const_iterator found = content_.find(depth);
+
+    if (found == content_.end())
+    {
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
+    }
+    else
+    {
+      assert(found->second != NULL);
+      return found->second->GetLayer();
+    }
+  }
+
+  
   void Scene2D::Apply(IVisitor& visitor) const
   {
     for (Content::const_iterator it = content_.begin(); 
          it != content_.end(); ++it)
     {
       assert(it->second != NULL);
-      visitor.Visit(*it->second, it->first);
+      visitor.Visit(it->second->GetLayer(), it->second->GetIdentifier(), it->first);
     }
   }
 
@@ -119,7 +173,7 @@
       assert(it->second != NULL);
       
       Extent2D tmp;
-      if (it->second->GetBoundingBox(tmp))
+      if (it->second->GetLayer().GetBoundingBox(tmp))
       {
         extent.Union(tmp);
       }
--- a/Framework/Scene2D/Scene2D.h	Sat Apr 27 12:38:25 2019 +0200
+++ b/Framework/Scene2D/Scene2D.h	Mon Apr 29 14:40:01 2019 +0200
@@ -39,21 +39,25 @@
       }
 
       virtual void Visit(const ISceneLayer& layer,
+                         uint64_t layerIdentifier,
                          int depth) = 0;
     };
 
   private:
-    typedef std::map<int, ISceneLayer*>  Content;
+    class Item;
+    
+    typedef std::map<int, Item*>  Content;
 
-    Content    content_;
-
+    Content            content_;
     AffineTransform2D  sceneToCanvas_;
     AffineTransform2D  canvasToScene_;
+    uint64_t           layerCounter_;
 
     Scene2D(const Scene2D& other);
     
   public:
-    Scene2D()
+    Scene2D() :
+      layerCounter_(0)
     {
     }
     
@@ -69,6 +73,10 @@
 
     void DeleteLayer(int depth);
 
+    bool HasLayer(int depth) const;
+
+    ISceneLayer& GetLayer(int depth) const;
+
     void Apply(IVisitor& visitor) const;
 
     const AffineTransform2D& GetSceneToCanvasTransform() const
--- a/Framework/Scene2D/TextSceneLayer.cpp	Sat Apr 27 12:38:25 2019 +0200
+++ b/Framework/Scene2D/TextSceneLayer.cpp	Mon Apr 29 14:40:01 2019 +0200
@@ -23,26 +23,59 @@
 
 namespace OrthancStone
 {
-  TextSceneLayer::TextSceneLayer(double x,
-                                 double y,
-                                 const std::string& utf8,
-                                 size_t fontIndex,
-                                 BitmapAnchor anchor,
-                                 unsigned int border) :
-    x_(x),
-    y_(y),
-    utf8_(utf8),
-    fontIndex_(fontIndex),
-    anchor_(anchor),
-    border_(border)
+  TextSceneLayer::TextSceneLayer() :
+    x_(0),
+    y_(0),
+    fontIndex_(0),
+    anchor_(BitmapAnchor_Center),
+    border_(0),
+    revision_(0)
   {
   }
 
 
   ISceneLayer* TextSceneLayer::Clone() const
   {
-    std::auto_ptr<TextSceneLayer> cloned(new TextSceneLayer(x_, y_, utf8_, fontIndex_, anchor_, border_));
+    std::auto_ptr<TextSceneLayer> cloned(new TextSceneLayer);
     cloned->SetColor(GetRed(), GetGreen(), GetBlue());
+    cloned->x_ = x_;
+    cloned->y_ = y_;
+    cloned->utf8_ = utf8_;
+    cloned->fontIndex_ = fontIndex_;
+    cloned->anchor_ = anchor_;
+    cloned->border_ = border_;
     return cloned.release();
   }
+
+  void TextSceneLayer::SetPosition(double x,
+                                   double y)
+  {
+    x_ = x;
+    y_ = y;
+    revision_ ++;
+  }
+
+  void TextSceneLayer::SetText(const std::string& utf8)
+  {
+    utf8_ = utf8;
+    revision_ ++;
+  }
+
+  void TextSceneLayer::SetFontIndex(size_t fontIndex)
+  {
+    fontIndex_ = fontIndex;
+    revision_ ++;
+  }
+
+  void TextSceneLayer::SetAnchor(BitmapAnchor anchor)
+  {
+    anchor_ = anchor;
+    revision_ ++;
+  }
+
+  void TextSceneLayer::SetBorder(unsigned int border)
+  {
+    border_ = border;
+    revision_ ++;
+  }
 }
--- a/Framework/Scene2D/TextSceneLayer.h	Sat Apr 27 12:38:25 2019 +0200
+++ b/Framework/Scene2D/TextSceneLayer.h	Mon Apr 29 14:40:01 2019 +0200
@@ -38,17 +38,24 @@
     size_t         fontIndex_;
     BitmapAnchor   anchor_;
     unsigned int   border_;
+    uint64_t       revision_;
   
   public:
-    TextSceneLayer(double x,
-                   double y,
-                   const std::string& utf8,
-                   size_t fontIndex,
-                   BitmapAnchor anchor,
-                   unsigned int border);
+    TextSceneLayer();
 
     virtual ISceneLayer* Clone() const;
 
+    void SetPosition(double x,
+                     double y);
+
+    void SetText(const std::string& utf8);
+
+    void SetFontIndex(size_t fontIndex);
+
+    void SetAnchor(BitmapAnchor anchor);
+
+    void SetBorder(unsigned int border);
+
     double GetX() const
     {
       return x_;
@@ -91,7 +98,7 @@
 
     virtual uint64_t GetRevision() const
     {
-      return 0;
+      return revision_;
     }
   };
 }
--- a/Samples/Sdl/BasicScene.cpp	Sat Apr 27 12:38:25 2019 +0200
+++ b/Samples/Sdl/BasicScene.cpp	Mon Apr 29 14:40:01 2019 +0200
@@ -39,7 +39,8 @@
 #include <SDL.h>
 #include <stdio.h>
 
-static const unsigned int FONT_SIZE = 64;
+static const unsigned int FONT_SIZE = 32;
+static const int LAYER_POSITION = 150;
 
 
 void PrepareScene(OrthancStone::Scene2D& scene)
@@ -125,7 +126,11 @@
   }
 
   // Some text
-  scene.SetLayer(170, new TextSceneLayer(0, 0, "Hello", 0, BitmapAnchor_Center, 20));
+  {
+    std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer);
+    layer->SetText("Hello");
+    scene.SetLayer(100, layer.release());
+  }
 }
 
 
@@ -156,7 +161,49 @@
                             unsigned int windowWidth,
                             unsigned int windowHeight)
 {
-  if (event.type == SDL_MOUSEBUTTONDOWN)
+  bool hasPositionLayer = false;
+  
+  if (event.type == SDL_MOUSEMOTION)
+  {
+    int scancodeCount = 0;
+    const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount);
+
+    if (activeTracker.get() == NULL &&
+        SDL_SCANCODE_LCTRL < scancodeCount &&
+        keyboardState[SDL_SCANCODE_LCTRL])
+    {
+      // The "left-ctrl" key is down, while no tracker is present
+
+      OrthancStone::PointerEvent e;
+      e.AddIntegerPosition(event.button.x - static_cast<int>(windowWidth) / 2,
+                           event.button.y - static_cast<int>(windowHeight) / 2);
+      OrthancStone::ScenePoint2D p = e.GetMainPosition().Apply(scene.GetCanvasToSceneTransform());
+
+      char buf[64];
+      sprintf(buf, "(%0.02f,%0.02f)", p.GetX(), p.GetY());
+
+      if (scene.HasLayer(LAYER_POSITION))
+      {
+        OrthancStone::TextSceneLayer& layer =
+          dynamic_cast<OrthancStone::TextSceneLayer&>(scene.GetLayer(LAYER_POSITION));
+        layer.SetText(buf);
+        layer.SetPosition(p.GetX(), p.GetY());
+      }
+      else
+      {
+        std::auto_ptr<OrthancStone::TextSceneLayer> layer(new OrthancStone::TextSceneLayer);
+        layer->SetColor(0, 255, 0);
+        layer->SetText(buf);
+        layer->SetBorder(20);
+        layer->SetAnchor(OrthancStone::BitmapAnchor_BottomCenter);
+        layer->SetPosition(p.GetX(), p.GetY());
+        scene.SetLayer(LAYER_POSITION, layer.release());
+      }
+
+      hasPositionLayer = true;
+    }
+  }
+  else if (event.type == SDL_MOUSEBUTTONDOWN)
   {
     OrthancStone::PointerEvent e;
     e.AddIntegerPosition(event.button.x, event.button.y);
@@ -198,6 +245,11 @@
         break;
     }
   }
+
+  if (!hasPositionLayer)
+  {
+    scene.DeleteLayer(LAYER_POSITION);
+  }
 }
 
 
@@ -284,14 +336,11 @@
             break;
 
           default:
-            HandleApplicationEvent(scene, event, tracker, window.GetCanvasWidth(), window.GetCanvasHeight());
             break;
         }
       }
-      else
-      {
-        HandleApplicationEvent(scene, event, tracker, window.GetCanvasWidth(), window.GetCanvasHeight());
-      }
+      
+      HandleApplicationEvent(scene, event, tracker, window.GetCanvasWidth(), window.GetCanvasHeight());
     }
 
     SDL_Delay(1);