Skip to content

Commit 259d733

Browse files
committed
Restored quick scale setting and added an XML attribute for it
1 parent 7e7c2ae commit 259d733

File tree

1 file changed

+69
-36
lines changed

1 file changed

+69
-36
lines changed

library/src/com/davemorrissey/labs/subscaleview/SubsamplingScaleImageView.java

Lines changed: 69 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ public class SubsamplingScaleImageView extends View {
143143
// Gesture detection settings
144144
private boolean panEnabled = true;
145145
private boolean zoomEnabled = true;
146+
private boolean quickScaleEnabled = true;
146147

147148
// Double tap zoom behaviour
148149
private float doubleTapZoomScale = 1F;
@@ -262,6 +263,9 @@ public boolean handleMessage(Message message) {
262263
if (typedAttr.hasValue(styleable.SubsamplingScaleImageView_zoomEnabled)) {
263264
setZoomEnabled(typedAttr.getBoolean(styleable.SubsamplingScaleImageView_zoomEnabled, true));
264265
}
266+
if (typedAttr.hasValue(styleable.SubsamplingScaleImageView_quickScaleEnabled)) {
267+
setQuickScaleEnabled(typedAttr.getBoolean(styleable.SubsamplingScaleImageView_quickScaleEnabled, true));
268+
}
265269
if (typedAttr.hasValue(styleable.SubsamplingScaleImageView_tileBackgroundColor)) {
266270
setTileBackgroundColor(typedAttr.getColor(styleable.SubsamplingScaleImageView_tileBackgroundColor, Color.argb(0, 0, 0, 0)));
267271
}
@@ -472,21 +476,28 @@ public boolean onSingleTapConfirmed(MotionEvent e) {
472476
@Override
473477
public boolean onDoubleTap(MotionEvent e) {
474478
if (zoomEnabled && readySent && vTranslate != null) {
475-
vCenterStart = new PointF(e.getX(), e.getY());
476-
vTranslateStart = new PointF(vTranslate.x, vTranslate.y);
477-
scaleStart = scale;
478-
479-
isQuickScaling = true;
480-
isZooming = true;
481-
quickScaleCenter = viewToSourceCoord(vCenterStart);
482-
quickScaleLastDistance = -1F;
483-
quickScaleLastPoint = new PointF(quickScaleCenter.x, quickScaleCenter.y);
484-
quickScaleMoved = false;
485-
479+
// Hacky solution for #15 - after a double tap the GestureDetector gets in a state
480+
// where the next fling is ignored, so here we replace it with a new one.
486481
setGestureDetector(context);
487-
488-
// We really want to get events in onTouchEvent after this, so don't return true
489-
return false;
482+
if (quickScaleEnabled) {
483+
// Store quick scale params. This will become either a double tap zoom or a
484+
// quick scale depending on whether the user swipes.
485+
vCenterStart = new PointF(e.getX(), e.getY());
486+
vTranslateStart = new PointF(vTranslate.x, vTranslate.y);
487+
scaleStart = scale;
488+
isQuickScaling = true;
489+
isZooming = true;
490+
quickScaleCenter = viewToSourceCoord(vCenterStart);
491+
quickScaleLastDistance = -1F;
492+
quickScaleLastPoint = new PointF(quickScaleCenter.x, quickScaleCenter.y);
493+
quickScaleMoved = false;
494+
// We need to get events in onTouchEvent after this.
495+
return false;
496+
} else {
497+
// Start double tap zoom animation.
498+
doubleTapZoom(viewToSourceCoord(new PointF(e.getX(), e.getY())), new PointF(e.getX(), e.getY()));
499+
return true;
500+
}
490501
}
491502
return super.onDoubleTapEvent(e);
492503
}
@@ -731,28 +742,7 @@ public boolean onTouchEvent(@NonNull MotionEvent event) {
731742
if (isQuickScaling) {
732743
isQuickScaling = false;
733744
if (!quickScaleMoved) {
734-
if (!panEnabled) {
735-
if (sRequestedCenter != null) {
736-
// With a center specified from code, zoom around that point.
737-
quickScaleCenter.x = sRequestedCenter.x;
738-
quickScaleCenter.y = sRequestedCenter.y;
739-
} else {
740-
// With no requested center, scale around the image center.
741-
quickScaleCenter.x = sWidth()/2;
742-
quickScaleCenter.y = sHeight()/2;
743-
}
744-
}
745-
float doubleTapZoomScale = Math.min(maxScale, SubsamplingScaleImageView.this.doubleTapZoomScale);
746-
boolean zoomIn = scale <= doubleTapZoomScale * 0.9;
747-
float targetScale = zoomIn ? doubleTapZoomScale : minScale();
748-
if (doubleTapZoomStyle == ZOOM_FOCUS_CENTER_IMMEDIATE) {
749-
setScaleAndCenter(targetScale, quickScaleCenter);
750-
} else if (doubleTapZoomStyle == ZOOM_FOCUS_CENTER || !zoomIn || !panEnabled) {
751-
new AnimationBuilder(targetScale, quickScaleCenter).withInterruptible(false).start();
752-
} else if (doubleTapZoomStyle == ZOOM_FOCUS_FIXED) {
753-
new AnimationBuilder(targetScale, quickScaleCenter, vCenterStart).withInterruptible(false).start();
754-
}
755-
invalidate();
745+
doubleTapZoom(quickScaleCenter, vCenterStart);
756746
}
757747
}
758748
if (maxTouchCount > 0 && (isZooming || isPanning)) {
@@ -789,6 +779,35 @@ public boolean onTouchEvent(@NonNull MotionEvent event) {
789779
return super.onTouchEvent(event);
790780
}
791781

782+
/**
783+
* Double tap zoom handler triggered from gesture detector or on touch, depending on whether
784+
* quick scale is enabled.
785+
*/
786+
private void doubleTapZoom(PointF sCenter, PointF vFocus) {
787+
if (!panEnabled) {
788+
if (sRequestedCenter != null) {
789+
// With a center specified from code, zoom around that point.
790+
sCenter.x = sRequestedCenter.x;
791+
sCenter.y = sRequestedCenter.y;
792+
} else {
793+
// With no requested center, scale around the image center.
794+
sCenter.x = sWidth()/2;
795+
sCenter.y = sHeight()/2;
796+
}
797+
}
798+
float doubleTapZoomScale = Math.min(maxScale, SubsamplingScaleImageView.this.doubleTapZoomScale);
799+
boolean zoomIn = scale <= doubleTapZoomScale * 0.9;
800+
float targetScale = zoomIn ? doubleTapZoomScale : minScale();
801+
if (doubleTapZoomStyle == ZOOM_FOCUS_CENTER_IMMEDIATE) {
802+
setScaleAndCenter(targetScale, sCenter);
803+
} else if (doubleTapZoomStyle == ZOOM_FOCUS_CENTER || !zoomIn || !panEnabled) {
804+
new AnimationBuilder(targetScale, sCenter).withInterruptible(false).start();
805+
} else if (doubleTapZoomStyle == ZOOM_FOCUS_FIXED) {
806+
new AnimationBuilder(targetScale, sCenter, vFocus).withInterruptible(false).start();
807+
}
808+
invalidate();
809+
}
810+
792811
/**
793812
* Draw method should not be called until the view has dimensions so the first calls are used as triggers to calculate
794813
* the scaling and tiling required. Once the view is setup, tiles are displayed as they are loaded.
@@ -2174,6 +2193,20 @@ public final void setZoomEnabled(boolean zoomEnabled) {
21742193
this.zoomEnabled = zoomEnabled;
21752194
}
21762195

2196+
/**
2197+
* Returns true if double tap & swipe to zoom is enabled.
2198+
*/
2199+
public final boolean isQuickScaleEnabled() {
2200+
return quickScaleEnabled;
2201+
}
2202+
2203+
/**
2204+
* Enable or disable double tap & swipe to zoom.
2205+
*/
2206+
public final void setQuickScaleEnabled(boolean quickScaleEnabled) {
2207+
this.quickScaleEnabled = quickScaleEnabled;
2208+
}
2209+
21772210
/**
21782211
* Returns true if pan gesture detection is enabled.
21792212
*/

0 commit comments

Comments
 (0)