Canvas: Prepare for DOM Level 2 like event model.

This commit is contained in:
Thomas Geymayer
2012-11-27 13:46:48 +01:00
parent 88a35fd162
commit 77946585b1
25 changed files with 598 additions and 87 deletions

View File

@@ -3,6 +3,10 @@ include (SimGearComponent)
set(HEADERS
canvas_fwd.hxx
Canvas.hxx
CanvasEvent.hxx
CanvasEventListener.hxx
CanvasEventTypes.hxx
CanvasEventVisitor.hxx
CanvasMgr.hxx
CanvasPlacement.hxx
CanvasSystemAdapter.hxx
@@ -13,6 +17,10 @@ set(HEADERS
set(SOURCES
Canvas.cxx
Canvas.cxx
CanvasEvent.cxx
CanvasEventListener.cxx
CanvasEventVisitor.cxx
CanvasMgr.cxx
CanvasPlacement.cxx
ODGauge.cxx

View File

@@ -17,6 +17,7 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include "Canvas.hxx"
#include "CanvasEventVisitor.hxx"
#include <simgear/canvas/MouseEvent.hxx>
#include <simgear/canvas/CanvasPlacement.hxx>
#include <simgear/scene/util/parse_color.hxx>
@@ -324,23 +325,31 @@ namespace canvas
}
//----------------------------------------------------------------------------
bool Canvas::handleMouseEvent(const MouseEvent& event)
bool Canvas::handleMouseEvent(const MouseEventPtr& event)
{
_mouse_x = event.x;
_mouse_y = event.y;
_mouse_dx = event.dx;
_mouse_dy = event.dy;
_mouse_button = event.button;
_mouse_state = event.state;
_mouse_mod = event.mod;
_mouse_scroll = event.scroll;
_mouse_x = event->pos.x();
_mouse_y = event->pos.y();
_mouse_dx = event->delta.x();
_mouse_dy = event->delta.y();
_mouse_button = event->button;
_mouse_state = event->state;
_mouse_mod = event->mod;
//_mouse_scroll = event.scroll;
// Always set event type last because all listeners are attached to it
_mouse_event = event.type;
_mouse_event = event->type;
if( _root_group.get() )
return _root_group->handleMouseEvent(event);
else
if( !_root_group.get() )
return false;
EventVisitor visitor( EventVisitor::TRAVERSE_DOWN,
event->getPos(),
event->getDelta() );
if( !_root_group->accept(visitor) )
return false;
// TODO create special events like click/dblclick etc.
return visitor.propagateEvent(event);
}
//----------------------------------------------------------------------------

View File

@@ -112,7 +112,7 @@ namespace canvas
void setViewWidth(int w);
void setViewHeight(int h);
bool handleMouseEvent(const MouseEvent& event);
bool handleMouseEvent(const MouseEventPtr& event);
virtual void childAdded( SGPropertyNode * parent,
SGPropertyNode * child );

View File

@@ -0,0 +1,59 @@
// Canvas Event for event model similar to DOM Level 2 Event Model
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include "CanvasEvent.hxx"
namespace simgear
{
namespace canvas
{
//----------------------------------------------------------------------------
Event::Event():
type(UNKNOWN)
{
}
//----------------------------------------------------------------------------
Event::Type Event::getType() const
{
return type;
}
//----------------------------------------------------------------------------
std::string Event::getTypeString() const
{
switch( type )
{
# define ENUM_MAPPING(name, str) case name: return str;
# include "CanvasEventTypes.hxx"
# undef ENUM_MAPPING
default:
return "unknown";
}
}
//----------------------------------------------------------------------------
ElementWeakPtr Event::getTarget() const
{
return target;
}
} // namespace canvas
} // namespace simgear

View File

@@ -0,0 +1,56 @@
// Canvas Event for event model similar to DOM Level 2 Event Model
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#ifndef CANVAS_EVENT_HXX_
#define CANVAS_EVENT_HXX_
#include "canvas_fwd.hxx"
namespace simgear
{
namespace canvas
{
struct Event
{
public:
enum Type
{
UNKNOWN,
# define ENUM_MAPPING(name, str) name,
# include "CanvasEventTypes.hxx"
# undef ENUM_MAPPING
USER_TYPE ///<! first unused id to be used for user defined types (not
/// implemented yet)
};
Type type;
ElementWeakPtr target;
Event();
Type getType() const;
std::string getTypeString() const;
ElementWeakPtr getTarget() const;
};
} // namespace canvas
} // namespace simgear
#endif /* CANVAS_EVENT_HXX_ */

View File

@@ -0,0 +1,66 @@
// Listener for canvas (GUI) events being passed to a Nasal function/code
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include "CanvasEventListener.hxx"
#include "CanvasSystemAdapter.hxx"
#include <simgear/nasal/nasal.h>
namespace simgear
{
namespace canvas
{
//----------------------------------------------------------------------------
EventListener::EventListener(naRef code, const SystemAdapterPtr& sys_adapter):
_code(code),
_gc_key(-1),
_sys(sys_adapter)
{
assert( sys_adapter );
if( !naIsCode(code)
&& !naIsCCode(code)
&& !naIsFunc(code) )
throw std::runtime_error
(
"canvas::EventListener: invalid function argument"
);
_gc_key = sys_adapter->gcSave(_code);
}
//----------------------------------------------------------------------------
EventListener::~EventListener()
{
assert( !_sys.expired() );
_sys.lock()->gcRelease(_gc_key);
}
//------------------------------------------------------------------------------
void EventListener::call()
{
const size_t num_args = 1;
naRef args[num_args] = {
naNil()
};
_sys.lock()->callMethod(_code, naNil(), num_args, args, naNil());
}
} // namespace canvas
} // namespace simgear

View File

@@ -0,0 +1,48 @@
// Listener for canvas (GUI) events being passed to a Nasal function/code
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#ifndef CANVAS_EVENT_LISTENER_HXX_
#define CANVAS_EVENT_LISTENER_HXX_
#include "canvas_fwd.hxx"
#include <simgear/nasal/naref.h>
namespace simgear
{
namespace canvas
{
class EventListener
{
public:
EventListener( naRef code,
const SystemAdapterPtr& sys_adapter );
~EventListener();
void call();
protected:
naRef _code;
int _gc_key;
SystemAdapterWeakPtr _sys;
};
} // namespace canvas
} // namespace simgear
#endif /* CANVAS_EVENT_LISTENER_HXX_ */

View File

@@ -0,0 +1,31 @@
// Mapping between canvas gui Event types and their names
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#ifndef ENUM_MAPPING
# error "Don't include this file directly!"
#endif
ENUM_MAPPING(MOUSE_DOWN, "mousedown")
ENUM_MAPPING(MOUSE_UP, "mouseup")
ENUM_MAPPING(CLICK, "click")
ENUM_MAPPING(DBL_CLICK, "dblclick")
ENUM_MAPPING(MOUSE_MOVE, "mousemove")
ENUM_MAPPING(MOUSE_OVER, "mouseover")
ENUM_MAPPING(MOUSE_OUT, "mouseout")
ENUM_MAPPING(MOUSE_ENTER, "mouseenter")
ENUM_MAPPING(MOUSE_LEAVE, "mouseleave")

View File

@@ -0,0 +1,113 @@
// Visitor for traversing a canvas element hierarchy similar to the traversal
// of the DOM Level 2 Event Model
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include "CanvasEvent.hxx"
#include "CanvasEventVisitor.hxx"
#include <simgear/canvas/elements/CanvasElement.hxx>
#include <iostream>
namespace simgear
{
namespace canvas
{
//----------------------------------------------------------------------------
EventVisitor::EventVisitor( TraverseMode mode,
const osg::Vec2f& pos,
const osg::Vec2f& delta ):
_traverse_mode( mode )
{
if( mode == TRAVERSE_DOWN )
{
EventTarget target = {0, pos, delta};
_target_path.push_back(target);
}
}
//----------------------------------------------------------------------------
EventVisitor::~EventVisitor()
{
}
//----------------------------------------------------------------------------
bool EventVisitor::traverse(Element& el)
{
if( _traverse_mode == TRAVERSE_UP )
return el.ascend(*this);
else
return el.traverse(*this);
}
//----------------------------------------------------------------------------
bool EventVisitor::apply(Element& el)
{
// We only need to check for hits while traversing down
if( _traverse_mode == TRAVERSE_DOWN )
{
// Transform event to local coordinates
const osg::Matrix& m = el.getMatrixTransform()->getInverseMatrix();
const osg::Vec2f& pos = _target_path.back().local_pos;
const osg::Vec2f local_pos
(
m(0, 0) * pos[0] + m(1, 0) * pos[1] + m(3, 0),
m(0, 1) * pos[0] + m(1, 1) * pos[1] + m(3, 1)
);
if( !el.hitBound(local_pos) )
return false;
const osg::Vec2f& delta = _target_path.back().local_delta;
const osg::Vec2f local_delta
(
m(0, 0) * delta[0] + m(1, 0) * delta[1],
m(0, 1) * delta[0] + m(1, 1) * delta[1]
);
EventTarget target = {&el, local_pos, local_delta};
_target_path.push_back(target);
if( el.traverse(*this) )
return true;
_target_path.pop_back();
return false;
}
else
return el.ascend(*this);
}
//----------------------------------------------------------------------------
bool EventVisitor::propagateEvent(const EventPtr& event)
{
// std::cout << "Propagate event " << event->getTypeString() << "\n";
// for( EventTargets::iterator it = _target_path.begin();
// it != _target_path.end();
// ++it )
// {
// if( it->element )
// std::cout << it->element->getProps()->getPath() << " "
// << "(" << it->local_pos.x() << "|" << it->local_pos.y() << ")\n";
// }
return true;
}
} // namespace canvas
} // namespace simgear

View File

@@ -0,0 +1,67 @@
// Visitor for traversing a canvas element hierarchy similar to the traversal
// of the DOM Level 2 Event Model
//
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#ifndef CANVAS_EVENT_VISITOR_HXX_
#define CANVAS_EVENT_VISITOR_HXX_
#include "canvas_fwd.hxx"
#include <deque>
namespace simgear
{
namespace canvas
{
class EventVisitor
{
public:
enum TraverseMode
{
TRAVERSE_UP,
TRAVERSE_DOWN
};
EventVisitor( TraverseMode mode,
const osg::Vec2f& pos,
const osg::Vec2f& delta );
virtual ~EventVisitor();
virtual bool traverse(Element& el);
virtual bool apply(Element& el);
bool propagateEvent(const EventPtr& event);
protected:
struct EventTarget
{
Element* element;
osg::Vec2f local_pos,
local_delta;
};
typedef std::deque<EventTarget> EventTargets;
EventTargets _target_path;
TraverseMode _traverse_mode;
};
} // namespace canvas
} // namespace simgear
#endif /* CANVAS_EVENTVISITOR_HXX_ */

View File

@@ -48,6 +48,15 @@ namespace canvas
* cleaned up by the garbage collector.
*/
virtual void gcRelease(int key) = 0;
/**
* Call a Nasal function with the given environment and arguments.
*/
virtual naRef callMethod( naRef code,
naRef self,
int argc,
naRef* args,
naRef locals ) = 0;
};
} // namespace canvas

View File

@@ -19,6 +19,7 @@
#ifndef CANVAS_MOUSE_EVENT_HXX_
#define CANVAS_MOUSE_EVENT_HXX_
#include "CanvasEvent.hxx"
#include <osgGA/GUIEventAdapter>
namespace simgear
@@ -26,32 +27,24 @@ namespace simgear
namespace canvas
{
class MouseEvent
struct MouseEvent:
public Event
{
public:
typedef osgGA::GUIEventAdapter::EventType EventType;
typedef osgGA::GUIEventAdapter::ScrollingMotion Scroll;
MouseEvent():
button(-1),
state(-1),
mod(-1)
{}
MouseEvent(EventType type):
type(type),
x(-1), y(-1),
dx(0), dy(0),
button(-1),
state(-1),
mod(-1),
scroll(osgGA::GUIEventAdapter::SCROLL_NONE)
{}
osg::Vec2f getPos() const { return pos; }
osg::Vec3f getPos3() const { return osg::Vec3f(pos, 0); }
osg::Vec2f getDelta() const { return delta; }
osg::Vec2f getPos() const { return osg::Vec2f(x, y); }
osg::Vec3f getPos3() const { return osg::Vec3f(x, y, 0); }
EventType type;
float x, y,
dx, dy;
int button, //<! Button for this event
state, //<! Current button state
mod; //<! Keyboard modifier state
Scroll scroll;
osg::Vec2f pos,
delta;
int button, //<! Button for this event
state, //<! Current button state
mod; //<! Keyboard modifier state
};
} // namespace canvas

View File

@@ -50,15 +50,21 @@ namespace canvas
SG_FWD_DECL(Path)
SG_FWD_DECL(Text)
SG_FWD_DECL(Event)
SG_FWD_DECL(EventListener)
SG_FWD_DECL(MouseEvent)
SG_FWD_DECL(Placement)
SG_FWD_DECL(SystemAdapter)
#undef SG_FWD_DECL
class EventVisitor;
typedef std::map<std::string, const SGPropertyNode*> Style;
typedef ElementPtr (*ElementFactory)( const CanvasWeakPtr&,
const SGPropertyNode_ptr&,
const Style& );
const Style&,
Element* );
typedef osg::ref_ptr<osgText::Font> FontPtr;

View File

@@ -17,6 +17,7 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include "CanvasElement.hxx"
#include <simgear/canvas/CanvasEventVisitor.hxx>
#include <simgear/canvas/MouseEvent.hxx>
#include <osg/Drawable>
@@ -108,6 +109,13 @@ namespace canvas
}
}
//----------------------------------------------------------------------------
naRef Element::addEventListener(const nasal::CallContext& ctx)
{
std::cout << "addEventListener " << _node->getPath() << std::endl;
return naNil();
}
//----------------------------------------------------------------------------
SGConstPropertyNode_ptr Element::getProps() const
{
@@ -121,28 +129,41 @@ namespace canvas
}
//----------------------------------------------------------------------------
bool Element::handleMouseEvent(const MouseEvent& event)
bool Element::accept(EventVisitor& visitor)
{
// Transform event to local coordinates
const osg::Matrixd& m = _transform->getInverseMatrix();
MouseEvent local_event = event;
local_event.x = m(0, 0) * event.x + m(1, 0) * event.y + m(3, 0);
local_event.y = m(0, 1) * event.x + m(1, 1) * event.y + m(3, 1);
return visitor.apply(*this);
}
//----------------------------------------------------------------------------
bool Element::ascend(EventVisitor& visitor)
{
if( _parent )
return _parent->accept(visitor);
return true;
}
//----------------------------------------------------------------------------
bool Element::traverse(EventVisitor& visitor)
{
return true;
}
//----------------------------------------------------------------------------
bool Element::hitBound(const osg::Vec2f& pos) const
{
const osg::Vec3f pos3(pos, 0);
// Drawables have a bounding box...
if( _drawable )
{
if( !_drawable->getBound().contains(local_event.getPos3()) )
if( !_drawable->getBound().contains(pos3) )
return false;
}
// ... for other elements, i.e. groups only a bounding sphere is available
else if( !_transform->getBound().contains(local_event.getPos3()) )
else if( !_transform->getBound().contains(pos3) )
return false;
local_event.dx = m(0, 0) * event.dx + m(1, 0) * event.dy;
local_event.dy = m(0, 1) * event.dx + m(1, 1) * event.dy;
return handleLocalMouseEvent(local_event);
return true;
}
//----------------------------------------------------------------------------
@@ -253,8 +274,10 @@ namespace canvas
//----------------------------------------------------------------------------
Element::Element( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style ):
const Style& parent_style,
Element* parent ):
_canvas( canvas ),
_parent( parent ),
_transform_dirty( false ),
_transform( new osg::MatrixTransform ),
_node( node ),
@@ -273,13 +296,11 @@ namespace canvas
}
//----------------------------------------------------------------------------
bool Element::handleLocalMouseEvent(const MouseEvent& event)
void Element::callListeners(canvas::Event& event)
{
// std::cout << _node->getPath()
// << " local: pos=(" << event.x << "|" << event.y << ") "
// << "d=(" << event.dx << "|" << event.dx << ")"
// << std::endl;
return true;
ListenerMap::iterator listeners = _listener.find(event.getType());
if( listeners == _listener.end() )
return;
}
//----------------------------------------------------------------------------

View File

@@ -20,8 +20,11 @@
#define CANVAS_ELEMENT_HXX_
#include <simgear/canvas/canvas_fwd.hxx>
#include <simgear/canvas/CanvasEvent.hxx>
#include <simgear/props/props.hxx>
#include <simgear/misc/stdint.hxx> // for uint32_t
#include <simgear/nasal/cppbind/Ghost.hxx>
#include <osg/BoundingBox>
#include <osg/MatrixTransform>
@@ -38,7 +41,6 @@ namespace simgear
namespace canvas
{
class MouseEvent;
class Element:
public SGPropertyChangeListener
{
@@ -67,14 +69,17 @@ namespace canvas
*/
virtual void update(double dt);
naRef addEventListener(const nasal::CallContext& ctx);
SGConstPropertyNode_ptr getProps() const;
SGPropertyNode_ptr getProps();
/**
* Handle mouse event (transforms coordinates to local coordinate frame
* and forwards event to #handleLocalMouseEvent)
*/
virtual bool handleMouseEvent(const canvas::MouseEvent& event);
virtual bool accept(EventVisitor& visitor);
virtual bool ascend(EventVisitor& visitor);
virtual bool traverse(EventVisitor& visitor);
virtual bool hitBound(const osg::Vec2f& pos) const;
osg::ref_ptr<osg::MatrixTransform> getMatrixTransform();
@@ -106,6 +111,7 @@ namespace canvas
};
CanvasWeakPtr _canvas;
Element *_parent;
uint32_t _attributes_dirty;
bool _transform_dirty;
@@ -117,9 +123,15 @@ namespace canvas
StyleSetters _style_setters;
std::vector<SGPropertyNode_ptr> _bounding_box;
typedef std::vector<EventListenerPtr> Listener;
typedef std::map<Event::Type, Listener> ListenerMap;
ListenerMap _listener;
Element( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style );
const Style& parent_style,
Element* parent );
template<typename T, class C1, class C2>
Element::StyleSetter
@@ -156,7 +168,7 @@ namespace canvas
return boost::bind(setter, instance, boost::bind(&getValue<T1>, _1));
}
virtual bool handleLocalMouseEvent(const canvas::MouseEvent& event);
void callListeners(canvas::Event& event);
virtual void childAdded(SGPropertyNode * child) {}
virtual void childRemoved(SGPropertyNode * child){}

View File

@@ -21,6 +21,8 @@
#include "CanvasMap.hxx"
#include "CanvasPath.hxx"
#include "CanvasText.hxx"
#include <simgear/canvas/CanvasEventVisitor.hxx>
#include <simgear/canvas/MouseEvent.hxx>
#include <boost/bind.hpp>
#include <boost/foreach.hpp>
@@ -36,16 +38,18 @@ namespace canvas
template<typename T>
ElementPtr createElement( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& style )
const Style& style,
Element* parent )
{
return ElementPtr( new T(canvas, node, style) );
return ElementPtr( new T(canvas, node, style, parent) );
}
//----------------------------------------------------------------------------
Group::Group( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style ):
Element(canvas, node, parent_style)
const Style& parent_style,
Element* parent ):
Element(canvas, node, parent_style, parent)
{
_child_factories["group"] = &createElement<Group>;
_child_factories["image"] = &createElement<Image>;
@@ -91,12 +95,12 @@ namespace canvas
}
//----------------------------------------------------------------------------
bool Group::handleLocalMouseEvent(const canvas::MouseEvent& event)
bool Group::traverse(EventVisitor& visitor)
{
// Iterate in reverse order as last child is displayed on top
BOOST_REVERSE_FOREACH( ChildList::value_type child, _children )
{
if( child.second->handleMouseEvent(event) )
if( child.second->accept(visitor) )
return true;
}
return false;
@@ -112,7 +116,7 @@ namespace canvas
_child_factories.find( child->getNameString() );
if( child_factory != _child_factories.end() )
{
ElementPtr element = child_factory->second(_canvas, child, _style);
ElementPtr element = child_factory->second(_canvas, child, _style, this);
// Add to osg scene graph...
_transform->addChild( element->getMatrixTransform() );

View File

@@ -39,7 +39,8 @@ namespace canvas
Group( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style = Style() );
const Style& parent_style = Style(),
Element* parent = 0 );
virtual ~Group();
ElementPtr createChild( const std::string& type,
@@ -48,6 +49,8 @@ namespace canvas
virtual void update(double dt);
virtual bool traverse(EventVisitor& visitor);
protected:
typedef std::map<std::string, ElementFactory> ChildFactories;
@@ -55,8 +58,6 @@ namespace canvas
ChildFactories _child_factories;
ChildList _children;
virtual bool handleLocalMouseEvent(const canvas::MouseEvent& event);
virtual void childAdded(SGPropertyNode * child);
virtual void childRemoved(SGPropertyNode * child);
virtual void childChanged(SGPropertyNode * child);

View File

@@ -74,8 +74,9 @@ namespace canvas
//----------------------------------------------------------------------------
Image::Image( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style ):
Element(canvas, node, parent_style),
const Style& parent_style,
Element* parent ):
Element(canvas, node, parent_style, parent),
_texture(new osg::Texture2D),
_node_src_rect( node->getNode("source", 0, true) )
{

View File

@@ -43,7 +43,8 @@ namespace canvas
*/
Image( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style );
const Style& parent_style,
Element* parent = 0 );
virtual ~Image();
virtual void update(double dt);

View File

@@ -47,8 +47,9 @@ namespace canvas
//----------------------------------------------------------------------------
Map::Map( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style ):
Group(canvas, node, parent_style),
const Style& parent_style,
Element* parent ):
Group(canvas, node, parent_style, parent),
// TODO make projection configurable
_projection(new SansonFlamsteedProjection),
_projection_dirty(true)

View File

@@ -37,7 +37,8 @@ namespace canvas
public:
Map( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style );
const Style& parent_style,
Element* parent = 0 );
virtual ~Map();
virtual void update(double dt);

View File

@@ -355,8 +355,9 @@ namespace canvas
//----------------------------------------------------------------------------
Path::Path( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style ):
Element(canvas, node, parent_style),
const Style& parent_style,
Element* parent ):
Element(canvas, node, parent_style, parent),
_path( new PathDrawable(this) )
{
setDrawable(_path);

View File

@@ -31,7 +31,8 @@ namespace canvas
public:
Path( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style );
const Style& parent_style,
Element* parent = 0 );
virtual ~Path();
virtual void update(double dt);

View File

@@ -177,8 +177,9 @@ namespace canvas
//----------------------------------------------------------------------------
Text::Text( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style ):
Element(canvas, node, parent_style),
const Style& parent_style,
Element* parent ):
Element(canvas, node, parent_style, parent),
_text( new Text::TextOSG(this) )
{
setDrawable(_text);

View File

@@ -35,7 +35,8 @@ namespace canvas
public:
Text( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style );
const Style& parent_style,
Element* parent = 0 );
~Text();
void setText(const char* text);