Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor for Candidats Windows and more #1567

Merged
merged 14 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions app/src/main/java/com/osfans/trime/core/Rime.kt
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ class Rime :
deleteRimeCandidateOnCurrentPage(idx).also { if (it) requireResponse() }
}

override suspend fun changeCandidatePage(backward: Boolean): Boolean =
withRimeContext {
changeRimeCandidatePage(backward).also { if (it) requireResponse() }
}

override suspend fun moveCursorPos(position: Int) =
withRimeContext {
setRimeCaretPos(position)
Expand Down Expand Up @@ -373,6 +378,9 @@ class Rime :
@JvmStatic
external fun forgetRimeCandidate(index: Int): Boolean

@JvmStatic
external fun changeRimeCandidatePage(backward: Boolean): Boolean

@JvmStatic
external fun getAvailableRimeSchemaList(): Array<SchemaItem>

Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/com/osfans/trime/core/RimeApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ interface RimeApi {

suspend fun deletedPagedCandidate(idx: Int): Boolean

suspend fun changeCandidatePage(backward: Boolean): Boolean

suspend fun moveCursorPos(position: Int)

suspend fun availableSchemata(): Array<SchemaItem>
Expand Down
18 changes: 10 additions & 8 deletions app/src/main/java/com/osfans/trime/data/prefs/AppPrefs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,10 @@ class AppPrefs(
companion object {
const val SOFT_CURSOR_ENABLED = "keyboard__soft_cursor"
const val POPUP_KEY_PRESS_ENABLED = "keyboard__show_key_popup"
const val SWITCHES_ENABLED = "keyboard__show_switches"
const val SHOW_SCHEMA_SWITCHES = "show_schema_switches_in_idle"
const val SHOW_ARROW_IN_SWITCHES = "show_arrow_in_switches"
const val LANDSCAPE_MODE = "keyboard__landscape_mode"
const val SPLIT_SPACE_PERCENT = "keyboard__split_space"
const val SWITCH_ARROW_ENABLED = "keyboard__show_switch_arrow"

const val HOOK_CTRL_A = "keyboard__hook_ctrl_a"
const val HOOK_CTRL_CV = "keyboard__hook_ctrl_cv"
Expand Down Expand Up @@ -146,8 +146,8 @@ class AppPrefs(

val softCursorEnabled by bool(SOFT_CURSOR_ENABLED, true)
val popupKeyPressEnabled = bool(POPUP_KEY_PRESS_ENABLED, false)
val switchesEnabled = bool(SWITCHES_ENABLED, true)
val switchArrowEnabled = bool(SWITCH_ARROW_ENABLED, true)
val showSchemaSwitches = bool(SHOW_SCHEMA_SWITCHES, true)
val showArrowInSwitches = bool(SHOW_ARROW_IN_SWITCHES, true)

enum class LandscapeModeOption {
NEVER,
Expand Down Expand Up @@ -188,12 +188,14 @@ class AppPrefs(
shared: SharedPreferences,
) : PreferenceDelegateOwner(shared, R.string.candidates_window) {
companion object {
const val MODE = "candidates__mode"
const val POSITION = "candidates__position"
const val MODE = "show_candidates_window"
const val POSITION = "candidates_window_position"
const val HIDE_QUICK_BAR = "hide_quick_bar"
}

val mode = enum(R.string.candidates_mode, MODE, PopupCandidatesMode.DISABLED)
val position = enum(R.string.display_position, POSITION, PopupPosition.BOTTOM_LEFT)
val mode = enum(R.string.show_candidates_window, MODE, PopupCandidatesMode.DISABLED)
val position = enum(R.string.candidates_window_position, POSITION, PopupPosition.BOTTOM_LEFT)
val hideQuickBar = switch(R.string.hide_quick_bar_when_always_show, HIDE_QUICK_BAR, false)
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,22 @@ abstract class PreferenceDelegateOwner(
},
)

protected fun switch(
@StringRes
title: Int,
key: String,
defaultValue: Boolean,
@StringRes
summary: Int? = null,
enableUiOn: (() -> Boolean)? = null,
): PreferenceDelegate<Boolean> {
val pref = PreferenceDelegate(sharedPreferences, key, defaultValue)
val ui = PreferenceDelegateUi.Switch(title, key, defaultValue, summary, enableUiOn)
pref.register()
ui.registerUi()
return pref
}

// TODO: replace all [enum] with this
protected inline fun <reified T> enum(
@StringRes title: Int,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import android.content.Context
import androidx.annotation.StringRes
import androidx.preference.ListPreference
import androidx.preference.Preference
import androidx.preference.SwitchPreference

abstract class PreferenceDelegateUi<T : Preference>(
val key: String,
Expand All @@ -17,6 +18,28 @@ abstract class PreferenceDelegateUi<T : Preference>(

fun isEnabled() = enableUiOn?.invoke() ?: true

class Switch(
@StringRes
val title: Int,
key: String,
val defaultValue: Boolean,
@StringRes
val summary: Int? = null,
enableUiOn: (() -> Boolean)? = null,
) : PreferenceDelegateUi<SwitchPreference>(key, enableUiOn) {
override fun createUi(context: Context) =
SwitchPreference(context).apply {
key = [email protected]
isIconSpaceReserved = false
isSingleLineTitle = false
setDefaultValue(defaultValue)
if ([email protected] != null) {
setSummary([email protected])
}
setTitle([email protected])
}
}

class StringList<T : Any>(
@StringRes
val title: Int,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,12 @@
package com.osfans.trime.data.schema

import com.osfans.trime.core.Rime
import com.osfans.trime.data.prefs.AppPrefs
import kotlinx.serialization.builtins.ListSerializer

object SchemaManager {
private lateinit var currentSchema: Schema
var visibleSwitches: List<Schema.Switch> = listOf()

private val arrow get() = AppPrefs.defaultInstance().keyboard.switchArrowEnabled

private val defaultSchema = Schema()

@JvmStatic
Expand Down
49 changes: 20 additions & 29 deletions app/src/main/java/com/osfans/trime/data/theme/ColorManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

package com.osfans.trime.data.theme

import android.content.Context
import android.content.res.Configuration
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
Expand All @@ -15,10 +14,8 @@ import com.osfans.trime.data.prefs.AppPrefs
import com.osfans.trime.data.sound.SoundEffectManager
import com.osfans.trime.util.ColorUtils
import com.osfans.trime.util.WeakHashSet
import com.osfans.trime.util.appContext
import com.osfans.trime.util.bitmapDrawable
import com.osfans.trime.util.isNightMode
import splitties.dimensions.dp
import timber.log.Timber
import java.io.File

Expand Down Expand Up @@ -345,36 +342,30 @@ object ColorManager {
}
}

// 返回图片或背景的drawable,支持null参数。 Config 2.0
fun getDrawable(
context: Context = appContext,
key: String,
border: Int = 0,
borderColorKey: String = "",
roundCorner: Float = 0f,
colorKey: String,
borderColorKey: String? = null,
borderPx: Int = 0,
cornerRadius: Float = 0f,
alpha: Int = 255,
): Drawable? {
val value = getColorValue(key)
if (value is Drawable) {
value.alpha = MathUtils.clamp(alpha, 0, 255)
return value
}

if (value is Int) {
val gradient = GradientDrawable().apply { setColor(value) }
if (roundCorner > 0) {
gradient.cornerRadius = roundCorner
): Drawable? =
when (val value = getColorValue(colorKey)) {
is Drawable -> {
value.also { it.alpha = MathUtils.clamp(alpha, 0, 255) }
}
if (borderColorKey.isNotEmpty() && border > 0) {
val borderPx = context.dp(border)
val stroke = getColor(borderColorKey)
if (stroke != null && borderPx > 0) {
gradient.setStroke(borderPx, stroke)
is Int -> {
GradientDrawable().apply {
setColor(value)
this.cornerRadius = cornerRadius
this.alpha = MathUtils.clamp(alpha, 0, 255)
if (!borderColorKey.isNullOrEmpty()) {
val borderColor = getColor(borderColorKey)
if (borderColor != null) {
setStroke(borderPx, borderColor)
}
}
}
}
gradient.alpha = MathUtils.clamp(alpha, 0, 255)
return gradient
else -> null
}
return null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class LayoutStyleMapper(

val roundCorner = getFloat("round_corner")

val alpha = getFloat("alpha", 0.8f)
val alpha = getInt("alpha", 204)
val elevation = getInt("elevation")
val movable = getString("movable")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ data class Layout(
val realMargin: Int,
val spacing: Int,
val roundCorner: Float,
val alpha: Float,
val alpha: Int,
val elevation: Int,
val movable: String,
)
24 changes: 10 additions & 14 deletions app/src/main/java/com/osfans/trime/ime/bar/QuickBar.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import com.osfans.trime.ime.window.BoardWindow
import com.osfans.trime.ime.window.BoardWindowManager
import kotlinx.coroutines.launch
import me.tatarka.inject.annotations.Inject
import splitties.dimensions.dp
import splitties.views.dsl.core.add
import splitties.views.dsl.core.lParams
import splitties.views.dsl.core.matchParent
Expand All @@ -52,15 +53,16 @@ class QuickBar(

private val prefs = AppPrefs.defaultInstance()

private val showSwitchers by prefs.keyboard.switchesEnabled
private val showSwitches by prefs.keyboard.showSchemaSwitches
private val hideQuickBar by prefs.candidates.hideQuickBar

val themedHeight =
theme.generalStyle.candidateViewHeight + theme.generalStyle.commentHeight

private fun evalAlwaysUiState() {
val newState =
when {
showSwitchers -> AlwaysUi.State.Switchers
showSwitches -> AlwaysUi.State.Switches
else -> AlwaysUi.State.Empty
}
if (newState == alwaysUi.currentState) return
Expand Down Expand Up @@ -159,7 +161,7 @@ class QuickBar(

override fun onInputContextUpdate(ctx: RimeProto.Context) {
// TODO: 临时修复状态栏与悬浮窗同时显示,后续需优化:考虑分离数据或寻找更好的实现方式
if (candidatesMode == PopupCandidatesMode.FORCE_SHOW) return
if (candidatesMode == PopupCandidatesMode.ALWAYS_SHOW) return

barStateMachine.push(
QuickBarStateMachine.TransitionEvent.CandidatesUpdated,
Expand All @@ -181,21 +183,18 @@ class QuickBar(
ViewAnimator(context).apply {
rime.launchOnReady {
visibility =
if (it.getRuntimeOption("_hide_candidate") ||
it.getRuntimeOption("_hide_bar")
) {
if (hideQuickBar && candidatesMode == PopupCandidatesMode.ALWAYS_SHOW) {
View.GONE
} else {
View.VISIBLE
}
}
background =
ColorManager.getDrawable(
context,
"candidate_background",
theme.generalStyle.candidateBorder,
"candidate_border_color",
theme.generalStyle.candidateBorderRound,
dp(theme.generalStyle.candidateBorder),
dp(theme.generalStyle.candidateBorderRound),
)
add(alwaysUi.root, lParams(matchParent, matchParent))
add(candidateUi.root, lParams(matchParent, matchParent))
Expand All @@ -211,7 +210,7 @@ class QuickBar(
}

override fun onRimeSchemaUpdated(schema: SchemaItem) {
if (alwaysUi.currentState == AlwaysUi.State.Switchers) {
if (alwaysUi.currentState == AlwaysUi.State.Switches) {
service.lifecycleScope.launch {
alwaysUi.switchesUi.setSwitches(SchemaManager.visibleSwitches)
}
Expand All @@ -223,11 +222,8 @@ class QuickBar(
"_hide_comment" -> {
// candidateUi.candidates.shouldShowComment = !value.value
}
"_hide_candidate", "_hide_bar" -> {
view.visibility = if (value.value) View.GONE else View.VISIBLE
}
}
if (alwaysUi.currentState == AlwaysUi.State.Switchers) {
if (alwaysUi.currentState == AlwaysUi.State.Switches) {
service.lifecycleScope.launch {
alwaysUi.switchesUi.setSwitches(SchemaManager.visibleSwitches)
}
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/com/osfans/trime/ime/bar/ui/AlwaysUi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class AlwaysUi(
) : Ui {
enum class State {
Empty,
Switchers,
Switches,
}

var currentState = State.Empty
Expand Down Expand Up @@ -55,7 +55,7 @@ class AlwaysUi(
Timber.d("Switch always ui to $state")
when (state) {
State.Empty -> animator.displayedChild = 0
State.Switchers -> animator.displayedChild = 1
State.Switches -> animator.displayedChild = 1
}
currentState = state
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import com.osfans.trime.data.theme.Theme
class SwitchesAdapter(
private val theme: Theme,
) : BaseQuickAdapter<Schema.Switch, SwitchesAdapter.Holder>() {
private val showArrow by AppPrefs.defaultInstance().keyboard.switchArrowEnabled
private val showArrow by AppPrefs.defaultInstance().keyboard.showArrowInSwitches

inner class Holder(
val ui: SwitchUi,
Expand All @@ -37,13 +37,7 @@ class SwitchesAdapter(
setFirstText(item.states[enabled])
val altText =
if (item.options.isEmpty()) {
item.states[1 - enabled].let {
if (showArrow) {
"→ $it"
} else {
it
}
}
"${if (showArrow) "→ " else ""}${item.states[1 - enabled]}"
} else {
""
}
Expand Down
Loading
Loading