Implement ColorFilterSetting (#859)

* Implement ColorFilterSetting

* Initial ColorFilterSetting

* Cleanup

---------

Co-authored-by: GG Bond <whatever@tagkong.com>
This commit is contained in:
renovate[bot]andGG Bond authored and GitHub committed 2024-03-05 17:20:09 +00:00
1 parent 298e80eb9d
commit e1f34a7b1b
2 files changed
+82 -3

No files matched your search

@@ -1,23 +1,85 @@
package com.hippo.ehviewer.ui.reader
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.Column
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Brightness5
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.res.stringArrayResource
import androidx.compose.ui.res.stringResource
import androidx.core.graphics.alpha
import androidx.core.graphics.blue
import androidx.core.graphics.green
import androidx.core.graphics.red
import com.hippo.ehviewer.R
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.asMutableState
@Composable
fun ColorFilterSetting() = Column {
val customBrightness = Settings.customBrightness.asMutableState()
SwitchChoice(
title = stringResource(id = R.string.pref_custom_brightness),
field = Settings.customBrightness.asMutableState(),
field = customBrightness,
)
AnimatedVisibility(visible = customBrightness.value) {
val brightness = Settings.customBrightnessValue.asMutableState()
SliderChoice(
startSlot = { Icon(imageVector = Icons.Default.Brightness5, contentDescription = null) },
endSlot = { Text(text = "${brightness.value}") },
range = -75..100,
field = brightness,
)
}
val colorFilter = Settings.colorFilter.asMutableState()
SwitchChoice(
title = stringResource(id = R.string.pref_custom_color_filter),
field = Settings.colorFilter.asMutableState(),
field = colorFilter,
)
AnimatedVisibility(visible = colorFilter.value) {
var color by Settings.colorFilterValue.asMutableState()
val rf = remember { mutableIntStateOf(color.red) }
val r by rf
val gf = remember { mutableIntStateOf(color.green) }
val g by gf
val bf = remember { mutableIntStateOf(color.blue) }
val b by bf
val af = remember { mutableIntStateOf(color.alpha) }
val a by af
color = (a shl 24) or (r shl 16) or (g shl 8) or (b)
Column {
SliderChoice(
startSlot = { Text(text = "R") },
endSlot = { Text(text = "$r") },
range = 0..255,
field = rf,
)
SliderChoice(
startSlot = { Text(text = "G") },
endSlot = { Text(text = "$g") },
range = 0..255,
field = gf,
)
SliderChoice(
startSlot = { Text(text = "B") },
endSlot = { Text(text = "$b") },
range = 0..255,
field = bf,
)
SliderChoice(
startSlot = { Text(text = "A") },
endSlot = { Text(text = "$a") },
range = 0..255,
field = af,
)
}
}
SpinnerChoice(
title = stringResource(id = R.string.pref_color_filter_mode),
entries = stringArrayResource(id = R.array.color_filter_modes),
@@ -14,6 +14,7 @@ import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Icon
import androidx.compose.material3.Slider
import androidx.compose.material3.SliderDefaults
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@@ -24,6 +25,8 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.unit.dp
@Composable
@@ -92,12 +95,26 @@ fun SliderChoice(
verticalAlignment = Alignment.CenterVertically,
) {
startSlot()
val configuration = LocalConfiguration.current
// https://m3.material.io/components/sliders/specs
// Tick width is 2 dp
val maxTickCount = configuration.screenWidthDp / 6
val steps = range.last - range.first - 1
val showTicks = steps < maxTickCount
Slider(
value = value.toFloat(),
onValueChange = { value = it.toInt() },
modifier = Modifier.weight(1f).padding(8.dp),
valueRange = (range.first.toFloat())..(range.last.toFloat()),
steps = range.last - range.first - 1,
steps = steps,
colors = if (showTicks) {
SliderDefaults.colors()
} else {
SliderDefaults.colors(
activeTickColor = Color.Transparent,
inactiveTickColor = Color.Transparent,
)
},
)
endSlot()
}