]> git.mxchange.org Git - simgear.git/blobdiff - simgear/canvas/elements/CanvasGroup.cxx
Canvas: rework style setter system.
[simgear.git] / simgear / canvas / elements / CanvasGroup.cxx
index fdcc7ae244454b882a3bc1934f99e73f51629c5c..9bfb8c2f26d3df44be309cc8815c591423dde953 100644 (file)
@@ -41,9 +41,14 @@ namespace canvas
                             const Style& style,
                             Element* parent )
   {
-    return ElementPtr( new T(canvas, node, style, parent) );
+    ElementPtr el( new T(canvas, node, style, parent) );
+    el->setSelf(el);
+    return el;
   }
 
+  //----------------------------------------------------------------------------
+  ElementFactories Group::_child_factories;
+
   //----------------------------------------------------------------------------
   Group::Group( const CanvasWeakPtr& canvas,
                 const SGPropertyNode_ptr& node,
@@ -51,11 +56,14 @@ namespace canvas
                 Element* parent ):
     Element(canvas, node, parent_style, parent)
   {
-    _child_factories["group"] = &createElement<Group>;
-    _child_factories["image"] = &createElement<Image>;
-    _child_factories["map"  ] = &createElement<Map  >;
-    _child_factories["path" ] = &createElement<Path >;
-    _child_factories["text" ] = &createElement<Text >;
+    if( !isInit<Group>() )
+    {
+      _child_factories["group"] = &createElement<Group>;
+      _child_factories["image"] = &createElement<Image>;
+      _child_factories["map"  ] = &createElement<Map  >;
+      _child_factories["path" ] = &createElement<Path >;
+      _child_factories["text" ] = &createElement<Text >;
+    }
   }
 
   //----------------------------------------------------------------------------
@@ -66,11 +74,11 @@ namespace canvas
 
   //----------------------------------------------------------------------------
   ElementPtr Group::createChild( const std::string& type,
-                                 const std::string& name )
+                                 const std::string& id )
   {
     SGPropertyNode* node = _node->addChild(type, 0, false);
-    if( !name.empty() )
-      node->setStringValue("name", name);
+    if( !id.empty() )
+      node->setStringValue("id", id);
 
     return getChild(node);
   }
@@ -85,6 +93,32 @@ namespace canvas
     return child->second;
   }
 
+  //----------------------------------------------------------------------------
+  ElementPtr Group::getElementById(const std::string& id)
+  {
+    std::vector<GroupPtr> groups;
+
+    BOOST_FOREACH( ChildList::value_type child, _children )
+    {
+      const ElementPtr& el = child.second;
+      if( el->getProps()->getStringValue("id") == id )
+        return el;
+
+      GroupPtr group = boost::dynamic_pointer_cast<Group>(el);
+      if( group )
+        groups.push_back(group);
+    }
+
+    BOOST_FOREACH( GroupPtr group, groups )
+    {
+      ElementPtr el = group->getElementById(id);
+      if( el )
+        return el;
+    }
+
+    return ElementPtr();
+  }
+
   //----------------------------------------------------------------------------
   void Group::update(double dt)
   {
@@ -106,13 +140,56 @@ namespace canvas
     return false;
   }
 
+  //----------------------------------------------------------------------------
+  bool Group::setStyle(const SGPropertyNode* style)
+  {
+    // Don't propagate styles directly applicable to this group
+    if( Element::setStyle(style) )
+      return true;
+
+    if(    style->getParent() != _node
+        && _style.find(style->getNameString()) != _style.end() )
+      return false;
+
+    bool handled = false;
+    BOOST_FOREACH( ChildList::value_type child, _children )
+    {
+      if( child.second->setStyle(style) )
+        handled = true;
+    }
+
+    return handled;
+  }
+
+  //----------------------------------------------------------------------------
+  osg::BoundingBox Group::getTransformedBounds(const osg::Matrix& m) const
+  {
+    osg::BoundingBox bb;
+
+    BOOST_FOREACH( ChildList::value_type child, _children )
+    {
+      if( !child.second->getMatrixTransform()->getNodeMask() )
+        continue;
+
+      bb.expandBy
+      (
+        child.second->getTransformedBounds
+        (
+          child.second->getMatrixTransform()->getMatrix() * m
+        )
+      );
+    }
+
+    return bb;
+  }
+
   //----------------------------------------------------------------------------
   void Group::childAdded(SGPropertyNode* child)
   {
     if( child->getParent() != _node )
       return;
 
-    ChildFactories::iterator child_factory =
+    ElementFactories::iterator child_factory =
       _child_factories.find( child->getNameString() );
     if( child_factory != _child_factories.end() )
     {
@@ -122,10 +199,18 @@ namespace canvas
       _transform->addChild( element->getMatrixTransform() );
       _children.push_back( ChildList::value_type(child, element) );
 
+      // ...and ensure correct ordering
+      handleZIndexChanged( --_children.end() );
+
       return;
     }
 
-    _style[ child->getNameString() ] = child;
+    if( !Element::setStyle(child) )
+    {
+      // Only add style if not applicable to group itself
+      _style[ child->getNameString() ] = child;
+      setStyle(child);
+    }
   }
 
   //----------------------------------------------------------------------------
@@ -163,13 +248,13 @@ namespace canvas
   {
     if(    node->getParent()->getParent() == _node
         && node->getNameString() == "z-index" )
-      return handleZIndexChanged(node->getParent(), node->getIntValue());
+      return handleZIndexChanged( findChild(node->getParent()),
+                                  node->getIntValue() );
   }
 
   //----------------------------------------------------------------------------
-  void Group::handleZIndexChanged(SGPropertyNode* node, int z_index)
+  void Group::handleZIndexChanged(ChildList::iterator child, int z_index)
   {
-    ChildList::iterator child = findChild(node);
     if( child == _children.end() )
       return;