Exemple #1
0
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;
}
Exemple #3
0
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;
}