Merge "Long-press not required for mouse or stylus." into tm-qpr-dev
This commit is contained in:
@@ -381,6 +381,13 @@ object KeyguardBottomAreaViewBinder {
|
|||||||
return when (event?.actionMasked) {
|
return when (event?.actionMasked) {
|
||||||
MotionEvent.ACTION_DOWN ->
|
MotionEvent.ACTION_DOWN ->
|
||||||
if (viewModel.configKey != null) {
|
if (viewModel.configKey != null) {
|
||||||
|
if (isUsingAccurateTool(event)) {
|
||||||
|
// For accurate tool types (stylus, mouse, etc.), we don't require a
|
||||||
|
// long-press.
|
||||||
|
} else {
|
||||||
|
// When not using a stylus, we require a long-press to activate the
|
||||||
|
// quick affordance, mostly to do "falsing" (e.g. protect from false
|
||||||
|
// clicks in the pocket/bag).
|
||||||
longPressAnimator =
|
longPressAnimator =
|
||||||
view
|
view
|
||||||
.animate()
|
.animate()
|
||||||
@@ -388,43 +395,40 @@ object KeyguardBottomAreaViewBinder {
|
|||||||
.scaleY(PRESSED_SCALE)
|
.scaleY(PRESSED_SCALE)
|
||||||
.setDuration(longPressDurationMs)
|
.setDuration(longPressDurationMs)
|
||||||
.withEndAction {
|
.withEndAction {
|
||||||
view.setOnClickListener {
|
dispatchClick(viewModel.configKey)
|
||||||
vibratorHelper?.vibrate(
|
|
||||||
if (viewModel.isActivated) {
|
|
||||||
Vibrations.Activated
|
|
||||||
} else {
|
|
||||||
Vibrations.Deactivated
|
|
||||||
}
|
|
||||||
)
|
|
||||||
viewModel.onClicked(
|
|
||||||
KeyguardQuickAffordanceViewModel.OnClickedParameters(
|
|
||||||
configKey = viewModel.configKey,
|
|
||||||
expandable = Expandable.fromView(view),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
view.performClick()
|
|
||||||
view.setOnClickListener(null)
|
|
||||||
cancel()
|
cancel()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
MotionEvent.ACTION_MOVE -> {
|
MotionEvent.ACTION_MOVE -> {
|
||||||
if (event.historySize > 0) {
|
if (!isUsingAccurateTool(event)) {
|
||||||
val distance =
|
// Moving too far while performing a long-press gesture cancels that
|
||||||
sqrt(
|
// gesture.
|
||||||
(event.y - event.getHistoricalY(0)).pow(2) +
|
val distanceMoved = distanceMoved(event)
|
||||||
(event.x - event.getHistoricalX(0)).pow(2)
|
if (distanceMoved > ViewConfiguration.getTouchSlop()) {
|
||||||
)
|
|
||||||
if (distance > ViewConfiguration.getTouchSlop()) {
|
|
||||||
cancel()
|
cancel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
MotionEvent.ACTION_UP -> {
|
MotionEvent.ACTION_UP -> {
|
||||||
|
if (isUsingAccurateTool(event)) {
|
||||||
|
// When using an accurate tool type (stylus, mouse, etc.), we don't require
|
||||||
|
// a long-press gesture to activate the quick affordance. Therefore, lifting
|
||||||
|
// the pointer performs a click.
|
||||||
|
if (
|
||||||
|
viewModel.configKey != null &&
|
||||||
|
distanceMoved(event) <= ViewConfiguration.getTouchSlop()
|
||||||
|
) {
|
||||||
|
dispatchClick(viewModel.configKey)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// When not using a stylus, lifting the finger/pointer will actually cancel
|
||||||
|
// the long-press gesture. Calling cancel after the quick affordance was
|
||||||
|
// already long-press activated is a no-op, so it's safe to call from here.
|
||||||
cancel(
|
cancel(
|
||||||
onAnimationEnd =
|
onAnimationEnd =
|
||||||
if (event.eventTime - event.downTime < longPressDurationMs) {
|
if (event.eventTime - event.downTime < longPressDurationMs) {
|
||||||
@@ -457,6 +461,7 @@ object KeyguardBottomAreaViewBinder {
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
MotionEvent.ACTION_CANCEL -> {
|
MotionEvent.ACTION_CANCEL -> {
|
||||||
@@ -467,6 +472,28 @@ object KeyguardBottomAreaViewBinder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun dispatchClick(
|
||||||
|
configKey: String,
|
||||||
|
) {
|
||||||
|
view.setOnClickListener {
|
||||||
|
vibratorHelper?.vibrate(
|
||||||
|
if (viewModel.isActivated) {
|
||||||
|
Vibrations.Activated
|
||||||
|
} else {
|
||||||
|
Vibrations.Deactivated
|
||||||
|
}
|
||||||
|
)
|
||||||
|
viewModel.onClicked(
|
||||||
|
KeyguardQuickAffordanceViewModel.OnClickedParameters(
|
||||||
|
configKey = configKey,
|
||||||
|
expandable = Expandable.fromView(view),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
view.performClick()
|
||||||
|
view.setOnClickListener(null)
|
||||||
|
}
|
||||||
|
|
||||||
private fun cancel(onAnimationEnd: Runnable? = null) {
|
private fun cancel(onAnimationEnd: Runnable? = null) {
|
||||||
longPressAnimator?.cancel()
|
longPressAnimator?.cancel()
|
||||||
longPressAnimator = null
|
longPressAnimator = null
|
||||||
@@ -475,6 +502,40 @@ object KeyguardBottomAreaViewBinder {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val PRESSED_SCALE = 1.5f
|
private const val PRESSED_SCALE = 1.5f
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns `true` if the tool type at the given pointer index is an accurate tool (like
|
||||||
|
* stylus or mouse), which means we can trust it to not be a false click; `false`
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
private fun isUsingAccurateTool(
|
||||||
|
event: MotionEvent,
|
||||||
|
pointerIndex: Int = 0,
|
||||||
|
): Boolean {
|
||||||
|
return when (event.getToolType(pointerIndex)) {
|
||||||
|
MotionEvent.TOOL_TYPE_STYLUS -> true
|
||||||
|
MotionEvent.TOOL_TYPE_MOUSE -> true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the amount of distance the pointer moved since the historical record at the
|
||||||
|
* [since] index.
|
||||||
|
*/
|
||||||
|
private fun distanceMoved(
|
||||||
|
event: MotionEvent,
|
||||||
|
since: Int = 0,
|
||||||
|
): Float {
|
||||||
|
return if (event.historySize > 0) {
|
||||||
|
sqrt(
|
||||||
|
(event.y - event.getHistoricalY(since)).pow(2) +
|
||||||
|
(event.x - event.getHistoricalX(since)).pow(2)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
0f
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user