nsEventStatus AsyncPanZoomController::HandleInputEvent(const InputEvent& event) { nsEventStatus rv = nsEventStatus_eIgnore; if (!mIsCompositing) return rv; switch (event.mMessage) { case MULTITOUCH_START_POINTER: case MULTITOUCH_START: rv = OnTouchStart((const MultiTouchEvent&)event); break; case MULTITOUCH_MOVE: rv = OnTouchMove((const MultiTouchEvent&)event); break; case MULTITOUCH_END: rv = OnTouchEnd((const MultiTouchEvent&)event); break; case MULTITOUCH_CANCEL: rv = OnTouchCancel((const MultiTouchEvent&)event); break; case PINCH_START: rv = OnScaleBegin((const PinchEvent&)event); break; case PINCH_SCALE: rv = OnScale((const PinchEvent&)event); break; case PINCH_END: rv = OnScaleEnd((const PinchEvent&)event); break; case TAP_LONG: rv = OnLongPress((const TapEvent&)event); break; case TAP_UP: rv = OnSingleTapUp((const TapEvent&)event); break; case TAP_CONFIRMED: rv = OnSingleTapConfirmed((const TapEvent&)event); break; case TAP_DOUBLE: rv = OnDoubleTap((const TapEvent&)event); break; case TAP_CANCEL: rv = OnCancelTap((const TapEvent&)event); break; default: break; } mLastEventTime = event.mTime; return rv; }
nsEventStatus AsyncPanZoomController::HandleInputEvent(const InputData& aEvent) { nsEventStatus rv = nsEventStatus_eIgnore; if (mGestureEventListener) { nsEventStatus rv = mGestureEventListener->HandleInputEvent(aEvent); if (rv == nsEventStatus_eConsumeNoDefault) return rv; } switch (aEvent.mInputType) { case MULTITOUCH_INPUT: { const MultiTouchInput& multiTouchInput = aEvent.AsMultiTouchInput(); switch (multiTouchInput.mType) { case MultiTouchInput::MULTITOUCH_START: rv = OnTouchStart(multiTouchInput); break; case MultiTouchInput::MULTITOUCH_MOVE: rv = OnTouchMove(multiTouchInput); break; case MultiTouchInput::MULTITOUCH_END: rv = OnTouchEnd(multiTouchInput); break; case MultiTouchInput::MULTITOUCH_CANCEL: rv = OnTouchCancel(multiTouchInput); break; default: NS_WARNING("Unhandled multitouch"); break; } break; } case PINCHGESTURE_INPUT: { const PinchGestureInput& pinchGestureInput = aEvent.AsPinchGestureInput(); switch (pinchGestureInput.mType) { case PinchGestureInput::PINCHGESTURE_START: rv = OnScaleBegin(pinchGestureInput); break; case PinchGestureInput::PINCHGESTURE_SCALE: rv = OnScale(pinchGestureInput); break; case PinchGestureInput::PINCHGESTURE_END: rv = OnScaleEnd(pinchGestureInput); break; default: NS_WARNING("Unhandled pinch gesture"); break; } break; } case TAPGESTURE_INPUT: { const TapGestureInput& tapGestureInput = aEvent.AsTapGestureInput(); switch (tapGestureInput.mType) { case TapGestureInput::TAPGESTURE_LONG: rv = OnLongPress(tapGestureInput); break; case TapGestureInput::TAPGESTURE_UP: rv = OnSingleTapUp(tapGestureInput); break; case TapGestureInput::TAPGESTURE_CONFIRMED: rv = OnSingleTapConfirmed(tapGestureInput); break; case TapGestureInput::TAPGESTURE_DOUBLE: rv = OnDoubleTap(tapGestureInput); break; case TapGestureInput::TAPGESTURE_CANCEL: rv = OnCancelTap(tapGestureInput); break; default: NS_WARNING("Unhandled tap gesture"); break; } break; } default: NS_WARNING("Unhandled input event"); break; } mLastEventTime = aEvent.mTime; return rv; }
bool CTouchInput::Handle(TouchEvent event, float x, float y, int64_t time, int32_t pointer /* = 0 */, float size /* = 0.0f */) { if (time < 0 || pointer < 0 || pointer >= TOUCH_MAX_POINTERS) return false; CSingleLock lock(m_critical); bool result = true; m_pointers[pointer].current.x = x; m_pointers[pointer].current.y = y; m_pointers[pointer].current.time = time; switch (event) { case TouchEventAbort: { CLog::Log(LOGDEBUG, "CTouchInput: TouchEventAbort"); setGestureState(TouchGestureUnknown); for (unsigned int pIndex = 0; pIndex < TOUCH_MAX_POINTERS; pIndex++) m_pointers[pIndex].reset(); OnTouchAbort(); break; } case TouchEventDown: { CLog::Log(LOGDEBUG, "CTouchInput: TouchEventDown"); m_pointers[pointer].down.x = x; m_pointers[pointer].down.y = y; m_pointers[pointer].down.time = time; m_pointers[pointer].moving = false; m_pointers[pointer].size = size; // If this is the down event of the primary pointer // we start by assuming that it's a single touch if (pointer == 0) { setGestureState(TouchGestureSingleTouch); result = OnSingleTouchStart(x, y); m_holdTimer->Start(m_holdTimeout); } // Otherwise it's the down event of another pointer else { // If we so far assumed single touch or still have the primary // pointer of a previous multi touch pressed down, we can update to multi touch if (m_gestureState == TouchGestureSingleTouch || m_gestureState == TouchGestureSingleTouchHold || m_gestureState == TouchGestureMultiTouchDone) { if (m_gestureState == TouchGestureSingleTouch || m_gestureState == TouchGestureSingleTouchHold) { result = OnMultiTouchStart(x, y); m_holdTimer->Stop(true); m_holdTimer->Start(m_holdTimeout); } else { result = OnMultiTouchDown(x, y, pointer); m_holdTimer->Stop(false); } setGestureState(TouchGestureMultiTouchStart); m_fRotateAngle = 0.0f; } // Otherwise we should ignore this pointer else { m_pointers[pointer].reset(); break; } } return result; } case TouchEventUp: { CLog::Log(LOGDEBUG, "CTouchInput: TouchEventUp"); // unexpected event => abort if (!m_pointers[pointer].valid() || m_gestureState == TouchGestureUnknown) break; m_holdTimer->Stop(false); // Just a single tap with a pointer if (m_gestureState == TouchGestureSingleTouch || m_gestureState == TouchGestureSingleTouchHold) { result = OnSingleTouchEnd(x, y); if (m_gestureState == TouchGestureSingleTouch) OnSingleTap(x, y); } // A pan gesture started with a single pointer (ignoring any other pointers) else if (m_gestureState == TouchGesturePan) { float velocityX = 0.0f; // number of pixels per second float velocityY = 0.0f; // number of pixels per second m_pointers[pointer].velocity(velocityX, velocityY, false); result = OnTouchGesturePanEnd(x, y, x - m_pointers[pointer].down.x, y - m_pointers[pointer].down.y, velocityX, velocityY); } // we are in multi-touch else result = OnMultiTouchUp(x, y, pointer); // If we were in multi touch mode and lifted one pointer // we can go into the TouchGestureMultiTouchDone state which will allow // the user to go back into multi touch mode without lifting the primary pointer if (m_gestureState == TouchGestureMultiTouchStart || m_gestureState == TouchGestureMultiTouchHold || m_gestureState == TouchGestureMultiTouch) { setGestureState(TouchGestureMultiTouchDone); // after lifting the primary pointer, the secondary pointer will // become the primary pointer in the next event if (pointer == 0) { m_pointers[0] = m_pointers[1]; pointer = 1; } } // Otherwise abort else { if (m_gestureState == TouchGestureMultiTouchDone) { result = OnMultiTouchEnd(m_pointers[0].down.x, m_pointers[0].down.y); // if neither of the two pointers moved we have a double tap if (m_gestureStateOld != TouchGestureMultiTouchHold && m_gestureStateOld != TouchGestureMultiTouch) OnDoubleTap(m_pointers[0].down.x, m_pointers[0].down.y, m_pointers[1].down.x, m_pointers[1].down.y); } setGestureState(TouchGestureUnknown); } m_pointers[pointer].reset(); return result; } case TouchEventMove: { CLog::Log(LOGDEBUG, "CTouchInput: TouchEventMove"); // unexpected event => abort if (!m_pointers[pointer].valid() || m_gestureState == TouchGestureUnknown || m_gestureState == TouchGestureMultiTouchDone) break; if (m_pointers[pointer].moving) m_holdTimer->Stop(); if (m_gestureState == TouchGestureSingleTouch) { // Check if the touch has moved far enough to count as movement if (!m_pointers[pointer].moving) break; result = OnTouchGesturePanStart(m_pointers[pointer].down.x, m_pointers[pointer].down.y); m_pointers[pointer].last.copy(m_pointers[pointer].down); setGestureState(TouchGesturePan); } else if (m_gestureState == TouchGestureMultiTouchStart) { setGestureState(TouchGestureMultiTouch); // set the starting point saveLastTouch(); } float offsetX = x - m_pointers[pointer].last.x; float offsetY = y - m_pointers[pointer].last.y; float velocityX = 0.0f; // number of pixels per second float velocityY = 0.0f; // number of pixels per second m_pointers[pointer].velocity(velocityX, velocityY); if (m_pointers[pointer].moving && (m_gestureState == TouchGestureSingleTouch || m_gestureState == TouchGestureSingleTouchHold || m_gestureState == TouchGesturePan)) result = OnSingleTouchMove(x, y, offsetX, offsetY, velocityX, velocityY); // Let's see if we have a pan gesture (i.e. the primary and only pointer moving) if (m_gestureState == TouchGesturePan) { result = OnTouchGesturePan(x, y, offsetX, offsetY, velocityX, velocityY); m_pointers[pointer].last.x = x; m_pointers[pointer].last.y = y; } else if (m_gestureState == TouchGestureMultiTouch) { if (m_pointers[pointer].moving) result = OnMultiTouchMove(x, y,offsetX, offsetY, velocityX, velocityY, pointer); handleMultiTouchGesture(); } else break; return result; } default: CLog::Log(LOGDEBUG, "CTouchInput: unknown TouchEvent"); break; } return false; }