1
0
Fork 0

Canvas: Image/Window unifying and allow using canvas inside canvas.

- Refactor and unify common functionality of canvas::Window and
   canvas::Image
 - Make canvas::Image actually work
 - Allow using canvases inside canvas::Image
   * Use new canvas:// "protocol" to allow using canvases in
     place of images
 - Prepare for categorizing canvases:
   * Move canvases to /canvas/by-index
   * Later support linking to other nodes in subbranches of
     /canvas
This commit is contained in:
Thomas Geymayer 2012-08-09 14:50:20 +02:00
parent 350d508324
commit 83bbd9e45c
14 changed files with 352 additions and 219 deletions

View file

@ -37,6 +37,7 @@ typedef boost::weak_ptr<PropertyBasedElement> PropertyBasedElementWeakPtr;
namespace canvas
{
class Group;
class Image;
class MouseEvent;
class Placement;

View file

@ -30,7 +30,7 @@ CanvasPtr canvasFactory(SGPropertyNode* node)
//------------------------------------------------------------------------------
CanvasMgr::CanvasMgr():
PropertyBasedMgr("/canvas", "texture", &canvasFactory)
PropertyBasedMgr("/canvas/by-index", "texture", &canvasFactory)
{
Canvas::addPlacementFactory
(
@ -46,11 +46,21 @@ CanvasMgr::CanvasMgr():
}
//------------------------------------------------------------------------------
unsigned int CanvasMgr::getCanvasTexId(size_t index) const
CanvasPtr CanvasMgr::getCanvas(size_t index) const
{
if( index >= _elements.size()
|| !_elements[index] )
return 0;
return CanvasPtr();
return static_cast<Canvas*>(_elements[index].get())->getTexId();
return boost::static_pointer_cast<Canvas>(_elements[index]);
}
//------------------------------------------------------------------------------
unsigned int CanvasMgr::getCanvasTexId(size_t index) const
{
CanvasPtr canvas = getCanvas(index);
if( canvas )
return canvas->getTexId();
else
return 0;
}

View file

@ -19,6 +19,7 @@
#ifndef CANVAS_MGR_H_
#define CANVAS_MGR_H_
#include "canvas_fwd.hpp"
#include "property_based_mgr.hxx"
class CanvasMgr:
@ -27,9 +28,20 @@ class CanvasMgr:
public:
CanvasMgr();
/**
* Get ::Canvas by index
*
* @param index Index of texture node in /canvas/by-index/
*/
CanvasPtr getCanvas(size_t index) const;
/**
* Get OpenGL texture name for given canvas
*
* @deprecated This was only meant to be used by the PUI CanvasWidget
* implementation as PUI can't handle osg::Texture objects.
* Use getCanvas(index)->getTexture() instead.
*
* @param Index of canvas
* @return OpenGL texture name
*/

View file

@ -20,6 +20,8 @@
#include <osgDB/ReadFile>
#include <Canvas/canvas.hxx>
#include <Canvas/canvas_mgr.hxx>
#include <Canvas/property_helper.hxx>
#include <osg/Array>
#include <osg/Geometry>
@ -28,43 +30,80 @@
#include <Main/globals.hxx>
#include <Main/fg_props.hxx>
#include <boost/algorithm/string/predicate.hpp>
/**
* Callback to enable/disable rendering of canvas displayed inside windows or
* other canvases.
*/
class CullCallback:
public osg::Drawable::CullCallback
{
public:
CullCallback(Canvas::CameraCullCallback* camera_cull);
private:
Canvas::CameraCullCallback *_camera_cull;
virtual bool cull( osg::NodeVisitor* nv,
osg::Drawable* drawable,
osg::RenderInfo* renderInfo ) const;
};
//------------------------------------------------------------------------------
CullCallback::CullCallback(Canvas::CameraCullCallback* camera_cull):
_camera_cull( camera_cull )
{
}
//------------------------------------------------------------------------------
bool CullCallback::cull( osg::NodeVisitor* nv,
osg::Drawable* drawable,
osg::RenderInfo* renderInfo ) const
{
_camera_cull->enableRendering();
// TODO check if window/image should be culled
return false;
}
namespace canvas
{
//----------------------------------------------------------------------------
Image::Image(SGPropertyNode_ptr node):
Element(node, COLOR | COLOR_FILL | BOUNDING_BOX),
_texture(new osg::Texture2D)
Element(node, COLOR_FILL | BOUNDING_BOX),
_texture(new osg::Texture2D),
_node_src_rect( node->getNode("source", 0, true) ),
_src_rect(0,0,0,0),
_region(0,0,0,0)
{
_source_rect = node->getChild("source");
_geom = new osg::Geometry;
_geom->setUseDisplayList(false);
osg::StateSet *stateSet = _geom->getOrCreateStateSet();
stateSet->setTextureAttributeAndModes(0, _texture.get());
stateSet->setDataVariance(osg::Object::STATIC);
// allocate arrays for the image
_vertices = new osg::Vec2Array;
_vertices = new osg::Vec3Array(4);
_vertices->setDataVariance(osg::Object::STATIC);
_vertices->reserve(4);
_geom->setVertexArray(_vertices);
_texCoords = new osg::Vec2Array;
_texCoords = new osg::Vec2Array(4);
_texCoords->setDataVariance(osg::Object::STATIC);
_texCoords->reserve(4);
_geom->setTexCoordArray(0, _texCoords);
_colors = new osg::Vec4Array;
_colors = new osg::Vec4Array(4);
_colors->setDataVariance(osg::Object::STATIC);
_geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
_geom->setColorArray(_colors);
osg::DrawArrays* prim = new osg::DrawArrays(osg::PrimitiveSet::QUADS);
prim->set(osg::PrimitiveSet::QUADS, 0, 1);
prim->set(osg::PrimitiveSet::QUADS, 0, 4);
prim->setDataVariance(osg::Object::STATIC);
_geom->addPrimitiveSet(prim);
setDrawable(_geom);
}
@ -79,69 +118,184 @@ namespace canvas
{
Element::update(dt);
if( _attributes_dirty & SRC_RECT ) {
_attributes_dirty &= ~SRC_RECT;
int texWidth = _texture->getTextureWidth();
int texHeight = _texture->getTextureHeight();
double x0 = _source_rect->getDoubleValue("left"),
x1 = _source_rect->getDoubleValue("right"),
y0 = _source_rect->getDoubleValue("top"),
y1 = _source_rect->getDoubleValue("bottom");
double width = x1 - x0, height = y1 - y0;
_vertices->clear();
_vertices->push_back(osg::Vec2(0, 0));
_vertices->push_back(osg::Vec2(width, 0));
_vertices->push_back(osg::Vec2(width, height));
_vertices->push_back(osg::Vec2(0, height));
if( _attributes_dirty & DEST_SIZE )
{
(*_vertices)[0].set(_region.l(), _region.t(), 0);
(*_vertices)[1].set(_region.r(), _region.t(), 0);
(*_vertices)[2].set(_region.r(), _region.b(), 0);
(*_vertices)[3].set(_region.l(), _region.b(), 0);
_vertices->dirty();
double u0 = x0 / texWidth,
u1 = x1 / texWidth,
v0 = y0 / texHeight,
v1 = y1 / texHeight;
_texCoords->clear();
_texCoords->push_back(osg::Vec2(u0, v0));
_texCoords->push_back(osg::Vec2(u1, v0));
_texCoords->push_back(osg::Vec2(u1, v1));
_texCoords->push_back(osg::Vec2(u0, v1));
_texCoords->dirty();
_attributes_dirty &= ~DEST_SIZE;
_geom->dirtyBound();
}
if( _attributes_dirty & SRC_RECT )
{
double u0 = _src_rect.l(),
u1 = _src_rect.r(),
v0 = _src_rect.b(),
v1 = _src_rect.t();
if( !_node_src_rect->getBoolValue("normalized", true) )
{
osg::Texture2D *texture = !_canvas.expired()
? _canvas.lock()->getTexture()
: _texture.get();
int texWidth = texture->getTextureWidth();
int texHeight = texture->getTextureHeight();
u0 /= texWidth;
u1 /= texWidth;
v0 /= texHeight;
v1 /= texHeight;
}
(*_texCoords)[0].set(u0, v0);
(*_texCoords)[1].set(u1, v0);
(*_texCoords)[2].set(u1, v1);
(*_texCoords)[3].set(u0, v1);
_texCoords->dirty();
_attributes_dirty &= ~SRC_RECT;
}
}
//----------------------------------------------------------------------------
void Image::setCanvas(CanvasPtr canvas)
{
_canvas = canvas;
_geom->getOrCreateStateSet()
->setTextureAttribute(0, canvas ? canvas->getTexture() : 0);
_geom->setCullCallback(
canvas ? new CullCallback(canvas->getCameraCullCallback()) : 0
);
}
//----------------------------------------------------------------------------
CanvasWeakPtr Image::getCanvas() const
{
return _canvas;
}
//----------------------------------------------------------------------------
void Image::setImage(osg::Image *img)
{
// remove canvas...
setCanvas( CanvasPtr() );
_texture->setImage(img);
_geom->getOrCreateStateSet()
->setTextureAttributeAndModes(0, _texture);
}
//----------------------------------------------------------------------------
const Rect<float>& Image::getRegion() const
{
return _region;
}
//----------------------------------------------------------------------------
void Image::valueChanged(SGPropertyNode *node)
{
if( node->getParent() == _node_src_rect )
{
_attributes_dirty |= SRC_RECT;
if( node->getNameString() == "left" )
_src_rect.setLeft( node->getFloatValue() );
else if( node->getNameString() == "right" )
_src_rect.setRight( node->getFloatValue() );
else if( node->getNameString() == "top" )
_src_rect.setTop( node->getFloatValue() );
else if( node->getNameString() == "bottom" )
_src_rect.setBottom( node->getFloatValue() );
}
else
Element::valueChanged(node);
}
//----------------------------------------------------------------------------
void Image::childChanged(SGPropertyNode* child)
{
const std::string& name = child->getNameString();
if (_source_rect == child)
_attributes_dirty |= SRC_RECT;
else if (name == "file") {
SGPath tpath = globals->resolve_ressource_path(child->getStringValue());
if (tpath.isNull() || !tpath.exists()) {
SG_LOG(SG_GL, SG_ALERT, "canvas::Image: No such image: " << child->getStringValue());
} else {
_texture->setImage(osgDB::readImageFile(tpath.c_str()));
_attributes_dirty |= SRC_RECT;
if( name == "x" )
{
_region.setX( child->getFloatValue() );
_attributes_dirty |= DEST_SIZE;
}
else if( name == "y" )
{
_region.setY( child->getFloatValue() );
_attributes_dirty |= DEST_SIZE;
}
else if( name == "size" )
{
if( child->getIndex() == 0 )
_region.setWidth( child->getFloatValue() );
else
_region.setHeight( child->getFloatValue() );
_attributes_dirty |= DEST_SIZE;
}
else if( name == "file" )
{
static const std::string CANVAS_PROTOCOL = "canvas://";
const std::string& path = child->getStringValue();
if( boost::starts_with(path, CANVAS_PROTOCOL) )
{
CanvasMgr* canvas_mgr =
dynamic_cast<CanvasMgr*>(globals->get_subsystem("Canvas"));
if( !canvas_mgr )
{
SG_LOG(SG_GL, SG_ALERT, "canvas::Image: Failed to get CanvasMgr");
return;
}
}
}
//----------------------------------------------------------------------------
void Image::colorChanged(const osg::Vec4& color)
{
_colors->clear();
for (int i=0; i<4; ++i) {
_colors->push_back(color);
const SGPropertyNode* canvas_node =
canvas_mgr->getPropertyRoot()
->getParent()
->getNode( path.substr(CANVAS_PROTOCOL.size()) );
if( !canvas_node )
{
SG_LOG(SG_GL, SG_ALERT, "canvas::Image: No such canvas: " << path);
return;
}
// TODO add support for other means of addressing canvases (eg. by
// name)
CanvasPtr canvas = canvas_mgr->getCanvas( canvas_node->getIndex() );
if( !canvas )
{
SG_LOG(SG_GL, SG_ALERT, "canvas::Image: Invalid canvas: " << path);
return;
}
setCanvas(canvas);
}
_colors->dirty();
else
{
SGPath tpath = globals->resolve_ressource_path(path);
if( tpath.isNull() || !tpath.exists() )
{
SG_LOG(SG_GL, SG_ALERT, "canvas::Image: No such image: " << path);
return;
}
setImage( osgDB::readImageFile(tpath.c_str()) );
}
}
}
//----------------------------------------------------------------------------
void Image::colorFillChanged(const osg::Vec4& /*color*/)
void Image::colorFillChanged(const osg::Vec4& color)
{
for( int i = 0; i < 4; ++i )
(*_colors)[i] = color;
_colors->dirty();
}
} // namespace canvas

View file

@ -20,11 +20,8 @@
#define CANVAS_IMAGE_HXX_
#include "element.hxx"
#include <boost/shared_ptr.hpp>
#include <map>
#include <vector>
#include <Canvas/canvas_fwd.hpp>
#include <Canvas/rect.hxx>
#include <osg/Texture2D>
@ -35,33 +32,58 @@ namespace canvas
public Element
{
public:
/**
* @param node Property node containing settings for this image:
* rect/[left/right/top/bottom] Dimensions of source
* rect
* size[0-1] Dimensions of rectangle
* [x,y] Position of rectangle
*/
Image(SGPropertyNode_ptr node);
~Image();
virtual void update(double dt);
void setCanvas(CanvasPtr canvas);
CanvasWeakPtr getCanvas() const;
void setImage(osg::Image *img);
const Rect<float>& getRegion() const;
/**
* Callback for every changed child node
*/
virtual void valueChanged(SGPropertyNode *node);
protected:
enum TextAttributes
enum ImageAttributes
{
SRC_RECT = LAST_ATTRIBUTE << 1, // Source image rectangle
DEST_SIZE = SRC_RECT << 1 // Element size
};
SGPropertyNode_ptr _source_rect,
_dest_rect;
/**
* Callback for changed direct child nodes
*/
virtual void childChanged(SGPropertyNode * child);
virtual void colorChanged(const osg::Vec4& color);
virtual void colorFillChanged(const osg::Vec4& color);
void handleHit(float x, float y);
osg::ref_ptr<osg::Texture2D> _texture;
// TODO optionally forward events to canvas
CanvasWeakPtr _canvas;
osg::Geometry *_geom;
osg::Vec2Array *_vertices;
osg::Vec3Array *_vertices;
osg::Vec2Array *_texCoords;
osg::Vec4Array* _colors;
osg::Vec4Array* _colors;
SGPropertyNode *_node_src_rect;
Rect<float> _src_rect,
_region;
};
} // namespace canvas

View file

@ -226,10 +226,10 @@ namespace canvas
_node->addChangeListener(this);
if( _attributes_used & COLOR )
linkColorNodes("color", _node, _color, osg::Vec4f(0,1,0,1));
linkColorNodes("color", _node, _color, osg::Vec4f(0,0,0,1));
if( _attributes_used & COLOR_FILL )
linkColorNodes("color-fill", _node, _color_fill, osg::Vec4f(1,0,1,1));
linkColorNodes("color-fill", _node, _color_fill, osg::Vec4f(1,1,1,1));
SG_LOG
(

View file

@ -24,6 +24,7 @@
#include <Viewer/CameraGroup.hxx>
#include <Viewer/renderer.hxx>
#include <osg/BlendFunc>
#include <osgViewer/Viewer>
#include <osgGA/GUIEventHandler>
@ -94,7 +95,6 @@ GUIMgr::GUIMgr():
PropertyBasedMgr("/sim/gui/canvas", "window", &windowFactory),
_event_handler( new GUIEventHandler(this) ),
_transform( new osg::MatrixTransform ),
_geode_windows( new osg::Geode ),
_width(_props, "size[0]"),
_height(_props, "size[1]"),
_last_push(-1)
@ -104,18 +104,31 @@ GUIMgr::GUIMgr():
osg::Camera* camera =
flightgear::getGUICamera( flightgear::CameraGroup::getDefault() );
assert(camera);
camera->addChild(_transform);
osg::Viewport* vp = camera->getViewport();
handleResize(vp->x(), vp->y(), vp->width(), vp->height());
_transform->addChild(_geode_windows);
camera->addChild(_transform);
Canvas::addPlacementFactory
(
"window",
boost::bind(&GUIMgr::addPlacement, this, _1, _2)
);
osg::StateSet* stateSet = _transform->getOrCreateStateSet();
stateSet->setDataVariance(osg::Object::STATIC);
stateSet->setRenderBinDetails(1000, "RenderBin");
// speed optimization?
stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
stateSet->setAttribute(new osg::BlendFunc(
osg::BlendFunc::SRC_ALPHA,
osg::BlendFunc::ONE_MINUS_SRC_ALPHA)
);
stateSet->setMode(GL_BLEND, osg::StateAttribute::ON);
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
stateSet->setMode(GL_FOG, osg::StateAttribute::OFF);
stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
}
//------------------------------------------------------------------------------
@ -141,9 +154,9 @@ void GUIMgr::shutdown()
//------------------------------------------------------------------------------
void GUIMgr::elementCreated(PropertyBasedElementPtr element)
{
_geode_windows->addDrawable
_transform->addChild
(
static_cast<canvas::Window*>(element.get())->getDrawable()
static_cast<canvas::Window*>(element.get())->getGroup()
);
}

View file

@ -51,7 +51,6 @@ class GUIMgr:
protected:
osg::ref_ptr<GUIEventHandler> _event_handler;
osg::ref_ptr<osg::MatrixTransform> _transform;
osg::ref_ptr<osg::Geode> _geode_windows;
simgear::PropertyObject<int> _width,
_height;

View file

@ -100,6 +100,12 @@ void PropertyBasedMgr::childRemoved( SGPropertyNode * parent,
_elements[index].reset();
}
//------------------------------------------------------------------------------
const SGPropertyNode* PropertyBasedMgr::getPropertyRoot() const
{
return _props;
}
//------------------------------------------------------------------------------
PropertyBasedMgr::PropertyBasedMgr( const std::string& path_root,
const std::string& name_elements,

View file

@ -43,6 +43,8 @@ class PropertyBasedMgr:
virtual void elementCreated(PropertyBasedElementPtr element) {}
virtual const SGPropertyNode* getPropertyRoot() const;
protected:
typedef boost::function<PropertyBasedElementPtr(SGPropertyNode*)>

View file

@ -49,11 +49,21 @@ namespace canvas
T width() const { return _x2 - _x1; }
T height() const { return _y2 - _y1; }
void setX(T x) { T w = width(); _x1 = x; _x2 = x + w; }
void setY(T y) { T h = height(); _y1 = y; _y2 = y + h; }
void setWidth(T w) { _x2 = _x1 + w; }
void setHeight(T h) { _y2 = _y1 + h; }
T l() const { return _x1; }
T r() const { return _x2; }
T t() const { return _y1; }
T b() const { return _y2; }
void setLeft(T l) { _x1 = l; }
void setRight(T r) { _x2 = r; }
void setTop(T t) { _y1 = t; }
void setBottom(T b) { _y2 = b; }
bool contains(T x, T y) const
{
return _x1 <= x && x <= _x2

View file

@ -19,164 +19,78 @@
#include "window.hxx"
#include <Canvas/canvas.hxx>
#include <osg/BlendFunc>
#include <osg/Geometry>
#include <osg/Texture2D>
#include <osgGA/GUIEventHandler>
#include <boost/foreach.hpp>
/**
* Callback to enable/disable rendering of canvas displayed inside windows
*/
class CullCallback:
public osg::Drawable::CullCallback
{
public:
CullCallback(Canvas::CameraCullCallback* camera_cull);
private:
Canvas::CameraCullCallback *_camera_cull;
virtual bool cull( osg::NodeVisitor* nv,
osg::Drawable* drawable,
osg::RenderInfo* renderInfo ) const;
};
//------------------------------------------------------------------------------
CullCallback::CullCallback(Canvas::CameraCullCallback* camera_cull):
_camera_cull( camera_cull )
{
}
//------------------------------------------------------------------------------
bool CullCallback::cull( osg::NodeVisitor* nv,
osg::Drawable* drawable,
osg::RenderInfo* renderInfo ) const
{
_camera_cull->enableRendering();
return false;
}
namespace canvas
{
//----------------------------------------------------------------------------
Window::Window(SGPropertyNode* node):
PropertyBasedElement(node),
_dirty(true),
_geometry( new osg::Geometry ),
_vertices( new osg::Vec3Array(4) ),
_tex_coords( new osg::Vec2Array(4) ),
_x(node, "x"),
_y(node, "y"),
_width(node, "size[0]"),
_height(node, "size[1]")
_image(node)
{
_x = 50;
_y = 100;
_width = 400;
_height = 300;
// TODO probably better remove default position and size
node->setFloatValue("x", 50);
node->setFloatValue("y", 100);
node->setFloatValue("size[0]", 400);
node->setFloatValue("size[1]", 300);
_geometry->setVertexArray(_vertices);
_geometry->setTexCoordArray(0,_tex_coords);
osg::Vec4Array* colors = new osg::Vec4Array(1);
(*colors)[0].set(1.0f,1.0f,1.0,1.0f);
_geometry->setColorArray(colors);
_geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
_geometry->addPrimitiveSet(
new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4)
);
_geometry->setDataVariance(osg::Object::DYNAMIC);
osg::StateSet* stateSet = _geometry->getOrCreateStateSet();
stateSet->setRenderBinDetails(1000, "RenderBin");
// speed optimization?
stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
stateSet->setAttribute(new osg::BlendFunc(
osg::BlendFunc::SRC_ALPHA,
osg::BlendFunc::ONE_MINUS_SRC_ALPHA)
);
stateSet->setMode(GL_BLEND, osg::StateAttribute::ON);
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
stateSet->setMode(GL_FOG, osg::StateAttribute::OFF);
stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
stateSet->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON);
node->setFloatValue("source/right", 1);
node->setFloatValue("source/bottom", 1);
node->setBoolValue("source/normalized", true);
}
//----------------------------------------------------------------------------
Window::~Window()
{
BOOST_FOREACH(osg::Node* parent, _geometry->getParents())
BOOST_FOREACH(osg::Group* parent, getGroup()->getParents())
{
osg::Geode* geode = dynamic_cast<osg::Geode*>(parent);
if( geode )
geode->removeDrawable(_geometry);
parent->removeChild(getGroup());
}
}
//----------------------------------------------------------------------------
void Window::update(double delta_time_sec)
{
if( !_dirty )
return;
_dirty = false;
_region.set(_x, _y, _width, _height);
int z = 0; // TODO do we need to use z for depth ordering?
(*_vertices)[0].set(_region.l(), _region.t(), z);
(*_vertices)[1].set(_region.r(), _region.t(), z);
(*_vertices)[2].set(_region.r(), _region.b(), z);
(*_vertices)[3].set(_region.l(), _region.b(), z);
float l = 0, t = 1, b = 0, r = 1;
(*_tex_coords)[0].set(l,t);
(*_tex_coords)[1].set(r,t);
(*_tex_coords)[2].set(r,b);
(*_tex_coords)[3].set(l,b);
_geometry->dirtyDisplayList();
_image.update(delta_time_sec);
}
//----------------------------------------------------------------------------
void Window::valueChanged (SGPropertyNode * node)
void Window::valueChanged(SGPropertyNode * node)
{
if( node->getParent() != _node )
return;
_image.valueChanged(node);
}
const std::string& name = node->getNameString();
if( name == "x" || name == "y" || name == "size" )
_dirty = true;
//----------------------------------------------------------------------------
osg::Group* Window::getGroup()
{
return _image.getMatrixTransform();
}
//----------------------------------------------------------------------------
const Rect<float>& Window::getRegion() const
{
return _image.getRegion();
}
//----------------------------------------------------------------------------
void Window::setCanvas(CanvasPtr canvas)
{
_canvas = canvas;
_geometry->getOrCreateStateSet()
->setTextureAttribute(0, canvas ? canvas->getTexture() : 0);
_geometry->dirtyDisplayList();
_geometry->setCullCallback(
canvas ? new CullCallback(canvas->getCameraCullCallback()) : 0
);
_image.setCanvas(canvas);
}
//----------------------------------------------------------------------------
CanvasWeakPtr Window::getCanvas() const
{
return _canvas;
return _image.getCanvas();
}
//----------------------------------------------------------------------------
bool Window::handleMouseEvent(const MouseEvent& event)
{
if( !_canvas.expired() )
return _canvas.lock()->handleMouseEvent(event);
if( !getCanvas().expired() )
return getCanvas().lock()->handleMouseEvent(event);
else
return false;
}

View file

@ -20,7 +20,7 @@
#define CANVAS_WINDOW_HXX_
#include "property_based_element.hxx"
#include "rect.hxx"
#include <Canvas/elements/CanvasImage.hxx>
#include <Canvas/MouseEvent.hxx>
#include <simgear/props/propertyObject.hxx>
@ -40,8 +40,8 @@ namespace canvas
virtual void update(double delta_time_sec);
virtual void valueChanged (SGPropertyNode * node);
osg::Drawable* getDrawable() { return _geometry; }
const Rect<int>& getRegion() const { return _region; }
osg::Group* getGroup();
const Rect<float>& getRegion() const;
void setCanvas(CanvasPtr canvas);
CanvasWeakPtr getCanvas() const;
@ -50,17 +50,7 @@ namespace canvas
protected:
bool _dirty;
osg::ref_ptr<osg::Geometry> _geometry;
osg::ref_ptr<osg::Vec3Array> _vertices;
osg::ref_ptr<osg::Vec2Array> _tex_coords;
simgear::PropertyObject<int> _x, _y,
_width, _height;
Rect<int> _region;
CanvasWeakPtr _canvas;
Image _image;
};
} // namespace canvas

View file

@ -32,7 +32,7 @@ CanvasWidget::CanvasWidget( int x, int y,
}
// Get the first unused canvas slot
SGPropertyNode* canvas_root = fgGetNode("/canvas", true);
SGPropertyNode* canvas_root = fgGetNode("/canvas/by-index", true);
for(int index = 0;; ++index)
{
if( !canvas_root->getChild("texture", index) )