Skip to content

Commit

Permalink
Fix: custom theme color in various AndroidView (#656)
Browse files Browse the repository at this point in the history
* Fix: background color of download list when using custom theme

* Fix background color in Migration's source list

* Fix custom theme color in manga's Edit Info

* Fix custom theme color in manga's Migration Config

* Fix custom theme color in manga's Migration Config

* Fix custom theme color & relayout merge setting's dialog

* using CustomColorScheme for DownloadQueue

* using CustomColorScheme for metadata source
  • Loading branch information
cuong-tran authored Jan 25, 2025
1 parent c7c76d2 commit 5b77536
Show file tree
Hide file tree
Showing 24 changed files with 512 additions and 280 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package eu.kanade.presentation.components

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.TextView
import androidx.annotation.LayoutRes
import eu.kanade.presentation.theme.colorscheme.AndroidViewColorScheme

// KMK -->
internal class SpinnerAdapter(
context: Context,
@LayoutRes val resource: Int,
objects: List<String>,
val colorScheme: AndroidViewColorScheme,
) : ArrayAdapter<String>(context, resource, objects) {
private val mInflater = LayoutInflater.from(context)

override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
return createViewFromResource(mInflater, position, convertView, parent, resource)
}

override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View {
return createViewFromResource(mInflater, position, convertView, parent, resource)
}

private fun createViewFromResource(
inflater: LayoutInflater,
position: Int,
convertView: View?,
parent: ViewGroup,
resource: Int,
): View {
val text: TextView

val view = convertView ?: inflater.inflate(resource, parent, false)

try {
// If no custom field is assigned, assume the whole resource is a TextView
text = view as TextView
} catch (e: ClassCastException) {
throw IllegalStateException("ArrayAdapter requires the resource ID to be a TextView", e)
}

val item: String? = getItem(position)
if (item != null) text.text = item

text.setTextColor(colorScheme.textColor)
text.setBackgroundColor(colorScheme.dropdownBgColor)

return view
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,16 @@ package eu.kanade.presentation.theme.colorscheme

import android.app.UiModeManager
import android.content.Context
import android.content.res.ColorStateList
import android.os.Build
import androidx.annotation.ColorInt
import androidx.compose.material3.ColorScheme
import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.unit.dp
import androidx.core.content.getSystemService
import com.google.android.material.progressindicator.LinearProgressIndicator
import com.materialkolor.Contrast
import com.materialkolor.PaletteStyle
import com.materialkolor.dynamicColorScheme
Expand Down Expand Up @@ -51,3 +58,179 @@ private class CustomCompatColorScheme(
},
)
}

class AndroidViewColorScheme(
colorScheme: ColorScheme,
) {
@ColorInt val primary: Int = colorScheme.primary.toArgb()

@ColorInt val onPrimary: Int = colorScheme.onPrimary.toArgb()

@ColorInt val primaryContainer: Int = colorScheme.primaryContainer.toArgb()

@ColorInt val onPrimaryContainer: Int = colorScheme.onPrimaryContainer.toArgb()

@ColorInt val inversePrimary: Int = colorScheme.inversePrimary.toArgb()

@ColorInt val secondary: Int = colorScheme.secondary.toArgb()

@ColorInt val onSecondary: Int = colorScheme.onSecondary.toArgb()

@ColorInt val secondaryContainer: Int = colorScheme.secondaryContainer.toArgb()

@ColorInt val onSecondaryContainer: Int = colorScheme.onSecondaryContainer.toArgb()

@ColorInt val tertiary: Int = colorScheme.tertiary.toArgb()

@ColorInt val onTertiary: Int = colorScheme.onTertiary.toArgb()

@ColorInt val tertiaryContainer: Int = colorScheme.tertiaryContainer.toArgb()

@ColorInt val onTertiaryContainer: Int = colorScheme.onTertiaryContainer.toArgb()

@ColorInt val background: Int = colorScheme.background.toArgb()

@ColorInt val onBackground: Int = colorScheme.onBackground.toArgb()

@ColorInt val surface: Int = colorScheme.surface.toArgb()

@ColorInt val onSurface: Int = colorScheme.onSurface.toArgb()

@ColorInt val surfaceVariant: Int = colorScheme.surfaceVariant.toArgb()

@ColorInt val onSurfaceVariant: Int = colorScheme.onSurfaceVariant.toArgb()

@ColorInt val surfaceTint: Int = colorScheme.surfaceTint.toArgb()

@ColorInt val inverseSurface: Int = colorScheme.inverseSurface.toArgb()

@ColorInt val inverseOnSurface: Int = colorScheme.inverseOnSurface.toArgb()

@ColorInt val error: Int = colorScheme.error.toArgb()

@ColorInt val onError: Int = colorScheme.onError.toArgb()

@ColorInt val errorContainer: Int = colorScheme.errorContainer.toArgb()

@ColorInt val onErrorContainer: Int = colorScheme.onErrorContainer.toArgb()

@ColorInt val outline: Int = colorScheme.outline.toArgb()

@ColorInt val outlineVariant: Int = colorScheme.outlineVariant.toArgb()

@ColorInt val scrim: Int = colorScheme.scrim.toArgb()

@ColorInt val surfaceBright: Int = colorScheme.surfaceBright.toArgb()

@ColorInt val surfaceDim: Int = colorScheme.surfaceDim.toArgb()

@ColorInt val surfaceContainer: Int = colorScheme.surfaceContainer.toArgb()

@ColorInt val surfaceContainerHigh: Int = colorScheme.surfaceContainerHigh.toArgb()

@ColorInt val surfaceContainerHighest: Int = colorScheme.surfaceContainerHighest.toArgb()

@ColorInt val surfaceContainerLow: Int = colorScheme.surfaceContainerLow.toArgb()

@ColorInt val surfaceContainerLowest: Int = colorScheme.surfaceContainerLowest.toArgb()

@ColorInt
val textColor: Int = onSurfaceVariant

@ColorInt
val textHighlightColor: Int = inversePrimary

@ColorInt
val iconColor: Int = primary

@ColorInt
val tagColor: Int = outlineVariant

@ColorInt
val tagTextColor: Int = onSurfaceVariant

@ColorInt
val btnTextColor: Int = onPrimary

@ColorInt
val btnBgColor: Int = surfaceTint

@ColorInt
val dropdownBgColor: Int = surfaceContainerHighest

@ColorInt
val dialogBgColor: Int = surfaceContainerHigh

@ColorInt
val surfaceElevation = colorScheme.surfaceColorAtElevation(4.dp).toArgb()

@ColorInt
val ratingBarColor = primary

@ColorInt
val ratingBarSecondaryColor = outlineVariant

/* MaterialSwitch */
val trackTintList = ColorStateList(
arrayOf(
intArrayOf(android.R.attr.state_checked),
intArrayOf(-android.R.attr.state_checked),
),
intArrayOf(
primary,
surface,
),
)
val thumbTintList = ColorStateList(
arrayOf(
intArrayOf(android.R.attr.state_checked),
intArrayOf(-android.R.attr.state_checked),
),
intArrayOf(
onPrimary,
onSurface,
),
)

val checkboxTintList = ColorStateList(
arrayOf(
intArrayOf(android.R.attr.state_checked),
intArrayOf(-android.R.attr.state_checked),
),
intArrayOf(
primary,
onSurface,
),
)

val editTextBackgroundTintList = ColorStateList(
arrayOf(
intArrayOf(android.R.attr.state_focused),
intArrayOf(-android.R.attr.state_focused),
),
intArrayOf(
primary,
onSurface,
),
)

val imageButtonTintList = ColorStateList(
arrayOf(
intArrayOf(android.R.attr.state_pressed), // Pressed state
intArrayOf(android.R.attr.state_focused), // Focused state
intArrayOf(), // Default state
),
intArrayOf(
primary, // Pressed color
primary, // Focused color
primary, // Default color
),
)

companion object {
fun LinearProgressIndicator.setColors(colorScheme: AndroidViewColorScheme) {
trackColor = colorScheme.secondaryContainer
setIndicatorColor(colorScheme.primary)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package eu.kanade.tachiyomi.ui.browse.migration.advanced.design

import android.content.res.ColorStateList
import android.graphics.drawable.ColorDrawable
import android.os.Build
import android.view.LayoutInflater
Expand All @@ -15,10 +14,10 @@ import androidx.compose.runtime.State
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.view.isVisible
import eu.kanade.presentation.components.AdaptiveSheet
import eu.kanade.presentation.theme.colorscheme.AndroidViewColorScheme
import eu.kanade.tachiyomi.databinding.MigrationBottomSheetBinding
import eu.kanade.tachiyomi.ui.browse.migration.MigrationFlags
import eu.kanade.tachiyomi.util.system.toast
Expand Down Expand Up @@ -49,10 +48,7 @@ fun MigrationBottomSheetDialog(
}

// KMK -->
val primaryColor = MaterialTheme.colorScheme.primary.toArgb()
val onSurface = MaterialTheme.colorScheme.onSurface.toArgb()
val surface = MaterialTheme.colorScheme.surface.toArgb()
val textHighlightColor = MaterialTheme.colorScheme.inversePrimary.toArgb()
val colorScheme = AndroidViewColorScheme(MaterialTheme.colorScheme)
// KMK <--

AdaptiveSheet(onDismissRequest = onDismissRequest) {
Expand All @@ -61,75 +57,48 @@ fun MigrationBottomSheetDialog(
val binding = MigrationBottomSheetBinding.inflate(LayoutInflater.from(factoryContext))
state.initPreferences(binding)
// KMK -->
binding.migrateBtn.setBackgroundColor(primaryColor)
binding.dataLabel.setTextColor(primaryColor)
binding.optionsLabel.setTextColor(primaryColor)

val buttonTintList = ColorStateList(
arrayOf(
intArrayOf(android.R.attr.state_checked),
intArrayOf(-android.R.attr.state_checked),
),
intArrayOf(
primaryColor,
onSurface,
),
)

binding.migChapters.buttonTintList = buttonTintList
binding.migCategories.buttonTintList = buttonTintList
binding.migTracking.buttonTintList = buttonTintList
binding.migCustomCover.buttonTintList = buttonTintList
binding.migExtra.buttonTintList = buttonTintList
binding.migDeleteDownloaded.buttonTintList = buttonTintList

binding.radioButton.buttonTintList = buttonTintList
binding.radioButton2.buttonTintList = buttonTintList

val trackTintList = ColorStateList(
arrayOf(
intArrayOf(android.R.attr.state_checked),
intArrayOf(-android.R.attr.state_checked),
),
intArrayOf(
primaryColor,
surface,
),
)

binding.useSmartSearch.trackTintList = trackTintList
binding.extraSearchParam.trackTintList = trackTintList
binding.skipStep.trackTintList = trackTintList
binding.HideNotFoundManga.trackTintList = trackTintList
binding.OnlyShowUpdates.trackTintList = trackTintList

val editTextBackgroundTintList = ColorStateList(
arrayOf(
intArrayOf(android.R.attr.state_focused),
intArrayOf(-android.R.attr.state_focused),
),
intArrayOf(
primaryColor,
onSurface,
),
)
binding.migrateBtn.setBackgroundColor(colorScheme.primary)
binding.dataLabel.setTextColor(colorScheme.primary)
binding.optionsLabel.setTextColor(colorScheme.primary)

binding.migChapters.buttonTintList = colorScheme.checkboxTintList
binding.migCategories.buttonTintList = colorScheme.checkboxTintList
binding.migTracking.buttonTintList = colorScheme.checkboxTintList
binding.migCustomCover.buttonTintList = colorScheme.checkboxTintList
binding.migExtra.buttonTintList = colorScheme.checkboxTintList
binding.migDeleteDownloaded.buttonTintList = colorScheme.checkboxTintList

binding.radioButton.buttonTintList = colorScheme.checkboxTintList
binding.radioButton2.buttonTintList = colorScheme.checkboxTintList

binding.useSmartSearch.trackTintList = colorScheme.trackTintList
binding.extraSearchParam.trackTintList = colorScheme.trackTintList
binding.skipStep.trackTintList = colorScheme.trackTintList
binding.HideNotFoundManga.trackTintList = colorScheme.trackTintList
binding.OnlyShowUpdates.trackTintList = colorScheme.trackTintList

binding.useSmartSearch.thumbTintList = colorScheme.thumbTintList
binding.extraSearchParam.thumbTintList = colorScheme.thumbTintList
binding.skipStep.thumbTintList = colorScheme.thumbTintList
binding.HideNotFoundManga.thumbTintList = colorScheme.thumbTintList
binding.OnlyShowUpdates.thumbTintList = colorScheme.thumbTintList

with(binding.extraSearchParamText) {
highlightColor = textHighlightColor
backgroundTintList = editTextBackgroundTintList
highlightColor = colorScheme.textHighlightColor
backgroundTintList = colorScheme.editTextBackgroundTintList

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
textCursorDrawable = ColorDrawable(primaryColor)
textCursorDrawable = ColorDrawable(colorScheme.primary)
textSelectHandle?.let { drawable ->
drawable.setTint(primaryColor)
drawable.setTint(colorScheme.primary)
setTextSelectHandle(drawable)
}
textSelectHandleLeft?.let { drawable ->
drawable.setTint(primaryColor)
drawable.setTint(colorScheme.primary)
setTextSelectHandleLeft(drawable)
}
textSelectHandleRight?.let { drawable ->
drawable.setTint(primaryColor)
drawable.setTint(colorScheme.primary)
setTextSelectHandleRight(drawable)
}
}
Expand Down
Loading

0 comments on commit 5b77536

Please sign in to comment.