This repository has been archived on 2023-08-08. You can view files and clone it, but cannot push or open issues or pull requests.
tomo-old/elements/fun/clock.go

95 lines
2.8 KiB
Go
Raw Normal View History

2023-01-13 00:52:21 +00:00
package fun
import "time"
import "math"
import "image"
2023-02-27 03:20:17 +00:00
import "image/color"
2023-03-31 05:06:29 +00:00
import "git.tebibyte.media/sashakoshka/tomo"
2023-04-15 22:24:16 +00:00
import "git.tebibyte.media/sashakoshka/tomo/canvas"
2023-02-27 03:20:17 +00:00
import "git.tebibyte.media/sashakoshka/tomo/artist/shapes"
2023-03-31 05:06:29 +00:00
import "git.tebibyte.media/sashakoshka/tomo/default/theme"
2023-01-13 00:52:21 +00:00
2023-01-17 22:13:01 +00:00
// AnalogClock can display the time of day in an analog format.
2023-01-13 00:52:21 +00:00
type AnalogClock struct {
2023-04-15 22:24:16 +00:00
entity tomo.Entity
time time.Time
2023-02-08 20:12:18 +00:00
theme theme.Wrapped
2023-01-13 00:52:21 +00:00
}
2023-01-17 22:13:01 +00:00
// NewAnalogClock creates a new analog clock that displays the specified time.
2023-01-13 00:52:21 +00:00
func NewAnalogClock (newTime time.Time) (element *AnalogClock) {
element = &AnalogClock { }
2023-03-31 05:06:29 +00:00
element.theme.Case = tomo.C("tomo", "clock")
2023-04-15 22:24:16 +00:00
element.entity = tomo.NewEntity(element)
2023-04-15 22:30:22 +00:00
element.entity.SetMinimumSize(64, 64)
2023-01-13 00:52:21 +00:00
return
}
2023-04-15 22:24:16 +00:00
// Entity returns this element's entity.
func (element *AnalogClock) Entity () tomo.Entity {
return element.entity
2023-01-13 00:52:21 +00:00
}
2023-04-15 22:24:16 +00:00
// Draw causes the element to draw to the specified destination canvas.
func (element *AnalogClock) Draw (destination canvas.Canvas) {
2023-04-15 22:30:22 +00:00
bounds := element.entity.Bounds()
2023-01-13 00:52:21 +00:00
2023-03-31 05:06:29 +00:00
state := tomo.State { }
pattern := element.theme.Pattern(tomo.PatternSunken, state)
padding := element.theme.Padding(tomo.PatternSunken)
2023-04-15 22:30:22 +00:00
pattern.Draw(destination, bounds)
2023-02-27 03:20:17 +00:00
bounds = padding.Apply(bounds)
2023-03-31 05:06:29 +00:00
foreground := element.theme.Color(tomo.ColorForeground, state)
accent := element.theme.Color(tomo.ColorAccent, state)
2023-01-13 00:52:21 +00:00
for hour := 0; hour < 12; hour ++ {
element.radialLine (
2023-04-15 22:30:22 +00:00
destination,
foreground,
2023-01-13 00:52:21 +00:00
0.8, 0.9, float64(hour) / 6 * math.Pi)
}
2023-01-13 18:55:20 +00:00
second := float64(element.time.Second())
minute := float64(element.time.Minute()) + second / 60
hour := float64(element.time.Hour()) + minute / 60
2023-04-15 22:24:16 +00:00
element.radialLine(destination, foreground, 0, 0.5, (hour - 3) / 6 * math.Pi)
element.radialLine(destination, foreground, 0, 0.7, (minute - 15) / 30 * math.Pi)
element.radialLine(destination, accent, 0, 0.7, (second - 15) / 30 * math.Pi)
}
// SetTime changes the time that the clock displays.
func (element *AnalogClock) SetTime (newTime time.Time) {
if newTime == element.time { return }
element.time = newTime
element.entity.Invalidate()
}
// SetTheme sets the element's theme.
func (element *AnalogClock) SetTheme (new tomo.Theme) {
if new == element.theme.Theme { return }
element.theme.Theme = new
element.entity.Invalidate()
2023-01-13 00:52:21 +00:00
}
func (element *AnalogClock) radialLine (
2023-04-15 22:24:16 +00:00
destination canvas.Canvas,
2023-02-27 03:20:17 +00:00
source color.RGBA,
2023-01-13 00:52:21 +00:00
inner float64,
outer float64,
radian float64,
) {
2023-04-15 22:24:16 +00:00
bounds := element.entity.Bounds()
2023-01-13 00:52:21 +00:00
width := float64(bounds.Dx()) / 2
height := float64(bounds.Dy()) / 2
2023-04-15 22:24:16 +00:00
min := bounds.Min.Add(image.Pt (
2023-01-13 00:52:21 +00:00
int(math.Cos(radian) * inner * width + width),
2023-01-31 23:39:17 +00:00
int(math.Sin(radian) * inner * height + height)))
2023-04-15 22:24:16 +00:00
max := bounds.Min.Add(image.Pt (
2023-01-13 00:52:21 +00:00
int(math.Cos(radian) * outer * width + width),
2023-01-31 23:39:17 +00:00
int(math.Sin(radian) * outer * height + height)))
2023-04-15 22:30:22 +00:00
shapes.ColorLine(destination, source, 1, min, max)
2023-01-13 00:52:21 +00:00
}