Commit 30eb22b8 authored by Mathias Goldau's avatar Mathias Goldau

[ADD #274] Now WCustomWidget supports event based notification with the use of...

[ADD #274] Now WCustomWidget supports event based notification with the use of member functions given via boost::bind
parent d299dae5
...@@ -26,11 +26,8 @@ ...@@ -26,11 +26,8 @@
#include "WCustomWidget.h" #include "WCustomWidget.h"
WCustomWidget::WCustomWidget( std::string title, EventType subscription ): WCustomWidget::WCustomWidget( std::string title ):
m_title( title ), m_title( title )
m_eventNotifier( new WCondition() ),
m_events( new WSharedSequenceContainer< EventDeque >() ),
m_subscription( subscription )
{ {
} }
...@@ -42,27 +39,3 @@ std::string WCustomWidget::getTitle() const ...@@ -42,27 +39,3 @@ std::string WCustomWidget::getTitle() const
{ {
return m_title; return m_title;
} }
WCustomWidget::EventQueueSPtr WCustomWidget::getNextEvents()
{
EventQueueSPtr unhandledEvents( new EventQueue() );
WSharedSequenceContainer< EventDeque >::WriteTicket t = m_events->getWriteTicket();
while( !t->get().empty() )
{
unhandledEvents->push( t->get().front() );
t->get().pop_front();
}
return unhandledEvents;
}
WCondition::SPtr WCustomWidget::getEventNotifier() const
{
return m_eventNotifier;
}
bool WCustomWidget::newEvents() const
{
WSharedSequenceContainer< EventDeque >::ReadTicket t = m_events->getReadTicket();
return t->get().size() > 0;
}
...@@ -26,40 +26,44 @@ ...@@ -26,40 +26,44 @@
#define WCUSTOMWIDGET_H #define WCUSTOMWIDGET_H
#include <string> #include <string>
#include <queue>
#include <deque>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <osg/ref_ptr> #include <osg/ref_ptr>
#include "../common/WCondition.h"
#include "../common/WSharedSequenceContainer.h"
#include "../graphicsEngine/WGEViewer.h" #include "../graphicsEngine/WGEViewer.h"
class WGEGroupNode; class WGEGroupNode;
/** /**
* Custom widget which is created by a module to display custom information. * Is just a short hand to the long name "osgGA::GUIEventAdapter".
*/ */
class WCustomWidget class GUIEvents : public osgGA::GUIEventAdapter
{ {
public: public:
/** using osgGA::GUIEventAdapter::EventType;
* Forward EventType from OSG using osgGA::GUIEventAdapter::MouseButtonMask;
*/ using osgGA::GUIEventAdapter::KeySymbol;
typedef osgGA::GUIEventAdapter::EventType EventType; using osgGA::GUIEventAdapter::ModKeyMask;
using osgGA::GUIEventAdapter::MouseYOrientation;
/** using osgGA::GUIEventAdapter::ScrollingMotion;
* Queue of GUI events. using osgGA::GUIEventAdapter::TabletPointerType;
*/
typedef std::queue< osg::ref_ptr< osgGA::GUIEventAdapter > > EventQueue;
private:
/** /**
* Convenience short hand for \c boost::shared_ptr on \c EventQueue. * The constructor is private to forbid instance generation.
*/ */
typedef boost::shared_ptr< EventQueue > EventQueueSPtr; GUIEvents()
{
}
};
/**
* Custom widget which is created by a module to display custom information.
*/
class WCustomWidget
{
public:
/** /**
* Abbreviation for a shared pointer on a instance of this class. * Abbreviation for a shared pointer on a instance of this class.
*/ */
...@@ -74,9 +78,8 @@ public: ...@@ -74,9 +78,8 @@ public:
* Constructor. Create a custom widget instance. * Constructor. Create a custom widget instance.
* *
* \param title the title of the widget * \param title the title of the widget
* \param subscription Binary mask on which event types you want to be notified.
*/ */
explicit WCustomWidget( std::string title, EventType subscription = osgGA::GUIEventAdapter::NONE ); explicit WCustomWidget( std::string title );
/** /**
* Destructor * Destructor
...@@ -119,114 +122,18 @@ public: ...@@ -119,114 +122,18 @@ public:
virtual size_t width() const = 0; virtual size_t width() const = 0;
/** /**
* Returns the next unhandled GUI event on this widget. After calling this function you take responisbility on the event-copy, * Adds an event handler to the widget's view.
* (meaning destroy it when you do not need it anymore). Additionally the notification of new events will be triggered again
* in case there are more events waiting to be processed.
* *
* \return Next GUI event ( shallow copy ). * \param handler Pointer to the handler.
*/ */
virtual EventQueueSPtr getNextEvents(); virtual void addEventHandler( osgGA::GUIEventHandler* handler ) = 0;
/**
* This condition fires whenever a new event has to be handled and there was no old event left.
*
* \return \c WCondition as event notifier.
*/
virtual WCondition::SPtr getEventNotifier() const;
/**
* Determines if there are new events which you have subscribed to and need to be processed or not.
*
* \return True when there are new events, false otherwise.
*/
virtual bool newEvents() const;
protected: protected:
/**
* \class WindowHandler
*
* An event handler for a custom widget.
*/
class WindowHandler : public osgGA::GUIEventHandler
{
public:
/**
* Constructor.
*
* \param widget The custom widget which should be notified.
*/
explicit WindowHandler( WCustomWidget* widget )
: m_widget( widget )
{
}
/**
* Deals with the events found by the osg.
*
* \param ea Event class for storing Keyboard, mouse and window events.
*
* \return true if the event was handled.
*/
bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& /* aa */ )
{
if( ea.getEventType() & m_widget->m_subscription )
{
WSharedSequenceContainer< EventDeque >::WriteTicket t = m_widget->m_events->getWriteTicket();
if( t->get().size() == 0 ) // when this is the first event, notify module only once
{
m_widget->m_eventNotifier->notify();
}
// else: Do not spam the module for new events, but still collect events into queue. Module will need to make queue empty again
t->get().push_back( new osgGA::GUIEventAdapter( ea ) );
return true;
}
return false; // There was no subscription to this event
}
private:
/**
* Reference to the WCustomWidget which has the condition for such events and needs to be notified.
*/
WCustomWidget* const m_widget;
};
/**
* This is a short hand type for our FiFo queue containing events.
*
* \note A std::queue would be better, as we are using it as a FiFo queue, but inorder to have thread safe access,
* we use WSharedSequenceContainer which only supports deque, list and vector at the moment.
*/
typedef std::deque< osg::ref_ptr< osgGA::GUIEventAdapter > > EventDeque;
/**
* Short hand type for boost::shared_ptr on internal event deque.
*/
typedef boost::shared_ptr< EventDeque > EventDequeSPtr;
private: private:
/** /**
* The widget's title string. * The widget's title string.
*/ */
std::string m_title; std::string m_title;
/**
* Condition fired if an GUI event has occured.
*/
WCondition::SPtr m_eventNotifier;
/**
* Stores last GUI events.
*/
WSharedSequenceContainer< EventDeque >::SPtr m_events;
/**
* Binary mask describing which events should be used for notification. For example you may use:
* \c subscription=MOVE|SCROLL|RESIZE.
*/
EventType m_subscription;
}; };
#endif // WCUSTOMWIDGET_H #endif // WCUSTOMWIDGET_H
...@@ -42,9 +42,6 @@ WQtCustomDockWidget::WQtCustomDockWidget( std::string title, QWidget* parent, WG ...@@ -42,9 +42,6 @@ WQtCustomDockWidget::WQtCustomDockWidget( std::string title, QWidget* parent, WG
// send mouse move events even if no button is pressed // send mouse move events even if no button is pressed
getGLWidget()->setMouseTracking( true ); getGLWidget()->setMouseTracking( true );
// register event handler for updating event condition
getViewer()->getView()->addEventHandler( new WindowHandler( this ) ); // register an event handler to update change conditions and event types
} }
osg::ref_ptr< WGEGroupNode > WQtCustomDockWidget::getScene() const osg::ref_ptr< WGEGroupNode > WQtCustomDockWidget::getScene() const
...@@ -83,4 +80,9 @@ size_t WQtCustomDockWidget::width() const ...@@ -83,4 +80,9 @@ size_t WQtCustomDockWidget::width() const
return static_cast< size_t >( getViewer()->getCamera()->getViewport()->width() ); return static_cast< size_t >( getViewer()->getCamera()->getViewport()->width() );
} }
void WQtCustomDockWidget::addEventHandler( osgGA::GUIEventHandler* handler )
{
getViewer()->getView()->addEventHandler( handler );
}
...@@ -91,6 +91,11 @@ public: ...@@ -91,6 +91,11 @@ public:
*/ */
virtual size_t width() const; virtual size_t width() const;
/**
* \copydoc WCustomWidget::addEventHandler()
*/
virtual void addEventHandler( osgGA::GUIEventHandler* handler );
protected: protected:
private: private:
/** /**
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment