Commit c66df030 authored by ckitagawa's avatar ckitagawa Committed by Commit Bot

[Paint Preview] Decouple *Controller classes from Mediator

Break cyclic dependency of PlayerFrameMediator with
- PlayerFrameScaleController
- PlayerFrameScrollController

BitmapState is tightly coupled to PlayerFrameMediator with good reason
so a cyclic dependency there is somewhat unavoidable.

This is achieved by having PlayerFrameCoordinator instantiate
everything and then introducing a new class that handles dispatch of
gestures. A helper for scaling is also added to break the two-way
interdependence that existed in the mediator.

Bug: 1099722
Change-Id: I13b258d973a5ff81cdf75505f59aabb02d66a6c6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2295751
Commit-Queue: Calder Kitagawa <ckitagawa@chromium.org>
Reviewed-by: default avatarMehran Mahmoudi <mahmoudi@chromium.org>
Reviewed-by: default avatarFred Mello <fredmello@chromium.org>
Cr-Commit-Position: refs/heads/master@{#789996}
parent 99ad7711
......@@ -61,6 +61,7 @@ android_library("java") {
"java/src/org/chromium/components/paintpreview/player/frame/PlayerFrameBitmapStateController.java",
"java/src/org/chromium/components/paintpreview/player/frame/PlayerFrameCoordinator.java",
"java/src/org/chromium/components/paintpreview/player/frame/PlayerFrameGestureDetector.java",
"java/src/org/chromium/components/paintpreview/player/frame/PlayerFrameGestureDetectorDelegate.java",
"java/src/org/chromium/components/paintpreview/player/frame/PlayerFrameMediator.java",
"java/src/org/chromium/components/paintpreview/player/frame/PlayerFrameMediatorDelegate.java",
"java/src/org/chromium/components/paintpreview/player/frame/PlayerFrameProperties.java",
......
......@@ -6,6 +6,7 @@ package org.chromium.components.paintpreview.player.frame;
import android.content.Context;
import android.graphics.Rect;
import android.util.Size;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.OverScroller;
......@@ -37,12 +38,24 @@ public class PlayerFrameCoordinator {
PropertyModel model = new PropertyModel.Builder(PlayerFrameProperties.ALL_KEYS).build();
OverScroller scroller = new OverScroller(context);
scroller.setFriction(ViewConfiguration.getScrollFriction() / 2);
mMediator = new PlayerFrameMediator(model, compositorDelegate, new PlayerFrameViewport(),
scroller, gestureHandler, frameGuid, contentWidth, contentHeight, initialScrollX,
initialScrollY);
mView = new PlayerFrameView(context, canDetectZoom, mMediator);
mMediator = new PlayerFrameMediator(model, compositorDelegate, gestureHandler, frameGuid,
new Size(contentWidth, contentHeight), initialScrollX, initialScrollY);
PlayerFrameScaleController scaleController = null;
if (canDetectZoom) {
scaleController =
new PlayerFrameScaleController(model.get(PlayerFrameProperties.SCALE_MATRIX),
mMediator, gestureHandler::onScale);
}
PlayerFrameScrollController scrollController = new PlayerFrameScrollController(
scroller, mMediator, gestureHandler::onScroll, gestureHandler::onFling);
PlayerFrameGestureDetectorDelegate gestureDelegate = new PlayerFrameGestureDetectorDelegate(
scaleController, scrollController, mMediator);
mView = new PlayerFrameView(context, canDetectZoom, mMediator, gestureDelegate);
if (overscrollHandler != null) {
mMediator.setOverscrollHandler(overscrollHandler);
scrollController.setOverscrollHandler(overscrollHandler);
}
PropertyModelChangeProcessor.create(model, mView, PlayerFrameViewBinder::bind);
}
......
......@@ -11,14 +11,14 @@ import android.view.ScaleGestureDetector;
/**
* Detects scroll, fling, and scale gestures on calls to {@link #onTouchEvent} and reports back to
* the provided {@link PlayerFrameViewDelegate}.
* the provided {@link PlayerFrameGestureDetectorDelegate}.
*/
class PlayerFrameGestureDetector
implements GestureDetector.OnGestureListener, ScaleGestureDetector.OnScaleGestureListener {
private GestureDetector mGestureDetector;
private ScaleGestureDetector mScaleGestureDetector;
private boolean mCanDetectZoom;
private PlayerFrameViewDelegate mPlayerFrameViewDelegate;
private PlayerFrameGestureDetectorDelegate mDelegate;
private PlayerFrameGestureDetector mParentGestureDetector;
/**
* Last horizontal scroll distance that was detected by this {@link PlayerFrameGestureDetector}
......@@ -36,14 +36,14 @@ class PlayerFrameGestureDetector
* {@link ScaleGestureDetector}.
* @param canDetectZoom Whether this {@link PlayerFrameGestureDetector} should detect scale
* gestures.
* @param playerFrameViewDelegate The delegate used when desired gestured are detected.
* @param delegate The delegate used when desired gestured are detected.
*/
PlayerFrameGestureDetector(Context context, boolean canDetectZoom,
PlayerFrameViewDelegate playerFrameViewDelegate) {
PlayerFrameGestureDetector(
Context context, boolean canDetectZoom, PlayerFrameGestureDetectorDelegate delegate) {
mGestureDetector = new GestureDetector(context, this);
mScaleGestureDetector = new ScaleGestureDetector(context, this);
mCanDetectZoom = canDetectZoom;
mPlayerFrameViewDelegate = playerFrameViewDelegate;
mDelegate = delegate;
}
/**
......@@ -65,7 +65,7 @@ class PlayerFrameGestureDetector
}
if (event.getAction() == MotionEvent.ACTION_UP) {
mPlayerFrameViewDelegate.onRelease();
mDelegate.onRelease();
// Propagate the release to the parent, this won't trigger any unexpected behavior as
// this is only an UP event.
if (mParentGestureDetector != null) {
......@@ -85,13 +85,13 @@ class PlayerFrameGestureDetector
@Override
public boolean onSingleTapUp(MotionEvent e) {
mPlayerFrameViewDelegate.onTap((int) e.getX(), (int) e.getY());
mDelegate.onTap((int) e.getX(), (int) e.getY());
return true;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
if (mPlayerFrameViewDelegate.scrollBy(distanceX, distanceY)) {
if (mDelegate.scrollBy(distanceX, distanceY)) {
mLastParentScrollX = 0f;
mLastParentScrollY = 0f;
return true;
......@@ -116,12 +116,12 @@ class PlayerFrameGestureDetector
@Override
public void onLongPress(MotionEvent e) {
mPlayerFrameViewDelegate.onLongPress((int) e.getX(), (int) e.getY());
mDelegate.onLongPress((int) e.getX(), (int) e.getY());
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if (mPlayerFrameViewDelegate.onFling(velocityX, velocityY)) return true;
if (mDelegate.onFling(velocityX, velocityY)) return true;
if (mParentGestureDetector != null) {
return mParentGestureDetector.onFling(e1, e2, velocityX, velocityY);
......@@ -132,7 +132,7 @@ class PlayerFrameGestureDetector
@Override
public boolean onScale(ScaleGestureDetector detector) {
assert mCanDetectZoom;
return mPlayerFrameViewDelegate.scaleBy(
return mDelegate.scaleBy(
detector.getScaleFactor(), detector.getFocusX(), detector.getFocusY());
}
......@@ -145,7 +145,7 @@ class PlayerFrameGestureDetector
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
assert mCanDetectZoom;
mPlayerFrameViewDelegate.scaleFinished(
mDelegate.scaleFinished(
detector.getScaleFactor(), detector.getFocusX(), detector.getFocusY());
}
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.components.paintpreview.player.frame;
/**
* Dispatches gesture events to the correct controllers.
*/
public class PlayerFrameGestureDetectorDelegate {
private final PlayerFrameScaleController mScaleController;
private final PlayerFrameScrollController mScrollController;
private final PlayerFrameViewDelegate mViewDelegate;
PlayerFrameGestureDetectorDelegate(PlayerFrameScaleController scaleController,
PlayerFrameScrollController scrollController, PlayerFrameViewDelegate viewDelegate) {
mScaleController = scaleController;
mScrollController = scrollController;
mViewDelegate = viewDelegate;
}
/**
* Called when a scroll gesture is performed.
* @param distanceX Horizontal scroll values in pixels.
* @param distanceY Vertical scroll values in pixels.
* @return Whether this scroll event was consumed.
*/
boolean scrollBy(float distanceX, float distanceY) {
return mScrollController.scrollBy(distanceX, distanceY);
}
/**
* Called when a fling gesture is performed.
* @param velocityX Horizontal velocity value in pixels.
* @param velocityY Vertical velocity value in pixels.
* @return Whether this fling was consumed.
*/
boolean onFling(float velocityX, float velocityY) {
return mScrollController.onFling(velocityX, velocityY);
}
/**
* Called when a gesture is released.
*/
void onRelease() {
mScrollController.onRelease();
}
/**
* Called when a scale gesture is performed.
* @return Whether this scale event was consumed.
*/
boolean scaleBy(float scaleFactor, float focalPointX, float focalPointY) {
return mScaleController.scaleBy(scaleFactor, focalPointX, focalPointY);
}
/**
* Called when a scale gesture is finished.
* @return Whether this scale event was consumed.
*/
boolean scaleFinished(float scaleFactor, float focalPointX, float focalPointY) {
return mScaleController.scaleFinished(scaleFactor, focalPointX, focalPointY);
}
/**
* Called when a single tap gesture is performed.
* @param x X coordinate of the point clicked.
* @param y Y coordinate of the point clicked.
*/
void onTap(int x, int y) {
mViewDelegate.onTap(x, y);
}
/**
* Called when a long press gesture is performed.
* @param x X coordinate of the point clicked.
* @param y Y coordinate of the point clicked.
*/
void onLongPress(int x, int y) {
mViewDelegate.onLongPress(x, y);
}
}
......@@ -9,12 +9,10 @@ import android.graphics.Matrix;
import android.graphics.Rect;
import android.util.Size;
import android.view.View;
import android.widget.OverScroller;
import androidx.annotation.VisibleForTesting;
import org.chromium.base.UnguessableToken;
import org.chromium.components.paintpreview.player.OverscrollHandler;
import org.chromium.components.paintpreview.player.PlayerCompositorDelegate;
import org.chromium.components.paintpreview.player.PlayerGestureListener;
import org.chromium.ui.modelutil.PropertyModel;
......@@ -64,36 +62,29 @@ class PlayerFrameMediator implements PlayerFrameViewDelegate, PlayerFrameMediato
/** The viewport of this frame. */
private final PlayerFrameViewport mViewport;
private float mInitialScaleFactor;
/** Handles scaling of bitmaps. */
private final Matrix mBitmapScaleMatrix = new Matrix();
/** Handles scrolling. */
private final PlayerFrameScrollController mScrollController;
/** Handles scaling. */
private final PlayerFrameScaleController mScaleController;
private final Matrix mBitmapScaleMatrix;
private final PlayerFrameBitmapStateController mBitmapStateController;
private PlayerGestureListener mGestureListener;
PlayerFrameMediator(PropertyModel model, PlayerCompositorDelegate compositorDelegate,
PlayerFrameViewport viewport, OverScroller scroller,
PlayerGestureListener gestureListener, UnguessableToken frameGuid, int contentWidth,
int contentHeight, int initialScrollX, int initialScrollY) {
PlayerGestureListener gestureListener, UnguessableToken frameGuid, Size contentSize,
int initialScrollX, int initialScrollY) {
mBitmapScaleMatrix = new Matrix();
mModel = model;
mModel.set(PlayerFrameProperties.SCALE_MATRIX, mBitmapScaleMatrix);
mCompositorDelegate = compositorDelegate;
mViewport = viewport;
mGestureListener = gestureListener;
mViewport = new PlayerFrameViewport();
mInitialScaleFactor = 0f;
mGuid = frameGuid;
mContentSize = new Size(contentWidth, contentHeight);
mContentSize = contentSize;
mBitmapStateController = new PlayerFrameBitmapStateController(
mGuid, mViewport, mContentSize, mCompositorDelegate, this);
mScrollController = new PlayerFrameScrollController(scroller, mViewport, mContentSize, this,
gestureListener::onScroll, gestureListener::onFling);
mScaleController = new PlayerFrameScaleController(
mViewport, mContentSize, mBitmapScaleMatrix, this, gestureListener::onScale);
mGestureListener = gestureListener;
mViewport.offset(initialScrollX, initialScrollY);
mViewport.setScale(0f);
}
......@@ -143,15 +134,6 @@ class PlayerFrameMediator implements PlayerFrameViewDelegate, PlayerFrameMediato
setBitmapScaleMatrix(matrix, scaleFactor);
}
/**
* Sets the overscroll-to-refresh handler on the {@link mScrollController}. This cannot be
* created at construction of this object as it needs to be created on top of the view
* hierarchy to show the animation.
*/
void setOverscrollHandler(OverscrollHandler overscrollHandler) {
mScrollController.setOverscrollHandler(overscrollHandler);
}
// PlayerFrameViewDelegate
@Override
......@@ -163,35 +145,10 @@ class PlayerFrameMediator implements PlayerFrameViewDelegate, PlayerFrameMediato
}
// Set initial scale so that content width fits within the layout dimensions.
mScaleController.calculateInitialScaleFactor(width);
adjustInitialScaleFactor(width);
final float scaleFactor = mViewport.getScale();
updateViewportSize(width, height,
(scaleFactor == 0f) ? mScaleController.getInitialScaleFactor() : scaleFactor);
}
@Override
public boolean scrollBy(float distanceX, float distanceY) {
return mScrollController.scrollBy(distanceX, distanceY);
}
@Override
public boolean onFling(float velocityX, float velocityY) {
return mScrollController.onFling(velocityX, velocityY);
}
@Override
public void onRelease() {
mScrollController.onRelease();
}
@Override
public boolean scaleBy(float scaleFactor, float focalPointX, float focalPointY) {
return mScaleController.scaleBy(scaleFactor, focalPointX, focalPointY);
}
@Override
public boolean scaleFinished(float scaleFactor, float focalPointX, float focalPointY) {
return mScaleController.scaleFinished(scaleFactor, focalPointX, focalPointY);
updateViewportSize(
width, height, (scaleFactor == 0f) ? getInitialScaleFactor() : scaleFactor);
}
@Override
......@@ -212,6 +169,21 @@ class PlayerFrameMediator implements PlayerFrameViewDelegate, PlayerFrameMediato
// PlayerFrameMediatorDelegate
@Override
public PlayerFrameViewport getViewport() {
return mViewport;
}
@Override
public Size getContentSize() {
return mContentSize;
}
@Override
public float getInitialScaleFactor() {
return mInitialScaleFactor;
}
@Override
public void onStartScaling() {
mBitmapStateController.invalidateLoadingBitmaps();
......@@ -342,10 +314,9 @@ class PlayerFrameMediator implements PlayerFrameViewDelegate, PlayerFrameMediato
@VisibleForTesting
void forceRedraw() {
mScaleController.calculateInitialScaleFactor(mViewport.getWidth());
adjustInitialScaleFactor(mViewport.getWidth());
final float scaleFactor = mViewport.getScale();
mViewport.setScale(
(scaleFactor == 0f) ? mScaleController.getInitialScaleFactor() : scaleFactor);
mViewport.setScale((scaleFactor == 0f) ? getInitialScaleFactor() : scaleFactor);
updateVisuals(true);
for (int i = 0; i < mSubFrameViews.size(); i++) {
if (mSubFrameViews.get(i).getVisibility() != View.VISIBLE) continue;
......@@ -360,4 +331,12 @@ class PlayerFrameMediator implements PlayerFrameViewDelegate, PlayerFrameMediato
(int) (((float) inRect.right) * scaleFactor),
(int) (((float) inRect.bottom) * scaleFactor));
}
/**
* Calculates the initial scale factor for a given viewport width.
* @param width The viewport width.
*/
private void adjustInitialScaleFactor(float width) {
mInitialScaleFactor = width / ((float) mContentSize.getWidth());
}
}
......@@ -7,11 +7,27 @@ package org.chromium.components.paintpreview.player.frame;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.util.Size;
/**
* API of the PlayerFrameMediator to helper classes.
*/
public interface PlayerFrameMediatorDelegate {
/**
* Gets the visual viewport of the player.
*/
public PlayerFrameViewport getViewport();
/**
* Gets the size of the content shown in the mediator.
*/
public Size getContentSize();
/**
* Gets the initial scale factor at the last computed viewport width.
*/
public float getInitialScaleFactor();
/**
* Triggers an update of the visual contents of the PlayerFrameView. This fetches updates the
* model and fetches any new bitmaps asynchronously.
......
......@@ -18,7 +18,6 @@ import org.chromium.base.Callback;
public class PlayerFrameScaleController {
private static final float MAX_SCALE_FACTOR = 5f;
private float mInitialScaleFactor;
private float mUncommittedScaleFactor;
/** References to shared state. */
......@@ -29,31 +28,17 @@ public class PlayerFrameScaleController {
private final PlayerFrameMediatorDelegate mMediatorDelegate;
private final Callback<Boolean> mOnScaleListener;
PlayerFrameScaleController(PlayerFrameViewport viewport, Size contentSize,
Matrix bitmapScaleMatrix, PlayerFrameMediatorDelegate mediatorDelegate,
PlayerFrameScaleController(Matrix bitmapScaleMatrix,
PlayerFrameMediatorDelegate mediatorDelegate,
@Nullable Callback<Boolean> onScaleListener) {
mViewport = viewport;
mContentSize = contentSize;
mUncommittedScaleFactor = 0f;
mViewport = mediatorDelegate.getViewport();
mContentSize = mediatorDelegate.getContentSize();
mBitmapScaleMatrix = bitmapScaleMatrix;
mMediatorDelegate = mediatorDelegate;
mOnScaleListener = onScaleListener;
}
/**
* Calculates the initial scale factor for a given viewport width.
* @param width The viewport width.
*/
void calculateInitialScaleFactor(float width) {
mInitialScaleFactor = width / ((float) mContentSize.getWidth());
}
/**
* Gets the initial scale factor at the last computed viewport width.
*/
float getInitialScaleFactor() {
return mInitialScaleFactor;
}
/**
* How scale for the paint preview player works.
*
......@@ -92,22 +77,23 @@ public class PlayerFrameScaleController {
}
// Don't scale outside of the acceptable range. The value is still accumulated such that the
// continuous gesture feels smooth.
final float initialScaleFactor = mMediatorDelegate.getInitialScaleFactor();
final float lastUncommittedScaleFactor = mUncommittedScaleFactor;
mUncommittedScaleFactor *= scaleFactor;
// Compute a corrected and bounded scale factor when close to the max/min scale.
if (mUncommittedScaleFactor < mInitialScaleFactor
&& lastUncommittedScaleFactor > mInitialScaleFactor) {
scaleFactor = mInitialScaleFactor / lastUncommittedScaleFactor;
if (mUncommittedScaleFactor < initialScaleFactor
&& lastUncommittedScaleFactor > initialScaleFactor) {
scaleFactor = initialScaleFactor / lastUncommittedScaleFactor;
} else if (mUncommittedScaleFactor > MAX_SCALE_FACTOR
&& lastUncommittedScaleFactor < MAX_SCALE_FACTOR) {
scaleFactor = MAX_SCALE_FACTOR / lastUncommittedScaleFactor;
} else if (mUncommittedScaleFactor > mInitialScaleFactor
&& lastUncommittedScaleFactor < mInitialScaleFactor) {
scaleFactor = mUncommittedScaleFactor / mInitialScaleFactor;
} else if (mUncommittedScaleFactor > initialScaleFactor
&& lastUncommittedScaleFactor < initialScaleFactor) {
scaleFactor = mUncommittedScaleFactor / initialScaleFactor;
} else if (mUncommittedScaleFactor < MAX_SCALE_FACTOR
&& lastUncommittedScaleFactor > MAX_SCALE_FACTOR) {
scaleFactor = mUncommittedScaleFactor / MAX_SCALE_FACTOR;
} else if (mUncommittedScaleFactor < mInitialScaleFactor
} else if (mUncommittedScaleFactor < initialScaleFactor
|| lastUncommittedScaleFactor > MAX_SCALE_FACTOR) {
return true;
}
......
......@@ -32,12 +32,11 @@ public class PlayerFrameScrollController {
private final Runnable mOnScrollListener;
private final Runnable mOnFlingListener;
PlayerFrameScrollController(OverScroller scroller, PlayerFrameViewport viewport,
Size contentSize, PlayerFrameMediatorDelegate mediatorDelegate,
PlayerFrameScrollController(OverScroller scroller, PlayerFrameMediatorDelegate mediatorDelegate,
@Nullable Runnable onScrollListener, @Nullable Runnable onFlingListener) {
mScroller = scroller;
mViewport = viewport;
mContentSize = contentSize;
mViewport = mediatorDelegate.getViewport();
mContentSize = mediatorDelegate.getContentSize();
mMediatorDelegate = mediatorDelegate;
mOnScrollListener = onScrollListener;
mOnFlingListener = onFlingListener;
......
......@@ -38,13 +38,14 @@ class PlayerFrameView extends FrameLayout {
* @param playerFrameViewDelegate The interface used for forwarding events.
*/
PlayerFrameView(@NonNull Context context, boolean canDetectZoom,
PlayerFrameViewDelegate playerFrameViewDelegate) {
PlayerFrameViewDelegate playerFrameViewDelegate,
PlayerFrameGestureDetectorDelegate gestureDetectorDelegate) {
super(context);
setWillNotDraw(false);
mDelegate = playerFrameViewDelegate;
mBitmapPainter = new PlayerFrameBitmapPainter(this::invalidate);
mGestureDetector =
new PlayerFrameGestureDetector(context, canDetectZoom, playerFrameViewDelegate);
new PlayerFrameGestureDetector(context, canDetectZoom, gestureDetectorDelegate);
}
PlayerFrameGestureDetector getGestureDetector() {
......
......@@ -13,26 +13,6 @@ interface PlayerFrameViewDelegate {
*/
void setLayoutDimensions(int width, int height);
/**
* Called when a scroll gesture is performed.
* @param distanceX Horizontal scroll values in pixels.
* @param distanceY Vertical scroll values in pixels.
* @return Whether this scroll event was consumed.
*/
boolean scrollBy(float distanceX, float distanceY);
/**
* Called when a scale gesture is performed.
* @return Whether this scale event was consumed.
*/
boolean scaleBy(float scaleFactor, float focalPointX, float focalPointY);
/**
* Called when a scale gesture is finished.
* @return Whether this scale event was consumed.
*/
boolean scaleFinished(float scaleFactor, float focalPointX, float focalPointY);
/**
* Called when a single tap gesture is performed.
* @param x X coordinate of the point clicked.
......@@ -46,17 +26,4 @@ interface PlayerFrameViewDelegate {
* @param y Y coordinate of the point clicked.
*/
void onLongPress(int x, int y);
/**
* Called when a fling gesture is performed.
* @param velocityX Horizontal velocity value in pixels.
* @param velocityY Vertical velocity value in pixels.
* @return Whether this fling was consumed.
*/
boolean onFling(float velocityX, float velocityY);
/**
* Called when a gesture is released.
*/
void onRelease();
}
......@@ -7,6 +7,7 @@ package org.chromium.components.paintpreview.player.frame;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.when;
import android.graphics.Matrix;
import android.util.Size;
......@@ -59,29 +60,16 @@ public class PlayerFrameScaleControllerTest {
Callback<Boolean> mScaleListener = (Boolean didFinish) -> mDidScale = true;
mViewport = new PlayerFrameViewport();
mBitmapScaleMatrix = new Matrix();
mScaleController =
new PlayerFrameScaleController(mViewport, new Size(CONTENT_WIDTH, CONTENT_HEIGHT),
mBitmapScaleMatrix, mMediatorDelegateMock, mScaleListener);
mScaleController.calculateInitialScaleFactor(CONTENT_WIDTH);
mViewport.setScale(mScaleController.getInitialScaleFactor());
Size contentSize = new Size(CONTENT_WIDTH, CONTENT_HEIGHT);
when(mMediatorDelegateMock.getViewport()).thenReturn(mViewport);
when(mMediatorDelegateMock.getContentSize()).thenReturn(contentSize);
when(mMediatorDelegateMock.getInitialScaleFactor()).thenReturn(1f);
mScaleController = new PlayerFrameScaleController(
mBitmapScaleMatrix, mMediatorDelegateMock, mScaleListener);
mViewport.setScale(1f);
mViewport.setSize(100, 100);
}
/**
* Tests calculating and getting the initial scale factor.
*/
@Test
public void testInitialScaleFactor() {
mScaleController.calculateInitialScaleFactor(CONTENT_WIDTH);
Assert.assertEquals(1f, mScaleController.getInitialScaleFactor(), TOLERANCE);
mScaleController.calculateInitialScaleFactor(250);
Assert.assertEquals(0.5f, mScaleController.getInitialScaleFactor(), TOLERANCE);
mScaleController.calculateInitialScaleFactor(1000);
Assert.assertEquals(2f, mScaleController.getInitialScaleFactor(), TOLERANCE);
}
/**
* Tests the limits of scaling.
*/
......
......@@ -56,9 +56,11 @@ public class PlayerFrameScrollControllerTest {
Runnable mOnScrollListener = () -> mDidScroll = true;
Runnable mOnFlingListener = () -> mDidFling = true;
mViewport = new PlayerFrameViewport();
mScrollController = new PlayerFrameScrollController(mScroller, mViewport,
new Size(CONTENT_WIDTH, CONTENT_HEIGHT), mMediatorDelegateMock, mOnScrollListener,
mOnFlingListener);
when(mMediatorDelegateMock.getViewport()).thenReturn(mViewport);
when(mMediatorDelegateMock.getContentSize())
.thenReturn(new Size(CONTENT_WIDTH, CONTENT_HEIGHT));
mScrollController = new PlayerFrameScrollController(
mScroller, mMediatorDelegateMock, mOnScrollListener, mOnFlingListener);
}
/**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment