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