mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-03 23:58:55 +01:00 
			
		
		
		
	Migrate ReaderColorFilterView to Compose
This commit is contained in:
		@@ -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)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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,
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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)) },
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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,
 | 
			
		||||
                    ),
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user