Skip to content

Commit

Permalink
feat: initial implementation of SwitchesUi
Browse files Browse the repository at this point in the history
  • Loading branch information
WhiredPlanck committed Aug 17, 2024
1 parent aa9d8a7 commit bfe66a4
Show file tree
Hide file tree
Showing 12 changed files with 255 additions and 56 deletions.
12 changes: 0 additions & 12 deletions app/src/main/java/com/osfans/trime/core/Rime.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ package com.osfans.trime.core

import com.osfans.trime.data.base.DataManager
import com.osfans.trime.data.opencc.OpenCCDictManager
import com.osfans.trime.data.prefs.AppPrefs
import com.osfans.trime.data.schema.SchemaManager
import com.osfans.trime.util.appContext
import com.osfans.trime.util.isAsciiPrintable
Expand Down Expand Up @@ -255,17 +254,6 @@ class Rime : RimeApi, RimeLifecycleOwner {
}
}

@JvmStatic
val candidatesOrStatusSwitches: Array<CandidateListItem>
get() {
val showSwitches = AppPrefs.defaultInstance().keyboard.switchesEnabled
return if (!isComposing && showSwitches) {
SchemaManager.getStatusSwitches()
} else {
inputContext?.candidates ?: arrayOf()
}
}

val candidatesWithoutSwitch: Array<CandidateListItem>
get() = if (isComposing) inputContext?.candidates ?: arrayOf() else arrayOf()

Expand Down
37 changes: 1 addition & 36 deletions app/src/main/java/com/osfans/trime/data/schema/SchemaManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@

package com.osfans.trime.data.schema

import com.osfans.trime.core.CandidateListItem
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
private lateinit var visibleSwitches: List<Schema.Switch>
lateinit var visibleSwitches: List<Schema.Switch>

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

Expand Down Expand Up @@ -44,38 +43,4 @@ object SchemaManager {
}
}
}

@JvmStatic
fun toggleSwitchOption(index: Int) {
if (!this::visibleSwitches.isInitialized || visibleSwitches.isEmpty()) return
val switch = visibleSwitches[index]
val enabled = switch.enabled
switch.enabled =
if (switch.options.isNullOrEmpty()) {
(1 - enabled).also { Rime.setOption(switch.name!!, it == 1) }
} else {
val options = switch.options
((enabled + 1) % options.size).also {
Rime.setOption(options[enabled], false)
Rime.setOption(options[it], true)
}
}
}

@JvmStatic
fun getStatusSwitches(): Array<CandidateListItem> {
if (!this::visibleSwitches.isInitialized || visibleSwitches.isEmpty()) return arrayOf()
return Array(visibleSwitches.size) {
val switch = visibleSwitches[it]
val enabled = switch.enabled
val text = switch.states!![enabled]
val comment =
if (switch.options.isNullOrEmpty()) {
"${if (arrow) "" else ""}${switch.states[1 - enabled]}"
} else {
""
}
CandidateListItem(comment, text)
}
}
}
59 changes: 58 additions & 1 deletion app/src/main/java/com/osfans/trime/ime/bar/QuickBar.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,17 @@ import android.content.Context
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
import android.view.inputmethod.EditorInfo
import android.widget.ViewAnimator
import com.osfans.trime.core.Rime
import com.osfans.trime.core.RimeNotification.OptionNotification
import com.osfans.trime.core.SchemaItem
import com.osfans.trime.data.prefs.AppPrefs
import com.osfans.trime.data.schema.SchemaManager
import com.osfans.trime.data.theme.ColorManager
import com.osfans.trime.data.theme.Theme
import com.osfans.trime.databinding.CandidateBarBinding
import com.osfans.trime.ime.bar.ui.AlwaysUi
import com.osfans.trime.ime.bar.ui.TabUi
import com.osfans.trime.ime.broadcast.InputBroadcastReceiver
import com.osfans.trime.ime.core.TrimeInputMethodService
Expand All @@ -28,6 +33,41 @@ import splitties.views.dsl.core.matchParent
@InputScope
@Inject
class QuickBar(context: Context, service: TrimeInputMethodService, theme: Theme) : InputBroadcastReceiver {
private val prefs = AppPrefs.defaultInstance()

private val showSwitchers get() = prefs.keyboard.switchesEnabled

private fun evalAlwaysUiState() {
val newState =
when {
showSwitchers -> AlwaysUi.State.Switchers
else -> AlwaysUi.State.Empty
}
if (newState == alwaysUi.currentState) return
alwaysUi.updateState(newState)
}

private val alwaysUi: AlwaysUi by lazy {
AlwaysUi(context, theme).apply {
switchesUi.apply {
setSwitches(SchemaManager.visibleSwitches)
setOnSwitchClick { switch ->
val prevEnabled = switch.enabled
switch.enabled =
if (switch.options.isNullOrEmpty()) {
(1 - prevEnabled).also { Rime.setOption(switch.name!!, it == 1) }
} else {
val options = switch.options
((prevEnabled + 1) % options.size).also {
Rime.setOption(options[prevEnabled], false)
Rime.setOption(options[it], true)
}
}
}
}
}
}

val oldCandidateBar by lazy {
CandidateBarBinding.inflate(LayoutInflater.from(context)).apply {
with(root) {
Expand All @@ -49,11 +89,12 @@ class QuickBar(context: Context, service: TrimeInputMethodService, theme: Theme)
}

enum class State {
Always,
Candidate,
Tab,
}

private fun switchUiByState(state: State) {
fun switchUiByState(state: State) {
val index = state.ordinal
if (view.displayedChild == index) return
val new = view.getChildAt(index)
Expand Down Expand Up @@ -81,11 +122,23 @@ class QuickBar(context: Context, service: TrimeInputMethodService, theme: Theme)
"candidate_border_color",
theme.generalStyle.candidateBorderRound,
)
add(alwaysUi.root, lParams(matchParent, matchParent))
add(oldCandidateBar.root, lParams(matchParent, matchParent))
add(tabUi.root, lParams(matchParent, matchParent))
}
}

override fun onStartInput(info: EditorInfo) {
evalAlwaysUiState()
}

override fun onRimeSchemaUpdated(schema: SchemaItem) {
if (alwaysUi.currentState == AlwaysUi.State.Switchers) {
SchemaManager.init(schema.id)
alwaysUi.switchesUi.setSwitches(SchemaManager.visibleSwitches)
}
}

override fun onRimeOptionUpdated(value: OptionNotification.Value) {
when (value.option) {
"_hide_comment" -> {
Expand All @@ -95,6 +148,10 @@ class QuickBar(context: Context, service: TrimeInputMethodService, theme: Theme)
view.visibility = if (value.value) View.GONE else View.VISIBLE
}
}
if (alwaysUi.currentState == AlwaysUi.State.Switchers) {
SchemaManager.updateSwitchOptions()
alwaysUi.switchesUi.setSwitches(SchemaManager.visibleSwitches)
}
}

override fun onWindowAttached(window: BoardWindow) {
Expand Down
62 changes: 62 additions & 0 deletions app/src/main/java/com/osfans/trime/ime/bar/ui/AlwaysUi.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// SPDX-FileCopyrightText: 2015 - 2024 Rime community
//
// SPDX-License-Identifier: GPL-3.0-or-later

package com.osfans.trime.ime.bar.ui

import android.content.Context
import android.widget.Space
import android.widget.ViewAnimator
import com.osfans.trime.data.theme.Theme
import com.osfans.trime.ime.bar.ui.always.switches.SwitchesUi
import splitties.views.dsl.constraintlayout.centerInParent
import splitties.views.dsl.constraintlayout.constraintLayout
import splitties.views.dsl.constraintlayout.lParams
import splitties.views.dsl.constraintlayout.matchConstraints
import splitties.views.dsl.core.Ui
import splitties.views.dsl.core.add
import splitties.views.dsl.core.lParams
import splitties.views.dsl.core.matchParent
import timber.log.Timber

class AlwaysUi(
override val ctx: Context,
private val theme: Theme,
) : Ui {
enum class State {
Empty,
Switchers,
}

var currentState = State.Empty
private set

val emptyBar = Space(ctx)

val switchesUi = SwitchesUi(ctx, theme)

private val animator =
ViewAnimator(ctx).apply {
add(emptyBar, lParams(matchParent, matchParent))
add(switchesUi.root, lParams(matchParent, matchParent))
}

override val root =
constraintLayout {
add(
animator,
lParams(matchConstraints, matchParent) {
centerInParent()
},
)
}

fun updateState(state: State) {
Timber.d("Switch always ui to $state")
when (state) {
State.Empty -> animator.displayedChild = 0
State.Switchers -> animator.displayedChild = 1
}
currentState = state
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// SPDX-FileCopyrightText: 2015 - 2024 Rime community
//
// SPDX-License-Identifier: GPL-3.0-or-later

package com.osfans.trime.ime.bar.ui.always.switches

import android.content.Context
import com.osfans.trime.data.theme.ColorManager
import com.osfans.trime.data.theme.FontManager
import com.osfans.trime.data.theme.Theme
import splitties.views.dsl.core.Ui
import splitties.views.dsl.core.add
import splitties.views.dsl.core.frameLayout
import splitties.views.dsl.core.lParams
import splitties.views.dsl.core.textView
import splitties.views.gravityCenter

class SwitchUi(override val ctx: Context, private val theme: Theme) : Ui {
var enabled: Int = -1

private val label =
textView {
textSize = theme.generalStyle.candidateTextSize.toFloat()
typeface = FontManager.getTypeface("candidate_font")
ColorManager.getColor("candidate_text_color")?.let { setTextColor(it) }
}

override val root =
frameLayout {
add(label, lParams { gravity = gravityCenter })
}

fun setLabel(str: String) {
label.text = str
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// SPDX-FileCopyrightText: 2015 - 2024 Rime community
//
// SPDX-License-Identifier: GPL-3.0-or-later

package com.osfans.trime.ime.bar.ui.always.switches

import android.content.Context
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.chad.library.adapter4.BaseQuickAdapter
import com.osfans.trime.data.schema.Schema
import com.osfans.trime.data.theme.Theme

class SwitchesAdapter(private val theme: Theme) :
BaseQuickAdapter<Schema.Switch, SwitchesAdapter.Holder>() {
inner class Holder(val ui: SwitchUi) : RecyclerView.ViewHolder(ui.root)

override fun onCreateViewHolder(
context: Context,
parent: ViewGroup,
viewType: Int,
): Holder {
return Holder(SwitchUi(context, theme))
}

override fun onBindViewHolder(
holder: Holder,
position: Int,
item: Schema.Switch?,
) {
holder.ui.apply {
val enabled = item!!.enabled
setLabel(item.states!![enabled])
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// SPDX-FileCopyrightText: 2015 - 2024 Rime community
//
// SPDX-License-Identifier: GPL-3.0-or-later

package com.osfans.trime.ime.bar.ui.always.switches

import android.content.Context
import android.view.ViewGroup
import com.chad.library.adapter4.util.setOnDebouncedItemClick
import com.osfans.trime.data.schema.Schema
import com.osfans.trime.data.theme.Theme
import com.osfans.trime.ime.symbol.SpacesItemDecoration
import splitties.dimensions.dp
import splitties.views.dsl.core.Ui
import splitties.views.dsl.core.matchParent
import splitties.views.dsl.recyclerview.recyclerView
import splitties.views.recyclerview.horizontalLayoutManager

class SwitchesUi(override val ctx: Context, val theme: Theme) : Ui {
private val switchesAdapter by lazy {
SwitchesAdapter(theme)
}

override val root =
recyclerView {
layoutParams = ViewGroup.LayoutParams(matchParent, matchParent)
layoutManager = horizontalLayoutManager()
adapter = switchesAdapter
addItemDecoration(SpacesItemDecoration(dp(3)))
}

fun setSwitches(list: List<Schema.Switch>) {
switchesAdapter.submitList(list)
}

fun setOnSwitchClick(listener: (Schema.Switch) -> Unit) {
switchesAdapter.setOnDebouncedItemClick { adapter, _, position ->
val typed = (adapter as SwitchesAdapter)
if (typed.items.isEmpty()) return@setOnDebouncedItemClick
val switch = typed.items[position]
listener(switch)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package com.osfans.trime.ime.broadcast

import android.view.inputmethod.EditorInfo
import com.osfans.trime.core.RimeNotification.OptionNotification
import com.osfans.trime.core.SchemaItem
import com.osfans.trime.ime.window.BoardWindow

interface InputBroadcastReceiver {
Expand All @@ -16,6 +17,8 @@ interface InputBroadcastReceiver {
end: Int,
) {}

fun onRimeSchemaUpdated(schema: SchemaItem) {}

fun onRimeOptionUpdated(value: OptionNotification.Value) {}

fun onWindowAttached(window: BoardWindow) {}
Expand Down
Loading

0 comments on commit bfe66a4

Please sign in to comment.