Skip to content

Commit

Permalink
Show file tree
Hide file tree
Showing 12 changed files with 250 additions and 139 deletions.
4 changes: 2 additions & 2 deletions app/src/main/java/com/osfans/trime/data/theme/ColorManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ object ColorManager {
key: String,
border: Int = 0,
borderColorKey: String = "",
roundCorner: Int = 0,
roundCorner: Float = 0f,
alpha: Int = 255,
): Drawable? {
val value = getColorValue(key)
Expand All @@ -363,7 +363,7 @@ object ColorManager {
if (value is Int) {
val gradient = GradientDrawable().apply { setColor(value) }
if (roundCorner > 0) {
gradient.cornerRadius = roundCorner.toFloat()
gradient.cornerRadius = roundCorner
}
if (borderColorKey.isNotEmpty() && border > 0) {
val borderPx = context.dp(border)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class GeneralStyleMapper(
val backgroundDimAmount = getFloat("background_dim_amount")

val candidateBorder = getInt("candidate_border")
val candidateBorderRound = getInt("candidate_border_round")
val candidateBorderRound = getFloat("candidate_border_round")

val candidateFont = getStringList("candidate_font")

Expand Down Expand Up @@ -123,13 +123,13 @@ class GeneralStyleMapper(

val previewOffset = getInt("preview_offset")

val previewTextSize = getInt("preview_text_size")
val previewTextSize = getFloat("preview_text_size")

val proximityCorrection = getBoolean("proximity_correction")

val resetASCIIMode = getBoolean("reset_ascii_mode")

val roundCorner = getInt("round_corner")
val roundCorner = getFloat("round_corner")

val shadowRadius = getFloat("shadow_radius")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class LayoutStyleMapper(

val spacing = getInt("spacing")

val roundCorner = getInt("round_corner")
val roundCorner = getFloat("round_corner")

val alpha = getInt("alpha")
val elevation = getInt("elevation")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ data class GeneralStyle(
val autoCaps: String,
val backgroundDimAmount: Float,
val candidateBorder: Int,
val candidateBorderRound: Int,
val candidateBorderRound: Float,
val candidateFont: List<String>,
val candidatePadding: Int,
val candidateSpacing: Float,
Expand Down Expand Up @@ -60,10 +60,10 @@ data class GeneralStyle(
val previewFont: List<String>,
val previewHeight: Int,
val previewOffset: Int,
val previewTextSize: Int,
val previewTextSize: Float,
val proximityCorrection: Boolean,
val resetASCIIMode: Boolean,
val roundCorner: Int,
val roundCorner: Float,
val shadowRadius: Float,
val speechOpenccConfig: String,
val symbolFont: List<String>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ data class Layout(
val lineSpacingMultiplier: Float,
val realMargin: Int,
val spacing: Int,
val roundCorner: Int,
val roundCorner: Float,
val alpha: Int,
val elevation: Int,
val movable: String,
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/java/com/osfans/trime/ime/core/InputView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import com.osfans.trime.ime.dependency.InputComponent
import com.osfans.trime.ime.dependency.create
import com.osfans.trime.ime.keyboard.KeyboardPrefs.isLandscapeMode
import com.osfans.trime.ime.keyboard.KeyboardWindow
import com.osfans.trime.ime.preview.KeyPreviewChoreographer
import com.osfans.trime.ime.symbol.LiquidKeyboard
import com.osfans.trime.util.ColorUtils
import com.osfans.trime.util.styledFloat
Expand Down Expand Up @@ -109,6 +110,7 @@ class InputView(
private val keyboardWindow: KeyboardWindow = inputComponent.keyboardWindow
private val liquidKeyboard: LiquidKeyboard = inputComponent.liquidKeyboard
private val compactCandidate: CompactCandidateModule = inputComponent.compactCandidate
private val preview: KeyPreviewChoreographer = inputComponent.preview

private fun addBroadcastReceivers() {
broadcaster.addReceiver(quickBar)
Expand Down Expand Up @@ -263,6 +265,13 @@ class InputView(
bottomOfParent()
},
)

add(
preview.root,
lParams(matchParent, matchParent) {
centerInParent()
},
)
}

private fun updateKeyboardSize() {
Expand Down Expand Up @@ -409,6 +418,7 @@ class InputView(
// implies that InputView should not be attached again after detached.
callbackHandlerJob.cancel()
updateWindowViewHeightJob.cancel()
preview.root.removeAllViews()
broadcaster.clear()
super.onDetachedFromWindow()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import com.osfans.trime.ime.core.InputView
import com.osfans.trime.ime.core.TrimeInputMethodService
import com.osfans.trime.ime.keyboard.CommonKeyboardActionListener
import com.osfans.trime.ime.keyboard.KeyboardWindow
import com.osfans.trime.ime.preview.KeyPreviewChoreographer
import com.osfans.trime.ime.symbol.LiquidKeyboard
import com.osfans.trime.ime.window.BoardWindowManager
import me.tatarka.inject.annotations.Component
Expand All @@ -36,6 +37,7 @@ abstract class InputComponent(
abstract val quickBar: QuickBar
abstract val composition: CompositionPopupWindow
abstract val windowManager: BoardWindowManager
abstract val preview: KeyPreviewChoreographer
abstract val keyboardWindow: KeyboardWindow
abstract val liquidKeyboard: LiquidKeyboard
abstract val compactCandidate: CompactCandidateModule
Expand Down
157 changes: 29 additions & 128 deletions app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,18 @@ import android.graphics.drawable.StateListDrawable
import android.os.Message
import android.view.GestureDetector
import android.view.GestureDetector.SimpleOnGestureListener
import android.view.Gravity
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.PopupWindow
import androidx.core.view.updateLayoutParams
import com.osfans.trime.core.Rime
import com.osfans.trime.data.prefs.AppPrefs
import com.osfans.trime.data.theme.ColorManager
import com.osfans.trime.data.theme.FontManager
import com.osfans.trime.data.theme.Theme
import com.osfans.trime.ime.preview.KeyPreviewChoreographer
import com.osfans.trime.util.LeakGuardHandlerWrapper
import com.osfans.trime.util.indexOfStateSet
import com.osfans.trime.util.sp
import com.osfans.trime.util.stateDrawableAt
import splitties.dimensions.dp
import splitties.views.dsl.core.textView
import splitties.views.dsl.core.wrapContent
import splitties.views.gravityBottomCenter
import timber.log.Timber
import java.util.Arrays
import kotlin.math.abs
Expand All @@ -51,6 +44,7 @@ class KeyboardView(
context: Context,
private val theme: Theme,
private val keyboard: Keyboard,
private val keyPreviewChoreographer: KeyPreviewChoreographer,
) : View(context) {
private var mCurrentKeyIndex = NOT_A_KEY
private val keyTextSize = theme.generalStyle.keyTextSize
Expand Down Expand Up @@ -85,32 +79,8 @@ class KeyboardView(
private val mShadowRadius = theme.generalStyle.shadowRadius
private val mShadowColor = ColorManager.getColor("shadow_color")!!

private val mPreviewText =
textView {
textSize = theme.generalStyle.previewTextSize.toFloat()
typeface = FontManager.getTypeface("preview_font")
ColorManager.getColor("preview_text_color")?.let { setTextColor(it) }
ColorManager.getColor("preview_back_color")?.let {
background =
GradientDrawable().apply {
setColor(it)
cornerRadius = theme.generalStyle.roundCorner.toFloat()
}
}
gravity = gravityBottomCenter
layoutParams = ViewGroup.LayoutParams(wrapContent, wrapContent)
}
private val mPreviewPopup =
PopupWindow(context).apply {
contentView = mPreviewText
isTouchable = false
}
private val mPreviewOffset = theme.generalStyle.previewOffset
private val mPreviewHeight = theme.generalStyle.previewHeight

// Working variable
private val mCoordinates = IntArray(2)
private var mPopupParent: View = this
private val originCoords = intArrayOf(0, 0)
private val mKeys get() = keyboard.keys

var keyboardActionListener: KeyboardActionListener? = null
Expand Down Expand Up @@ -199,8 +169,7 @@ class KeyboardView(
val mKeyboardView = getOwnerInstanceOrNull() ?: return
val repeatInterval by AppPrefs.defaultInstance().keyboard.repeatInterval
when (msg.what) {
MSG_SHOW_PREVIEW -> mKeyboardView.showKey(msg.arg1, KeyBehavior.entries[msg.arg2])
MSG_REMOVE_PREVIEW -> mKeyboardView.mPreviewPopup.dismiss()
MSG_REMOVE_PREVIEW -> mKeyboardView.dismissKeyPreviewWithoutDelay(msg.obj as Key)
MSG_REPEAT ->
if (mKeyboardView.repeatKey()) {
val repeat = Message.obtain(this, MSG_REPEAT)
Expand All @@ -216,7 +185,6 @@ class KeyboardView(
}

init {
setKeyboardBackground()
computeProximityThreshold(keyboard)
invalidateAllKeys()
}
Expand Down Expand Up @@ -356,12 +324,28 @@ class KeyboardView(
},
).apply { setIsLongpressEnabled(false) }

private fun setKeyboardBackground() {
val d = mPreviewText.background
if (d is GradientDrawable) {
d.cornerRadius = keyboard.roundCorner
mPreviewText.background = d
private fun showKeyPreview(
key: Key,
behavior: KeyBehavior,
) {
getLocationInWindow(originCoords)
keyPreviewChoreographer.placeAndShowKeyPreview(key, key.getPreviewText(behavior), width, originCoords)
}

private fun dismissKeyPreviewWithoutDelay(key: Key) {
keyPreviewChoreographer.dismissKeyPreview(key)
invalidateKey(key)
}

private fun dismissKeyPreview(key: Key) {
if (isHardwareAccelerated) {
keyPreviewChoreographer.dismissKeyPreview(key)
return
}
mHandler.sendMessageDelayed(
mHandler.obtainMessage(MSG_REMOVE_PREVIEW, key),
DELAY_AFTER_PREVIEW,
)
}

/**
Expand Down Expand Up @@ -714,7 +698,6 @@ class KeyboardView(
behavior: KeyBehavior = KeyBehavior.COMPOSING,
) {
val oldKeyIndex = mCurrentKeyIndex
val previewPopup = mPreviewPopup
mCurrentKeyIndex = keyIndex
// Release the old key and press the new key
val keys = mKeys
Expand All @@ -732,88 +715,12 @@ class KeyboardView(
}
// If key changed and preview is on ...
if (oldKeyIndex != mCurrentKeyIndex && showPreview) {
mHandler.removeMessages(MSG_SHOW_PREVIEW)
if (previewPopup.isShowing) {
if (keyIndex == NOT_A_KEY) {
mHandler.sendMessageDelayed(
mHandler.obtainMessage(MSG_REMOVE_PREVIEW),
DELAY_AFTER_PREVIEW.toLong(),
)
}
}
if (keyIndex != -1) {
if (previewPopup.isShowing && mPreviewText.visibility == VISIBLE) {
// Show right away, if it's already visible and finger is moving around
showKey(keyIndex, behavior)
} else {
mHandler.sendMessageDelayed(
mHandler.obtainMessage(MSG_SHOW_PREVIEW, keyIndex, behavior.ordinal),
DELAY_BEFORE_PREVIEW.toLong(),
)
}
}
}
}

private fun showKey(
index: Int,
behavior: KeyBehavior,
) {
val previewPopup = mPreviewPopup
if (index !in mKeys.indices) return
val key = mKeys[index]
mPreviewText.setCompoundDrawables(null, null, null, null)
mPreviewText.text = key.getPreviewText(behavior)
mPreviewText.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
val popupWidth =
max(
mPreviewText.measuredWidth,
key.width + mPreviewText.paddingLeft + mPreviewText.paddingRight,
)
val popupHeight = dp(mPreviewHeight)
mPreviewText.updateLayoutParams {
width = popupWidth
height = popupHeight
}
var mPopupPreviewY: Int
var mPopupPreviewX: Int
val mPreviewCentered = false
if (!mPreviewCentered) {
mPopupPreviewX = key.x - mPreviewText.paddingLeft + paddingLeft
mPopupPreviewY = key.y - popupHeight + dp(mPreviewOffset)
} else {
// TODO: Fix this if centering is brought back
mPopupPreviewX = 160 - mPreviewText.measuredWidth / 2
mPopupPreviewY = -mPreviewText.measuredHeight
}
mHandler.removeMessages(MSG_REMOVE_PREVIEW)
getLocationInWindow(mCoordinates)

// Set the preview background state
mPreviewText.background.setState(EMPTY_STATE_SET)
mPopupPreviewX += mCoordinates[0]
mPopupPreviewY += mCoordinates[1]

// If the popup cannot be shown above the key, put it on the side
getLocationOnScreen(mCoordinates)
if (mPopupPreviewY + mCoordinates[1] < 0) {
// If the key you're pressing is on the left side of the keyboard, show the popup on
// the right, offset by enough to see at least one key to the left/right.
if (key.x + key.width <= width / 2) {
mPopupPreviewX += (key.width * 2.5).toInt()
if (keyIndex == NOT_A_KEY) {
dismissKeyPreview(keys[oldKeyIndex])
} else {
mPopupPreviewX -= (key.width * 2.5).toInt()
showKeyPreview(keys[keyIndex], behavior)
}
mPopupPreviewY += popupHeight
}
if (previewPopup.isShowing) {
// previewPopup.update(mPopupPreviewX, mPopupPreviewY, popupWidth, popupHeight);
previewPopup.dismiss() // 禁止窗口動畫
}
previewPopup.width = popupWidth
previewPopup.height = popupHeight
previewPopup.showAtLocation(mPopupParent, Gravity.NO_GRAVITY, mPopupPreviewX, mPopupPreviewY)
mPreviewText.visibility = VISIBLE
}

/**
Expand Down Expand Up @@ -1157,13 +1064,9 @@ class KeyboardView(
private fun removeMessages() {
mHandler.removeMessages(MSG_REPEAT)
mHandler.removeMessages(MSG_LONGPRESS)
mHandler.removeMessages(MSG_SHOW_PREVIEW)
}

fun onDetach() {
if (mPreviewPopup.isShowing) {
mPreviewPopup.dismiss()
}
removeMessages()
freeDrawingBuffer()
}
Expand Down Expand Up @@ -1192,12 +1095,10 @@ class KeyboardView(

companion object {
private const val NOT_A_KEY = -1
private const val MSG_SHOW_PREVIEW = 1
private const val MSG_REMOVE_PREVIEW = 2
private const val MSG_REPEAT = 3
private const val MSG_LONGPRESS = 4
private const val DELAY_BEFORE_PREVIEW = 0
private const val DELAY_AFTER_PREVIEW = 70
private const val DELAY_AFTER_PREVIEW = 100L
private const val DEBOUNCE_TIME = 70
private const val MAX_NEARBY_KEYS = 12
}
Expand Down
Loading

0 comments on commit 2c84113

Please sign in to comment.