/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
MultiTouchInput::MultiTouchInput(const WidgetTouchEvent& aTouchEvent)
: InputData(MULTITOUCH_INPUT, aTouchEvent.mTimeStamp,
aTouchEvent.mModifiers),
mHandledByAPZ(aTouchEvent.mFlags.mHandledByAPZ),
mButton(aTouchEvent.mButton),
mButtons(aTouchEvent.mButtons) {
MOZ_ASSERT(NS_IsMainThread(), "Can only copy from WidgetTouchEvent on main thread");
switch (aTouchEvent.mMessage) { case eTouchStart:
mType = MULTITOUCH_START; break; case eTouchMove:
mType = MULTITOUCH_MOVE; break; case eTouchEnd:
mType = MULTITOUCH_END; break; case eTouchCancel:
mType = MULTITOUCH_CANCEL; break; default:
MOZ_ASSERT_UNREACHABLE("Did not assign a type to a MultiTouchInput"); break;
}
for (auto& touchData : mTouches) { for (auto& historicalData : touchData.mHistoricalData) {
historicalData.mScreenPoint.MoveBy(translation.x, translation.y);
}
touchData.mScreenPoint.MoveBy(translation.x, translation.y);
}
}
WidgetTouchEvent MultiTouchInput::ToWidgetEvent(nsIWidget* aWidget,
uint16_t aInputSource) const {
MOZ_ASSERT(NS_IsMainThread(), "Can only convert To WidgetTouchEvent on main thread");
MOZ_ASSERT(aInputSource ==
mozilla::dom::MouseEvent_Binding::MOZ_SOURCE_TOUCH ||
aInputSource == mozilla::dom::MouseEvent_Binding::MOZ_SOURCE_PEN);
EventMessage touchEventMessage = eVoidEvent; switch (mType) { case MULTITOUCH_START:
touchEventMessage = eTouchStart; break; case MULTITOUCH_MOVE:
touchEventMessage = eTouchMove; break; case MULTITOUCH_END:
touchEventMessage = eTouchEnd; break; case MULTITOUCH_CANCEL:
touchEventMessage = eTouchCancel; break; default:
MOZ_ASSERT_UNREACHABLE( "Did not assign a type to WidgetTouchEvent in MultiTouchInput"); break;
}
template <class WidgetMouseOrPointerEvent>
WidgetMouseOrPointerEvent MouseInput::ToWidgetEvent(nsIWidget* aWidget) const {
MOZ_ASSERT(NS_IsMainThread(), "Can only convert To WidgetTouchEvent on main thread");
const DebugOnly<bool> isPointerEvent =
std::is_same<WidgetMouseOrPointerEvent, WidgetPointerEvent>::value; const DebugOnly<bool> isMouseEvent =
std::is_same<WidgetMouseOrPointerEvent, WidgetMouseEvent>::value; const DebugOnly<bool> isDragEvent =
std::is_same<WidgetMouseOrPointerEvent, WidgetDragEvent>::value;
MOZ_ASSERT(!IsPointerEventType() || isPointerEvent, "Please use ToWidgetEvent() for the instance");
MOZ_ASSERT(IsPointerEventType() || isMouseEvent || isDragEvent, "Please use ToWidgetEvent() or " "ToWidgetEvent() for the instance");
EventMessage msg = eVoidEvent;
uint32_t clickCount = 0;
Maybe<WidgetMouseEvent::ExitFrom> exitFrom; switch (mType) { case MOUSE_MOVE:
msg = eMouseMove; break; case MOUSE_UP:
msg = eMouseUp;
clickCount = 1; break; case MOUSE_DOWN:
msg = eMouseDown;
clickCount = 1; break; case MOUSE_DRAG_START:
msg = eDragStart; break; case MOUSE_DRAG_END:
msg = eDragEnd; break; case MOUSE_DRAG_ENTER:
msg = eDragEnter; break; case MOUSE_DRAG_OVER:
msg = eDragOver; break; case MOUSE_DRAG_EXIT:
msg = eDragExit; break; case MOUSE_DROP:
msg = eDrop; break; case MOUSE_WIDGET_ENTER:
msg = eMouseEnterIntoWidget; break; case MOUSE_WIDGET_EXIT:
msg = eMouseExitFromWidget;
exitFrom = Some(WidgetMouseEvent::ePlatformChild); break; case MOUSE_EXPLORE_BY_TOUCH:
msg = eMouseExploreByTouch; break; case MOUSE_HITTEST:
msg = eMouseHitTest; break; case MOUSE_CONTEXTMENU:
msg = eContextMenu;
MOZ_ASSERT(mButtonType == MouseInput::SECONDARY_BUTTON); break; default:
MOZ_ASSERT_UNREACHABLE( "Did not assign a type to WidgetMouseEvent in MouseInput"); break;
}
if (mDeltaType == PanGestureInput::PANDELTA_PAGE) { // Skip transforming the pan displacement because we want // raw page proportion counts.
mLocalPanDisplacement = ViewAs<ParentLayerPixel>(
mPanDisplacement, PixelCastJustification::DeltaIsPageProportion); returntrue;
}
double PinchGestureInput::ComputeDeltaY(nsIWidget* aWidget) const { #ifdefined(XP_DARWIN) // This converts the pinch gesture value to a fake wheel event that has the // control key pressed so that pages can implement custom pinch gesture // handling. It may seem strange that this doesn't use a wheel event with // the deltaZ property set, but this matches Chrome's behavior as described // at https://code.google.com/p/chromium/issues/detail?id=289887 // // The intent of the formula below is to produce numbers similar to Chrome's // implementation of this feature. Chrome implements deltaY using the formula // "-100 * log(1 + [event magnification])" which is unfortunately incorrect. // All deltas for a single pinch gesture should sum to 0 if the start and end // of a pinch gesture end up in the same place. This doesn't happen in Chrome // because they followed Apple's misleading documentation, which implies that // "1 + [event magnification]" is the scale factor. The scale factor is // instead "pow(ratio, [event magnification])" so "[event magnification]" is // already in log space. // // The multiplication by the backing scale factor below counteracts the // division by the backing scale factor in WheelEvent.
// We want to set deltaY to |-100.0 * M * GetDefaultScaleInternal()| where M // is [event magnification] but [event magnification] is only available in the // macOS widget code so we have to reverse engineer from mCurrentSpan and // mPreviousSpan (which are derived from [event magnification]) to get it. // Specifically, we know |mCurrentSpan == 100.0| and |mPreviousSpan == 100.0 * // (1.0 - M)|. We can calculate deltaY by solving the mPreviousSpan equation // for M in terms of mPreviousSpan and plugging that into to the formula for // deltaY. return (mPreviousSpan - 100.0) *
(aWidget ? aWidget->GetDefaultScaleInternal() : 1.f); #else // This calculation is based on what the Windows and Linux widget code does. // Specifically, it creates a PinchGestureInput with |mCurrentSpan == 100.0 * // currentScale| and |mPreviousSpan == 100.0 * lastScale| where currentScale // is the scale from the current OS event and lastScale is the scale when the // previous OS event happened. On macOS [event magnification] is a relative // change in scale factor, ie if the scale factor changed from 1 to 1.1 it // will be 0.1, similarly if it changed from 1 to 0.9 it will be -0.1. To // calculate the relative scale change on Windows we would calculate |M = // currentScale - lastScale = (mCurrentSpan-mPreviousSpan)/100| and use the // same formula as the macOS code // (|-100.0 * M * GetDefaultScaleInternal()|).
bool PinchGestureInput::SetLineOrPageDeltaY(nsIWidget* aWidget) { double deltaY = ComputeDeltaY(aWidget); if (deltaY == 0 && mType != PINCHGESTURE_END) { returnfalse;
}
gfx::IntPoint lineOrPageDelta = PinchGestureInput::GetIntegerDeltaForEvent(
(mType == PINCHGESTURE_START), 0, deltaY);
mLineOrPageDeltaY = lineOrPageDelta.y; if (mLineOrPageDeltaY == 0) { // For PINCHGESTURE_SCALE events, don't dispatch them. Note that the delta // isn't lost; it remains in the accumulator in GetIntegerDeltaForEvent(). if (mType == PINCHGESTURE_SCALE) { returnfalse;
} // On Windows, drop PINCHGESTURE_START as well (the Windows widget code will // defer the START event until we accumulate enough delta). // The Linux widget code doesn't support this, so instead set the event's // mLineOrPageDeltaY to the smallest nonzero amount in the relevant // direction. if (mType == PINCHGESTURE_START) { #ifdef XP_WIN returnfalse; #else
mLineOrPageDeltaY = (deltaY >= 0) ? 1 : -1; #endif
} // For PINCHGESTURE_END events, not dispatching a DOMMouseScroll for them is // fine.
} returntrue;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.