diff --git a/app/src/main/java/com/osfans/trime/ime/bar/QuickBar.kt b/app/src/main/java/com/osfans/trime/ime/bar/QuickBar.kt index d77cbc159d..0da8ac5e3c 100644 --- a/app/src/main/java/com/osfans/trime/ime/bar/QuickBar.kt +++ b/app/src/main/java/com/osfans/trime/ime/bar/QuickBar.kt @@ -6,9 +6,11 @@ import android.view.LayoutInflater import android.view.View import android.widget.ViewAnimator import com.osfans.trime.core.Rime +import com.osfans.trime.core.RimeNotification.OptionNotification import com.osfans.trime.data.theme.ColorManager import com.osfans.trime.databinding.CandidateBarBinding import com.osfans.trime.databinding.TabBarBinding +import com.osfans.trime.ime.broadcast.InputBroadcastReceiver import com.osfans.trime.ime.core.TrimeInputMethodService import com.osfans.trime.ime.dependency.InputScope import com.osfans.trime.ime.enums.SymbolKeyboardType @@ -19,7 +21,7 @@ import splitties.views.dsl.core.matchParent @InputScope @Inject -class QuickBar(context: Context, service: TrimeInputMethodService) { +class QuickBar(context: Context, service: TrimeInputMethodService) : InputBroadcastReceiver { val oldCandidateBar by lazy { CandidateBarBinding.inflate(LayoutInflater.from(context)).apply { with(root) { @@ -72,4 +74,15 @@ class QuickBar(context: Context, service: TrimeInputMethodService) { add(oldTabBar.root, lParams(matchParent, matchParent)) } } + + override fun onRimeOptionUpdated(value: OptionNotification.Value) { + when (value.option) { + "_hide_comment" -> { + oldCandidateBar.candidates.shouldShowComment = !value.value + } + "_hide_candidate", "_hide_bar" -> { + view.visibility = if (value.value) View.GONE else View.VISIBLE + } + } + } } 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 new file mode 100644 index 0000000000..8d1d7d92c9 --- /dev/null +++ b/app/src/main/java/com/osfans/trime/ime/broadcast/InputBroadcastReceiver.kt @@ -0,0 +1,7 @@ +package com.osfans.trime.ime.broadcast + +import com.osfans.trime.core.RimeNotification.OptionNotification + +interface InputBroadcastReceiver { + fun onRimeOptionUpdated(value: OptionNotification.Value) {} +} 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 new file mode 100644 index 0000000000..6e7f870eb3 --- /dev/null +++ b/app/src/main/java/com/osfans/trime/ime/broadcast/InputBroadcaster.kt @@ -0,0 +1,30 @@ +package com.osfans.trime.ime.broadcast + +import com.osfans.trime.core.RimeNotification.OptionNotification +import com.osfans.trime.ime.dependency.InputScope +import java.util.concurrent.ConcurrentLinkedQueue + +@InputScope +class InputBroadcaster : InputBroadcastReceiver { + private val receivers = ConcurrentLinkedQueue() + + fun addReceiver(receiver: T) { + if (receiver is InputBroadcastReceiver && receiver !is InputBroadcaster) { + receivers.add(receiver) + } + } + + fun removeReceiver(receiver: T) { + if (receiver is InputBroadcastReceiver && receiver !is InputBroadcaster) { + receivers.remove(receiver) + } + } + + fun clear() { + receivers.clear() + } + + override fun onRimeOptionUpdated(value: OptionNotification.Value) { + receivers.forEach { it.onRimeOptionUpdated(value) } + } +} 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 3bb62a28a0..3aa102cdc6 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 @@ -21,6 +21,7 @@ import com.osfans.trime.core.RimeNotification import com.osfans.trime.data.theme.ColorManager import com.osfans.trime.data.theme.ThemeManager import com.osfans.trime.ime.bar.QuickBar +import com.osfans.trime.ime.broadcast.InputBroadcaster import com.osfans.trime.ime.dependency.InputComponent import com.osfans.trime.ime.dependency.create import com.osfans.trime.ime.keyboard.KeyboardWindow @@ -86,12 +87,19 @@ class InputView( private val notificationHandlerJob: Job private val themedContext = context.withTheme(android.R.style.Theme_DeviceDefault_Settings) - private val inputComponent = InputComponent::class.create(themedContext, theme, service) + private val broadcaster = InputBroadcaster() + private val inputComponent = InputComponent::class.create(themedContext, theme, service, broadcaster) private val windowManager = inputComponent.windowManager val quickBar: QuickBar = inputComponent.quickBar val keyboardWindow: KeyboardWindow = inputComponent.keyboardWindow val liquidKeyboard: LiquidKeyboard = inputComponent.liquidKeyboard + private fun addBroadcastReceivers() { + broadcaster.addReceiver(quickBar) + broadcaster.addReceiver(keyboardWindow) + broadcaster.addReceiver(liquidKeyboard) + } + private val keyboardSidePadding = theme.style.getInt("keyboard_padding") private val keyboardSidePaddingLandscape = theme.style.getInt("keyboard_padding_land") private val keyboardBottomPadding = theme.style.getInt("keyboard_padding_bottom") @@ -120,6 +128,8 @@ class InputView( val keyboardView: View init { + addBroadcastReceivers() + notificationHandlerJob = service.lifecycleScope.launch { rime.notificationFlow.collect { @@ -283,20 +293,7 @@ class InputView( private fun handleRimeNotification(it: RimeNotification<*>) { when (it) { is RimeNotification.OptionNotification -> { - when (it.value.option) { - "_hide_comment" -> { - quickBar.oldCandidateBar.candidates.shouldShowComment = !it.value.value - } - "_hide_bar", - "_hide_candidate", - -> { - quickBar.view.visibility = - if (it.value.value) View.GONE else View.VISIBLE - } - "_hide_key_hint" -> keyboardWindow.oldMainInputView.mainKeyboardView.showKeyHint = !it.value.value - "_hide_key_symbol" -> keyboardWindow.oldMainInputView.mainKeyboardView.showKeySymbol = !it.value.value - } - keyboardWindow.oldMainInputView.mainKeyboardView.invalidateAllKeys() + broadcaster.onRimeOptionUpdated(it.value) } else -> {} } @@ -347,9 +344,10 @@ class InputView( override fun onDetachedFromWindow() { ViewCompat.setOnApplyWindowInsetsListener(this, null) showingDialog?.dismiss() - // cancel the notification job, + // cancel the notification job and clear all broadcast receivers, // implies that InputView should not be attached again after detached. notificationHandlerJob.cancel() + broadcaster.clear() super.onDetachedFromWindow() } } 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 66e0d98830..759222ae5c 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 @@ -3,6 +3,7 @@ package com.osfans.trime.ime.dependency import android.content.Context import com.osfans.trime.data.theme.Theme import com.osfans.trime.ime.bar.QuickBar +import com.osfans.trime.ime.broadcast.InputBroadcaster import com.osfans.trime.ime.core.TrimeInputMethodService import com.osfans.trime.ime.keyboard.KeyboardWindow import com.osfans.trime.ime.symbol.LiquidKeyboard @@ -16,6 +17,7 @@ abstract class InputComponent( @get:InputScope @get:Provides val themedContext: Context, @get:InputScope @get:Provides val theme: Theme, @get:InputScope @get:Provides val service: TrimeInputMethodService, + @get:InputScope @get:Provides val broadcaster: InputBroadcaster, ) { abstract val quickBar: QuickBar abstract val windowManager: BoardWindowManager 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 aaa8bbcb24..2fe0cdd4a8 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 @@ -3,7 +3,9 @@ package com.osfans.trime.ime.keyboard import android.content.Context import android.view.LayoutInflater import android.view.View +import com.osfans.trime.core.RimeNotification.OptionNotification import com.osfans.trime.databinding.MainInputLayoutBinding +import com.osfans.trime.ime.broadcast.InputBroadcastReceiver import com.osfans.trime.ime.core.TrimeInputMethodService import com.osfans.trime.ime.dependency.InputScope import com.osfans.trime.ime.window.BoardWindow @@ -12,7 +14,10 @@ import me.tatarka.inject.annotations.Inject @InputScope @Inject -class KeyboardWindow(context: Context, private val service: TrimeInputMethodService) : BoardWindow.NoBarBoardWindow(), ResidentWindow { +class KeyboardWindow( + context: Context, + private val service: TrimeInputMethodService, +) : BoardWindow.NoBarBoardWindow(), ResidentWindow, InputBroadcastReceiver { val oldMainInputView by lazy { MainInputLayoutBinding.inflate(LayoutInflater.from(context)) } @@ -26,6 +31,14 @@ class KeyboardWindow(context: Context, private val service: TrimeInputMethodServ return oldMainInputView.root } + override fun onRimeOptionUpdated(value: OptionNotification.Value) { + when (value.option) { + "_hide_key_hint" -> oldMainInputView.mainKeyboardView.showKeyHint = !value.value + "_hide_key_symbol" -> oldMainInputView.mainKeyboardView.showKeySymbol = !value.value + } + oldMainInputView.mainKeyboardView.invalidateAllKeys() + } + override fun onAttached() { oldMainInputView.mainKeyboardView.onKeyboardActionListener = service.textInputManager } diff --git a/app/src/main/java/com/osfans/trime/ime/window/BoardWindowManager.kt b/app/src/main/java/com/osfans/trime/ime/window/BoardWindowManager.kt index 7cd3e3a074..302ff54367 100644 --- a/app/src/main/java/com/osfans/trime/ime/window/BoardWindowManager.kt +++ b/app/src/main/java/com/osfans/trime/ime/window/BoardWindowManager.kt @@ -3,6 +3,7 @@ package com.osfans.trime.ime.window import android.content.Context import android.view.View import android.widget.FrameLayout +import com.osfans.trime.ime.broadcast.InputBroadcaster import com.osfans.trime.ime.dependency.InputScope import me.tatarka.inject.annotations.Inject import splitties.views.dsl.core.add @@ -15,6 +16,7 @@ import timber.log.Timber @Inject class BoardWindowManager( private val context: Context, + private val broadcaster: InputBroadcaster, ) { private val cachedResidentWindows = mutableMapOf>() @@ -52,6 +54,7 @@ class BoardWindowManager( cachedResidentWindows[window.key]?.second ?: window.onCreateView() .also { cachedResidentWindows[window.key] = window to it } } else { + broadcaster.addReceiver(window) window.onCreateView() } if (currentWindow != null) { @@ -60,6 +63,9 @@ class BoardWindowManager( oldWindow.onDetached() view.removeView(oldView) Timber.d("Detach $oldWindow") + if (oldWindow !is ResidentWindow) { + broadcaster.removeReceiver(oldWindow) + } } if (window is ResidentWindow) { window.beforeAttached()