This is the first step in transitioning the API over to the new design. The new tomo.Canvas interface gives drawing functions direct access to data buffers and eliminates overhead associated with calling functions for every pixel. The entire artist package will be remade around this.
91 lines
2.2 KiB
Go
91 lines
2.2 KiB
Go
package fun
|
|
|
|
import "time"
|
|
import "math"
|
|
import "image"
|
|
import "git.tebibyte.media/sashakoshka/tomo"
|
|
import "git.tebibyte.media/sashakoshka/tomo/theme"
|
|
import "git.tebibyte.media/sashakoshka/tomo/artist"
|
|
import "git.tebibyte.media/sashakoshka/tomo/elements/core"
|
|
|
|
type AnalogClock struct {
|
|
*core.Core
|
|
core core.CoreControl
|
|
time time.Time
|
|
}
|
|
|
|
func NewAnalogClock (newTime time.Time) (element *AnalogClock) {
|
|
element = &AnalogClock { }
|
|
element.Core, element.core = core.NewCore(element)
|
|
element.core.SetMinimumSize(64, 64)
|
|
return
|
|
}
|
|
|
|
func (element *AnalogClock) Handle (event tomo.Event) {
|
|
switch event.(type) {
|
|
case tomo.EventResize:
|
|
resizeEvent := event.(tomo.EventResize)
|
|
element.core.AllocateCanvas (
|
|
resizeEvent.Width,
|
|
resizeEvent.Height)
|
|
element.draw()
|
|
}
|
|
}
|
|
|
|
func (element *AnalogClock) SetTime (newTime time.Time) {
|
|
if newTime == element.time { return }
|
|
element.time = newTime
|
|
if element.core.HasImage() {
|
|
element.draw()
|
|
element.core.PushAll()
|
|
}
|
|
}
|
|
|
|
func (element *AnalogClock) draw () {
|
|
bounds := element.core.Bounds()
|
|
|
|
artist.ChiseledRectangle (
|
|
element.core,
|
|
theme.BackgroundProfile(true),
|
|
bounds)
|
|
|
|
for hour := 0; hour < 12; hour ++ {
|
|
element.radialLine (
|
|
theme.ForegroundImage(),
|
|
0.8, 0.9, float64(hour) / 6 * math.Pi)
|
|
}
|
|
|
|
second := float64(element.time.Second())
|
|
minute := float64(element.time.Minute()) + second / 60
|
|
hour := float64(element.time.Hour()) + minute / 60
|
|
|
|
element.radialLine (
|
|
theme.ForegroundImage(),
|
|
0, 0.5, (hour - 3) / 6 * math.Pi)
|
|
element.radialLine (
|
|
theme.ForegroundImage(),
|
|
0, 0.7, (minute - 15) / 30 * math.Pi)
|
|
element.radialLine (
|
|
theme.AccentImage(),
|
|
0, 0.7, (second - 15) / 30 * math.Pi)
|
|
}
|
|
|
|
func (element *AnalogClock) radialLine (
|
|
source artist.Pattern,
|
|
inner float64,
|
|
outer float64,
|
|
radian float64,
|
|
) {
|
|
bounds := element.core.Bounds()
|
|
width := float64(bounds.Dx()) / 2
|
|
height := float64(bounds.Dy()) / 2
|
|
min := image.Pt (
|
|
int(math.Cos(radian) * inner * width + width),
|
|
int(math.Sin(radian) * inner * height + height))
|
|
max := image.Pt (
|
|
int(math.Cos(radian) * outer * width + width),
|
|
int(math.Sin(radian) * outer * height + height))
|
|
// println(min.String(), max.String())
|
|
artist.Line(element.core, source, 1, min, max)
|
|
}
|