diff --git a/render-compose/api/android/render-compose.api b/render-compose/api/android/render-compose.api index 6797e1f..b1e734f 100644 --- a/render-compose/api/android/render-compose.api +++ b/render-compose/api/android/render-compose.api @@ -60,6 +60,23 @@ public final class ink/ui/render/compose/theme/ColorVariant$Defaults { public final fun getLight ()Link/ui/render/compose/theme/ColorVariant; } +public final class ink/ui/render/compose/theme/ColorVariant$Defaults$Colors { + public static final field $stable I + public static final field INSTANCE Link/ui/render/compose/theme/ColorVariant$Defaults$Colors; + public final fun getBLACK-0d7_KjU ()J + public final fun getBLUE-0d7_KjU ()J + public final fun getGRAY-0d7_KjU ()J + public final fun getGREEN-0d7_KjU ()J + public final fun getORANGE-0d7_KjU ()J + public final fun getPURPLE-0d7_KjU ()J + public final fun getRED-0d7_KjU ()J + public final fun getSOFT_BLACK-0d7_KjU ()J + public final fun getSOFT_GRAY-0d7_KjU ()J + public final fun getSOFT_WHITE-0d7_KjU ()J + public final fun getWHITE-0d7_KjU ()J + public final fun getYELLOW-0d7_KjU ()J +} + public final class ink/ui/render/compose/theme/ColorsKt { public static final fun brighten-DxMtmZc (JF)J public static final fun darken-DxMtmZc (JF)J diff --git a/render-compose/api/jvm/render-compose.api b/render-compose/api/jvm/render-compose.api index 6797e1f..b1e734f 100644 --- a/render-compose/api/jvm/render-compose.api +++ b/render-compose/api/jvm/render-compose.api @@ -60,6 +60,23 @@ public final class ink/ui/render/compose/theme/ColorVariant$Defaults { public final fun getLight ()Link/ui/render/compose/theme/ColorVariant; } +public final class ink/ui/render/compose/theme/ColorVariant$Defaults$Colors { + public static final field $stable I + public static final field INSTANCE Link/ui/render/compose/theme/ColorVariant$Defaults$Colors; + public final fun getBLACK-0d7_KjU ()J + public final fun getBLUE-0d7_KjU ()J + public final fun getGRAY-0d7_KjU ()J + public final fun getGREEN-0d7_KjU ()J + public final fun getORANGE-0d7_KjU ()J + public final fun getPURPLE-0d7_KjU ()J + public final fun getRED-0d7_KjU ()J + public final fun getSOFT_BLACK-0d7_KjU ()J + public final fun getSOFT_GRAY-0d7_KjU ()J + public final fun getSOFT_WHITE-0d7_KjU ()J + public final fun getWHITE-0d7_KjU ()J + public final fun getYELLOW-0d7_KjU ()J +} + public final class ink/ui/render/compose/theme/ColorsKt { public static final fun brighten-DxMtmZc (JF)J public static final fun darken-DxMtmZc (JF)J diff --git a/render-compose/src/commonMain/composeResources/drawable/snow.xml b/render-compose/src/commonMain/composeResources/drawable/snow.xml new file mode 100644 index 0000000..ff28b1b --- /dev/null +++ b/render-compose/src/commonMain/composeResources/drawable/snow.xml @@ -0,0 +1,9 @@ + + + diff --git a/render-compose/src/commonMain/kotlin/ink/ui/render/compose/renderer/Symbols.kt b/render-compose/src/commonMain/kotlin/ink/ui/render/compose/renderer/Symbols.kt index 882456d..9e3118d 100644 --- a/render-compose/src/commonMain/kotlin/ink/ui/render/compose/renderer/Symbols.kt +++ b/render-compose/src/commonMain/kotlin/ink/ui/render/compose/renderer/Symbols.kt @@ -30,6 +30,7 @@ val Symbol.resource: DrawableResource get() = when (this) { Symbol.Person -> Res.drawable.person Symbol.Rain -> Res.drawable.rain Symbol.Remove -> Res.drawable.remove + Symbol.Snow -> Res.drawable.snow Symbol.Sunshine -> Res.drawable.sunshine Symbol.Temperature -> Res.drawable.temperature Symbol.Water -> Res.drawable.water diff --git a/render-compose/src/commonMain/kotlin/ink/ui/render/compose/renderer/WeatherRenderer.kt b/render-compose/src/commonMain/kotlin/ink/ui/render/compose/renderer/WeatherRenderer.kt index 2f2931a..7d318ff 100644 --- a/render-compose/src/commonMain/kotlin/ink/ui/render/compose/renderer/WeatherRenderer.kt +++ b/render-compose/src/commonMain/kotlin/ink/ui/render/compose/renderer/WeatherRenderer.kt @@ -3,57 +3,148 @@ package ink.ui.render.compose.renderer import androidx.compose.foundation.Image import androidx.compose.foundation.layout.* import androidx.compose.foundation.text.BasicText +import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.ColorFilter +import ink.ui.render.compose.theme.ColorVariant +import ink.ui.render.compose.theme.ComposeRenderTheme import ink.ui.structures.Symbol import ink.ui.structures.elements.WeatherElement +import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.painterResource val WeatherRenderer = renderer { theme, element -> - Box( - contentAlignment = Alignment.Center, + val description = when (element.condition) { + WeatherElement.Condition.Clear -> "Clear" + WeatherElement.Condition.Cloudy -> "Cloudy" + WeatherElement.Condition.Rainy -> "Rainy" + WeatherElement.Condition.Snowy -> "Snowy" + } + val icon = when (element.condition) { + WeatherElement.Condition.Clear -> if (element.daytime) { + Symbol.Sunshine.resource + } else { + Symbol.Moon.resource + } + WeatherElement.Condition.Cloudy -> Symbol.Cloud.resource + WeatherElement.Condition.Rainy -> Symbol.Rain.resource + WeatherElement.Condition.Snowy -> Symbol.Snow.resource + } + + val sentiment = element.sentiment + val tint = when { + sentiment != null -> theme.colors.forSentiment(sentiment) + element.condition == WeatherElement.Condition.Rainy -> ColorVariant.Defaults.Colors.BLUE + element.condition == WeatherElement.Condition.Clear -> ColorVariant.Defaults.Colors.YELLOW + element.condition == WeatherElement.Condition.Cloudy -> ColorVariant.Defaults.Colors.GRAY + else -> theme.colors.foreground + }.let(ColorFilter::tint) + + if (element.compact) { + InlineRender( + theme = theme, + title = element.title, + icon = icon, + tint = tint, + iconDescription = description, + temperature = element.temperature, + secondaryText = element.secondaryText, + ) + } else { + BoxRender( + theme = theme, + title = element.title, + icon = icon, + tint = tint, + iconDescription = description, + temperature = element.temperature, + secondaryText = element.secondaryText, + ) + } +} + +@Composable +private fun InlineRender( + theme: ComposeRenderTheme, + title: String? = null, + icon: DrawableResource, + tint: ColorFilter, + iconDescription: String, + temperature: String, + secondaryText: String?, +) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.padding(theme.spacing.item) ) { Column( horizontalAlignment = Alignment.CenterHorizontally, ) { - val title = element.title - if (title != null) { + if (title != null && title.isNotBlank()) { BasicText( text = title, style = theme.typography.caption.copy(color = theme.colors.foreground), ) } + Image( + painterResource(icon), + colorFilter = tint, + contentDescription = iconDescription, + modifier = Modifier.size(theme.sizing.hintIcons) + ) + } - val description = when (element.condition) { - WeatherElement.Condition.Clear -> "Clear" - WeatherElement.Condition.Cloudy -> "Cloudy" - WeatherElement.Condition.Rainy -> "Rainy" + Spacer(modifier = Modifier.width(theme.spacing.item)) + + Column( + horizontalAlignment = Alignment.CenterHorizontally, + ) { + BasicText(temperature, style = theme.typography.body.copy(color = theme.colors.foreground)) + + if (secondaryText != null && secondaryText.isNotBlank()) { + BasicText(secondaryText, style = theme.typography.caption.copy(color = theme.colors.foreground)) } - val icon = when (element.condition) { - WeatherElement.Condition.Clear -> if (element.daytime) { - Symbol.Sunshine.resource - } else { - Symbol.Moon.resource - } - WeatherElement.Condition.Cloudy -> Symbol.Cloud.resource - WeatherElement.Condition.Rainy -> Symbol.Rain.resource + } + } +} + +@Composable +private fun BoxRender( + theme: ComposeRenderTheme, + title: String? = null, + icon: DrawableResource, + tint: ColorFilter, + iconDescription: String, + temperature: String, + secondaryText: String?, +) { + + Box( + contentAlignment = Alignment.Center, + ) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + ) { + if (title != null) { + BasicText( + text = title, + style = theme.typography.caption.copy(color = theme.colors.foreground), + ) } Image( painterResource(icon), - colorFilter = ColorFilter.tint(theme.colors.forSentiment(element.sentiment)), - contentDescription = description, + colorFilter = tint, + contentDescription = iconDescription, modifier = Modifier.size(theme.sizing.widgetIcons).padding(theme.spacing.item) ) - BasicText(element.temperature, style = theme.typography.body.copy(color = theme.colors.foreground)) + BasicText(temperature, style = theme.typography.body.copy(color = theme.colors.foreground)) - val secondaryTemperature = element.secondaryText - if (secondaryTemperature != null) { - BasicText(secondaryTemperature, style = theme.typography.caption.copy(color = theme.colors.foreground)) + if (secondaryText != null) { + BasicText(secondaryText, style = theme.typography.caption.copy(color = theme.colors.foreground)) } } } } - diff --git a/render-compose/src/commonMain/kotlin/ink/ui/render/compose/theme/ColorVariant.kt b/render-compose/src/commonMain/kotlin/ink/ui/render/compose/theme/ColorVariant.kt index f92311d..0773d4a 100644 --- a/render-compose/src/commonMain/kotlin/ink/ui/render/compose/theme/ColorVariant.kt +++ b/render-compose/src/commonMain/kotlin/ink/ui/render/compose/theme/ColorVariant.kt @@ -28,16 +28,33 @@ data class ColorVariant( Sentiment.Idle -> idle } - object Defaults { + object Defaults + { + object Colors + { + val BLACK = Color(0xFF000000) + val WHITE = Color(0xFFFFFFFF) + val SOFT_WHITE = Color(0xFFF8F8F8) + val SOFT_BLACK = Color(0xFF212121) + val GRAY = Color(0xFF90A4AE) + val SOFT_GRAY = Color(0xFF323232) + val RED = Color(0xFFe82a70) + val GREEN = Color(0xFF00a600) + val ORANGE = Color(0xFFfe9720) + val YELLOW = Color(0xFFe3c52d) + val BLUE = Color(0xFF008DA9) + val PURPLE = Color(0xFFa175c9) + } + val light = ColorVariant( - foreground = Color(0xFF212121), - background = Color(0xFFF8F8F8), - surface = Color(0xFFFFFFFF), - primary = Color(0xFF008DA9), - positive = Color(0xFF00a600), - negative = Color(0xFFf92772), - caution = Color(0xFFfe9720), - idle = Color(0xFF90A4AE), + foreground = Colors.SOFT_BLACK, + background = Colors.WHITE, + surface = Colors.WHITE, + primary = Colors.BLUE, + positive = Colors.GREEN, + negative = Colors.RED, + caution = Colors.ORANGE, + idle = Colors.GRAY, ).let { it.copy( surfaceInteraction = it.surface.darken(0.1f), @@ -45,9 +62,9 @@ data class ColorVariant( } val dark = light.copy( - foreground = Color(0xFFFFFFFF), - background = Color(0xFF212121), - surface = Color(0xFF323232), + foreground = Colors.WHITE, + background = Colors.SOFT_BLACK, + surface = Colors.SOFT_GRAY, ).let { it.copy( surfaceInteraction = it.surface.brighten(0.1f), diff --git a/sample-android/src/main/kotlin/example/SampleScreen.kt b/sample-android/src/main/kotlin/example/SampleScreen.kt index cfe02ec..ff4e80a 100644 --- a/sample-android/src/main/kotlin/example/SampleScreen.kt +++ b/sample-android/src/main/kotlin/example/SampleScreen.kt @@ -88,6 +88,16 @@ val SampleScreen = ScrollingListLayout( temperature = "72", condition = WeatherElement.Condition.Clear, ), + WeatherElement( + title = "Sun", + temperature = "72", + secondaryText = "60", + condition = WeatherElement.Condition.Snowy, + ), + WeatherElement( + temperature = "72", + condition = WeatherElement.Condition.Cloudy, + ), WeatherElement( title = "Sun", temperature = "72", @@ -98,6 +108,36 @@ val SampleScreen = ScrollingListLayout( positioning = Positioning.Center, orientation = Orientation.Horizontal, ), + ElementList( + items = listOf( + WeatherElement( + temperature = "72", + condition = WeatherElement.Condition.Clear, + compact = true, + ), + WeatherElement( + title = "Sun", + temperature = "72", + secondaryText = "60", + condition = WeatherElement.Condition.Snowy, + compact = true, + ), + WeatherElement( + temperature = "72", + condition = WeatherElement.Condition.Cloudy, + compact = true, + ), + WeatherElement( + title = "Sun", + temperature = "72", + secondaryText = "60", + condition = WeatherElement.Condition.Rainy, + compact = true, + ), + ), + positioning = Positioning.Start, + orientation = Orientation.Horizontal, + ), SpinnerElement( value = "5", onNextValue = {}, diff --git a/structures/api/structures.api b/structures/api/structures.api index 54c9af8..46d4dfd 100644 --- a/structures/api/structures.api +++ b/structures/api/structures.api @@ -74,6 +74,7 @@ public final class ink/ui/structures/Symbol$Companion { public final fun getPerson-ZR4vNbg ()Ljava/lang/String; public final fun getRain-ZR4vNbg ()Ljava/lang/String; public final fun getRemove-ZR4vNbg ()Ljava/lang/String; + public final fun getSnow-ZR4vNbg ()Ljava/lang/String; public final fun getSunshine-ZR4vNbg ()Ljava/lang/String; public final fun getTemperature-ZR4vNbg ()Ljava/lang/String; public final fun getWater-ZR4vNbg ()Ljava/lang/String; @@ -527,17 +528,19 @@ public abstract interface class ink/ui/structures/elements/UiElement$Static : in } public final class ink/ui/structures/elements/WeatherElement : ink/ui/structures/elements/UiElement$Static { - public fun (Ljava/lang/String;Link/ui/structures/elements/WeatherElement$Condition;Ljava/lang/String;Ljava/lang/String;ZLink/ui/structures/Sentiment;)V - public synthetic fun (Ljava/lang/String;Link/ui/structures/elements/WeatherElement$Condition;Ljava/lang/String;Ljava/lang/String;ZLink/ui/structures/Sentiment;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Ljava/lang/String;Link/ui/structures/elements/WeatherElement$Condition;Ljava/lang/String;Ljava/lang/String;ZLink/ui/structures/Sentiment;Z)V + public synthetic fun (Ljava/lang/String;Link/ui/structures/elements/WeatherElement$Condition;Ljava/lang/String;Ljava/lang/String;ZLink/ui/structures/Sentiment;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Ljava/lang/String; public final fun component2 ()Link/ui/structures/elements/WeatherElement$Condition; public final fun component3 ()Ljava/lang/String; public final fun component4 ()Ljava/lang/String; public final fun component5 ()Z public final fun component6 ()Link/ui/structures/Sentiment; - public final fun copy (Ljava/lang/String;Link/ui/structures/elements/WeatherElement$Condition;Ljava/lang/String;Ljava/lang/String;ZLink/ui/structures/Sentiment;)Link/ui/structures/elements/WeatherElement; - public static synthetic fun copy$default (Link/ui/structures/elements/WeatherElement;Ljava/lang/String;Link/ui/structures/elements/WeatherElement$Condition;Ljava/lang/String;Ljava/lang/String;ZLink/ui/structures/Sentiment;ILjava/lang/Object;)Link/ui/structures/elements/WeatherElement; + public final fun component7 ()Z + public final fun copy (Ljava/lang/String;Link/ui/structures/elements/WeatherElement$Condition;Ljava/lang/String;Ljava/lang/String;ZLink/ui/structures/Sentiment;Z)Link/ui/structures/elements/WeatherElement; + public static synthetic fun copy$default (Link/ui/structures/elements/WeatherElement;Ljava/lang/String;Link/ui/structures/elements/WeatherElement$Condition;Ljava/lang/String;Ljava/lang/String;ZLink/ui/structures/Sentiment;ZILjava/lang/Object;)Link/ui/structures/elements/WeatherElement; public fun equals (Ljava/lang/Object;)Z + public final fun getCompact ()Z public final fun getCondition ()Link/ui/structures/elements/WeatherElement$Condition; public final fun getDaytime ()Z public final fun getSecondaryText ()Ljava/lang/String; @@ -552,6 +555,7 @@ public final class ink/ui/structures/elements/WeatherElement$Condition : java/la public static final field Clear Link/ui/structures/elements/WeatherElement$Condition; public static final field Cloudy Link/ui/structures/elements/WeatherElement$Condition; public static final field Rainy Link/ui/structures/elements/WeatherElement$Condition; + public static final field Snowy Link/ui/structures/elements/WeatherElement$Condition; public static fun getEntries ()Lkotlin/enums/EnumEntries; public static fun valueOf (Ljava/lang/String;)Link/ui/structures/elements/WeatherElement$Condition; public static fun values ()[Link/ui/structures/elements/WeatherElement$Condition; diff --git a/structures/src/commonMain/kotlin/ink/ui/structures/Symbol.kt b/structures/src/commonMain/kotlin/ink/ui/structures/Symbol.kt index c13511b..74cdc5a 100644 --- a/structures/src/commonMain/kotlin/ink/ui/structures/Symbol.kt +++ b/structures/src/commonMain/kotlin/ink/ui/structures/Symbol.kt @@ -31,6 +31,7 @@ value class Symbol(val key: String) { val Movie = Symbol("Movie") val Person = Symbol("Person") val Rain = Symbol("Rain") + val Snow = Symbol("Snow") val Remove = Symbol("Remove") val Sunshine = Symbol("Sunshine") val Temperature = Symbol("Temperature") diff --git a/structures/src/commonMain/kotlin/ink/ui/structures/elements/WeatherElement.kt b/structures/src/commonMain/kotlin/ink/ui/structures/elements/WeatherElement.kt index 448b2c9..862daff 100644 --- a/structures/src/commonMain/kotlin/ink/ui/structures/elements/WeatherElement.kt +++ b/structures/src/commonMain/kotlin/ink/ui/structures/elements/WeatherElement.kt @@ -8,12 +8,14 @@ data class WeatherElement( val secondaryText: String? = null, val title: String? = null, val daytime: Boolean = true, - val sentiment: Sentiment = Sentiment.Nominal, + val sentiment: Sentiment? = null, + val compact: Boolean = false, ): UiElement.Static { enum class Condition { Clear, Cloudy, Rainy, + Snowy, } }