From e53b05feba5c8484799bae6bb3bad1511532a2bd Mon Sep 17 00:00:00 2001 From: inorichi Date: Sat, 30 Jan 2016 16:40:41 +0100 Subject: [PATCH] Fix gestures on vertical readers --- .../viewer/pager/PagerReaderFragment.java | 4 +- .../viewer/pager/vertical/VerticalPager.java | 17 +---- .../reader/viewer/webtoon/WebtoonAdapter.java | 5 ++ .../reader/viewer/webtoon/WebtoonHolder.java | 6 +- .../reader/viewer/webtoon/WebtoonReader.java | 10 --- .../SubsamplingScaleImageView.java | 70 +++++++++++++------ 6 files changed, 61 insertions(+), 51 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerReaderFragment.java b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerReaderFragment.java index ffcd8429c0..9330f20675 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerReaderFragment.java +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerReaderFragment.java @@ -25,6 +25,7 @@ import eu.kanade.tachiyomi.R; import eu.kanade.tachiyomi.data.source.model.Page; import eu.kanade.tachiyomi.ui.base.fragment.BaseFragment; import eu.kanade.tachiyomi.ui.reader.ReaderActivity; +import eu.kanade.tachiyomi.ui.reader.viewer.pager.vertical.VerticalReader; import rx.Observable; import rx.Subscription; import rx.android.schedulers.AndroidSchedulers; @@ -61,12 +62,13 @@ public class PagerReaderFragment extends BaseFragment { } imageView.setParallelLoadingEnabled(true); - imageView.setMaxDimensions(activity.getMaxBitmapSize(), activity.getMaxBitmapSize()); + imageView.setMaxBitmapDimensions(activity.getMaxBitmapSize()); imageView.setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_FIXED); imageView.setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_INSIDE); imageView.setMinimumScaleType(parentFragment.scaleType); imageView.setRegionDecoderClass(parentFragment.getRegionDecoderClass()); imageView.setBitmapDecoderClass(parentFragment.getBitmapDecoderClass()); + imageView.setVerticalScroll(parentFragment instanceof VerticalReader); imageView.setOnTouchListener((v, motionEvent) -> parentFragment.onImageTouch(motionEvent)); imageView.setOnImageEventListener(new SubsamplingScaleImageView.DefaultOnImageEventListener() { @Override diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/vertical/VerticalPager.java b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/vertical/VerticalPager.java index 25b6271b54..fc9fc563c0 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/vertical/VerticalPager.java +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/vertical/VerticalPager.java @@ -32,7 +32,7 @@ public class VerticalPager extends VerticalViewPagerImpl implements Pager { } private void init(Context context) { - gestureDetector = new GestureDetector(context, new VerticalPagerGestureListener(this)); + gestureDetector = new GestureDetector(context, new PagerGestureListener(this)); } @Override @@ -119,20 +119,5 @@ public class VerticalPager extends VerticalViewPagerImpl implements Pager { } }); } - - private static class VerticalPagerGestureListener extends PagerGestureListener { - - public VerticalPagerGestureListener(Pager pager) { - super(pager); - } - - @Override - public boolean onDown(MotionEvent e) { - // Vertical view pager ignores scrolling events sometimes. - // Returning true here fixes it, but we lose touch events on the image like - // double tap to zoom - return true; - } - } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonAdapter.java b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonAdapter.java index 451f0b141c..780e8c1e75 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonAdapter.java +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonAdapter.java @@ -10,6 +10,7 @@ import java.util.List; import eu.kanade.tachiyomi.R; import eu.kanade.tachiyomi.data.source.model.Page; +import eu.kanade.tachiyomi.ui.reader.ReaderActivity; public class WebtoonAdapter extends RecyclerView.Adapter { @@ -64,4 +65,8 @@ public class WebtoonAdapter extends RecyclerView.Adapter { return fragment; } + public ReaderActivity getReaderActivity() { + return (ReaderActivity) fragment.getActivity(); + } + } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonHolder.java b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonHolder.java index ad10fbf20b..f384d98ffb 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonHolder.java +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonHolder.java @@ -14,7 +14,6 @@ import butterknife.Bind; import butterknife.ButterKnife; import eu.kanade.tachiyomi.R; import eu.kanade.tachiyomi.data.source.model.Page; -import eu.kanade.tachiyomi.ui.reader.ReaderActivity; public class WebtoonHolder extends RecyclerView.ViewHolder { @@ -31,17 +30,16 @@ public class WebtoonHolder extends RecyclerView.ViewHolder { this.adapter = adapter; ButterKnife.bind(this, view); - int maxDim = ((ReaderActivity)adapter.getReader().getActivity()).getMaxBitmapSize(); - imageView.setParallelLoadingEnabled(true); + imageView.setMaxBitmapDimensions(adapter.getReaderActivity().getMaxBitmapSize()); imageView.setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_FIXED); imageView.setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_INSIDE); imageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_FIT_WIDTH); imageView.setMaxScale(10); imageView.setRegionDecoderClass(adapter.getReader().getRegionDecoderClass()); imageView.setBitmapDecoderClass(adapter.getReader().getBitmapDecoderClass()); + imageView.setVerticalScroll(true); imageView.setOnTouchListener(touchListener); - imageView.setMaxDimensions(maxDim, maxDim); imageView.setOnImageEventListener(new SubsamplingScaleImageView.DefaultOnImageEventListener() { @Override public void onImageLoaded() { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonReader.java b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonReader.java index f7adb06f45..4e09dee99c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonReader.java +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonReader.java @@ -1,7 +1,6 @@ package eu.kanade.tachiyomi.ui.reader.viewer.webtoon; import android.os.Bundle; -import android.support.annotation.Nullable; import android.support.v7.widget.RecyclerView; import android.view.GestureDetector; import android.view.LayoutInflater; @@ -30,7 +29,6 @@ public class WebtoonReader extends BaseReader { private Subscription decoderSubscription; private GestureDetector gestureDetector; - @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) { adapter = new WebtoonAdapter(this); @@ -56,14 +54,6 @@ public class WebtoonReader extends BaseReader { getReaderActivity().onCenterSingleTap(); return true; } - - @Override - public boolean onDown(MotionEvent e) { - // The only way I've found to allow panning. Double tap event (zoom) is lost - // but panning should be the most used one - return true; - } - }); setPages(); diff --git a/libs/SubsamplingScaleImageView/src/com/davemorrissey/labs/subscaleview/SubsamplingScaleImageView.java b/libs/SubsamplingScaleImageView/src/com/davemorrissey/labs/subscaleview/SubsamplingScaleImageView.java index 15664a7d0c..a4d559baa7 100644 --- a/libs/SubsamplingScaleImageView/src/com/davemorrissey/labs/subscaleview/SubsamplingScaleImageView.java +++ b/libs/SubsamplingScaleImageView/src/com/davemorrissey/labs/subscaleview/SubsamplingScaleImageView.java @@ -201,8 +201,12 @@ public class SubsamplingScaleImageView extends View { private int sOrientation; private Rect sRegion; private Rect pRegion; - private int cWidth; - private int cHeight; + + // Max bitmap dimensions the device can display + private int maxBitmapDimensions; + + // Vertical pagers/scrollers should enable this + private boolean isVerticalScroll; // Is two-finger zooming in progress private boolean isZooming; @@ -754,16 +758,32 @@ public class SubsamplingScaleImageView extends View { float lastX = vTranslate.x; float lastY = vTranslate.y; fitToBounds(true); - boolean atXEdge = lastX != vTranslate.x; - boolean edgeXSwipe = atXEdge && dx > dy && !isPanning; - boolean yPan = lastY == vTranslate.y && dy > 15; - if (!edgeXSwipe && (!atXEdge || yPan || isPanning)) { - isPanning = true; - } else if (dx > 5) { - // Haven't panned the image, and we're at the left or right edge. Switch to page swipe. - maxTouchCount = 0; - handler.removeMessages(MESSAGE_LONG_CLICK); - getParent().requestDisallowInterceptTouchEvent(false); + if (!isVerticalScroll) { + boolean atXEdge = lastX != vTranslate.x; + boolean edgeXSwipe = atXEdge && dx > dy && !isPanning; + boolean yPan = lastY == vTranslate.y && dy > 15; + + if (!edgeXSwipe && (!atXEdge || yPan || isPanning)) { + isPanning = true; + } else if (dx > 5) { + // Haven't panned the image, and we're at the left or right edge. Switch to page swipe. + maxTouchCount = 0; + handler.removeMessages(MESSAGE_LONG_CLICK); + getParent().requestDisallowInterceptTouchEvent(false); + } + } else { + boolean atYEdge = lastY != vTranslate.y; + boolean edgeYSwipe = atYEdge && dy > dx && !isPanning; + boolean xPan = lastX == vTranslate.x && dx > 15; + + if (!edgeYSwipe && (!atYEdge || xPan || isPanning)) { + isPanning = true; + } else if (dy > 5) { + // Haven't panned the image, and we're at the left or right edge. Switch to page swipe. + maxTouchCount = 0; + handler.removeMessages(MESSAGE_LONG_CLICK); + getParent().requestDisallowInterceptTouchEvent(false); + } } if (!panEnabled) { @@ -870,7 +890,7 @@ public class SubsamplingScaleImageView extends View { } // When using tiles, on first render with no tile map ready, initialise it and kick off async base image loading. - if (tileMap == null && decoder != null && cWidth == 0 && cHeight == 0) { + if (tileMap == null && decoder != null && maxBitmapDimensions == 0) { initialiseBaseLayer(getMaxBitmapDimensions(canvas)); } @@ -1390,11 +1410,6 @@ public class SubsamplingScaleImageView extends View { } } - public void setMaxDimensions(int width, int height) { - cWidth = width; - cHeight = height; - } - /** * Async task used to get image details without blocking the UI thread. */ @@ -1473,8 +1488,8 @@ public class SubsamplingScaleImageView extends View { this.sHeight = sHeight; this.sOrientation = sOrientation; checkReady(); - if (!checkImageLoaded() && cWidth != 0 && cHeight != 0) { - initialiseBaseLayer(new Point(cWidth, cHeight)); + if (!checkImageLoaded() && maxBitmapDimensions > 0) { + initialiseBaseLayer(new Point(maxBitmapDimensions, maxBitmapDimensions)); } invalidate(); requestLayout(); @@ -2476,6 +2491,21 @@ public class SubsamplingScaleImageView extends View { this.parallelLoadingEnabled = parallelLoadingEnabled; } + /** + * Set max bitmap dimensions the device can display + */ + public void setMaxBitmapDimensions(int maxBitmapDimensions) { + this.maxBitmapDimensions = maxBitmapDimensions; + } + + + /** + * Set vertical scroll mode to fix gestures + */ + public void setVerticalScroll(boolean isVerticalScroll) { + this.isVerticalScroll = isVerticalScroll; + } + /** * Enables visual debugging, showing tile boundaries and sizes. */