set(HEADERS
canvas_fwd.hxx
Canvas.hxx
+ CanvasEvent.hxx
+ CanvasEventListener.hxx
+ CanvasEventTypes.hxx
+ CanvasEventVisitor.hxx
CanvasMgr.hxx
CanvasPlacement.hxx
CanvasSystemAdapter.hxx
set(SOURCES
Canvas.cxx
+ Canvas.cxx
+ CanvasEvent.cxx
+ CanvasEventListener.cxx
+ CanvasEventVisitor.cxx
CanvasMgr.cxx
CanvasPlacement.cxx
ODGauge.cxx
// 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>
}
//----------------------------------------------------------------------------
- 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);
}
//----------------------------------------------------------------------------
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 );
--- /dev/null
+// 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
--- /dev/null
+// 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_ */
--- /dev/null
+// 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
--- /dev/null
+// 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_ */
--- /dev/null
+// 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")
--- /dev/null
+// 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
--- /dev/null
+// 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_ */
* 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
#ifndef CANVAS_MOUSE_EVENT_HXX_
#define CANVAS_MOUSE_EVENT_HXX_
+#include "CanvasEvent.hxx"
#include <osgGA/GUIEventAdapter>
namespace simgear
namespace canvas
{
- class MouseEvent
+ struct MouseEvent:
+ public Event
{
- public:
- typedef osgGA::GUIEventAdapter::EventType EventType;
- typedef osgGA::GUIEventAdapter::ScrollingMotion Scroll;
-
- 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 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;
+ MouseEvent():
+ button(-1),
+ state(-1),
+ mod(-1)
+ {}
+
+ osg::Vec2f getPos() const { return pos; }
+ osg::Vec3f getPos3() const { return osg::Vec3f(pos, 0); }
+ osg::Vec2f getDelta() const { return delta; }
+
+ osg::Vec2f pos,
+ delta;
+ int button, //<! Button for this event
+ state, //<! Current button state
+ mod; //<! Keyboard modifier state
};
} // 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;
// 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>
}
}
+ //----------------------------------------------------------------------------
+ naRef Element::addEventListener(const nasal::CallContext& ctx)
+ {
+ std::cout << "addEventListener " << _node->getPath() << std::endl;
+ return naNil();
+ }
+
//----------------------------------------------------------------------------
SGConstPropertyNode_ptr Element::getProps() const
{
}
//----------------------------------------------------------------------------
- bool Element::handleMouseEvent(const MouseEvent& event)
+ bool Element::accept(EventVisitor& visitor)
+ {
+ return visitor.apply(*this);
+ }
+
+ //----------------------------------------------------------------------------
+ bool Element::ascend(EventVisitor& visitor)
+ {
+ if( _parent )
+ return _parent->accept(visitor);
+ return true;
+ }
+
+ //----------------------------------------------------------------------------
+ bool Element::traverse(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 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;
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
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 ),
}
//----------------------------------------------------------------------------
- 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;
}
//----------------------------------------------------------------------------
#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>
namespace canvas
{
- class MouseEvent;
class Element:
public SGPropertyChangeListener
{
*/
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();
};
CanvasWeakPtr _canvas;
+ Element *_parent;
uint32_t _attributes_dirty;
bool _transform_dirty;
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
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){}
#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>
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>;
}
//----------------------------------------------------------------------------
- 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;
_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() );
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,
virtual void update(double dt);
+ virtual bool traverse(EventVisitor& visitor);
+
protected:
typedef std::map<std::string, ElementFactory> ChildFactories;
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);
//----------------------------------------------------------------------------
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) )
{
*/
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);
//----------------------------------------------------------------------------
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)
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);
//----------------------------------------------------------------------------
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);
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);
//----------------------------------------------------------------------------
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);
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);