Color schemes

This commit is contained in:
Koitharu
2023-02-03 19:39:14 +02:00
parent fd26de7619
commit 35b8003cf9
21 changed files with 564 additions and 204 deletions

View File

@@ -12,6 +12,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ActionMode
import androidx.appcompat.widget.ActionBarContextView
import androidx.appcompat.widget.Toolbar
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.graphics.ColorUtils
import androidx.core.view.ViewCompat
@@ -51,12 +52,9 @@ abstract class BaseActivity<B : ViewBinding> :
override fun onCreate(savedInstanceState: Bundle?) {
EntryPointAccessors.fromApplication(this, BaseActivityEntryPoint::class.java).inject(this)
val isAmoled = settings.isAmoledTheme
val isDynamic = settings.isDynamicTheme
when {
isAmoled && isDynamic -> setTheme(R.style.Theme_Kotatsu_Monet_Amoled)
isAmoled -> setTheme(R.style.Theme_Kotatsu_Amoled)
isDynamic -> setTheme(R.style.Theme_Kotatsu_Monet)
setTheme(settings.colorScheme.styleResId)
if (settings.isAmoledTheme) {
setTheme(R.style.ThemeOverlay_Kotatsu_Amoled)
}
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)
@@ -89,9 +87,8 @@ abstract class BaseActivity<B : ViewBinding> :
} else super.onOptionsItemSelected(item)
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
if (BuildConfig.DEBUG && keyCode == KeyEvent.KEYCODE_VOLUME_UP) { // TODO remove
// ActivityCompat.recreate(this)
TODO("Test error")
if (BuildConfig.DEBUG && keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
ActivityCompat.recreate(this)
return true
}
return super.onKeyDown(keyCode, event)

View File

@@ -1,119 +0,0 @@
package org.koitharu.kotatsu.base.ui.widgets
import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.annotation.AttrRes
import androidx.annotation.IdRes
import androidx.core.view.children
import com.google.android.material.R as materialR
import com.google.android.material.button.MaterialButton
import com.google.android.material.shape.ShapeAppearanceModel
class CheckableButtonGroup @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
@AttrRes defStyleAttr: Int = materialR.attr.materialButtonToggleGroupStyle,
) : LinearLayout(context, attrs, defStyleAttr, materialR.style.Widget_MaterialComponents_MaterialButtonToggleGroup),
View.OnClickListener {
private val originalCornerData = ArrayList<CornerData>()
var onCheckedChangeListener: OnCheckedChangeListener? = null
override fun addView(child: View?, index: Int, params: ViewGroup.LayoutParams?) {
if (child is MaterialButton) {
setupButton(child)
}
super.addView(child, index, params)
}
override fun onFinishInflate() {
super.onFinishInflate()
updateChildShapes()
}
override fun onClick(v: View) {
setCheckedId(v.id)
}
fun setCheckedId(@IdRes viewRes: Int) {
children.forEach {
(it as? MaterialButton)?.isChecked = it.id == viewRes
}
onCheckedChangeListener?.onCheckedChanged(this, viewRes)
}
private fun updateChildShapes() {
val childCount = childCount
val firstVisibleChildIndex = 0
val lastVisibleChildIndex = childCount - 1
for (i in 0 until childCount) {
val button: MaterialButton = getChildAt(i) as? MaterialButton ?: continue
if (button.visibility == GONE) {
continue
}
val builder = button.shapeAppearanceModel.toBuilder()
val newCornerData: CornerData? =
getNewCornerData(i, firstVisibleChildIndex, lastVisibleChildIndex)
updateBuilderWithCornerData(builder, newCornerData)
button.shapeAppearanceModel = builder.build()
}
}
private fun setupButton(button: MaterialButton) {
button.setOnClickListener(this)
button.isElegantTextHeight = false
// Saves original corner data
val shapeAppearanceModel: ShapeAppearanceModel = button.shapeAppearanceModel
originalCornerData.add(
CornerData(
shapeAppearanceModel.topLeftCornerSize,
shapeAppearanceModel.bottomLeftCornerSize,
shapeAppearanceModel.topRightCornerSize,
shapeAppearanceModel.bottomRightCornerSize,
),
)
}
private fun getNewCornerData(
index: Int,
firstVisibleChildIndex: Int,
lastVisibleChildIndex: Int,
): CornerData? {
val cornerData: CornerData = originalCornerData.get(index)
// If only one (visible) child exists, use its original corners
if (firstVisibleChildIndex == lastVisibleChildIndex) {
return cornerData
}
val isHorizontal = orientation == HORIZONTAL
if (index == firstVisibleChildIndex) {
return if (isHorizontal) cornerData.start(this) else cornerData.top()
}
return if (index == lastVisibleChildIndex) {
if (isHorizontal) cornerData.end(this) else cornerData.bottom()
} else null
}
private fun updateBuilderWithCornerData(
shapeAppearanceModelBuilder: ShapeAppearanceModel.Builder,
cornerData: CornerData?,
) {
if (cornerData == null) {
shapeAppearanceModelBuilder.setAllCornerSizes(0f)
return
}
shapeAppearanceModelBuilder
.setTopLeftCornerSize(cornerData.topLeft)
.setBottomLeftCornerSize(cornerData.bottomLeft)
.setTopRightCornerSize(cornerData.topRight)
.setBottomRightCornerSize(cornerData.bottomRight)
}
fun interface OnCheckedChangeListener {
fun onCheckedChanged(group: CheckableButtonGroup, checkedId: Int)
}
}

View File

@@ -1,47 +0,0 @@
package org.koitharu.kotatsu.base.ui.widgets
import android.view.View
import androidx.core.view.ViewCompat
import com.google.android.material.shape.AbsoluteCornerSize
import com.google.android.material.shape.CornerSize
class CornerData(
var topLeft: CornerSize,
var bottomLeft: CornerSize,
var topRight: CornerSize,
var bottomRight: CornerSize,
) {
fun start(view: View): CornerData {
return if (isLayoutRtl(view)) right() else left()
}
fun end(view: View): CornerData {
return if (isLayoutRtl(view)) left() else right()
}
fun left(): CornerData {
return CornerData(topLeft, bottomLeft, noCorner, noCorner)
}
fun right(): CornerData {
return CornerData(noCorner, noCorner, topRight, bottomRight)
}
fun top(): CornerData {
return CornerData(topLeft, noCorner, topRight, noCorner)
}
fun bottom(): CornerData {
return CornerData(noCorner, bottomLeft, noCorner, bottomRight)
}
private companion object {
val noCorner: CornerSize = AbsoluteCornerSize(0f)
fun isLayoutRtl(view: View): Boolean {
return ViewCompat.getLayoutDirection(view) == ViewCompat.LAYOUT_DIRECTION_RTL
}
}
}

View File

@@ -0,0 +1,94 @@
package org.koitharu.kotatsu.base.ui.widgets
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Outline
import android.graphics.Paint
import android.graphics.Path
import android.util.AttributeSet
import android.view.View
import android.view.ViewOutlineProvider
import androidx.core.content.withStyledAttributes
import androidx.core.graphics.withClip
import com.google.android.material.drawable.DrawableUtils
import org.koitharu.kotatsu.R
class ShapeView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
) : View(context, attrs, defStyleAttr) {
private val corners = FloatArray(8)
private val outlinePath = Path()
private val strokePaint = Paint(Paint.ANTI_ALIAS_FLAG)
init {
context.withStyledAttributes(attrs, R.styleable.ShapeView, defStyleAttr) {
val cornerSize = getDimension(R.styleable.ShapeView_cornerSize, 0f)
corners[0] = getDimension(R.styleable.ShapeView_cornerSizeTopLeft, cornerSize)
corners[1] = corners[0]
corners[2] = getDimension(R.styleable.ShapeView_cornerSizeTopRight, cornerSize)
corners[3] = corners[2]
corners[4] = getDimension(R.styleable.ShapeView_cornerSizeBottomRight, cornerSize)
corners[5] = corners[4]
corners[6] = getDimension(R.styleable.ShapeView_cornerSizeBottomLeft, cornerSize)
corners[7] = corners[6]
strokePaint.color = getColor(R.styleable.ShapeView_strokeColor, Color.TRANSPARENT)
strokePaint.strokeWidth = getDimension(R.styleable.ShapeView_strokeWidth, 0f)
strokePaint.style = Paint.Style.STROKE
}
outlineProvider = OutlineProvider()
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
if (w != oldw || h != oldh) {
rebuildPath()
}
}
override fun draw(canvas: Canvas) {
canvas.withClip(outlinePath) {
super.draw(canvas)
}
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
if (strokePaint.strokeWidth > 0f) {
canvas.drawPath(outlinePath, strokePaint)
}
}
private fun rebuildPath() {
outlinePath.reset()
val w = width
val h = height
if (w > 0 && h > 0) {
outlinePath.addRoundRect(0f, 0f, w.toFloat(), h.toFloat(), corners, Path.Direction.CW)
}
}
private inner class OutlineProvider : ViewOutlineProvider() {
@SuppressLint("RestrictedApi")
override fun getOutline(view: View?, outline: Outline) {
val corner = corners[0]
var isRoundRect = true
for (item in corners) {
if (item != corner) {
isRoundRect = false
break
}
}
if (isRoundRect) {
outline.setRoundRect(0, 0, width, height, corner)
} else {
DrawableUtils.setOutlineToPath(outline, outlinePath)
}
}
}
}

View File

@@ -9,7 +9,6 @@ import androidx.collection.arraySetOf
import androidx.core.content.edit
import androidx.core.os.LocaleListCompat
import androidx.preference.PreferenceManager
import com.google.android.material.color.DynamicColors
import dagger.hilt.android.qualifiers.ApplicationContext
import org.koitharu.kotatsu.BuildConfig
import org.koitharu.kotatsu.core.model.ZoomMode
@@ -70,8 +69,8 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
val theme: Int
get() = prefs.getString(KEY_THEME, null)?.toIntOrNull() ?: AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
val isDynamicTheme: Boolean
get() = DynamicColors.isDynamicColorAvailable() && prefs.getBoolean(KEY_DYNAMIC_THEME, false)
val colorScheme: ColorScheme
get() = prefs.getEnumValue(KEY_COLOR_THEME, ColorScheme.default)
val isAmoledTheme: Boolean
get() = prefs.getBoolean(KEY_THEME_AMOLED, false)
@@ -312,7 +311,7 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
const val KEY_LIST_MODE = "list_mode_2"
const val KEY_THEME = "theme"
const val KEY_DYNAMIC_THEME = "dynamic_theme"
const val KEY_COLOR_THEME = "color_theme"
const val KEY_THEME_AMOLED = "amoled_theme"
const val KEY_DATE_FORMAT = "date_format"
const val KEY_SOURCES_ORDER = "sources_order_2"

View File

@@ -0,0 +1,40 @@
package org.koitharu.kotatsu.core.prefs
import androidx.annotation.StringRes
import androidx.annotation.StyleRes
import com.google.android.material.color.DynamicColors
import org.koitharu.kotatsu.R
enum class ColorScheme(
@StyleRes val styleResId: Int,
@StringRes val titleResId: Int,
) {
DEFAULT(R.style.Theme_Kotatsu, R.string.system_default),
MONET(R.style.Theme_Kotatsu_Monet, R.string.theme_name_dynamic),
MINT(R.style.Theme_Kotatsu_Mint, R.string.theme_name_mint),
OCTOBER(R.style.Theme_Kotatsu_October, R.string.theme_name_october),
;
companion object {
val default: ColorScheme
get() = if (DynamicColors.isDynamicColorAvailable()) {
MONET
} else {
DEFAULT
}
fun getAvailableList(): List<ColorScheme> {
val list = enumValues<ColorScheme>().toMutableList()
if (!DynamicColors.isDynamicColorAvailable()) {
list.remove(MONET)
}
return list
}
fun safeValueOf(name: String): ColorScheme? {
return enumValues<ColorScheme>().find { it.name == name }
}
}
}

View File

@@ -14,7 +14,6 @@ import androidx.core.view.postDelayed
import androidx.preference.ListPreference
import androidx.preference.Preference
import androidx.preference.TwoStatePreference
import com.google.android.material.color.DynamicColors
import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.base.ui.BasePreferenceFragment
@@ -56,7 +55,6 @@ class AppearanceSettingsFragment :
entryValues = ListMode.values().names()
setDefaultValueCompat(ListMode.GRID.name)
}
findPreference<Preference>(AppSettings.KEY_DYNAMIC_THEME)?.isVisible = DynamicColors.isDynamicColorAvailable()
findPreference<ListPreference>(AppSettings.KEY_DATE_FORMAT)?.run {
entryValues = resources.getStringArray(R.array.date_formats)
val now = Date().time
@@ -105,10 +103,7 @@ class AppearanceSettingsFragment :
AppCompatDelegate.setDefaultNightMode(settings.theme)
}
AppSettings.KEY_DYNAMIC_THEME -> {
postRestart()
}
AppSettings.KEY_COLOR_THEME,
AppSettings.KEY_THEME_AMOLED -> {
postRestart()
}

View File

@@ -0,0 +1,84 @@
package org.koitharu.kotatsu.settings.utils
import android.content.Context
import android.content.res.TypedArray
import android.os.Build
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.LinearLayout
import androidx.appcompat.view.ContextThemeWrapper
import androidx.core.view.isVisible
import androidx.preference.Preference
import androidx.preference.PreferenceViewHolder
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.prefs.ColorScheme
import org.koitharu.kotatsu.databinding.ItemColorSchemeBinding
class ThemeChooserPreference @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = R.attr.themeChooserPreferenceStyle,
defStyleRes: Int = R.style.Preference_ThemeChooser,
) : Preference(context, attrs, defStyleAttr, defStyleRes) {
private val entries = ColorScheme.getAvailableList()
private var currentValue: ColorScheme = ColorScheme.default
private val itemClickListener = View.OnClickListener {
val tag = it.tag as? ColorScheme ?: return@OnClickListener
setValueInternal(tag.name, true)
}
var value: String
get() = currentValue.name
set(value) = setValueInternal(value, notifyChanged = true)
override fun onBindViewHolder(holder: PreferenceViewHolder) {
super.onBindViewHolder(holder)
val layout = holder.findViewById(R.id.linear) as? LinearLayout ?: return
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
layout.suppressLayout(true)
}
layout.removeAllViews()
for (theme in entries) {
val context = ContextThemeWrapper(context, theme.styleResId)
val item = ItemColorSchemeBinding.inflate(LayoutInflater.from(context), layout, false)
item.card.isChecked = theme == currentValue
item.textViewTitle.setText(theme.titleResId)
item.root.tag = theme
item.card.tag = theme
item.imageViewCheck.isVisible = theme == currentValue
item.root.setOnClickListener(itemClickListener)
item.card.setOnClickListener(itemClickListener)
layout.addView(item.root)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
layout.suppressLayout(false)
}
}
override fun onSetInitialValue(defaultValue: Any?) {
value = getPersistedString(
when (defaultValue) {
is String -> ColorScheme.safeValueOf(defaultValue) ?: ColorScheme.default
is ColorScheme -> defaultValue
else -> ColorScheme.default
}.name,
)
}
override fun onGetDefaultValue(a: TypedArray, index: Int): Any {
return a.getInt(index, 0)
}
private fun setValueInternal(enumName: String, notifyChanged: Boolean) {
val newValue = ColorScheme.safeValueOf(enumName) ?: return
if (newValue != currentValue) {
currentValue = newValue
persistString(newValue.name)
if (notifyChanged) {
notifyChanged()
}
}
}
}

View File

@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
android:orientation="vertical"
android:padding="6dp"
tools:theme="@style/Theme.Kotatsu.Mint">
<com.google.android.material.card.MaterialCardView
android:id="@+id/card"
style="?materialCardViewFilledStyle"
android:layout_width="@dimen/widget_cover_width"
android:layout_height="@dimen/widget_cover_height"
android:focusableInTouchMode="false">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="6dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Abc"
android:textSize="12sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
<org.koitharu.kotatsu.base.ui.widgets.ShapeView
android:id="@+id/shape_1"
android:layout_width="0dp"
android:layout_height="6dp"
android:layout_marginBottom="6dp"
android:background="?colorSecondary"
app:cornerSize="4dp"
app:layout_constraintBottom_toTopOf="@id/shape_2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintWidth_percent="0.4" />
<org.koitharu.kotatsu.base.ui.widgets.ShapeView
android:id="@+id/shape_2"
android:layout_width="0dp"
android:layout_height="6dp"
android:background="?colorSecondary"
app:cornerSize="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.65"
app:layout_constraintWidth_percent="0.7" />
<org.koitharu.kotatsu.base.ui.widgets.ShapeView
android:layout_width="16dp"
android:layout_height="16dp"
android:background="?colorPrimary"
app:cornerSize="6dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<ImageView
android:id="@+id/imageView_check"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|end"
android:layout_margin="6dp"
android:visibility="gone"
app:srcCompat="@drawable/ic_mtrl_checked_circle"
app:tint="?colorPrimary"
tools:visibility="visible" />
</com.google.android.material.card.MaterialCardView>
<TextView
android:id="@+id/textView_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elegantTextHeight="false"
android:ellipsize="end"
android:paddingTop="4dp"
android:singleLine="true"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?android:attr/textColorPrimary"
tools:text="@string/theme_name_mint" />
</LinearLayout>

View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:clipChildren="false"
android:clipToPadding="false"
android:gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:orientation="horizontal"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
tools:ignore="PrivateResource">
<include layout="@layout/image_frame" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:clipChildren="false"
android:clipToPadding="false"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="true"
android:baselineAlignedChildIndex="0"
android:orientation="horizontal">
<TextView
android:id="@android:id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="marquee"
android:labelFor="@id/seekbar"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceListItem"
tools:ignore="LabelFor" />
<TextView
android:id="@android:id/summary"
style="@style/PreferenceSummaryTextStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAlignment="viewStart"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:clipToPadding="false"
android:paddingStart="0dp"
android:paddingEnd="16dp"
android:scrollIndicators="start|end"
android:scrollbars="none"
tools:ignore="UnusedAttribute">
<LinearLayout
android:id="@+id/linear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" />
</HorizontalScrollView>
</LinearLayout>
</LinearLayout>

View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Colored themes -->
<style name="Theme.Kotatsu.Mint">
<item name="colorPrimary">#4CDBCE</item>
<item name="colorOnPrimary">#003733</item>
<item name="colorPrimaryContainer">#00504A</item>
<item name="colorOnPrimaryContainer">#6EF8EA</item>
<item name="colorSecondary">#B1CCC8</item>
<item name="colorOnSecondary">#1C3532</item>
<item name="colorSecondaryContainer">#324B48</item>
<item name="colorOnSecondaryContainer">#CCE8E4</item>
<item name="colorTertiary">#AFC9E7</item>
<item name="colorOnTertiary">#17324A</item>
<item name="colorTertiaryContainer">#2F4961</item>
<item name="colorOnTertiaryContainer">#CEE5FF</item>
<item name="colorError">#FFB4AB</item>
<item name="colorErrorContainer">#93000A</item>
<item name="colorOnError">#690005</item>
<item name="colorOnErrorContainer">#FFDAD6</item>
<item name="android:colorBackground">#191C1C</item>
<item name="colorOnBackground">#E0E3E1</item>
<item name="colorSurface">#191C1C</item>
<item name="colorOnSurface">#E0E3E1</item>
<item name="colorSurfaceVariant">#3F4947</item>
<item name="colorOnSurfaceVariant">#BEC9C6</item>
<item name="colorOutline">#899391</item>
<item name="colorOnSurfaceInverse">#191C1C</item>
<item name="colorSurfaceInverse">#E0E3E1</item>
<item name="colorPrimaryInverse">#006A63</item>
</style>
<style name="Theme.Kotatsu.October">
<item name="colorPrimary">#FFB3AF</item>
<item name="colorOnPrimary">#68000E</item>
<item name="colorPrimaryContainer">#930018</item>
<item name="colorOnPrimaryContainer">#FFDAD7</item>
<item name="colorSecondary">#FFB783</item>
<item name="colorOnSecondary">#4F2500</item>
<item name="colorSecondaryContainer">#713700</item>
<item name="colorOnSecondaryContainer">#FFDCC5</item>
<item name="colorTertiary">#E2C28C</item>
<item name="colorOnTertiary">#412D05</item>
<item name="colorTertiaryContainer">#594319</item>
<item name="colorOnTertiaryContainer">#FFDEA9</item>
<item name="colorError">#FFB4AB</item>
<item name="colorErrorContainer">#93000A</item>
<item name="colorOnError">#690005</item>
<item name="colorOnErrorContainer">#FFDAD6</item>
<item name="android:colorBackground">#201A1A</item>
<item name="colorOnBackground">#EDE0DE</item>
<item name="colorSurface">#201A1A</item>
<item name="colorOnSurface">#EDE0DE</item>
<item name="colorSurfaceVariant">#534342</item>
<item name="colorOnSurfaceVariant">#D8C1C0</item>
<item name="colorOutline">#A08C8B</item>
<item name="colorOnSurfaceInverse">#201A1A</item>
<item name="colorSurfaceInverse">#EDE0DE</item>
<item name="colorPrimaryInverse">#BA1928</item>
</style>
</resources>

View File

@@ -3,14 +3,9 @@
<style name="ThemeOverlay.Kotatsu" parent="ThemeOverlay.Material3.Dark" />
<style name="Theme.Kotatsu.Amoled">
<style name="ThemeOverlay.Kotatsu.Amoled" parent="">
<item name="colorSurface">@color/surface_amoled</item>
<item name="android:colorBackground">@color/background_amoled</item>
</style>
<style name="Theme.Kotatsu.Monet.Amoled">
<item name="colorSurface">@color/surface_amoled</item>
<item name="android:colorBackground">@color/background_amoled</item>
</style>
</resources>
</resources>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="is_color_themes_available">true</bool>
</resources>

View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Colored themes -->
<style name="Theme.Kotatsu.Mint">
<item name="colorPrimary">#006A63</item>
<item name="colorOnPrimary">#FFFFFF</item>
<item name="colorPrimaryContainer">#6EF8EA</item>
<item name="colorOnPrimaryContainer">#00201D</item>
<item name="colorSecondary">#4A6360</item>
<item name="colorOnSecondary">#FFFFFF</item>
<item name="colorSecondaryContainer">#CCE8E4</item>
<item name="colorOnSecondaryContainer">#051F1D</item>
<item name="colorTertiary">#47617A</item>
<item name="colorOnTertiary">#FFFFFF</item>
<item name="colorTertiaryContainer">#CEE5FF</item>
<item name="colorOnTertiaryContainer">#001D33</item>
<item name="colorError">#BA1A1A</item>
<item name="colorErrorContainer">#FFDAD6</item>
<item name="colorOnError">#FFFFFF</item>
<item name="colorOnErrorContainer">#410002</item>
<item name="android:colorBackground">#FAFDFB</item>
<item name="colorOnBackground">#191C1C</item>
<item name="colorSurface">#FAFDFB</item>
<item name="colorOnSurface">#191C1C</item>
<item name="colorSurfaceVariant">#DAE5E2</item>
<item name="colorOnSurfaceVariant">#3F4947</item>
<item name="colorOutline">#6F7977</item>
<item name="colorOnSurfaceInverse">#EFF1F0</item>
<item name="colorSurfaceInverse">#2D3130</item>
<item name="colorPrimaryInverse">#4CDBCE</item>
</style>
<style name="Theme.Kotatsu.October">
<item name="colorPrimary">#BA1928</item>
<item name="colorOnPrimary">#FFFFFF</item>
<item name="colorPrimaryContainer">#FFDAD7</item>
<item name="colorOnPrimaryContainer">#410005</item>
<item name="colorSecondary">#944B00</item>
<item name="colorOnSecondary">#FFFFFF</item>
<item name="colorSecondaryContainer">#FFDCC5</item>
<item name="colorOnSecondaryContainer">#301400</item>
<item name="colorTertiary">#735B2E</item>
<item name="colorOnTertiary">#FFFFFF</item>
<item name="colorTertiaryContainer">#FFDEA9</item>
<item name="colorOnTertiaryContainer">#271900</item>
<item name="colorError">#BA1A1A</item>
<item name="colorErrorContainer">#FFDAD6</item>
<item name="colorOnError">#FFFFFF</item>
<item name="colorOnErrorContainer">#410002</item>
<item name="android:colorBackground">#FFFBFF</item>
<item name="colorOnBackground">#201A1A</item>
<item name="colorSurface">#FFFBFF</item>
<item name="colorOnSurface">#201A1A</item>
<item name="colorSurfaceVariant">#F4DDDB</item>
<item name="colorOnSurfaceVariant">#534342</item>
<item name="colorOutline">#857372</item>
<item name="colorOnSurfaceInverse">#FBEEEC</item>
<item name="colorSurfaceInverse">#362F2E</item>
<item name="colorPrimaryInverse">#FFB3AF</item>
</style>
</resources>

View File

@@ -4,6 +4,7 @@
<attr name="sliderPreferenceStyle" />
<attr name="multiAutoCompleteTextViewPreferenceStyle" />
<attr name="autoCompleteTextViewPreferenceStyle" />
<attr name="themeChooserPreferenceStyle" />
<attr name="listItemTextViewStyle" />
<attr name="fastScrollerStyle" />
@@ -75,4 +76,14 @@
<attr name="fitStatusBar" format="boolean" />
</declare-styleable>
<declare-styleable name="ShapeView">
<attr name="strokeWidth" />
<attr name="strokeColor" />
<attr name="cornerSize" />
<attr name="cornerSizeTopLeft" />
<attr name="cornerSizeTopRight" />
<attr name="cornerSizeBottomLeft" />
<attr name="cornerSizeBottomRight" />
</declare-styleable>
</resources>

View File

@@ -4,4 +4,5 @@
<bool name="light_status_bar">true</bool>
<bool name="light_navigation_bar">false</bool>
<bool name="com_samsung_android_icon_container_has_icon_container">true</bool>
<bool name="is_color_themes_available">false</bool>
</resources>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.Kotatsu.Mint" />
<style name="Theme.Kotatsu.October" />
</resources>

View File

@@ -407,4 +407,8 @@
<string name="enable_logging">Enable logging</string>
<string name="enable_logging_summary">Record some actions for debug purposes</string>
<string name="show_suspicious_content">Show suspicious content</string>
<string name="theme_name_mint">Mint</string>
<string name="theme_name_dynamic">Dynamic</string>
<string name="color_theme">Color scheme</string>
<string name="theme_name_october">October</string>
</resources>

View File

@@ -255,6 +255,11 @@
<item name="android:widgetLayout">@layout/preference_widget_material_switch</item>
</style>
<style name="Preference.ThemeChooser" parent="Preference.Material">
<item name="android:layout">@layout/preference_theme</item>
<item name="android:selectable">false</item>
</style>
<!-- Progress drawable -->
<style name="ProgressDrawable">

View File

@@ -87,12 +87,10 @@
<!-- Monet theme only support S+ -->
<style name="Theme.Kotatsu.Monet" />
<style name="Theme.Kotatsu.Amoled" />
<style name="Theme.Kotatsu.Monet.Amoled" />
<style name="ThemeOverlay.Kotatsu" parent="ThemeOverlay.Material3.Light" />
<style name="ThemeOverlay.Kotatsu.Amoled" parent="" />
<style name="Theme.Kotatsu.Dialog" parent="">
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>

View File

@@ -11,12 +11,10 @@
android:title="@string/theme"
app:useSimpleSummaryProvider="true" />
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="dynamic_theme"
android:summary="@string/dynamic_theme_summary"
android:title="@string/dynamic_theme"
app:isPreferenceVisible="false" />
<org.koitharu.kotatsu.settings.utils.ThemeChooserPreference
android:key="color_theme"
android:title="@string/color_theme"
app:isPreferenceVisible="@bool/is_color_themes_available" />
<SwitchPreferenceCompat
android:defaultValue="false"
@@ -26,7 +24,8 @@
<org.koitharu.kotatsu.settings.utils.ActivityListPreference
android:key="app_locale"
android:title="@string/language" />
android:title="@string/language"
app:allowDividerAbove="true" />
<ListPreference
android:key="date_format"
@@ -36,7 +35,6 @@
android:entries="@array/list_modes"
android:key="list_mode_2"
android:title="@string/list_mode"
app:allowDividerAbove="true"
app:useSimpleSummaryProvider="true" />
<org.koitharu.kotatsu.settings.utils.SliderPreference