Add orbit clock style
This commit is contained in:
parent
f5052f9bf7
commit
3bd6b1dbff
@ -11,10 +11,11 @@ The clock widget has two layouts:
|
|||||||
|
|
||||||
## Style
|
## Style
|
||||||
|
|
||||||
There are five different clock styles:
|
There are six different clock styles:
|
||||||
|
|
||||||
- Fat digital clock
|
- Fat digital clock
|
||||||
- Boring digital clock
|
- Boring digital clock
|
||||||
|
- Orbit clock
|
||||||
- [Binary clock](https://en.wikipedia.org/wiki/Binary_clock#Binary-coded_sexagesimal_clocks)
|
- [Binary clock](https://en.wikipedia.org/wiki/Binary_clock#Binary-coded_sexagesimal_clocks)
|
||||||
- Analog clock
|
- Analog clock
|
||||||
- Empty clock; in case you want to disable the clock altogether
|
- Empty clock; in case you want to disable the clock altogether
|
||||||
|
|||||||
@ -111,6 +111,7 @@ message Settings {
|
|||||||
enum ClockStyle {
|
enum ClockStyle {
|
||||||
DigitalClock1 = 0;
|
DigitalClock1 = 0;
|
||||||
DigitalClock2 = 1;
|
DigitalClock2 = 1;
|
||||||
|
OrbitClock = 5;
|
||||||
BinaryClock = 2;
|
BinaryClock = 2;
|
||||||
AnalogClock = 3;
|
AnalogClock = 3;
|
||||||
EmptyClock = 4;
|
EmptyClock = 4;
|
||||||
|
|||||||
@ -135,10 +135,11 @@ fun Clock(
|
|||||||
) {
|
) {
|
||||||
val time = LocalTime.current
|
val time = LocalTime.current
|
||||||
when (style) {
|
when (style) {
|
||||||
ClockStyle.DigitalClock1 -> DigitalClock1(time, layout)
|
ClockStyle.DigitalClock1 -> DigitalClock1(time = time, layout = layout)
|
||||||
ClockStyle.DigitalClock2 -> DigitalClock2(time, layout)
|
ClockStyle.DigitalClock2 -> DigitalClock2(time, layout)
|
||||||
ClockStyle.BinaryClock -> BinaryClock(time, layout)
|
ClockStyle.BinaryClock -> BinaryClock(time, layout)
|
||||||
ClockStyle.AnalogClock -> AnalogClock(time, layout)
|
ClockStyle.AnalogClock -> AnalogClock(time, layout)
|
||||||
|
ClockStyle.OrbitClock -> OrbitClock(time, layout)
|
||||||
ClockStyle.EmptyClock -> EmptyClock(time, layout)
|
ClockStyle.EmptyClock -> EmptyClock(time, layout)
|
||||||
else -> {}
|
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