Esempio n. 1
0
nsEventStatus
SelectionCarets::HandleEvent(WidgetEvent* aEvent)
{
  WidgetMouseEvent *mouseEvent = aEvent->AsMouseEvent();
  if (mouseEvent && mouseEvent->reason == WidgetMouseEvent::eSynthesized) {
    return nsEventStatus_eIgnore;
  }

  WidgetTouchEvent *touchEvent = aEvent->AsTouchEvent();
  nsIntPoint movePoint;
  int32_t nowTouchId = -1;
  if (touchEvent && !touchEvent->touches.IsEmpty()) {
    // If touch happened, just grab event with same identifier
    if (mActiveTouchId >= 0) {
      for (uint32_t i = 0; i < touchEvent->touches.Length(); ++i) {
        if (touchEvent->touches[i]->Identifier() == mActiveTouchId) {
          movePoint = touchEvent->touches[i]->mRefPoint;
          nowTouchId = touchEvent->touches[i]->Identifier();
          break;
        }
      }

      // not found, consume it
      if (nowTouchId == -1) {
        return nsEventStatus_eConsumeNoDefault;
      }
    } else {
      movePoint = touchEvent->touches[0]->mRefPoint;
      nowTouchId = touchEvent->touches[0]->Identifier();
    }
  } else if (mouseEvent) {
    movePoint = LayoutDeviceIntPoint::ToUntyped(mouseEvent->AsGUIEvent()->refPoint);
  }

  // Get event coordinate relative to canvas frame
  nsIFrame* canvasFrame = mPresShell->GetCanvasFrame();
  if (!canvasFrame) {
    return nsEventStatus_eIgnore;
  }
  nsPoint ptInCanvas =
    nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, movePoint, canvasFrame);

  if (aEvent->message == NS_TOUCH_START ||
      (aEvent->message == NS_MOUSE_BUTTON_DOWN &&
       mouseEvent->button == WidgetMouseEvent::eLeftButton)) {
    // If having a active touch, ignore other touch down event
    if (aEvent->message == NS_TOUCH_START && mActiveTouchId >= 0) {
      return nsEventStatus_eConsumeNoDefault;
    }

    mActiveTouchId = nowTouchId;
    mDownPoint = ptInCanvas;
    int32_t inflateSize = SelectionCaretsInflateSize();
    if (mVisible && IsOnRect(GetStartFrameRect(), ptInCanvas, inflateSize)) {
      mDragMode = START_FRAME;
      mCaretCenterToDownPointOffsetY = GetCaretYCenterPosition() - ptInCanvas.y;
      SetSelectionDirection(false);
      SetMouseDownState(true);
      return nsEventStatus_eConsumeNoDefault;
    } else if (mVisible && IsOnRect(GetEndFrameRect(), ptInCanvas, inflateSize)) {
      mDragMode = END_FRAME;
      mCaretCenterToDownPointOffsetY = GetCaretYCenterPosition() - ptInCanvas.y;
      SetSelectionDirection(true);
      SetMouseDownState(true);
      return nsEventStatus_eConsumeNoDefault;
    } else {
      mDragMode = NONE;
      mActiveTouchId = -1;
      SetVisibility(false);
      LaunchLongTapDetector();
    }
  } else if (aEvent->message == NS_TOUCH_END ||
             aEvent->message == NS_TOUCH_CANCEL ||
             aEvent->message == NS_MOUSE_BUTTON_UP) {
    CancelLongTapDetector();
    if (mDragMode != NONE) {
      // Only care about same id
      if (mActiveTouchId == nowTouchId) {
        SetMouseDownState(false);
        mDragMode = NONE;
        mActiveTouchId = -1;
      }
      return nsEventStatus_eConsumeNoDefault;
    }
  } else if (aEvent->message == NS_TOUCH_MOVE ||
             aEvent->message == NS_MOUSE_MOVE) {
    if (mDragMode == START_FRAME || mDragMode == END_FRAME) {
      if (mActiveTouchId == nowTouchId) {
        ptInCanvas.y += mCaretCenterToDownPointOffsetY;
        return DragSelection(ptInCanvas);
      }

      return nsEventStatus_eConsumeNoDefault;
    }

    nsPoint delta = mDownPoint - ptInCanvas;
    if (NS_hypot(delta.x, delta.y) >
          nsPresContext::AppUnitsPerCSSPixel() * kMoveStartTolerancePx) {
      CancelLongTapDetector();
    }
  } else if (aEvent->message == NS_MOUSE_MOZLONGTAP) {
    if (!mVisible) {
      SelectWord();
      return nsEventStatus_eConsumeNoDefault;
    }
  }
  return nsEventStatus_eIgnore;
}
Esempio n. 2
0
nsEventStatus
SelectionCarets::HandleEvent(WidgetEvent* aEvent)
{
  WidgetMouseEvent *mouseEvent = aEvent->AsMouseEvent();
  if (mouseEvent && mouseEvent->reason == WidgetMouseEvent::eSynthesized) {
    return nsEventStatus_eIgnore;
  }

  WidgetTouchEvent *touchEvent = aEvent->AsTouchEvent();
  LayoutDeviceIntPoint movePoint;
  int32_t nowTouchId = -1;
  if (touchEvent && !touchEvent->touches.IsEmpty()) {
    // If touch happened, just grab event with same identifier
    if (mActiveTouchId >= 0) {
      for (uint32_t i = 0; i < touchEvent->touches.Length(); ++i) {
        if (touchEvent->touches[i]->Identifier() == mActiveTouchId) {
          movePoint = touchEvent->touches[i]->mRefPoint;
          nowTouchId = touchEvent->touches[i]->Identifier();
          break;
        }
      }

      // not found, consume it
      if (nowTouchId == -1) {
        return nsEventStatus_eConsumeNoDefault;
      }
    } else {
      movePoint = touchEvent->touches[0]->mRefPoint;
      nowTouchId = touchEvent->touches[0]->Identifier();
    }
  } else if (mouseEvent) {
    movePoint = mouseEvent->AsGUIEvent()->refPoint;
  }

  // XUL has no SelectionCarets elements.
  if (!mPresShell->GetSelectionCaretsStartElement() ||
      !mPresShell->GetSelectionCaretsEndElement()) {
    return nsEventStatus_eIgnore;
  }

  // Get event coordinate relative to root frame
  nsIFrame* rootFrame = mPresShell->GetRootFrame();
  if (!rootFrame) {
    return nsEventStatus_eIgnore;
  }
  nsPoint ptInRoot =
    nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, movePoint, rootFrame);

  if (aEvent->mMessage == eTouchStart ||
      (aEvent->mMessage == eMouseDown &&
       mouseEvent->button == WidgetMouseEvent::eLeftButton)) {
    // If having a active touch, ignore other touch down event
    if (aEvent->mMessage == eTouchStart && mActiveTouchId >= 0) {
      return nsEventStatus_eConsumeNoDefault;
    }

    mActiveTouchId = nowTouchId;
    mDownPoint = ptInRoot;
    if (IsOnStartFrameInner(ptInRoot)) {
      mDragMode = START_FRAME;
      mCaretCenterToDownPointOffsetY = GetCaretYCenterPosition() - ptInRoot.y;
      SetSelectionDirection(eDirPrevious);
      SetSelectionDragState(true);
      return nsEventStatus_eConsumeNoDefault;
    } else if (IsOnEndFrameInner(ptInRoot)) {
      mDragMode = END_FRAME;
      mCaretCenterToDownPointOffsetY = GetCaretYCenterPosition() - ptInRoot.y;
      SetSelectionDirection(eDirNext);
      SetSelectionDragState(true);
      return nsEventStatus_eConsumeNoDefault;
    } else {
      mDragMode = NONE;
      mActiveTouchId = -1;
      LaunchLongTapDetector();
    }
  } else if (aEvent->mMessage == eTouchEnd ||
             aEvent->mMessage == eTouchCancel ||
             aEvent->mMessage == eMouseUp) {
    CancelLongTapDetector();
    if (mDragMode != NONE) {
      // Only care about same id
      if (mActiveTouchId == nowTouchId) {
        SetSelectionDragState(false);
        mDragMode = NONE;
        mActiveTouchId = -1;
      }
      return nsEventStatus_eConsumeNoDefault;
    }
  } else if (aEvent->mMessage == eTouchMove || aEvent->mMessage == eMouseMove) {
    if (mDragMode == START_FRAME || mDragMode == END_FRAME) {
      if (mActiveTouchId == nowTouchId) {
        ptInRoot.y += mCaretCenterToDownPointOffsetY;

        if (mDragMode == START_FRAME) {
          if (ptInRoot.y > mDragDownYBoundary) {
            ptInRoot.y = mDragDownYBoundary;
          }
        } else if (mDragMode == END_FRAME) {
          if (ptInRoot.y < mDragUpYBoundary) {
            ptInRoot.y = mDragUpYBoundary;
          }
        }
        return DragSelection(ptInRoot);
      }

      return nsEventStatus_eConsumeNoDefault;
    }

    nsPoint delta = mDownPoint - ptInRoot;
    if (NS_hypot(delta.x, delta.y) >
          nsPresContext::AppUnitsPerCSSPixel() * kMoveStartTolerancePx) {
      CancelLongTapDetector();
    }

  } else if (aEvent->mMessage == eMouseLongTap) {
    if (!mVisible || !sSelectionCaretDetectsLongTap) {
      SELECTIONCARETS_LOG("SelectWord from eMouseLongTap");

      mDownPoint = ptInRoot;
      nsresult wordSelected = SelectWord();

      if (NS_FAILED(wordSelected)) {
        SELECTIONCARETS_LOG("SelectWord from eMouseLongTap failed!");
        return nsEventStatus_eIgnore;
      }

      return nsEventStatus_eConsumeNoDefault;
    }
  }
  return nsEventStatus_eIgnore;
}