Add orbit clock style
This commit is contained in:
parent
f5052f9bf7
commit
3bd6b1dbff
@ -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
|
||||
|
||||
@ -111,6 +111,7 @@ message Settings {
|
||||
enum ClockStyle {
|
||||
DigitalClock1 = 0;
|
||||
DigitalClock2 = 1;
|
||||
OrbitClock = 5;
|
||||
BinaryClock = 2;
|
||||
AnalogClock = 3;
|
||||
EmptyClock = 4;
|
||||
|
||||
@ -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 -> {}
|
||||
}
|
||||
|
||||
@ -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
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user