CanvasPlacement.hxx
CanvasSystemAdapter.hxx
CanvasWindow.hxx
- MouseEvent.hxx
ODGauge.hxx
VGInitOperation.hxx
)
add_subdirectory(ShivaVG/src)
add_subdirectory(elements)
+add_subdirectory(events)
simgear_scene_component(canvas canvas "${SOURCES}" "${HEADERS}")
#include "Canvas.hxx"
#include "CanvasEventManager.hxx"
#include "CanvasEventVisitor.hxx"
-#include <simgear/canvas/MouseEvent.hxx>
-#include <simgear/canvas/CanvasPlacement.hxx>
+#include "CanvasPlacement.hxx"
+#include <simgear/canvas/events/MouseEvent.hxx>
#include <simgear/scene/util/parse_color.hxx>
#include <simgear/scene/util/RenderConstants.hxx>
//----------------------------------------------------------------------------
bool Canvas::handleMouseEvent(const MouseEventPtr& event)
{
- if( !_root_group.get() )
+ if( !_root_group )
return false;
EventVisitor visitor( EventVisitor::TRAVERSE_DOWN,
return _event_manager->handleEvent(event, visitor.getPropagationPath());
}
+ //----------------------------------------------------------------------------
+ bool Canvas::propagateEvent( EventPtr const& event,
+ EventPropagationPath const& path )
+ {
+ return _event_manager->propagateEvent(event, path);
+ }
+
//----------------------------------------------------------------------------
void Canvas::childAdded( SGPropertyNode * parent,
SGPropertyNode * child )
SGRect<int> getViewport() const;
bool handleMouseEvent(const MouseEventPtr& event);
+ bool propagateEvent( EventPtr const& event,
+ EventPropagationPath const& path );
virtual void childAdded( SGPropertyNode * parent,
SGPropertyNode * child );
//----------------------------------------------------------------------------
Event::Event():
type(UNKNOWN),
+ time(-1),
propagation_stopped(false)
{
}
//----------------------------------------------------------------------------
- Event::Type Event::getType() const
+ bool Event::canBubble() const
+ {
+ return true;
+ }
+
+ //----------------------------------------------------------------------------
+ int 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";
- }
+ return typeToStr(type);
}
//----------------------------------------------------------------------------
}
//----------------------------------------------------------------------------
- Event::Type Event::strToType(const std::string& str)
+ int Event::getOrRegisterType(const std::string& type_str)
{
- typedef std::map<std::string, Type> TypeMap;
- static TypeMap type_map;
+ int type = strToType(type_str);
- if( type_map.empty() )
+ if( type == UNKNOWN )
{
-# define ENUM_MAPPING(type, str) type_map[ str ] = type;
-# include "CanvasEventTypes.hxx"
-# undef ENUM_MAPPING
+ // Register new type
+ TypeMap& type_map = getTypeMap();
+ type = type_map.size() + 1; // ids start with 1 (after UNKNOWN)
+ type_map.insert(TypeMap::value_type(type_str, type));
}
- TypeMap::const_iterator it = type_map.find(str);
- if( it == type_map.end() )
+ return type;
+ }
+
+ //----------------------------------------------------------------------------
+ int Event::strToType(const std::string& str)
+ {
+ TypeMap const& type_map = getTypeMap();
+
+ TypeMap::map_by<name>::const_iterator it = type_map.by<name>().find(str);
+ if( it == type_map.by<name>().end() )
return UNKNOWN;
+ return it->second;
+ }
+
+ //----------------------------------------------------------------------------
+ std::string Event::typeToStr(int type)
+ {
+ TypeMap const& type_map = getTypeMap();
+ TypeMap::map_by<id>::const_iterator it = type_map.by<id>().find(type);
+ if( it == type_map.by<id>().end() )
+ return "unknown";
return it->second;
}
+ //----------------------------------------------------------------------------
+ Event::TypeMap& Event::getTypeMap()
+ {
+ static TypeMap type_map;
+
+ if( type_map.empty() )
+ {
+# define ENUM_MAPPING(type, str)\
+ type_map.insert(TypeMap::value_type(str, type));
+# include "CanvasEventTypes.hxx"
+# undef ENUM_MAPPING
+ }
+
+ return type_map;
+ }
+
} // namespace canvas
} // namespace simgear
#define CANVAS_EVENT_HXX_
#include "canvas_fwd.hxx"
+#include <boost/bimap.hpp>
namespace simgear
{
namespace canvas
{
- class Event
+ class Event:
+ public SGReferenced
{
public:
# 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)
+ CUSTOM_EVENT ///<! all user defined event types share the same id. They
+ /// are just differentiated by using the type string.
};
- Type type;
+ int type;
ElementWeakPtr target,
current_target;
double time;
// of the actual event instances.
virtual ~Event();
- Type getType() const;
+ /**
+ * Get whether this events support bubbling
+ */
+ virtual bool canBubble() const;
+
+ /**
+ * Set type of event.
+ *
+ * If no such type exists it is registered.
+ */
+ void setType(const std::string& type);
+
+ int getType() const;
std::string getTypeString() const;
ElementWeakPtr getTarget() const;
void stopPropagation();
- static Type strToType(const std::string& str);
+ static int getOrRegisterType(const std::string& type);
+ static int strToType(const std::string& type);
+ static std::string typeToStr(int type);
+
+ protected:
+ struct name {};
+ struct id {};
+ typedef boost::bimaps::bimap<
+ boost::bimaps::tagged<std::string, name>,
+ boost::bimaps::tagged<int, id>
+ > TypeMap;
+
+ static TypeMap& getTypeMap();
};
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include "CanvasEventManager.hxx"
-#include "MouseEvent.hxx"
+#include <simgear/canvas/events/MouseEvent.hxx>
#include <simgear/canvas/elements/CanvasElement.hxx>
#include <cmath>
return handled | propagateEvent(event, path);
}
+ //----------------------------------------------------------------------------
+ bool EventManager::propagateEvent( const EventPtr& event,
+ const EventPropagationPath& path )
+ {
+ event->target = path.back().element;
+ MouseEventPtr mouse_event = dynamic_cast<MouseEvent*>(event.get());
+
+ // Event propagation similar to DOM Level 3 event flow:
+ // http://www.w3.org/TR/DOM-Level-3-Events/#event-flow
+
+ // Position update only needed for drag event (as event needs to be
+ // delivered to element of initial mousedown, but with update positions)
+ if( mouse_event && mouse_event->type == MouseEvent::DRAG )
+ {
+ osg::Vec2f local_pos = mouse_event->client_pos;
+
+ // Capturing phase (currently just update position)
+ for( EventPropagationPath::const_iterator it = path.begin();
+ it != path.end();
+ ++it )
+ {
+ ElementPtr el = it->element.lock();
+ if( !el )
+ continue;
+
+ it->local_pos = local_pos = el->posToLocal(local_pos);
+ }
+ }
+
+ bool const do_bubble = event->canBubble();
+
+ // Bubbling phase
+ for( EventPropagationPath::const_reverse_iterator
+ it = path.rbegin();
+ it != path.rend();
+ ++it )
+ {
+ ElementPtr el = it->element.lock();
+
+ if( !el )
+ {
+ // Ignore element if it has been destroyed while traversing the event
+ // (eg. removed by another event handler)
+ if( do_bubble )
+ continue;
+ else
+ break;
+ }
+
+ // 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 )
+ mouse_event->local_pos = it->local_pos;
+
+ event->current_target = el;
+ el->handleEvent(event);
+
+ if( event->propagation_stopped || !do_bubble )
+ return true;
+ }
+
+ return true;
+ }
+
//----------------------------------------------------------------------------
bool EventManager::handleClick( const MouseEventPtr& event,
const EventPropagationPath& path )
return handled;
}
- //----------------------------------------------------------------------------
- bool EventManager::propagateEvent( const EventPtr& event,
- const EventPropagationPath& path )
- {
- event->target = path.back().element;
- MouseEventPtr mouse_event = boost::dynamic_pointer_cast<MouseEvent>(event);
-
- // Event propagation similar to DOM Level 3 event flow:
- // http://www.w3.org/TR/DOM-Level-3-Events/#event-flow
-
- // Position update only needed for drag event (as event needs to be
- // delivered to element of initial mousedown, but with update positions)
- if( mouse_event && mouse_event->type == MouseEvent::DRAG )
- {
- osg::Vec2f local_pos = mouse_event->client_pos;
-
- // Capturing phase (currently just update position)
- for( EventPropagationPath::const_iterator it = path.begin();
- it != path.end();
- ++it )
- {
- ElementPtr el = it->element.lock();
- if( !el )
- continue;
-
- it->local_pos = local_pos = el->posToLocal(local_pos);
- }
- }
-
- // Check if event supports bubbling
- const Event::Type types_no_bubbling[] = {
- Event::MOUSE_ENTER,
- Event::MOUSE_LEAVE,
- };
- const size_t num_types_no_bubbling = sizeof(types_no_bubbling)
- / sizeof(types_no_bubbling[0]);
- bool do_bubble = true;
- for( size_t i = 0; i < num_types_no_bubbling; ++i )
- if( event->type == types_no_bubbling[i] )
- {
- do_bubble = false;
- break;
- }
-
- // Bubbling phase
- for( EventPropagationPath::const_reverse_iterator
- it = path.rbegin();
- it != path.rend();
- ++it )
- {
- ElementPtr el = it->element.lock();
-
- if( !el )
- {
- // Ignore element if it has been destroyed while traversing the event
- // (eg. removed by another event handler)
- if( do_bubble )
- continue;
- else
- break;
- }
-
- // 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 )
- mouse_event->local_pos = it->local_pos;
-
- event->current_target = el;
- el->handleEvent(event);
-
- if( event->propagation_stopped || !do_bubble )
- return true;
- }
-
- return true;
- }
-
//----------------------------------------------------------------------------
bool
EventManager::checkClickDistance( const osg::Vec2f& pos1,
// Used as storage by EventManager during event propagation
mutable osg::Vec2f local_pos;
+
+ EventTarget( Element* el,
+ const osg::Vec2f pos = osg::Vec2f() ):
+ element(el),
+ local_pos(pos)
+ {}
};
- typedef std::deque<EventTarget> EventPropagationPath;
+
inline bool operator==(const EventTarget& t1, const EventTarget& t2)
{
return t1.element.lock() == t2.element.lock();
bool handleEvent( const MouseEventPtr& event,
const EventPropagationPath& path );
+ bool propagateEvent( const EventPtr& event,
+ const EventPropagationPath& path );
+
protected:
struct StampedPropagationPath
{
bool handleMove( const MouseEventPtr& event,
const EventPropagationPath& path );
- bool propagateEvent( const EventPtr& event,
- const EventPropagationPath& path );
-
/**
* Check if two click events (either mousedown/up or two consecutive
* clicks) are inside a maximum distance to still create a click or
_root(root)
{
if( mode == TRAVERSE_DOWN )
- {
- EventTarget target = {ElementWeakPtr(), pos};
- _target_path.push_back(target);
- }
+ _target_path.push_back( EventTarget(NULL, pos) );
}
//----------------------------------------------------------------------------
&& !el.hitBound(_target_path.front().local_pos, pos, local_pos) )
return false;
- EventTarget target = {ElementPtr(&el), local_pos};
- _target_path.push_back(target);
+ _target_path.push_back( EventTarget(&el, local_pos) );
if( el.traverse(*this) || &el == _root.get() )
return true;
#include "Canvas.hxx"
#include "CanvasObjectPlacement.hxx"
-#include "MouseEvent.hxx"
+#include <simgear/canvas/events/MouseEvent.hxx>
#include <simgear/props/props.hxx>
#include <simgear/scene/util/SGPickCallback.hxx>
#define CANVAS_WINDOW_HXX_
#include <simgear/canvas/elements/CanvasImage.hxx>
-#include <simgear/canvas/MouseEvent.hxx>
+#include <simgear/canvas/events/MouseEvent.hxx>
#include <simgear/props/PropertyBasedElement.hxx>
#include <simgear/props/propertyObject.hxx>
#include <simgear/misc/CSSBorder.hxx>
+++ /dev/null
-// Mouse event
-//
-// 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_MOUSE_EVENT_HXX_
-#define CANVAS_MOUSE_EVENT_HXX_
-
-#include "CanvasEvent.hxx"
-#include <osgGA/GUIEventAdapter>
-
-namespace simgear
-{
-namespace canvas
-{
-
- class MouseEvent:
- public Event
- {
- public:
- MouseEvent():
- button(0),
- buttons(0),
- modifiers(0),
- click_count(0)
- {}
-
- MouseEvent(const osgGA::GUIEventAdapter& ea):
- button(0),
- buttons(ea.getButtonMask()),
- modifiers(ea.getModKeyMask()),
- click_count(0)
- {
- time = ea.getTime();
-
- // Convert button mask to index
- int button_mask = ea.getButton();
- while( (button_mask >>= 1) > 0 )
- button += 1;
- }
-
- 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 getScreenY() const { return screen_pos.y(); }
-
- 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(); }
-
- int getButton() const { return button; }
- int getButtonMask() const { return buttons; }
- int getModifiers() const { return modifiers; }
-
- int getCurrentClickCount() const { return click_count; }
-
- 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
- buttons, //<! Current button state
- modifiers, //<! Keyboard modifier state
- click_count; //<! Current click count
- };
-
-} // namespace canvas
-} // namespace simgear
-
-#endif /* CANVAS_MOUSE_EVENT_HXX_ */
SG_FWD_DECL(Text)
SG_FWD_DECL(Window)
+ SG_FWD_DECL(Event)
+ SG_FWD_DECL(CustomEvent)
+ SG_FWD_DECL(MouseEvent)
+
#undef SG_FWD_DECL
#define SG_FWD_DECL(name)\
typedef boost::shared_ptr<name> name##Ptr;\
typedef boost::weak_ptr<name> name##WeakPtr;
- SG_FWD_DECL(Event)
- SG_FWD_DECL(MouseEvent)
SG_FWD_DECL(Placement)
SG_FWD_DECL(SystemAdapter)
class EventManager;
class EventVisitor;
+ struct EventTarget;
+ typedef std::deque<EventTarget> EventPropagationPath;
+
typedef std::map<std::string, const SGPropertyNode*> Style;
typedef ElementPtr (*ElementFactory)( const CanvasWeakPtr&,
const SGPropertyNode_ptr&,
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include "CanvasElement.hxx"
+#include <simgear/canvas/Canvas.hxx>
#include <simgear/canvas/CanvasEventVisitor.hxx>
-#include <simgear/canvas/MouseEvent.hxx>
+#include <simgear/canvas/events/MouseEvent.hxx>
#include <simgear/math/SGMisc.hxx>
#include <simgear/misc/strutils.hxx>
#include <simgear/scene/material/parseBlendFunc.hxx>
"addEventListener(" << _node->getPath() << ", " << type_str << ")"
);
- Event::Type type = Event::strToType(type_str);
- if( type == Event::UNKNOWN )
- {
- SG_LOG( SG_GENERAL,
- SG_WARN,
- "addEventListener: Unknown event type " << type_str );
- return false;
- }
-
- _listener[ type ].push_back(cb);
-
+ _listener[ Event::getOrRegisterType(type_str) ].push_back(cb);
return true;
}
}
//----------------------------------------------------------------------------
- bool Element::handleEvent(canvas::EventPtr event)
+ bool Element::handleEvent(EventPtr event)
{
ListenerMap::iterator listeners = _listener.find(event->getType());
if( listeners == _listener.end() )
return true;
}
+ //----------------------------------------------------------------------------
+ bool Element::dispatchEvent(EventPtr event)
+ {
+ EventPropagationPath path;
+ path.push_back( EventTarget(this) );
+
+ for( Element* parent = _parent;
+ parent != NULL;
+ parent = parent->_parent )
+ path.push_front( EventTarget(parent) );
+
+ CanvasPtr canvas = _canvas.lock();
+ if( !canvas )
+ return false;
+
+ return canvas->propagateEvent(event, path);
+ }
+
//----------------------------------------------------------------------------
bool Element::hitBound( const osg::Vec2f& global_pos,
const osg::Vec2f& parent_pos,
virtual bool ascend(EventVisitor& visitor);
virtual bool traverse(EventVisitor& visitor);
- virtual bool handleEvent(canvas::EventPtr event);
+ virtual bool handleEvent(EventPtr event);
+ bool dispatchEvent(EventPtr event);
/**
*
RelativeScissor *_scissor;
typedef std::vector<EventListener> Listener;
- typedef std::map<Event::Type, Listener> ListenerMap;
+ typedef std::map<int, Listener> ListenerMap;
ListenerMap _listener;
#include "CanvasPath.hxx"
#include "CanvasText.hxx"
#include <simgear/canvas/CanvasEventVisitor.hxx>
-#include <simgear/canvas/MouseEvent.hxx>
+#include <simgear/canvas/events/MouseEvent.hxx>
#include <boost/bind.hpp>
#include <boost/foreach.hpp>
#include <simgear/canvas/Canvas.hxx>
#include <simgear/canvas/CanvasMgr.hxx>
#include <simgear/canvas/CanvasSystemAdapter.hxx>
-#include <simgear/canvas/MouseEvent.hxx>
+#include <simgear/canvas/events/MouseEvent.hxx>
#include <simgear/scene/util/OsgMath.hxx>
#include <simgear/scene/util/parse_color.hxx>
#include <simgear/misc/sg_path.hxx>
if( !src_canvas )
return handled;
- MouseEventPtr mouse_event = boost::dynamic_pointer_cast<MouseEvent>(event);
+ MouseEventPtr mouse_event = dynamic_cast<MouseEvent*>(event.get());
if( mouse_event )
{
mouse_event.reset( new MouseEvent(*mouse_event) );
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;
+
+ handled |= src_canvas->handleMouseEvent(mouse_event);
}
- return handled | src_canvas->handleMouseEvent(mouse_event);
+ return handled;
}
//----------------------------------------------------------------------------
--- /dev/null
+include (SimGearComponent)
+
+set(HEADERS
+ CustomEvent.hxx
+ MouseEvent.hxx
+)
+
+set(SOURCES
+ CustomEvent.cxx
+ MouseEvent.cxx
+)
+
+simgear_scene_component(canvas-events canvas/events "${SOURCES}" "${HEADERS}")
+
+add_boost_test(canvas_event
+ SOURCES event_test.cpp
+ LIBRARIES ${TEST_LIBS}
+)
\ No newline at end of file
--- /dev/null
+// Canvas user defined event
+//
+// Copyright (C) 2014 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 "CustomEvent.hxx"
+
+namespace simgear
+{
+namespace canvas
+{
+
+ //----------------------------------------------------------------------------
+ CustomEvent::CustomEvent( std::string const& type_str,
+ StringMap const& data ):
+ detail(data)
+ {
+ type = getOrRegisterType(type_str);
+ }
+
+ //----------------------------------------------------------------------------
+ CustomEvent::CustomEvent( int type_id,
+ StringMap const& data ):
+ detail(data)
+ {
+ type = type_id;
+// TypeMap::map_by<id>::type const& type_map = getTypeMap().by<id>();
+// assert( type_map.find(type_id) != type_map.end() );
+ }
+
+ //----------------------------------------------------------------------------
+ void CustomEvent::setDetail(StringMap const& data)
+ {
+ detail = data;
+ }
+
+} // namespace canvas
+} // namespace simgear
--- /dev/null
+///@file Canvas user defined event
+//
+// Copyright (C) 2014 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_CUSTOM_EVENT_HXX_
+#define CANVAS_CUSTOM_EVENT_HXX_
+
+#include <simgear/canvas/CanvasEvent.hxx>
+#include <simgear/structure/map.hxx>
+
+namespace simgear
+{
+namespace canvas
+{
+
+ class CustomEvent:
+ public Event
+ {
+ public:
+
+ /**
+ *
+ * @param type_str Event type name (if name does not exist yet it will
+ * be registered as new event type)
+ * @param data Optional user data stored in event
+ */
+ CustomEvent( std::string const& type_str,
+ StringMap const& data = StringMap() );
+
+ /**
+ *
+ * @param type_id Event type id
+ * @param data Optional user data stored in event
+ */
+ CustomEvent( int type_id,
+ StringMap const& data = StringMap() );
+
+ /**
+ * Set user data
+ */
+ void setDetail(StringMap const& data);
+
+ /**
+ * Get user data
+ */
+ StringMap const& getDetail() const { return detail; }
+
+ virtual bool canBubble() const { return bubbles; }
+
+ StringMap detail; //<! user data map
+ bool bubbles;
+ };
+
+} // namespace canvas
+} // namespace simgear
+
+#endif /* CANVAS_CUSTOM_EVENT_HXX_ */
--- /dev/null
+// Mouse event
+//
+// Copyright (C) 2014 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 "MouseEvent.hxx"
+
+namespace simgear
+{
+namespace canvas
+{
+
+ //----------------------------------------------------------------------------
+ MouseEvent::MouseEvent():
+ button(0),
+ buttons(0),
+ modifiers(0),
+ click_count(0)
+ {
+
+ }
+
+ //----------------------------------------------------------------------------
+ MouseEvent::MouseEvent(const osgGA::GUIEventAdapter& ea):
+ button(0),
+ buttons(ea.getButtonMask()),
+ modifiers(ea.getModKeyMask()),
+ click_count(0)
+ {
+ time = ea.getTime();
+
+ // Convert button mask to index
+ int button_mask = ea.getButton();
+ while( (button_mask >>= 1) > 0 )
+ button += 1;
+ }
+
+ //----------------------------------------------------------------------------
+ bool MouseEvent::canBubble() const
+ {
+ // Check if event supports bubbling
+ const Event::Type types_no_bubbling[] = {
+ Event::MOUSE_ENTER,
+ Event::MOUSE_LEAVE,
+ };
+ const size_t num_types_no_bubbling = sizeof(types_no_bubbling)
+ / sizeof(types_no_bubbling[0]);
+
+ for( size_t i = 0; i < num_types_no_bubbling; ++i )
+ if( type == types_no_bubbling[i] )
+ return false;
+
+ return true;
+ }
+
+} // namespace canvas
+} // namespace simgear
--- /dev/null
+///@file Mouse event
+//
+// 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_MOUSE_EVENT_HXX_
+#define CANVAS_MOUSE_EVENT_HXX_
+
+#include <simgear/canvas/CanvasEvent.hxx>
+#include <osgGA/GUIEventAdapter>
+
+namespace simgear
+{
+namespace canvas
+{
+
+ class MouseEvent:
+ public Event
+ {
+ public:
+ MouseEvent();
+ MouseEvent(const osgGA::GUIEventAdapter& ea);
+
+ virtual bool canBubble() const;
+
+ 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 getScreenY() const { return screen_pos.y(); }
+
+ 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(); }
+
+ int getButton() const { return button; }
+ int getButtonMask() const { return buttons; }
+ int getModifiers() const { return modifiers; }
+
+ int getCurrentClickCount() const { return click_count; }
+
+ 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
+ buttons, //<! Current button state
+ modifiers, //<! Keyboard modifier state
+ click_count; //<! Current click count
+ };
+
+} // namespace canvas
+} // namespace simgear
+
+#endif /* CANVAS_MOUSE_EVENT_HXX_ */
--- /dev/null
+/// Unit tests for reference counting and smart pointer classes
+#define BOOST_TEST_MODULE structure
+#include <BoostTestTargetConfig.h>
+
+#include "MouseEvent.hxx"
+#include "CustomEvent.hxx"
+
+namespace sc = simgear::canvas;
+
+BOOST_AUTO_TEST_CASE( canvas_event_types )
+{
+ // Register type
+ BOOST_REQUIRE_EQUAL( sc::Event::strToType("test"),
+ sc::Event::UNKNOWN );
+ BOOST_REQUIRE_EQUAL( sc::Event::getOrRegisterType("test"),
+ sc::Event::CUSTOM_EVENT );
+ BOOST_REQUIRE_EQUAL( sc::Event::strToType("test"),
+ sc::Event::CUSTOM_EVENT );
+ BOOST_REQUIRE_EQUAL( sc::Event::typeToStr(sc::Event::CUSTOM_EVENT),
+ "test" );
+
+ // Basic internal type
+ BOOST_REQUIRE_EQUAL( sc::Event::typeToStr(sc::Event::MOUSE_DOWN),
+ "mousedown" );
+ BOOST_REQUIRE_EQUAL( sc::Event::strToType("mousedown"),
+ sc::Event::MOUSE_DOWN );
+
+ // Unknown type
+ BOOST_REQUIRE_EQUAL( sc::Event::typeToStr(123),
+ "unknown" );
+
+ // Register type through custom event instance
+ sc::CustomEvent e("blub");
+ BOOST_REQUIRE_EQUAL( e.getTypeString(), "blub" );
+ BOOST_REQUIRE_NE( e.getType(), sc::Event::UNKNOWN );
+}
Map() {}
/**
- * Initilize a new mape with the given key/value pair.
+ * Initialize a new map with the given key/value pair.
*/
Map(const Key& key, const Value& value)
{