// (eg. removed by another event handler)
continue;
- // TODO provide functions to convert position and delta to local
- // coordinates on demand. Events shouldn't contain informations in
- // local coordinates as they might differe between different elements
- // receiving the same event.
-// if( mouse_event && event->type != Event::DRAG )
-// {
-// // TODO transform pos and delta for drag events. Maybe we should just
-// // store the global coordinates and convert to local coordinates
-// // on demand.
-//
-// // Position and delta are specified in local coordinate system of
-// // current element
-// mouse_event->pos = it->local_pos;
-// mouse_event->delta = it->local_delta;
-// }
+ // TODO provide functions to convert delta to local coordinates on demand.
+ // Maybe also provide a clone method for events as local coordinates
+ // might differ between different elements receiving the same event.
+ if( mouse_event ) //&& event->type != Event::DRAG )
+ {
+ // TODO transform pos and delta for drag events. Maybe we should just
+ // store the global coordinates and convert to local coordinates
+ // on demand.
+
+ // Position and delta are specified in local coordinate system of
+ // current element
+ mouse_event->local_pos = it->local_pos;
+ //mouse_event->delta = it->local_delta;
+ }
- el->callListeners(event);
+ el->handleEvent(event);
if( event->propagation_stopped )
return true;
osg::Vec2f getScreenPos() const { return screen_pos; }
osg::Vec2f getClientPos() const { return client_pos; }
+ osg::Vec2f getLocalPos() const { return local_pos; }
osg::Vec2f getDelta() const { return delta; }
float getScreenX() const { return screen_pos.x(); }
float getClientX() const { return client_pos.x(); }
float getClientY() const { return client_pos.y(); }
+ float getLocalX() const { return local_pos.x(); }
+ float getLocalY() const { return local_pos.y(); }
+
float getDeltaX() const { return delta.x(); }
float getDeltaY() const { return delta.y(); }
osg::Vec2f screen_pos, //<! Position in screen coordinates
client_pos, //<! Position in window/canvas coordinates
+ local_pos, //<! Position in local/element coordinates
delta;
int button, //<! Button for this event
state, //<! Current button state
}
//----------------------------------------------------------------------------
- void Element::callListeners(const canvas::EventPtr& event)
+ bool Element::handleEvent(canvas::EventPtr event)
{
ListenerMap::iterator listeners = _listener.find(event->getType());
if( listeners == _listener.end() )
- return;
+ return false;
BOOST_FOREACH(EventListenerPtr listener, listeners->second)
listener->call(event);
+
+ return true;
}
//----------------------------------------------------------------------------
virtual bool ascend(EventVisitor& visitor);
virtual bool traverse(EventVisitor& visitor);
- void callListeners(const canvas::EventPtr& event);
+ virtual bool handleEvent(canvas::EventPtr event);
virtual bool hitBound( const osg::Vec2f& pos,
const osg::Vec2f& local_pos ) const;
#include <simgear/canvas/CanvasMgr.hxx>
#include <simgear/canvas/CanvasSystemAdapter.hxx>
#include <simgear/canvas/MouseEvent.hxx>
+#include <simgear/scene/util/OsgMath.hxx>
#include <simgear/scene/util/parse_color.hxx>
#include <simgear/misc/sg_path.hxx>
}
//----------------------------------------------------------------------------
- bool Image::handleMouseEvent(MouseEventPtr event)
+ bool Image::handleEvent(EventPtr event)
{
- CanvasPtr src_canvas = _src_canvas.lock();
+ bool handled = Element::handleEvent(event);
+ CanvasPtr src_canvas = _src_canvas.lock();
if( !src_canvas )
- return false;
+ return handled;
- if( _outset.valid )
+ MouseEventPtr mouse_event = boost::dynamic_pointer_cast<MouseEvent>(event);
+ if( mouse_event )
{
- CSSOffsets outset = _outset.getAbsOffsets(getTextureDimensions());
-
- event.reset( new MouseEvent(*event) );
- event->client_pos += osg::Vec2f(outset.l, outset.t);
- event->client_pos.x() *= src_canvas->getViewWidth()
- / (_region.width() + outset.l + outset.r);
- event->client_pos.y() *= src_canvas->getViewHeight()
- / (_region.height() + outset.t + outset.b);
+ mouse_event.reset( new MouseEvent(*mouse_event) );
+ event = mouse_event;
+
+ mouse_event->client_pos = mouse_event->local_pos
+ - toOsg(_region.getMin());
+
+ osg::Vec2f size(_region.width(), _region.height());
+ if( _outset.valid )
+ {
+ CSSOffsets outset = _outset.getAbsOffsets(getTextureDimensions());
+
+ mouse_event->client_pos += osg::Vec2f(outset.l, outset.t);
+ size.x() += outset.l + outset.r;
+ size.y() += outset.t + outset.b;
+ }
+
+ // Scale event pos according to canvas view size vs. displayed/screen size
+ mouse_event->client_pos.x() *= src_canvas->getViewWidth() / size.x();
+ mouse_event->client_pos.y() *= src_canvas->getViewHeight()/ size.y();
+ mouse_event->local_pos = mouse_event->client_pos;
}
- return src_canvas->handleMouseEvent(event);
+ return handled || src_canvas->handleMouseEvent(mouse_event);
}
//----------------------------------------------------------------------------
const SGRect<float>& getRegion() const;
- bool handleMouseEvent(MouseEventPtr event);
+ bool handleEvent(EventPtr event);
protected: