From: Thomas Geymayer Date: Sun, 12 May 2013 22:34:09 +0000 (+0200) Subject: Canvas: Add local_pos to mouse event and fix transformation of event positions with... X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=01104cc1d317656a9140f39a2dbd81d492bdc8fa;p=simgear.git Canvas: Add local_pos to mouse event and fix transformation of event positions with multi-level nested canvases. --- diff --git a/simgear/canvas/CanvasEventManager.cxx b/simgear/canvas/CanvasEventManager.cxx index 89f25719..8801d84a 100644 --- a/simgear/canvas/CanvasEventManager.cxx +++ b/simgear/canvas/CanvasEventManager.cxx @@ -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. + + // 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; diff --git a/simgear/canvas/MouseEvent.hxx b/simgear/canvas/MouseEvent.hxx index c84fcd27..f6faee76 100644 --- a/simgear/canvas/MouseEvent.hxx +++ b/simgear/canvas/MouseEvent.hxx @@ -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, //getType()); if( listeners == _listener.end() ) - return; + return false; BOOST_FOREACH(EventListenerPtr listener, listeners->second) listener->call(event); + + return true; } //---------------------------------------------------------------------------- diff --git a/simgear/canvas/elements/CanvasElement.hxx b/simgear/canvas/elements/CanvasElement.hxx index 31961825..65e84dbf 100644 --- a/simgear/canvas/elements/CanvasElement.hxx +++ b/simgear/canvas/elements/CanvasElement.hxx @@ -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; diff --git a/simgear/canvas/elements/CanvasImage.cxx b/simgear/canvas/elements/CanvasImage.cxx index d4e56601..f7a4d92c 100644 --- a/simgear/canvas/elements/CanvasImage.cxx +++ b/simgear/canvas/elements/CanvasImage.cxx @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -411,26 +412,40 @@ namespace canvas } //---------------------------------------------------------------------------- - 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(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); } //---------------------------------------------------------------------------- diff --git a/simgear/canvas/elements/CanvasImage.hxx b/simgear/canvas/elements/CanvasImage.hxx index fccc20f5..453f7dce 100644 --- a/simgear/canvas/elements/CanvasImage.hxx +++ b/simgear/canvas/elements/CanvasImage.hxx @@ -81,7 +81,7 @@ namespace canvas const SGRect& getRegion() const; - bool handleMouseEvent(MouseEventPtr event); + bool handleEvent(EventPtr event); protected: