/******************************************************************************* * Copyright 2011, 2012 Chris Banes. * <p> * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *******************************************************************************/ package me.xiaopan.sketch.feature.zoom; import android.content.Context; import android.graphics.Point; import android.graphics.RectF; import android.widget.ImageView; import me.xiaopan.sketch.SLogType; import me.xiaopan.sketch.SLog; import me.xiaopan.sketch.feature.zoom.scrollerproxy.ScrollerProxy; class FlingTranslateRunner implements Runnable { private final ScrollerProxy mScroller; private ImageZoomer imageZoomer; private int mCurrentX, mCurrentY; FlingTranslateRunner(Context context, ImageZoomer imageZoomer) { this.mScroller = ScrollerProxy.getScroller(context); this.imageZoomer = imageZoomer; } void fling(int velocityX, int velocityY) { if (!imageZoomer.isWorking()) { if (SLogType.ZOOM.isEnabled()) { SLog.w(SLogType.ZOOM, ImageZoomer.NAME, "not working. fling"); } return; } RectF drawRectF = new RectF(); imageZoomer.getDrawRect(drawRectF); if (drawRectF.isEmpty()) { return; } Point imageViewSize = imageZoomer.getImageViewSize(); final int imageViewWidth = imageViewSize.x; final int imageViewHeight = imageViewSize.y; final int startX = Math.round(-drawRectF.left); final int minX, maxX, minY, maxY; if (imageViewWidth < drawRectF.width()) { minX = 0; maxX = Math.round(drawRectF.width() - imageViewWidth); } else { minX = maxX = startX; } final int startY = Math.round(-drawRectF.top); if (imageViewHeight < drawRectF.height()) { minY = 0; maxY = Math.round(drawRectF.height() - imageViewHeight); } else { minY = maxY = startY; } if (SLogType.ZOOM.isEnabled()) { SLog.d(SLogType.ZOOM, ImageZoomer.NAME, "fling. start=%dx %d, min=%dx%d, max=%dx%d", startX, startY, minX, minY, maxX, maxY); } // If we actually can move, fling the scroller if (startX != maxX || startY != maxY) { mCurrentX = startX; mCurrentY = startY; mScroller.fling(startX, startY, velocityX, velocityY, minX, maxX, minY, maxY, 0, 0); } ImageView imageView = imageZoomer.getImageView(); imageView.removeCallbacks(this); imageView.post(this); } @Override public void run() { // remaining post that should not be handled if (mScroller.isFinished()) { if (SLogType.ZOOM.isEnabled()) { SLog.w(SLogType.ZOOM, ImageZoomer.NAME, "finished. fling run"); } return; } if (!imageZoomer.isWorking()) { if (SLogType.ZOOM.isEnabled()) { SLog.w(SLogType.ZOOM, ImageZoomer.NAME, "not working. fling run"); } return; } if (!mScroller.computeScrollOffset()) { if (SLogType.ZOOM.isEnabled()) { SLog.w(SLogType.ZOOM, ImageZoomer.NAME, "scroll finished. fling run"); } return; } final int newX = mScroller.getCurrX(); final int newY = mScroller.getCurrY(); imageZoomer.translateBy(mCurrentX - newX, mCurrentY - newY); mCurrentX = newX; mCurrentY = newY; // Post On animation CompatUtils.postOnAnimation(imageZoomer.getImageView(), this); } @SuppressWarnings("WeakerAccess") public void cancelFling() { if (SLogType.ZOOM.isEnabled()) { SLog.d(SLogType.ZOOM, ImageZoomer.NAME, "cancel fling"); } if (mScroller != null) { mScroller.forceFinished(true); } ImageView imageView = imageZoomer.getImageView(); if (imageView != null) { imageView.removeCallbacks(this); } } }