diff --git a/app/src/main/kotlin/com/simplemobiletools/keyboard/activities/SettingsActivity.kt b/app/src/main/kotlin/com/simplemobiletools/keyboard/activities/SettingsActivity.kt index 5565aed..3a19ffc 100644 --- a/app/src/main/kotlin/com/simplemobiletools/keyboard/activities/SettingsActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/keyboard/activities/SettingsActivity.kt @@ -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 { diff --git a/app/src/main/kotlin/com/simplemobiletools/keyboard/dialogs/ChangeLanguagePopup.kt b/app/src/main/kotlin/com/simplemobiletools/keyboard/dialogs/ChangeLanguagePopup.kt new file mode 100644 index 0000000..53538bd --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/keyboard/dialogs/ChangeLanguagePopup.kt @@ -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() + } + } +} diff --git a/app/src/main/kotlin/com/simplemobiletools/keyboard/dialogs/KeyboardRadioGroupDialog.kt b/app/src/main/kotlin/com/simplemobiletools/keyboard/dialogs/KeyboardRadioGroupDialog.kt new file mode 100644 index 0000000..578e501 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/keyboard/dialogs/KeyboardRadioGroupDialog.kt @@ -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, + 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(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(R.id.dialog_radio_holder).apply { + onGlobalLayout { + scrollY = radioGroup.findViewById(selectedItemId).bottom - height + } + } + } + + wasInit = true + } + + private fun itemSelected(checkedId: Int) { + if (wasInit) { + callback(items[checkedId].value) + dialog?.dismiss() + } + } +} diff --git a/app/src/main/kotlin/com/simplemobiletools/keyboard/extensions/Context.kt b/app/src/main/kotlin/com/simplemobiletools/keyboard/extensions/Context.kt index 23451f9..55d9aa9 100644 --- a/app/src/main/kotlin/com/simplemobiletools/keyboard/extensions/Context.kt +++ b/app/src/main/kotlin/com/simplemobiletools/keyboard/extensions/Context.kt @@ -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 { + 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)" + } +} + diff --git a/app/src/main/kotlin/com/simplemobiletools/keyboard/services/SimpleKeyboardIME.kt b/app/src/main/kotlin/com/simplemobiletools/keyboard/services/SimpleKeyboardIME.kt index 877f906..90e960b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/keyboard/services/SimpleKeyboardIME.kt +++ b/app/src/main/kotlin/com/simplemobiletools/keyboard/services/SimpleKeyboardIME.kt @@ -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) { diff --git a/app/src/main/kotlin/com/simplemobiletools/keyboard/views/MyKeyboardView.kt b/app/src/main/kotlin/com/simplemobiletools/keyboard/views/MyKeyboardView.kt index 649726c..a40b9b6 100644 --- a/app/src/main/kotlin/com/simplemobiletools/keyboard/views/MyKeyboardView.kt +++ b/app/src/main/kotlin/com/simplemobiletools/keyboard/views/MyKeyboardView.kt @@ -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(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(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(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(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 } diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 7b1d476..18a3639 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -13,4 +13,11 @@ + +