mirror of
https://github.com/florisboard/florisboard.git
synced 2024-09-20 03:52:18 +02:00
Rework ComputingEvaluator
interface and eliminate RenderInfo
This commit is contained in:
parent
5362df02a5
commit
0606afbb64
@ -559,7 +559,7 @@ private fun TextKeyDataPreviewBox(
|
||||
val context = LocalContext.current
|
||||
val evaluator = remember(context) {
|
||||
object : ComputingEvaluator by DefaultComputingEvaluator {
|
||||
val keyboard = object : Keyboard() {
|
||||
override val keyboard = object : Keyboard() {
|
||||
override val mode = KeyboardMode.NUMERIC_ADVANCED
|
||||
override fun getKeyForPos(pointerX: Float, pointerY: Float) = error("not implemented")
|
||||
override fun keys() = error("not implemented")
|
||||
@ -567,7 +567,6 @@ private fun TextKeyDataPreviewBox(
|
||||
extendTouchBoundariesDownwards: Boolean) = error("not implemented")
|
||||
}
|
||||
override fun context() = context
|
||||
override fun keyboard() = keyboard
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,11 +28,15 @@ import dev.patrickgold.florisboard.ime.text.key.KeyType
|
||||
import dev.patrickgold.florisboard.lib.FlorisLocale
|
||||
|
||||
interface ComputingEvaluator {
|
||||
fun activeEditorInfo(): FlorisEditorInfo
|
||||
val version: Int
|
||||
|
||||
fun activeState(): KeyboardState
|
||||
val keyboard: Keyboard
|
||||
|
||||
fun activeSubtype(): Subtype
|
||||
val editorInfo: FlorisEditorInfo
|
||||
|
||||
val state: KeyboardState
|
||||
|
||||
val subtype: Subtype
|
||||
|
||||
fun context(): Context?
|
||||
|
||||
@ -42,19 +46,21 @@ interface ComputingEvaluator {
|
||||
|
||||
fun evaluateVisible(data: KeyData): Boolean
|
||||
|
||||
fun keyboard(): Keyboard
|
||||
|
||||
fun isSlot(data: KeyData): Boolean
|
||||
|
||||
fun slotData(data: KeyData): KeyData?
|
||||
}
|
||||
|
||||
object DefaultComputingEvaluator : ComputingEvaluator {
|
||||
override fun activeEditorInfo(): FlorisEditorInfo = FlorisEditorInfo.Unspecified
|
||||
override val version = -1
|
||||
|
||||
override fun activeState(): KeyboardState = KeyboardState.new()
|
||||
override val keyboard = PlaceholderLoadingKeyboard
|
||||
|
||||
override fun activeSubtype(): Subtype = Subtype.DEFAULT
|
||||
override val editorInfo = FlorisEditorInfo.Unspecified
|
||||
|
||||
override val state = KeyboardState.new()
|
||||
|
||||
override val subtype = Subtype.DEFAULT
|
||||
|
||||
override fun context(): Context? = null
|
||||
|
||||
@ -64,8 +70,6 @@ object DefaultComputingEvaluator : ComputingEvaluator {
|
||||
|
||||
override fun evaluateVisible(data: KeyData): Boolean = true
|
||||
|
||||
override fun keyboard(): Keyboard = PlaceholderLoadingKeyboard
|
||||
|
||||
override fun isSlot(data: KeyData): Boolean = false
|
||||
|
||||
override fun slotData(data: KeyData): KeyData? = null
|
||||
@ -103,8 +107,8 @@ fun ComputingEvaluator.computeLabel(data: KeyData): String? {
|
||||
KeyCode.PHONE_PAUSE -> evaluator.context()?.getString(R.string.key__phone_pause)
|
||||
KeyCode.PHONE_WAIT -> evaluator.context()?.getString(R.string.key__phone_wait)
|
||||
KeyCode.SPACE, KeyCode.CJK_SPACE -> {
|
||||
when (evaluator.keyboard().mode) {
|
||||
KeyboardMode.CHARACTERS -> evaluator.activeSubtype().primaryLocale.let { locale ->
|
||||
when (evaluator.keyboard.mode) {
|
||||
KeyboardMode.CHARACTERS -> evaluator.subtype.primaryLocale.let { locale ->
|
||||
computeLanguageDisplayName(locale, evaluator.displayLanguageNamesIn())
|
||||
}
|
||||
else -> null
|
||||
@ -183,8 +187,8 @@ fun ComputingEvaluator.computeIconResId(data: KeyData): Int? {
|
||||
R.drawable.ic_backspace
|
||||
}
|
||||
KeyCode.ENTER -> {
|
||||
val imeOptions = evaluator.activeEditorInfo().imeOptions
|
||||
val inputAttributes = evaluator.activeEditorInfo().inputAttributes
|
||||
val imeOptions = evaluator.editorInfo.imeOptions
|
||||
val inputAttributes = evaluator.editorInfo.inputAttributes
|
||||
if (imeOptions.flagNoEnterAction || inputAttributes.flagTextMultiLine) {
|
||||
R.drawable.ic_keyboard_return
|
||||
} else {
|
||||
@ -213,13 +217,13 @@ fun ComputingEvaluator.computeIconResId(data: KeyData): Int? {
|
||||
R.drawable.ic_settings
|
||||
}
|
||||
KeyCode.SHIFT -> {
|
||||
when (evaluator.activeState().inputShiftState != InputShiftState.UNSHIFTED) {
|
||||
when (evaluator.state.inputShiftState != InputShiftState.UNSHIFTED) {
|
||||
true -> R.drawable.ic_keyboard_capslock
|
||||
else -> R.drawable.ic_keyboard_arrow_up
|
||||
}
|
||||
}
|
||||
KeyCode.SPACE, KeyCode.CJK_SPACE -> {
|
||||
when (evaluator.keyboard().mode) {
|
||||
when (evaluator.keyboard.mode) {
|
||||
KeyboardMode.NUMERIC,
|
||||
KeyboardMode.NUMERIC_ADVANCED,
|
||||
KeyboardMode.PHONE,
|
||||
@ -236,14 +240,14 @@ fun ComputingEvaluator.computeIconResId(data: KeyData): Int? {
|
||||
R.drawable.ic_redo
|
||||
}
|
||||
KeyCode.KANA_SWITCHER -> {
|
||||
if (evaluator.activeState().isKanaKata) {
|
||||
if (evaluator.state.isKanaKata) {
|
||||
R.drawable.ic_keyboard_kana_switcher_kata
|
||||
} else {
|
||||
R.drawable.ic_keyboard_kana_switcher_hira
|
||||
}
|
||||
}
|
||||
KeyCode.CHAR_WIDTH_SWITCHER -> {
|
||||
if (evaluator.activeState().isCharHalfWidth) {
|
||||
if (evaluator.state.isCharHalfWidth) {
|
||||
R.drawable.ic_keyboard_char_width_switcher_full
|
||||
} else {
|
||||
R.drawable.ic_keyboard_char_width_switcher_half
|
||||
|
@ -130,7 +130,7 @@ class CaseSelector(
|
||||
val upper: AbstractKeyData,
|
||||
) : AbstractKeyData {
|
||||
override fun compute(evaluator: ComputingEvaluator): KeyData? {
|
||||
return (if (evaluator.activeState().isUppercase) { upper } else { lower }).compute(evaluator)
|
||||
return (if (evaluator.state.isUppercase) { upper } else { lower }).compute(evaluator)
|
||||
}
|
||||
|
||||
override fun asString(isForDisplay: Boolean): String {
|
||||
@ -175,7 +175,7 @@ class ShiftStateSelector(
|
||||
val default: AbstractKeyData? = null,
|
||||
) : AbstractKeyData {
|
||||
override fun compute(evaluator: ComputingEvaluator): KeyData? {
|
||||
return when (evaluator.activeState().inputShiftState) {
|
||||
return when (evaluator.state.inputShiftState) {
|
||||
InputShiftState.UNSHIFTED -> unshifted ?: default
|
||||
InputShiftState.SHIFTED_MANUAL -> shiftedManual ?: shifted ?: default
|
||||
InputShiftState.SHIFTED_AUTOMATIC -> shiftedAutomatic ?: shifted ?: default
|
||||
@ -224,7 +224,7 @@ data class VariationSelector(
|
||||
val password: AbstractKeyData? = null,
|
||||
) : AbstractKeyData {
|
||||
override fun compute(evaluator: ComputingEvaluator): KeyData? {
|
||||
return when (evaluator.activeState().keyVariation) {
|
||||
return when (evaluator.state.keyVariation) {
|
||||
KeyVariation.ALL -> default
|
||||
KeyVariation.EMAIL_ADDRESS -> email ?: default
|
||||
KeyVariation.NORMAL -> normal ?: default
|
||||
@ -262,7 +262,7 @@ class LayoutDirectionSelector(
|
||||
val rtl: AbstractKeyData,
|
||||
) : AbstractKeyData {
|
||||
override fun compute(evaluator: ComputingEvaluator): KeyData? {
|
||||
val isRtl = evaluator.activeState().layoutDirection == LayoutDirection.Rtl
|
||||
val isRtl = evaluator.state.layoutDirection == LayoutDirection.Rtl
|
||||
return (if (isRtl) { rtl } else { ltr }).compute(evaluator)
|
||||
}
|
||||
|
||||
@ -294,7 +294,7 @@ class CharWidthSelector(
|
||||
val half: AbstractKeyData?,
|
||||
) : AbstractKeyData {
|
||||
override fun compute(evaluator: ComputingEvaluator): KeyData? {
|
||||
val data = if (evaluator.activeState().isCharHalfWidth) { half } else { full }
|
||||
val data = if (evaluator.state.isCharHalfWidth) { half } else { full }
|
||||
return data?.compute(evaluator)
|
||||
}
|
||||
|
||||
@ -326,7 +326,7 @@ class KanaSelector(
|
||||
val kata: AbstractKeyData,
|
||||
) : AbstractKeyData {
|
||||
override fun compute(evaluator: ComputingEvaluator): KeyData? {
|
||||
val data = if (evaluator.activeState().isKanaKata) { kata } else { hira }
|
||||
val data = if (evaluator.state.isKanaKata) { kata } else { hira }
|
||||
return data.compute(evaluator)
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,46 @@ import dev.patrickgold.florisboard.ime.text.keyboard.TextKey
|
||||
import dev.patrickgold.florisboard.ime.text.keyboard.TextKeyData
|
||||
import dev.patrickgold.florisboard.ime.text.keyboard.TextKeyboard
|
||||
|
||||
/**
|
||||
* Abstract class describing a computed keyboard. The exact implementation is dependent on the subclass and the
|
||||
* structure can vary quite much between different subclasses.
|
||||
*/
|
||||
abstract class Keyboard {
|
||||
/**
|
||||
* The mode of this keyboard, used to let computers and the layout process behave differently based on different
|
||||
* modes.
|
||||
*/
|
||||
abstract val mode: KeyboardMode
|
||||
|
||||
/**
|
||||
* Returns the key for given [pointerX] and [pointerY] coords or null if no key touch hit box is defined at the
|
||||
* given coords.
|
||||
*
|
||||
* @param pointerX The x-coordinate of the input event, absolute within the parent keyboard view.
|
||||
* @param pointerY The y-coordinate of the input event, absolute within the parent keyboard view.
|
||||
*
|
||||
* @return The key for given coords or null if no key touch hit box is defined for this position.
|
||||
*/
|
||||
abstract fun getKeyForPos(pointerX: Float, pointerY: Float): Key?
|
||||
|
||||
/**
|
||||
* Returns an iterator which allows to loop through all keys within the layout, independent of the actual
|
||||
* structure and layout.
|
||||
*/
|
||||
abstract fun keys(): Iterator<Key>
|
||||
|
||||
/**
|
||||
* Layouts the keys according the the dimensions and parameters provided by given arguments. This method's
|
||||
* exact behavior is highly dependent aon the actual subclass.
|
||||
*/
|
||||
abstract fun layout(
|
||||
keyboardWidth: Float,
|
||||
keyboardHeight: Float,
|
||||
desiredKey: Key,
|
||||
extendTouchBoundariesDownwards: Boolean,
|
||||
)
|
||||
}
|
||||
|
||||
val PlaceholderLoadingKeyboard = TextKeyboard(
|
||||
arrangement = arrayOf(
|
||||
arrayOf(
|
||||
@ -72,42 +112,9 @@ val PlaceholderLoadingKeyboard = TextKeyboard(
|
||||
extendedPopupMappingDefault = null,
|
||||
)
|
||||
|
||||
/**
|
||||
* Abstract class describing a computed keyboard. The exact implementation is dependent on the subclass and the
|
||||
* structure can vary quite much between different subclasses.
|
||||
*/
|
||||
abstract class Keyboard {
|
||||
/**
|
||||
* The mode of this keyboard, used to let computers and the layout process behave differently based on different
|
||||
* modes.
|
||||
*/
|
||||
abstract val mode: KeyboardMode
|
||||
|
||||
/**
|
||||
* Returns the key for given [pointerX] and [pointerY] coords or null if no key touch hit box is defined at the
|
||||
* given coords.
|
||||
*
|
||||
* @param pointerX The x-coordinate of the input event, absolute within the parent keyboard view.
|
||||
* @param pointerY The y-coordinate of the input event, absolute within the parent keyboard view.
|
||||
*
|
||||
* @return The key for given coords or null if no key touch hit box is defined for this position.
|
||||
*/
|
||||
abstract fun getKeyForPos(pointerX: Float, pointerY: Float): Key?
|
||||
|
||||
/**
|
||||
* Returns an iterator which allows to loop through all keys within the layout, independent of the actual
|
||||
* structure and layout.
|
||||
*/
|
||||
abstract fun keys(): Iterator<Key>
|
||||
|
||||
/**
|
||||
* Layouts the keys according the the dimensions and parameters provided by given arguments. This method's
|
||||
* exact behavior is highly dependent aon the actual subclass.
|
||||
*/
|
||||
abstract fun layout(
|
||||
keyboardWidth: Float,
|
||||
keyboardHeight: Float,
|
||||
desiredKey: Key,
|
||||
extendTouchBoundariesDownwards: Boolean,
|
||||
)
|
||||
}
|
||||
val SmartbarQuickActionsKeyboard = TextKeyboard(
|
||||
arrangement = emptyArray(),
|
||||
mode = KeyboardMode.SMARTBAR_QUICK_ACTIONS,
|
||||
extendedPopupMapping = null,
|
||||
extendedPopupMappingDefault = null,
|
||||
)
|
||||
|
@ -22,7 +22,6 @@ import android.view.KeyEvent
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.neverEqualPolicy
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import dev.patrickgold.florisboard.FlorisImeService
|
||||
import dev.patrickgold.florisboard.R
|
||||
@ -53,7 +52,6 @@ import dev.patrickgold.florisboard.ime.text.key.KeyCode
|
||||
import dev.patrickgold.florisboard.ime.text.key.KeyType
|
||||
import dev.patrickgold.florisboard.ime.text.key.UtilityKeyAction
|
||||
import dev.patrickgold.florisboard.ime.text.keyboard.TextKeyData
|
||||
import dev.patrickgold.florisboard.ime.text.keyboard.TextKeyboard
|
||||
import dev.patrickgold.florisboard.ime.text.keyboard.TextKeyboardCache
|
||||
import dev.patrickgold.florisboard.lib.android.showShortToast
|
||||
import dev.patrickgold.florisboard.lib.devtools.LogTopic
|
||||
@ -70,18 +68,12 @@ import dev.patrickgold.florisboard.subtypeManager
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
|
||||
data class RenderInfo(
|
||||
val version: Int = 0,
|
||||
val keyboard: TextKeyboard = PlaceholderLoadingKeyboard,
|
||||
val state: KeyboardState = KeyboardState.new(),
|
||||
val evaluator: ComputingEvaluator = DefaultComputingEvaluator,
|
||||
)
|
||||
|
||||
private val DefaultRenderInfo = RenderInfo()
|
||||
private val DoubleSpacePeriodMatcher = """([^.!?‽\s]\s)""".toRegex()
|
||||
|
||||
class KeyboardManager(context: Context) : InputKeyEventReceiver {
|
||||
@ -101,12 +93,12 @@ class KeyboardManager(context: Context) : InputKeyEventReceiver {
|
||||
val smartbarActions = SmartbarActions()
|
||||
val activeState = KeyboardState.new()
|
||||
|
||||
private val renderInfoGuard = Mutex(locked = false)
|
||||
private var renderInfoVersion: Int = 1
|
||||
private val _renderInfo = MutableLiveData(DefaultRenderInfo)
|
||||
val renderInfo: LiveData<RenderInfo> get() = _renderInfo
|
||||
private val _smartbarRenderInfo = MutableLiveData(DefaultRenderInfo)
|
||||
val smartbarRenderInfo: LiveData<RenderInfo> get() = _smartbarRenderInfo
|
||||
private val activeEvaluatorGuard = Mutex(locked = false)
|
||||
private var activeEvaluatorVersion: Int = 1
|
||||
private val _activeEvaluator = MutableStateFlow<ComputingEvaluator>(DefaultComputingEvaluator)
|
||||
val activeEvaluator get() = _activeEvaluator.asStateFlow()
|
||||
private val _activeSmartbarEvaluator = MutableStateFlow<ComputingEvaluator>(DefaultComputingEvaluator)
|
||||
val activeSmartbarEvaluator get() = _activeSmartbarEvaluator.asStateFlow()
|
||||
|
||||
val inputEventDispatcher = InputEventDispatcher.new(
|
||||
repeatableKeyCodes = intArrayOf(
|
||||
@ -121,33 +113,33 @@ class KeyboardManager(context: Context) : InputKeyEventReceiver {
|
||||
|
||||
init {
|
||||
resources.anyChanged.observeForever {
|
||||
updateRenderInfo {
|
||||
updateActiveEvaluators {
|
||||
keyboardCache.clear()
|
||||
}
|
||||
}
|
||||
prefs.keyboard.numberRow.observeForever {
|
||||
updateRenderInfo {
|
||||
updateActiveEvaluators {
|
||||
keyboardCache.clear(KeyboardMode.CHARACTERS)
|
||||
}
|
||||
}
|
||||
prefs.keyboard.hintedNumberRowEnabled.observeForever {
|
||||
updateRenderInfo()
|
||||
updateActiveEvaluators()
|
||||
}
|
||||
prefs.keyboard.hintedSymbolsEnabled.observeForever {
|
||||
updateRenderInfo()
|
||||
updateActiveEvaluators()
|
||||
}
|
||||
prefs.keyboard.utilityKeyEnabled.observeForever {
|
||||
updateRenderInfo()
|
||||
updateActiveEvaluators()
|
||||
}
|
||||
activeState.observeForever {
|
||||
updateRenderInfo()
|
||||
updateActiveEvaluators()
|
||||
}
|
||||
subtypeManager.activeSubtypeFlow.collectLatestIn(scope) {
|
||||
reevaluateInputShiftState()
|
||||
updateRenderInfo()
|
||||
updateActiveEvaluators()
|
||||
}
|
||||
clipboardManager.primaryClipFlow.collectLatestIn(scope) {
|
||||
updateRenderInfo()
|
||||
updateActiveEvaluators()
|
||||
}
|
||||
editorInstance.activeContentFlow.collectIn(scope) { content ->
|
||||
if (!activeState.isComposingEnabled) {
|
||||
@ -158,8 +150,8 @@ class KeyboardManager(context: Context) : InputKeyEventReceiver {
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateRenderInfo(action: () -> Unit = { }) = scope.launch {
|
||||
renderInfoGuard.withLock {
|
||||
private fun updateActiveEvaluators(action: () -> Unit = { }) = scope.launch {
|
||||
activeEvaluatorGuard.withLock {
|
||||
action()
|
||||
val editorInfo = editorInstance.activeInfo
|
||||
val state = activeState.snapshot()
|
||||
@ -176,7 +168,8 @@ class KeyboardManager(context: Context) : InputKeyEventReceiver {
|
||||
subtype = subtype,
|
||||
).await()
|
||||
}.await()
|
||||
val computingEvaluator = KeyboardComputingEvaluator(
|
||||
val computingEvaluator = ComputingEvaluatorImpl(
|
||||
version = activeEvaluatorVersion++,
|
||||
keyboard = computedKeyboard,
|
||||
editorInfo = editorInfo,
|
||||
state = state,
|
||||
@ -186,42 +179,11 @@ class KeyboardManager(context: Context) : InputKeyEventReceiver {
|
||||
key.compute(computingEvaluator)
|
||||
key.computeLabelsAndDrawables(computingEvaluator)
|
||||
}
|
||||
_renderInfo.postValue(RenderInfo(
|
||||
version = renderInfoVersion++,
|
||||
keyboard = computedKeyboard,
|
||||
state = state,
|
||||
evaluator = computingEvaluator,
|
||||
))
|
||||
smartbarClipboardCursorRenderInfo(editorInfo, state)
|
||||
_activeEvaluator.value = computingEvaluator
|
||||
_activeSmartbarEvaluator.value = computingEvaluator.asSmartbarQuickActionsEvaluator()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun smartbarClipboardCursorRenderInfo(editorInfo: FlorisEditorInfo, state: KeyboardState) {
|
||||
val mode = KeyboardMode.SMARTBAR_CLIPBOARD_CURSOR_ROW
|
||||
val subtype = Subtype.DEFAULT
|
||||
val computedKeyboard = keyboardCache.getOrElseAsync(mode, subtype) {
|
||||
layoutManager.computeKeyboardAsync(
|
||||
keyboardMode = mode,
|
||||
subtype = subtype,
|
||||
).await()
|
||||
}.await()
|
||||
val computingEvaluator = KeyboardComputingEvaluator(
|
||||
keyboard = computedKeyboard,
|
||||
editorInfo = editorInfo,
|
||||
state = state,
|
||||
subtype = subtype,
|
||||
)
|
||||
for (key in computedKeyboard.keys()) {
|
||||
key.compute(computingEvaluator)
|
||||
key.computeLabelsAndDrawables(computingEvaluator)
|
||||
}
|
||||
_smartbarRenderInfo.postValue(RenderInfo(
|
||||
keyboard = computedKeyboard,
|
||||
state = state,
|
||||
evaluator = computingEvaluator,
|
||||
))
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun observeActiveState(): State<KeyboardState> {
|
||||
return activeState.observeAsNonNullState(neverEqualPolicy())
|
||||
@ -834,19 +796,14 @@ class KeyboardManager(context: Context) : InputKeyEventReceiver {
|
||||
}
|
||||
}
|
||||
|
||||
private inner class KeyboardComputingEvaluator(
|
||||
val keyboard: Keyboard,
|
||||
val editorInfo: FlorisEditorInfo,
|
||||
val state: KeyboardState,
|
||||
val subtype: Subtype,
|
||||
private inner class ComputingEvaluatorImpl(
|
||||
override val version: Int,
|
||||
override val keyboard: Keyboard,
|
||||
override val editorInfo: FlorisEditorInfo,
|
||||
override val state: KeyboardState,
|
||||
override val subtype: Subtype,
|
||||
) : ComputingEvaluator {
|
||||
|
||||
override fun activeEditorInfo(): FlorisEditorInfo = editorInfo
|
||||
|
||||
override fun activeState(): KeyboardState = state
|
||||
|
||||
override fun activeSubtype(): Subtype = subtype
|
||||
|
||||
override fun context(): Context = appContext
|
||||
|
||||
override fun displayLanguageNamesIn(): DisplayLanguageNamesIn {
|
||||
@ -903,14 +860,22 @@ class KeyboardManager(context: Context) : InputKeyEventReceiver {
|
||||
}
|
||||
}
|
||||
|
||||
override fun keyboard(): Keyboard = keyboard
|
||||
|
||||
override fun isSlot(data: KeyData): Boolean {
|
||||
return CurrencySet.isCurrencySlot(data.code)
|
||||
}
|
||||
|
||||
override fun slotData(data: KeyData): KeyData? {
|
||||
return subtypeManager.getCurrencySet(activeSubtype()).getSlot(data.code)
|
||||
return subtypeManager.getCurrencySet(subtype).getSlot(data.code)
|
||||
}
|
||||
|
||||
fun asSmartbarQuickActionsEvaluator(): ComputingEvaluatorImpl {
|
||||
return ComputingEvaluatorImpl(
|
||||
version = activeEvaluatorVersion,
|
||||
keyboard = SmartbarQuickActionsKeyboard,
|
||||
editorInfo = editorInfo,
|
||||
state = state,
|
||||
subtype = Subtype.DEFAULT,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,8 @@ enum class KeyboardMode(val value: Int) {
|
||||
PHONE(6),
|
||||
PHONE2(7),
|
||||
SMARTBAR_CLIPBOARD_CURSOR_ROW(8),
|
||||
SMARTBAR_NUMBER_ROW(9);
|
||||
SMARTBAR_NUMBER_ROW(9),
|
||||
SMARTBAR_QUICK_ACTIONS(10);
|
||||
|
||||
companion object {
|
||||
fun fromInt(int: Int) = values().firstOrNull { it.value == int } ?: CHARACTERS
|
||||
|
@ -19,6 +19,7 @@ package dev.patrickgold.florisboard.ime.smartbar
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
@ -26,19 +27,18 @@ import androidx.compose.ui.platform.LocalLayoutDirection
|
||||
import androidx.compose.ui.unit.LayoutDirection
|
||||
import dev.patrickgold.florisboard.ime.text.keyboard.TextKeyboardLayout
|
||||
import dev.patrickgold.florisboard.keyboardManager
|
||||
import dev.patrickgold.florisboard.lib.observeAsNonNullState
|
||||
|
||||
@Composable
|
||||
fun SmartbarClipboardCursorRow(modifier: Modifier = Modifier) {
|
||||
val context = LocalContext.current
|
||||
val keyboardManager by context.keyboardManager()
|
||||
|
||||
val renderInfo by keyboardManager.smartbarRenderInfo.observeAsNonNullState()
|
||||
val evaluator by keyboardManager.activeSmartbarEvaluator.collectAsState()
|
||||
|
||||
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Ltr) {
|
||||
TextKeyboardLayout(
|
||||
modifier = modifier.fillMaxSize(),
|
||||
renderInfo = renderInfo,
|
||||
evaluator = evaluator,
|
||||
isSmartbarKeyboard = true,
|
||||
)
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.IconButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
@ -57,7 +58,7 @@ fun QuickActionsRow(modifier: Modifier = Modifier) = with(LocalDensity.current)
|
||||
val keyboardManager by context.keyboardManager()
|
||||
|
||||
val flipToggles by prefs.smartbar.flipToggles.observeAsState()
|
||||
val renderInfo by keyboardManager.renderInfo.observeAsNonNullState()
|
||||
val evaluator by keyboardManager.activeEvaluator.collectAsState()
|
||||
val smartbarActions by keyboardManager.smartbarActions.observeAsNonNullState()
|
||||
|
||||
val buttonStyle = FlorisImeTheme.style.get(FlorisImeUi.SmartbarQuickAction)
|
||||
@ -79,7 +80,7 @@ fun QuickActionsRow(modifier: Modifier = Modifier) = with(LocalDensity.current)
|
||||
MoreButton()
|
||||
}
|
||||
for (smartbarAction in visibleSmartbarActions) {
|
||||
val icon = renderInfo.evaluator.computeIconResId(smartbarAction.data)
|
||||
val icon = evaluator.computeIconResId(smartbarAction.data)
|
||||
IconButton(
|
||||
modifier = Modifier
|
||||
.padding(SmartbarActionPadding)
|
||||
|
@ -21,6 +21,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.wrapContentHeight
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
@ -29,7 +30,6 @@ import androidx.compose.ui.unit.LayoutDirection
|
||||
import dev.patrickgold.florisboard.ime.text.keyboard.TextKeyboardLayout
|
||||
import dev.patrickgold.florisboard.ime.smartbar.Smartbar
|
||||
import dev.patrickgold.florisboard.keyboardManager
|
||||
import dev.patrickgold.florisboard.lib.observeAsNonNullState
|
||||
|
||||
@Composable
|
||||
fun TextInputLayout(
|
||||
@ -38,7 +38,7 @@ fun TextInputLayout(
|
||||
val context = LocalContext.current
|
||||
val keyboardManager by context.keyboardManager()
|
||||
|
||||
val renderInfo by keyboardManager.renderInfo.observeAsNonNullState()
|
||||
val evaluator by keyboardManager.activeEvaluator.collectAsState()
|
||||
|
||||
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Ltr) {
|
||||
Column(
|
||||
@ -47,9 +47,7 @@ fun TextInputLayout(
|
||||
.wrapContentHeight(),
|
||||
) {
|
||||
Smartbar()
|
||||
TextKeyboardLayout(
|
||||
renderInfo = renderInfo,
|
||||
)
|
||||
TextKeyboardLayout(evaluator = evaluator)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ class TextKey(override val data: AbstractKeyData) : Key(data) {
|
||||
var computedDataOnDown: KeyData = TextKeyData.UNSPECIFIED
|
||||
|
||||
fun compute(evaluator: ComputingEvaluator) {
|
||||
val keyboard = evaluator.keyboard() as? TextKeyboard ?: return
|
||||
val keyboard = evaluator.keyboard as? TextKeyboard ?: return
|
||||
val keyboardMode = keyboard.mode
|
||||
val computed = data.compute(evaluator)
|
||||
|
||||
@ -63,7 +63,7 @@ class TextKey(override val data: AbstractKeyData) : Key(data) {
|
||||
mergePopups(computed, evaluator, computedPopups::merge)
|
||||
if (keyboardMode == KeyboardMode.CHARACTERS || keyboardMode == KeyboardMode.NUMERIC_ADVANCED ||
|
||||
keyboardMode == KeyboardMode.SYMBOLS || keyboardMode == KeyboardMode.SYMBOLS2) {
|
||||
val computedLabel = computed.label.lowercase(evaluator.activeSubtype().primaryLocale)
|
||||
val computedLabel = computed.label.lowercase(evaluator.subtype.primaryLocale)
|
||||
val extLabel = when (computed.groupId) {
|
||||
KeyData.GROUP_ENTER -> {
|
||||
"~enter"
|
||||
@ -84,7 +84,7 @@ class TextKey(override val data: AbstractKeyData) : Key(data) {
|
||||
val extendedPopupsDefault = keyboard.extendedPopupMappingDefault
|
||||
val extendedPopups = keyboard.extendedPopupMapping
|
||||
var popupSet: PopupSet<AbstractKeyData>? = null
|
||||
val kv = evaluator.activeState().keyVariation
|
||||
val kv = evaluator.state.keyVariation
|
||||
if (popupSet == null && kv == KeyVariation.PASSWORD) {
|
||||
popupSet = extendedPopups?.get(KeyVariation.PASSWORD)?.get(extLabel) ?:
|
||||
extendedPopupsDefault?.get(KeyVariation.PASSWORD)?.get(extLabel)
|
||||
@ -231,7 +231,7 @@ class TextKey(override val data: AbstractKeyData) : Key(data) {
|
||||
foregroundDrawableId = evaluator.computeIconResId(computedData)
|
||||
|
||||
val data = computedData
|
||||
if (data.type == KeyType.NUMERIC && evaluator.keyboard().mode == KeyboardMode.PHONE) {
|
||||
if (data.type == KeyType.NUMERIC && evaluator.keyboard.mode == KeyboardMode.PHONE) {
|
||||
hintedLabel = when (data.code) {
|
||||
48 /* 0 */ -> "+"
|
||||
49 /* 1 */ -> ""
|
||||
|
@ -504,8 +504,8 @@ class AutoTextKeyData(
|
||||
TextKeyData(type, data.code, data.label, groupId, popup)
|
||||
}
|
||||
} else {
|
||||
state.recomputeIfNecessary(evaluator.activeSubtype().primaryLocale)
|
||||
if (evaluator.activeState().isUppercase) { state.upper } else { state.lower }
|
||||
state.recomputeIfNecessary(evaluator.subtype.primaryLocale)
|
||||
if (evaluator.state.isUppercase) { state.upper } else { state.lower }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,9 +65,9 @@ import dev.patrickgold.florisboard.app.florisPreferenceModel
|
||||
import dev.patrickgold.florisboard.editorInstance
|
||||
import dev.patrickgold.florisboard.glideTypingManager
|
||||
import dev.patrickgold.florisboard.ime.input.InputEventDispatcher
|
||||
import dev.patrickgold.florisboard.ime.keyboard.ComputingEvaluator
|
||||
import dev.patrickgold.florisboard.ime.keyboard.FlorisImeSizing
|
||||
import dev.patrickgold.florisboard.ime.keyboard.KeyboardMode
|
||||
import dev.patrickgold.florisboard.ime.keyboard.RenderInfo
|
||||
import dev.patrickgold.florisboard.ime.popup.ExceptionsForKeyCodes
|
||||
import dev.patrickgold.florisboard.ime.popup.PopupUiController
|
||||
import dev.patrickgold.florisboard.ime.popup.rememberPopupUiController
|
||||
@ -105,7 +105,7 @@ import kotlin.math.sqrt
|
||||
@Composable
|
||||
fun TextKeyboardLayout(
|
||||
modifier: Modifier = Modifier,
|
||||
renderInfo: RenderInfo,
|
||||
evaluator: ComputingEvaluator,
|
||||
isPreview: Boolean = false,
|
||||
isSmartbarKeyboard: Boolean = false,
|
||||
): Unit = with(LocalDensity.current) {
|
||||
@ -114,7 +114,7 @@ fun TextKeyboardLayout(
|
||||
val configuration = LocalConfiguration.current
|
||||
val glideTypingManager by context.glideTypingManager()
|
||||
|
||||
val keyboard = renderInfo.keyboard
|
||||
val keyboard = evaluator.keyboard as TextKeyboard
|
||||
val numberRowEnabled by prefs.keyboard.numberRow.observeAsTransformingState { numberRowEnabled ->
|
||||
when (keyboard.mode) {
|
||||
KeyboardMode.CHARACTERS,
|
||||
@ -125,8 +125,8 @@ fun TextKeyboardLayout(
|
||||
}
|
||||
}
|
||||
val glideEnabledInternal by prefs.glide.enabled.observeAsState()
|
||||
val glideEnabled = glideEnabledInternal && renderInfo.evaluator.activeEditorInfo().isRichInputEditor &&
|
||||
renderInfo.evaluator.activeState().keyVariation != KeyVariation.PASSWORD
|
||||
val glideEnabled = glideEnabledInternal && evaluator.editorInfo.isRichInputEditor &&
|
||||
evaluator.state.keyVariation != KeyVariation.PASSWORD
|
||||
val glideShowTrail by prefs.glide.showTrail.observeAsState()
|
||||
val glideTrailColor = FlorisImeTheme.style.get(element = FlorisImeUi.GlideTrail)
|
||||
.foreground.solidColor(default = Color.Green)
|
||||
@ -302,14 +302,14 @@ fun TextKeyboardLayout(
|
||||
}
|
||||
},
|
||||
)
|
||||
popupUiController.evaluator = renderInfo.evaluator
|
||||
popupUiController.evaluator = evaluator
|
||||
popupUiController.fontSizeMultiplier = fontSizeMultiplier
|
||||
popupUiController.keyHintConfiguration = prefs.keyboard.keyHintConfiguration()
|
||||
controller.popupUiController = popupUiController
|
||||
val debugShowTouchBoundaries by prefs.devtools.showKeyTouchBoundaries.observeAsState()
|
||||
for (textKey in keyboard.keys()) {
|
||||
TextKeyButton(
|
||||
textKey, renderInfo, fontSizeMultiplier, isSmartbarKeyboard,
|
||||
textKey, evaluator, fontSizeMultiplier, isSmartbarKeyboard,
|
||||
debugShowTouchBoundaries,
|
||||
)
|
||||
}
|
||||
@ -329,7 +329,7 @@ fun TextKeyboardLayout(
|
||||
@Composable
|
||||
private fun TextKeyButton(
|
||||
key: TextKey,
|
||||
renderInfo: RenderInfo,
|
||||
evaluator: ComputingEvaluator,
|
||||
fontSizeMultiplier: Float,
|
||||
isSmartbarKey: Boolean,
|
||||
debugShowTouchBoundaries: Boolean,
|
||||
@ -337,7 +337,7 @@ private fun TextKeyButton(
|
||||
val keyStyle = FlorisImeTheme.style.get(
|
||||
element = if (isSmartbarKey) FlorisImeUi.SmartbarKey else FlorisImeUi.Key,
|
||||
code = key.computedData.code,
|
||||
mode = renderInfo.state.inputShiftState.value,
|
||||
mode = evaluator.state.inputShiftState.value,
|
||||
isPressed = key.isPressed && key.isEnabled,
|
||||
isDisabled = !key.isEnabled,
|
||||
)
|
||||
@ -371,7 +371,7 @@ private fun TextKeyButton(
|
||||
style = keyStyle,
|
||||
clip = false,
|
||||
) { }
|
||||
val isTelpadKey = key.computedData.type == KeyType.NUMERIC && renderInfo.keyboard.mode == KeyboardMode.PHONE
|
||||
val isTelpadKey = key.computedData.type == KeyType.NUMERIC && evaluator.keyboard.mode == KeyboardMode.PHONE
|
||||
key.label?.let { label ->
|
||||
if (key.computedData.code == KeyCode.SPACE) {
|
||||
val prefs by florisPreferenceModel()
|
||||
@ -399,7 +399,7 @@ private fun TextKeyButton(
|
||||
val keyHintStyle = FlorisImeTheme.style.get(
|
||||
element = FlorisImeUi.KeyHint,
|
||||
code = key.computedHintData.code,
|
||||
mode = renderInfo.state.inputShiftState.value,
|
||||
mode = evaluator.state.inputShiftState.value,
|
||||
isPressed = key.isPressed,
|
||||
)
|
||||
val hintFontSize = keyHintStyle.fontSize.spSize() safeTimes fontSizeMultiplier
|
||||
|
@ -14,7 +14,7 @@ androidx-navigation = "2.5.1"
|
||||
androidx-profileinstaller = "1.2.0"
|
||||
androidx-room = "2.4.3"
|
||||
cache4k = "0.7.0"
|
||||
jetpref = "main-SNAPSHOT"#"0.1.0-beta13"
|
||||
jetpref = "8d9d5fc2c334c7e62b7aaeab1103ab681857d695"#"0.1.0-beta13"
|
||||
kotlin = "1.7.10"
|
||||
kotlinx-coroutines = "1.6.3"
|
||||
kotlinx-serialization-json = "1.3.3"
|
||||
|
Loading…
Reference in New Issue
Block a user