summaryrefslogtreecommitdiff
path: root/widget/cocoa/SwipeTracker.mm
diff options
context:
space:
mode:
Diffstat (limited to 'widget/cocoa/SwipeTracker.mm')
-rw-r--r--widget/cocoa/SwipeTracker.mm219
1 files changed, 0 insertions, 219 deletions
diff --git a/widget/cocoa/SwipeTracker.mm b/widget/cocoa/SwipeTracker.mm
deleted file mode 100644
index 51169171a4..0000000000
--- a/widget/cocoa/SwipeTracker.mm
+++ /dev/null
@@ -1,219 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; 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/. */
-
-#include "SwipeTracker.h"
-
-#include "InputData.h"
-#include "mozilla/TimeStamp.h"
-#include "mozilla/TouchEvents.h"
-#include "nsAlgorithm.h"
-#include "nsChildView.h"
-#include "UnitTransforms.h"
-
-// These values were tweaked to make the physics feel similar to the native swipe.
-static const double kSpringForce = 250.0;
-static const double kVelocityTwitchTolerance = 0.0000001;
-static const double kWholePagePixelSize = 1000.0;
-static const double kRubberBandResistanceFactor = 4.0;
-static const double kSwipeSuccessThreshold = 0.25;
-static const double kSwipeSuccessVelocityContribution = 0.3;
-
-namespace mozilla {
-
-static already_AddRefed<nsRefreshDriver>
-GetRefreshDriver(nsIWidget& aWidget)
-{
- nsIWidgetListener* widgetListener = aWidget.GetWidgetListener();
- nsIPresShell* presShell = widgetListener ? widgetListener->GetPresShell() : nullptr;
- nsPresContext* presContext = presShell ? presShell->GetPresContext() : nullptr;
- RefPtr<nsRefreshDriver> refreshDriver = presContext ? presContext->RefreshDriver() : nullptr;
- return refreshDriver.forget();
-}
-
-SwipeTracker::SwipeTracker(nsChildView& aWidget,
- const PanGestureInput& aSwipeStartEvent,
- uint32_t aAllowedDirections,
- uint32_t aSwipeDirection)
- : mWidget(aWidget)
- , mRefreshDriver(GetRefreshDriver(mWidget))
- , mAxis(0.0, 0.0, 0.0, kSpringForce, 1.0)
- , mEventPosition(RoundedToInt(ViewAs<LayoutDevicePixel>(aSwipeStartEvent.mPanStartPoint,
- PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent)))
- , mLastEventTimeStamp(aSwipeStartEvent.mTimeStamp)
- , mAllowedDirections(aAllowedDirections)
- , mSwipeDirection(aSwipeDirection)
- , mGestureAmount(0.0)
- , mCurrentVelocity(0.0)
- , mEventsAreControllingSwipe(true)
- , mEventsHaveStartedNewGesture(false)
- , mRegisteredWithRefreshDriver(false)
-{
- SendSwipeEvent(eSwipeGestureStart, 0, 0.0);
- ProcessEvent(aSwipeStartEvent);
-}
-
-void
-SwipeTracker::Destroy()
-{
- UnregisterFromRefreshDriver();
-}
-
-SwipeTracker::~SwipeTracker()
-{
- MOZ_ASSERT(!mRegisteredWithRefreshDriver, "Destroy needs to be called before deallocating");
-}
-
-double
-SwipeTracker::SwipeSuccessTargetValue() const
-{
- return (mSwipeDirection == nsIDOMSimpleGestureEvent::DIRECTION_RIGHT) ? -1.0 : 1.0;
-}
-
-double
-SwipeTracker::ClampToAllowedRange(double aGestureAmount) const
-{
- // gestureAmount needs to stay between -1 and 0 when swiping right and
- // between 0 and 1 when swiping left.
- double min = (mSwipeDirection == nsIDOMSimpleGestureEvent::DIRECTION_RIGHT) ? -1.0 : 0.0;
- double max = (mSwipeDirection == nsIDOMSimpleGestureEvent::DIRECTION_LEFT) ? 1.0 : 0.0;
- return clamped(aGestureAmount, min, max);
-}
-
-bool
-SwipeTracker::ComputeSwipeSuccess() const
-{
- double targetValue = SwipeSuccessTargetValue();
-
- // If the fingers were moving away from the target direction when they were
- // lifted from the touchpad, abort the swipe.
- if (mCurrentVelocity * targetValue < -kVelocityTwitchTolerance) {
- return false;
- }
-
- return (mGestureAmount * targetValue +
- mCurrentVelocity * targetValue * kSwipeSuccessVelocityContribution) >= kSwipeSuccessThreshold;
-}
-
-nsEventStatus
-SwipeTracker::ProcessEvent(const PanGestureInput& aEvent)
-{
- // If the fingers have already been lifted, don't process this event for swiping.
- if (!mEventsAreControllingSwipe) {
- // Return nsEventStatus_eConsumeNoDefault for events from the swipe gesture
- // and nsEventStatus_eIgnore for events of subsequent scroll gestures.
- if (aEvent.mType == PanGestureInput::PANGESTURE_MAYSTART ||
- aEvent.mType == PanGestureInput::PANGESTURE_START) {
- mEventsHaveStartedNewGesture = true;
- }
- return mEventsHaveStartedNewGesture ? nsEventStatus_eIgnore : nsEventStatus_eConsumeNoDefault;
- }
-
- double delta = -aEvent.mPanDisplacement.x / mWidget.BackingScaleFactor() / kWholePagePixelSize;
- if (!SwipingInAllowedDirection()) {
- delta /= kRubberBandResistanceFactor;
- }
- mGestureAmount = ClampToAllowedRange(mGestureAmount + delta);
- SendSwipeEvent(eSwipeGestureUpdate, 0, mGestureAmount);
-
- if (aEvent.mType != PanGestureInput::PANGESTURE_END) {
- double elapsedSeconds = std::max(0.008, (aEvent.mTimeStamp - mLastEventTimeStamp).ToSeconds());
- mCurrentVelocity = delta / elapsedSeconds;
- mLastEventTimeStamp = aEvent.mTimeStamp;
- } else {
- mEventsAreControllingSwipe = false;
- bool didSwipeSucceed = SwipingInAllowedDirection() && ComputeSwipeSuccess();
- double targetValue = 0.0;
- if (didSwipeSucceed) {
- SendSwipeEvent(eSwipeGesture, mSwipeDirection, 0.0);
- targetValue = SwipeSuccessTargetValue();
- }
- StartAnimating(targetValue);
- }
-
- return nsEventStatus_eConsumeNoDefault;
-}
-
-void
-SwipeTracker::StartAnimating(double aTargetValue)
-{
- mAxis.SetPosition(mGestureAmount);
- mAxis.SetDestination(aTargetValue);
- mAxis.SetVelocity(mCurrentVelocity);
-
- mLastAnimationFrameTime = TimeStamp::Now();
-
- // Add ourselves as a refresh driver observer. The refresh driver
- // will call WillRefresh for each animation frame until we
- // unregister ourselves.
- MOZ_ASSERT(!mRegisteredWithRefreshDriver);
- if (mRefreshDriver) {
- mRefreshDriver->AddRefreshObserver(this, Flush_Style);
- mRegisteredWithRefreshDriver = true;
- }
-}
-
-void
-SwipeTracker::WillRefresh(mozilla::TimeStamp aTime)
-{
- TimeStamp now = TimeStamp::Now();
- mAxis.Simulate(now - mLastAnimationFrameTime);
- mLastAnimationFrameTime = now;
-
- bool isFinished = mAxis.IsFinished(1.0 / kWholePagePixelSize);
- mGestureAmount = (isFinished ? mAxis.GetDestination() : mAxis.GetPosition());
- SendSwipeEvent(eSwipeGestureUpdate, 0, mGestureAmount);
-
- if (isFinished) {
- UnregisterFromRefreshDriver();
- SwipeFinished();
- }
-}
-
-void
-SwipeTracker::CancelSwipe()
-{
- SendSwipeEvent(eSwipeGestureEnd, 0, 0.0);
-}
-
-void SwipeTracker::SwipeFinished()
-{
- SendSwipeEvent(eSwipeGestureEnd, 0, 0.0);
- mWidget.SwipeFinished();
-}
-
-void
-SwipeTracker::UnregisterFromRefreshDriver()
-{
- if (mRegisteredWithRefreshDriver) {
- MOZ_ASSERT(mRefreshDriver, "How were we able to register, then?");
- mRefreshDriver->RemoveRefreshObserver(this, Flush_Style);
- }
- mRegisteredWithRefreshDriver = false;
-}
-
-/* static */ WidgetSimpleGestureEvent
-SwipeTracker::CreateSwipeGestureEvent(EventMessage aMsg, nsIWidget* aWidget,
- const LayoutDeviceIntPoint& aPosition)
-{
- WidgetSimpleGestureEvent geckoEvent(true, aMsg, aWidget);
- geckoEvent.mModifiers = 0;
- geckoEvent.mTimeStamp = TimeStamp::Now();
- geckoEvent.mRefPoint = aPosition;
- geckoEvent.buttons = 0;
- return geckoEvent;
-}
-
-bool
-SwipeTracker::SendSwipeEvent(EventMessage aMsg, uint32_t aDirection, double aDelta)
-{
- WidgetSimpleGestureEvent geckoEvent =
- CreateSwipeGestureEvent(aMsg, &mWidget, mEventPosition);
- geckoEvent.mDirection = aDirection;
- geckoEvent.mDelta = aDelta;
- geckoEvent.mAllowedDirections = mAllowedDirections;
- return mWidget.DispatchWindowEvent(geckoEvent);
-}
-
-} // namespace mozilla