diff --git a/mobile/android/base/gfx/GeckoLayerClient.java b/mobile/android/base/gfx/GeckoLayerClient.java index e5ce30ddcefa..d21797161aab 100644 --- a/mobile/android/base/gfx/GeckoLayerClient.java +++ b/mobile/android/base/gfx/GeckoLayerClient.java @@ -94,7 +94,6 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget private boolean mGeckoIsReady; private final PanZoomController mPanZoomController; - private final LayerMarginsAnimator mMarginsAnimator; private final DynamicToolbarAnimator mToolbarAnimator; private final LayerView mView; @@ -137,7 +136,6 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget mDrawListeners = new ArrayList(); mToolbarAnimator = new DynamicToolbarAnimator(this); mPanZoomController = PanZoomController.Factory.create(this, view, eventDispatcher); - mMarginsAnimator = new LayerMarginsAnimator(this, view); mView = view; mView.setListener(this); mContentDocumentIsDisplayed = true; @@ -173,7 +171,6 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget public void destroy() { mPanZoomController.destroy(); - mMarginsAnimator.destroy(); mToolbarAnimator.destroy(); mDrawListeners.clear(); } @@ -749,12 +746,6 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget return mView.getFullScreenState(); } - /** Implementation of PanZoomTarget */ - @Override - public RectF getMaxMargins() { - return mMarginsAnimator.getMaxMargins(); - } - /** Implementation of PanZoomTarget */ @Override public void setAnimationTarget(ImmutableViewportMetrics metrics) { diff --git a/mobile/android/base/gfx/LayerMarginsAnimator.java b/mobile/android/base/gfx/LayerMarginsAnimator.java deleted file mode 100644 index 0c5e7adad9d6..000000000000 --- a/mobile/android/base/gfx/LayerMarginsAnimator.java +++ /dev/null @@ -1,321 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * 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/. */ - -package org.mozilla.gecko.gfx; - -import org.mozilla.gecko.GeckoAppShell; -import org.mozilla.gecko.GeckoEvent; -import org.mozilla.gecko.PrefsHelper; -import org.mozilla.gecko.util.FloatUtils; -import org.mozilla.gecko.util.ThreadUtils; - -import android.graphics.PointF; -import android.graphics.RectF; -import android.os.SystemClock; -import android.util.Log; -import android.view.animation.DecelerateInterpolator; -import android.view.MotionEvent; -import android.view.View; - -public class LayerMarginsAnimator { - private static final String LOGTAG = "GeckoLayerMarginsAnimator"; - // The duration of the animation in ns - private static final long MARGIN_ANIMATION_DURATION = 250000000; - private static final String PREF_SHOW_MARGINS_THRESHOLD = "browser.ui.show-margins-threshold"; - - /* This is the proportion of the viewport rect, minus maximum margins, - * that needs to be travelled before margins will be exposed. - */ - private float SHOW_MARGINS_THRESHOLD = 0.20f; - - /* This rect stores the maximum value margins can grow to when scrolling. When writing - * to this member variable, or when reading from this member variable on a non-UI thread, - * you must synchronize on the LayerMarginsAnimator instance. */ - private final RectF mMaxMargins; - /* If this boolean is true, scroll changes will not affect margins */ - private boolean mMarginsPinned; - /* The task that handles showing/hiding margins */ - private LayerMarginsAnimationTask mAnimationTask; - /* This interpolator is used for the above mentioned animation */ - private final DecelerateInterpolator mInterpolator; - /* The GeckoLayerClient whose margins will be animated */ - private final GeckoLayerClient mTarget; - /* The distance that has been scrolled since either the first touch event, - * or since the margins were last fully hidden */ - private final PointF mTouchTravelDistance; - /* The ID of the prefs listener for the show-margins threshold */ - private Integer mPrefObserverId; - - public LayerMarginsAnimator(GeckoLayerClient aTarget, LayerView aView) { - // Assign member variables from parameters - mTarget = aTarget; - - // Create other member variables - mMaxMargins = new RectF(); - mInterpolator = new DecelerateInterpolator(); - mTouchTravelDistance = new PointF(); - - // Listen to the dynamic toolbar pref - mPrefObserverId = PrefsHelper.getPref(PREF_SHOW_MARGINS_THRESHOLD, new PrefsHelper.PrefHandlerBase() { - @Override - public void prefValue(String pref, int value) { - SHOW_MARGINS_THRESHOLD = value / 100.0f; - } - - @Override - public boolean isObserver() { - return true; - } - }); - } - - public void destroy() { - if (mPrefObserverId != null) { - PrefsHelper.removeObserver(mPrefObserverId); - mPrefObserverId = null; - } - } - - /** - * Sets the maximum values for margins to grow to, in pixels. - */ - public synchronized void setMaxMargins(float left, float top, float right, float bottom) { - ThreadUtils.assertOnUiThread(); - - mMaxMargins.set(left, top, right, bottom); - } - - synchronized RectF getMaxMargins() { - return mMaxMargins; - } - - private void animateMargins(final float left, final float top, final float right, final float bottom, boolean immediately) { - if (mAnimationTask != null) { - mTarget.getView().removeRenderTask(mAnimationTask); - mAnimationTask = null; - } - - if (immediately) { - ImmutableViewportMetrics newMetrics = mTarget.getViewportMetrics().setMargins(left, top, right, bottom); - mTarget.forceViewportMetrics(newMetrics, true, true); - return; - } - - ImmutableViewportMetrics metrics = mTarget.getViewportMetrics(); - if (!canAnimateMargins(metrics, left, top, right, bottom)) { - return; - } - - mAnimationTask = new LayerMarginsAnimationTask(false, metrics, left, top, right, bottom); - mTarget.getView().postRenderTask(mAnimationTask); - } - - /** - * Returns true if we can animate the margins from their current position, false otherwise. - * We can animate if the given values are not identical (i.e. there is somewhere to animate to). - */ - private static boolean canAnimateMargins(final ImmutableViewportMetrics metrics, - final float left, final float top, final float right, final float bottom) { - return !(FloatUtils.fuzzyEquals(left, metrics.marginLeft) && - FloatUtils.fuzzyEquals(top, metrics.marginTop) && - FloatUtils.fuzzyEquals(right, metrics.marginRight) && - FloatUtils.fuzzyEquals(bottom, metrics.marginBottom)); - } - - /** - * Exposes the margin area by growing the margin components of the current - * metrics to the values set in setMaxMargins. - */ - public synchronized void showMargins(boolean immediately) { - animateMargins(mMaxMargins.left, mMaxMargins.top, mMaxMargins.right, mMaxMargins.bottom, immediately); - } - - public synchronized void hideMargins(boolean immediately) { - animateMargins(0, 0, 0, 0, immediately); - } - - public void setMarginsPinned(boolean pin) { - if (pin == mMarginsPinned) { - return; - } - - mMarginsPinned = pin; - } - - public boolean areMarginsShown() { - final ImmutableViewportMetrics metrics = mTarget.getViewportMetrics(); - return metrics.marginLeft != 0 || - metrics.marginRight != 0 || - metrics.marginTop != 0 || - metrics.marginBottom != 0; - } - - /** - * This function will scroll a margin down to zero, or up to the maximum - * specified margin size and return the left-over delta. - * aMargins are in/out parameters. In specifies the current margin size, - * and out specifies the modified margin size. They are specified in the - * order of start-margin, then end-margin. - * This function will also take into account how far the touch point has - * moved and react accordingly. If a touch point hasn't moved beyond a - * certain threshold, margins can only be hidden and not shown. - * aNegativeOffset can be used if the remaining delta should be determined - * by the end-margin instead of the start-margin (for example, in rtl - * pages). - */ - private float scrollMargin(float[] aMargins, float aDelta, - float aOverscrollStart, float aOverscrollEnd, - float aTouchTravelDistance, - float aViewportStart, float aViewportEnd, - float aPageStart, float aPageEnd, - float aMaxMarginStart, float aMaxMarginEnd, - boolean aNegativeOffset) { - float marginStart = aMargins[0]; - float marginEnd = aMargins[1]; - float viewportSize = aViewportEnd - aViewportStart; - float exposeThreshold = viewportSize * SHOW_MARGINS_THRESHOLD; - - if (aDelta >= 0) { - float marginDelta = Math.max(0, aDelta - aOverscrollStart); - aMargins[0] = marginStart - Math.min(marginDelta, marginStart); - if (aTouchTravelDistance < exposeThreshold && marginEnd == 0) { - // We only want the margin to be newly exposed after the touch - // has moved a certain distance. - marginDelta = Math.max(0, marginDelta - (aPageEnd - aViewportEnd)); - } - aMargins[1] = marginEnd + Math.min(marginDelta, aMaxMarginEnd - marginEnd); - } else { - float marginDelta = Math.max(0, -aDelta - aOverscrollEnd); - aMargins[1] = marginEnd - Math.min(marginDelta, marginEnd); - if (-aTouchTravelDistance < exposeThreshold && marginStart == 0) { - marginDelta = Math.max(0, marginDelta - (aViewportStart - aPageStart)); - } - aMargins[0] = marginStart + Math.min(marginDelta, aMaxMarginStart - marginStart); - } - - if (aNegativeOffset) { - return aDelta - (marginEnd - aMargins[1]); - } - return aDelta - (marginStart - aMargins[0]); - } - - /* - * Taking maximum margins into account, offsets the margins and then the - * viewport origin and returns the modified metrics. - */ - ImmutableViewportMetrics scrollBy(ImmutableViewportMetrics aMetrics, float aDx, float aDy) { - float[] newMarginsX = { aMetrics.marginLeft, aMetrics.marginRight }; - float[] newMarginsY = { aMetrics.marginTop, aMetrics.marginBottom }; - - // Only alter margins if the toolbar isn't pinned - if (!mMarginsPinned) { - // Make sure to cancel any margin animations when margin-scrolling begins - if (mAnimationTask != null) { - mTarget.getView().removeRenderTask(mAnimationTask); - mAnimationTask = null; - } - - // Reset the touch travel when changing direction - if ((aDx >= 0) != (mTouchTravelDistance.x >= 0)) { - mTouchTravelDistance.x = 0; - } - if ((aDy >= 0) != (mTouchTravelDistance.y >= 0)) { - mTouchTravelDistance.y = 0; - } - - mTouchTravelDistance.offset(aDx, aDy); - RectF overscroll = aMetrics.getOverscroll(); - - // Only allow margins to scroll if the page can fill the viewport. - if (aMetrics.getPageWidth() >= aMetrics.getWidth()) { - aDx = scrollMargin(newMarginsX, aDx, - overscroll.left, overscroll.right, - mTouchTravelDistance.x, - aMetrics.viewportRectLeft, aMetrics.viewportRectRight(), - aMetrics.pageRectLeft, aMetrics.pageRectRight, - mMaxMargins.left, mMaxMargins.right, - aMetrics.isRTL); - } - if (aMetrics.getPageHeight() >= aMetrics.getHeight()) { - aDy = scrollMargin(newMarginsY, aDy, - overscroll.top, overscroll.bottom, - mTouchTravelDistance.y, - aMetrics.viewportRectTop, aMetrics.viewportRectBottom(), - aMetrics.pageRectTop, aMetrics.pageRectBottom, - mMaxMargins.top, mMaxMargins.bottom, - false); - } - } - - return aMetrics.setMargins(newMarginsX[0], newMarginsY[0], newMarginsX[1], newMarginsY[1]).offsetViewportBy(aDx, aDy); - } - - boolean onInterceptTouchEvent(MotionEvent event) { - int action = event.getActionMasked(); - if (action == MotionEvent.ACTION_DOWN && event.getPointerCount() == 1) { - mTouchTravelDistance.set(0.0f, 0.0f); - } - - return false; - } - - class LayerMarginsAnimationTask extends RenderTask { - private final float mStartLeft, mStartTop, mStartRight, mStartBottom; - private final float mTop, mBottom, mLeft, mRight; - private boolean mContinueAnimation; - - public LayerMarginsAnimationTask(boolean runAfter, ImmutableViewportMetrics metrics, - float left, float top, float right, float bottom) { - super(runAfter); - mContinueAnimation = true; - this.mStartLeft = metrics.marginLeft; - this.mStartTop = metrics.marginTop; - this.mStartRight = metrics.marginRight; - this.mStartBottom = metrics.marginBottom; - this.mLeft = left; - this.mRight = right; - this.mTop = top; - this.mBottom = bottom; - } - - @Override - public boolean internalRun(long timeDelta, long currentFrameStartTime) { - if (!mContinueAnimation) { - return false; - } - - // Calculate the progress (between 0 and 1) - float progress = mInterpolator.getInterpolation( - Math.min(1.0f, (System.nanoTime() - getStartTime()) - / (float)MARGIN_ANIMATION_DURATION)); - - // Calculate the new metrics accordingly - synchronized (mTarget.getLock()) { - ImmutableViewportMetrics oldMetrics = mTarget.getViewportMetrics(); - ImmutableViewportMetrics newMetrics = oldMetrics.setMargins( - FloatUtils.interpolate(mStartLeft, mLeft, progress), - FloatUtils.interpolate(mStartTop, mTop, progress), - FloatUtils.interpolate(mStartRight, mRight, progress), - FloatUtils.interpolate(mStartBottom, mBottom, progress)); - PointF oldOffset = oldMetrics.getMarginOffset(); - PointF newOffset = newMetrics.getMarginOffset(); - newMetrics = - newMetrics.offsetViewportByAndClamp(newOffset.x - oldOffset.x, - newOffset.y - oldOffset.y); - - if (progress >= 1.0f) { - mContinueAnimation = false; - - // Force a redraw and update Gecko - mTarget.forceViewportMetrics(newMetrics, true, true); - } else { - mTarget.forceViewportMetrics(newMetrics, false, false); - } - } - return mContinueAnimation; - } - } - -} diff --git a/mobile/android/base/gfx/PanZoomTarget.java b/mobile/android/base/gfx/PanZoomTarget.java index 3bdde3f143ba..f36b8310d1d5 100644 --- a/mobile/android/base/gfx/PanZoomTarget.java +++ b/mobile/android/base/gfx/PanZoomTarget.java @@ -14,7 +14,6 @@ public interface PanZoomTarget { public ImmutableViewportMetrics getViewportMetrics(); public ZoomConstraints getZoomConstraints(); public FullScreenState getFullScreenState(); - public RectF getMaxMargins(); public void setAnimationTarget(ImmutableViewportMetrics viewport); public void setViewportMetrics(ImmutableViewportMetrics viewport); diff --git a/mobile/android/base/moz.build b/mobile/android/base/moz.build index 0d218890862d..414f2f0917b3 100644 --- a/mobile/android/base/moz.build +++ b/mobile/android/base/moz.build @@ -278,7 +278,6 @@ gbjar.sources += [ 'gfx/IntSize.java', 'gfx/JavaPanZoomController.java', 'gfx/Layer.java', - 'gfx/LayerMarginsAnimator.java', 'gfx/LayerRenderer.java', 'gfx/LayerView.java', 'gfx/NativePanZoomController.java',