Add orbit clock style

This commit is contained in:
MM20 2022-10-22 18:05:58 +02:00
parent f5052f9bf7
commit 3bd6b1dbff
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
4 changed files with 133 additions and 2 deletions

View File

@ -11,10 +11,11 @@ The clock widget has two layouts:
## Style
There are five different clock styles:
There are six different clock styles:
- Fat digital clock
- Boring digital clock
- Orbit clock
- [Binary clock](https://en.wikipedia.org/wiki/Binary_clock#Binary-coded_sexagesimal_clocks)
- Analog clock
- Empty clock; in case you want to disable the clock altogether

View File

@ -111,6 +111,7 @@ message Settings {
enum ClockStyle {
DigitalClock1 = 0;
DigitalClock2 = 1;
OrbitClock = 5;
BinaryClock = 2;
AnalogClock = 3;
EmptyClock = 4;

View File

@ -135,10 +135,11 @@ fun Clock(
) {
val time = LocalTime.current
when (style) {
ClockStyle.DigitalClock1 -> DigitalClock1(time, layout)
ClockStyle.DigitalClock1 -> DigitalClock1(time = time, layout = layout)
ClockStyle.DigitalClock2 -> DigitalClock2(time, layout)
ClockStyle.BinaryClock -> BinaryClock(time, layout)
ClockStyle.AnalogClock -> AnalogClock(time, layout)
ClockStyle.OrbitClock -> OrbitClock(time, layout)
ClockStyle.EmptyClock -> EmptyClock(time, layout)
else -> {}
}

View File

@ -0,0 +1,128 @@
package de.mm20.launcher2.ui.launcher.widgets.clock.clocks
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.center
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathEffect
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.drawText
import androidx.compose.ui.text.rememberTextMeasurer
import androidx.compose.ui.unit.center
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.toOffset
import de.mm20.launcher2.preferences.Settings
import java.util.Calendar
import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.sin
@Composable
fun OrbitClock(
time: Long,
layout: Settings.ClockWidgetSettings.ClockWidgetLayout
) {
val verticalLayout = layout == Settings.ClockWidgetSettings.ClockWidgetLayout.Vertical
val date = Calendar.getInstance()
date.timeInMillis = time
val minute = date[Calendar.MINUTE]
val hour = date[Calendar.HOUR_OF_DAY]
val mu by animateFloatAsState(minute / 60f * 2f * PI.toFloat())
val heta by animateFloatAsState((hour % 12) / 12f * 2f * PI.toFloat() + (minute / 60f) * 1f / 6f * PI.toFloat())
val color = LocalContentColor.current
val measurer = rememberTextMeasurer()
val textStyle = MaterialTheme.typography.labelMedium
val strokeWidth = if (verticalLayout) 2.dp else 1.dp
Canvas(modifier = Modifier
.padding(bottom = if (verticalLayout) 8.dp else 0.dp)
.size(if (verticalLayout) 192.dp else 56.dp)
) {
val rm = size.width * 0.45f
val rh = size.width * 0.25f
drawCircle(
color = color.copy(alpha = 0.5f),
radius = rm,
style = Stroke(width = strokeWidth.toPx(),
pathEffect = PathEffect.dashPathEffect(floatArrayOf(4.dp.toPx(), 4.dp.toPx()))
)
)
drawCircle(
color = color.copy(alpha = 0.5f),
radius = rh,
style = Stroke(width = strokeWidth.toPx(),
pathEffect = PathEffect.dashPathEffect(floatArrayOf(4.dp.toPx(), 4.dp.toPx())),
)
)
val mPos = Offset(x = sin(mu) * rm, y = -cos(mu) * rm)
val hPos = Offset(x = sin(heta) * rh, y = -cos(heta) * rh)
drawCircle(
color = Color.Black,
radius = size.width * 0.08f,
center = size.center + mPos,
blendMode = BlendMode.DstOut
)
drawCircle(
color = Color.Black,
radius = size.width * 0.08f,
center = size.center + hPos,
blendMode = BlendMode.DstOut
)
if (verticalLayout) {
val textMResult = measurer.measure(
AnnotatedString(minute.toString()),
maxLines = 1,
style = textStyle
)
val textHResult = measurer.measure(
AnnotatedString(hour.toString()),
maxLines = 1,
style = textStyle
)
drawText(
textMResult,
color = Color.Black,
topLeft = size.center - textMResult.size.center.toOffset() + mPos
)
drawText(
textHResult,
color = Color.Black,
topLeft = size.center - textHResult.size.center.toOffset() + hPos
)
}
drawCircle(
color = color,
radius = size.width * 0.08f,
center = size.center + hPos,
blendMode = BlendMode.SrcOut
)
drawCircle(
color = color,
radius = size.width * 0.08f,
center = size.center + mPos,
blendMode = BlendMode.SrcOut
)
}
}