Эх сурвалжийг харах

增加一些基本的界面自定义功能

HapeLee 1 жил өмнө
parent
commit
66b78f53af

+ 0 - 2
app/src/main/java/io/legato/kazusa/App.kt

@@ -9,7 +9,6 @@ import android.content.pm.ApplicationInfo
 import android.content.res.Configuration
 import android.os.Build
 import com.github.liuyueyi.quick.transfer.constants.TransType
-import com.google.android.material.color.DynamicColors
 import com.jeremyliao.liveeventbus.LiveEventBus
 import com.jeremyliao.liveeventbus.logger.DefaultLogger
 import com.script.rhino.ReadOnlyJavaObject
@@ -66,7 +65,6 @@ class App : Application() {
 
     override fun onCreate() {
         super.onCreate()
-        DynamicColors.applyToActivitiesIfAvailable(this)
         FirebaseManager.init(this)
         CrashHandler(this)
         if (isDebuggable) {

+ 15 - 2
app/src/main/java/io/legato/kazusa/base/BaseActivity.kt

@@ -17,6 +17,7 @@ import androidx.core.view.WindowCompat
 import androidx.viewbinding.ViewBinding
 import com.google.android.material.appbar.AppBarLayout
 import com.google.android.material.color.DynamicColors
+import com.google.android.material.color.DynamicColorsOptions
 import io.legato.kazusa.R
 import io.legato.kazusa.constant.AppLog
 import io.legato.kazusa.constant.EventBus
@@ -31,6 +32,7 @@ import io.legato.kazusa.utils.hideSoftInput
 import io.legato.kazusa.utils.observeEvent
 import io.legato.kazusa.utils.toastOnUi
 import io.legato.kazusa.utils.windowSize
+import io.legato.kazusa.lib.theme.primaryColor
 
 
 abstract class BaseActivity<VB : ViewBinding>(
@@ -128,7 +130,9 @@ abstract class BaseActivity<VB : ViewBinding>(
 
     open fun initTheme() {
         when (getPrefString("app_theme", "0")) {
-            "0" -> DynamicColors.applyToActivitiesIfAvailable(application)
+            "0" -> {
+                DynamicColors.applyToActivitiesIfAvailable(application)
+            }
             "1" -> setTheme(R.style.Theme_Base_GR)
             "2" -> setTheme(R.style.Theme_Base_Lemon)
             "3" -> setTheme(R.style.Theme_Base_WH)
@@ -139,8 +143,17 @@ abstract class BaseActivity<VB : ViewBinding>(
             "8" -> setTheme(R.style.Theme_Base_Yuuka)
             "9" -> setTheme(R.style.Theme_Base_Phoebe)
             "10" -> setTheme(R.style.Theme_Base_Mujika)
-            "11" -> setTheme(R.style.AppTheme_Transparent)
+            "11" -> {
+                if (AppConfig.customMode == "accent")
+                    setTheme(R.style.ThemeOverlay_WhiteBackground)
+                DynamicColors.applyToActivitiesIfAvailable(application, DynamicColorsOptions.Builder()
+                    .setContentBasedSource(application.primaryColor)
+                    .build())
+
+            }
+            "12" -> setTheme(R.style.AppTheme_Transparent)
         }
+
         if (AppConfig.pureBlack)
             setTheme(R.style.ThemeOverlay_PureBlack)
     }

+ 1 - 0
app/src/main/java/io/legato/kazusa/constant/PreferKey.kt

@@ -162,6 +162,7 @@ object PreferKey {
     const val firebaseEnable = "firebaseEnable"
     const val cPrimary = "colorPrimary"
     const val cAccent = "colorAccent"
+    const val customMode = "customMode"
     const val cBackground = "colorBackground"
     const val cBBackground = "colorBottomBackground"
     const val bgImage = "backgroundImage"

+ 1 - 0
app/src/main/java/io/legato/kazusa/help/config/AppConfig.kt

@@ -27,6 +27,7 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
     var useAntiAlias = appCtx.getPrefBoolean(PreferKey.antiAlias)
     var userAgent: String = getPrefUserAgent()
     var isEInkMode = appCtx.getPrefString(PreferKey.themeMode) == "3"
+    var customMode = appCtx.getPrefString(PreferKey.customMode)
     var clickActionTL = appCtx.getPrefInt(PreferKey.clickActionTL, 2)
     var clickActionTC = appCtx.getPrefInt(PreferKey.clickActionTC, 2)
     var clickActionTR = appCtx.getPrefInt(PreferKey.clickActionTR, 1)

+ 6 - 1
app/src/main/java/io/legato/kazusa/lib/prefs/ColorPreference.kt

@@ -14,9 +14,13 @@ import androidx.preference.PreferenceViewHolder
 import com.jaredrummler.android.colorpicker.*
 import io.legato.kazusa.utils.ColorUtils
 import io.legato.kazusa.utils.applyTint
+import io.legato.kazusa.utils.themeColor
 
 @Suppress("MemberVisibilityCanBePrivate", "unused")
-class ColorPreference(context: Context, attrs: AttributeSet) : Preference(context, attrs),
+class ColorPreference @JvmOverloads constructor(
+    context: Context,
+    attrs: AttributeSet? = null
+) : Preference(context, attrs),
     ColorPickerDialogListener {
 
     var onSaveColor: ((color: Int) -> Boolean)? = null
@@ -123,6 +127,7 @@ class ColorPreference(context: Context, attrs: AttributeSet) : Preference(contex
         )
         if (v is ColorPanelView) {
             v.color = mColor
+            v.setBorderColor(context.themeColor(com.google.android.material.R.attr.colorPrimaryContainer))
         }
     }
 

+ 14 - 3
app/src/main/java/io/legato/kazusa/lib/prefs/ThemeCardPreference.kt

@@ -4,6 +4,8 @@ import android.annotation.SuppressLint
 import android.content.Context
 import android.content.res.ColorStateList
 import android.graphics.Color
+import android.os.Handler
+import android.os.Looper
 import android.util.AttributeSet
 import android.view.ContextThemeWrapper
 import android.view.LayoutInflater
@@ -17,6 +19,7 @@ import com.google.android.material.card.MaterialCardView
 import io.legato.kazusa.R
 import io.legato.kazusa.constant.EventBus
 import io.legato.kazusa.utils.postEvent
+import io.legato.kazusa.utils.restart
 
 @SuppressLint("ResourceType")
 class ThemeCardPreference(context: Context, attrs: AttributeSet) : Preference(context, attrs) {
@@ -73,11 +76,19 @@ class ThemeCardPreference(context: Context, attrs: AttributeSet) : Preference(co
 
             holder.card.setOnClickListener {
                 if (value != currentValue) {
+                    val oldValue = currentValue
                     currentValue = value
                     persistString(value)
                     callChangeListener(value)
                     notifyDataSetChanged()
-                    postEvent(EventBus.RECREATE, "")
+                    val isDynamicSwitch = (oldValue == "11" || value == "11")
+                    Handler(Looper.getMainLooper()).postDelayed({
+                        if (isDynamicSwitch) {
+                            context.restart()
+                        } else {
+                            postEvent(EventBus.RECREATE, "")
+                        }
+                    }, 300)
                 }
             }
         }
@@ -98,8 +109,8 @@ class ThemeCardPreference(context: Context, attrs: AttributeSet) : Preference(co
         "8" to R.style.Theme_Base_Yuuka,
         "9" to R.style.Theme_Base_Phoebe,
         "10" to R.style.Theme_Base_Mujika,
-        "11" to R.style.AppTheme_Transparent
-        )
+        "11" to R.style.Theme_Base_WH,
+        "12" to R.style.AppTheme_Transparent)
 
     private fun getThemeColors(value: String): List<Int> {
         val themeResId = themeResIdMap[value] ?: return listOf(Color.GRAY, Color.GRAY, Color.GRAY, Color.GRAY)

+ 5 - 1
app/src/main/java/io/legato/kazusa/lib/prefs/ThemeModePreference.kt

@@ -1,6 +1,8 @@
 package io.legato.kazusa.lib.prefs
 
 import android.content.Context
+import android.os.Handler
+import android.os.Looper
 import android.util.AttributeSet
 import androidx.preference.PreferenceViewHolder
 import com.google.android.material.button.MaterialButtonToggleGroup
@@ -56,7 +58,9 @@ class ThemeModePreference(context: Context, attrs: AttributeSet) : Preference(co
                     currentValue = newValue
                     persistString(newValue)
                     callChangeListener(newValue)
-                    ThemeConfig.applyDayNight(context)
+                    Handler(Looper.getMainLooper()).postDelayed({
+                        ThemeConfig.applyDayNight(context)
+                    }, 300)
                 }
             }
         }

+ 10 - 0
app/src/main/java/io/legato/kazusa/lib/theme/MaterialValueHelper.kt

@@ -2,6 +2,16 @@
 
 package io.legato.kazusa.lib.theme
 
+import android.content.Context
+
 /**
  * @author Karim Abou Zeid (kabouzeid)
  */
+val Context.primaryColor: Int
+    get() = ThemeStore.primaryColor(this)
+
+val Context.secondaryColor: Int
+    get() = ThemeStore.secondaryColor(this)
+
+val Context.primaryContainerColor: Int
+    get() = ThemeStore.primaryContainerColor(this)

+ 91 - 179
app/src/main/java/io/legato/kazusa/lib/theme/ThemeStore.kt

@@ -11,20 +11,63 @@ import androidx.core.content.ContextCompat
 import androidx.core.graphics.toColorInt
 import io.legato.kazusa.utils.ColorUtils
 import splitties.init.appCtx
+import androidx.core.content.edit
+import com.google.android.material.color.DynamicColors
+import com.google.android.material.color.DynamicColorsOptions
+import com.google.android.material.color.MaterialColors
 
 /**
  * @author Aidan Follestad (afollestad), Karim Abou Zeid (kabouzeid)
  */
+
 @Suppress("unused")
 class ThemeStore @SuppressLint("CommitPrefEdits")
 private constructor(private val mContext: Context) : ThemeStoreInterface {
 
     private val mEditor = prefs(mContext).edit()
 
+    override fun addColorScheme(@ColorInt color: Int): ThemeStore {
+        val options = DynamicColorsOptions.Builder()
+            .setContentBasedSource(color)
+            .build()
+
+        val wrapped = DynamicColors.wrapContextIfAvailable(
+            mContext,
+            options).apply {
+            resources.configuration.uiMode = mContext.resources.configuration.uiMode
+            }
+
+        val fallback = color
+
+        val secondary = MaterialColors.getColor(
+            wrapped,
+            com.google.android.material.R.attr.colorSecondary,
+            fallback
+        )
+
+        val primaryContainer = MaterialColors.getColor(
+            wrapped,
+            com.google.android.material.R.attr.colorSecondaryContainer,
+            fallback
+        )
+
+        val primary = MaterialColors.getColor(
+            wrapped,
+            androidx.appcompat.R.attr.colorPrimary,
+            fallback
+        )
+
+        mEditor.putInt(ThemeStorePrefKeys.KEY_SECONDARY_COLOR, secondary)
+        mEditor.putInt(ThemeStorePrefKeys.KEY_PRIMARY_CONTAINER_COLOR, primaryContainer)
+        mEditor.putInt(ThemeStorePrefKeys.KEY_PRIMARY_COLOR, primary)
+
+        return this
+    }
+
     override fun primaryColor(@ColorInt color: Int): ThemeStore {
-        mEditor.putInt(ThemeStorePrefKeys.KEY_PRIMARY_COLOR, color)
         if (autoGeneratePrimaryDark(mContext))
             primaryColorDark(ColorUtils.darkenColor(color))
+        addColorScheme(color)
         return this
     }
 
@@ -49,97 +92,6 @@ private constructor(private val mContext: Context) : ThemeStoreInterface {
         return primaryColorDark(ThemeUtils.resolveColor(mContext, colorAttr))
     }
 
-    override fun accentColor(@ColorInt color: Int): ThemeStore {
-        mEditor.putInt(ThemeStorePrefKeys.KEY_ACCENT_COLOR, color)
-        return this
-    }
-
-    override fun accentColorRes(@ColorRes colorRes: Int): ThemeStore {
-        return accentColor(ContextCompat.getColor(mContext, colorRes))
-    }
-
-    override fun accentColorAttr(@AttrRes colorAttr: Int): ThemeStore {
-        return accentColor(ThemeUtils.resolveColor(mContext, colorAttr))
-    }
-
-    override fun statusBarColor(@ColorInt color: Int): ThemeStore {
-        mEditor.putInt(ThemeStorePrefKeys.KEY_STATUS_BAR_COLOR, color)
-        return this
-    }
-
-    override fun statusBarColorRes(@ColorRes colorRes: Int): ThemeStore {
-        return statusBarColor(ContextCompat.getColor(mContext, colorRes))
-    }
-
-    override fun statusBarColorAttr(@AttrRes colorAttr: Int): ThemeStore {
-        return statusBarColor(ThemeUtils.resolveColor(mContext, colorAttr))
-    }
-
-    override fun navigationBarColor(@ColorInt color: Int): ThemeStore {
-        mEditor.putInt(ThemeStorePrefKeys.KEY_NAVIGATION_BAR_COLOR, color)
-        return this
-    }
-
-    override fun navigationBarColorRes(@ColorRes colorRes: Int): ThemeStore {
-        return navigationBarColor(ContextCompat.getColor(mContext, colorRes))
-    }
-
-    override fun navigationBarColorAttr(@AttrRes colorAttr: Int): ThemeStore {
-        return navigationBarColor(ThemeUtils.resolveColor(mContext, colorAttr))
-    }
-
-    override fun textColorPrimary(@ColorInt color: Int): ThemeStore {
-        mEditor.putInt(ThemeStorePrefKeys.KEY_TEXT_COLOR_PRIMARY, color)
-        return this
-    }
-
-    override fun textColorPrimaryRes(@ColorRes colorRes: Int): ThemeStore {
-        return textColorPrimary(ContextCompat.getColor(mContext, colorRes))
-    }
-
-    override fun textColorPrimaryAttr(@AttrRes colorAttr: Int): ThemeStore {
-        return textColorPrimary(ThemeUtils.resolveColor(mContext, colorAttr))
-    }
-
-    override fun textColorPrimaryInverse(@ColorInt color: Int): ThemeStore {
-        mEditor.putInt(ThemeStorePrefKeys.KEY_TEXT_COLOR_PRIMARY_INVERSE, color)
-        return this
-    }
-
-    override fun textColorPrimaryInverseRes(@ColorRes colorRes: Int): ThemeStore {
-        return textColorPrimaryInverse(ContextCompat.getColor(mContext, colorRes))
-    }
-
-    override fun textColorPrimaryInverseAttr(@AttrRes colorAttr: Int): ThemeStore {
-        return textColorPrimaryInverse(ThemeUtils.resolveColor(mContext, colorAttr))
-    }
-
-    override fun textColorSecondary(@ColorInt color: Int): ThemeStore {
-        mEditor.putInt(ThemeStorePrefKeys.KEY_TEXT_COLOR_SECONDARY, color)
-        return this
-    }
-
-    override fun textColorSecondaryRes(@ColorRes colorRes: Int): ThemeStore {
-        return textColorSecondary(ContextCompat.getColor(mContext, colorRes))
-    }
-
-    override fun textColorSecondaryAttr(@AttrRes colorAttr: Int): ThemeStore {
-        return textColorSecondary(ThemeUtils.resolveColor(mContext, colorAttr))
-    }
-
-    override fun textColorSecondaryInverse(@ColorInt color: Int): ThemeStore {
-        mEditor.putInt(ThemeStorePrefKeys.KEY_TEXT_COLOR_SECONDARY_INVERSE, color)
-        return this
-    }
-
-    override fun textColorSecondaryInverseRes(@ColorRes colorRes: Int): ThemeStore {
-        return textColorSecondaryInverse(ContextCompat.getColor(mContext, colorRes))
-    }
-
-    override fun textColorSecondaryInverseAttr(@AttrRes colorAttr: Int): ThemeStore {
-        return textColorSecondaryInverse(ThemeUtils.resolveColor(mContext, colorAttr))
-    }
-
     override fun backgroundColor(color: Int): ThemeStore {
         mEditor.putInt(ThemeStorePrefKeys.KEY_BACKGROUND_COLOR, color)
         return this
@@ -161,17 +113,17 @@ private constructor(private val mContext: Context) : ThemeStoreInterface {
         mEditor.putLong(ThemeStorePrefKeys.VALUES_CHANGED, System.currentTimeMillis())
             .putBoolean(ThemeStorePrefKeys.IS_CONFIGURED_KEY, true)
             .apply()
-        accentColor = accentColor()
     }
 
     companion object {
 
-        var accentColor = accentColor()
-
         fun editTheme(context: Context): ThemeStore {
             return ThemeStore(context)
         }
 
+        fun isCustomThemeEnabled(context: Context): Boolean = true
+           // AppConfig.customTheme
+
         // Static getters
 
         @CheckResult
@@ -189,110 +141,70 @@ private constructor(private val mContext: Context) : ThemeStoreInterface {
         @CheckResult
         @ColorInt
         fun primaryColor(context: Context = appCtx): Int {
-            return prefs(context).getInt(
-                ThemeStorePrefKeys.KEY_PRIMARY_COLOR,
-                ThemeUtils.resolveColor(
-                    context,
-                    androidx.appcompat.R.attr.colorPrimary,
-                    "#455A64".toColorInt()
-                )
-            )
-        }
-
-        @CheckResult
-        @ColorInt
-        fun primaryColorDark(context: Context): Int {
-            return prefs(context).getInt(
-                ThemeStorePrefKeys.KEY_PRIMARY_COLOR_DARK,
-                ThemeUtils.resolveColor(
-                    context,
-                    androidx.appcompat.R.attr.colorPrimaryDark,
-                    "#37474F".toColorInt()
+            return if (isCustomThemeEnabled(context)) {
+                prefs(context).getInt(
+                    ThemeStorePrefKeys.KEY_PRIMARY_COLOR,
+                    ThemeUtils.resolveColor(
+                        context,
+                        androidx.appcompat.R.attr.colorPrimary,
+                        "#455A64".toColorInt()
+                    )
                 )
-            )
+            } else {
+                ThemeUtils.resolveColor(context, androidx.appcompat.R.attr.colorPrimary)
+            }
         }
 
-        @CheckResult
-        @ColorInt
-        fun accentColor(context: Context = appCtx): Int {
-            return prefs(context).getInt(
-                ThemeStorePrefKeys.KEY_ACCENT_COLOR,
-                ThemeUtils.resolveColor(
-                    context,
-                    androidx.appcompat.R.attr.colorAccent,
-                    "#263238".toColorInt()
+        fun primaryContainerColor(context: Context = appCtx): Int {
+            return if (isCustomThemeEnabled(context)) {
+                prefs(context).getInt(
+                    ThemeStorePrefKeys.KEY_PRIMARY_CONTAINER_COLOR,
+                    "#FFFFFF".toColorInt()
                 )
-            )
+            } else {
+                ThemeUtils.resolveColor(context, com.google.android.material.R.attr.colorPrimaryContainer)
+            }
         }
 
-        @CheckResult
-        @ColorInt
-        fun statusBarColor(context: Context, transparent: Boolean): Int {
-            return if (transparent) {
+        fun secondaryColor(context: Context = appCtx): Int {
+            return if (isCustomThemeEnabled(context)) {
                 prefs(context).getInt(
-                    ThemeStorePrefKeys.KEY_STATUS_BAR_COLOR,
+                    ThemeStorePrefKeys.KEY_SECONDARY_COLOR,
                     primaryColor(context)
                 )
             } else {
-                prefs(context).getInt(
-                    ThemeStorePrefKeys.KEY_STATUS_BAR_COLOR,
-                    primaryColorDark(context)
-                )
+                primaryColor(context)
             }
         }
 
         @CheckResult
         @ColorInt
-        fun navigationBarColor(context: Context): Int {
-            return prefs(context).getInt(
-                ThemeStorePrefKeys.KEY_NAVIGATION_BAR_COLOR,
-                bottomBackground(context)
-            )
-        }
-
-        @CheckResult
-        @ColorInt
-        fun textColorPrimary(context: Context): Int {
-            return prefs(context).getInt(
-                ThemeStorePrefKeys.KEY_TEXT_COLOR_PRIMARY,
-                ThemeUtils.resolveColor(context, android.R.attr.textColorPrimary)
-            )
-        }
-
-        @CheckResult
-        @ColorInt
-        fun textColorPrimaryInverse(context: Context): Int {
-            return prefs(context).getInt(
-                ThemeStorePrefKeys.KEY_TEXT_COLOR_PRIMARY_INVERSE,
-                ThemeUtils.resolveColor(context, android.R.attr.textColorPrimaryInverse)
-            )
-        }
-
-        @CheckResult
-        @ColorInt
-        fun textColorSecondary(context: Context): Int {
-            return prefs(context).getInt(
-                ThemeStorePrefKeys.KEY_TEXT_COLOR_SECONDARY,
-                ThemeUtils.resolveColor(context, android.R.attr.textColorSecondary)
-            )
-        }
-
-        @CheckResult
-        @ColorInt
-        fun textColorSecondaryInverse(context: Context): Int {
-            return prefs(context).getInt(
-                ThemeStorePrefKeys.KEY_TEXT_COLOR_SECONDARY_INVERSE,
-                ThemeUtils.resolveColor(context, android.R.attr.textColorSecondaryInverse)
-            )
+        fun primaryColorDark(context: Context): Int {
+            return if (isCustomThemeEnabled(context)) {
+                prefs(context).getInt(
+                    ThemeStorePrefKeys.KEY_PRIMARY_COLOR_DARK,
+                    ThemeUtils.resolveColor(
+                        context,
+                        androidx.appcompat.R.attr.colorPrimaryDark,
+                        "#37474F".toColorInt()
+                    )
+                )
+            } else {
+                ThemeUtils.resolveColor(context, androidx.appcompat.R.attr.colorPrimaryDark)
+            }
         }
 
         @CheckResult
         @ColorInt
         fun backgroundColor(context: Context = appCtx): Int {
-            return prefs(context).getInt(
-                ThemeStorePrefKeys.KEY_BACKGROUND_COLOR,
+            return if (isCustomThemeEnabled(context)) {
+                prefs(context).getInt(
+                    ThemeStorePrefKeys.KEY_BACKGROUND_COLOR,
+                    ThemeUtils.resolveColor(context, android.R.attr.colorBackground)
+                )
+            } else {
                 ThemeUtils.resolveColor(context, android.R.attr.colorBackground)
-            )
+            }
         }
 
         @CheckResult
@@ -332,7 +244,7 @@ private constructor(private val mContext: Context) : ThemeStoreInterface {
             val prefs = prefs(context)
             val lastVersion = prefs.getInt(ThemeStorePrefKeys.IS_CONFIGURED_VERSION_KEY, -1)
             if (version > lastVersion) {
-                prefs.edit().putInt(ThemeStorePrefKeys.IS_CONFIGURED_VERSION_KEY, version).apply()
+                prefs.edit { putInt(ThemeStorePrefKeys.IS_CONFIGURED_VERSION_KEY, version) }
                 return false
             }
             return true

+ 1 - 51
app/src/main/java/io/legato/kazusa/lib/theme/ThemeStoreInterface.kt

@@ -26,57 +26,7 @@ internal interface ThemeStoreInterface {
 
     fun primaryColorDarkAttr(@AttrRes colorAttr: Int): ThemeStore
 
-    // Accent colors
-
-    fun accentColor(@ColorInt color: Int): ThemeStore
-
-    fun accentColorRes(@ColorRes colorRes: Int): ThemeStore
-
-    fun accentColorAttr(@AttrRes colorAttr: Int): ThemeStore
-
-    // Status bar color
-
-    fun statusBarColor(@ColorInt color: Int): ThemeStore
-
-    fun statusBarColorRes(@ColorRes colorRes: Int): ThemeStore
-
-    fun statusBarColorAttr(@AttrRes colorAttr: Int): ThemeStore
-
-    // Navigation bar color
-
-    fun navigationBarColor(@ColorInt color: Int): ThemeStore
-
-    fun navigationBarColorRes(@ColorRes colorRes: Int): ThemeStore
-
-    fun navigationBarColorAttr(@AttrRes colorAttr: Int): ThemeStore
-
-    // Primary text color
-
-    fun textColorPrimary(@ColorInt color: Int): ThemeStore
-
-    fun textColorPrimaryRes(@ColorRes colorRes: Int): ThemeStore
-
-    fun textColorPrimaryAttr(@AttrRes colorAttr: Int): ThemeStore
-
-    fun textColorPrimaryInverse(@ColorInt color: Int): ThemeStore
-
-    fun textColorPrimaryInverseRes(@ColorRes colorRes: Int): ThemeStore
-
-    fun textColorPrimaryInverseAttr(@AttrRes colorAttr: Int): ThemeStore
-
-    // Secondary text color
-
-    fun textColorSecondary(@ColorInt color: Int): ThemeStore
-
-    fun textColorSecondaryRes(@ColorRes colorRes: Int): ThemeStore
-
-    fun textColorSecondaryAttr(@AttrRes colorAttr: Int): ThemeStore
-
-    fun textColorSecondaryInverse(@ColorInt color: Int): ThemeStore
-
-    fun textColorSecondaryInverseRes(@ColorRes colorRes: Int): ThemeStore
-
-    fun textColorSecondaryInverseAttr(@AttrRes colorAttr: Int): ThemeStore
+    fun addColorScheme(@ColorInt color: Int): ThemeStore
 
     // Background
 

+ 2 - 11
app/src/main/java/io/legato/kazusa/lib/theme/ThemeStorePrefKeys.kt

@@ -9,21 +9,12 @@ object ThemeStorePrefKeys {
     const val IS_CONFIGURED_KEY = "is_configured"
     const val IS_CONFIGURED_VERSION_KEY = "is_configured_version"
     const val VALUES_CHANGED = "values_changed"
-
     const val KEY_PRIMARY_COLOR = "primary_color"
+    const val KEY_PRIMARY_CONTAINER_COLOR = "KEY_PRIMARY_CONTAINER_COLOR"
     const val KEY_PRIMARY_COLOR_DARK = "primary_color_dark"
-    const val KEY_ACCENT_COLOR = "accent_color"
-    const val KEY_STATUS_BAR_COLOR = "status_bar_color"
-    const val KEY_NAVIGATION_BAR_COLOR = "navigation_bar_color"
-
-    const val KEY_TEXT_COLOR_PRIMARY = "text_color_primary"
-    const val KEY_TEXT_COLOR_PRIMARY_INVERSE = "text_color_primary_inverse"
-    const val KEY_TEXT_COLOR_SECONDARY = "text_color_secondary"
-    const val KEY_TEXT_COLOR_SECONDARY_INVERSE = "text_color_secondary_inverse"
-
+    const val KEY_SECONDARY_COLOR = "KEY_SECONDARY_COLOR"
     const val KEY_BACKGROUND_COLOR = "backgroundColor"
     const val KEY_BOTTOM_BACKGROUND = "bottomBackground"
-
     const val KEY_APPLY_PRIMARYDARK_STATUSBAR = "apply_primarydark_statusbar"
     const val KEY_APPLY_PRIMARY_NAVBAR = "apply_primary_navbar"
     const val KEY_AUTO_GENERATE_PRIMARYDARK = "auto_generate_primarydark"

+ 48 - 6
app/src/main/java/io/legato/kazusa/ui/config/ThemeConfigFragment.kt

@@ -2,13 +2,18 @@ package io.legato.kazusa.ui.config
 
 //import io.legado.app.lib.theme.primaryColor
 import android.annotation.SuppressLint
+import android.app.Application
 import android.content.SharedPreferences
 import android.net.Uri
 import android.os.Bundle
+import android.os.Handler
+import android.os.Looper
 import android.view.View
 import android.widget.SeekBar
 import androidx.preference.Preference
 import androidx.preference.PreferenceFragmentCompat
+import com.google.android.material.color.DynamicColors
+import com.google.android.material.color.DynamicColorsOptions
 import io.legato.kazusa.R
 import io.legato.kazusa.base.AppContextWrapper
 import io.legato.kazusa.constant.EventBus
@@ -21,8 +26,11 @@ import io.legato.kazusa.help.config.ThemeConfig
 import io.legato.kazusa.lib.dialogs.alert
 import io.legato.kazusa.lib.dialogs.selector
 import io.legato.kazusa.lib.prefs.ColorPreference
+import io.legato.kazusa.lib.prefs.NameListPreference
 import io.legato.kazusa.lib.prefs.ThemeCardPreference
 import io.legato.kazusa.lib.prefs.ThemeModePreference
+import io.legato.kazusa.lib.theme.ThemeStore
+import io.legato.kazusa.lib.theme.primaryColor
 import io.legato.kazusa.ui.widget.number.NumberPickerDialog
 import io.legato.kazusa.ui.widget.seekbar.SeekBarChangeListener
 import io.legato.kazusa.utils.ColorUtils
@@ -38,6 +46,7 @@ import io.legato.kazusa.utils.putPrefInt
 import io.legato.kazusa.utils.putPrefString
 import io.legato.kazusa.utils.readUri
 import io.legato.kazusa.utils.removePref
+import io.legato.kazusa.utils.restart
 import io.legato.kazusa.utils.startActivity
 import io.legato.kazusa.utils.toastOnUi
 import splitties.init.appCtx
@@ -101,11 +110,25 @@ class ThemeConfigFragment : PreferenceFragmentCompat(),
             }
         }
 
-        findPreference<ThemeCardPreference>(PreferKey.themePref)?.let {
+        val themePref = findPreference<ThemeCardPreference>(PreferKey.themePref)
+        val colorPrimary = findPreference<ColorPreference>("colorPrimary")
+
+        val currentTheme = getPrefString("app_theme")
+        colorPrimary?.isVisible = currentTheme == "11"
+
+        val customMode = findPreference<NameListPreference>("customMode")
+        customMode?.isVisible = currentTheme == "11"
+        themePref?.let {
             it.setOnPreferenceChangeListener { _, _ ->
                 true
             }
         }
+
+        themePref?.setOnPreferenceChangeListener { _, newValue ->
+            colorPrimary?.isVisible = newValue == "11"
+            customMode?.isVisible = newValue == "11"
+            true
+        }
     }
 
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -136,19 +159,38 @@ class ThemeConfigFragment : PreferenceFragmentCompat(),
                 //recreateActivities()
             }
 
+            PreferKey.customMode -> {
+                Handler(Looper.getMainLooper()).postDelayed({
+                    requireContext().restart()
+                }, 300)
+            }
+
             PreferKey.pureBlack -> {
-                recreateActivities()
+                Handler(Looper.getMainLooper()).postDelayed({
+                    recreateActivities()
+                }, 300)
+            }
+
+            PreferKey.cPrimary -> {
+                val color = getPrefInt(key, ThemeStore.primaryColor(requireContext()))
+                ThemeStore.editTheme(requireContext())
+                    .primaryColor(color)
+                    .apply()
+                DynamicColors.applyToActivitiesIfAvailable(requireContext().applicationContext as Application, DynamicColorsOptions.Builder()
+                    .setContentBasedSource(requireContext().primaryColor)
+                    .build())
+                Handler(Looper.getMainLooper()).postDelayed({
+                    recreateActivities()
+                }, 300)
             }
 
-            PreferKey.cPrimary,
-            PreferKey.cAccent,
             PreferKey.cBackground,
             PreferKey.cBBackground -> {
                 upTheme(false)
             }
 
-            PreferKey.cNPrimary,
-            PreferKey.cNAccent,
+            //PreferKey.cNPrimary,
+
             PreferKey.cNBackground,
             PreferKey.cNBBackground -> {
                 upTheme(true)

+ 29 - 0
app/src/main/res/values-night/themes.xml

@@ -12,6 +12,35 @@
         <item name="alertDialogTheme">@style/AppTheme.AlertDialog</item>
     </style>
 
+    <style name="ThemeOverlay.WhiteBackground" parent="">
+        <item name="colorOnPrimary">@color/wh_theme_onPrimary</item>
+        <item name="colorOnSecondary">@color/wh_theme_onSecondary</item>
+        <item name="colorOnTertiary">@color/wh_theme_onTertiary</item>
+        <item name="colorOnTertiaryContainer">@color/wh_theme_onTertiaryContainer</item>
+        <item name="colorError">@color/wh_theme_error</item>
+        <item name="colorOnError">@color/wh_theme_onError</item>
+        <item name="colorErrorContainer">@color/wh_theme_errorContainer</item>
+        <item name="colorOnErrorContainer">@color/wh_theme_onErrorContainer</item>
+        <item name="android:colorBackground">@color/wh_theme_background</item>
+        <item name="colorOnBackground">@color/wh_theme_onBackground</item>
+        <item name="colorSurface">@color/wh_theme_surface</item>
+        <item name="colorOnSurface">@color/wh_theme_onSurface</item>
+        <item name="colorSurfaceVariant">@color/wh_theme_surfaceVariant</item>
+        <item name="colorOutlineVariant">@color/wh_theme_outlineVariant</item>
+        <item name="colorOnSurfaceInverse">@color/wh_theme_inverseOnSurface</item>
+        <item name="colorTertiaryFixed">@color/wh_theme_tertiaryFixed</item>
+        <item name="colorOnTertiaryFixed">@color/wh_theme_onTertiaryFixed</item>
+        <item name="colorTertiaryFixedDim">@color/wh_theme_tertiaryFixedDim</item>
+        <item name="colorOnTertiaryFixedVariant">@color/wh_theme_onTertiaryFixedVariant</item>
+        <item name="colorSurfaceDim">@color/wh_theme_surfaceDim</item>
+        <item name="colorSurfaceBright">@color/wh_theme_surfaceBright</item>
+        <item name="colorSurfaceContainerLowest">@color/wh_theme_surfaceContainerLowest</item>
+        <item name="colorSurfaceContainerLow">@color/wh_theme_surfaceContainerLow</item>
+        <item name="colorSurfaceContainer">@color/wh_theme_surfaceContainer</item>
+        <item name="colorSurfaceContainerHigh">@color/wh_theme_surfaceContainerHigh</item>
+        <item name="colorSurfaceContainerHighest">@color/wh_theme_surfaceContainerHighest</item>
+    </style>
+
     <style name="ThemeOverlay.PureBlack" parent="">
         <item name="android:colorBackground">@color/black</item>
         <item name="colorSurface">@color/black</item>

+ 3 - 3
app/src/main/res/values/colors.xml

@@ -66,9 +66,9 @@
     <color name="wh_theme_onError">#FFFFFF</color>
     <color name="wh_theme_errorContainer">#FFDAD6</color>
     <color name="wh_theme_onErrorContainer">#93000A</color>
-    <color name="wh_theme_background">#FCF8F8</color>
+    <color name="wh_theme_background">#FAFAFA</color>
     <color name="wh_theme_onBackground">#1C1B1B</color>
-    <color name="wh_theme_surface">#FCF8F8</color>
+    <color name="wh_theme_surface">#F8F8F8</color>
     <color name="wh_theme_onSurface">#1C1B1B</color>
     <color name="wh_theme_surfaceVariant">#E0E3E3</color>
     <color name="wh_theme_onSurfaceVariant">#444748</color>
@@ -91,7 +91,7 @@
     <color name="wh_theme_tertiaryFixedDim">#CBC5C7</color>
     <color name="wh_theme_onTertiaryFixedVariant">#494648</color>
     <color name="wh_theme_surfaceDim">#DDD9D8</color>
-    <color name="wh_theme_surfaceBright">#FCF8F8</color>
+    <color name="wh_theme_surfaceBright">#F8F8F8</color>
     <color name="wh_theme_surfaceContainerLowest">#FFFFFF</color>
     <color name="wh_theme_surfaceContainerLow">#F7F3F2</color>
     <color name="wh_theme_surfaceContainer">#F1EDEC</color>

+ 29 - 0
app/src/main/res/values/themes.xml

@@ -11,6 +11,35 @@
         <item name="alertDialogTheme">@style/AppTheme.AlertDialog</item>
     </style>
 
+    <style name="ThemeOverlay.WhiteBackground" parent="">
+        <item name="colorOnPrimary">@color/wh_theme_onPrimary</item>
+        <item name="colorOnSecondary">@color/wh_theme_onSecondary</item>
+        <item name="colorOnTertiary">@color/wh_theme_onTertiary</item>
+        <item name="colorOnTertiaryContainer">@color/wh_theme_onTertiaryContainer</item>
+        <item name="colorError">@color/wh_theme_error</item>
+        <item name="colorOnError">@color/wh_theme_onError</item>
+        <item name="colorErrorContainer">@color/wh_theme_errorContainer</item>
+        <item name="colorOnErrorContainer">@color/wh_theme_onErrorContainer</item>
+        <item name="android:colorBackground">@color/wh_theme_background</item>
+        <item name="colorOnBackground">@color/wh_theme_onBackground</item>
+        <item name="colorSurface">@color/wh_theme_surface</item>
+        <item name="colorOnSurface">@color/wh_theme_onSurface</item>
+        <item name="colorSurfaceVariant">@color/wh_theme_surfaceVariant</item>
+        <item name="colorOutlineVariant">@color/wh_theme_outlineVariant</item>
+        <item name="colorOnSurfaceInverse">@color/wh_theme_inverseOnSurface</item>
+        <item name="colorTertiaryFixed">@color/wh_theme_tertiaryFixed</item>
+        <item name="colorOnTertiaryFixed">@color/wh_theme_onTertiaryFixed</item>
+        <item name="colorTertiaryFixedDim">@color/wh_theme_tertiaryFixedDim</item>
+        <item name="colorOnTertiaryFixedVariant">@color/wh_theme_onTertiaryFixedVariant</item>
+        <item name="colorSurfaceDim">@color/wh_theme_surfaceDim</item>
+        <item name="colorSurfaceBright">@color/wh_theme_surfaceBright</item>
+        <item name="colorSurfaceContainerLowest">@color/wh_theme_surfaceContainerLowest</item>
+        <item name="colorSurfaceContainerLow">@color/wh_theme_surfaceContainerLow</item>
+        <item name="colorSurfaceContainer">@color/wh_theme_surfaceContainer</item>
+        <item name="colorSurfaceContainerHigh">@color/wh_theme_surfaceContainerHigh</item>
+        <item name="colorSurfaceContainerHighest">@color/wh_theme_surfaceContainerHighest</item>
+    </style>
+
     <style name="ThemeOverlay.PureBlack" parent="">
 
     </style>

+ 24 - 31
app/src/main/res/xml/pref_config_theme.xml

@@ -33,7 +33,22 @@
         <io.legato.kazusa.lib.prefs.SwitchPreference
             android:defaultValue="false"
             android:key="pure_black"
-            android:title="纯黑暗色模式" />
+            android:title="纯黑深色模式" />
+
+        <io.legato.kazusa.lib.prefs.ColorPreference
+            android:defaultValue="@color/md_green_500"
+            android:key="colorPrimary"
+            android:summary="使用种子颜色创建主题"
+            android:title="种子色"
+            app:cpv_dialogType="preset"
+            app:iconSpaceReserved="false" />
+
+        <io.legato.kazusa.lib.prefs.NameListPreference
+            android:defaultValue="global"
+            android:key="customMode"
+            android:title="自定义模式"
+            app:entries="@array/customMode"
+            app:entryValues="@array/customMode_value" />
 
         <io.legato.kazusa.lib.prefs.IconListPreference
             android:defaultValue="ic_launcher"
@@ -67,52 +82,30 @@
             app:iconSpaceReserved="false" />
 
         <io.legato.kazusa.lib.prefs.Preference
-            android:key="themeList"
-            android:summary="@string/theme_list_summary"
-            android:title="@string/theme_list"
-            app:allowDividerAbove="false"
-            app:allowDividerBelow="false"
-            app:iconSpaceReserved="false" />
+            android:key="backgroundImage"
+            android:title="@string/background_image" />
 
     </io.legato.kazusa.lib.prefs.PreferenceCategory>
 
     <io.legato.kazusa.lib.prefs.PreferenceCategory
         android:key="dayThemeCategory"
-        android:title="@string/day"
+        android:title="@string/share"
         app:allowDividerAbove="true"
         app:allowDividerBelow="false"
         app:iconSpaceReserved="false"
         app:layout="@layout/view_preference_category">
 
         <io.legato.kazusa.lib.prefs.Preference
-            android:key="backgroundImage"
-            android:title="@string/background_image" />
-
-        <io.legato.kazusa.lib.prefs.Preference
-            android:key="saveDayTheme"
-            android:summary="@string/save_day_theme_summary"
-            android:title="@string/save_theme_config"
+            android:key="themeList"
+            android:summary="@string/theme_list_summary"
+            android:title="@string/theme_list"
             app:allowDividerAbove="false"
             app:allowDividerBelow="false"
             app:iconSpaceReserved="false" />
 
-    </io.legato.kazusa.lib.prefs.PreferenceCategory>
-
-    <io.legato.kazusa.lib.prefs.PreferenceCategory
-        android:key="nightThemeCategory"
-        android:title="@string/night"
-        app:allowDividerAbove="true"
-        app:allowDividerBelow="false"
-        app:iconSpaceReserved="false"
-        app:layout="@layout/view_preference_category">
-
-        <io.legato.kazusa.lib.prefs.Preference
-            android:key="backgroundImageNight"
-            android:title="@string/background_image" />
-
         <io.legato.kazusa.lib.prefs.Preference
-            android:key="saveNightTheme"
-            android:summary="@string/save_night_theme_summary"
+            android:key="saveDayTheme"
+            android:summary="@string/save_day_theme_summary"
             android:title="@string/save_theme_config"
             app:allowDividerAbove="false"
             app:allowDividerBelow="false"