Canvas: Add local_pos to mouse event and fix transformation of event positions with multi-level nested canvases.
This commit is contained in:
parent
d61b5827fd
commit
01104cc1d3
@ -210,23 +210,22 @@ namespace canvas
|
||||
// (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.
|
||||
|
||||
el->callListeners(event);
|
||||
// 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->handleEvent(event);
|
||||
|
||||
if( event->propagation_stopped )
|
||||
return true;
|
||||
|
@ -49,6 +49,7 @@ namespace canvas
|
||||
|
||||
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(); }
|
||||
@ -57,6 +58,9 @@ namespace canvas
|
||||
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(); }
|
||||
|
||||
@ -64,6 +68,7 @@ namespace canvas
|
||||
|
||||
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
|
||||
|
@ -185,14 +185,16 @@ namespace canvas
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
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;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -90,7 +90,7 @@ namespace canvas
|
||||
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;
|
||||
|
@ -22,6 +22,7 @@
|
||||
#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>
|
||||
|
||||
@ -411,26 +412,40 @@ namespace canvas
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool Image::handleMouseEvent(MouseEventPtr event)
|
||||
bool Image::handleEvent(EventPtr event)
|
||||
{
|
||||
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());
|
||||
mouse_event.reset( new MouseEvent(*mouse_event) );
|
||||
event = mouse_event;
|
||||
|
||||
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->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);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -81,7 +81,7 @@ namespace canvas
|
||||
|
||||
const SGRect<float>& getRegion() const;
|
||||
|
||||
bool handleMouseEvent(MouseEventPtr event);
|
||||
bool handleEvent(EventPtr event);
|
||||
|
||||
protected:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user