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