[go: nahoru, domu]

blob: 24b0fd5b31752467ceb44fcaa39eade4fe22f186 [file] [log] [blame]
/*
* Copyright 2020 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.node
import android.os.SystemClock
import android.view.InputDevice
import android.view.MotionEvent
import android.view.MotionEvent.ACTION_CANCEL
import androidx.ui.core.PointerEvent
import androidx.compose.ui.geometry.Offset
import androidx.ui.unit.Duration
import androidx.ui.unit.NanosecondsPerMillisecond
import androidx.ui.unit.milliseconds
/**
* Converts to a [MotionEvent] and runs [block] with it.
*
* @param offset The offset to be applied to the resulting [MotionEvent].
* @param block The block to be executed with the resulting [MotionEvent].
*/
internal fun PointerEvent.toMotionEventScope(
offset: Offset,
block: (MotionEvent) -> Unit
) {
toMotionEventScope(offset, block, false)
}
/**
* Converts to an [MotionEvent.ACTION_CANCEL] [MotionEvent] and runs [block] with it.
*
* @param offset The offset to be applied to the resulting [MotionEvent].
* @param block The block to be executed with the resulting [MotionEvent].
*/
internal fun PointerEvent.toCancelMotionEventScope(
offset: Offset,
block: (MotionEvent) -> Unit
) {
toMotionEventScope(offset, block, true)
}
internal fun emptyCancelMotionEventScope(
now: Duration = SystemClock.uptimeMillis().milliseconds,
block: (MotionEvent) -> Unit
) {
// Does what ViewGroup does when it needs to send a minimal ACTION_CANCEL event.
val nowMillis = now.nanoseconds / NanosecondsPerMillisecond
val motionEvent =
MotionEvent.obtain(nowMillis, nowMillis, ACTION_CANCEL, 0.0f, 0.0f, 0)
motionEvent.source = InputDevice.SOURCE_UNKNOWN
block(motionEvent)
motionEvent.recycle()
}
private fun PointerEvent.toMotionEventScope(
offset: Offset,
block: (MotionEvent) -> Unit,
cancel: Boolean
) {
requireNotNull(motionEvent) {
"The PointerEvent receiver cannot have a null MotionEvent."
}
motionEvent.apply {
val oldAction = action
if (cancel) {
action = ACTION_CANCEL
}
offsetLocation(-offset.x, -offset.y)
block(this)
offsetLocation(offset.x, offset.y)
action = oldAction
}
}