Analog clock widget!!
This commit is contained in:
		
							parent
							
								
									60c2ccbec2
								
							
						
					
					
						commit
						b5469e103d
					
				
							
								
								
									
										88
									
								
								elements/fun/clock.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								elements/fun/clock.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,88 @@ | ||||
| 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) | ||||
| 	} | ||||
| 
 | ||||
| 	element.radialLine ( | ||||
| 		theme.ForegroundImage(), | ||||
| 		0, 0.5, float64(element.time.Hour() - 3) / 6 * math.Pi) | ||||
| 	element.radialLine ( | ||||
| 		theme.ForegroundImage(), | ||||
| 		0, 0.7, float64(element.time.Minute() - 15) / 30 * math.Pi) | ||||
| 	element.radialLine ( | ||||
| 		theme.AccentImage(), | ||||
| 		0, 0.7, float64(element.time.Second() - 15) / 30 * math.Pi) | ||||
| 	// TODO: engraved background, draw lines with std foreground, draw the | ||||
| 	// second hand with the accent color. | ||||
| } | ||||
| 
 | ||||
| func (element *AnalogClock) radialLine ( | ||||
| 	source tomo.Image, | ||||
| 	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) | ||||
| } | ||||
| @ -3,6 +3,7 @@ package main | ||||
| import "os" | ||||
| import "time" | ||||
| import "git.tebibyte.media/sashakoshka/tomo" | ||||
| import "git.tebibyte.media/sashakoshka/tomo/elements/fun" | ||||
| import "git.tebibyte.media/sashakoshka/tomo/elements/basic" | ||||
| import "git.tebibyte.media/sashakoshka/tomo/elements/layouts" | ||||
| import _ "git.tebibyte.media/sashakoshka/tomo/backends/x" | ||||
| @ -17,20 +18,25 @@ func run () { | ||||
| 	window.SetTitle("clock") | ||||
| 	container := basic.NewContainer(layouts.Vertical { true, true }) | ||||
| 	window.Adopt(container) | ||||
| 
 | ||||
| 	clock := fun.NewAnalogClock(time.Now()) | ||||
| 	container.Adopt(clock, true) | ||||
| 	label := basic.NewLabel(formatTime(), false) | ||||
| 	container.Adopt(label, false) | ||||
| 	 | ||||
| 	window.OnClose(tomo.Stop) | ||||
| 	window.Show() | ||||
| 	go tick(label) | ||||
| 	go tick(label, clock) | ||||
| } | ||||
| 
 | ||||
| func formatTime () (timeString string) { | ||||
| 	return time.Now().Format("2006-01-02 15:04:05") | ||||
| } | ||||
| 
 | ||||
| func tick (label *basic.Label) { | ||||
| func tick (label *basic.Label, clock *fun.AnalogClock) { | ||||
| 	for { | ||||
| 		label.SetText(formatTime()) | ||||
| 		clock.SetTime(time.Now()) | ||||
| 		time.Sleep(time.Second) | ||||
| 	} | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user