]> git.mxchange.org Git - simgear.git/blobdiff - simgear/canvas/Canvas.cxx
Canvas::Text: add line-height property.
[simgear.git] / simgear / canvas / Canvas.cxx
index cb8d6917d25ab3d785080b8773f957fd573c5626..fa6712389c22ecaf2357cfb9b225f98f090ed63d 100644 (file)
@@ -31,7 +31,6 @@
 
 #include <boost/algorithm/string/predicate.hpp>
 #include <boost/foreach.hpp>
-#include <iostream>
 
 namespace simgear
 {
@@ -76,9 +75,13 @@ namespace canvas
   }
 
   //----------------------------------------------------------------------------
-  Canvas::~Canvas()
+  void Canvas::onDestroy()
   {
-
+    if( _root_group )
+    {
+      _root_group->clearEventListener();
+      _root_group->onDestroy();
+    }
   }
 
   //----------------------------------------------------------------------------
@@ -107,7 +110,31 @@ namespace canvas
   }
 
   //----------------------------------------------------------------------------
-  void Canvas::addDependentCanvas(const CanvasWeakPtr& canvas)
+  bool Canvas::isInit() const
+  {
+    return _texture.serviceable();
+  }
+
+  //----------------------------------------------------------------------------
+  void Canvas::addParentCanvas(const CanvasWeakPtr& canvas)
+  {
+    if( canvas.expired() )
+    {
+      SG_LOG
+      (
+        SG_GENERAL,
+        SG_WARN,
+        "Canvas::addParentCanvas(" << _node->getPath(true) << "): "
+        "got an expired parent!"
+      );
+      return;
+    }
+
+    _parent_canvases.insert(canvas);
+  }
+
+  //----------------------------------------------------------------------------
+  void Canvas::addChildCanvas(const CanvasWeakPtr& canvas)
   {
     if( canvas.expired() )
     {
@@ -115,28 +142,49 @@ namespace canvas
       (
         SG_GENERAL,
         SG_WARN,
-        "Canvas::addDependentCanvas: got an expired Canvas dependent on "
-        << _node->getPath()
+        "Canvas::addChildCanvas(" << _node->getPath(true) << "): "
+        " got an expired child!"
       );
       return;
     }
 
-    _dependent_canvases.insert(canvas);
+    _child_canvases.insert(canvas);
   }
 
   //----------------------------------------------------------------------------
-  void Canvas::removeDependentCanvas(const CanvasWeakPtr& canvas)
+  void Canvas::removeParentCanvas(const CanvasWeakPtr& canvas)
   {
-    _dependent_canvases.erase(canvas);
+    _parent_canvases.erase(canvas);
+  }
+
+  //----------------------------------------------------------------------------
+  void Canvas::removeChildCanvas(const CanvasWeakPtr& canvas)
+  {
+    _child_canvases.erase(canvas);
   }
 
   //----------------------------------------------------------------------------
   GroupPtr Canvas::createGroup(const std::string& name)
   {
-    return boost::dynamic_pointer_cast<Group>
-    (
-      _root_group->createChild("group", name)
-    );
+    return _root_group->createChild<Group>(name);
+  }
+
+  //----------------------------------------------------------------------------
+  GroupPtr Canvas::getGroup(const std::string& name)
+  {
+    return _root_group->getChild<Group>(name);
+  }
+
+  //----------------------------------------------------------------------------
+  GroupPtr Canvas::getOrCreateGroup(const std::string& name)
+  {
+    return _root_group->getOrCreateChild<Group>(name);
+  }
+
+  //----------------------------------------------------------------------------
+  GroupPtr Canvas::getRootGroup()
+  {
+    return _root_group;
   }
 
   //----------------------------------------------------------------------------
@@ -179,9 +227,6 @@ namespace canvas
 
       camera->addChild(_root_group->getMatrixTransform());
 
-      // Ensure objects are drawn in order of traversal
-      camera->getOrCreateStateSet()->setBinName("TraversalOrderBin");
-
       if( _texture.serviceable() )
       {
         setStatusFlags(STATUS_OK);
@@ -197,10 +242,18 @@ namespace canvas
 
     if( _visible || _render_always )
     {
+      BOOST_FOREACH(CanvasWeakPtr canvas, _child_canvases)
+      {
+        // TODO should we check if the image the child canvas is displayed
+        //      within is really visible?
+        if( !canvas.expired() )
+          canvas.lock()->_visible = true;
+      }
+
       if( _render_dirty )
       {
-        // Also mark all dependent (eg. recursively used) canvases as dirty
-        BOOST_FOREACH(CanvasWeakPtr canvas, _dependent_canvases)
+        // Also mark all canvases this canvas is displayed within as dirty
+        BOOST_FOREACH(CanvasWeakPtr canvas, _parent_canvases)
         {
           if( !canvas.expired() )
             canvas.lock()->_render_dirty = true;
@@ -340,13 +393,19 @@ namespace canvas
   //----------------------------------------------------------------------------
   int Canvas::getViewWidth() const
   {
-    return _view_width;
+    return _texture.getViewSize().x();
   }
 
   //----------------------------------------------------------------------------
   int Canvas::getViewHeight() const
   {
-    return _view_height;
+    return _texture.getViewSize().y();
+  }
+
+  //----------------------------------------------------------------------------
+  SGRect<int> Canvas::getViewport() const
+  {
+    return SGRect<int>(0, 0, getViewWidth(), getViewHeight());
   }
 
   //----------------------------------------------------------------------------
@@ -357,7 +416,8 @@ namespace canvas
 
     EventVisitor visitor( EventVisitor::TRAVERSE_DOWN,
                           event->getClientPos(),
-                          event->getDelta() );
+                          event->getDelta(),
+                          _root_group );
     if( !_root_group->accept(visitor) )
       return false;
 
@@ -404,21 +464,26 @@ namespace canvas
     if(    node->getParent()->getParent() == _node
         && node->getParent()->getNameString() == "placement" )
     {
-      bool placement_dirty = false;
-      BOOST_FOREACH(Placements& placements, _placements)
+      size_t index = node->getIndex();
+      if( index < _placements.size() )
       {
-        BOOST_FOREACH(PlacementPtr& placement, placements)
+        Placements& placements = _placements[index];
+        if( !placements.empty() )
         {
-          // check if change can be directly handled by placement
-          if(    placement->getProps() == node->getParent()
-              && !placement->childChanged(node) )
-            placement_dirty = true;
+          bool placement_dirty = false;
+          BOOST_FOREACH(PlacementPtr& placement, placements)
+          {
+            // check if change can be directly handled by placement
+            if(    placement->getProps() == node->getParent()
+                && !placement->childChanged(node) )
+              placement_dirty = true;
+          }
+
+          if( !placement_dirty )
+            return;
         }
       }
 
-      if( !placement_dirty )
-        return;
-
       // prevent double updates...
       for( size_t i = 0; i < _dirty_placements.size(); ++i )
       {