--- a/qstmgesturelib/qstmgestureevent.cpp Thu Sep 23 15:32:11 2010 -0400
+++ b/qstmgesturelib/qstmgestureevent.cpp Fri Oct 15 17:30:59 2010 -0400
@@ -19,14 +19,97 @@
*
*/
-#include <QWidget>
-#include <QApplication>
#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;
+}
+
-Qt::GestureType QStm_Gesture::s_assignedType = Qt::CustomGesture;
+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())
@@ -39,8 +122,47 @@
}
+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)
{
@@ -51,9 +173,11 @@
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();
};
@@ -66,9 +190,12 @@
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.m_target;
+ m_target = other.target();
+ m_timestamp = other.timestamp();
+ setHotSpot(other.hotSpot());
return *this;
}
@@ -109,6 +236,104 @@
}
}
+
+
+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) {
@@ -133,11 +358,13 @@
break;
}
case QStmReleaseGestureType:
+ case QStmFlickGestureType:
{
types.append(QEvent::MouseButtonRelease);
break;
}
case QStmTapGestureType:
+ //case QStmMaybeTapGestureType:
{
types.append(QEvent::MouseButtonPress);
types.append(QEvent::MouseButtonRelease);
@@ -152,7 +379,6 @@
}
break;
}
- case QStmFlickGestureType:
case QStmEdgeScrollGestureType:
case QStmPinchGestureType:
case QStmLongPressGestureType:
@@ -162,6 +388,9 @@
return;
}
+
+
+
bool QStm_Gesture::sendOrPostMouseEvents(QObject* receiver, Qt::KeyboardModifier modifier, bool send)
{
bool ret = false;
@@ -176,25 +405,37 @@
buttons &= Qt::MouseButtonMask;
if (receiver->isWidgetType()) {
- QWidget* w = static_cast<QWidget*>(receiver);
+ 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();
+ //if (w) w->grabMouse();
QApplication::sendEvent(receiver, &evt);
- if (w) w->releaseMouse();
+ //if (w) w->releaseMouse();
}
else {
QMouseEvent* evt = new QMouseEvent(mtype, pos, gpos, Qt::LeftButton, buttons, modifier);
@@ -210,6 +451,13 @@
{
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);
@@ -220,26 +468,97 @@
}
if (w) {
- if (event->type() == QStm_GestureEvent::stmGestureEventType() &&
+ 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);
- QWidget* modal = QApplication::activeModalWidget();
+
if (uiEvent && m_target == modal) {
//re-generate mouse events
- sendMouseEvents(w);
+ return(sendMouseEvents(w));
}
- }
+
else {
- QApplication::sendEvent(w, event);
+ 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)
{
- Q_ASSERT(m_target);
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) {
@@ -283,6 +602,160 @@
}
+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;
@@ -297,3 +770,120 @@
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;
+}