Skip to content

Commit

Permalink
feat: integrate UI creation for PreferenceDelegate
Browse files Browse the repository at this point in the history
  • Loading branch information
WhiredPlanck committed Nov 21, 2024
1 parent b3406b5 commit 8a0fea7
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* SPDX-FileCopyrightText: 2015 - 2024 Rime community
* SPDX-License-Identifier: GPL-3.0-or-later
*/

package com.osfans.trime.data.prefs

import androidx.annotation.StringRes

interface PreferenceDelegateEnum {
@get:StringRes
val stringRes: Int
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* SPDX-FileCopyrightText: 2015 - 2024 Rime community
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package com.osfans.trime.data.prefs

import android.os.Bundle
import androidx.annotation.CallSuper
import androidx.preference.PreferenceScreen
import com.osfans.trime.ui.components.PaddingPreferenceFragment

abstract class PreferenceDelegateFragment(
private val preferenceProvider: PreferenceDelegateProvider,
) : PaddingPreferenceFragment() {
open fun onPreferenceUiCreated(screen: PreferenceScreen) {}

@CallSuper
override fun onCreatePreferences(
savedInstanceState: Bundle?,
rootKey: String?,
) {
preferenceScreen =
preferenceManager.createPreferenceScreen(preferenceManager.context).also { screen ->
preferenceProvider.createUi(screen)
onPreferenceUiCreated(screen)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
package com.osfans.trime.data.prefs

import android.content.SharedPreferences
import androidx.annotation.StringRes
import androidx.preference.PreferenceScreen

abstract class PreferenceDelegateOwner(
protected val sharedPreferences: SharedPreferences,
) {
@StringRes val title: Int = 0,
) : PreferenceDelegateProvider() {
protected fun int(
key: String,
defaultValue: Int,
Expand Down Expand Up @@ -57,4 +60,37 @@ abstract class PreferenceDelegateOwner(
override fun deserialize(raw: String) = enumValueOf<T>(raw.uppercase())
},
)

// TODO: replace all [enum] with this
protected inline fun <reified T> enum(
@StringRes title: Int,
key: String,
defaultValue: T,
noinline enableUiOn: (() -> Boolean)? = null,
): PreferenceDelegate.SerializableDelegate<T> where T : Enum<T>, T : PreferenceDelegateEnum {
val serializer =
object : PreferenceDelegate.Serializer<T> {
override fun serialize(t: T) = t.name

override fun deserialize(raw: String) = enumValueOf<T>(raw.uppercase())
}
val entryValues = enumValues<T>().toList()
val entryLabels = entryValues.map { it.stringRes }
val pref = serializable(key, defaultValue, serializer)
val ui = PreferenceDelegateUi.StringList(title, key, defaultValue, serializer, entryValues, entryLabels)
pref.register()
ui.registerUi()
return pref
}

override fun createUi(screen: PreferenceScreen) {
val ctx = screen.context
preferenceDelegatesUi.forEach {
screen.addPreference(
it.createUi(ctx).apply {
isEnabled = it.isEnabled()
},
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* SPDX-FileCopyrightText: 2015 - 2024 Rime community
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package com.osfans.trime.data.prefs

import androidx.preference.PreferenceScreen

abstract class PreferenceDelegateProvider {
private val _preferenceDelegates: MutableMap<String, PreferenceDelegate<*>> = mutableMapOf()

private val _preferenceDelegatesUi: MutableList<PreferenceDelegateUi<*>> = mutableListOf()

val preferenceDelegates: Map<String, PreferenceDelegate<*>>
get() = _preferenceDelegates

val preferenceDelegatesUi: List<PreferenceDelegateUi<*>>
get() = _preferenceDelegatesUi

open fun createUi(screen: PreferenceScreen) {
}

fun PreferenceDelegateUi<*>.registerUi() {
_preferenceDelegatesUi.add(this)
}

fun PreferenceDelegate<*>.register() {
_preferenceDelegates[key] = this
}
}
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.data.prefs

import android.content.Context
import androidx.annotation.StringRes
import androidx.preference.ListPreference
import androidx.preference.Preference

abstract class PreferenceDelegateUi<T : Preference>(
val key: String,
private val enableUiOn: (() -> Boolean)? = null,
) {
abstract fun createUi(context: Context): T

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

class StringList<T : Any>(
@StringRes
val title: Int,
key: String,
val defaultValue: T,
val serializer: PreferenceDelegate.Serializer<T>,
val entryValues: List<T>,
@StringRes
val entryLabels: List<Int>,
enableUiOn: (() -> Boolean)? = null,
) : PreferenceDelegateUi<ListPreference>(key, enableUiOn) {
override fun createUi(context: Context) =
ListPreference(context).apply {
key = this@StringList.key
isIconSpaceReserved = false
isSingleLineTitle = false
entryValues = this@StringList.entryValues.map { serializer.serialize(it) }.toTypedArray()
summaryProvider = ListPreference.SimpleSummaryProvider.getInstance()
setDefaultValue(serializer.serialize(defaultValue))
setTitle(this@StringList.title)
entries = this@StringList.entryLabels.map { context.getString(it) }.toTypedArray()
setDialogTitle(this@StringList.title)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ class PrefMainActivity : AppCompatActivity() {
m.isVisible = it
}
}
navHostFragment.navController.addOnDestinationChangedListener { _, dest, _ ->
dest.label?.let { viewModel.setToolbarTitle(it.toString()) }
}

supportActionBar?.setDisplayHomeAsUpEnabled(true)
if (SetupActivity.shouldSetup()) {
Expand Down

0 comments on commit 8a0fea7

Please sign in to comment.