qstmgesturelib/qstmgestureevent.cpp
author hgs
Thu, 23 Sep 2010 15:32:11 -0400
changeset 14 6aeb7a756187
parent 3 0954f5dd2cd0
child 16 3c88a81ff781
permissions -rw-r--r--
201037_03

/*
* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 2.1 of the License.
* 
* This program 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program.  If not, 
* see "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/".
*
* Description:
*
*/

#include <QWidget>
#include <QApplication>
#include "qstmgestureevent.h"
#include "qstmuievent_if.h"

using namespace qstmUiEventEngine;

Qt::GestureType QStm_Gesture::s_assignedType = Qt::CustomGesture;

QStm_GestureEvent::QStm_GestureEvent():
                   QEvent(QStm_GestureEvent::stmGestureEventType())

{
}

QStm_GestureEvent::~QStm_GestureEvent()
{
}





QStm_Gesture::QStm_Gesture(QObject* parent) : QGesture(parent)
{
	    m_speed = 0.0;    
	    m_direction = -1;
	    m_vector = QPoint(0,0);
	    m_gstType = QStmUknownGestureType; 
	    m_state = Qt::NoGesture;
	    m_gstSubType = 0;
	    m_pos = QPoint(INT_MIN,INT_MIN);
	    m_details = NULL;
	    m_speedVec = QPointF(0.0, 0.0);
	    m_target = NULL;
};


QStm_Gesture& QStm_Gesture::operator=(QStm_Gesture& other)
{
    m_speed = other.getSpeed();    
    m_direction = other.getDirection();
    m_vector = other.getLengthAndDirection();
    m_gstType = other.getGestureStmType(); 
    m_state = other.gestureState();
    m_gstSubType = other.getGestureSubType();
    m_pos = other.position();
    m_details = other.getDetails();
    m_speedVec = other.getSpeedVec();
    m_target = other.m_target;
	return *this;
}


QString  QStm_Gesture::gestureName()
{
    switch (m_gstType) {
        case QStmUknownGestureType:
            return QString("QStmUknownGestureType");    
        case QStmTouchGestureType:
            return QString("QStmTouchGestureType");
        case QStmTapGestureType:
            return QString("QStmTapGestureType");
        case QStmDoubleTapGestureType:
            return QString("QStmDoubleTapGestureType");
        case QStmLongPressGestureType:
            return QString("QStmLongPressGestureType");
        case QStmHoverGestureType:
            return QString("QStmHoverGestureType");
        case QStmPanGestureType:
            return QString("QStmPanGestureType");
        case QStmReleaseGestureType:
            return QString("QStmReleaseGestureType");
        case QStmLeftRightGestureType:
            return QString("QStmLeftRightGestureType");
        case QStmUpDownGestureType:
            return QString("QString");
        case QStmFlickGestureType:
            return QString("QStmFlickGestureType");
        case QStmEdgeScrollGestureType:
            return QString("QStmEdgeScrollGestureType");
        case QStmPinchGestureType:
            return QString("QStmPinchGestureType");
        case QStmCornerZoomGestureType:
            return QString("QStmCornerZoomGestureType");
        default:
            return QString("XZ Gesture");
    }	
}

void QStm_Gesture::gestureTypeToMouseTypes(QVarLengthArray<int, 4>& types)
{
	switch (m_gstType) {
		case QStmTouchGestureType:
		{
			types.append(QEvent::MouseButtonPress);
			break;
		}
		case QStmDoubleTapGestureType:
		{
			types.append(QEvent::MouseButtonDblClick);
			break;
		}

		case QStmHoverGestureType:
		case QStmPanGestureType:
		case QStmLeftRightGestureType:
		case QStmUpDownGestureType:
		case QStmCornerZoomGestureType:
		{
			types.append(QEvent::MouseMove);
			break;
		}
		case QStmReleaseGestureType:
		{
			types.append(QEvent::MouseButtonRelease);
			break;
		}
		case QStmTapGestureType:
		{
			types.append(QEvent::MouseButtonPress);
			types.append(QEvent::MouseButtonRelease); 
			break;
		}
		case QStmUknownGestureType:
		{
		    QStm_UiEventIf* uiEvent = static_cast<QStm_UiEventIf*>(m_details);
		    if (uiEvent) {
		        QEvent::Type evType = uiEvent->mapToMouseEventType();
		        types.append(evType);
		    }
		    break;
		}
		case QStmFlickGestureType:
		case QStmEdgeScrollGestureType:
		case QStmPinchGestureType:
		case QStmLongPressGestureType:
		default:
			break;
	}
	return;
}

bool QStm_Gesture::sendOrPostMouseEvents(QObject* receiver, Qt::KeyboardModifier modifier, bool send)
{
    bool ret = false;
    QPoint pos = position();
    QPoint gpos = pos;
    QWidget* w = NULL;
    Qt::MouseButtons buttons = Qt::LeftButton;
    
    
    buttons &= ~Qt::RightButton;
    buttons &= ~Qt::MidButton; 
    buttons &= Qt::MouseButtonMask;
    
    if (receiver->isWidgetType()) {
    	QWidget* w = static_cast<QWidget*>(receiver);
    	pos = w->mapFromGlobal(gpos);
    }    
    
    QVarLengthArray<int, 4> mouseTypes;
    gestureTypeToMouseTypes(mouseTypes);   
    
    for (int i = 0; i < mouseTypes.size(); i++) {
    	QEvent::Type mtype = static_cast<QEvent::Type>(mouseTypes[i]);
    	
    	if (mtype == QEvent::MouseButtonRelease) {
    		buttons = 0;
    	}
    	
    	if (send) {
    	    QMouseEvent evt(mtype, pos, gpos, Qt::LeftButton, buttons, modifier);
    	    if (w) w->grabMouse();
    	    QApplication::sendEvent(receiver, &evt);
    	    if (w) w->releaseMouse();
    	}
    	else {
    		QMouseEvent* evt = new QMouseEvent(mtype, pos, gpos, Qt::LeftButton, buttons, modifier);
    		QApplication::postEvent(receiver, evt);
    	}
    }
    
    return ret;
}


bool QStm_Gesture::sendEvent(QEvent* event)
{
    QWidget* target = static_cast<QWidget*>(m_target);
    QWidget* w = NULL;
    
    if (target) {
        QPoint pos = target->mapFromGlobal(m_pos);
        w = target->childAt(pos);
        if (!w) {
            w = target;
        }
    }
    
    if (w) {
        if (event->type() == QStm_GestureEvent::stmGestureEventType() && 
            m_gstType == QStmUknownGestureType) {
            QStm_UiEventIf* uiEvent = static_cast<QStm_UiEventIf*>(m_details);
            QWidget* modal = QApplication::activeModalWidget();
            if (uiEvent && m_target == modal) {
            //re-generate mouse events
                sendMouseEvents(w);
            }
        }        
        else {
            QApplication::sendEvent(w, event);
        }
    }
}


bool QStm_Gesture::sendMouseEvents(Qt::KeyboardModifier modifier)
{
    Q_ASSERT(m_target);
    QWidget* target = static_cast<QWidget*>(m_target);
    QPoint pos = target->mapFromGlobal(m_pos);
    QWidget* w = target->childAt(pos);
    if (!w) {
        w = target;
    }
    
    return sendMouseEvents(w);
}

bool QStm_Gesture::sendMouseEvents(QObject* receiver, Qt::KeyboardModifier modifier)
{
	return sendOrPostMouseEvents(receiver, modifier, true);
}

bool QStm_Gesture::postMouseEvents(QObject* receiver, Qt::KeyboardModifier modifier)
{
	return sendOrPostMouseEvents(receiver, modifier, false);
}

QList<QMouseEvent*>   QStm_Gesture::getMouseEvents()
{
	QList<QMouseEvent*> mouseEventsList;
    QPoint pos = position(); 
    QPoint gpos = pos;
    Qt::MouseButtons buttons = Qt::LeftButton;        
    buttons &= ~Qt::RightButton;
    buttons &= ~Qt::MidButton; 
    buttons &= Qt::MouseButtonMask;
        
    
    
    QVarLengthArray<int, 4> mouseTypes;
    gestureTypeToMouseTypes(mouseTypes);
    
    for (int i = 0; i < mouseTypes.size(); i++) {
        QMouseEvent* evt = new QMouseEvent(static_cast<QEvent::Type>(mouseTypes[i]), 
        		               pos, gpos, Qt::LeftButton, buttons, Qt::NoModifier);
        mouseEventsList.append(evt);
    }
	return mouseEventsList;
}


QSTMGESTURELIB_EXPORT QStm_Gesture*  getQStmGesture(QEvent* event)
{	
	QStm_Gesture* gesture = NULL;
	if (event->type() == QEvent::Gesture) {
	    QGestureEvent* ge = static_cast<QGestureEvent*>(event);
	    QList<QGesture*> l = ge->gestures();
	    QGesture* g = !l.isEmpty() ? l.at(0) : NULL;
	    if (g && g->gestureType() == QStm_Gesture::assignedType()) {
	        gesture = static_cast<QStm_Gesture*>(g);
	    }
	}
	return gesture;
}