qstmgesturelib/qstmgestureengine.cpp
changeset 0 1450b09d0cfd
child 3 0954f5dd2cd0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qstmgesturelib/qstmgestureengine.cpp	Tue May 04 12:39:35 2010 +0300
@@ -0,0 +1,322 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+
+#include "qstmgestureengine.h"
+#include "qstmfilelogger.h"
+#include "qstmutils.h"
+
+
+using namespace qstmGesture ;
+
+QStm_GestureEngine::QStm_GestureEngine()
+{
+	m_loggingEnabled = 0;
+    m_numOfActiveStreams = 0 ;
+    m_currentGestureOwner = -1 ;
+    m_currentLockedGesture = -1 ;
+    for (int i = 0; i < qstmUiEventEngine::KMaxNumberOfPointers; i++) {
+        m_uiEventStream[i] = NULL ;
+    }
+}
+
+QStm_GestureEngine::~QStm_GestureEngine()
+{
+    m_gestures.clear() ;
+}
+
+bool QStm_GestureEngine::addGesture(const QStm_GestureRecogniserIf* newGesture)
+{
+    // Add the new gesture recogniser to our list of recognisers
+	if (newGesture) {
+		QStm_GestureRecogniserIf* p = const_cast<QStm_GestureRecogniserIf*>(newGesture);
+		m_gestures.append(p);
+	}
+    return true;
+}
+
+bool QStm_GestureEngine::insertGesture(const QStm_GestureRecogniserIf* newGesture, int startPos)
+{
+	QStm_GestureRecogniserIf* p = const_cast<QStm_GestureRecogniserIf*>(newGesture);
+    m_gestures.insert(startPos, p);
+    return true;
+}
+
+int QStm_GestureEngine::findGesture(const QStm_GestureRecogniserIf* gesture, int startPos) const
+{
+    for(int i = MAX(startPos, 0); i < m_gestures.count(); ++i) {
+        if(m_gestures[i] == gesture) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+int QStm_GestureEngine::findGestureReverse(const QStm_GestureRecogniserIf* gesture, int startPos) const
+{
+    for(int i = MIN(startPos, m_gestures.count() - 1); i >=0; --i) {
+        if(m_gestures[i] == gesture) {
+            return i;
+            }
+        }
+    return -1;
+}
+
+int QStm_GestureEngine::findGesture(QStm_GestureUid uid, int startPos) const
+{
+    for(int i = MAX(startPos, 0); i < m_gestures.count(); ++i) {
+        if(m_gestures[i]->gestureUid() == uid) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+int QStm_GestureEngine::findGestureReverse(QStm_GestureUid uid, int startPos) const
+{
+    for(int i = MIN(startPos, m_gestures.count() - 1); i >=0; --i) {
+        if(m_gestures[i]->gestureUid() == uid) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+int QStm_GestureEngine::gestureCount() const
+{
+    return m_gestures.count();
+}
+
+bool QStm_GestureEngine::removeGesture(const QStm_GestureRecogniserIf* oldGesture)
+{
+    // If gestures are removed, there cannot be current gesture owner...
+    if (m_currentGestureOwner != -1)
+    {
+        QStm_GestureRecogniserIf* pgrif = m_gestures[m_currentGestureOwner] ;
+        pgrif->release(this) ;
+        m_currentGestureOwner = -1 ;    // no more gesture owners...
+    }
+    QStm_GestureRecogniserIf* p = const_cast<QStm_GestureRecogniserIf*>(oldGesture);
+    int ix = m_gestures.indexOf(p) ;
+    bool found = (ix != -1);
+    if (found) {
+        m_gestures.removeAt(ix) ;
+    }
+    return found ;
+}
+
+int QStm_GestureEngine::activeStreamCount() const
+{
+    return m_numOfActiveStreams ;
+}
+
+const qstmUiEventEngine::QStm_UiEventIf* QStm_GestureEngine::getUiEvents(int indexOfActiveStream) const
+{
+//#if defined(ADVANCED_POINTER_EVENTS)
+    // create temporary array of active event streams and initialize with zero
+    const qstmUiEventEngine::QStm_UiEventIf* activeEventPointers[qstmUiEventEngine::KMaxNumberOfPointers] ;
+    for (int x = 0; x < qstmUiEventEngine::KMaxNumberOfPointers; activeEventPointers[x++] = 0);
+    
+    // then fill from currently active event streams
+    int indextoactiveEventPointers = 0 ;
+    for (int i = 0; i < qstmUiEventEngine::KMaxNumberOfPointers; i++) {
+        if (m_uiEventStream[i] != NULL) {
+            activeEventPointers[indextoactiveEventPointers++] = m_uiEventStream[i] ;
+        }
+    }
+    // then return the active event stream asked
+    return activeEventPointers[indexOfActiveStream] ;
+//#else
+    // in single touch it is enough to return the only possible pointer
+//    return m_uiEventStream[indexOfActiveStream] ;
+//#endif
+}
+
+/*!
+ * Process the UI events
+ */
+void QStm_GestureEngine::handleUiEvent(const qstmUiEventEngine::QStm_UiEventIf& event )
+{
+    // process one incoming UI event
+    storeUiEvent(event) ;  // store the event to the "stream" based on the index of pointer
+    walkTroughGestures() ;  // and walk trough the gestures to process the UI event
+    updateUiEvents() ;
+    // If it was last release event, make sure no-one has the gestures locked
+    m_numOfActiveStreams = 0 ;
+    for (int i = 0; i < qstmUiEventEngine::KMaxNumberOfPointers; i++) {
+        if (m_uiEventStream[i] != NULL) m_numOfActiveStreams++ ;
+    }
+    
+    if (m_numOfActiveStreams == 0)
+    {
+        if (m_currentLockedGesture != -1)
+        {
+            QStm_GestureRecogniserIf* pgrif = m_gestures[m_currentLockedGesture] ;
+            pgrif->release(this) ;
+        }
+        m_currentLockedGesture = -1 ;
+    }
+}
+
+/*!
+ * Store the UI event.  There are max X "streams" of events, one for each
+ * pointer.  The streams are actually just pointers to the latest event, since the
+ * MUiEvent interface has methods to walk trough the chain of events.
+ */
+void QStm_GestureEngine::storeUiEvent(const qstmUiEventEngine::QStm_UiEventIf& event)
+{
+    m_uiEventStream[event.index()] = &event ;
+    m_numOfActiveStreams = 0 ;
+    for (int i = 0; i < qstmUiEventEngine::KMaxNumberOfPointers; i++) {
+        if (m_uiEventStream[i] != NULL) m_numOfActiveStreams++ ;
+    }
+}
+
+/*!
+ *  Call each gesture handler in turn until one claims to be in control of the gesture.
+ */
+void QStm_GestureEngine::walkTroughGestures()
+{
+    int newowner = -1 ;
+    int newlocker =  -1; //m_currentLockedGesture ;
+    // check if someone has locked the gesture
+    QStm_GestureRecognitionState thestate = ENotMyGesture ;
+    if (m_currentLockedGesture != -1) {
+        QStm_GestureRecogniserIf* pgrif = m_gestures[m_currentLockedGesture] ;
+        if (pgrif != NULL) {
+            if (m_loggingEnabled) {
+                // log entry about locked gesture (hmm.. should have added names to the MGestureRecogniserIf
+                LOGARG("locked gesture recognizer %d (addr %d), active streams %d", 
+                		m_currentLockedGesture, pgrif, m_numOfActiveStreams);
+            }
+
+            thestate = pgrif->recognise(m_numOfActiveStreams, this) ;
+            switch (thestate) {
+				case EGestureActive:
+				{
+					// This gesture recogniser owns the gesture, so release the lock
+					newlocker = -1 ;
+					newowner = m_currentLockedGesture ;
+					if (m_loggingEnabled) {
+						LOGARG("new owner %d lock release", m_currentLockedGesture);
+					}
+					break;
+				}
+				case ELockToThisGesture:
+				{
+					// this gesture recogniser wants to keep the lock
+					newowner = m_currentLockedGesture ;
+					newlocker = m_currentLockedGesture ;
+					if (m_loggingEnabled) {
+						LOGARG("new owner %d keep lock", m_currentLockedGesture);
+					}
+					break;
+	
+				}
+				case ENotMyGesture:
+				{
+					break;
+				}
+            }
+        }
+        else {
+            if (m_loggingEnabled) {
+                LOGARG("NULL recogniser for %d", m_currentLockedGesture);
+            }
+        }
+    }
+    QStm_GestureRecognitionState currentState = ENotMyGesture;
+    if (thestate == ENotMyGesture) {
+        if (m_loggingEnabled) {
+            LOGARG("walk trough recognizers active streams %d", m_numOfActiveStreams);
+        }
+        // No locking gesture, walk trough the list until someone handles this
+        int gcount = m_gestures.count();
+        if (m_currentGestureOwner > -1) {
+            QStm_GestureRecogniserIf* gestureOwner = m_gestures[m_currentGestureOwner] ;
+            currentState = gestureOwner->state();
+        }
+        else {
+            currentState = ENotMyGesture;
+        }
+        
+        for (int i = 0; i < gcount; i++) {
+            bool controlObtained = false;
+            QStm_GestureRecogniserIf* pgrif = m_gestures[i];
+            
+            
+            if (pgrif != NULL) {
+                switch (pgrif->recognise(m_numOfActiveStreams, this)) {
+					case EGestureActive:
+					{
+						// This gesture recogniser owns the gesture, stop looping...
+						controlObtained = true;
+						newowner = i;
+						break;
+					}
+					case ELockToThisGesture:
+					{
+						// this gesture recogniser wants to take ownership
+						controlObtained = true;
+						newowner = i;
+						newlocker = i;
+						break;
+	
+					}
+					case ENotMyGesture:
+					{
+						break;
+					}
+                }
+                LOGARG("walkTroughGestures: 0x%x, recognizers count %d, newowner %d, m_currentGestureOwner %d", 
+                		pgrif, gcount, newowner, m_currentGestureOwner);
+            }
+            if (controlObtained)  {
+                break; // do not process rest of the gestures
+            }
+
+        }
+    }
+    if (newowner != m_currentGestureOwner) {
+        if (m_currentGestureOwner != -1 ) {
+            QStm_GestureRecogniserIf* pgrif = m_gestures[m_currentGestureOwner] ;
+            if ((currentState == EGestureActive || currentState == ELockToThisGesture) &&
+                 pgrif->state() == ENotMyGesture) {
+                
+                pgrif->release(this) ;
+            }
+        }
+        m_currentGestureOwner = newowner ;
+    }
+    m_currentLockedGesture = newlocker ;    // if someone locked it or released the lock
+}
+
+void QStm_GestureEngine::updateUiEvents()
+{
+    for (int i = 0; i < qstmUiEventEngine::KMaxNumberOfPointers; i++) {
+        if (m_uiEventStream[i] != NULL) {
+            if (m_uiEventStream[i]->code() == qstmUiEventEngine::ERelease) {
+                // Event can be removed since Release is the last event
+                // note that it is the lower layer event engine
+                // which actually deletes the object
+                m_uiEventStream[i] = NULL ;
+            }
+        }
+    }
+}
+
+