diff --git a/app/src/main/java/com/osfans/trime/ime/broadcast/EnterKeyLabelModule.kt b/app/src/main/java/com/osfans/trime/ime/broadcast/EnterKeyLabelModule.kt new file mode 100644 index 0000000000..8326beafdb --- /dev/null +++ b/app/src/main/java/com/osfans/trime/ime/broadcast/EnterKeyLabelModule.kt @@ -0,0 +1,88 @@ +/* + * SPDX-FileCopyrightText: 2015 - 2024 Rime community + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.osfans.trime.ime.broadcast + +import android.view.inputmethod.EditorInfo +import com.osfans.trime.data.theme.Theme +import com.osfans.trime.ime.dependency.InputScope +import me.tatarka.inject.annotations.Inject +import splitties.bitflags.hasFlag + +@InputScope +@Inject +class EnterKeyLabelModule( + private val broadcaster: InputBroadcaster, + private val theme: Theme, +) { + companion object { + const val DEFAULT_LABEL = "⏎" + } + + enum class Mode { + ACTION_LABEL_NEVER, + ACTION_LABEL_ONLY, + ACTION_LABEL_PREFERRED, + CUSTOM_PREFERRED, + } + + val mode: Mode = runCatching { Mode.entries[theme.generalStyle.enterLabelMode] }.getOrDefault(Mode.ACTION_LABEL_NEVER) + + var keyLabel: String = DEFAULT_LABEL + private set + + private var actionLabel: String = DEFAULT_LABEL + + private fun labelFromEditorInfo(info: EditorInfo): String { + if (info.imeOptions.hasFlag(EditorInfo.IME_FLAG_NO_ENTER_ACTION)) { + return theme.generalStyle.enterLabel.default + } else { + val action = info.imeOptions and EditorInfo.IME_MASK_ACTION + val actionLabel = info.actionLabel + when (mode) { + Mode.ACTION_LABEL_ONLY -> { + return actionLabel.toString() + } + Mode.ACTION_LABEL_PREFERRED -> { + return if (!actionLabel.isNullOrEmpty()) { + actionLabel.toString() + } else { + theme.generalStyle.enterLabel.default + } + } + Mode.CUSTOM_PREFERRED, + Mode.ACTION_LABEL_NEVER, + -> { + return when (action) { + EditorInfo.IME_ACTION_DONE -> theme.generalStyle.enterLabel.done + EditorInfo.IME_ACTION_GO -> theme.generalStyle.enterLabel.go + EditorInfo.IME_ACTION_NEXT -> theme.generalStyle.enterLabel.next + EditorInfo.IME_ACTION_PREVIOUS -> theme.generalStyle.enterLabel.pre + EditorInfo.IME_ACTION_SEARCH -> theme.generalStyle.enterLabel.search + EditorInfo.IME_ACTION_SEND -> theme.generalStyle.enterLabel.send + else -> { + if (mode == Mode.ACTION_LABEL_NEVER) { + theme.generalStyle.enterLabel.default + } else { + if (!actionLabel.isNullOrEmpty()) { + actionLabel.toString() + } else { + theme.generalStyle.enterLabel.default + } + } + } + } + } + } + } + } + + fun updateLabelOnEditorInfo(info: EditorInfo) { + actionLabel = labelFromEditorInfo(info) + if (keyLabel == actionLabel) return + keyLabel = actionLabel + broadcaster.onEnterKeyLabelUpdate(keyLabel) + } +} diff --git a/app/src/main/java/com/osfans/trime/ime/broadcast/InputBroadcastReceiver.kt b/app/src/main/java/com/osfans/trime/ime/broadcast/InputBroadcastReceiver.kt index cd40a3d59d..894283f80d 100644 --- a/app/src/main/java/com/osfans/trime/ime/broadcast/InputBroadcastReceiver.kt +++ b/app/src/main/java/com/osfans/trime/ime/broadcast/InputBroadcastReceiver.kt @@ -27,4 +27,6 @@ interface InputBroadcastReceiver { fun onWindowAttached(window: BoardWindow) {} fun onWindowDetached(window: BoardWindow) {} + + fun onEnterKeyLabelUpdate(label: String) {} } diff --git a/app/src/main/java/com/osfans/trime/ime/broadcast/InputBroadcaster.kt b/app/src/main/java/com/osfans/trime/ime/broadcast/InputBroadcaster.kt index 10a32f85b7..69085b3cdf 100644 --- a/app/src/main/java/com/osfans/trime/ime/broadcast/InputBroadcaster.kt +++ b/app/src/main/java/com/osfans/trime/ime/broadcast/InputBroadcaster.kt @@ -64,4 +64,8 @@ class InputBroadcaster : InputBroadcastReceiver { override fun onWindowDetached(window: BoardWindow) { receivers.forEach { it.onWindowDetached(window) } } + + override fun onEnterKeyLabelUpdate(label: String) { + receivers.forEach { it.onEnterKeyLabelUpdate(label) } + } } diff --git a/app/src/main/java/com/osfans/trime/ime/core/InputView.kt b/app/src/main/java/com/osfans/trime/ime/core/InputView.kt index 85619cd31c..6eecbeb261 100644 --- a/app/src/main/java/com/osfans/trime/ime/core/InputView.kt +++ b/app/src/main/java/com/osfans/trime/ime/core/InputView.kt @@ -102,6 +102,7 @@ class InputView( private val inputComponent = InputComponent::class.create(this, themedContext, theme, service, rime) private val broadcaster = inputComponent.broadcaster val commonKeyboardActionListener = inputComponent.commonKeyboardActionListener + private val enterKeyLabel = inputComponent.enterKeyLabel private val windowManager = inputComponent.windowManager private val quickBar: QuickBar = inputComponent.quickBar val composition: CompositionPopupWindow = inputComponent.composition @@ -315,10 +316,10 @@ class InputView( } } broadcaster.onStartInput(info) + enterKeyLabel.updateLabelOnEditorInfo(info) if (!restarting) { windowManager.attachWindow(KeyboardWindow) } - keyboardWindow.mainKeyboardView.updateEnterLabelOnEditorInfo(info) } private fun handleRimeNotification(it: RimeNotification<*>) { diff --git a/app/src/main/java/com/osfans/trime/ime/core/TrimeInputMethodService.kt b/app/src/main/java/com/osfans/trime/ime/core/TrimeInputMethodService.kt index 9588946399..b69b67321c 100644 --- a/app/src/main/java/com/osfans/trime/ime/core/TrimeInputMethodService.kt +++ b/app/src/main/java/com/osfans/trime/ime/core/TrimeInputMethodService.kt @@ -106,7 +106,6 @@ open class TrimeInputMethodService : LifecycleInputMethodService() { ColorManager.OnColorChangeListener { lifecycleScope.launch(Dispatchers.Main) { recreateInputView() - currentInputEditorInfo?.let { inputView?.startInput(it) } } } diff --git a/app/src/main/java/com/osfans/trime/ime/dependency/InputComponent.kt b/app/src/main/java/com/osfans/trime/ime/dependency/InputComponent.kt index 5a82c2af73..be1debf8de 100644 --- a/app/src/main/java/com/osfans/trime/ime/dependency/InputComponent.kt +++ b/app/src/main/java/com/osfans/trime/ime/dependency/InputComponent.kt @@ -8,6 +8,7 @@ import android.content.Context import com.osfans.trime.daemon.RimeSession import com.osfans.trime.data.theme.Theme import com.osfans.trime.ime.bar.QuickBar +import com.osfans.trime.ime.broadcast.EnterKeyLabelModule import com.osfans.trime.ime.broadcast.InputBroadcaster import com.osfans.trime.ime.candidates.CompactCandidateModule import com.osfans.trime.ime.composition.CompositionPopupWindow @@ -31,6 +32,7 @@ abstract class InputComponent( ) { abstract val broadcaster: InputBroadcaster abstract val commonKeyboardActionListener: CommonKeyboardActionListener + abstract val enterKeyLabel: EnterKeyLabelModule abstract val quickBar: QuickBar abstract val composition: CompositionPopupWindow abstract val windowManager: BoardWindowManager diff --git a/app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardView.kt b/app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardView.kt index 2c3d47928c..dc6806170a 100644 --- a/app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardView.kt +++ b/app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardView.kt @@ -21,21 +21,18 @@ import android.view.Gravity import android.view.MotionEvent import android.view.View import android.view.ViewGroup -import android.view.inputmethod.EditorInfo import android.widget.PopupWindow import com.osfans.trime.core.Rime import com.osfans.trime.data.prefs.AppPrefs import com.osfans.trime.data.theme.ColorManager import com.osfans.trime.data.theme.FontManager import com.osfans.trime.data.theme.ThemeManager -import com.osfans.trime.data.theme.model.EnterLabel import com.osfans.trime.databinding.KeyboardPopupKeyboardBinding import com.osfans.trime.ime.enums.KeyEventType import com.osfans.trime.util.LeakGuardHandlerWrapper import com.osfans.trime.util.indexOfStateSet import com.osfans.trime.util.sp import com.osfans.trime.util.stateDrawableAt -import splitties.bitflags.hasFlag import splitties.dimensions.dp import splitties.systemservices.layoutInflater import splitties.views.dsl.core.textView @@ -53,20 +50,6 @@ class KeyboardView( context: Context, ) : View(context), View.OnClickListener { - enum class EnterLabelMode { - ACTION_LABEL_NEVER, - ACTION_LABEL_ONLY, - ACTION_LABEL_PREFERRED, - CUSTOM_PREFERRED, - ; - - companion object { - fun fromOrdinal(ordinal: Int) = - runCatching { entries[ordinal] } - .getOrDefault(ACTION_LABEL_NEVER) - } - } - private val theme get() = ThemeManager.activeTheme private var mKeyboard: Keyboard? = null @@ -237,58 +220,10 @@ class KeyboardView( private val mHeadsetRequiredToHearPasswordsAnnounced = false var showKeyHint = !Rime.getOption("_hide_key_hint") var showKeySymbol = !Rime.getOption("_hide_key_symbol") - private lateinit var labelEnter: String - private val mEnterLabels: EnterLabel = theme.generalStyle.enterLabel - private val enterLabelMode = EnterLabelMode.fromOrdinal(theme.generalStyle.enterLabelMode) + private var labelEnter: String = theme.generalStyle.enterLabel.default - private fun handleEnterLabel() { - labelEnter = mEnterLabels.default ?: "⏎" - } - - fun updateEnterLabelOnEditorInfo(info: EditorInfo) { - if (info.imeOptions.hasFlag(EditorInfo.IME_FLAG_NO_ENTER_ACTION)) { - labelEnter = mEnterLabels.default - } else { - val action = info.imeOptions and EditorInfo.IME_MASK_ACTION - val actionLabel = info.actionLabel - when (enterLabelMode) { - EnterLabelMode.ACTION_LABEL_ONLY -> { - labelEnter = actionLabel.toString() - } - EnterLabelMode.ACTION_LABEL_PREFERRED -> { - labelEnter = - if (!actionLabel.isNullOrEmpty()) { - actionLabel.toString() - } else { - mEnterLabels.default - } - } - EnterLabelMode.CUSTOM_PREFERRED, - EnterLabelMode.ACTION_LABEL_NEVER, - -> { - labelEnter = - when (action) { - EditorInfo.IME_ACTION_DONE -> mEnterLabels.done - EditorInfo.IME_ACTION_GO -> mEnterLabels.go - EditorInfo.IME_ACTION_NEXT -> mEnterLabels.next - EditorInfo.IME_ACTION_PREVIOUS -> mEnterLabels.pre - EditorInfo.IME_ACTION_SEARCH -> mEnterLabels.search - EditorInfo.IME_ACTION_SEND -> mEnterLabels.send - else -> { - if (enterLabelMode == EnterLabelMode.ACTION_LABEL_NEVER) { - mEnterLabels.default - } else { - if (!actionLabel.isNullOrEmpty()) { - actionLabel.toString() - } else { - mEnterLabels.default - } - } - } - } - } - } - } + fun onEnterKeyLabelUpdate(label: String) { + labelEnter = label } private val mHandler = MyHandler(this) @@ -317,7 +252,6 @@ class KeyboardView( init { initGestureDetector() - handleEnterLabel() invalidateAllKeys() } diff --git a/app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardWindow.kt b/app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardWindow.kt index 15873b81dd..c43e57e49d 100644 --- a/app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardWindow.kt +++ b/app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardWindow.kt @@ -248,6 +248,10 @@ class KeyboardWindow( mainKeyboardView.invalidateAllKeys() } + override fun onEnterKeyLabelUpdate(label: String) { + mainKeyboardView.onEnterKeyLabelUpdate(label) + } + override fun onAttached() { mainKeyboardView.keyboardActionListener = ListenerDecorator(commonKeyboardActionListener.listener) }