#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
+#include <map>
#include <vector>
namespace simgear
typedef boost::shared_ptr<Canvas> CanvasPtr;
typedef boost::weak_ptr<Canvas> CanvasWeakPtr;
+ class Element;
+ typedef boost::shared_ptr<Element> ElementPtr;
+ typedef boost::weak_ptr<Element> ElementWeakPtr;
+
+ typedef std::map<std::string, const SGPropertyNode*> Style;
+ typedef boost::function<ElementPtr( const CanvasWeakPtr&,
+ const SGPropertyNode_ptr&,
+ const Style& )> ElementFactory;
+
typedef osg::ref_ptr<osgText::Font> FontPtr;
class Placement;
//----------------------------------------------------------------------------
Element::Element( const CanvasWeakPtr& canvas,
- SGPropertyNode_ptr node,
+ const SGPropertyNode_ptr& node,
const Style& parent_style ):
_canvas( canvas ),
_transform_dirty( false ),
public SGPropertyChangeListener
{
public:
- typedef std::map<std::string, const SGPropertyNode*> Style;
typedef boost::function<void(const SGPropertyNode*)> StyleSetter;
typedef std::map<std::string, StyleSetter> StyleSetters;
std::vector<SGPropertyNode_ptr> _bounding_box;
Element( const CanvasWeakPtr& canvas,
- SGPropertyNode_ptr node,
+ const SGPropertyNode_ptr& node,
const Style& parent_style );
template<typename T, class C1, class C2>
#include "CanvasPath.hxx"
#include "CanvasText.hxx"
+#include <boost/bind.hpp>
#include <boost/foreach.hpp>
+#include <boost/make_shared.hpp>
+#include <boost/lambda/core.hpp>
namespace simgear
{
namespace canvas
{
+ /**
+ * Create an ElementFactory for elements of type T
+ */
+ template<typename T>
+ ElementFactory createElementFactory()
+ {
+ return boost::bind
+ (
+ &boost::make_shared<T, const CanvasWeakPtr&,
+ const SGPropertyNode_ptr&,
+ const Style&>,
+ boost::lambda::_1,
+ boost::lambda::_2,
+ boost::lambda::_3
+ );
+ }
//----------------------------------------------------------------------------
Group::Group( const CanvasWeakPtr& canvas,
- SGPropertyNode_ptr node,
+ const SGPropertyNode_ptr& node,
const Style& parent_style ):
Element(canvas, node, parent_style)
{
-
+ _child_factories["group"] = createElementFactory<Group>();
+ _child_factories["image"] = createElementFactory<Image>();
+ _child_factories["map" ] = createElementFactory<Map >();
+ _child_factories["path" ] = createElementFactory<Path >();
+ _child_factories["text" ] = createElementFactory<Text >();
}
//----------------------------------------------------------------------------
if( child->getParent() != _node )
return;
- boost::shared_ptr<Element> element;
-
- // TODO create map of child factories and use also to check for element
- // on deletion in ::childRemoved
- if( child->getNameString() == "text" )
- element.reset( new Text(_canvas, child, _style) );
- else if( child->getNameString() == "group" )
- element.reset( new Group(_canvas, child, _style) );
- else if( child->getNameString() == "map" )
- element.reset( new Map(_canvas, child, _style) );
- else if( child->getNameString() == "path" )
- element.reset( new Path(_canvas, child, _style) );
- else if( child->getNameString() == "image" )
- element.reset( new Image(_canvas, child, _style) );
-
- if( element )
+ ChildFactories::iterator child_factory =
+ _child_factories.find( child->getNameString() );
+ if( child_factory != _child_factories.end() )
{
+ ElementPtr element = child_factory->second(_canvas, child, _style);
+
// Add to osg scene graph...
_transform->addChild( element->getMatrixTransform() );
_children.push_back( ChildList::value_type(child, element) );
+
return;
}
if( node->getParent() != _node )
return;
- if( node->getNameString() == "text"
- || node->getNameString() == "group"
- || node->getNameString() == "map"
- || node->getNameString() == "path"
- || node->getNameString() == "image" )
+ if( _child_factories.find(node->getNameString()) != _child_factories.end() )
{
ChildFinder pred(node);
ChildList::iterator child =
#include "CanvasElement.hxx"
-#include <boost/shared_ptr.hpp>
#include <list>
-#include <map>
namespace simgear
{
namespace canvas
{
- typedef boost::shared_ptr<Element> ElementPtr;
-
class Group:
public Element
{
> ChildList;
Group( const CanvasWeakPtr& canvas,
- SGPropertyNode_ptr node,
+ const SGPropertyNode_ptr& node,
const Style& parent_style = Style() );
virtual ~Group();
protected:
- ChildList _children;
+ typedef std::map<std::string, ElementFactory> ChildFactories;
+
+ ChildFactories _child_factories;
+ ChildList _children;
virtual bool handleLocalMouseEvent(const canvas::MouseEvent& event);
//----------------------------------------------------------------------------
Image::Image( const CanvasWeakPtr& canvas,
- SGPropertyNode_ptr node,
+ const SGPropertyNode_ptr& node,
const Style& parent_style ):
Element(canvas, node, parent_style),
_texture(new osg::Texture2D),
* [x,y] Position of rectangle
*/
Image( const CanvasWeakPtr& canvas,
- SGPropertyNode_ptr node,
+ const SGPropertyNode_ptr& node,
const Style& parent_style );
virtual ~Image();
//----------------------------------------------------------------------------
Map::Map( const CanvasWeakPtr& canvas,
- SGPropertyNode_ptr node,
+ const SGPropertyNode_ptr& node,
const Style& parent_style ):
Group(canvas, node, parent_style),
// TODO make projection configurable
{
public:
Map( const CanvasWeakPtr& canvas,
- SGPropertyNode_ptr node,
+ const SGPropertyNode_ptr& node,
const Style& parent_style );
virtual ~Map();
//----------------------------------------------------------------------------
Path::Path( const CanvasWeakPtr& canvas,
- SGPropertyNode_ptr node,
+ const SGPropertyNode_ptr& node,
const Style& parent_style ):
Element(canvas, node, parent_style),
_path( new PathDrawable(this) )
{
public:
Path( const CanvasWeakPtr& canvas,
- SGPropertyNode_ptr node,
+ const SGPropertyNode_ptr& node,
const Style& parent_style );
virtual ~Path();
//----------------------------------------------------------------------------
Text::Text( const CanvasWeakPtr& canvas,
- SGPropertyNode_ptr node,
+ const SGPropertyNode_ptr& node,
const Style& parent_style ):
Element(canvas, node, parent_style),
_text( new Text::TextOSG(this) )
{
public:
Text( const CanvasWeakPtr& canvas,
- SGPropertyNode_ptr node,
+ const SGPropertyNode_ptr& node,
const Style& parent_style );
~Text();