diff --git a/README.md b/README.md index 0b22325..9539137 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,10 @@ A container for view hierarchies that can be panned or zoomed. app:verticalPanEnabled="true" app:zoomEnabled="true" app:flingEnabled="true" + app:scrollEnabled="true" + app:oneFingerScrollEnabled="true" + app:twoFingersScrollEnabled="true" + app:threeFingersScrollEnabled="true" app:minZoom="0.7" app:minZoomType="zoom" app:maxZoom="2.5" @@ -106,6 +110,10 @@ An `ImageView` implementation to control pan and zoom over its Drawable or Bitma app:verticalPanEnabled="true" app:zoomEnabled="true" app:flingEnabled="true" + app:scrollEnabled="true" + app:oneFingerScrollEnabled="true" + app:twoFingersScrollEnabled="true" + app:threeFingersScrollEnabled="true" app:minZoom="0.7" app:minZoomType="zoom" app:maxZoom="2.5" @@ -158,6 +166,10 @@ that streams image buffers into a `Surface`. app:verticalPanEnabled="true" app:zoomEnabled="true" app:flingEnabled="true" + app:scrollEnabled="true" + app:oneFingerScrollEnabled="true" + app:twoFingersScrollEnabled="true" + app:threeFingersScrollEnabled="true" app:minZoom="1" app:minZoomType="zoom" app:maxZoom="2.5" @@ -351,6 +363,10 @@ In any case the current scale is not considered, so your system won't change if |`setHorizontalPanEnabled(boolean)`|If true, the content will be allowed to pan **horizontally** by user input.|`true`| |`setVerticalPanEnabled(boolean)`|If true, the content will be allowed to pan **vertically** by user input.|`true`| |`setFlingEnabled(boolean)`|If true, fling gestures will be detected.|`true`| +|`setScrollEnabled(boolean)`|If true, scroll gestures will be detected.|`true`| +|`setOneFingerScrollEnabled(boolean)`|If true, one finger scroll gestures will be detected.|`true`| +|`setTwoFingersScrollEnabled(boolean)`|If true, two fingers scroll gestures will be detected.|`true`| +|`setThreeFingersScrollEnabled(boolean)`|If true, three fingers scroll gestures will be detected.|`true`| |`setAllowFlingInOverscroll(boolean)`|If true, fling gestures will be allowed even when detected while overscrolled. This might cause artifacts so it is disabled by default.|`false`| |`panTo(float, float, boolean)`|Pans to the given values, animating if needed.|`-`| |`panBy(float, float, boolean)`|Applies the given deltas to the current pan, animating if needed.|`-`| diff --git a/library/src/main/java/com/otaliastudios/zoom/ZoomApi.kt b/library/src/main/java/com/otaliastudios/zoom/ZoomApi.kt index 8c102f9..7148d48 100644 --- a/library/src/main/java/com/otaliastudios/zoom/ZoomApi.kt +++ b/library/src/main/java/com/otaliastudios/zoom/ZoomApi.kt @@ -229,6 +229,34 @@ interface ZoomApi { fun setFlingEnabled(enabled: Boolean) // TODO (v2) rename to var isFlingEnabled or isGestureFlingEnabled to clearly differentiate gestures and engine movements (pan/zoom) + /** + * Controls whether scroll gesture is enabled or not. + * + * @param enabled true enables scroll gesture, false disables it + */ + fun setScrollEnabled(enabled: Boolean) + + /** + * Controls whether one finger scroll gesture is enabled or not. + * + * @param enabled true enables one finger scroll gesture, false disables it + */ + fun setOneFingerScrollEnabled(enabled: Boolean) + + /** + * Controls whether two fingers scroll gesture is enabled or not. + * + * @param enabled true enables two fingers scroll gesture, false disables it + */ + fun setTwoFingersScrollEnabled(enabled: Boolean) + + /** + * Controls whether three fingers scroll gesture is enabled or not. + * + * @param enabled true enables three fingers scroll gesture, false disables it + */ + fun setThreeFingersScrollEnabled(enabled: Boolean) + /** * Controls whether fling events are allowed when the view is in an overscrolled state. * diff --git a/library/src/main/java/com/otaliastudios/zoom/ZoomEngine.kt b/library/src/main/java/com/otaliastudios/zoom/ZoomEngine.kt index 3d03f3b..b5fc5de 100644 --- a/library/src/main/java/com/otaliastudios/zoom/ZoomEngine.kt +++ b/library/src/main/java/com/otaliastudios/zoom/ZoomEngine.kt @@ -430,6 +430,42 @@ internal constructor(context: Context) : ZoomApi { scrollFlingDetector.flingEnabled = enabled } + /** + * Controls whether scroll gesture is enabled or not. + * + * @param enabled true enables scroll gesture, false disables it + */ + override fun setScrollEnabled(enabled: Boolean) { + scrollFlingDetector.scrollEnabled = enabled + } + + /** + * Controls whether one finger scroll gesture is enabled or not. + * + * @param enabled true enables one finger scroll gesture, false disables it + */ + override fun setOneFingerScrollEnabled(enabled: Boolean) { + scrollFlingDetector.oneFingerScrollEnabled = enabled + } + + /** + * Controls whether two fingers scroll gesture is enabled or not. + * + * @param enabled true enables two fingers scroll gesture, false disables it + */ + override fun setTwoFingersScrollEnabled(enabled: Boolean) { + scrollFlingDetector.twoFingersScrollEnabled = enabled + } + + /** + * Controls whether three fingers scroll gesture is enabled or not. + * + * @param enabled true enables three fingers scroll gesture, false disables it + */ + override fun setThreeFingersScrollEnabled(enabled: Boolean) { + scrollFlingDetector.threeFingersScrollEnabled = enabled + } + /** * Controls whether fling events are allowed when the view is in an overscrolled state. * diff --git a/library/src/main/java/com/otaliastudios/zoom/ZoomImageView.kt b/library/src/main/java/com/otaliastudios/zoom/ZoomImageView.kt index 74f2d8a..9a26156 100644 --- a/library/src/main/java/com/otaliastudios/zoom/ZoomImageView.kt +++ b/library/src/main/java/com/otaliastudios/zoom/ZoomImageView.kt @@ -42,6 +42,10 @@ open class ZoomImageView private constructor( val overPinchable = a.getBoolean(R.styleable.ZoomEngine_overPinchable, true) val zoomEnabled = a.getBoolean(R.styleable.ZoomEngine_zoomEnabled, true) val flingEnabled = a.getBoolean(R.styleable.ZoomEngine_flingEnabled, true) + val scrollEnabled = a.getBoolean(R.styleable.ZoomEngine_scrollEnabled, true) + val oneFingerScrollEnabled = a.getBoolean(R.styleable.ZoomEngine_oneFingerScrollEnabled, true) + val twoFingersScrollEnabled = a.getBoolean(R.styleable.ZoomEngine_twoFingersScrollEnabled, true) + val threeFingersScrollEnabled = a.getBoolean(R.styleable.ZoomEngine_threeFingersScrollEnabled, true) val allowFlingInOverscroll = a.getBoolean(R.styleable.ZoomEngine_allowFlingInOverscroll, true) val minZoom = a.getFloat(R.styleable.ZoomEngine_minZoom, ZoomApi.MIN_ZOOM_DEFAULT) val maxZoom = a.getFloat(R.styleable.ZoomEngine_maxZoom, ZoomApi.MAX_ZOOM_DEFAULT) @@ -72,6 +76,10 @@ open class ZoomImageView private constructor( setOverPinchable(overPinchable) setZoomEnabled(zoomEnabled) setFlingEnabled(flingEnabled) + setScrollEnabled(scrollEnabled) + setOneFingerScrollEnabled(oneFingerScrollEnabled) + setTwoFingersScrollEnabled(twoFingersScrollEnabled) + setThreeFingersScrollEnabled(threeFingersScrollEnabled) setAllowFlingInOverscroll(allowFlingInOverscroll) setAnimationDuration(animationDuration) setMinZoom(minZoom, minZoomMode) diff --git a/library/src/main/java/com/otaliastudios/zoom/ZoomLayout.kt b/library/src/main/java/com/otaliastudios/zoom/ZoomLayout.kt index b3dae23..acb56c2 100644 --- a/library/src/main/java/com/otaliastudios/zoom/ZoomLayout.kt +++ b/library/src/main/java/com/otaliastudios/zoom/ZoomLayout.kt @@ -47,6 +47,10 @@ open class ZoomLayout private constructor( val overPinchable = a.getBoolean(R.styleable.ZoomEngine_overPinchable, true) val zoomEnabled = a.getBoolean(R.styleable.ZoomEngine_zoomEnabled, true) val flingEnabled = a.getBoolean(R.styleable.ZoomEngine_flingEnabled, true) + val scrollEnabled = a.getBoolean(R.styleable.ZoomEngine_scrollEnabled, true) + val oneFingerScrollEnabled = a.getBoolean(R.styleable.ZoomEngine_oneFingerScrollEnabled, true) + val twoFingersScrollEnabled = a.getBoolean(R.styleable.ZoomEngine_twoFingersScrollEnabled, true) + val threeFingersScrollEnabled = a.getBoolean(R.styleable.ZoomEngine_threeFingersScrollEnabled, true) val allowFlingInOverscroll = a.getBoolean(R.styleable.ZoomEngine_allowFlingInOverscroll, true) val hasChildren = a.getBoolean(R.styleable.ZoomEngine_hasClickableChildren, false) val minZoom = a.getFloat(R.styleable.ZoomEngine_minZoom, ZoomApi.MIN_ZOOM_DEFAULT) @@ -73,6 +77,10 @@ open class ZoomLayout private constructor( setOverPinchable(overPinchable) setZoomEnabled(zoomEnabled) setFlingEnabled(flingEnabled) + setScrollEnabled(scrollEnabled) + setOneFingerScrollEnabled(oneFingerScrollEnabled) + setTwoFingersScrollEnabled(twoFingersScrollEnabled) + setThreeFingersScrollEnabled(threeFingersScrollEnabled) setAllowFlingInOverscroll(allowFlingInOverscroll) setAnimationDuration(animationDuration) setMinZoom(minZoom, minZoomMode) diff --git a/library/src/main/java/com/otaliastudios/zoom/ZoomSurfaceView.kt b/library/src/main/java/com/otaliastudios/zoom/ZoomSurfaceView.kt index 8b5883f..a399534 100644 --- a/library/src/main/java/com/otaliastudios/zoom/ZoomSurfaceView.kt +++ b/library/src/main/java/com/otaliastudios/zoom/ZoomSurfaceView.kt @@ -152,6 +152,10 @@ open class ZoomSurfaceView private constructor( val overPinchable = a.getBoolean(R.styleable.ZoomEngine_overPinchable, false) val zoomEnabled = a.getBoolean(R.styleable.ZoomEngine_zoomEnabled, true) val flingEnabled = a.getBoolean(R.styleable.ZoomEngine_flingEnabled, true) + val scrollEnabled = a.getBoolean(R.styleable.ZoomEngine_scrollEnabled, true) + val oneFingerScrollEnabled = a.getBoolean(R.styleable.ZoomEngine_oneFingerScrollEnabled, true) + val twoFingersScrollEnabled = a.getBoolean(R.styleable.ZoomEngine_twoFingersScrollEnabled, true) + val threeFingersScrollEnabled = a.getBoolean(R.styleable.ZoomEngine_threeFingersScrollEnabled, true) val allowFlingInOverscroll = a.getBoolean(R.styleable.ZoomEngine_allowFlingInOverscroll, true) val minZoom = a.getFloat(R.styleable.ZoomEngine_minZoom, 1F) val maxZoom = a.getFloat(R.styleable.ZoomEngine_maxZoom, ZoomApi.MAX_ZOOM_DEFAULT) @@ -180,6 +184,10 @@ open class ZoomSurfaceView private constructor( setOverPinchable(overPinchable) setZoomEnabled(zoomEnabled) setFlingEnabled(flingEnabled) + setScrollEnabled(scrollEnabled) + setOneFingerScrollEnabled(oneFingerScrollEnabled) + setTwoFingersScrollEnabled(twoFingersScrollEnabled) + setThreeFingersScrollEnabled(threeFingersScrollEnabled) setAllowFlingInOverscroll(allowFlingInOverscroll) setAnimationDuration(animationDuration) setMinZoom(minZoom, minZoomMode) diff --git a/library/src/main/java/com/otaliastudios/zoom/internal/gestures/ScrollFlingDetector.kt b/library/src/main/java/com/otaliastudios/zoom/internal/gestures/ScrollFlingDetector.kt index b841ccb..ea72e14 100644 --- a/library/src/main/java/com/otaliastudios/zoom/internal/gestures/ScrollFlingDetector.kt +++ b/library/src/main/java/com/otaliastudios/zoom/internal/gestures/ScrollFlingDetector.kt @@ -37,6 +37,10 @@ internal class ScrollFlingDetector( private val panStatusY = PanManager.Status() internal var flingEnabled = true + internal var scrollEnabled = true + internal var oneFingerScrollEnabled = true + internal var twoFingersScrollEnabled = true + internal var threeFingersScrollEnabled = true internal var flingInOverPanEnabled = false /** @@ -144,6 +148,15 @@ internal class ScrollFlingDetector( @ZoomApi.ScaledPan distanceX: Float, @ZoomApi.ScaledPan distanceY: Float ): Boolean { + if (!scrollEnabled) return false + + val isOneFinger = e2?.pointerCount == 1 + val isTwoFingers = e2?.pointerCount == 2 + val isThreeFingers = e2?.pointerCount == 3 + + if (!oneFingerScrollEnabled && isOneFinger) return false + if (!twoFingersScrollEnabled && isTwoFingers) return false + if (!threeFingersScrollEnabled && isThreeFingers) return false if (!panManager.isEnabled) return false if (!stateController.setScrolling()) return false diff --git a/library/src/main/res/values/attrs.xml b/library/src/main/res/values/attrs.xml index b9fbb4a..30035b7 100644 --- a/library/src/main/res/values/attrs.xml +++ b/library/src/main/res/values/attrs.xml @@ -9,6 +9,10 @@ + + + +