diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/component/weather/AnimatedWeatherIcon.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/component/weather/AnimatedWeatherIcon.kt index 20f01cbbc..a825c396b 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/component/weather/AnimatedWeatherIcon.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/component/weather/AnimatedWeatherIcon.kt @@ -189,21 +189,20 @@ private fun Cloud1(icon: WeatherIcon, colors: WeatherIconColors) { when (it) { WeatherIcon.Thunderstorm, WeatherIcon.Thunder, - WeatherIcon.Wind -> colors.cloudDark2 + WeatherIcon.Wind, + WeatherIcon.HeavyRain -> colors.cloud1 WeatherIcon.Rain, - WeatherIcon.HeavyRain, WeatherIcon.Sleet, WeatherIcon.Hail, WeatherIcon.Overcast, - WeatherIcon.Wind, - WeatherIcon.Fog -> colors.cloudDark1 + WeatherIcon.Fog -> colors.cloud2 WeatherIcon.LightRain, - WeatherIcon.Snow -> colors.cloudMedium2 + WeatherIcon.Snow -> colors.cloud3 - WeatherIcon.PartlyCloudy -> colors.cloudLight1 - else -> colors.cloudMedium2 + WeatherIcon.PartlyCloudy -> colors.cloud5 + else -> colors.cloud3 } } @@ -261,19 +260,19 @@ private fun Cloud2(icon: WeatherIcon, colors: WeatherIconColors) { when (it) { WeatherIcon.Thunderstorm, WeatherIcon.Thunder, - WeatherIcon.Wind -> colors.cloudMedium2 + WeatherIcon.Wind, + WeatherIcon.HeavyRain -> colors.cloud2 WeatherIcon.Rain, - WeatherIcon.HeavyRain, - WeatherIcon.LightRain, WeatherIcon.Sleet, - WeatherIcon.Snow, WeatherIcon.Hail, WeatherIcon.Overcast, - WeatherIcon.Wind, - WeatherIcon.Fog -> colors.cloudMedium1 + WeatherIcon.Fog -> colors.cloud3 - else -> colors.cloudMedium2 + WeatherIcon.LightRain, + WeatherIcon.Snow -> colors.cloud4 + + else -> colors.cloud2 } } @@ -329,19 +328,18 @@ private fun Cloud3(icon: WeatherIcon, colors: WeatherIconColors) { when (it) { WeatherIcon.Thunderstorm, WeatherIcon.Thunder, - WeatherIcon.Wind -> colors.cloudDark1 + WeatherIcon.Wind, + WeatherIcon.HeavyRain -> colors.cloud3 WeatherIcon.Rain, - WeatherIcon.HeavyRain, WeatherIcon.Sleet, WeatherIcon.Hail, - WeatherIcon.Overcast, - WeatherIcon.Wind -> colors.cloudMedium2 + WeatherIcon.Overcast -> colors.cloud4 WeatherIcon.LightRain, - WeatherIcon.Snow -> colors.cloudLight2 + WeatherIcon.Snow -> colors.cloud5 - else -> colors.cloudMedium2 + else -> colors.cloud4 } } @@ -429,8 +427,8 @@ fun AnimatedWeatherIconTestPanel() { AnimatedWeatherIcon(icon = icon, night = night) WeatherIcon(icon = icon, night = night) - val monochromeColors = WeatherIconDefaults.monochromeColors( - MaterialTheme.colorScheme.secondary + val monochromeColors = WeatherIconDefaults.themedColors( + MaterialTheme.colorScheme.secondary, ) AnimatedWeatherIcon( diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/component/weather/WeatherIcon.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/component/weather/WeatherIcon.kt index e2233ee21..9a7064a0c 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/component/weather/WeatherIcon.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/component/weather/WeatherIcon.kt @@ -123,19 +123,19 @@ private fun Cloud1(icon: WeatherIcon, colors: WeatherIconColors) { } val color = when (icon) { WeatherIcon.Thunderstorm, - WeatherIcon.Thunder -> colors.cloudDark2 + WeatherIcon.Thunder, + WeatherIcon.HeavyRain -> colors.cloud1 WeatherIcon.Rain, - WeatherIcon.HeavyRain, WeatherIcon.Sleet, WeatherIcon.Hail, WeatherIcon.Overcast, - WeatherIcon.Fog -> colors.cloudDark1 + WeatherIcon.Fog -> colors.cloud2 WeatherIcon.LightRain, - WeatherIcon.Snow -> colors.cloudMedium2 + WeatherIcon.Snow -> colors.cloud3 - WeatherIcon.PartlyCloudy -> colors.cloudLight1 + WeatherIcon.PartlyCloudy -> colors.cloud5 } Icon( @@ -195,16 +195,17 @@ private fun Cloud2(icon: WeatherIcon, colors: WeatherIconColors) { } val color = when (icon) { WeatherIcon.Thunderstorm, - WeatherIcon.Thunder -> colors.cloudMedium2 + WeatherIcon.Thunder, + WeatherIcon.HeavyRain -> colors.cloud2 WeatherIcon.Rain, - WeatherIcon.HeavyRain, - WeatherIcon.LightRain, WeatherIcon.Sleet, - WeatherIcon.Snow, WeatherIcon.Hail, WeatherIcon.Overcast, - WeatherIcon.Fog -> colors.cloudMedium1 + WeatherIcon.Fog -> colors.cloud3 + + WeatherIcon.LightRain, + WeatherIcon.Snow -> colors.cloud4 } Icon( @@ -246,16 +247,16 @@ private fun Cloud3(icon: WeatherIcon, colors: WeatherIconColors) { } val color = when (icon) { WeatherIcon.Thunderstorm, - WeatherIcon.Thunder -> colors.cloudDark1 + WeatherIcon.Thunder, + WeatherIcon.HeavyRain -> colors.cloud3 WeatherIcon.Rain, - WeatherIcon.HeavyRain, WeatherIcon.Sleet, WeatherIcon.Hail, - WeatherIcon.Overcast -> colors.cloudMedium2 + WeatherIcon.Overcast -> colors.cloud4 WeatherIcon.LightRain, - WeatherIcon.Snow -> colors.cloudLight2 + WeatherIcon.Snow -> colors.cloud5 } Icon( diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/component/weather/WeatherIconColors.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/component/weather/WeatherIconColors.kt index 932fc9732..bfa0adc13 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/component/weather/WeatherIconColors.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/component/weather/WeatherIconColors.kt @@ -9,162 +9,100 @@ import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalContext import blend.Blend import de.mm20.launcher2.ui.ktx.atTone -import de.mm20.launcher2.ui.locals.LocalDarkTheme import hct.Hct data class WeatherIconColors( val sun: Color, val moon: Color, - val cloudDark1: Color, - val cloudDark2: Color, - val cloudMedium1: Color, - val cloudMedium2: Color, - val cloudLight1: Color, - val cloudLight2: Color, + val cloud1: Color, + val cloud2: Color, + val cloud3: Color, + val cloud4: Color, + val cloud5: Color, val rain: Color, val snow: Color, val hail: Color, val fog: Color, val wind: Color, - val windDark: Color, val lightningBolt: Color, val hot: Color, val cold: Color, ) object WeatherIconDefaults { - @Composable - fun colors(): WeatherIconColors { - val darkTheme = LocalDarkTheme.current - if (darkTheme) { - return darkColors() - } else { - return lightColors() + @Composable + fun colors( + background: Color = MaterialTheme.colorScheme.surface + ): WeatherIconColors { + val themeColor = MaterialTheme.colorScheme.primary + val neutralColor = MaterialTheme.colorScheme.outline + + return remember(background, neutralColor, themeColor) { + val baseTone = Hct.fromInt(background.toArgb()).tone.toInt() + + WeatherIconColors( + sun = harmonize(0xfff7ae00.toInt(), themeColor).atTone(t(baseTone, 75)), + moon = neutralColor.atTone(t(baseTone, 90)), + cloud1 = neutralColor.atTone(t(baseTone, 20)), + cloud2 = neutralColor.atTone(t(baseTone, 35)), + cloud3 = neutralColor.atTone(t(baseTone, 50)), + cloud4 = neutralColor.atTone(t(baseTone, 65)), + cloud5 = neutralColor.atTone(t(baseTone, 90)), + rain = harmonize(0xff1c71d8.toInt(), themeColor).atTone(t(baseTone, 50)), + snow = neutralColor.atTone(t(baseTone, 100)), + hail = neutralColor.atTone(t(baseTone, 90)), + fog = neutralColor.atTone(t(baseTone, 60)), + wind = neutralColor.atTone(t(baseTone, 65)), + lightningBolt = harmonize(0xfff7ae00.toInt(), themeColor).atTone(t(baseTone, 80)), + hot = harmonize(0xffec3435.toInt(), themeColor).atTone(t(baseTone, 50)), + cold = harmonize(0xff1c71d8.toInt(), themeColor).atTone(t(baseTone, 50)), + ) } } @Composable - fun invertedColors(): WeatherIconColors { - val darkTheme = LocalDarkTheme.current - - if (!darkTheme) { - return darkColors() - } else { - return lightColors() - } - } - - @Composable - fun darkColors(): WeatherIconColors { - val context = LocalContext.current + fun themedColors(backgroundColor: Color): WeatherIconColors { val themeColor = MaterialTheme.colorScheme.primary + val neutralColor = MaterialTheme.colorScheme.outline - val neutral1 = MaterialTheme.colorScheme.outline - val neutral2 = MaterialTheme.colorScheme.outline + return remember(backgroundColor, themeColor, neutralColor) { + val baseTone = Hct.fromInt(backgroundColor.toArgb()).tone.toInt() - return remember(themeColor) { WeatherIconColors( - sun = harmonize(0xFFFFB300.toInt(), themeColor), - moon = harmonize(0xFF9E9E9E.toInt(), themeColor), - cloudDark1 = harmonize(neutral1.atTone(40).toArgb(), themeColor), - cloudDark2 = harmonize(neutral1.atTone(30).toArgb(), themeColor), - cloudMedium1 = harmonize(neutral1.atTone(60).toArgb(), themeColor), - cloudMedium2 = harmonize(neutral1.atTone(50).toArgb(), themeColor), - cloudLight1 = harmonize(neutral1.atTone(95).toArgb(), themeColor), - cloudLight2 = harmonize(neutral1.atTone(85).toArgb(), themeColor), - rain = harmonize(0xFF64B5F6.toInt(), themeColor), - snow = harmonize(0xFFF5F5F5.toInt(), themeColor), - hail = harmonize(0xFFF5F5F5.toInt(), themeColor), - fog = harmonize(neutral1.atTone(95).toArgb(), themeColor), - wind = harmonize(neutral2.atTone(70).toArgb(), themeColor), - windDark = harmonize(neutral2.atTone(40).toArgb(), themeColor), - lightningBolt = harmonize(0xFFFFB300.toInt(), themeColor), - hot = harmonize(0xFFE57373.toInt(), themeColor), - cold = harmonize(0xFF4FC3F7.toInt(), themeColor), + sun = themeColor.atTone(t(baseTone, 75)), + moon = neutralColor.atTone(t(baseTone, 90)), + cloud1 = neutralColor.atTone(t(baseTone, 20)), + cloud2 = neutralColor.atTone(t(baseTone, 35)), + cloud3 = neutralColor.atTone(t(baseTone, 50)), + cloud4 = neutralColor.atTone(t(baseTone, 65)), + cloud5 = neutralColor.atTone(t(baseTone, 90)), + rain = themeColor.atTone(t(baseTone, 55)), + snow = neutralColor.atTone(t(baseTone, 100)), + hail = neutralColor.atTone(t(baseTone, 90)), + fog = neutralColor.atTone(t(baseTone, 60)), + wind = neutralColor.atTone(t(baseTone, 65)), + lightningBolt = themeColor.atTone(t(baseTone, 80)), + hot = themeColor.atTone(t(baseTone, 50)), + cold = themeColor.atTone(t(baseTone, 50)), ) } } - @Composable - fun lightColors(): WeatherIconColors { - val context = LocalContext.current + private fun t(base: Int, tone: Int): Int { + val upper = (base + 15f).coerceAtMost(100f) + val lower = (base - 15f).coerceAtLeast(0f) + val diff = upper - lower + val scale = (100f - diff) / 100f - val themeColor = MaterialTheme.colorScheme.primary - val neutral1 = MaterialTheme.colorScheme.outline - val neutral2 = MaterialTheme.colorScheme.outline + val tn = tone * scale - return remember(themeColor) { - WeatherIconColors( - sun = harmonize(0xFFFFB300.toInt(), themeColor), - moon = harmonize(0xFF9E9E9E.toInt(), themeColor), - cloudDark1 = harmonize(neutral1.atTone(30).toArgb(), themeColor), - cloudDark2 = harmonize(neutral1.atTone(20).toArgb(), themeColor), - cloudMedium1 = harmonize(neutral1.atTone(50).toArgb(), themeColor), - cloudMedium2 = harmonize(neutral1.atTone(40).toArgb(), themeColor), - cloudLight1 = harmonize(neutral1.atTone(85).toArgb(), themeColor), - cloudLight2 = harmonize(neutral1.atTone(75).toArgb(), themeColor), - rain = harmonize(0xFF1E88E5.toInt(), themeColor), - snow = harmonize(0xFFE0E0E0.toInt(), themeColor), - hail = harmonize(0xFFE0E0E0.toInt(), themeColor), - fog = harmonize(neutral1.atTone(85).toArgb(), themeColor), - wind = harmonize(neutral2.atTone(75).toArgb(), themeColor), - windDark = harmonize(neutral2.atTone(45).toArgb(), themeColor), - lightningBolt = harmonize(0xFFFFB300.toInt(), themeColor), - hot = harmonize(0xFFE53935.toInt(), themeColor), - cold = harmonize(0xFF039BE5.toInt(), themeColor), - ) - } - } - - @Composable - fun monochromeColors(baseColor: Color): WeatherIconColors { - val baseTone = Hct.fromInt(baseColor.toArgb()).tone.toInt() - - return remember(baseColor) { - /** - * Adjusts the tone of a color. - * The tone is adjusted up or down to not overlap with the base color's tone. - * - * @param tone The tone to adjust. - * @return The adjusted tone. - */ - fun t(tone: Int): Int { - val upper = (baseTone + 15f).coerceAtMost(100f) - val lower = (baseTone - 15f).coerceAtLeast(0f) - val diff = upper - lower - val scale = (100f - diff) / 100f - - val tn = tone * scale - - if (tn > lower) { - return (tn + diff).toInt() - } - return tn.toInt() - } - - WeatherIconColors( - sun = baseColor.atTone(t(90)), - moon = baseColor.atTone(t(90)), - cloudDark1 = baseColor.atTone(t(25)), - cloudDark2 = baseColor.atTone(t(15)), - cloudMedium1 = baseColor.atTone(t(45)), - cloudMedium2 = baseColor.atTone(t(35)), - cloudLight1 = baseColor.atTone(t(65)), - cloudLight2 = baseColor.atTone(t(55)), - rain = baseColor.atTone(t(55)), - snow = baseColor.atTone(t(100)), - hail = baseColor.atTone(t(90)), - fog = baseColor.atTone(t(60)), - wind = baseColor.atTone(t(65)), - windDark = baseColor.atTone(t(45)), - lightningBolt = baseColor.atTone(t(90)), - hot = baseColor.atTone(t(55)), - cold = baseColor.atTone(t(55)), - ) + if (tn > lower) { + return (tn + diff).toInt() } + return tn.toInt() } } diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/weather/WeatherWidget.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/weather/WeatherWidget.kt index fad88ba33..05d823e3d 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/weather/WeatherWidget.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/weather/WeatherWidget.kt @@ -364,7 +364,8 @@ fun CurrentWeather( end = 8.dp ), icon = weatherIconById(forecast.icon), - night = forecast.night + night = forecast.night, + WeatherIconDefaults.colors(MaterialTheme.colorScheme.surface) ) } } @@ -485,8 +486,10 @@ fun WeatherTimeSelector( val listState = rememberLazyListState() - val colors = WeatherIconDefaults.colors() - val selectedColors = WeatherIconDefaults.monochromeColors(MaterialTheme.colorScheme.secondary) + val colors = WeatherIconDefaults.colors(MaterialTheme.colorScheme.surfaceBright) + val selectedColors = WeatherIconDefaults.themedColors( + MaterialTheme.colorScheme.secondary, + ) LazyRow( state = listState, @@ -587,8 +590,10 @@ fun WeatherDaySelector( val dateFormat = SimpleDateFormat("EEE") val context = LocalContext.current - val colors = WeatherIconDefaults.colors() - val selectedColors = WeatherIconDefaults.monochromeColors(MaterialTheme.colorScheme.secondary) + val colors = WeatherIconDefaults.colors(MaterialTheme.colorScheme.surfaceBright) + val selectedColors = WeatherIconDefaults.themedColors( + MaterialTheme.colorScheme.secondary, + ) val listState = rememberLazyListState() LazyRow(