[go: nahoru, domu]

blob: 277aa36c5e4a52f2e274392deeb874a2208d477c [file] [log] [blame]
/*
* Copyright 2019 The Android Open Source Project
*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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 androidx.ui.core.gesture
import androidx.compose.Composable
import androidx.compose.memo
import androidx.compose.unaryPlus
import androidx.ui.core.Direction
import androidx.ui.core.PxPosition
// TODO(shepshapard): Convert to functional component with effects once effects are ready.
/**
* This gesture detector detects dragging in any direction.
*
* Dragging begins when the touch slop distance (currently defined by [TouchSlop]) is
* surpassed in a supported direction (see [DragObserver.onDrag]). When dragging begins,
* [DragObserver.onStart] is called, followed immediately by a call to [DragObserver.onDrag].
* [DragObserver.onDrag] is then continuously called whenever pointers have moved.
* [DragObserver.onDrag] is called when the dragging ends due to all of the pointers no longer
* interacting with the DragGestureDetector (for example, the last finger has been lifted off
* of the DragGestureDetector).
*
* When multiple pointers are touching the detector, the drag distance is taken as the average of
* all of the pointers.
*
* @param canDrag Set to limit the directions under which touch slop can be exceeded. Return true
* if you want a drag to be started due to the touch slop being surpassed in the given [Direction].
* If [canDrag] is not provided, touch slop will be able to be exceeded in all directions.
* @param dragObserver The callback interface to report all events related to dragging.
*/
@Composable
fun TouchSlopDragGestureDetector(
dragObserver: DragObserver,
canDrag: ((Direction) -> Boolean)? = null,
children: @Composable() () -> Unit
) {
val glue = +memo { TouchSlopDragGestureDetectorGlue() }
glue.touchSlopDragObserver = dragObserver
RawDragGestureDetector(glue.rawDragObserver, glue::dragEnabled) {
TouchSlopExceededGestureDetector(glue::enableDrag, canDrag, children)
}
}
/**
* Glues together the logic of RawDragGestureDetector and TouchSlopExceededGestureDetector.
*/
private class TouchSlopDragGestureDetectorGlue {
lateinit var touchSlopDragObserver: DragObserver
var dragEnabled = false
fun enableDrag() {
dragEnabled = true
}
val rawDragObserver: DragObserver =
object : DragObserver {
override fun onStart(downPosition: PxPosition) {
touchSlopDragObserver.onStart(downPosition)
}
override fun onDrag(dragDistance: PxPosition): PxPosition {
return touchSlopDragObserver.onDrag(dragDistance)
}
override fun onStop(velocity: PxPosition) {
touchSlopDragObserver.onStop(velocity)
dragEnabled = false
}
}
}