Canvas: Ensure all element types are initialized before first usage.

If setting properties on a group a check is performed if
this property exists on any possible child element, and
only if this is the case the property is stored in the
groups style.

Previously elements have been only initialized during
their first usage, leading to ignored styles if they
have been set on a parent element before instantiating
an instance of the actual element type.
This commit is contained in:
Thomas Geymayer 2013-07-20 15:45:02 +02:00
parent fc75b0bd21
commit b236821661
12 changed files with 125 additions and 66 deletions

View File

@ -523,6 +523,8 @@ namespace canvas
_style( parent_style ), _style( parent_style ),
_drawable( 0 ) _drawable( 0 )
{ {
staticInit();
SG_LOG SG_LOG
( (
SG_GL, SG_GL,
@ -530,11 +532,6 @@ namespace canvas
"New canvas element " << node->getPath() "New canvas element " << node->getPath()
); );
if( !isInit<Element>() )
{
addStyle("clip", "", &Element::setClip, false);
}
// Ensure elements are drawn in order they appear in the element tree // Ensure elements are drawn in order they appear in the element tree
_transform->getOrCreateStateSet() _transform->getOrCreateStateSet()
->setRenderBinDetails ->setRenderBinDetails
@ -545,6 +542,15 @@ namespace canvas
); );
} }
//----------------------------------------------------------------------------
void Element::staticInit()
{
if( isInit<Element>() )
return;
addStyle("clip", "", &Element::setClip, false);
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool Element::isStyleEmpty(const SGPropertyNode* child) const bool Element::isStyleEmpty(const SGPropertyNode* child) const
{ {

View File

@ -197,6 +197,8 @@ namespace canvas
typedef std::map<std::string, StyleInfo> StyleSetters; typedef std::map<std::string, StyleInfo> StyleSetters;
static StyleSetters _style_setters; static StyleSetters _style_setters;
static void staticInit();
Element( const CanvasWeakPtr& canvas, Element( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node, const SGPropertyNode_ptr& node,
const Style& parent_style, const Style& parent_style,
@ -210,7 +212,7 @@ namespace canvas
* @tparam Derived (Derived) class type * @tparam Derived (Derived) class type
*/ */
template<class Derived> template<class Derived>
bool isInit() const static bool isInit()
{ {
static bool is_init = false; static bool is_init = false;
if( is_init ) if( is_init )
@ -239,6 +241,7 @@ namespace canvas
typename T2, typename T2,
class Derived class Derived
> >
static
StyleSetter StyleSetter
addStyle( const std::string& name, addStyle( const std::string& name,
const std::string& type, const std::string& type,
@ -282,6 +285,7 @@ namespace canvas
typename T, typename T,
class Derived class Derived
> >
static
StyleSetter StyleSetter
addStyle( const std::string& name, addStyle( const std::string& name,
const std::string& type, const std::string& type,
@ -295,6 +299,7 @@ namespace canvas
typename T, typename T,
class Derived class Derived
> >
static
StyleSetter StyleSetter
addStyle( const std::string& name, addStyle( const std::string& name,
const std::string& type, const std::string& type,
@ -315,6 +320,7 @@ namespace canvas
typename T2, typename T2,
class Derived class Derived
> >
static
StyleSetterFunc StyleSetterFunc
addStyle( const std::string& name, addStyle( const std::string& name,
const std::string& type, const std::string& type,
@ -333,6 +339,7 @@ namespace canvas
template< template<
class Derived class Derived
> >
static
StyleSetter StyleSetter
addStyle( const std::string& name, addStyle( const std::string& name,
const std::string& type, const std::string& type,
@ -354,6 +361,7 @@ namespace canvas
class Other, class Other,
class OtherRef class OtherRef
> >
static
StyleSetter StyleSetter
addStyle( const std::string& name, addStyle( const std::string& name,
const std::string& type, const std::string& type,
@ -377,6 +385,7 @@ namespace canvas
class Other, class Other,
class OtherRef class OtherRef
> >
static
StyleSetter StyleSetter
addStyle( const std::string& name, addStyle( const std::string& name,
const std::string& type, const std::string& type,
@ -400,6 +409,7 @@ namespace canvas
class Other, class Other,
class OtherRef class OtherRef
> >
static
StyleSetter StyleSetter
addStyle( const std::string& name, addStyle( const std::string& name,
const std::string& type, const std::string& type,
@ -421,6 +431,7 @@ namespace canvas
class Other, class Other,
class OtherRef class OtherRef
> >
static
StyleSetter StyleSetter
addStyle( const std::string& name, addStyle( const std::string& name,
const std::string& type, const std::string& type,
@ -439,6 +450,7 @@ namespace canvas
} }
template<typename T, class Derived, class Other, class OtherRef> template<typename T, class Derived, class Other, class OtherRef>
static
boost::function<void (Derived&, T)> boost::function<void (Derived&, T)>
bindOther( void (Other::*setter)(T), OtherRef Derived::*instance_ref ) bindOther( void (Other::*setter)(T), OtherRef Derived::*instance_ref )
{ {
@ -446,6 +458,7 @@ namespace canvas
} }
template<typename T, class Derived, class Other, class OtherRef> template<typename T, class Derived, class Other, class OtherRef>
static
boost::function<void (Derived&, T)> boost::function<void (Derived&, T)>
bindOther( const boost::function<void (Other&, T)>& setter, bindOther( const boost::function<void (Other&, T)>& setter,
OtherRef Derived::*instance_ref ) OtherRef Derived::*instance_ref )
@ -463,6 +476,7 @@ namespace canvas
} }
template<typename T1, typename T2, class Derived> template<typename T1, typename T2, class Derived>
static
StyleSetterFuncUnchecked StyleSetterFuncUnchecked
bindStyleSetter( const std::string& name, bindStyleSetter( const std::string& name,
const boost::function<void (Derived&, T2)>& setter ) const boost::function<void (Derived&, T2)>& setter )

View File

@ -38,6 +38,7 @@ namespace canvas
template<typename ElementType> template<typename ElementType>
void add(ElementFactories& factories) void add(ElementFactories& factories)
{ {
ElementType::staticInit();
factories[ElementType::TYPE_NAME] = &Element::create<ElementType>; factories[ElementType::TYPE_NAME] = &Element::create<ElementType>;
} }
@ -52,6 +53,19 @@ namespace canvas
"canvas::Group::" << member_name << ": Group has expired." ); "canvas::Group::" << member_name << ": Group has expired." );
} }
//----------------------------------------------------------------------------
void Group::staticInit()
{
if( isInit<Group>() )
return;
add<Group>(_child_factories);
add<Image>(_child_factories);
add<Map >(_child_factories);
add<Path >(_child_factories);
add<Text >(_child_factories);
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
Group::Group( const CanvasWeakPtr& canvas, Group::Group( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node, const SGPropertyNode_ptr& node,
@ -59,14 +73,7 @@ namespace canvas
Element* parent ): Element* parent ):
Element(canvas, node, parent_style, parent) Element(canvas, node, parent_style, parent)
{ {
if( !isInit<Group>() ) staticInit();
{
add<Group>(_child_factories);
add<Image>(_child_factories);
add<Map >(_child_factories);
add<Path >(_child_factories);
add<Text >(_child_factories);
}
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------

View File

@ -35,6 +35,7 @@ namespace canvas
{ {
public: public:
static const std::string TYPE_NAME; static const std::string TYPE_NAME;
static void staticInit();
typedef std::list< std::pair< const SGPropertyNode*, typedef std::list< std::pair< const SGPropertyNode*,
ElementPtr ElementPtr

View File

@ -89,6 +89,18 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
const std::string Image::TYPE_NAME = "image"; const std::string Image::TYPE_NAME = "image";
//----------------------------------------------------------------------------
void Image::staticInit()
{
if( isInit<Image>() )
return;
addStyle("fill", "color", &Image::setFill);
addStyle("slice", "", &Image::setSlice);
addStyle("slice-width", "", &Image::setSliceWidth);
addStyle("outset", "", &Image::setOutset);
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
Image::Image( const CanvasWeakPtr& canvas, Image::Image( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node, const SGPropertyNode_ptr& node,
@ -100,6 +112,8 @@ namespace canvas
_src_rect(0,0), _src_rect(0,0),
_region(0,0) _region(0,0)
{ {
staticInit();
_geom = new osg::Geometry; _geom = new osg::Geometry;
_geom->setUseDisplayList(false); _geom->setUseDisplayList(false);
@ -128,16 +142,7 @@ namespace canvas
setDrawable(_geom); setDrawable(_geom);
if( !isInit<Image>() )
{
addStyle("fill", "color", &Image::setFill);
addStyle("slice", "", &Image::setSlice);
addStyle("slice-width", "", &Image::setSliceWidth);
addStyle("outset", "", &Image::setOutset);
}
setFill("#ffffff"); // TODO how should we handle default values? setFill("#ffffff"); // TODO how should we handle default values?
setupStyle(); setupStyle();
} }

View File

@ -35,6 +35,7 @@ namespace canvas
{ {
public: public:
static const std::string TYPE_NAME; static const std::string TYPE_NAME;
static void staticInit();
/** /**
* @param node Property node containing settings for this image: * @param node Property node containing settings for this image:

View File

@ -46,6 +46,17 @@ namespace canvas
const std::string GEO = "-geo"; const std::string GEO = "-geo";
const std::string Map::TYPE_NAME = "map"; const std::string Map::TYPE_NAME = "map";
//----------------------------------------------------------------------------
void Map::staticInit()
{
Group::staticInit();
if( isInit<Map>() )
return;
// Do some initialization if needed...
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
Map::Map( const CanvasWeakPtr& canvas, Map::Map( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node, const SGPropertyNode_ptr& node,
@ -56,7 +67,7 @@ namespace canvas
_projection(new SansonFlamsteedProjection), _projection(new SansonFlamsteedProjection),
_projection_dirty(true) _projection_dirty(true)
{ {
staticInit();
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------

View File

@ -36,6 +36,7 @@ namespace canvas
{ {
public: public:
static const std::string TYPE_NAME; static const std::string TYPE_NAME;
static void staticInit();
Map( const CanvasWeakPtr& canvas, Map( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node, const SGPropertyNode_ptr& node,

View File

@ -472,6 +472,22 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
const std::string Path::TYPE_NAME = "path"; const std::string Path::TYPE_NAME = "path";
//----------------------------------------------------------------------------
void Path::staticInit()
{
if( isInit<Path>() )
return;
PathDrawableRef Path::*path = &Path::_path;
addStyle("fill", "color", &PathDrawable::setFill, path);
addStyle("fill-rule", "", &PathDrawable::setFillRule, path);
addStyle("stroke", "color", &PathDrawable::setStroke, path);
addStyle("stroke-width", "numeric", &PathDrawable::setStrokeWidth, path);
addStyle("stroke-dasharray", "", &PathDrawable::setStrokeDashArray, path);
addStyle("stroke-linecap", "", &PathDrawable::setStrokeLinecap, path);
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
Path::Path( const CanvasWeakPtr& canvas, Path::Path( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node, const SGPropertyNode_ptr& node,
@ -480,20 +496,9 @@ namespace canvas
Element(canvas, node, parent_style, parent), Element(canvas, node, parent_style, parent),
_path( new PathDrawable(this) ) _path( new PathDrawable(this) )
{ {
staticInit();
setDrawable(_path); setDrawable(_path);
if( !isInit<Path>() )
{
PathDrawableRef Path::*path = &Path::_path;
addStyle("fill", "color", &PathDrawable::setFill, path);
addStyle("fill-rule", "", &PathDrawable::setFillRule, path);
addStyle("stroke", "color", &PathDrawable::setStroke, path);
addStyle("stroke-width", "numeric", &PathDrawable::setStrokeWidth, path);
addStyle("stroke-dasharray", "", &PathDrawable::setStrokeDashArray, path);
addStyle("stroke-linecap", "", &PathDrawable::setStrokeLinecap, path);
}
setupStyle(); setupStyle();
} }

View File

@ -31,6 +31,7 @@ namespace canvas
{ {
public: public:
static const std::string TYPE_NAME; static const std::string TYPE_NAME;
static void staticInit();
Path( const CanvasWeakPtr& canvas, Path( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node, const SGPropertyNode_ptr& node,

View File

@ -261,6 +261,39 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
const std::string Text::TYPE_NAME = "text"; const std::string Text::TYPE_NAME = "text";
//----------------------------------------------------------------------------
void Text::staticInit()
{
if( isInit<Text>() )
return;
osg::ref_ptr<TextOSG> Text::*text = &Text::_text;
addStyle("fill", "color", &TextOSG::setFill, text);
addStyle("background", "color", &TextOSG::setBackgroundColor, text);
addStyle("character-size",
"numeric",
static_cast<
void (TextOSG::*)(float)
> (&TextOSG::setCharacterSize),
text);
addStyle("character-aspect-ratio",
"numeric",
&TextOSG::setCharacterAspect, text);
addStyle("line-height", "numeric", &TextOSG::setLineHeight, text);
addStyle("font-resolution", "numeric", &TextOSG::setFontResolution, text);
addStyle("padding", "numeric", &TextOSG::setBoundingBoxMargin, text);
// TEXT = 1 default
// BOUNDINGBOX = 2
// FILLEDBOUNDINGBOX = 4
// ALIGNMENT = 8
addStyle<int>("draw-mode", "", &TextOSG::setDrawMode, text);
addStyle("max-width", "numeric", &TextOSG::setMaximumWidth, text);
addStyle("font", "", &Text::setFont);
addStyle("alignment", "", &Text::setAlignment);
addStyle("text", "", &Text::setText, false);
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
Text::Text( const CanvasWeakPtr& canvas, Text::Text( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node, const SGPropertyNode_ptr& node,
@ -269,40 +302,13 @@ namespace canvas
Element(canvas, node, parent_style, parent), Element(canvas, node, parent_style, parent),
_text( new Text::TextOSG(this) ) _text( new Text::TextOSG(this) )
{ {
staticInit();
setDrawable(_text); setDrawable(_text);
_text->setCharacterSizeMode(osgText::Text::OBJECT_COORDS); _text->setCharacterSizeMode(osgText::Text::OBJECT_COORDS);
_text->setAxisAlignment(osgText::Text::USER_DEFINED_ROTATION); _text->setAxisAlignment(osgText::Text::USER_DEFINED_ROTATION);
_text->setRotation(osg::Quat(osg::PI, osg::X_AXIS)); _text->setRotation(osg::Quat(osg::PI, osg::X_AXIS));
if( !isInit<Text>() )
{
osg::ref_ptr<TextOSG> Text::*text = &Text::_text;
addStyle("fill", "color", &TextOSG::setFill, text);
addStyle("background", "color", &TextOSG::setBackgroundColor, text);
addStyle("character-size",
"numeric",
static_cast<
void (TextOSG::*)(float)
> (&TextOSG::setCharacterSize),
text);
addStyle("character-aspect-ratio",
"numeric",
&TextOSG::setCharacterAspect, text);
addStyle("line-height", "numeric", &TextOSG::setLineHeight, text);
addStyle("font-resolution", "numeric", &TextOSG::setFontResolution, text);
addStyle("padding", "numeric", &TextOSG::setBoundingBoxMargin, text);
// TEXT = 1 default
// BOUNDINGBOX = 2
// FILLEDBOUNDINGBOX = 4
// ALIGNMENT = 8
addStyle<int>("draw-mode", "", &TextOSG::setDrawMode, text);
addStyle("max-width", "numeric", &TextOSG::setMaximumWidth, text);
addStyle("font", "", &Text::setFont);
addStyle("alignment", "", &Text::setAlignment);
addStyle("text", "", &Text::setText, false);
}
setupStyle(); setupStyle();
} }

View File

@ -34,6 +34,7 @@ namespace canvas
{ {
public: public:
static const std::string TYPE_NAME; static const std::string TYPE_NAME;
static void staticInit();
Text( const CanvasWeakPtr& canvas, Text( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node, const SGPropertyNode_ptr& node,