Expose character-aspect-ratio and do some clean up
- Fix stupid memory corruption bug - Fix bounding box calculations - Fix docs - Fix text size - Expose setting background color - Expose trigger for updating elements - Untie nodes if deleting according element - Allow deleting canvas, text and group elements - Allow creating groups as children of groups
This commit is contained in:
parent
17ec3278ed
commit
023021a879
14 changed files with 394 additions and 152 deletions
|
@ -2,7 +2,7 @@ Canvas - A 2D Drawing API
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
Author: Thomas Geymayer <admin@tomprogs.at>
|
Author: Thomas Geymayer <admin@tomprogs.at>
|
||||||
Revision: 2012/05/04
|
Revision: 2012/05/18
|
||||||
|
|
||||||
Introduction
|
Introduction
|
||||||
------------
|
------------
|
||||||
|
@ -22,11 +22,11 @@ Creating a canvas
|
||||||
A new canvas can be instantiated by creating a node /canvas/texture[<INDEX>]
|
A new canvas can be instantiated by creating a node /canvas/texture[<INDEX>]
|
||||||
with at least the following children:
|
with at least the following children:
|
||||||
|
|
||||||
<size-x type="int"> The width of the underlying texture
|
<size n="0" type="int"> The width of the underlying texture
|
||||||
<size-y type="int"> The height of the underlying texture
|
<size n="1" type="int"> The height of the underlying texture
|
||||||
|
|
||||||
<view-width type="int"> The width of the canvas
|
<view n="0" type="int"> The width of the canvas
|
||||||
<view-height type="int"> The height of the canvas
|
<view n="1" type="int"> The height of the canvas
|
||||||
|
|
||||||
The dimensions of the canvas are needed to be able to use textures with
|
The dimensions of the canvas are needed to be able to use textures with
|
||||||
different resolutions but use the same units for rendering to the canvas.
|
different resolutions but use the same units for rendering to the canvas.
|
||||||
|
@ -60,6 +60,7 @@ only drawing Text is possible:
|
||||||
<red type="float">
|
<red type="float">
|
||||||
<green type="float">
|
<green type="float">
|
||||||
<blue type="float">
|
<blue type="float">
|
||||||
|
<alpha type="float">
|
||||||
</NAME>
|
</NAME>
|
||||||
|
|
||||||
* Text:
|
* Text:
|
||||||
|
@ -71,7 +72,9 @@ only drawing Text is possible:
|
||||||
2. aircraft-dir
|
2. aircraft-dir
|
||||||
3. $FG_DATA/Fonts
|
3. $FG_DATA/Fonts
|
||||||
4. Default osg font paths
|
4. Default osg font paths
|
||||||
<size type="float"> The font size (default: 32)
|
<character-size type="float"> The font size (default: 32)
|
||||||
|
<character-aspect-ratio type="float"> Ratio between character height and width
|
||||||
|
(default: 1)
|
||||||
<tf> A 3x3 transformation matrix specified by 6 values
|
<tf> A 3x3 transformation matrix specified by 6 values
|
||||||
(child elements <a>, ..., <f>) See
|
(child elements <a>, ..., <f>) See
|
||||||
http://www.w3.org/TR/SVG/coords.html#TransformMatrixDefined
|
http://www.w3.org/TR/SVG/coords.html#TransformMatrixDefined
|
||||||
|
@ -129,17 +132,24 @@ Example
|
||||||
|
|
||||||
<canvas>
|
<canvas>
|
||||||
<texture>
|
<texture>
|
||||||
<size-x type="int">384</size-x>
|
<size n="0" type="int">384</size-x>
|
||||||
<size-y type="int">512</size-y>
|
<size n="1" type="int">512</size-y>
|
||||||
<view-width type="int">768</view-width>
|
<view n="0" type="int">768</view-width>
|
||||||
<view-height type="int">1024</view-height>
|
<view n="1" type="int">1024</view-height>
|
||||||
<mipmapping type="bool">false</mipmapping>
|
<mipmapping type="bool">false</mipmapping>
|
||||||
<coverage-samples type="int">0</coverage-samples>
|
<coverage-samples type="int">0</coverage-samples>
|
||||||
<color-samples type="int">0</color-samples>
|
<color-samples type="int">0</color-samples>
|
||||||
|
<color-background>
|
||||||
|
<red type="float">0</red>
|
||||||
|
<green type="float">0.02</green>
|
||||||
|
<blue type="float">0</blue>
|
||||||
|
<alpha type="float">1</alpha>
|
||||||
|
</color-background>
|
||||||
<group>
|
<group>
|
||||||
<text>
|
<text>
|
||||||
<text type="string">TEST MESSAGE</text>
|
<text type="string">TEST MESSAGE</text>
|
||||||
<font type="string">helvetica_bold.txf</font>
|
<font type="string">helvetica_bold.txf</font>
|
||||||
|
<character-size type="float">40</character-size>
|
||||||
<tf>
|
<tf>
|
||||||
<!-- Translate (18|50) -->
|
<!-- Translate (18|50) -->
|
||||||
<tx>18</tx>
|
<tx>18</tx>
|
||||||
|
|
|
@ -6,6 +6,7 @@ set(SOURCES
|
||||||
elements/element.cxx
|
elements/element.cxx
|
||||||
elements/group.cxx
|
elements/group.cxx
|
||||||
elements/text.cxx
|
elements/text.cxx
|
||||||
|
property_helper.cxx
|
||||||
)
|
)
|
||||||
|
|
||||||
set(HEADERS
|
set(HEADERS
|
||||||
|
@ -14,6 +15,7 @@ set(HEADERS
|
||||||
elements/element.hxx
|
elements/element.hxx
|
||||||
elements/group.hxx
|
elements/group.hxx
|
||||||
elements/text.hxx
|
elements/text.hxx
|
||||||
|
property_helper.hxx
|
||||||
)
|
)
|
||||||
|
|
||||||
flightgear_component(Canvas "${SOURCES}" "${HEADERS}")
|
flightgear_component(Canvas "${SOURCES}" "${HEADERS}")
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include "canvas.hxx"
|
#include "canvas.hxx"
|
||||||
#include "elements/group.hxx"
|
#include "elements/group.hxx"
|
||||||
|
#include <Canvas/property_helper.hxx>
|
||||||
|
|
||||||
#include <osg/Camera>
|
#include <osg/Camera>
|
||||||
#include <osg/Geode>
|
#include <osg/Geode>
|
||||||
|
@ -25,9 +26,6 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
//#include <Main/globals.hxx>
|
|
||||||
//#include <Viewer/renderer.hxx>
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Callback used to disable/enable rendering to the texture if it is not
|
* Callback used to disable/enable rendering to the texture if it is not
|
||||||
|
@ -97,8 +95,9 @@ Canvas::Canvas():
|
||||||
_view_width(-1),
|
_view_width(-1),
|
||||||
_view_height(-1),
|
_view_height(-1),
|
||||||
_status(0),
|
_status(0),
|
||||||
_node(0),
|
_sampling_dirty(false),
|
||||||
_sampling_dirty(false)
|
_color_dirty(true),
|
||||||
|
_node(0)
|
||||||
{
|
{
|
||||||
setStatusFlags(MISSING_SIZE_X | MISSING_SIZE_Y);
|
setStatusFlags(MISSING_SIZE_X | MISSING_SIZE_Y);
|
||||||
|
|
||||||
|
@ -110,7 +109,10 @@ Canvas::Canvas():
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
Canvas::~Canvas()
|
Canvas::~Canvas()
|
||||||
{
|
{
|
||||||
|
clearPlacements();
|
||||||
|
|
||||||
|
unbind();
|
||||||
|
_node = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -122,23 +124,21 @@ int Canvas::getStatus() const
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
void Canvas::reset(SGPropertyNode* node)
|
void Canvas::reset(SGPropertyNode* node)
|
||||||
{
|
{
|
||||||
if( _node )
|
if( node )
|
||||||
{
|
SG_LOG
|
||||||
_node->untie("size[0]");
|
(
|
||||||
_node->untie("size[1]");
|
SG_GL,
|
||||||
_node->untie("view[0]");
|
SG_INFO,
|
||||||
_node->untie("view[1]");
|
"Canvas::reset() texture[" << node->getIndex() << "]"
|
||||||
_node->untie("status");
|
);
|
||||||
_node->untie("status-msg");
|
|
||||||
_node->removeChangeListener(this);
|
|
||||||
_node = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
unbind();
|
||||||
|
|
||||||
|
_node = node;
|
||||||
setStatusFlags(MISSING_SIZE_X | MISSING_SIZE_Y);
|
setStatusFlags(MISSING_SIZE_X | MISSING_SIZE_Y);
|
||||||
|
|
||||||
if( node )
|
if( _node )
|
||||||
{
|
{
|
||||||
_node = node;
|
|
||||||
_node->tie
|
_node->tie
|
||||||
(
|
(
|
||||||
"size[0]",
|
"size[0]",
|
||||||
|
@ -174,6 +174,14 @@ void Canvas::reset(SGPropertyNode* node)
|
||||||
SGRawValueMethods<Canvas, const char*>(*this, &Canvas::getStatusMsg)
|
SGRawValueMethods<Canvas, const char*>(*this, &Canvas::getStatusMsg)
|
||||||
);
|
);
|
||||||
_node->addChangeListener(this);
|
_node->addChangeListener(this);
|
||||||
|
|
||||||
|
canvas::linkColorNodes
|
||||||
|
(
|
||||||
|
"color-background",
|
||||||
|
_node,
|
||||||
|
_color_background,
|
||||||
|
osg::Vec4f(0,0,0,1)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,6 +225,17 @@ void Canvas::update(double delta_time_sec)
|
||||||
);
|
);
|
||||||
_sampling_dirty = false;
|
_sampling_dirty = false;
|
||||||
}
|
}
|
||||||
|
if( _color_dirty )
|
||||||
|
{
|
||||||
|
_texture.getCamera()->setClearColor
|
||||||
|
(
|
||||||
|
osg::Vec4( _color_background[0]->getFloatValue(),
|
||||||
|
_color_background[1]->getFloatValue(),
|
||||||
|
_color_background[2]->getFloatValue(),
|
||||||
|
_color_background[3]->getFloatValue() )
|
||||||
|
);
|
||||||
|
_color_dirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
while( !_dirty_placements.empty() )
|
while( !_dirty_placements.empty() )
|
||||||
{
|
{
|
||||||
|
@ -345,8 +364,6 @@ void Canvas::childAdded( SGPropertyNode * parent,
|
||||||
{
|
{
|
||||||
_dirty_placements.push_back(child);
|
_dirty_placements.push_back(child);
|
||||||
}
|
}
|
||||||
// else
|
|
||||||
// std::cout << "Canvas::childAdded: " << child->getPath() << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -358,15 +375,19 @@ void Canvas::childRemoved( SGPropertyNode * parent,
|
||||||
|
|
||||||
if( child->getNameString() == "placement" )
|
if( child->getNameString() == "placement" )
|
||||||
clearPlacements(child->getIndex());
|
clearPlacements(child->getIndex());
|
||||||
else
|
|
||||||
std::cout << "Canvas::childRemoved: " << child->getPath() << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void Canvas::valueChanged(SGPropertyNode * node)
|
void Canvas::valueChanged(SGPropertyNode * node)
|
||||||
{
|
{
|
||||||
if( node->getParent()->getParent() == _node
|
if( node->getParent()->getParent() == _node )
|
||||||
&& node->getParent()->getNameString() == "placement" )
|
{
|
||||||
|
if( !_color_background.empty()
|
||||||
|
&& _color_background[0]->getParent() == node->getParent() )
|
||||||
|
{
|
||||||
|
_color_dirty = true;
|
||||||
|
}
|
||||||
|
else if( node->getParent()->getNameString() == "placement" )
|
||||||
{
|
{
|
||||||
// prevent double updates...
|
// prevent double updates...
|
||||||
for( size_t i = 0; i < _dirty_placements.size(); ++i )
|
for( size_t i = 0; i < _dirty_placements.size(); ++i )
|
||||||
|
@ -377,6 +398,7 @@ void Canvas::valueChanged(SGPropertyNode * node)
|
||||||
|
|
||||||
_dirty_placements.push_back(node->getParent());
|
_dirty_placements.push_back(node->getParent());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if( node->getParent() == _node )
|
else if( node->getParent() == _node )
|
||||||
{
|
{
|
||||||
if( node->getNameString() == "mipmapping"
|
if( node->getNameString() == "mipmapping"
|
||||||
|
@ -428,3 +450,26 @@ void Canvas::clearPlacements(int index)
|
||||||
parent->removeChild(group);
|
parent->removeChild(group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void Canvas::clearPlacements()
|
||||||
|
{
|
||||||
|
for(size_t i = 0; i < _placements.size(); ++i)
|
||||||
|
clearPlacements(i);
|
||||||
|
_placements.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void Canvas::unbind()
|
||||||
|
{
|
||||||
|
if( !_node )
|
||||||
|
return;
|
||||||
|
|
||||||
|
_node->untie("size[0]");
|
||||||
|
_node->untie("size[1]");
|
||||||
|
_node->untie("view[0]");
|
||||||
|
_node->untie("view[1]");
|
||||||
|
_node->untie("status");
|
||||||
|
_node->untie("status-msg");
|
||||||
|
_node->removeChangeListener(this);
|
||||||
|
}
|
||||||
|
|
|
@ -73,6 +73,9 @@ class Canvas:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
Canvas(const Canvas&); // = delete;
|
||||||
|
Canvas& operator=(const Canvas&); // = delete;
|
||||||
|
|
||||||
int _size_x,
|
int _size_x,
|
||||||
_size_y,
|
_size_y,
|
||||||
_view_width,
|
_view_width,
|
||||||
|
@ -81,10 +84,13 @@ class Canvas:
|
||||||
int _status;
|
int _status;
|
||||||
std::string _status_msg;
|
std::string _status_msg;
|
||||||
|
|
||||||
FGODGauge _texture;
|
bool _sampling_dirty,
|
||||||
SGPropertyNode *_node;
|
_color_dirty;
|
||||||
|
|
||||||
bool _sampling_dirty;
|
FGODGauge _texture;
|
||||||
|
|
||||||
|
SGPropertyNode_ptr _node;
|
||||||
|
std::vector<SGPropertyNode_ptr> _color_background;
|
||||||
|
|
||||||
osg::ref_ptr<osg::NodeCallback> _camera_callback;
|
osg::ref_ptr<osg::NodeCallback> _camera_callback;
|
||||||
osg::ref_ptr<osg::NodeCallback> _cull_callback;
|
osg::ref_ptr<osg::NodeCallback> _cull_callback;
|
||||||
|
@ -96,6 +102,9 @@ class Canvas:
|
||||||
|
|
||||||
void setStatusFlags(unsigned int flags, bool set = true);
|
void setStatusFlags(unsigned int flags, bool set = true);
|
||||||
void clearPlacements(int index);
|
void clearPlacements(int index);
|
||||||
|
void clearPlacements();
|
||||||
|
|
||||||
|
void unbind();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* CANVAS_HXX_ */
|
#endif /* CANVAS_HXX_ */
|
||||||
|
|
|
@ -73,7 +73,8 @@ void CanvasMgr::unbind()
|
||||||
void CanvasMgr::update(double delta_time_sec)
|
void CanvasMgr::update(double delta_time_sec)
|
||||||
{
|
{
|
||||||
for( size_t i = 0; i < _canvases.size(); ++i )
|
for( size_t i = 0; i < _canvases.size(); ++i )
|
||||||
_canvases[i].update(delta_time_sec);
|
if( _canvases[i] )
|
||||||
|
_canvases[i]->update(delta_time_sec);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -85,8 +86,6 @@ void CanvasMgr::childAdded( SGPropertyNode * parent,
|
||||||
|
|
||||||
if( child->getNameString() == "texture" )
|
if( child->getNameString() == "texture" )
|
||||||
textureAdded(child);
|
textureAdded(child);
|
||||||
else
|
|
||||||
std::cout << "CanvasMgr::childAdded: " << child->getPath() << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -96,7 +95,16 @@ void CanvasMgr::childRemoved( SGPropertyNode * parent,
|
||||||
if( parent != _props )
|
if( parent != _props )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::cout << "CanvasMgr::childRemoved: " << child->getPath() << std::endl;
|
if( child->getNameString() == "texture" )
|
||||||
|
{
|
||||||
|
size_t index = child->getIndex();
|
||||||
|
|
||||||
|
if( index >= _canvases.size() )
|
||||||
|
SG_LOG(SG_GL, SG_WARN, "can't removed unknown texture[" << index << "]!");
|
||||||
|
else
|
||||||
|
// remove the canvas...
|
||||||
|
_canvases[index].reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -108,17 +116,16 @@ void CanvasMgr::textureAdded(SGPropertyNode* node)
|
||||||
{
|
{
|
||||||
if( index > _canvases.size() )
|
if( index > _canvases.size() )
|
||||||
SG_LOG(SG_GL, SG_WARN, "Skipping unused texture slot(s)!");
|
SG_LOG(SG_GL, SG_WARN, "Skipping unused texture slot(s)!");
|
||||||
SG_LOG(SG_GL, SG_INFO, "Add new texture[" << index << "]");
|
|
||||||
|
|
||||||
_canvases.resize(index + 1);
|
_canvases.resize(index + 1);
|
||||||
_canvases[index];
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SG_LOG(SG_GL, SG_WARN, "texture[" << index << "] already exists!");
|
SG_LOG(SG_GL, SG_WARN, "texture[" << index << "] already exists!");
|
||||||
}
|
}
|
||||||
|
|
||||||
_canvases[index].reset(node);
|
_canvases[index].reset( new Canvas() );
|
||||||
|
_canvases[index]->reset(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -132,13 +139,3 @@ void CanvasMgr::triggerChangeRecursive(SGPropertyNode* node)
|
||||||
for( int i = 0; i < node->nChildren(); ++i )
|
for( int i = 0; i < node->nChildren(); ++i )
|
||||||
triggerChangeRecursive( node->getChild(i) );
|
triggerChangeRecursive( node->getChild(i) );
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
template<class T>
|
|
||||||
T CanvasMgr::getParam(const SGPropertyNode* node, const char* prop)
|
|
||||||
{
|
|
||||||
const SGPropertyNode* child = node->getChild(prop);
|
|
||||||
if( !child )
|
|
||||||
throw std::runtime_error(std::string("Missing property ") + prop);
|
|
||||||
return getValue<T>(child);
|
|
||||||
}
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class Canvas;
|
class Canvas;
|
||||||
|
typedef boost::shared_ptr<Canvas> CanvasPtr;
|
||||||
|
|
||||||
class CanvasMgr:
|
class CanvasMgr:
|
||||||
public SGSubsystem,
|
public SGSubsystem,
|
||||||
|
@ -55,7 +56,7 @@ class CanvasMgr:
|
||||||
SGPropertyNode_ptr _props;
|
SGPropertyNode_ptr _props;
|
||||||
|
|
||||||
/** The actual canvases */
|
/** The actual canvases */
|
||||||
std::vector<Canvas> _canvases;
|
std::vector<CanvasPtr> _canvases;
|
||||||
|
|
||||||
void textureAdded(SGPropertyNode* node);
|
void textureAdded(SGPropertyNode* node);
|
||||||
|
|
||||||
|
@ -65,12 +66,6 @@ class CanvasMgr:
|
||||||
*/
|
*/
|
||||||
void triggerChangeRecursive(SGPropertyNode* node);
|
void triggerChangeRecursive(SGPropertyNode* node);
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the value of a property or throw an exception if it doesn't exist.
|
|
||||||
*/
|
|
||||||
template<class T>
|
|
||||||
T getParam(const SGPropertyNode* node, const char* prop);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* CANVAS_MGR_H_ */
|
#endif /* CANVAS_MGR_H_ */
|
||||||
|
|
|
@ -17,10 +17,13 @@
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
#include "element.hxx"
|
#include "element.hxx"
|
||||||
#include <cassert>
|
#include <Canvas/property_helper.hxx>
|
||||||
|
|
||||||
#include <osg/Drawable>
|
#include <osg/Drawable>
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
namespace canvas
|
namespace canvas
|
||||||
{
|
{
|
||||||
const std::string NAME_TRANSFORM = "tf";
|
const std::string NAME_TRANSFORM = "tf";
|
||||||
|
@ -33,12 +36,6 @@ namespace canvas
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
SGPropertyNode* Element::getPropertyNode()
|
|
||||||
{
|
|
||||||
return _node;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void Element::update(double dt)
|
void Element::update(double dt)
|
||||||
{
|
{
|
||||||
|
@ -97,7 +94,7 @@ namespace canvas
|
||||||
colorChanged( osg::Vec4( _color[0]->getFloatValue(),
|
colorChanged( osg::Vec4( _color[0]->getFloatValue(),
|
||||||
_color[1]->getFloatValue(),
|
_color[1]->getFloatValue(),
|
||||||
_color[2]->getFloatValue(),
|
_color[2]->getFloatValue(),
|
||||||
1 ) );
|
_color[3]->getFloatValue() ) );
|
||||||
_attributes_dirty &= ~COLOR;
|
_attributes_dirty &= ~COLOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,18 +103,19 @@ namespace canvas
|
||||||
colorFillChanged( osg::Vec4( _color_fill[0]->getFloatValue(),
|
colorFillChanged( osg::Vec4( _color_fill[0]->getFloatValue(),
|
||||||
_color_fill[1]->getFloatValue(),
|
_color_fill[1]->getFloatValue(),
|
||||||
_color_fill[2]->getFloatValue(),
|
_color_fill[2]->getFloatValue(),
|
||||||
1 ) );
|
_color_fill[3]->getFloatValue() ) );
|
||||||
_attributes_dirty &= ~COLOR_FILL;
|
_attributes_dirty &= ~COLOR_FILL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( _drawable && (_attributes_dirty & BOUNDING_BOX) )
|
if( !_bounding_box.empty() )
|
||||||
{
|
{
|
||||||
_bounding_box[0]->setFloatValue(_drawable->getBound()._min.x());
|
assert( _drawable );
|
||||||
_bounding_box[1]->setFloatValue(_drawable->getBound()._min.y());
|
|
||||||
_bounding_box[2]->setFloatValue(_drawable->getBound()._max.x());
|
|
||||||
_bounding_box[3]->setFloatValue(_drawable->getBound()._max.y());
|
|
||||||
|
|
||||||
_attributes_dirty &= ~BOUNDING_BOX;
|
const osg::BoundingBox& bb = _drawable->getBound();
|
||||||
|
_bounding_box[0]->setFloatValue(bb._min.x());
|
||||||
|
_bounding_box[1]->setFloatValue(bb._min.y());
|
||||||
|
_bounding_box[2]->setFloatValue(bb._max.x());
|
||||||
|
_bounding_box[3]->setFloatValue(bb._max.y());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,29 +126,22 @@ namespace canvas
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
Element::Element(SGPropertyNode* node, uint32_t attributes_used):
|
Element::Element(SGPropertyNode_ptr node, uint32_t attributes_used):
|
||||||
_node( node ),
|
|
||||||
_drawable( 0 ),
|
|
||||||
_attributes_used( attributes_used ),
|
_attributes_used( attributes_used ),
|
||||||
_attributes_dirty( 0 ),
|
_attributes_dirty( attributes_used ),
|
||||||
_transform_dirty( false ),
|
_transform_dirty( false ),
|
||||||
_transform( new osg::MatrixTransform )
|
_transform( new osg::MatrixTransform ),
|
||||||
|
_node( node ),
|
||||||
|
_drawable( 0 )
|
||||||
{
|
{
|
||||||
assert( _node );
|
assert( _node );
|
||||||
_node->addChangeListener(this);
|
_node->addChangeListener(this);
|
||||||
|
|
||||||
if( _attributes_used & COLOR )
|
if( _attributes_used & COLOR )
|
||||||
linkColorNodes("color", _color, osg::Vec4f(0,1,0,1));
|
linkColorNodes("color", _node, _color, osg::Vec4f(0,1,0,1));
|
||||||
|
|
||||||
if( _attributes_used & COLOR_FILL )
|
if( _attributes_used & COLOR_FILL )
|
||||||
linkColorNodes("color-fill", _color_fill);
|
linkColorNodes("color-fill", _node, _color_fill);
|
||||||
if( _attributes_used & BOUNDING_BOX )
|
|
||||||
{
|
|
||||||
SGPropertyNode* bb = _node->getChild("bounding-box", 0, true);
|
|
||||||
_bounding_box[0] = bb->getChild("x-min", 0, true);
|
|
||||||
_bounding_box[1] = bb->getChild("y-min", 0, true);
|
|
||||||
_bounding_box[2] = bb->getChild("x-max", 0, true);
|
|
||||||
_bounding_box[3] = bb->getChild("y-max", 0, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
SG_LOG
|
SG_LOG
|
||||||
(
|
(
|
||||||
|
@ -161,22 +152,19 @@ namespace canvas
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void Element::linkColorNodes( const char* name,
|
void Element::setDrawable( osg::Drawable* drawable )
|
||||||
SGPropertyNode** nodes,
|
|
||||||
const osg::Vec4& def )
|
|
||||||
{
|
{
|
||||||
// Don't tie to allow the usage of aliases
|
_drawable = drawable;
|
||||||
SGPropertyNode* color = _node->getChild(name, 0, true);
|
assert( _drawable );
|
||||||
|
|
||||||
static const char* color_names[] = {"red", "green", "blue"};
|
if( _attributes_used & BOUNDING_BOX )
|
||||||
for( size_t i = 0; i < sizeof(color_names)/sizeof(color_names[0]); ++i )
|
|
||||||
{
|
{
|
||||||
color->setFloatValue
|
SGPropertyNode* bb_node = _node->getChild("bounding-box", 0, true);
|
||||||
(
|
_bounding_box.resize(4);
|
||||||
color_names[i],
|
_bounding_box[0] = bb_node->getChild("min-x", 0, true);
|
||||||
color->getFloatValue(color_names[i], def[i])
|
_bounding_box[1] = bb_node->getChild("min-y", 0, true);
|
||||||
);
|
_bounding_box[2] = bb_node->getChild("max-x", 0, true);
|
||||||
nodes[i] = color->getChild(color_names[i]);
|
_bounding_box[3] = bb_node->getChild("max-y", 0, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,13 +242,18 @@ namespace canvas
|
||||||
{
|
{
|
||||||
if( parent->getNameString() == NAME_TRANSFORM )
|
if( parent->getNameString() == NAME_TRANSFORM )
|
||||||
_transform_dirty = true;
|
_transform_dirty = true;
|
||||||
else if( parent->getNameString() == NAME_COLOR )
|
else if( !_color.empty() && _color[0]->getParent() == parent )
|
||||||
_attributes_dirty |= COLOR;
|
_attributes_dirty |= COLOR;
|
||||||
else if( parent->getNameString() == NAME_COLOR_FILL )
|
else if( !_color_fill.empty() && _color_fill[0]->getParent() == parent )
|
||||||
_attributes_dirty |= COLOR_FILL;
|
_attributes_dirty |= COLOR_FILL;
|
||||||
}
|
}
|
||||||
|
else if( parent == _node )
|
||||||
|
{
|
||||||
|
if( child->getNameString() == "update" )
|
||||||
|
update(0);
|
||||||
else
|
else
|
||||||
childChanged(child);
|
childChanged(child);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace canvas
|
} // namespace canvas
|
||||||
|
|
|
@ -36,7 +36,6 @@ namespace canvas
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Element() = 0;
|
virtual ~Element() = 0;
|
||||||
SGPropertyNode* getPropertyNode();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called every frame to update internal state
|
* Called every frame to update internal state
|
||||||
|
@ -53,7 +52,8 @@ namespace canvas
|
||||||
{
|
{
|
||||||
COLOR = 0x0001,
|
COLOR = 0x0001,
|
||||||
COLOR_FILL = 0x0002,
|
COLOR_FILL = 0x0002,
|
||||||
BOUNDING_BOX = 0x0004
|
BOUNDING_BOX = 0x0004,
|
||||||
|
LAST_ATTRIBUTE = BOUNDING_BOX
|
||||||
};
|
};
|
||||||
|
|
||||||
enum TransformType
|
enum TransformType
|
||||||
|
@ -65,9 +65,6 @@ namespace canvas
|
||||||
TT_SCALE
|
TT_SCALE
|
||||||
};
|
};
|
||||||
|
|
||||||
SGPropertyNode *_node;
|
|
||||||
osg::Drawable *_drawable;
|
|
||||||
|
|
||||||
uint32_t _attributes_used;
|
uint32_t _attributes_used;
|
||||||
uint32_t _attributes_dirty;
|
uint32_t _attributes_dirty;
|
||||||
|
|
||||||
|
@ -75,11 +72,12 @@ namespace canvas
|
||||||
osg::ref_ptr<osg::MatrixTransform> _transform;
|
osg::ref_ptr<osg::MatrixTransform> _transform;
|
||||||
std::vector<TransformType> _transform_types;
|
std::vector<TransformType> _transform_types;
|
||||||
|
|
||||||
SGPropertyNode *_bounding_box[4]; ///<! x-min, y-min, x-max, y-max
|
SGPropertyNode_ptr _node;
|
||||||
SGPropertyNode *_color[3];
|
std::vector<SGPropertyNode_ptr> _color,
|
||||||
SGPropertyNode *_color_fill[3];
|
_color_fill;
|
||||||
|
std::vector<SGPropertyNode_ptr> _bounding_box;
|
||||||
|
|
||||||
Element(SGPropertyNode* node, uint32_t attributes_used = 0);
|
Element(SGPropertyNode_ptr node, uint32_t attributes_used = 0);
|
||||||
|
|
||||||
virtual void childAdded(SGPropertyNode * child) {}
|
virtual void childAdded(SGPropertyNode * child) {}
|
||||||
virtual void childRemoved(SGPropertyNode * child){}
|
virtual void childRemoved(SGPropertyNode * child){}
|
||||||
|
@ -88,11 +86,12 @@ namespace canvas
|
||||||
virtual void colorChanged(const osg::Vec4& color) {}
|
virtual void colorChanged(const osg::Vec4& color) {}
|
||||||
virtual void colorFillChanged(const osg::Vec4& color){}
|
virtual void colorFillChanged(const osg::Vec4& color){}
|
||||||
|
|
||||||
void linkColorNodes( const char* name,
|
void setDrawable( osg::Drawable* drawable );
|
||||||
SGPropertyNode** nodes,
|
|
||||||
const osg::Vec4& def = osg::Vec4(1,1,0,1) );
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
osg::Drawable *_drawable;
|
||||||
|
|
||||||
Element(const Element&);// = delete
|
Element(const Element&);// = delete
|
||||||
|
|
||||||
virtual void childAdded( SGPropertyNode * parent,
|
virtual void childAdded( SGPropertyNode * parent,
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace canvas
|
||||||
{
|
{
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
Group::Group(SGPropertyNode* node):
|
Group::Group(SGPropertyNode_ptr node):
|
||||||
Element(node)
|
Element(node)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -39,7 +39,10 @@ namespace canvas
|
||||||
void Group::update(double dt)
|
void Group::update(double dt)
|
||||||
{
|
{
|
||||||
for( size_t i = 0; i < _children.size(); ++i )
|
for( size_t i = 0; i < _children.size(); ++i )
|
||||||
|
{
|
||||||
|
if( _children[i] )
|
||||||
_children[i]->update(dt);
|
_children[i]->update(dt);
|
||||||
|
}
|
||||||
|
|
||||||
Element::update(dt);
|
Element::update(dt);
|
||||||
}
|
}
|
||||||
|
@ -47,19 +50,58 @@ namespace canvas
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void Group::childAdded(SGPropertyNode* child)
|
void Group::childAdded(SGPropertyNode* child)
|
||||||
{
|
{
|
||||||
|
boost::shared_ptr<Element> element;
|
||||||
|
|
||||||
if( child->getNameString() == "text" )
|
if( child->getNameString() == "text" )
|
||||||
{
|
element.reset( new Text(child) );
|
||||||
_children.push_back( boost::shared_ptr<Element>(new Text(child)) );
|
else if( child->getNameString() == "group" )
|
||||||
_transform->addChild( _children.back()->getMatrixTransform() );
|
element.reset( new Group(child) );
|
||||||
}
|
|
||||||
else
|
else
|
||||||
std::cout << "New unknown child: " << child->getDisplayName() << std::endl;
|
SG_LOG
|
||||||
|
(
|
||||||
|
SG_GL,
|
||||||
|
SG_WARN,
|
||||||
|
"canvas::Group unknown child: " << child->getDisplayName()
|
||||||
|
);
|
||||||
|
|
||||||
|
if( !element )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Add to osg scene graph...
|
||||||
|
_transform->addChild( element->getMatrixTransform() );
|
||||||
|
|
||||||
|
// ...and build up canvas hierarchy
|
||||||
|
size_t index = child->getIndex();
|
||||||
|
|
||||||
|
if( index >= _children.size() )
|
||||||
|
_children.resize(index + 1);
|
||||||
|
|
||||||
|
_children[index] = element;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void Group::childRemoved(SGPropertyNode* child)
|
void Group::childRemoved(SGPropertyNode* child)
|
||||||
{
|
{
|
||||||
|
if( child->getNameString() == "text"
|
||||||
|
|| child->getNameString() == "group" )
|
||||||
|
{
|
||||||
|
size_t index = child->getIndex();
|
||||||
|
|
||||||
|
if( index >= _children.size() )
|
||||||
|
SG_LOG
|
||||||
|
(
|
||||||
|
SG_GL,
|
||||||
|
SG_WARN,
|
||||||
|
"can't removed unknown child " << child->getDisplayName()
|
||||||
|
);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
boost::shared_ptr<Element>& element = _children[index];
|
||||||
|
if( element )
|
||||||
|
_transform->removeChild(element->getMatrixTransform());
|
||||||
|
element.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace canvas
|
} // namespace canvas
|
||||||
|
|
|
@ -26,17 +26,19 @@
|
||||||
namespace canvas
|
namespace canvas
|
||||||
{
|
{
|
||||||
|
|
||||||
|
typedef boost::shared_ptr<Element> ElementPtr;
|
||||||
|
|
||||||
class Group:
|
class Group:
|
||||||
public Element
|
public Element
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Group(SGPropertyNode* node);
|
Group(SGPropertyNode_ptr node);
|
||||||
virtual ~Group();
|
virtual ~Group();
|
||||||
|
|
||||||
virtual void update(double dt);
|
virtual void update(double dt);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::vector<boost::shared_ptr<Element> > _children;
|
std::vector<ElementPtr> _children;
|
||||||
|
|
||||||
virtual void childAdded(SGPropertyNode * child);
|
virtual void childAdded(SGPropertyNode * child);
|
||||||
virtual void childRemoved(SGPropertyNode * child);
|
virtual void childRemoved(SGPropertyNode * child);
|
||||||
|
|
|
@ -17,26 +17,30 @@
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
#include "text.hxx"
|
#include "text.hxx"
|
||||||
#include <osgText/Text>
|
#include <Canvas/property_helper.hxx>
|
||||||
|
|
||||||
#include <Main/globals.hxx>
|
#include <Main/globals.hxx>
|
||||||
#include <Main/fg_props.hxx>
|
#include <Main/fg_props.hxx>
|
||||||
|
|
||||||
|
#include <osgText/Text>
|
||||||
|
|
||||||
namespace canvas
|
namespace canvas
|
||||||
{
|
{
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
Text::Text(SGPropertyNode* node):
|
Text::Text(SGPropertyNode_ptr node):
|
||||||
Element(node, COLOR | COLOR_FILL | BOUNDING_BOX),
|
Element(node, COLOR | COLOR_FILL | BOUNDING_BOX),
|
||||||
_text( new osgText::Text )
|
_text( new osgText::Text ),
|
||||||
|
_font_size( 0 ),
|
||||||
|
_font_aspect( 0 )
|
||||||
{
|
{
|
||||||
_drawable = _text;
|
setDrawable(_text);
|
||||||
_text->setCharacterSizeMode(osgText::Text::SCREEN_COORDS);
|
_text->setCharacterSizeMode(osgText::Text::OBJECT_COORDS);
|
||||||
|
_text->setAxisAlignment(osgText::Text::USER_DEFINED_ROTATION);
|
||||||
|
_text->setRotation(osg::Quat(osg::PI, osg::X_AXIS));
|
||||||
|
|
||||||
// font size and property node
|
_font_size = getChildDefault<float>(_node, "character-size", 32);
|
||||||
float character_size = _node->getFloatValue("size", 32);
|
_font_aspect = getChildDefault<float>(_node, "character-aspect-ratio", 1);
|
||||||
_text->setCharacterSize( character_size );
|
|
||||||
_node->setFloatValue("size", character_size);
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
|
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
|
||||||
geode->addDrawable(_text);
|
geode->addDrawable(_text);
|
||||||
|
@ -82,7 +86,30 @@ namespace canvas
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
Text::~Text()
|
Text::~Text()
|
||||||
{
|
{
|
||||||
|
if( _node )
|
||||||
|
{
|
||||||
|
_node->untie("alignment");
|
||||||
|
_node->untie("padding");
|
||||||
|
_node->untie("draw-mode");
|
||||||
|
}
|
||||||
|
_node = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Text::update(double dt)
|
||||||
|
{
|
||||||
|
Element::update(dt);
|
||||||
|
|
||||||
|
if( _attributes_dirty & FONT_SIZE )
|
||||||
|
{
|
||||||
|
_text->setCharacterSize
|
||||||
|
(
|
||||||
|
_font_size->getFloatValue(),
|
||||||
|
_font_aspect->getFloatValue()
|
||||||
|
);
|
||||||
|
|
||||||
|
_attributes_dirty &= ~FONT_SIZE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
@ -123,16 +150,12 @@ namespace canvas
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void Text::childChanged(SGPropertyNode* child)
|
void Text::childChanged(SGPropertyNode* child)
|
||||||
{
|
{
|
||||||
if( child->getNameString() == "text" )
|
if( _font_size == child || _font_aspect == child )
|
||||||
|
_attributes_dirty |= FONT_SIZE;
|
||||||
|
else if( child->getNameString() == "text" )
|
||||||
_text->setText( child->getStringValue() );
|
_text->setText( child->getStringValue() );
|
||||||
else if( child->getNameString() == "size" )
|
|
||||||
_text->setCharacterSize( child->getFloatValue() );
|
|
||||||
else if( child->getNameString() == "font" )
|
else if( child->getNameString() == "font" )
|
||||||
setFont( child->getStringValue() );
|
setFont( child->getStringValue() );
|
||||||
else
|
|
||||||
return;
|
|
||||||
|
|
||||||
_attributes_dirty |= BOUNDING_BOX;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
|
@ -32,17 +32,28 @@ namespace canvas
|
||||||
public Element
|
public Element
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Text(SGPropertyNode* node);
|
Text(SGPropertyNode_ptr node);
|
||||||
virtual ~Text();
|
virtual ~Text();
|
||||||
|
|
||||||
|
virtual void update(double dt);
|
||||||
|
|
||||||
void setFont(const char* name);
|
void setFont(const char* name);
|
||||||
|
|
||||||
void setAlignment(const char* align);
|
void setAlignment(const char* align);
|
||||||
const char* getAlignment() const;
|
const char* getAlignment() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
enum TextAttributes
|
||||||
|
{
|
||||||
|
FONT_SIZE = LAST_ATTRIBUTE << 1, // Font size and aspect ration
|
||||||
|
};
|
||||||
|
|
||||||
osg::ref_ptr<osgText::Text> _text;
|
osg::ref_ptr<osgText::Text> _text;
|
||||||
|
|
||||||
|
SGPropertyNode_ptr _font_size,
|
||||||
|
_font_aspect;
|
||||||
|
|
||||||
virtual void childChanged(SGPropertyNode * child);
|
virtual void childChanged(SGPropertyNode * child);
|
||||||
virtual void colorChanged(const osg::Vec4& color);
|
virtual void colorChanged(const osg::Vec4& color);
|
||||||
virtual void colorFillChanged(const osg::Vec4& color);
|
virtual void colorFillChanged(const osg::Vec4& color);
|
||||||
|
|
47
src/Canvas/property_helper.cxx
Normal file
47
src/Canvas/property_helper.cxx
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
// Some helper functions for accessing the property tree
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#include "property_helper.hxx"
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
namespace canvas
|
||||||
|
{
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void linkColorNodes( const char* name,
|
||||||
|
SGPropertyNode* parent,
|
||||||
|
std::vector<SGPropertyNode_ptr>& nodes,
|
||||||
|
const osg::Vec4& def )
|
||||||
|
{
|
||||||
|
static const char* channels[] = {"red", "green", "blue", "alpha"};
|
||||||
|
static const size_t num_channels = sizeof(channels)/sizeof(channels[0]);
|
||||||
|
|
||||||
|
assert(name);
|
||||||
|
assert(parent);
|
||||||
|
|
||||||
|
// Don't tie to allow the usage of aliases
|
||||||
|
SGPropertyNode_ptr color = parent->getChild(name, 0, true);
|
||||||
|
|
||||||
|
// We need to be carefull do not get any unitialized nodes or null pointers
|
||||||
|
// because while creating the node a valueChanged event will be triggered.
|
||||||
|
nodes.clear();
|
||||||
|
nodes.reserve(num_channels);
|
||||||
|
|
||||||
|
for( size_t i = 0; i < num_channels; ++i )
|
||||||
|
nodes.push_back( getChildDefault(color, channels[i], def[i]) );
|
||||||
|
}
|
||||||
|
}
|
67
src/Canvas/property_helper.hxx
Normal file
67
src/Canvas/property_helper.hxx
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
// Some helper functions for accessing the property tree
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#ifndef PROPERTY_HELPER_HXX_
|
||||||
|
#define PROPERTY_HELPER_HXX_
|
||||||
|
|
||||||
|
#include <simgear/props/props.hxx>
|
||||||
|
#include <osg/Vec4>
|
||||||
|
|
||||||
|
namespace canvas
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get property node with default value
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
SGPropertyNode* getChildDefault( SGPropertyNode* parent,
|
||||||
|
const char* name,
|
||||||
|
T def_val )
|
||||||
|
{
|
||||||
|
SGPropertyNode* node = parent->getNode(name);
|
||||||
|
if( node )
|
||||||
|
// also set value for existing nodes to enforce type...
|
||||||
|
def_val = getValue<T>(node);
|
||||||
|
else
|
||||||
|
node = parent->getChild(name, 0, true);
|
||||||
|
|
||||||
|
setValue(node, def_val);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name Name of color node
|
||||||
|
* @param parent Parent for color channel nodes
|
||||||
|
* @param nodes Vector to push color nodes into
|
||||||
|
* @param def Default color
|
||||||
|
*
|
||||||
|
* <name>
|
||||||
|
* <red type="float">def[0] or existing value</red>
|
||||||
|
* <green type="float">def[1] or existing value</green>
|
||||||
|
* <blue type="float">def[2] or existing value</blue>
|
||||||
|
* <alpha type="float">def[3] or existing value</alpha>
|
||||||
|
* </name>
|
||||||
|
*/
|
||||||
|
void linkColorNodes( const char* name,
|
||||||
|
SGPropertyNode* parent,
|
||||||
|
std::vector<SGPropertyNode_ptr>& nodes,
|
||||||
|
const osg::Vec4& def = osg::Vec4(0,0,0,0) );
|
||||||
|
|
||||||
|
} // namespace canvas
|
||||||
|
|
||||||
|
#endif /* PROPERTY_HELPER_HXX_ */
|
Loading…
Reference in a new issue