qstmgesturelib/qstmgestureevent.cpp
author hgs
Fri, 15 Oct 2010 17:30:59 -0400
changeset 16 3c88a81ff781
parent 3 0954f5dd2cd0
permissions -rw-r--r--
201041

/*
* 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 "qstmgestureevent.h"
#include "qstmuievent_if.h"

#include <QGraphicsSceneMouseEvent>

using namespace qstmUiEventEngine;
using namespace qstmGesture;

static Qt::GestureType s_assignedType = Qt::CustomGesture;
static int s_stmGestureEventType = QEvent::User;
static QGraphicsItem* s_gestureGrabberItem = NULL;
static QGraphicsItem* s_gestureFocusedItem = NULL;


QStm_GestureEventFilter* QStm_GestureEventFilter::m_instance = 0;

QStm_GestureEventFilter* QStm_GestureEventFilter::instance()
{
    if (!m_instance) {
        m_instance = new QStm_GestureEventFilter();
    }
    return m_instance;
}

bool QStm_GestureEventFilter::eventFilter(QObject* receiver, QEvent* evt)
{
    return qstmIsGraphicsSceneMouseEvent(evt) || qstmIsMouseEvent(evt) || 
           qstmIsTouchEvent(evt) || qstmIsContextMenuEvent(evt);
}




bool QStm_GestureEventFilter::sendGraphicsSceneMouseEvent(QEvent* event, QGraphicsObject* go)
{
    bool ret = false;
    if (event->type() == QEvent::Gesture) {
        QStm_Gesture* gesture = getQStmGesture(event);
        if (gesture) {
            ret = gesture->sendGraphicsSceneMouseEvent(go);
        }

    }
    return ret;
}


bool QStm_GestureEventFilter::event(QEvent* event)
{
    if (event->type() == QEvent::Gesture) {
        QStm_Gesture* gesture = getQStmGesture(event);
        if (gesture) {
            QStm_GestureType gtype = gesture->getGestureStmType();
            
            /*
             * Touch mapped to mouse press, Tap mapped to mouse release
             * UpDown, LeftRight and Pan are mapped to mouse move.
             */
            if (gtype == QStmMaybeTapGestureType) {// in case of tap send mouse release
                gesture->setGestureStmType(QStmReleaseGestureType);
            }
            
            bool ret = (gtype == QStmTouchGestureType ||
                        gtype == QStmMaybeTapGestureType ||
                        gtype == QStmLeftRightGestureType || 
                        gtype == QStmUpDownGestureType ||
                        gtype == QStmPanGestureType ||
                        gtype == QStmReleaseGestureType ||
                        gtype == QStmFlickGestureType ||
                        gtype == QStmUknownGestureType) ;
                         
            if (ret) {
                gesture->sendMouseEvents();
                (static_cast<QGestureEvent*>(event))->accept(QStm_Gesture::assignedType());
                (static_cast<QGestureEvent*>(event))->accept();
            }
            
            if (gtype == QStmTapGestureType) {// restore gesture type. 
                gesture->setGestureStmType(QStmTapGestureType);
            }
            
            return ret;
        }
    }
    return false;
}






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

{
}

QStm_GestureEvent::~QStm_GestureEvent()
{
}


QEvent::Type QStm_GestureEvent::stmGestureEventType() 
{ 
    if (s_stmGestureEventType == QEvent::User) {
        s_stmGestureEventType = QEvent::registerEventType(QStmGestureEventType);    
    }
    return static_cast<QEvent::Type>(QStmGestureEventType); 
}



void QStm_Gesture::setAssignedGestureType(Qt::GestureType type) 
{ 
    s_assignedType = type; 
}

Qt::GestureType QStm_Gesture::assignedType() 
{ 
    return s_assignedType; 
} 


QGraphicsItem* QStm_Gesture::gestureGrabberItem()
{ 
    return s_gestureGrabberItem; 
}

void QStm_Gesture::setGestureGrabberItem(QGraphicsItem* item)
{ 
    s_gestureGrabberItem = item; 
}


QGraphicsItem* QStm_Gesture::gestureFocusedItem()
{
    return s_gestureFocusedItem;
}

void QStm_Gesture::setGestureFocusedItem(QGraphicsItem* item)
{
    s_gestureFocusedItem = item;
}

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_pos2 = QPoint(INT_MIN,INT_MIN);
	    m_details = NULL;
	    m_speedVec = QPointF(0.0, 0.0);
	    m_target = NULL;
        m_timestamp = QTime::currentTime();
};


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_pos2 = other.position2();
    m_details = other.getDetails();
    m_speedVec = other.getSpeedVec();
    m_target = other.target();
    m_timestamp = other.timestamp();
    setHotSpot(other.hotSpot());
	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");
    }	
}



QStm_GestureType  QStm_Gesture::gestureUidToStmType(QStm_GestureUid uid, int stmGestSubType)
{
    QStm_GestureType  gtype = QStmUknownGestureType;
    
    switch (uid) {
        case EGestureUidTap:
        {
            QStm_TapType type = qstmGesture::QStm_TapType(stmGestSubType);
            if (type == qstmGesture::ETapTypeDouble) {
                gtype = QStmDoubleTapGestureType;
            }
            else  {
                gtype = QStmTapGestureType;
            }
            break;
        }

        case EGestureUidTouch:
        {
            gtype = QStmTouchGestureType;
            break;
        }

        case EGestureUidRelease:
        {
            gtype = QStmReleaseGestureType;
            break;
        }

        case EGestureUidFlick:
        {
            gtype = QStmFlickGestureType;
            break;
        }

        case EGestureUidLeftRight:
        {
            gtype = QStmLeftRightGestureType;
            break;
        }

        case EGestureUidUpDown:
        {
            gtype = QStmUpDownGestureType;
            break;
        }

        case EGestureUidPan:
        {
            gtype = QStmPanGestureType;
            break;
        }

        case EGestureUidHover:
        {
            gtype = QStmHoverGestureType;
            break;
        }

        case EGestureUidLongPress:
        {
            gtype = QStmLongPressGestureType;
            break;
        }

        case EGestureUidEdgeScroll:
        {
            gtype = QStmEdgeScrollGestureType;
            break;
        }

        case EGestureUidCornerZoom:
        {
            gtype = QStmCornerZoomGestureType;
            break;
        }

        case EGestureUidPinch:
        {
            gtype = QStmPinchGestureType;
            break;
        }
        case EGestureUidMaybeTap:
        {
            gtype = QStmMaybeTapGestureType;
            break;
        }
        default:
        {
            gtype = QStmUknownGestureType;
            break;
        }
    }    
    return gtype;
}

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:
		case QStmFlickGestureType:
		{
			types.append(QEvent::MouseButtonRelease);
			break;
		}
		case QStmTapGestureType:
        //case QStmMaybeTapGestureType:
		{
			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 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()) {
        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::None) {
            continue;
        }
        else if (mtype != QEvent::MouseButtonRelease && w) {
            QPoint wtl = w->mapToGlobal(w->pos());
            QRect wgeom = QRect(wtl, w->size());
            if (!wgeom.contains(m_pos)) {
                continue;
            }
        }

    	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;
    QWidget* modal = QApplication::activeModalWidget();

    
    
    if (modal) {
        target = modal;
    }
    
    if (target) {
        QPoint pos = target->mapFromGlobal(m_pos);
        w = target->childAt(pos);
        if (!w) {
            w = target;
        }
    }
    
    if (w) {
        if (modal) { //we send mouse events to modal dialogs.
            return(sendMouseEvents(w));
        }
        /*
        else if (event->type() == QStm_GestureEvent::stmGestureEventType() && 
            m_gstType == QStmUknownGestureType) {
            QStm_UiEventIf* uiEvent = static_cast<QStm_UiEventIf*>(m_details);
            
            if (uiEvent && m_target == modal) {
            //re-generate mouse events
                return(sendMouseEvents(w));
            }

        else {
                return(QApplication::sendEvent(w, event));
        }
    }
		*/
        else {
            if (!target->hasFocus()) {
                target->setFocus(Qt::MouseFocusReason);
            }
            return(QApplication::sendEvent(w, event));
        }
    }
    return false;
}


bool QStm_Gesture::sendGraphicsSceneMouseEvent(QGraphicsObject* go)
{
    QEvent::Type eventType = gestureType2GraphicsSceneMouseType();
    bool ret = false;

    if (eventType != QEvent::None) {
        QGraphicsSceneMouseEvent gsme(eventType);
        QPointF scenePos = qstmMapToScene(m_pos, go);
        qstmSetGraphicsSceneMouseEvent(scenePos, go, gsme);
        ret = go->event(&gsme);
    }
    return ret;
}


QEvent::Type QStm_Gesture::gestureType2GraphicsSceneMouseType()
{
    QEvent::Type type = QEvent::None;
    switch(m_gstType)
    {
        case QStmTouchGestureType:
            type = QEvent::GraphicsSceneMousePress;
            break;
        case QStmMaybeTapGestureType:
        case QStmReleaseGestureType:
        case QStmFlickGestureType:
            type = QEvent::GraphicsSceneMouseRelease;
            break;
        case QStmLeftRightGestureType:
        case QStmUpDownGestureType:
        case QStmPanGestureType:
            type = QEvent::GraphicsSceneMouseMove;
            break;
        case  QStmUknownGestureType:
        {
            QVarLengthArray<int, 4> mouseTypes;
            gestureTypeToMouseTypes(mouseTypes);
            switch (mouseTypes[0])
            {
                case QEvent::MouseButtonPress:
                    type = QEvent::GraphicsSceneMousePress;
                    break;
                case QEvent::MouseButtonRelease:
                    type = QEvent::GraphicsSceneMouseRelease;
                    break;
                case QEvent::MouseMove:
                    type = QEvent::GraphicsSceneMouseMove;
                    break;
            }
        }
    }
    return type;
}

bool QStm_Gesture::sendMouseEvents(Qt::KeyboardModifier modifier)
{
    QWidget* target = static_cast<QWidget*>(m_target);

    if (!target) {
        target = QApplication::widgetAt(m_pos);
    }
    if (!target) return false;
    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;
}


bool QStm_Gesture::isGestureEnded()
{
    bool gestureEnded = false;
    
    if (m_gstType == QStmUknownGestureType) {
        QStm_UiEventIf* uiEvent = static_cast<QStm_UiEventIf*>(m_details);
        if (uiEvent) {
            QEvent::Type evType = uiEvent->mapToMouseEventType();
            gestureEnded = (evType == ERelease);
        }
    }
    else if (m_gstType == QStmReleaseGestureType ||
             m_gstType == QStmFlickGestureType ||
             m_gstType == QStmTapGestureType ||
             m_gstType == QStmDoubleTapGestureType) {
        gestureEnded = true;
    }
    return gestureEnded;
}

bool QStm_Gesture::clearGestureFocusedItemIfNeeded()
{
    bool reset = isGestureEnded();
    if (reset) {
        QStm_Gesture::setGestureFocusedItem(NULL);
    }
    return reset;
}

void QStm_Gesture::updateGestureFocusedItemIfNeeded(QGraphicsItem* gi)
{
    if (isGestureEnded()) {
        QStm_Gesture::setGestureFocusedItem(NULL);        
    }
    else if (gestureState() != Qt::GestureFinished) { 
        QStm_Gesture::setGestureFocusedItem(gi);
    }    
}

QPointF QStm_Gesture::scenePosition(QGraphicsItem* i)
{
    return qstmMapToScene(m_pos, static_cast<QGraphicsObject*>(i));
}

QPointF QStm_Gesture::scenePosition2(QGraphicsItem* i)
{
    return qstmMapToScene(m_pos2, static_cast<QGraphicsObject*>(i));
}

QPointF QStm_Gesture::sceneSpeedVec(QGraphicsItem* i)
{
    QGraphicsObject* o = static_cast<QGraphicsObject*>(i);

    return qstmMapToScene(m_speedVec,o) - qstmMapToScene(QPointF(0, 0), o);
}

QPointF QStm_Gesture::sceneLengthAndDirection(QGraphicsItem* i)
{
    QGraphicsObject* o = static_cast<QGraphicsObject*>(i);

    return qstmMapToScene(QPointF(-m_vector.x(), m_vector.y()),o) - qstmMapToScene(QPointF(0, 0), o);
}

int QStm_Gesture::sceneDirection(QGraphicsItem *i)
{
    QStm_GestureDirection dir = ENorth ;
    QPointF v = sceneLengthAndDirection(i);

    qreal x = qAbs(v.x()) ;
    qreal y = qAbs(v.y()) ;

    if (y == 0 && x == 0) {
        dir = ENoDirection;
    }
    else if (y <= x/2) {
        if (v.x() < 0)
            dir = EWest ;
        else
            dir = EEast ;
    }
    else if (y > x/2 && y <= (x+x/2)) {
        if (v.x() < 0)  {
            if (v.y() < 0 )
                dir = ESouthWest ;
            else
                dir = ENorthWest ;
        }
        else {
            if (v.y() < 0 )
                dir = ESouthEast ;
            else
                dir = ENorthEast ;
        }
    }
    else if (y > x+x/2) {
        if (v.y() < 0)
            dir = ESouth ;
        else
            dir = ENorth ;
    }

    return dir ;
}

QSTMGESTURELIB_EXPORT QPoint qstmMapFromScene(const QPointF& gpos, QGraphicsObject* graphicsObj)
{
    QGraphicsView* grView = qstmGetGraphicsView(graphicsObj);
    QPointF pos = QPointF(0.0, 0.0);
    if (grView) {
        pos = grView->mapFromScene(gpos);
        return grView->mapToGlobal(pos.toPoint());
    }
    return QPoint(0, 0);
}


QSTMGESTURELIB_EXPORT QPointF qstmMapToScene(const QPointF& gpos, QGraphicsObject* graphicsObj)
{
    QGraphicsView* grView = qstmGetGraphicsView(graphicsObj);
    QPointF pos = QPointF(0.0, 0.0);
    if (grView) {
        pos = grView->mapFromGlobal(gpos.toPoint());
        pos = grView->mapToScene(pos.toPoint());
    }
    return pos;
}


QSTMGESTURELIB_EXPORT QPointF qstmMapFromGlobal(const QPointF& gpos, QGraphicsObject* graphicsObj)
{
    QGraphicsView* grView = qstmGetGraphicsView(graphicsObj);
    QPointF pos = QPointF(0.0, 0.0);
    if (grView) {
        pos = grView->mapFromGlobal(gpos.toPoint());
    }
    return pos;
}

QSTMGESTURELIB_EXPORT QGraphicsView* qstmGetGraphicsView(QGraphicsObject* graphicsObj)
{
    QGraphicsScene* scene = graphicsObj->scene();
    QList<QGraphicsView*> gvList = scene->views();
    QList<QGraphicsView*>::iterator it;
    
    /*
    for (it = gvList.begin(); it != gvList.end(); it++) {
        if (static_cast<QGraphicsView*>(*it)->hasFocus()) {
            return static_cast<QGraphicsView*>(*it);
        }
    }
    */
    return gvList.isEmpty() ? NULL : gvList[0];
}

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;
}

QSTMGESTURELIB_EXPORT bool qstmDeliverGestureEventToGraphicsItem(QGraphicsView* gv, QEvent* event)
{
    if (event->type() != QEvent::Gesture) return false;
    
    bool ret = false;
    QStm_Gesture* gesture = getQStmGesture(event);
    if (gesture) {

        QGraphicsScene* gs = gv->scene();
        QGraphicsItem* gestureGrabber = QStm_Gesture::gestureGrabberItem();
        QGraphicsItem* gi = QStm_Gesture::gestureFocusedItem();
        QGraphicsItem* mgItem = gs->mouseGrabberItem();
        
        if (gestureGrabber) {
            gs->sendEvent(gestureGrabber, event);
            ret = true; //no fallback to mouse events   
        }
        else {
            if (!gi) {
                gi = mgItem;
            }
            if (!gi) {
                QPoint pos = gv->mapFromGlobal(gesture->position());
                pos = gv->mapToScene(pos).toPoint();
                QList<QGraphicsItem *> itemsList = gs->items(pos, Qt::IntersectsItemShape,
                                                             Qt::DescendingOrder);
                for(int i = 0; i < itemsList.size(); i++) {

                    if (itemsList[i] && (itemsList[i])->opacity() < qreal(0.001)) {
                        continue;
                    }
                    gi = itemsList[i];
                    gs->setFocusItem(gi, Qt::MouseFocusReason);
                    break;
                }
            }
            if (gi) {
                //gs->setFocusItem(gi, Qt::MouseFocusReason);
                //ret = gs->sendEvent(gi, event);
                //gs->setFocusItem(0, Qt::MouseFocusReason);

                QGraphicsObject* go = gi->toGraphicsObject();
                if (go) {
                    ret = go->event(event);
                }

            }
        }
        
        if (!ret) { // fallback to mouse events
            QStm_GestureEventFilter::instance()->event(event);
            ret = true;
        }
        else if (!gestureGrabber) {
            gesture->updateGestureFocusedItemIfNeeded(gi);
        }
    }
    return ret;
}


QSTMGESTURELIB_EXPORT void qstmSetGraphicsSceneMouseEvent(const QPointF& scenePos, QGraphicsObject* graphicsObj,
                                                         QGraphicsSceneMouseEvent& event, bool select)
{
    QPointF pos = scenePos;
    QPoint gpos = qstmMapFromScene(pos, graphicsObj);

    event.setScenePos(pos);
    event.setScreenPos(gpos);
    event.setPos(graphicsObj->mapFromScene(pos));
    if (!select && event.type() != QEvent::GraphicsSceneMouseMove) {
        event.setButton(Qt::LeftButton);
    }
    else {
        event.setButton(Qt::NoButton);
    }
    if (!select) {
        event.setButtons(Qt::NoButton);
    }
    else {
        event.setButtons(Qt::LeftButton);
    }
    event.setModifiers(Qt::NoModifier);
}

QSTMGESTURELIB_EXPORT bool qstmIsGraphicsSceneMouseEvent(QEvent* event)
{
    QEvent::Type  type = event->type();
    return type == QEvent::GraphicsSceneMouseMove ||
           type == QEvent::GraphicsSceneMousePress ||
           type == QEvent::GraphicsSceneMouseRelease ||
           type == QEvent::GraphicsSceneMouseDoubleClick;
}

QSTMGESTURELIB_EXPORT bool qstmIsMouseEvent(QEvent* event)
{
    QEvent::Type  type = event->type();
    return type == QEvent::MouseButtonPress ||
           type == QEvent::MouseButtonRelease ||
           type == QEvent::MouseMove ||
           type == QEvent::MouseButtonDblClick;
}

QSTMGESTURELIB_EXPORT bool qstmIsTouchEvent(QEvent* event)
{
    QEvent::Type  type = event->type();
    return type == QEvent::TouchBegin ||
           type == QEvent::TouchEnd ||
           type == QEvent::TouchUpdate;
}

QSTMGESTURELIB_EXPORT bool qstmIsContextMenuEvent(QEvent* event)
{
    QEvent::Type  type = event->type();
    return type == QEvent::ContextMenu ||
           type == QEvent::GraphicsSceneContextMenu;
}