Skip to content

Commit bdb5f7d

Browse files
neobuddy89joeyhuab
authored andcommitted
SystemUI: Add custom gradient start/end color support
Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>
1 parent aee4207 commit bdb5f7d

5 files changed

Lines changed: 355 additions & 20 deletions

File tree

core/java/android/provider/Settings.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7729,6 +7729,24 @@ public static void setShowGTalkServiceStatusForUser(ContentResolver cr, boolean
77297729
*/
77307730
public static final String VOLUME_SLIDER_GRADIENT = "volume_slider_gradient";
77317731

7732+
/**
7733+
* Gradient color mode
7734+
* @hide
7735+
*/
7736+
public static final String CUSTOM_GRADIENT_COLOR_MODE = "custom_gradient_color_mode";
7737+
7738+
/**
7739+
* Gradient start color
7740+
* @hide
7741+
*/
7742+
public static final String CUSTOM_GRADIENT_START_COLOR = "custom_gradient_start_color";
7743+
7744+
/**
7745+
* Gradient end color
7746+
* @hide
7747+
*/
7748+
public static final String CUSTOM_GRADIENT_END_COLOR = "custom_gradient_end_color";
7749+
77327750
/**
77337751
* Keys we no longer back up under the current schema, but want to continue to
77347752
* process when restoring historical backup datasets.

packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt

Lines changed: 119 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,15 @@ fun BrightnessSlider(
171171

172172
val trackShape = RoundedCornerShape(trackCornerDp)
173173
val brightnessGradient = brightnessSliderGradient()
174+
val thumbColorOverride: Color? =
175+
if (!rememberSliderGradient()) {
176+
null
177+
} else if (rememberGradientColorMode() == 1) {
178+
val (customStart, _) = rememberGradientCustomColors()
179+
customStart
180+
} else {
181+
MaterialTheme.colorScheme.primary
182+
}
174183

175184
var value by remember(gammaValue) { mutableIntStateOf(gammaValue) }
176185
val animatedValue by
@@ -322,7 +331,9 @@ fun BrightnessSlider(
322331
interactionSource = interactionSource,
323332
enabled = enabled,
324333
thumbSize = DpSize(ThumbWidth, ThumbHeight),
325-
colors = colors,
334+
colors = SliderDefaults.colors(
335+
thumbColor = thumbColorOverride ?: SliderDefaults.colors().thumbColor
336+
)
326337
)
327338
},
328339
track = { sliderState ->
@@ -546,14 +557,107 @@ private fun rememberSliderGradient(): Boolean {
546557
return enabled
547558
}
548559

560+
@Composable
561+
private fun rememberGradientColorMode(): Int {
562+
val contentResolver = LocalContext.current.contentResolver
563+
564+
fun readMode(): Int = try {
565+
Settings.System.getIntForUser(
566+
contentResolver, Settings.System.CUSTOM_GRADIENT_COLOR_MODE, 0,
567+
UserHandle.USER_CURRENT
568+
)
569+
} catch (_: Throwable) {
570+
0
571+
}
572+
573+
var mode by remember { mutableIntStateOf(readMode()) }
574+
575+
DisposableEffect(contentResolver) {
576+
val observer = object : ContentObserver(null) {
577+
override fun onChange(selfChange: Boolean) {
578+
mode = readMode()
579+
}
580+
}
581+
582+
contentResolver.registerContentObserver(
583+
Settings.System.getUriFor(Settings.System.CUSTOM_GRADIENT_COLOR_MODE),
584+
false, observer, UserHandle.USER_ALL
585+
)
586+
587+
onDispose {
588+
contentResolver.unregisterContentObserver(observer)
589+
}
590+
}
591+
592+
return mode
593+
}
594+
595+
@Composable
596+
private fun rememberGradientCustomColors(): Pair<Color, Color> {
597+
val contentResolver = LocalContext.current.contentResolver
598+
599+
fun readStart(): Int = try {
600+
Settings.System.getIntForUser(
601+
contentResolver, Settings.System.CUSTOM_GRADIENT_START_COLOR, 0,
602+
UserHandle.USER_CURRENT
603+
)
604+
} catch (_: Throwable) {
605+
0
606+
}
607+
608+
fun readEnd(): Int = try {
609+
Settings.System.getIntForUser(
610+
contentResolver, Settings.System.CUSTOM_GRADIENT_END_COLOR, 0,
611+
UserHandle.USER_CURRENT
612+
)
613+
} catch (_: Throwable) {
614+
0
615+
}
616+
617+
var startInt by remember { mutableIntStateOf(readStart()) }
618+
var endInt by remember { mutableIntStateOf(readEnd()) }
619+
620+
DisposableEffect(contentResolver) {
621+
val observer = object : ContentObserver(null) {
622+
override fun onChange(selfChange: Boolean) {
623+
startInt = readStart()
624+
endInt = readEnd()
625+
}
626+
}
627+
628+
contentResolver.registerContentObserver(
629+
Settings.System.getUriFor(Settings.System.CUSTOM_GRADIENT_START_COLOR),
630+
false, observer, UserHandle.USER_ALL
631+
)
632+
contentResolver.registerContentObserver(
633+
Settings.System.getUriFor(Settings.System.CUSTOM_GRADIENT_END_COLOR),
634+
false, observer, UserHandle.USER_ALL
635+
)
636+
637+
onDispose {
638+
contentResolver.unregisterContentObserver(observer)
639+
}
640+
}
641+
642+
val start = if (startInt != 0) Color(startInt) else MaterialTheme.colorScheme.primary
643+
val end = if (endInt != 0) Color(endInt) else MaterialTheme.colorScheme.secondary
644+
return start to end
645+
}
646+
549647
@Composable
550648
private fun brightnessSliderGradient(): BrightnessGradient? {
551649
if (!rememberSliderGradient()) return null
552650

553-
val colors = listOf(
554-
MaterialTheme.colorScheme.primary,
555-
MaterialTheme.colorScheme.secondary
556-
)
651+
val mode = rememberGradientColorMode()
652+
val colors = if (mode == 1) {
653+
val (start, end) = rememberGradientCustomColors()
654+
listOf(start, end)
655+
} else {
656+
listOf(
657+
MaterialTheme.colorScheme.primary,
658+
MaterialTheme.colorScheme.secondary
659+
)
660+
}
557661

558662
return BrightnessGradient(
559663
brush = Brush.horizontalGradient(colors)
@@ -612,9 +716,11 @@ private fun drawAutoBrightnessButton(
612716
3 -> RoundedCornerShape(0.dp)
613717
else -> RoundedCornerShape(animatedCornerRadius)
614718
}
719+
val brightnessGradient = brightnessSliderGradient()
720+
val autoIconBrush: Brush? = if (autoMode) brightnessGradient?.brush else null
615721
val backgroundColor by animateColorAsState(
616722
targetValue = if (autoMode) {
617-
MaterialTheme.colorScheme.primary
723+
if (autoIconBrush == null) MaterialTheme.colorScheme.primary else Color.Unspecified
618724
} else {
619725
LocalAndroidColorScheme.current.surfaceEffect1
620726
}
@@ -641,7 +747,13 @@ private fun drawAutoBrightnessButton(
641747
modifier = Modifier
642748
.size(45.dp)
643749
.clip(autoIconShape)
644-
.background(backgroundColor)
750+
.then(
751+
if (autoIconBrush != null) {
752+
Modifier.background(autoIconBrush)
753+
} else {
754+
Modifier.background(backgroundColor)
755+
}
756+
)
645757
.clickable(
646758
interactionSource = remember { MutableInteractionSource() },
647759
indication = null, // Disable ripple effect

packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt

Lines changed: 98 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,93 @@ fun rememberQsGradient(): Boolean {
693693
return enabled
694694
}
695695

696+
@Composable
697+
private fun rememberGradientColorMode(): Int {
698+
val contentResolver = LocalContext.current.contentResolver
699+
700+
fun readMode(): Int = try {
701+
Settings.System.getIntForUser(
702+
contentResolver, Settings.System.CUSTOM_GRADIENT_COLOR_MODE, 0,
703+
UserHandle.USER_CURRENT
704+
)
705+
} catch (_: Throwable) {
706+
0
707+
}
708+
709+
var mode by remember { mutableIntStateOf(readMode()) }
710+
711+
DisposableEffect(contentResolver) {
712+
val observer = object : ContentObserver(null) {
713+
override fun onChange(selfChange: Boolean) {
714+
mode = readMode()
715+
}
716+
}
717+
718+
contentResolver.registerContentObserver(
719+
Settings.System.getUriFor(Settings.System.CUSTOM_GRADIENT_COLOR_MODE),
720+
false, observer, UserHandle.USER_ALL
721+
)
722+
723+
onDispose {
724+
contentResolver.unregisterContentObserver(observer)
725+
}
726+
}
727+
728+
return mode
729+
}
730+
731+
@Composable
732+
private fun rememberGradientCustomColors(): Pair<Color, Color> {
733+
val contentResolver = LocalContext.current.contentResolver
734+
735+
fun readStart(): Int = try {
736+
Settings.System.getIntForUser(
737+
contentResolver, Settings.System.CUSTOM_GRADIENT_START_COLOR, 0,
738+
UserHandle.USER_CURRENT
739+
)
740+
} catch (_: Throwable) {
741+
0
742+
}
743+
744+
fun readEnd(): Int = try {
745+
Settings.System.getIntForUser(
746+
contentResolver, Settings.System.CUSTOM_GRADIENT_END_COLOR, 0,
747+
UserHandle.USER_CURRENT
748+
)
749+
} catch (_: Throwable) {
750+
0
751+
}
752+
753+
var startInt by remember { mutableIntStateOf(readStart()) }
754+
var endInt by remember { mutableIntStateOf(readEnd()) }
755+
756+
DisposableEffect(contentResolver) {
757+
val observer = object : ContentObserver(null) {
758+
override fun onChange(selfChange: Boolean) {
759+
startInt = readStart()
760+
endInt = readEnd()
761+
}
762+
}
763+
764+
contentResolver.registerContentObserver(
765+
Settings.System.getUriFor(Settings.System.CUSTOM_GRADIENT_START_COLOR),
766+
false, observer, UserHandle.USER_ALL
767+
)
768+
contentResolver.registerContentObserver(
769+
Settings.System.getUriFor(Settings.System.CUSTOM_GRADIENT_END_COLOR),
770+
false, observer, UserHandle.USER_ALL
771+
)
772+
773+
onDispose {
774+
contentResolver.unregisterContentObserver(observer)
775+
}
776+
}
777+
778+
val start = if (startInt != 0) Color(startInt) else MaterialTheme.colorScheme.primary
779+
val end = if (endInt != 0) Color(endInt) else MaterialTheme.colorScheme.secondary
780+
return start to end
781+
}
782+
696783
private object TileDefaults {
697784
val ActiveIconCornerRadius = 16.dp
698785

@@ -841,11 +928,19 @@ private object TileDefaults {
841928
fun qsTileBackgroundBrush(enabled: Boolean): Brush? {
842929
if (!enabled) return null
843930

844-
return Brush.linearGradient(
845-
colors = listOf(
931+
val mode = rememberGradientColorMode()
932+
val colors = if (mode == 1) {
933+
val (start, end) = rememberGradientCustomColors()
934+
listOf(start, end)
935+
} else {
936+
listOf(
846937
MaterialTheme.colorScheme.primary,
847938
MaterialTheme.colorScheme.secondary
848-
),
939+
)
940+
}
941+
942+
return Brush.linearGradient(
943+
colors = colors,
849944
start = Offset(0f, 0f),
850945
end = Offset.Infinite
851946
)

packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import androidx.compose.runtime.LaunchedEffect
3232
import androidx.compose.runtime.getValue
3333
import androidx.compose.runtime.remember
3434
import androidx.compose.ui.Modifier
35+
import androidx.compose.ui.graphics.Color
3536
import androidx.compose.ui.input.pointer.pointerInput
3637
import androidx.compose.ui.platform.ComposeView
3738
import androidx.compose.ui.platform.LocalContext
@@ -46,6 +47,9 @@ import com.android.systemui.res.R
4647
import com.android.systemui.volume.dialog.domain.interactor.DesktopAudioTileDetailsFeatureInteractor
4748
import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderScope
4849
import com.android.systemui.volume.dialog.sliders.ui.compose.SliderTrack
50+
import com.android.systemui.volume.dialog.sliders.ui.compose.rememberGradientColorMode
51+
import com.android.systemui.volume.dialog.sliders.ui.compose.rememberGradientCustomColors
52+
import com.android.systemui.volume.dialog.sliders.ui.compose.rememberVolumeGradientEnabled
4953
import com.android.systemui.volume.dialog.sliders.ui.viewmodel.VolumeDialogOverscrollViewModel
5054
import com.android.systemui.volume.dialog.sliders.ui.viewmodel.VolumeDialogSliderViewModel
5155
import com.android.systemui.volume.haptics.ui.VolumeHapticsConfigsProvider
@@ -128,6 +132,16 @@ private fun VolumeDialogSlider(
128132
}
129133
}
130134

135+
val thumbColorOverride: Color? =
136+
if (!rememberVolumeGradientEnabled()) {
137+
null
138+
} else if (rememberGradientColorMode() == 1) {
139+
val (customStart, _) = rememberGradientCustomColors()
140+
customStart
141+
} else {
142+
MaterialTheme.colorScheme.primary
143+
}
144+
131145
Slider(
132146
value = sliderStateModel.value,
133147
valueRange = sliderStateModel.valueRange,
@@ -191,14 +205,17 @@ private fun VolumeDialogSlider(
191205
isVisible = iconsState.isInactiveTrackEndIconVisible,
192206
)
193207
},
208+
ignoreGradient = false,
194209
)
195210
},
196211
thumb = { sliderState, interactions ->
197212
SliderDefaults.Thumb(
198213
sliderState = sliderState,
199214
interactionSource = interactions,
200215
enabled = !sliderStateModel.isDisabled,
201-
colors = colors,
216+
colors = SliderDefaults.colors(
217+
thumbColor = thumbColorOverride ?: SliderDefaults.colors().thumbColor
218+
),
202219
thumbSize =
203220
if (isVolumeDialogVertical) {
204221
DpSize(52.dp, 4.dp)

0 commit comments

Comments
 (0)