Browse Source

Migrate ReaderColorFilterView to Compose

arkon 1 year ago
parent
commit
5b2a099203

+ 0 - 27
app/src/main/java/eu/kanade/presentation/reader/BrightnessOverlay.kt

@@ -1,27 +0,0 @@
-package eu.kanade.presentation.reader
-
-import androidx.annotation.IntRange
-import androidx.compose.foundation.Canvas
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.graphicsLayer
-import kotlin.math.abs
-
-@Composable
-fun BrightnessOverlay(
-    @IntRange(from = -100, to = 100) value: Int,
-) {
-    if (value >= 0) return
-
-    Canvas(
-        modifier = Modifier
-            .fillMaxSize()
-            .graphicsLayer {
-                alpha = abs(value) / 100f
-            },
-    ) {
-        drawRect(Color.Black)
-    }
-}

+ 43 - 0
app/src/main/java/eu/kanade/presentation/reader/ReaderContentOverlay.kt

@@ -0,0 +1,43 @@
+package eu.kanade.presentation.reader
+
+import androidx.annotation.ColorInt
+import androidx.annotation.IntRange
+import androidx.compose.foundation.Canvas
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.BlendMode
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.graphicsLayer
+import kotlin.math.abs
+
+@Composable
+fun ReaderContentOverlay(
+    @IntRange(from = -100, to = 100) brightness: Int,
+    @ColorInt color: Int?,
+    colorBlendMode: BlendMode? = BlendMode.SrcOver,
+) {
+    if (brightness < 0) {
+        Canvas(
+            modifier = Modifier
+                .fillMaxSize()
+                .graphicsLayer {
+                    alpha = abs(brightness) / 100f
+                },
+        ) {
+            drawRect(Color.Black)
+        }
+    }
+
+    if (color != null) {
+        Canvas(
+            modifier = Modifier
+                .fillMaxSize(),
+        ) {
+            drawRect(
+                color = Color(color),
+                blendMode = colorBlendMode,
+            )
+        }
+    }
+}

+ 3 - 22
app/src/main/java/eu/kanade/presentation/reader/settings/ColorFilterPage.kt

@@ -1,6 +1,5 @@
 package eu.kanade.presentation.reader.settings
 
-import android.os.Build
 import androidx.compose.foundation.layout.ColumnScope
 import androidx.compose.material3.FilterChip
 import androidx.compose.material3.Text
@@ -10,6 +9,7 @@ import androidx.core.graphics.alpha
 import androidx.core.graphics.blue
 import androidx.core.graphics.green
 import androidx.core.graphics.red
+import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences.Companion.ColorFilterMode
 import eu.kanade.tachiyomi.ui.reader.setting.ReaderSettingsScreenModel
 import tachiyomi.core.preference.getAndSet
 import tachiyomi.i18n.MR
@@ -21,25 +21,6 @@ import tachiyomi.presentation.core.util.collectAsState
 
 @Composable
 internal fun ColumnScope.ColorFilterPage(screenModel: ReaderSettingsScreenModel) {
-    val colorFilterModes = buildList {
-        addAll(
-            listOf(
-                MR.strings.label_default,
-                MR.strings.filter_mode_multiply,
-                MR.strings.filter_mode_screen,
-            ),
-        )
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
-            addAll(
-                listOf(
-                    MR.strings.filter_mode_overlay,
-                    MR.strings.filter_mode_lighten,
-                    MR.strings.filter_mode_darken,
-                ),
-            )
-        }
-    }.map { stringResource(it) }
-
     val customBrightness by screenModel.preferences.customBrightness().collectAsState()
     CheckboxItem(
         label = stringResource(MR.strings.pref_custom_brightness),
@@ -118,11 +99,11 @@ internal fun ColumnScope.ColorFilterPage(screenModel: ReaderSettingsScreenModel)
 
         val colorFilterMode by screenModel.preferences.colorFilterMode().collectAsState()
         SettingsChipRow(MR.strings.pref_color_filter_mode) {
-            colorFilterModes.mapIndexed { index, it ->
+            ColorFilterMode.mapIndexed { index, it ->
                 FilterChip(
                     selected = colorFilterMode == index,
                     onClick = { screenModel.preferences.colorFilterMode().set(index) },
-                    label = { Text(it) },
+                    label = { Text(stringResource(it.first)) },
                 )
             }
         }

+ 14 - 37
app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt

@@ -34,17 +34,16 @@ import androidx.core.transition.doOnEnd
 import androidx.core.view.WindowCompat
 import androidx.core.view.WindowInsetsCompat
 import androidx.core.view.WindowInsetsControllerCompat
-import androidx.core.view.isVisible
 import androidx.lifecycle.lifecycleScope
 import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
 import com.google.android.material.elevation.SurfaceColors
 import com.google.android.material.transition.platform.MaterialContainerTransform
 import dev.chrisbanes.insetter.applyInsetter
 import eu.kanade.domain.base.BasePreferences
-import eu.kanade.presentation.reader.BrightnessOverlay
 import eu.kanade.presentation.reader.DisplayRefreshHost
 import eu.kanade.presentation.reader.OrientationSelectDialog
 import eu.kanade.presentation.reader.PageIndicatorText
+import eu.kanade.presentation.reader.ReaderContentOverlay
 import eu.kanade.presentation.reader.ReaderPageActionsDialog
 import eu.kanade.presentation.reader.ReadingModeSelectDialog
 import eu.kanade.presentation.reader.appbars.ReaderAppBars
@@ -331,11 +330,24 @@ class ReaderActivity : BaseActivity() {
             val isFullscreen by readerPreferences.fullscreen().collectAsState()
             val flashOnPageChange by readerPreferences.flashOnPageChange().collectAsState()
 
+            val colorOverlayEnabled by readerPreferences.colorFilter().collectAsState()
+            val colorOverlay by readerPreferences.colorFilterValue().collectAsState()
+            val colorOverlayMode by readerPreferences.colorFilterMode().collectAsState()
+            val colorOverlayBlendMode = remember(colorOverlayMode) {
+                ReaderPreferences.ColorFilterMode.getOrNull(colorOverlayMode)?.second
+            }
+
             val cropBorderPaged by readerPreferences.cropBorders().collectAsState()
             val cropBorderWebtoon by readerPreferences.cropBordersWebtoon().collectAsState()
             val isPagerType = ReadingMode.isPagerType(viewModel.getMangaReadingMode())
             val cropEnabled = if (isPagerType) cropBorderPaged else cropBorderWebtoon
 
+            ReaderContentOverlay(
+                brightness = state.brightnessOverlayValue,
+                color = colorOverlay.takeIf { colorOverlayEnabled },
+                colorBlendMode = colorOverlayBlendMode,
+            )
+
             ReaderAppBars(
                 visible = state.menuVisible,
                 fullscreen = isFullscreen,
@@ -378,10 +390,6 @@ class ReaderActivity : BaseActivity() {
                 onClickSettings = viewModel::openSettingsDialog,
             )
 
-            BrightnessOverlay(
-                value = state.brightnessOverlayValue,
-            )
-
             if (flashOnPageChange) {
                 DisplayRefreshHost(
                     hostState = displayRefreshHost,
@@ -805,14 +813,6 @@ class ReaderActivity : BaseActivity() {
                 .onEach(::setCustomBrightness)
                 .launchIn(lifecycleScope)
 
-            readerPreferences.colorFilter().changes()
-                .onEach(::setColorFilter)
-                .launchIn(lifecycleScope)
-
-            readerPreferences.colorFilterMode().changes()
-                .onEach { setColorFilter(readerPreferences.colorFilter().get()) }
-                .launchIn(lifecycleScope)
-
             merge(readerPreferences.grayscale().changes(), readerPreferences.invertedColors().changes())
                 .onEach { setLayerPaint(readerPreferences.grayscale().get(), readerPreferences.invertedColors().get()) }
                 .launchIn(lifecycleScope)
@@ -884,20 +884,6 @@ class ReaderActivity : BaseActivity() {
             }
         }
 
-        /**
-         * Sets the color filter overlay according to [enabled].
-         */
-        private fun setColorFilter(enabled: Boolean) {
-            if (enabled) {
-                readerPreferences.colorFilterValue().changes()
-                    .sample(100)
-                    .onEach(::setColorFilterValue)
-                    .launchIn(lifecycleScope)
-            } else {
-                binding.colorOverlay.isVisible = false
-            }
-        }
-
         /**
          * Sets the brightness of the screen. Range is [-75, 100].
          * From -75 to -1 a semi-transparent black view is overlaid with the minimum brightness.
@@ -919,15 +905,6 @@ class ReaderActivity : BaseActivity() {
 
             viewModel.setBrightnessOverlayValue(value)
         }
-
-        /**
-         * Sets the color filter [value].
-         */
-        private fun setColorFilterValue(value: Int) {
-            binding.colorOverlay.isVisible = true
-            binding.colorOverlay.setFilterColor(value, readerPreferences.colorFilterMode().get())
-        }
-
         private fun setLayerPaint(grayscale: Boolean, invertedColors: Boolean) {
             val paint = if (grayscale || invertedColors) getCombinedPaint(grayscale, invertedColors) else null
             binding.viewerContainer.setLayerType(LAYER_TYPE_HARDWARE, paint)

+ 0 - 36
app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderColorFilterView.kt

@@ -1,36 +0,0 @@
-package eu.kanade.tachiyomi.ui.reader
-
-import android.content.Context
-import android.graphics.Canvas
-import android.graphics.Paint
-import android.graphics.PorterDuff
-import android.util.AttributeSet
-import android.view.View
-import androidx.core.graphics.toXfermode
-
-class ReaderColorFilterView(
-    context: Context,
-    attrs: AttributeSet? = null,
-) : View(context, attrs) {
-
-    private val colorFilterPaint: Paint = Paint()
-
-    fun setFilterColor(color: Int, filterMode: Int) {
-        colorFilterPaint.color = color
-        colorFilterPaint.xfermode = when (filterMode) {
-            1 -> PorterDuff.Mode.MULTIPLY
-            2 -> PorterDuff.Mode.SCREEN
-            3 -> PorterDuff.Mode.OVERLAY
-            4 -> PorterDuff.Mode.LIGHTEN
-            5 -> PorterDuff.Mode.DARKEN
-            else -> PorterDuff.Mode.SRC_OVER
-        }.toXfermode()
-
-        invalidate()
-    }
-
-    override fun onDraw(canvas: Canvas) {
-        super.onDraw(canvas)
-        canvas.drawPaint(colorFilterPaint)
-    }
-}

+ 21 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/ReaderPreferences.kt

@@ -1,5 +1,7 @@
 package eu.kanade.tachiyomi.ui.reader.setting
 
+import android.os.Build
+import androidx.compose.ui.graphics.BlendMode
 import dev.icerock.moko.resources.StringResource
 import tachiyomi.core.preference.PreferenceStore
 import tachiyomi.core.preference.getEnum
@@ -178,5 +180,24 @@ class ReaderPreferences(
             MR.strings.zoom_start_right,
             MR.strings.zoom_start_center,
         )
+
+        val ColorFilterMode = buildList {
+            addAll(
+                listOf(
+                    MR.strings.label_default to BlendMode.SrcOver,
+                    MR.strings.filter_mode_multiply to BlendMode.Modulate,
+                    MR.strings.filter_mode_screen to BlendMode.Screen,
+                ),
+            )
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+                addAll(
+                    listOf(
+                        MR.strings.filter_mode_overlay to BlendMode.Overlay,
+                        MR.strings.filter_mode_lighten to BlendMode.Lighten,
+                        MR.strings.filter_mode_darken to BlendMode.Darken,
+                    ),
+                )
+            }
+        }
     }
 }

+ 0 - 6
app/src/main/res/layout/reader_activity.xml

@@ -21,12 +21,6 @@
 
     </FrameLayout>
 
-    <eu.kanade.tachiyomi.ui.reader.ReaderColorFilterView
-        android:id="@+id/color_overlay"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:visibility="gone" />
-
     <eu.kanade.tachiyomi.ui.reader.ReaderNavigationOverlayView
         android:id="@+id/navigation_overlay"
         android:layout_width="match_parent"