@@ -19,25 +19,18 @@ import android.graphics.drawable.StateListDrawable
19
19
import android.os.Message
20
20
import android.view.GestureDetector
21
21
import android.view.GestureDetector.SimpleOnGestureListener
22
- import android.view.Gravity
23
22
import android.view.MotionEvent
24
23
import android.view.View
25
- import android.view.ViewGroup
26
- import android.widget.PopupWindow
27
- import androidx.core.view.updateLayoutParams
28
24
import com.osfans.trime.core.Rime
29
25
import com.osfans.trime.data.prefs.AppPrefs
30
26
import com.osfans.trime.data.theme.ColorManager
31
27
import com.osfans.trime.data.theme.FontManager
32
28
import com.osfans.trime.data.theme.Theme
29
+ import com.osfans.trime.ime.preview.KeyPreviewChoreographer
33
30
import com.osfans.trime.util.LeakGuardHandlerWrapper
34
31
import com.osfans.trime.util.indexOfStateSet
35
32
import com.osfans.trime.util.sp
36
33
import com.osfans.trime.util.stateDrawableAt
37
- import splitties.dimensions.dp
38
- import splitties.views.dsl.core.textView
39
- import splitties.views.dsl.core.wrapContent
40
- import splitties.views.gravityBottomCenter
41
34
import timber.log.Timber
42
35
import java.util.Arrays
43
36
import kotlin.math.abs
@@ -51,6 +44,7 @@ class KeyboardView(
51
44
context : Context ,
52
45
private val theme : Theme ,
53
46
private val keyboard : Keyboard ,
47
+ private val keyPreviewChoreographer : KeyPreviewChoreographer ,
54
48
) : View(context) {
55
49
private var mCurrentKeyIndex = NOT_A_KEY
56
50
private val keyTextSize = theme.generalStyle.keyTextSize
@@ -85,32 +79,8 @@ class KeyboardView(
85
79
private val mShadowRadius = theme.generalStyle.shadowRadius
86
80
private val mShadowColor = ColorManager .getColor(" shadow_color" )!!
87
81
88
- private val mPreviewText =
89
- textView {
90
- textSize = theme.generalStyle.previewTextSize.toFloat()
91
- typeface = FontManager .getTypeface(" preview_font" )
92
- ColorManager .getColor(" preview_text_color" )?.let { setTextColor(it) }
93
- ColorManager .getColor(" preview_back_color" )?.let {
94
- background =
95
- GradientDrawable ().apply {
96
- setColor(it)
97
- cornerRadius = theme.generalStyle.roundCorner.toFloat()
98
- }
99
- }
100
- gravity = gravityBottomCenter
101
- layoutParams = ViewGroup .LayoutParams (wrapContent, wrapContent)
102
- }
103
- private val mPreviewPopup =
104
- PopupWindow (context).apply {
105
- contentView = mPreviewText
106
- isTouchable = false
107
- }
108
- private val mPreviewOffset = theme.generalStyle.previewOffset
109
- private val mPreviewHeight = theme.generalStyle.previewHeight
110
-
111
82
// Working variable
112
- private val mCoordinates = IntArray (2 )
113
- private var mPopupParent: View = this
83
+ private val originCoords = intArrayOf(0 , 0 )
114
84
private val mKeys get() = keyboard.keys
115
85
116
86
var keyboardActionListener: KeyboardActionListener ? = null
@@ -199,8 +169,7 @@ class KeyboardView(
199
169
val mKeyboardView = getOwnerInstanceOrNull() ? : return
200
170
val repeatInterval by AppPrefs .defaultInstance().keyboard.repeatInterval
201
171
when (msg.what) {
202
- MSG_SHOW_PREVIEW -> mKeyboardView.showKey(msg.arg1, KeyBehavior .entries[msg.arg2])
203
- MSG_REMOVE_PREVIEW -> mKeyboardView.mPreviewPopup.dismiss()
172
+ MSG_REMOVE_PREVIEW -> mKeyboardView.dismissKeyPreviewWithoutDelay(msg.obj as Key )
204
173
MSG_REPEAT ->
205
174
if (mKeyboardView.repeatKey()) {
206
175
val repeat = Message .obtain(this , MSG_REPEAT )
@@ -216,7 +185,6 @@ class KeyboardView(
216
185
}
217
186
218
187
init {
219
- setKeyboardBackground()
220
188
computeProximityThreshold(keyboard)
221
189
invalidateAllKeys()
222
190
}
@@ -356,12 +324,28 @@ class KeyboardView(
356
324
},
357
325
).apply { setIsLongpressEnabled(false ) }
358
326
359
- private fun setKeyboardBackground () {
360
- val d = mPreviewText.background
361
- if (d is GradientDrawable ) {
362
- d.cornerRadius = keyboard.roundCorner
363
- mPreviewText.background = d
327
+ private fun showKeyPreview (
328
+ key : Key ,
329
+ behavior : KeyBehavior ,
330
+ ) {
331
+ getLocationInWindow(originCoords)
332
+ keyPreviewChoreographer.placeAndShowKeyPreview(key, key.getPreviewText(behavior), width, originCoords)
333
+ }
334
+
335
+ private fun dismissKeyPreviewWithoutDelay (key : Key ) {
336
+ keyPreviewChoreographer.dismissKeyPreview(key)
337
+ invalidateKey(key)
338
+ }
339
+
340
+ private fun dismissKeyPreview (key : Key ) {
341
+ if (isHardwareAccelerated) {
342
+ keyPreviewChoreographer.dismissKeyPreview(key)
343
+ return
364
344
}
345
+ mHandler.sendMessageDelayed(
346
+ mHandler.obtainMessage(MSG_REMOVE_PREVIEW , key),
347
+ DELAY_AFTER_PREVIEW ,
348
+ )
365
349
}
366
350
367
351
/* *
@@ -714,7 +698,6 @@ class KeyboardView(
714
698
behavior : KeyBehavior = KeyBehavior .COMPOSING ,
715
699
) {
716
700
val oldKeyIndex = mCurrentKeyIndex
717
- val previewPopup = mPreviewPopup
718
701
mCurrentKeyIndex = keyIndex
719
702
// Release the old key and press the new key
720
703
val keys = mKeys
@@ -732,88 +715,12 @@ class KeyboardView(
732
715
}
733
716
// If key changed and preview is on ...
734
717
if (oldKeyIndex != mCurrentKeyIndex && showPreview) {
735
- mHandler.removeMessages(MSG_SHOW_PREVIEW )
736
- if (previewPopup.isShowing) {
737
- if (keyIndex == NOT_A_KEY ) {
738
- mHandler.sendMessageDelayed(
739
- mHandler.obtainMessage(MSG_REMOVE_PREVIEW ),
740
- DELAY_AFTER_PREVIEW .toLong(),
741
- )
742
- }
743
- }
744
- if (keyIndex != - 1 ) {
745
- if (previewPopup.isShowing && mPreviewText.visibility == VISIBLE ) {
746
- // Show right away, if it's already visible and finger is moving around
747
- showKey(keyIndex, behavior)
748
- } else {
749
- mHandler.sendMessageDelayed(
750
- mHandler.obtainMessage(MSG_SHOW_PREVIEW , keyIndex, behavior.ordinal),
751
- DELAY_BEFORE_PREVIEW .toLong(),
752
- )
753
- }
754
- }
755
- }
756
- }
757
-
758
- private fun showKey (
759
- index : Int ,
760
- behavior : KeyBehavior ,
761
- ) {
762
- val previewPopup = mPreviewPopup
763
- if (index !in mKeys.indices) return
764
- val key = mKeys[index]
765
- mPreviewText.setCompoundDrawables(null , null , null , null )
766
- mPreviewText.text = key.getPreviewText(behavior)
767
- mPreviewText.measure(MeasureSpec .UNSPECIFIED , MeasureSpec .UNSPECIFIED )
768
- val popupWidth =
769
- max(
770
- mPreviewText.measuredWidth,
771
- key.width + mPreviewText.paddingLeft + mPreviewText.paddingRight,
772
- )
773
- val popupHeight = dp(mPreviewHeight)
774
- mPreviewText.updateLayoutParams {
775
- width = popupWidth
776
- height = popupHeight
777
- }
778
- var mPopupPreviewY: Int
779
- var mPopupPreviewX: Int
780
- val mPreviewCentered = false
781
- if (! mPreviewCentered) {
782
- mPopupPreviewX = key.x - mPreviewText.paddingLeft + paddingLeft
783
- mPopupPreviewY = key.y - popupHeight + dp(mPreviewOffset)
784
- } else {
785
- // TODO: Fix this if centering is brought back
786
- mPopupPreviewX = 160 - mPreviewText.measuredWidth / 2
787
- mPopupPreviewY = - mPreviewText.measuredHeight
788
- }
789
- mHandler.removeMessages(MSG_REMOVE_PREVIEW )
790
- getLocationInWindow(mCoordinates)
791
-
792
- // Set the preview background state
793
- mPreviewText.background.setState(EMPTY_STATE_SET )
794
- mPopupPreviewX + = mCoordinates[0 ]
795
- mPopupPreviewY + = mCoordinates[1 ]
796
-
797
- // If the popup cannot be shown above the key, put it on the side
798
- getLocationOnScreen(mCoordinates)
799
- if (mPopupPreviewY + mCoordinates[1 ] < 0 ) {
800
- // If the key you're pressing is on the left side of the keyboard, show the popup on
801
- // the right, offset by enough to see at least one key to the left/right.
802
- if (key.x + key.width <= width / 2 ) {
803
- mPopupPreviewX + = (key.width * 2.5 ).toInt()
718
+ if (keyIndex == NOT_A_KEY ) {
719
+ dismissKeyPreview(keys[oldKeyIndex])
804
720
} else {
805
- mPopupPreviewX - = (key.width * 2.5 ).toInt( )
721
+ showKeyPreview(keys[keyIndex], behavior )
806
722
}
807
- mPopupPreviewY + = popupHeight
808
- }
809
- if (previewPopup.isShowing) {
810
- // previewPopup.update(mPopupPreviewX, mPopupPreviewY, popupWidth, popupHeight);
811
- previewPopup.dismiss() // 禁止窗口動畫
812
723
}
813
- previewPopup.width = popupWidth
814
- previewPopup.height = popupHeight
815
- previewPopup.showAtLocation(mPopupParent, Gravity .NO_GRAVITY , mPopupPreviewX, mPopupPreviewY)
816
- mPreviewText.visibility = VISIBLE
817
724
}
818
725
819
726
/* *
@@ -1157,13 +1064,9 @@ class KeyboardView(
1157
1064
private fun removeMessages () {
1158
1065
mHandler.removeMessages(MSG_REPEAT )
1159
1066
mHandler.removeMessages(MSG_LONGPRESS )
1160
- mHandler.removeMessages(MSG_SHOW_PREVIEW )
1161
1067
}
1162
1068
1163
1069
fun onDetach () {
1164
- if (mPreviewPopup.isShowing) {
1165
- mPreviewPopup.dismiss()
1166
- }
1167
1070
removeMessages()
1168
1071
freeDrawingBuffer()
1169
1072
}
@@ -1192,12 +1095,10 @@ class KeyboardView(
1192
1095
1193
1096
companion object {
1194
1097
private const val NOT_A_KEY = - 1
1195
- private const val MSG_SHOW_PREVIEW = 1
1196
1098
private const val MSG_REMOVE_PREVIEW = 2
1197
1099
private const val MSG_REPEAT = 3
1198
1100
private const val MSG_LONGPRESS = 4
1199
- private const val DELAY_BEFORE_PREVIEW = 0
1200
- private const val DELAY_AFTER_PREVIEW = 70
1101
+ private const val DELAY_AFTER_PREVIEW = 100L
1201
1102
private const val DEBOUNCE_TIME = 70
1202
1103
private const val MAX_NEARBY_KEYS = 12
1203
1104
}
0 commit comments