mirror of
https://github.com/fcitx5-android/fcitx5-android.git
synced 2026-08-02 20:16:06 +08:00
Only rotate the icon in ToolButton
Gesture directions are no longer confusing
This commit is contained in:
parent
6628588284
commit
f784f5d61b
@ -47,6 +47,7 @@ import org.fcitx.fcitx5.android.input.bar.KawaiiBarStateMachine.TransitionEvent.
|
||||
import org.fcitx.fcitx5.android.input.bar.ui.CandidateUi
|
||||
import org.fcitx.fcitx5.android.input.bar.ui.IdleUi
|
||||
import org.fcitx.fcitx5.android.input.bar.ui.TitleUi
|
||||
import org.fcitx.fcitx5.android.input.bar.ui.ToolButton
|
||||
import org.fcitx.fcitx5.android.input.broadcast.InputBroadcastReceiver
|
||||
import org.fcitx.fcitx5.android.input.candidates.expanded.ExpandedCandidateStyle
|
||||
import org.fcitx.fcitx5.android.input.candidates.expanded.window.FlexboxExpandedCandidateWindow
|
||||
@ -80,10 +81,8 @@ import kotlin.coroutines.resume
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.atan2
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.hypot
|
||||
import kotlin.math.min
|
||||
import kotlin.math.sin
|
||||
|
||||
class KawaiiBarComponent : UniqueViewComponent<KawaiiBarComponent, FrameLayout>(),
|
||||
InputBroadcastReceiver {
|
||||
@ -209,49 +208,40 @@ class KawaiiBarComponent : UniqueViewComponent<KawaiiBarComponent, FrameLayout>(
|
||||
// - If horizontal is dominant and left, show number row (when allowed).
|
||||
// - If vertical is dominant and down, hide keyboard.
|
||||
private val swipeHideKeyboardCallback = CustomGestureView.OnGestureListener { v, e ->
|
||||
require(v is ToolButton)
|
||||
val numberRowAvailable = isCapabilityFlagsPassword && !isKeyboardLayoutNumber
|
||||
if (numberRowAvailable) {
|
||||
val dir = if (context.resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_LTR) 1 else -1
|
||||
// We can't access the rawX and rawY of the MotionEvent, so we need to do some math.
|
||||
// `e.x` and `e.y` are relative to the view's top-left corner, we want to rotate
|
||||
// around the center of the view, so we translate them to be relative to the center
|
||||
val relX = e.x - v.width / 2f
|
||||
val relY = e.y - v.height / 2f
|
||||
// `e.x` and `e.y` are relative to the view's top-left corner
|
||||
val centerX = e.x - v.width / 2f
|
||||
val centerY = e.y - v.height / 2f
|
||||
|
||||
// rotate the relative coordinates by current rotation to get absolute coordinates
|
||||
val distance = hypot(centerX, centerY)
|
||||
// the button is ↓, so apply -90 degrees offset
|
||||
val theta = Math.toRadians(v.rotation.toDouble()) - PI / 2
|
||||
val c = cos(theta)
|
||||
val s = sin(theta)
|
||||
val screenX = c * relX - s * relY
|
||||
val screenY = s * relX + c * relY
|
||||
val distance = hypot(screenX, screenY)
|
||||
var angle = Math.toDegrees(atan2(screenY, screenX)).toFloat()
|
||||
var angle = atan2(-centerX, centerY) * (180f / PI.toFloat())
|
||||
|
||||
when (e.type) {
|
||||
CustomGestureView.GestureType.Move -> {
|
||||
angle = if (angle in -45f..45f) {
|
||||
angle.coerceIn(-10f, 10f)
|
||||
} else abs(angle).coerceIn(90f - 10f, 90f + 10f) * dir
|
||||
v.rotation = angle
|
||||
v.iconRotation = angle
|
||||
}
|
||||
CustomGestureView.GestureType.Up -> {
|
||||
val thresholdX = (v as CustomGestureView).swipeThresholdX
|
||||
val thresholdY = v.swipeThresholdY
|
||||
val handled = when (angle) {
|
||||
in -45f..45f if distance > thresholdY -> {
|
||||
in -45f..45f if distance > v.swipeThresholdX -> {
|
||||
service.requestHideSelf(0)
|
||||
true
|
||||
}
|
||||
!in -45f..45f if distance > thresholdX -> {
|
||||
v.rotation = 90f * dir
|
||||
!in -45f..45f if distance > v.swipeThresholdY -> {
|
||||
v.iconRotation = 90f * dir
|
||||
numberRowState = NumberRowState.ForceShow
|
||||
evalIdleUiState(fromUser = true)
|
||||
true
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
v.rotation = 0f
|
||||
v.iconRotation = 0f
|
||||
return@OnGestureListener handled
|
||||
}
|
||||
else -> {}
|
||||
|
||||
@ -72,7 +72,7 @@ class IdleUi(
|
||||
}
|
||||
|
||||
val menuButton = ToolButton(ctx, R.drawable.ic_baseline_expand_more_24, theme).apply {
|
||||
rotation = menuButtonRotation
|
||||
iconRotation = menuButtonRotation
|
||||
}
|
||||
|
||||
val hideKeyboardButton = ToolButton(ctx, R.drawable.ic_baseline_arrow_drop_down_24, theme)
|
||||
@ -161,12 +161,12 @@ class IdleUi(
|
||||
private fun updateMenuButtonRotation(instant: Boolean = false) {
|
||||
val targetRotation = menuButtonRotation
|
||||
menuButton.apply {
|
||||
if (targetRotation == rotation) return
|
||||
animate().cancel()
|
||||
if (targetRotation == iconRotation) return
|
||||
iconAnimate().cancel()
|
||||
if (!instant && !disableAnimation) {
|
||||
animate().setDuration(200L).rotation(targetRotation)
|
||||
iconAnimate().setDuration(200L).rotation(targetRotation)
|
||||
} else {
|
||||
rotation = targetRotation
|
||||
iconRotation = targetRotation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ package org.fcitx.fcitx5.android.input.bar.ui
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.view.ViewPropertyAnimator
|
||||
import android.widget.ImageView
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.annotation.DrawableRes
|
||||
@ -36,6 +37,12 @@ class ToolButton(context: Context) : CustomGestureView(context) {
|
||||
scaleType = ImageView.ScaleType.CENTER_INSIDE
|
||||
}
|
||||
|
||||
var iconRotation: Float
|
||||
get() = image.rotation
|
||||
set(value) {
|
||||
image.rotation = value
|
||||
}
|
||||
|
||||
constructor(context: Context, @DrawableRes icon: Int, theme: Theme) : this(context) {
|
||||
image.imageTintList = ColorStateList.valueOf(theme.altKeyTextColor)
|
||||
setIcon(icon)
|
||||
@ -43,6 +50,8 @@ class ToolButton(context: Context) : CustomGestureView(context) {
|
||||
add(image, lParams(wrapContent, wrapContent, gravityCenter))
|
||||
}
|
||||
|
||||
fun iconAnimate(): ViewPropertyAnimator = image.animate()
|
||||
|
||||
fun setIcon(@DrawableRes icon: Int) {
|
||||
image.imageResource = icon
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user