Color schemes
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
96
app/src/main/res/layout/item_color_scheme.xml
Normal file
96
app/src/main/res/layout/item_color_scheme.xml
Normal 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>
|
||||
76
app/src/main/res/layout/preference_theme.xml
Normal file
76
app/src/main/res/layout/preference_theme.xml
Normal 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>
|
||||
61
app/src/main/res/values-night-v23/color_themes.xml
Normal file
61
app/src/main/res/values-night-v23/color_themes.xml
Normal 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>
|
||||
@@ -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>
|
||||
|
||||
4
app/src/main/res/values-v23/bools.xml
Normal file
4
app/src/main/res/values-v23/bools.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<bool name="is_color_themes_available">true</bool>
|
||||
</resources>
|
||||
61
app/src/main/res/values-v23/color_themes.xml
Normal file
61
app/src/main/res/values-v23/color_themes.xml
Normal 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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
7
app/src/main/res/values/color_themes.xml
Normal file
7
app/src/main/res/values/color_themes.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="Theme.Kotatsu.Mint" />
|
||||
|
||||
<style name="Theme.Kotatsu.October" />
|
||||
</resources>
|
||||
@@ -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>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user