adding some code style and readability changes, no real functionality change

This commit is contained in:
tibbi 2022-01-07 21:23:29 +01:00
parent f69e898e32
commit cddff0675f
2 changed files with 205 additions and 163 deletions

View File

@ -35,12 +35,7 @@ import java.util.*
* @attr ref android.R.styleable#KeyboardView_popupLayout
*
*/
class MyKeyboardView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet?,
defStyleAttr: Int = R.attr.keyboardViewStyle,
defStyleRes: Int = 0
) :
class MyKeyboardView @JvmOverloads constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int = R.attr.keyboardViewStyle, defStyleRes: Int = 0) :
View(context, attrs, defStyleAttr, defStyleRes), View.OnClickListener {
/**
@ -249,7 +244,7 @@ class MyKeyboardView @JvmOverloads constructor(
}
init {
val a = context.obtainStyledAttributes(attrs, R.styleable.KeyboardView, defStyleAttr, defStyleRes)
val a = context.obtainStyledAttributes(attrs, R.styleable.MyKeyboardView, defStyleAttr, defStyleRes)
val inflate = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
var previewLayout = 0
val keyTextSize = 0
@ -257,21 +252,20 @@ class MyKeyboardView @JvmOverloads constructor(
for (i in 0 until n) {
val attr = a.getIndex(i)
when (attr) {
R.styleable.KeyboardView_keyBackground -> mKeyBackground = a.getDrawable(attr)
R.styleable.KeyboardView_verticalCorrection -> mVerticalCorrection = a.getDimensionPixelOffset(attr, 0)
R.styleable.KeyboardView_keyPreviewLayout -> previewLayout = a.getResourceId(attr, 0)
R.styleable.KeyboardView_keyPreviewOffset -> mPreviewOffset = a.getDimensionPixelOffset(attr, 0)
R.styleable.KeyboardView_keyPreviewHeight -> mPreviewHeight = a.getDimensionPixelSize(attr, 80)
R.styleable.KeyboardView_keyTextSize -> mKeyTextSize = a.getDimensionPixelSize(attr, 18)
R.styleable.KeyboardView_keyTextColor -> mKeyTextColor = a.getColor(attr, -0x1000000)
R.styleable.KeyboardView_labelTextSize -> mLabelTextSize = a.getDimensionPixelSize(attr, 14)
R.styleable.KeyboardView_popupLayout -> mPopupLayout = a.getResourceId(attr, 0)
R.styleable.KeyboardView_shadowColor -> mShadowColor = a.getColor(attr, 0)
R.styleable.KeyboardView_shadowRadius -> mShadowRadius = a.getFloat(attr, 0f)
R.styleable.MyKeyboardView_keyBackground -> mKeyBackground = a.getDrawable(attr)
R.styleable.MyKeyboardView_verticalCorrection -> mVerticalCorrection = a.getDimensionPixelOffset(attr, 0)
R.styleable.MyKeyboardView_keyPreviewLayout -> previewLayout = a.getResourceId(attr, 0)
R.styleable.MyKeyboardView_keyPreviewOffset -> mPreviewOffset = a.getDimensionPixelOffset(attr, 0)
R.styleable.MyKeyboardView_keyPreviewHeight -> mPreviewHeight = a.getDimensionPixelSize(attr, 80)
R.styleable.MyKeyboardView_keyTextSize -> mKeyTextSize = a.getDimensionPixelSize(attr, 18)
R.styleable.MyKeyboardView_keyTextColor -> mKeyTextColor = a.getColor(attr, -0x1000000)
R.styleable.MyKeyboardView_labelTextSize -> mLabelTextSize = a.getDimensionPixelSize(attr, 14)
R.styleable.MyKeyboardView_popupLayout -> mPopupLayout = a.getResourceId(attr, 0)
R.styleable.MyKeyboardView_shadowColor -> mShadowColor = a.getColor(attr, 0)
R.styleable.MyKeyboardView_shadowRadius -> mShadowRadius = a.getFloat(attr, 0f)
}
}
mKeyBackground = resources.getDrawable(R.drawable.keyboard_popup_panel_background, context.theme)
mBackgroundDimAmount = 0.5f
mPreviewPopup = PopupWindow(context)
if (previewLayout != 0) {
@ -282,6 +276,7 @@ class MyKeyboardView @JvmOverloads constructor(
} else {
isPreviewEnabled = false
}
mPreviewPopup.isTouchable = false
mPopupKeyboard = PopupWindow(context)
mPopupKeyboard.setBackgroundDrawable(null)
@ -303,12 +298,12 @@ class MyKeyboardView @JvmOverloads constructor(
resetMultiTap()
}
@SuppressLint("HandlerLeak")
override fun onAttachedToWindow() {
super.onAttachedToWindow()
initGestureDetector()
if (mHandler == null) {
mHandler = object : Handler() {
@SuppressLint("HandlerLeak")
override fun handleMessage(msg: Message) {
when (msg.what) {
MSG_SHOW_PREVIEW -> showKey(msg.arg1)
@ -327,11 +322,11 @@ class MyKeyboardView @JvmOverloads constructor(
private fun initGestureDetector() {
if (mGestureDetector == null) {
mGestureDetector = GestureDetector(context, object : SimpleOnGestureListener() {
override fun onFling(
me1: MotionEvent, me2: MotionEvent,
velocityX: Float, velocityY: Float
): Boolean {
if (mPossiblePoly) return false
override fun onFling(me1: MotionEvent, me2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
if (mPossiblePoly) {
return false
}
val absX = Math.abs(velocityX)
val absY = Math.abs(velocityY)
val deltaX = me2.x - me1.x
@ -380,16 +375,7 @@ class MyKeyboardView @JvmOverloads constructor(
mGestureDetector!!.setIsLongpressEnabled(false)
}
}
/**
* Returns the current keyboard being displayed by this view.
* @return the currently attached keyboard
* @see .setKeyboard
*/// Remove any pending messages
// Hint to reallocate the buffer if the size changed
// Not really necessary to do every time, but will free up views
// Switching to a different keyboard should abort any pending keys so that the key up
// doesn't get delivered to the old or new keyboard
// Until the next ACTION_DOWN
/**
* Attaches a keyboard to this view. The keyboard can be switched at any time and the
* view will re-layout itself to accommodate the keyboard.
@ -404,6 +390,7 @@ class MyKeyboardView @JvmOverloads constructor(
if (mKeyboard != null) {
showPreview(NOT_A_KEY)
}
// Remove any pending messages
removeMessages()
mKeyboard = keyboard
@ -414,7 +401,8 @@ class MyKeyboardView @JvmOverloads constructor(
mKeyboardChanged = true
invalidateAllKeys()
computeProximityThreshold(keyboard)
mMiniKeyboardCache.clear() // Not really necessary to do every time, but will free up views
mMiniKeyboardCache.clear()
// Not really necessary to do every time, but will free up views
// Switching to a different keyboard should abort any pending keys so that the key up
// doesn't get delivered to the old or new keyboard
mAbortKey = true // Until the next ACTION_DOWN
@ -446,9 +434,10 @@ class MyKeyboardView @JvmOverloads constructor(
var isShifted: Boolean = false
get() = if (mKeyboard != null) {
mKeyboard!!.isShifted
} else false
} else {
false
}
fun setVerticalCorrection(verticalOffset: Int) {}
fun setPopupParent(v: View) {
mPopupParent = v
}
@ -470,11 +459,11 @@ class MyKeyboardView @JvmOverloads constructor(
}
private fun adjustCase(label: CharSequence): CharSequence? {
var label: CharSequence? = label
if (mKeyboard!!.isShifted && label != null && label.length < 3 && Character.isLowerCase(label[0])) {
label = label.toString().toUpperCase()
var newLabel: CharSequence? = label
if (mKeyboard!!.isShifted && newLabel != null && newLabel.length < 3 && Character.isLowerCase(newLabel[0])) {
newLabel = newLabel.toString().toUpperCase()
}
return label
return newLabel
}
public override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
@ -497,15 +486,22 @@ class MyKeyboardView @JvmOverloads constructor(
* @param keyboard
*/
private fun computeProximityThreshold(keyboard: Keyboard?) {
if (keyboard == null) return
val keys = mKeys ?: return
if (keyboard == null) {
return
}
val keys = mKeys
val length = keys.size
var dimensionSum = 0
for (i in 0 until length) {
val key = keys[i]
dimensionSum += Math.min(key.width, key.height) + key.gap
}
if (dimensionSum < 0 || length == 0) return
if (dimensionSum < 0 || length == 0) {
return
}
mProximityThreshold = (dimensionSum * 1.4f / length).toInt()
mProximityThreshold *= mProximityThreshold // Square it
}
@ -529,9 +525,7 @@ class MyKeyboardView @JvmOverloads constructor(
private fun onBufferDraw() {
if (mBuffer == null || mKeyboardChanged) {
if (mBuffer == null || mKeyboardChanged &&
(mBuffer!!.width != width || mBuffer!!.height != height)
) {
if (mBuffer == null || mKeyboardChanged && (mBuffer!!.width != width || mBuffer!!.height != height)) {
// Make sure our bitmap is at least 1x1
val width = Math.max(1, width)
val height = Math.max(1, height)
@ -541,7 +535,11 @@ class MyKeyboardView @JvmOverloads constructor(
invalidateAllKeys()
mKeyboardChanged = false
}
if (mKeyboard == null) return
if (mKeyboard == null) {
return
}
mCanvas!!.save()
val canvas = mCanvas
canvas!!.clipRect(mDirtyRect)
@ -557,10 +555,15 @@ class MyKeyboardView @JvmOverloads constructor(
var drawSingleKey = false
if (invalidKey != null && canvas.getClipBounds(clipRegion)) {
// Is clipRegion completely contained within the invalidated key?
if (invalidKey.x + kbdPaddingLeft - 1 <= clipRegion.left && invalidKey.y + kbdPaddingTop - 1 <= clipRegion.top && invalidKey.x + invalidKey.width + kbdPaddingLeft + 1 >= clipRegion.right && invalidKey.y + invalidKey.height + kbdPaddingTop + 1 >= clipRegion.bottom) {
if (invalidKey.x + kbdPaddingLeft - 1 <= clipRegion.left &&
invalidKey.y + kbdPaddingTop - 1 <= clipRegion.top &&
invalidKey.x + invalidKey.width + kbdPaddingLeft + 1 >= clipRegion.right &&
invalidKey.y + invalidKey.height + kbdPaddingTop + 1 >= clipRegion.bottom
) {
drawSingleKey = true
}
}
canvas.drawColor(0x00000000, PorterDuff.Mode.CLEAR)
val keyCount = keys.size
for (i in 0 until keyCount) {
@ -568,17 +571,22 @@ class MyKeyboardView @JvmOverloads constructor(
if (drawSingleKey && invalidKey !== key) {
continue
}
val drawableState = key.currentDrawableState
keyBackground!!.state = drawableState
// Switch the character to uppercase if shift is pressed
val label = if (key.label == null) null else adjustCase(key.label).toString()
val label = if (key.label == null) {
null
} else {
adjustCase(key.label).toString()
}
val bounds = keyBackground.bounds
if (key.width != bounds.right ||
key.height != bounds.bottom
) {
if (key.width != bounds.right || key.height != bounds.bottom) {
keyBackground.setBounds(0, 0, key.width, key.height)
}
canvas.translate((key.x + kbdPaddingLeft).toFloat(), (key.y + kbdPaddingTop).toFloat())
keyBackground.draw(canvas)
if (label != null) {
@ -590,6 +598,7 @@ class MyKeyboardView @JvmOverloads constructor(
paint.textSize = mKeyTextSize.toFloat()
paint.typeface = Typeface.DEFAULT
}
// Draw a drop shadow for the text
paint.setShadowLayer(mShadowRadius, 0f, 0f, mShadowColor)
// Draw the text
@ -603,9 +612,7 @@ class MyKeyboardView @JvmOverloads constructor(
val drawableX = (key.width - padding.left - padding.right - key.icon.intrinsicWidth) / 2 + padding.left
val drawableY = (key.height - padding.top - padding.bottom - key.icon.intrinsicHeight) / 2 + paddingTop
canvas.translate(drawableX.toFloat(), drawableY.toFloat())
key.icon.setBounds(
0, 0, key.icon.intrinsicWidth, key.icon.intrinsicHeight
)
key.icon.setBounds(0, 0, key.icon.intrinsicWidth, key.icon.intrinsicHeight)
key.icon.draw(canvas)
canvas.translate(-drawableX.toFloat(), -drawableY.toFloat())
}
@ -634,31 +641,35 @@ class MyKeyboardView @JvmOverloads constructor(
private fun getKeyIndices(x: Int, y: Int, allKeys: IntArray?): Int {
val keys = mKeys
var primaryIndex: Int = NOT_A_KEY
var closestKey: Int = NOT_A_KEY
var primaryIndex = NOT_A_KEY
var closestKey = NOT_A_KEY
var closestKeyDist = mProximityThreshold + 1
Arrays.fill(mDistances, Int.MAX_VALUE)
val nearestKeyIndices = mKeyboard!!.getNearestKeys(x, y)
val keyCount = nearestKeyIndices.size
for (i in 0 until keyCount) {
val key = keys!![nearestKeyIndices[i]]
val key = keys[nearestKeyIndices[i]]
var dist = 0
val isInside = key.isInside(x, y)
if (isInside) {
primaryIndex = nearestKeyIndices[i]
}
if (((isProximityCorrectionEnabled
&& key.squaredDistanceFrom(x, y).also { dist = it } < mProximityThreshold)
|| isInside)
&& key.codes[0] > 32
) {
if (((isProximityCorrectionEnabled && key.squaredDistanceFrom(x, y).also {
dist = it
} < mProximityThreshold) || isInside) && key.codes[0] > 32) {
// Find insertion point
val nCodes = key.codes.size
if (dist < closestKeyDist) {
closestKeyDist = dist
closestKey = nearestKeyIndices[i]
}
if (allKeys == null) continue
if (allKeys == null) {
continue
}
for (j in mDistances.indices) {
if (mDistances[j] > dist) {
// Make space for nCodes codes
@ -670,6 +681,7 @@ class MyKeyboardView @JvmOverloads constructor(
allKeys, j, allKeys, j + nCodes,
allKeys.size - j - nCodes
)
for (c in 0 until nCodes) {
allKeys[j + c] = key.codes[c]
mDistances[j + c] = dist
@ -679,9 +691,11 @@ class MyKeyboardView @JvmOverloads constructor(
}
}
}
if (primaryIndex == NOT_A_KEY) {
primaryIndex = closestKey
}
return primaryIndex
}
@ -693,7 +707,7 @@ class MyKeyboardView @JvmOverloads constructor(
onKeyboardActionListener!!.onRelease(NOT_A_KEY)
} else {
var code = key.codes[0]
//TextEntryState.keyPressedAt(key, x, y);
// TextEntryState.keyPressedAt(key, x, y);
val codes = IntArray(MAX_NEARBY_KEYS)
Arrays.fill(codes, NOT_A_KEY)
getKeyIndices(x, y, codes)
@ -721,7 +735,13 @@ class MyKeyboardView @JvmOverloads constructor(
return if (mInMultiTap) {
// Multi-tap
mPreviewLabel.setLength(0)
mPreviewLabel.append(key.codes[if (mTapCount < 0) 0 else mTapCount].toChar())
val codeTapCount = if (mTapCount < 0) {
0
} else {
mTapCount
}
mPreviewLabel.append(key.codes[codeTapCount].toChar())
adjustCase(mPreviewLabel)
} else {
adjustCase(key.label)
@ -749,21 +769,19 @@ class MyKeyboardView @JvmOverloads constructor(
AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED, keyCode
)
}
if (mCurrentKeyIndex != NOT_A_KEY && keys!!.size > mCurrentKeyIndex) {
if (mCurrentKeyIndex != NOT_A_KEY && keys.size > mCurrentKeyIndex) {
val newKey = keys[mCurrentKeyIndex]
newKey.onPressed()
invalidateKey(mCurrentKeyIndex)
val keyCode = newKey.codes[0]
sendAccessibilityEventForUnicodeCharacter(
AccessibilityEvent.TYPE_VIEW_HOVER_ENTER,
keyCode
)
sendAccessibilityEventForUnicodeCharacter(AccessibilityEvent.TYPE_VIEW_HOVER_ENTER, keyCode)
// TODO: We need to implement AccessibilityNodeProvider for this view.
sendAccessibilityEventForUnicodeCharacter(
AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED, keyCode
)
}
}
// If key changed and preview is on ...
if (oldKeyIndex != mCurrentKeyIndex && isPreviewEnabled) {
mHandler!!.removeMessages(MSG_SHOW_PREVIEW)
@ -775,6 +793,7 @@ class MyKeyboardView @JvmOverloads constructor(
)
}
}
if (keyIndex != NOT_A_KEY) {
if (previewPopup.isShowing && mPreviewText!!.visibility == VISIBLE) {
// Show right away, if it's already visible and finger is moving around
@ -792,39 +811,40 @@ class MyKeyboardView @JvmOverloads constructor(
private fun showKey(keyIndex: Int) {
val previewPopup = mPreviewPopup
val keys = mKeys
if (keyIndex < 0 || keyIndex >= mKeys!!.size) return
val key = keys!![keyIndex]
if (keyIndex < 0 || keyIndex >= mKeys.size) {
return
}
val key = keys[keyIndex]
if (key.icon != null) {
mPreviewText!!.setCompoundDrawables(
null, null, null,
if (key.iconPreview != null) key.iconPreview else key.icon
)
mPreviewText!!.setText(null)
val bottomDrawable = if (key.iconPreview != null) {
key.iconPreview
} else {
key.icon
}
mPreviewText!!.setCompoundDrawables(null, null, null, bottomDrawable)
mPreviewText!!.text = null
} else {
mPreviewText!!.setCompoundDrawables(null, null, null, null)
mPreviewText!!.text = getPreviewText(key)
if (key.label.length > 1 && key.codes.size < 2) {
mPreviewText!!.setTextSize(TypedValue.COMPLEX_UNIT_PX, mKeyTextSize.toFloat())
mPreviewText!!.setTypeface(Typeface.DEFAULT_BOLD)
mPreviewText!!.typeface = Typeface.DEFAULT_BOLD
} else {
mPreviewText!!.setTextSize(TypedValue.COMPLEX_UNIT_PX, mPreviewTextSizeLarge.toFloat())
mPreviewText!!.setTypeface(Typeface.DEFAULT)
mPreviewText!!.typeface = Typeface.DEFAULT
}
}
mPreviewText!!.measure(
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
)
val popupWidth = Math.max(
mPreviewText!!.measuredWidth, key.width
+ mPreviewText!!.paddingLeft + mPreviewText!!.paddingRight
)
mPreviewText!!.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED))
val popupWidth = Math.max(mPreviewText!!.measuredWidth, key.width + mPreviewText!!.paddingLeft + mPreviewText!!.paddingRight)
val popupHeight = mPreviewHeight
val lp = mPreviewText!!.layoutParams
if (lp != null) {
lp.width = popupWidth
lp.height = popupHeight
}
if (!mPreviewCentered) {
mPopupPreviewX = key.x - mPreviewText!!.paddingLeft + paddingLeft
mPopupPreviewY = key.y - popupHeight + mPreviewOffset
@ -833,13 +853,19 @@ class MyKeyboardView @JvmOverloads constructor(
mPopupPreviewX = 160 - mPreviewText!!.measuredWidth / 2
mPopupPreviewY = -mPreviewText!!.measuredHeight
}
mHandler!!.removeMessages(MSG_REMOVE_PREVIEW)
getLocationInWindow(mCoordinates)
mCoordinates[0] += mMiniKeyboardOffsetX // Offset may be zero
mCoordinates[1] += mMiniKeyboardOffsetY // Offset may be zero
// Set the preview background state
mPreviewText!!.background.state = if (key.popupResId != 0) LONG_PRESSABLE_STATE_SET else EMPTY_STATE_SET
mPreviewText!!.background.state = if (key.popupResId != 0) {
LONG_PRESSABLE_STATE_SET
} else {
EMPTY_STATE_SET
}
mPopupPreviewX += mCoordinates[0]
mPopupPreviewY += mCoordinates[1]
@ -855,6 +881,7 @@ class MyKeyboardView @JvmOverloads constructor(
}
mPopupPreviewY += popupHeight
}
if (previewPopup.isShowing) {
previewPopup.update(
mPopupPreviewX, mPopupPreviewY,
@ -863,10 +890,7 @@ class MyKeyboardView @JvmOverloads constructor(
} else {
previewPopup.width = popupWidth
previewPopup.height = popupHeight
previewPopup.showAtLocation(
mPopupParent, Gravity.NO_GRAVITY,
mPopupPreviewX, mPopupPreviewY
)
previewPopup.showAtLocation(mPopupParent, Gravity.NO_GRAVITY, mPopupPreviewX, mPopupPreviewY)
}
mPreviewText!!.visibility = VISIBLE
}
@ -875,16 +899,15 @@ class MyKeyboardView @JvmOverloads constructor(
if (mAccessibilityManager.isEnabled) {
val event = AccessibilityEvent.obtain(eventType)
onInitializeAccessibilityEvent(event)
val text: String
when (code) {
Keyboard.KEYCODE_ALT -> text = context.getString(R.string.keyboardview_keycode_alt)
Keyboard.KEYCODE_CANCEL -> text = context.getString(R.string.keyboardview_keycode_cancel)
Keyboard.KEYCODE_DELETE -> text = context.getString(R.string.keyboardview_keycode_delete)
Keyboard.KEYCODE_DONE -> text = context.getString(R.string.keyboardview_keycode_done)
Keyboard.KEYCODE_MODE_CHANGE -> text = context.getString(R.string.keyboardview_keycode_mode_change)
Keyboard.KEYCODE_SHIFT -> text = context.getString(R.string.keyboardview_keycode_shift)
'\n'.toInt() -> text = context.getString(R.string.keyboardview_keycode_enter)
else -> text = code.toChar().toString()
val text: String = when (code) {
Keyboard.KEYCODE_ALT -> context.getString(R.string.keyboardview_keycode_alt)
Keyboard.KEYCODE_CANCEL -> context.getString(R.string.keyboardview_keycode_cancel)
Keyboard.KEYCODE_DELETE -> context.getString(R.string.keyboardview_keycode_delete)
Keyboard.KEYCODE_DONE -> context.getString(R.string.keyboardview_keycode_done)
Keyboard.KEYCODE_MODE_CHANGE -> context.getString(R.string.keyboardview_keycode_mode_change)
Keyboard.KEYCODE_SHIFT -> context.getString(R.string.keyboardview_keycode_shift)
'\n'.toInt() -> context.getString(R.string.keyboardview_keycode_enter)
else -> code.toChar().toString()
}
event.text.add(text)
mAccessibilityManager.sendAccessibilityEvent(event)
@ -914,6 +937,7 @@ class MyKeyboardView @JvmOverloads constructor(
if (keyIndex < 0 || keyIndex >= mKeys.size) {
return
}
val key = mKeys[keyIndex]
mInvalidatedKey = key
mDirtyRect.union(
@ -932,15 +956,18 @@ class MyKeyboardView @JvmOverloads constructor(
if (mPopupLayout == 0) {
return false
}
if (mCurrentKey < 0 || mCurrentKey >= mKeys.size) {
return false
}
val popupKey = mKeys[mCurrentKey]
val result = onLongPress(popupKey)
if (result) {
mAbortKey = true
showPreview(NOT_A_KEY)
}
return result
}
@ -956,9 +983,7 @@ class MyKeyboardView @JvmOverloads constructor(
if (popupKeyboardId != 0) {
mMiniKeyboardContainer = mMiniKeyboardCache[popupKey]
if (mMiniKeyboardContainer == null) {
val inflater = context.getSystemService(
Context.LAYOUT_INFLATER_SERVICE
) as LayoutInflater
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
mMiniKeyboardContainer = inflater.inflate(mPopupLayout, null)
mMiniKeyboard = mMiniKeyboardContainer!!.findViewById<View>(R.id.keyboardView) as MyKeyboardView
val closeButton = mMiniKeyboardContainer!!.findViewById<View>(R.id.closeButton)
@ -987,16 +1012,14 @@ class MyKeyboardView @JvmOverloads constructor(
onKeyboardActionListener!!.onRelease(primaryCode)
}
}
//mInputView.setSuggest(mSuggest);
val keyboard: Keyboard
keyboard = if (popupKey.popupCharacters != null) {
Keyboard(
context, popupKeyboardId,
popupKey.popupCharacters, -1, paddingLeft + paddingRight
)
val keyboard: Keyboard = if (popupKey.popupCharacters != null) {
Keyboard(context, popupKeyboardId, popupKey.popupCharacters, -1, paddingLeft + paddingRight)
} else {
Keyboard(context, popupKeyboardId)
}
mMiniKeyboard!!.keyboard = keyboard
mMiniKeyboard!!.setPopupParent(this)
mMiniKeyboardContainer!!.measure(
@ -1005,15 +1028,14 @@ class MyKeyboardView @JvmOverloads constructor(
)
mMiniKeyboardCache[popupKey] = mMiniKeyboardContainer
} else {
mMiniKeyboard = mMiniKeyboardContainer!!.findViewById<View>(
R.id.keyboardView
) as MyKeyboardView
mMiniKeyboard = mMiniKeyboardContainer!!.findViewById<View>(R.id.keyboardView) as MyKeyboardView
}
getLocationInWindow(mCoordinates)
mPopupX = popupKey.x + paddingLeft
mPopupY = popupKey.y + paddingTop
mPopupX = mPopupX + popupKey.width - mMiniKeyboardContainer!!.measuredWidth
mPopupY = mPopupY - mMiniKeyboardContainer!!.measuredHeight
mPopupY -= mMiniKeyboardContainer!!.measuredHeight
val x = mPopupX + mMiniKeyboardContainer!!.paddingRight + mCoordinates[0]
val y = mPopupY + mMiniKeyboardContainer!!.paddingBottom + mCoordinates[1]
mMiniKeyboard!!.setPopupOffset(if (x < 0) 0 else x, y)
@ -1032,17 +1054,10 @@ class MyKeyboardView @JvmOverloads constructor(
override fun onHoverEvent(event: MotionEvent): Boolean {
if (mAccessibilityManager.isTouchExplorationEnabled && event.pointerCount == 1) {
val action = event.action
when (action) {
MotionEvent.ACTION_HOVER_ENTER -> {
event.action = MotionEvent.ACTION_DOWN
}
MotionEvent.ACTION_HOVER_MOVE -> {
event.action = MotionEvent.ACTION_MOVE
}
MotionEvent.ACTION_HOVER_EXIT -> {
event.action = MotionEvent.ACTION_UP
}
when (event.action) {
MotionEvent.ACTION_HOVER_ENTER -> event.action = MotionEvent.ACTION_DOWN
MotionEvent.ACTION_HOVER_MOVE -> event.action = MotionEvent.ACTION_MOVE
MotionEvent.ACTION_HOVER_EXIT -> event.action = MotionEvent.ACTION_UP
}
return onTouchEvent(event)
}
@ -1059,10 +1074,7 @@ class MyKeyboardView @JvmOverloads constructor(
if (pointerCount != mOldPointerCount) {
if (pointerCount == 1) {
// Send a down event for the latest pointer
val down = MotionEvent.obtain(
now, now, MotionEvent.ACTION_DOWN,
me.x, me.y, me.metaState
)
val down = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN, me.x, me.y, me.metaState)
result = onModifiedTouchEvent(down, false)
down.recycle()
// If it's an up action, then deliver the up as well.
@ -1071,10 +1083,7 @@ class MyKeyboardView @JvmOverloads constructor(
}
} else {
// Send an up event for the last pointer
val up = MotionEvent.obtain(
now, now, MotionEvent.ACTION_UP,
mOldPointerX, mOldPointerY, me.metaState
)
val up = MotionEvent.obtain(now, now, MotionEvent.ACTION_UP, mOldPointerX, mOldPointerY, me.metaState)
result = onModifiedTouchEvent(up, true)
up.recycle()
}
@ -1093,24 +1102,29 @@ class MyKeyboardView @JvmOverloads constructor(
}
private fun onModifiedTouchEvent(me: MotionEvent, possiblePoly: Boolean): Boolean {
var touchX: Int = me.x.toInt() - paddingLeft
var touchY: Int = me.y.toInt() - paddingTop
if (touchY >= -mVerticalCorrection) touchY += mVerticalCorrection
var touchX = me.x.toInt() - paddingLeft
var touchY = me.y.toInt() - paddingTop
if (touchY >= -mVerticalCorrection) {
touchY += mVerticalCorrection
}
val action = me.action
val eventTime = me.eventTime
val keyIndex = getKeyIndices(touchX, touchY, null)
mPossiblePoly = possiblePoly
// Track the last few movements to look for spurious swipes.
if (action == MotionEvent.ACTION_DOWN) mSwipeTracker.clear()
if (action == MotionEvent.ACTION_DOWN) {
mSwipeTracker.clear()
}
mSwipeTracker.addMovement(me)
// Ignore all motion events until a DOWN.
if (mAbortKey
&& action != MotionEvent.ACTION_DOWN && action != MotionEvent.ACTION_CANCEL
) {
if (mAbortKey && action != MotionEvent.ACTION_DOWN && action != MotionEvent.ACTION_CANCEL) {
return true
}
if (mGestureDetector!!.onTouchEvent(me)) {
showPreview(NOT_A_KEY)
mHandler!!.removeMessages(MSG_REPEAT)
@ -1123,6 +1137,7 @@ class MyKeyboardView @JvmOverloads constructor(
if (mMiniKeyboardOnScreen && action != MotionEvent.ACTION_CANCEL) {
return true
}
when (action) {
MotionEvent.ACTION_DOWN -> {
mAbortKey = false
@ -1138,7 +1153,14 @@ class MyKeyboardView @JvmOverloads constructor(
mDownTime = me.eventTime
mLastMoveTime = mDownTime
checkMultiTap(eventTime, keyIndex)
onKeyboardActionListener!!.onPress(if (keyIndex != NOT_A_KEY) mKeys[keyIndex].codes[0] else 0)
val onPressKey = if (keyIndex != NOT_A_KEY) {
mKeys[keyIndex].codes[0]
} else {
0
}
onKeyboardActionListener!!.onPress(onPressKey)
var wasHandled = false
if (mCurrentKey >= 0 && mKeys[mCurrentKey].repeatable) {
@ -1152,6 +1174,7 @@ class MyKeyboardView @JvmOverloads constructor(
wasHandled = true
}
}
if (!wasHandled && mCurrentKey != NOT_A_KEY) {
val msg = mHandler!!.obtainMessage(MSG_LONGPRESS, me)
mHandler!!.sendMessageDelayed(msg, LONGPRESS_TIMEOUT.toLong())
@ -1202,6 +1225,7 @@ class MyKeyboardView @JvmOverloads constructor(
mCurrentKey = keyIndex
mCurrentKeyTime = 0
}
if (mCurrentKeyTime < mLastKeyTime && mCurrentKeyTime < DEBOUNCE_TIME && mLastKey != NOT_A_KEY) {
mCurrentKey = mLastKey
touchX = mLastCodeX
@ -1303,9 +1327,7 @@ class MyKeyboardView @JvmOverloads constructor(
val key = mKeys[keyIndex]
if (key.codes.size > 1) {
mInMultiTap = true
if (eventTime < mLastTapTime + MULTITAP_INTERVAL
&& keyIndex == mLastSentIndex
) {
if (eventTime < mLastTapTime + MULTITAP_INTERVAL && keyIndex == mLastSentIndex) {
mTapCount = (mTapCount + 1) % key.codes.size
return
} else {
@ -1313,12 +1335,18 @@ class MyKeyboardView @JvmOverloads constructor(
return
}
}
if (eventTime > mLastTapTime + MULTITAP_INTERVAL || keyIndex != mLastSentIndex) {
resetMultiTap()
}
}
private class SwipeTracker {
companion object {
const val NUM_PAST = 4
const val LONGEST_PAST_TIME = 200
}
val mPastX = FloatArray(NUM_PAST)
val mPastY = FloatArray(NUM_PAST)
val mPastTime = LongArray(NUM_PAST)
@ -1333,19 +1361,15 @@ class MyKeyboardView @JvmOverloads constructor(
val time = ev.eventTime
val N = ev.historySize
for (i in 0 until N) {
addPoint(
ev.getHistoricalX(i), ev.getHistoricalY(i),
ev.getHistoricalEventTime(i)
)
addPoint(ev.getHistoricalX(i), ev.getHistoricalY(i), ev.getHistoricalEventTime(i))
}
addPoint(ev.x, ev.y, time)
}
private fun addPoint(x: Float, y: Float, time: Long) {
var drop = -1
var i: Int
val pastTime = mPastTime
i = 0
var i = 0
while (i < NUM_PAST) {
if (pastTime[i] == 0L) {
break
@ -1354,9 +1378,11 @@ class MyKeyboardView @JvmOverloads constructor(
}
i++
}
if (i == NUM_PAST && drop < 0) {
drop = 0
}
if (drop == i) drop--
val pastX = mPastX
val pastY = mPastY
@ -1372,6 +1398,7 @@ class MyKeyboardView @JvmOverloads constructor(
pastY[i] = y
pastTime[i] = time
i++
if (i < NUM_PAST) {
pastTime[i] = 0
}
@ -1394,23 +1421,38 @@ class MyKeyboardView @JvmOverloads constructor(
}
N++
}
for (i in 1 until N) {
val dur = (pastTime[i] - oldestTime).toInt()
if (dur == 0) continue
var dist = pastX[i] - oldestX
var vel = dist / dur * units // pixels/frame.
accumX = if (accumX == 0f) vel else (accumX + vel) * .5f
accumX = if (accumX == 0f) {
vel
} else {
(accumX + vel) * .5f
}
dist = pastY[i] - oldestY
vel = dist / dur * units // pixels/frame.
accumY = if (accumY == 0f) vel else (accumY + vel) * .5f
accumY = if (accumY == 0f) {
vel
} else {
(accumY + vel) * .5f
}
}
xVelocity = if (accumX < 0.0f) Math.max(accumX, -maxVelocity) else Math.min(accumX, maxVelocity)
yVelocity = if (accumY < 0.0f) Math.max(accumY, -maxVelocity) else Math.min(accumY, maxVelocity)
}
companion object {
const val NUM_PAST = 4
const val LONGEST_PAST_TIME = 200
xVelocity = if (accumX < 0.0f) {
Math.max(accumX, -maxVelocity)
} else {
Math.min(accumX, maxVelocity)
}
yVelocity = if (accumY < 0.0f) {
Math.max(accumY, -maxVelocity)
} else {
Math.min(accumY, maxVelocity)
}
}
}
}

View File

@ -21,7 +21,7 @@
<item name="shadowRadius">2.75</item>
</style>
<declare-styleable name="KeyboardView">
<declare-styleable name="MyKeyboardView">
<attr name="keyboardViewStyle" format="reference" />
<!-- Image for the key. This image needs to be a StateListDrawable, with the following
possible states: normal, pressed, checkable, checkable+pressed, checkable+checked,