This section describes creating a new gesture recognizer. It describes the steps to release drag gesture event.
#include <Inventor/gestures/recognizers/SoDragGestureRecognizer.h>
#include <Inventor/touch/events/SoTouchEvent.h>
SoDragGestureRecognizer::SoDragGestureRecognizer()
{
m_finger1ID = -1;
m_finger2ID = -1;
m_recoInProgress = false;
}
SoDragGestureRecognizer::~SoDragGestureRecognizer() {}
SoEvent*
SoDragGestureRecognizer::recognize( SoEvent* touchEvent )
{
SoTouchEvent* dragTouchEvent = dynamic_cast<SoTouchEvent*>( touchEvent );
SbVec2f otherFingerPosition;
SbVec2f otherFingerFirstPosition;
SbVec2f position = dragTouchEvent->getPositionFloat();
SoTouchManager* touchManager = dragTouchEvent->getTouchManager();
if ( dragTouchEvent == 0 )
return NULL;
// If the recognizer is turned on
if ( m_recoInProgress )
{
// If you put up one of your finger, the recognition is endeed and the recognizer return
// an event with the END attribute.
if ( dragTouchEvent->getState() == SoTouchEvent::UP )
{
if ( dragTouchEvent->getFingerId() == m_finger1ID )
{
m_finger1ID = -1;
}
else if ( dragTouchEvent->getFingerId() == m_finger2ID )
{
m_finger2ID = -1;
}
m_returnedEvent.setGestureState( SoGestureEvent::END );
m_recoInProgress = false;
return &m_returnedEvent;
}
// If it's not a UP, two fingers are moving on the screen. The position of the other finger is recovered.
// and the distance between fingers is updated to calculate the new distance.
else
{
if ( dragTouchEvent->getFingerId() == m_finger1ID )
{
otherFingerPosition = touchManager->getEventById( m_finger2ID )->getPositionFloat();
otherFingerFirstPosition = touchManager->getEventById( m_finger2ID )->getFirstPosition();
}
else if ( dragTouchEvent->getFingerId() == m_finger2ID )
{
otherFingerPosition = touchManager->getEventById( m_finger1ID )->getPositionFloat();
otherFingerFirstPosition = touchManager->getEventById( m_finger1ID )->getFirstPosition();
}
SbVec2f pos = ( position + otherFingerPosition ) / 2;
m_returnedEvent.setPosition( pos );
m_returnedEvent.setDraggedDistance( pos - ( dragTouchEvent->getFirstPosition() + otherFingerFirstPosition ) / 2 );
m_returnedEvent.setGestureState( SoGestureEvent::DELTA );
return &m_returnedEvent;
}
}
// If the recognizer is turned off.
else
{
if ( dragTouchEvent->getState() == SoTouchEvent::UP )
{
if ( dragTouchEvent->getFingerId() == m_finger1ID )
{
m_finger1ID = -1;
}
}
// if one finger is put down the sreen
else if ( dragTouchEvent->getState() == SoTouchEvent::DOWN )
{
if ( m_finger1ID == -1 )
{
m_finger1ID = dragTouchEvent->getFingerId();
}
// and an other finger is touch the screen too.
else if ( dragTouchEvent->getFingerId() != m_finger1ID )
{
m_finger2ID = dragTouchEvent->getFingerId();
otherFingerPosition = touchManager->getEventById( m_finger1ID )->getPositionFloat();
otherFingerFirstPosition = touchManager->getEventById( m_finger1ID )->getFirstPosition();
SbVec2f pos = ( position + otherFingerPosition ) / 2;
m_returnedEvent.setDraggedDistance( pos - ( dragTouchEvent->getFirstPosition() + otherFingerFirstPosition ) / 2 );
m_returnedEvent.setGestureState( SoGestureEvent::BEGIN );
m_recoInProgress = true;
return &m_returnedEvent;
}
}
}
return NULL;
}