Merge pull request #104 from KryptKode/feat/switch-language-on-longpress-emoji

feature: support switching language on longpress of emoji key
This commit is contained in:
Tibor Kaputa 2022-11-07 22:26:36 +01:00 committed by GitHub
commit a50c86caba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 396 additions and 143 deletions

View file

@ -9,6 +9,8 @@ import com.simplemobiletools.commons.helpers.isTiramisuPlus
import com.simplemobiletools.commons.models.RadioItem
import com.simplemobiletools.keyboard.R
import com.simplemobiletools.keyboard.extensions.config
import com.simplemobiletools.keyboard.extensions.getKeyboardLanguageText
import com.simplemobiletools.keyboard.extensions.getKeyboardLanguages
import com.simplemobiletools.keyboard.helpers.*
import kotlinx.android.synthetic.main.activity_settings.*
import java.util.*
@ -117,22 +119,7 @@ class SettingsActivity : SimpleActivity() {
private fun setupKeyboardLanguage() {
settings_keyboard_language.text = getKeyboardLanguageText(config.keyboardLanguage)
settings_keyboard_language_holder.setOnClickListener {
val items = arrayListOf(
RadioItem(LANGUAGE_BENGALI, getKeyboardLanguageText(LANGUAGE_BENGALI)),
RadioItem(LANGUAGE_BULGARIAN, getKeyboardLanguageText(LANGUAGE_BULGARIAN)),
RadioItem(LANGUAGE_ENGLISH_QWERTY, getKeyboardLanguageText(LANGUAGE_ENGLISH_QWERTY)),
RadioItem(LANGUAGE_ENGLISH_QWERTZ, getKeyboardLanguageText(LANGUAGE_ENGLISH_QWERTZ)),
RadioItem(LANGUAGE_ENGLISH_DVORAK, getKeyboardLanguageText(LANGUAGE_ENGLISH_DVORAK)),
RadioItem(LANGUAGE_FRENCH, getKeyboardLanguageText(LANGUAGE_FRENCH)),
RadioItem(LANGUAGE_GERMAN, getKeyboardLanguageText(LANGUAGE_GERMAN)),
RadioItem(LANGUAGE_LITHUANIAN, getKeyboardLanguageText(LANGUAGE_LITHUANIAN)),
RadioItem(LANGUAGE_ROMANIAN, getKeyboardLanguageText(LANGUAGE_ROMANIAN)),
RadioItem(LANGUAGE_RUSSIAN, getKeyboardLanguageText(LANGUAGE_RUSSIAN)),
RadioItem(LANGUAGE_SLOVENIAN, getKeyboardLanguageText(LANGUAGE_SLOVENIAN)),
RadioItem(LANGUAGE_SPANISH, getKeyboardLanguageText(LANGUAGE_SPANISH)),
RadioItem(LANGUAGE_TURKISH_Q, getKeyboardLanguageText(LANGUAGE_TURKISH_Q)),
)
val items = getKeyboardLanguages()
RadioGroupDialog(this@SettingsActivity, items, config.keyboardLanguage) {
config.keyboardLanguage = it as Int
settings_keyboard_language.text = getKeyboardLanguageText(config.keyboardLanguage)
@ -140,24 +127,6 @@ class SettingsActivity : SimpleActivity() {
}
}
private fun getKeyboardLanguageText(language: Int): String {
return when (language) {
LANGUAGE_BENGALI -> getString(R.string.translation_bengali)
LANGUAGE_BULGARIAN -> getString(R.string.translation_bulgarian)
LANGUAGE_ENGLISH_DVORAK -> "${getString(R.string.translation_english)} (DVORAK)"
LANGUAGE_ENGLISH_QWERTZ -> "${getString(R.string.translation_english)} (QWERTZ)"
LANGUAGE_FRENCH -> getString(R.string.translation_french)
LANGUAGE_GERMAN -> getString(R.string.translation_german)
LANGUAGE_LITHUANIAN -> getString(R.string.translation_lithuanian)
LANGUAGE_ROMANIAN -> getString(R.string.translation_romanian)
LANGUAGE_RUSSIAN -> getString(R.string.translation_russian)
LANGUAGE_SLOVENIAN -> getString(R.string.translation_slovenian)
LANGUAGE_SPANISH -> getString(R.string.translation_spanish)
LANGUAGE_TURKISH_Q -> "${getString(R.string.translation_turkish)} (Q)"
else -> "${getString(R.string.translation_english)} (QWERTY)"
}
}
private fun setupKeyboardHeightMultiplier() {
settings_keyboard_height_multiplier.text = getKeyboardHeightMultiplierText(config.keyboardHeightMultiplier)
settings_keyboard_height_multiplier_holder.setOnClickListener {

View file

@ -0,0 +1,21 @@
package com.simplemobiletools.keyboard.dialogs
import android.view.View
import com.simplemobiletools.keyboard.extensions.config
import com.simplemobiletools.keyboard.extensions.getKeyboardLanguages
class ChangeLanguagePopup(
inputView: View,
private val onSelect: () -> Unit,
) {
private val context = inputView.context
private val config = context.config
init {
val items = context.getKeyboardLanguages()
KeyboardRadioGroupDialog(inputView, items, config.keyboardLanguage) {
config.keyboardLanguage = it as Int
onSelect.invoke()
}
}
}

View file

@ -0,0 +1,81 @@
package com.simplemobiletools.keyboard.dialogs
import android.view.ContextThemeWrapper
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.RadioButton
import android.widget.RadioGroup
import android.widget.ScrollView
import androidx.appcompat.app.AlertDialog
import com.simplemobiletools.commons.extensions.onGlobalLayout
import com.simplemobiletools.commons.models.RadioItem
import com.simplemobiletools.keyboard.R
import com.simplemobiletools.keyboard.extensions.getKeyboardDialogBuilder
import com.simplemobiletools.keyboard.extensions.setupKeyboardDialogStuff
class KeyboardRadioGroupDialog(
private val inputView: View,
private val items: ArrayList<RadioItem>,
private val checkedItemId: Int = -1,
private val titleId: Int = 0,
showOKButton: Boolean = false,
private val cancelCallback: (() -> Unit)? = null,
private val callback: (newValue: Any) -> Unit
) {
private val context = ContextThemeWrapper(inputView.context, R.style.MyKeyboard_Alert)
private var dialog: AlertDialog? = null
private var wasInit = false
private var selectedItemId = -1
private val layoutInflater = LayoutInflater.from(context)
init {
val view = layoutInflater.inflate(R.layout.dialog_radio_group, null)
val radioGroup = view.findViewById<RadioGroup>(R.id.dialog_radio_group).apply {
for (i in 0 until items.size) {
val radioButton = (layoutInflater.inflate(R.layout.radio_button, null) as RadioButton).apply {
text = items[i].title
isChecked = items[i].id == checkedItemId
id = i
setOnClickListener { itemSelected(i) }
}
if (items[i].id == checkedItemId) {
selectedItemId = i
}
addView(radioButton, RadioGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT))
}
}
val builder = context.getKeyboardDialogBuilder()
.setOnCancelListener { cancelCallback?.invoke() }
if (selectedItemId != -1 && showOKButton) {
builder.setPositiveButton(R.string.ok) { _, _ -> itemSelected(selectedItemId) }
}
builder.apply {
context.setupKeyboardDialogStuff(inputView.windowToken, view, this, titleId) { alertDialog ->
dialog = alertDialog
}
}
if (selectedItemId != -1) {
view.findViewById<ScrollView>(R.id.dialog_radio_holder).apply {
onGlobalLayout {
scrollY = radioGroup.findViewById<View>(selectedItemId).bottom - height
}
}
}
wasInit = true
}
private fun itemSelected(checkedId: Int) {
if (wasInit) {
callback(items[checkedId].value)
dialog?.dismiss()
}
}
}

View file

@ -3,12 +3,22 @@ package com.simplemobiletools.keyboard.extensions
import android.content.ClipboardManager
import android.content.Context
import android.graphics.Color
import com.simplemobiletools.commons.extensions.getProperBackgroundColor
import com.simplemobiletools.commons.extensions.isUsingSystemDarkTheme
import com.simplemobiletools.commons.extensions.lightenColor
import android.os.IBinder
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.view.WindowManager
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.core.content.res.ResourcesCompat
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.models.RadioItem
import com.simplemobiletools.commons.views.MyTextView
import com.simplemobiletools.keyboard.R
import com.simplemobiletools.keyboard.databases.ClipsDatabase
import com.simplemobiletools.keyboard.helpers.Config
import com.simplemobiletools.keyboard.helpers.*
import com.simplemobiletools.keyboard.interfaces.ClipsDao
val Context.config: Config get() = Config.newInstance(applicationContext)
@ -36,3 +46,141 @@ fun Context.getStrokeColor(): Int {
}
}
}
fun Context.getKeyboardDialogBuilder() = if (baseConfig.isUsingSystemTheme) {
MaterialAlertDialogBuilder(this, R.style.MyKeyboard_Alert)
} else {
AlertDialog.Builder(this, R.style.MyKeyboard_Alert)
}
fun Context.setupKeyboardDialogStuff(
windowToken: IBinder,
view: View,
dialog: AlertDialog.Builder,
titleId: Int = 0,
titleText: String = "",
cancelOnTouchOutside: Boolean = true,
callback: ((alertDialog: AlertDialog) -> Unit)? = null
) {
val textColor = getProperTextColor()
val backgroundColor = getProperBackgroundColor()
val primaryColor = getProperPrimaryColor()
if (view is ViewGroup) {
updateTextColors(view)
} else if (view is MyTextView) {
view.setColors(textColor, primaryColor, backgroundColor)
}
if (dialog is MaterialAlertDialogBuilder) {
dialog.create().apply {
if (titleId != 0) {
setTitle(titleId)
} else if (titleText.isNotEmpty()) {
setTitle(titleText)
}
val lp = window?.attributes
lp?.token = windowToken
lp?.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG
window?.attributes = lp
window?.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM)
setView(view)
setCancelable(cancelOnTouchOutside)
show()
val bgDrawable = when {
isBlackAndWhiteTheme() -> ResourcesCompat.getDrawable(resources, R.drawable.black_dialog_background, theme)
baseConfig.isUsingSystemTheme -> ResourcesCompat.getDrawable(resources, R.drawable.dialog_you_background, theme)
else -> resources.getColoredDrawableWithColor(R.drawable.dialog_bg, baseConfig.backgroundColor)
}
window?.setBackgroundDrawable(bgDrawable)
callback?.invoke(this)
}
} else {
var title: TextView? = null
if (titleId != 0 || titleText.isNotEmpty()) {
title = LayoutInflater.from(this).inflate(R.layout.dialog_title, null) as TextView
title.apply {
if (titleText.isNotEmpty()) {
text = titleText
} else {
setText(titleId)
}
setTextColor(textColor)
}
}
// if we use the same primary and background color, use the text color for dialog confirmation buttons
val dialogButtonColor = if (primaryColor == baseConfig.backgroundColor) {
textColor
} else {
primaryColor
}
dialog.create().apply {
setView(view)
requestWindowFeature(Window.FEATURE_NO_TITLE)
setCustomTitle(title)
val lp = window?.attributes
lp?.token = windowToken
lp?.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG
window?.attributes = lp
window?.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM)
setCanceledOnTouchOutside(cancelOnTouchOutside)
show()
getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(dialogButtonColor)
getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(dialogButtonColor)
getButton(AlertDialog.BUTTON_NEUTRAL).setTextColor(dialogButtonColor)
val bgDrawable = when {
isBlackAndWhiteTheme() -> ResourcesCompat.getDrawable(resources, R.drawable.black_dialog_background, theme)
baseConfig.isUsingSystemTheme -> ResourcesCompat.getDrawable(resources, R.drawable.dialog_you_background, theme)
else -> resources.getColoredDrawableWithColor(R.drawable.dialog_bg, baseConfig.backgroundColor)
}
window?.setBackgroundDrawable(bgDrawable)
callback?.invoke(this)
}
}
}
fun Context.getKeyboardLanguages(): ArrayList<RadioItem> {
return arrayListOf(
RadioItem(LANGUAGE_BENGALI, getKeyboardLanguageText(LANGUAGE_BENGALI)),
RadioItem(LANGUAGE_BULGARIAN, getKeyboardLanguageText(LANGUAGE_BULGARIAN)),
RadioItem(LANGUAGE_ENGLISH_QWERTY, getKeyboardLanguageText(LANGUAGE_ENGLISH_QWERTY)),
RadioItem(LANGUAGE_ENGLISH_QWERTZ, getKeyboardLanguageText(LANGUAGE_ENGLISH_QWERTZ)),
RadioItem(LANGUAGE_ENGLISH_DVORAK, getKeyboardLanguageText(LANGUAGE_ENGLISH_DVORAK)),
RadioItem(LANGUAGE_FRENCH, getKeyboardLanguageText(LANGUAGE_FRENCH)),
RadioItem(LANGUAGE_GERMAN, getKeyboardLanguageText(LANGUAGE_GERMAN)),
RadioItem(LANGUAGE_LITHUANIAN, getKeyboardLanguageText(LANGUAGE_LITHUANIAN)),
RadioItem(LANGUAGE_ROMANIAN, getKeyboardLanguageText(LANGUAGE_ROMANIAN)),
RadioItem(LANGUAGE_RUSSIAN, getKeyboardLanguageText(LANGUAGE_RUSSIAN)),
RadioItem(LANGUAGE_SLOVENIAN, getKeyboardLanguageText(LANGUAGE_SLOVENIAN)),
RadioItem(LANGUAGE_SPANISH, getKeyboardLanguageText(LANGUAGE_SPANISH)),
RadioItem(LANGUAGE_TURKISH_Q, getKeyboardLanguageText(LANGUAGE_TURKISH_Q)),
)
}
fun Context.getKeyboardLanguageText(language: Int): String {
return when (language) {
LANGUAGE_BENGALI -> getString(R.string.translation_bengali)
LANGUAGE_BULGARIAN -> getString(R.string.translation_bulgarian)
LANGUAGE_ENGLISH_DVORAK -> "${getString(R.string.translation_english)} (DVORAK)"
LANGUAGE_ENGLISH_QWERTZ -> "${getString(R.string.translation_english)} (QWERTZ)"
LANGUAGE_FRENCH -> getString(R.string.translation_french)
LANGUAGE_GERMAN -> getString(R.string.translation_german)
LANGUAGE_LITHUANIAN -> getString(R.string.translation_lithuanian)
LANGUAGE_ROMANIAN -> getString(R.string.translation_romanian)
LANGUAGE_RUSSIAN -> getString(R.string.translation_russian)
LANGUAGE_SLOVENIAN -> getString(R.string.translation_slovenian)
LANGUAGE_SPANISH -> getString(R.string.translation_spanish)
LANGUAGE_TURKISH_Q -> "${getString(R.string.translation_turkish)} (Q)"
else -> "${getString(R.string.translation_english)} (QWERTY)"
}
}

View file

@ -61,18 +61,7 @@ class SimpleKeyboardIME : InputMethodService(), MyKeyboardView.OnKeyboardActionL
inputTypeClass = attribute!!.inputType and TYPE_MASK_CLASS
enterKeyType = attribute.imeOptions and (IME_MASK_ACTION or IME_FLAG_NO_ENTER_ACTION)
val keyboardXml = when (inputTypeClass) {
TYPE_CLASS_NUMBER, TYPE_CLASS_DATETIME, TYPE_CLASS_PHONE -> {
keyboardMode = KEYBOARD_SYMBOLS
R.xml.keys_symbols
}
else -> {
keyboardMode = KEYBOARD_LETTERS
getKeyboardLayoutXML()
}
}
keyboard = MyKeyboard(this, keyboardXml, enterKeyType)
keyboard = getKeyBoard()
keyboardView?.setKeyboard(keyboard!!)
keyboardView?.setEditorInfo(attribute)
updateShiftKeyState()
@ -220,6 +209,27 @@ class SimpleKeyboardIME : InputMethodService(), MyKeyboardView.OnKeyboardActionL
currentInputConnection?.commitText(text, 0)
}
override fun reloadKeyboard() {
val keyboard = getKeyBoard()
this.keyboard = keyboard
keyboardView?.setKeyboard(keyboard)
}
private fun getKeyBoard(): MyKeyboard {
val keyboardXml = when (inputTypeClass) {
TYPE_CLASS_NUMBER, TYPE_CLASS_DATETIME, TYPE_CLASS_PHONE -> {
keyboardMode = KEYBOARD_SYMBOLS
R.xml.keys_symbols
}
else -> {
keyboardMode = KEYBOARD_LETTERS
getKeyboardLayoutXML()
}
}
return MyKeyboard(this, keyboardXml, enterKeyType)
}
override fun onUpdateSelection(oldSelStart: Int, oldSelEnd: Int, newSelStart: Int, newSelEnd: Int, candidatesStart: Int, candidatesEnd: Int) {
super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd, candidatesStart, candidatesEnd)
if (newSelStart == newSelEnd) {

View file

@ -37,6 +37,7 @@ import com.simplemobiletools.keyboard.activities.ManageClipboardItemsActivity
import com.simplemobiletools.keyboard.activities.SettingsActivity
import com.simplemobiletools.keyboard.adapters.ClipsKeyboardAdapter
import com.simplemobiletools.keyboard.adapters.EmojisAdapter
import com.simplemobiletools.keyboard.dialogs.ChangeLanguagePopup
import com.simplemobiletools.keyboard.extensions.*
import com.simplemobiletools.keyboard.helpers.*
import com.simplemobiletools.keyboard.helpers.MyKeyboard.Companion.KEYCODE_DELETE
@ -90,6 +91,11 @@ class MyKeyboardView @JvmOverloads constructor(context: Context, attrs: Attribut
* @param text the string to be displayed.
*/
fun onText(text: String)
/**
* Called to force the KeyboardView to reload the keyboard
*/
fun reloadKeyboard()
}
private var mKeyboard: MyKeyboard? = null
@ -949,100 +955,111 @@ class MyKeyboardView @JvmOverloads constructor(context: Context, attrs: Attribut
* handle the call.
*/
private fun onLongPress(popupKey: MyKeyboard.Key, me: MotionEvent): Boolean {
val popupKeyboardId = popupKey.popupResId
if (popupKeyboardId != 0) {
mMiniKeyboardContainer = mMiniKeyboardCache[popupKey]
if (mMiniKeyboardContainer == null) {
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
mMiniKeyboardContainer = inflater.inflate(mPopupLayout, null)
mMiniKeyboard = mMiniKeyboardContainer!!.findViewById<View>(R.id.mini_keyboard_view) as MyKeyboardView
mMiniKeyboard!!.mOnKeyboardActionListener = object : OnKeyboardActionListener {
override fun onKey(code: Int) {
mOnKeyboardActionListener!!.onKey(code)
dismissPopupKeyboard()
}
override fun onPress(primaryCode: Int) {
mOnKeyboardActionListener!!.onPress(primaryCode)
}
override fun onActionUp() {
mOnKeyboardActionListener!!.onActionUp()
}
override fun moveCursorLeft() {
mOnKeyboardActionListener!!.moveCursorLeft()
}
override fun moveCursorRight() {
mOnKeyboardActionListener!!.moveCursorRight()
}
override fun onText(text: String) {
mOnKeyboardActionListener!!.onText(text)
}
}
val keyboard = if (popupKey.popupCharacters != null) {
MyKeyboard(context, popupKeyboardId, popupKey.popupCharacters!!, popupKey.width)
} else {
MyKeyboard(context, popupKeyboardId, 0)
}
mMiniKeyboard!!.setKeyboard(keyboard)
mPopupParent = this
mMiniKeyboardContainer!!.measure(
MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST)
)
mMiniKeyboardCache[popupKey] = mMiniKeyboardContainer
} else {
mMiniKeyboard = mMiniKeyboardContainer!!.findViewById<View>(R.id.mini_keyboard_view) as MyKeyboardView
}
getLocationInWindow(mCoordinates)
mPopupX = popupKey.x
mPopupY = popupKey.y
val widthToUse = mMiniKeyboardContainer!!.measuredWidth - (popupKey.popupCharacters!!.length / 2) * popupKey.width
mPopupX = mPopupX + popupKey.width - widthToUse
mPopupY -= mMiniKeyboardContainer!!.measuredHeight
val x = mPopupX + mCoordinates[0]
val y = mPopupY + mCoordinates[1]
val xOffset = Math.max(0, x)
mMiniKeyboard!!.setPopupOffset(xOffset, y)
// make sure we highlight the proper key right after long pressing it, before any ACTION_MOVE event occurs
val miniKeyboardX = if (xOffset + mMiniKeyboard!!.measuredWidth <= measuredWidth) {
xOffset
} else {
measuredWidth - mMiniKeyboard!!.measuredWidth
}
val keysCnt = mMiniKeyboard!!.mKeys.size
var selectedKeyIndex = Math.floor((me.x - miniKeyboardX) / popupKey.width.toDouble()).toInt()
if (keysCnt > MAX_KEYS_PER_MINI_ROW) {
selectedKeyIndex += MAX_KEYS_PER_MINI_ROW
}
selectedKeyIndex = Math.max(0, Math.min(selectedKeyIndex, keysCnt - 1))
for (i in 0 until keysCnt) {
mMiniKeyboard!!.mKeys[i].focused = i == selectedKeyIndex
}
mMiniKeyboardSelectedKeyIndex = selectedKeyIndex
mMiniKeyboard!!.invalidateAllKeys()
val miniShiftStatus = if (isShifted()) SHIFT_ON_PERMANENT else SHIFT_OFF
mMiniKeyboard!!.setShifted(miniShiftStatus)
mPopupKeyboard.contentView = mMiniKeyboardContainer
mPopupKeyboard.width = mMiniKeyboardContainer!!.measuredWidth
mPopupKeyboard.height = mMiniKeyboardContainer!!.measuredHeight
mPopupKeyboard.showAtLocation(this, Gravity.NO_GRAVITY, x, y)
mMiniKeyboardOnScreen = true
invalidateAllKeys()
if (popupKey.code == KEYCODE_EMOJI) {
ChangeLanguagePopup(this, onSelect = {
mOnKeyboardActionListener?.reloadKeyboard()
})
return true
} else {
val popupKeyboardId = popupKey.popupResId
if (popupKeyboardId != 0) {
mMiniKeyboardContainer = mMiniKeyboardCache[popupKey]
if (mMiniKeyboardContainer == null) {
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
mMiniKeyboardContainer = inflater.inflate(mPopupLayout, null)
mMiniKeyboard = mMiniKeyboardContainer!!.findViewById<View>(R.id.mini_keyboard_view) as MyKeyboardView
mMiniKeyboard!!.mOnKeyboardActionListener = object : OnKeyboardActionListener {
override fun onKey(code: Int) {
mOnKeyboardActionListener!!.onKey(code)
dismissPopupKeyboard()
}
override fun onPress(primaryCode: Int) {
mOnKeyboardActionListener!!.onPress(primaryCode)
}
override fun onActionUp() {
mOnKeyboardActionListener!!.onActionUp()
}
override fun moveCursorLeft() {
mOnKeyboardActionListener!!.moveCursorLeft()
}
override fun moveCursorRight() {
mOnKeyboardActionListener!!.moveCursorRight()
}
override fun onText(text: String) {
mOnKeyboardActionListener!!.onText(text)
}
override fun reloadKeyboard() {
mOnKeyboardActionListener!!.reloadKeyboard()
}
}
val keyboard = if (popupKey.popupCharacters != null) {
MyKeyboard(context, popupKeyboardId, popupKey.popupCharacters!!, popupKey.width)
} else {
MyKeyboard(context, popupKeyboardId, 0)
}
mMiniKeyboard!!.setKeyboard(keyboard)
mPopupParent = this
mMiniKeyboardContainer!!.measure(
MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST)
)
mMiniKeyboardCache[popupKey] = mMiniKeyboardContainer
} else {
mMiniKeyboard = mMiniKeyboardContainer!!.findViewById<View>(R.id.mini_keyboard_view) as MyKeyboardView
}
getLocationInWindow(mCoordinates)
mPopupX = popupKey.x
mPopupY = popupKey.y
val widthToUse = mMiniKeyboardContainer!!.measuredWidth - (popupKey.popupCharacters!!.length / 2) * popupKey.width
mPopupX = mPopupX + popupKey.width - widthToUse
mPopupY -= mMiniKeyboardContainer!!.measuredHeight
val x = mPopupX + mCoordinates[0]
val y = mPopupY + mCoordinates[1]
val xOffset = Math.max(0, x)
mMiniKeyboard!!.setPopupOffset(xOffset, y)
// make sure we highlight the proper key right after long pressing it, before any ACTION_MOVE event occurs
val miniKeyboardX = if (xOffset + mMiniKeyboard!!.measuredWidth <= measuredWidth) {
xOffset
} else {
measuredWidth - mMiniKeyboard!!.measuredWidth
}
val keysCnt = mMiniKeyboard!!.mKeys.size
var selectedKeyIndex = Math.floor((me.x - miniKeyboardX) / popupKey.width.toDouble()).toInt()
if (keysCnt > MAX_KEYS_PER_MINI_ROW) {
selectedKeyIndex += MAX_KEYS_PER_MINI_ROW
}
selectedKeyIndex = Math.max(0, Math.min(selectedKeyIndex, keysCnt - 1))
for (i in 0 until keysCnt) {
mMiniKeyboard!!.mKeys[i].focused = i == selectedKeyIndex
}
mMiniKeyboardSelectedKeyIndex = selectedKeyIndex
mMiniKeyboard!!.invalidateAllKeys()
val miniShiftStatus = if (isShifted()) SHIFT_ON_PERMANENT else SHIFT_OFF
mMiniKeyboard!!.setShifted(miniShiftStatus)
mPopupKeyboard.contentView = mMiniKeyboardContainer
mPopupKeyboard.width = mMiniKeyboardContainer!!.measuredWidth
mPopupKeyboard.height = mMiniKeyboardContainer!!.measuredHeight
mPopupKeyboard.showAtLocation(this, Gravity.NO_GRAVITY, x, y)
mMiniKeyboardOnScreen = true
invalidateAllKeys()
return true
}
}
return false
}

View file

@ -13,4 +13,11 @@
<style name="MyKeyboardViewPopup" parent="MyKeyboard">
<item name="keyTextSize">@dimen/preview_text_size</item>
</style>
<style name="MyKeyboard.Alert" parent="Theme.Material3.Light.Dialog.Alert">
<item name="colorAccent">@color/color_primary</item>
<item name="android:buttonBarNegativeButtonStyle">@style/DialogButtonStyle</item>
<item name="android:buttonBarPositiveButtonStyle">@style/DialogButtonStyle</item>
<item name="android:buttonBarNeutralButtonStyle">@style/DialogButtonStyle</item>
</style>
</resources>