add text shadow for transparent mode, replace alarm emoji with tinted icon

This commit is contained in:
Damocles 2026-04-22 23:00:57 +02:00
parent f70856b861
commit 843786507f

View file

@ -5,9 +5,12 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.provider.AlarmClock import android.provider.AlarmClock
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.DpSize import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.glance.ColorFilter
import androidx.glance.Image
import androidx.glance.ImageProvider
import androidx.glance.GlanceId import androidx.glance.GlanceId
import androidx.glance.GlanceModifier import androidx.glance.GlanceModifier
import androidx.glance.GlanceTheme import androidx.glance.GlanceTheme
@ -18,8 +21,8 @@ import androidx.glance.appwidget.GlanceAppWidgetReceiver
import androidx.glance.appwidget.SizeMode import androidx.glance.appwidget.SizeMode
import androidx.glance.appwidget.action.actionStartActivity import androidx.glance.appwidget.action.actionStartActivity
import androidx.glance.appwidget.provideContent import androidx.glance.appwidget.provideContent
import androidx.compose.ui.graphics.Color
import androidx.glance.background import androidx.glance.background
import androidx.glance.color.ColorProvider
import androidx.glance.color.DynamicThemeColorProviders import androidx.glance.color.DynamicThemeColorProviders
import space.darkest.nova.android.data.WidgetPreferences import space.darkest.nova.android.data.WidgetPreferences
import androidx.glance.layout.Alignment import androidx.glance.layout.Alignment
@ -30,6 +33,7 @@ import androidx.glance.layout.Spacer
import androidx.glance.layout.fillMaxSize import androidx.glance.layout.fillMaxSize
import androidx.glance.layout.height import androidx.glance.layout.height
import androidx.glance.layout.padding import androidx.glance.layout.padding
import androidx.glance.layout.size
import androidx.glance.layout.width import androidx.glance.layout.width
import androidx.glance.text.FontWeight import androidx.glance.text.FontWeight
import androidx.glance.text.Text import androidx.glance.text.Text
@ -76,7 +80,7 @@ class ClockWidget : GlanceAppWidget() {
"$day, $date" "$day, $date"
} }
val alarmStr = if (alarmTime != null && alarmDate != null) { val alarmStr = if (alarmTime != null && alarmDate != null) {
"\u23F0 ${formatAlarm(alarmTime, alarmDate)}" formatAlarm(alarmTime, alarmDate)
} else null } else null
Box( Box(
@ -91,100 +95,143 @@ class ClockWidget : GlanceAppWidget() {
contentAlignment = Alignment.CenterStart, contentAlignment = Alignment.CenterStart,
) { ) {
if (compact) { if (compact) {
CompactLayout(hours, minutes, dateStr, alarmStr) CompactLayout(hours, minutes, dateStr, alarmStr, transparentBg)
} else { } else {
FullLayout(hours, minutes, dateStr, alarmStr) FullLayout(hours, minutes, dateStr, alarmStr, transparentBg)
} }
} }
} }
// text with a dark shadow layer behind it for readability on wallpapers
@Composable @Composable
private fun TimeRow(hours: String, minutes: String, fontSize: Int = 48) { private fun ShadowText(
Row(verticalAlignment = Alignment.Bottom) { text: String,
style: TextStyle,
shadow: Boolean,
maxLines: Int = Int.MAX_VALUE,
) {
if (shadow) {
Box {
Text( Text(
text = text,
style = style.copy(
color = ColorProvider(Color(0x90000000)),
),
maxLines = maxLines,
modifier = GlanceModifier.padding(start = 1.dp, top = 1.dp),
)
Text(text = text, style = style, maxLines = maxLines)
}
} else {
Text(text = text, style = style, maxLines = maxLines)
}
}
@Composable
private fun TimeRow(hours: String, minutes: String, fontSize: Int = 48, shadow: Boolean = false) {
Row(verticalAlignment = Alignment.Bottom) {
ShadowText(
text = hours, text = hours,
style = TextStyle( style = TextStyle(
color = GlanceTheme.colors.primary, color = GlanceTheme.colors.primary,
fontSize = fontSize.sp, fontSize = fontSize.sp,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
), ),
shadow = shadow,
) )
Text( ShadowText(
text = ":", text = ":",
style = TextStyle( style = TextStyle(
color = GlanceTheme.colors.onSurfaceVariant, color = GlanceTheme.colors.onSurfaceVariant,
fontSize = fontSize.sp, fontSize = fontSize.sp,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
), ),
shadow = shadow,
) )
Text( ShadowText(
text = minutes, text = minutes,
style = TextStyle( style = TextStyle(
color = GlanceTheme.colors.tertiary, color = GlanceTheme.colors.tertiary,
fontSize = fontSize.sp, fontSize = fontSize.sp,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
), ),
shadow = shadow,
) )
} }
} }
@Composable @Composable
private fun CompactLayout(hours: String, minutes: String, dateStr: String, alarmStr: String?) { private fun CompactLayout(
hours: String, minutes: String, dateStr: String, alarmStr: String?, shadow: Boolean,
) {
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
modifier = GlanceModifier.fillMaxSize(), modifier = GlanceModifier.fillMaxSize(),
) { ) {
TimeRow(hours, minutes, fontSize = 36) TimeRow(hours, minutes, fontSize = 36, shadow = shadow)
Spacer(GlanceModifier.width(12.dp)) Spacer(GlanceModifier.width(12.dp))
Column { Column {
Text( ShadowText(
text = dateStr, text = dateStr,
style = TextStyle( style = TextStyle(
color = GlanceTheme.colors.onSurfaceVariant, color = GlanceTheme.colors.onSurfaceVariant,
fontSize = 12.sp, fontSize = 12.sp,
), ),
shadow = shadow,
) )
if (alarmStr != null) { if (alarmStr != null) {
Spacer(GlanceModifier.height(2.dp)) Spacer(GlanceModifier.height(2.dp))
Text( AlarmRow(alarmStr, 11, shadow)
text = alarmStr,
style = TextStyle(
color = GlanceTheme.colors.secondary,
fontSize = 11.sp,
),
)
} }
} }
} }
} }
@Composable @Composable
private fun FullLayout(hours: String, minutes: String, dateStr: String, alarmStr: String?) { private fun FullLayout(
hours: String, minutes: String, dateStr: String, alarmStr: String?, shadow: Boolean,
) {
Column { Column {
TimeRow(hours, minutes) TimeRow(hours, minutes, shadow = shadow)
Spacer(GlanceModifier.height(2.dp)) Spacer(GlanceModifier.height(2.dp))
Text( ShadowText(
text = dateStr, text = dateStr,
style = TextStyle( style = TextStyle(
color = GlanceTheme.colors.onSurfaceVariant, color = GlanceTheme.colors.onSurfaceVariant,
fontSize = 14.sp, fontSize = 14.sp,
), ),
shadow = shadow,
) )
if (alarmStr != null) { if (alarmStr != null) {
Spacer(GlanceModifier.height(4.dp)) Spacer(GlanceModifier.height(4.dp))
Text( AlarmRow(alarmStr, 12, shadow)
text = alarmStr, }
}
}
@Composable
private fun AlarmRow(text: String, fontSize: Int, shadow: Boolean) {
Row(verticalAlignment = Alignment.CenterVertically) {
Image(
provider = ImageProvider(android.R.drawable.ic_lock_idle_alarm),
contentDescription = "Alarm",
modifier = GlanceModifier.size(fontSize.dp),
colorFilter = ColorFilter.tint(GlanceTheme.colors.secondary),
)
Spacer(GlanceModifier.width(4.dp))
ShadowText(
text = text,
style = TextStyle( style = TextStyle(
color = GlanceTheme.colors.secondary, color = GlanceTheme.colors.secondary,
fontSize = 12.sp, fontSize = fontSize.sp,
), ),
shadow = shadow,
) )
} }
} }
}
private fun formatAlarm(time: LocalTime, date: LocalDate): String { private fun formatAlarm(time: LocalTime, date: LocalDate): String {
val today = LocalDate.now() val today = LocalDate.now()