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 "os" | ||||||
| import "time" | import "time" | ||||||
| import "git.tebibyte.media/sashakoshka/tomo" | 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/basic" | ||||||
| import "git.tebibyte.media/sashakoshka/tomo/elements/layouts" | import "git.tebibyte.media/sashakoshka/tomo/elements/layouts" | ||||||
| import _ "git.tebibyte.media/sashakoshka/tomo/backends/x" | import _ "git.tebibyte.media/sashakoshka/tomo/backends/x" | ||||||
| @ -17,20 +18,25 @@ func run () { | |||||||
| 	window.SetTitle("clock") | 	window.SetTitle("clock") | ||||||
| 	container := basic.NewContainer(layouts.Vertical { true, true }) | 	container := basic.NewContainer(layouts.Vertical { true, true }) | ||||||
| 	window.Adopt(container) | 	window.Adopt(container) | ||||||
|  | 
 | ||||||
|  | 	clock := fun.NewAnalogClock(time.Now()) | ||||||
|  | 	container.Adopt(clock, true) | ||||||
| 	label := basic.NewLabel(formatTime(), false) | 	label := basic.NewLabel(formatTime(), false) | ||||||
| 	container.Adopt(label, false) | 	container.Adopt(label, false) | ||||||
|  | 	 | ||||||
| 	window.OnClose(tomo.Stop) | 	window.OnClose(tomo.Stop) | ||||||
| 	window.Show() | 	window.Show() | ||||||
| 	go tick(label) | 	go tick(label, clock) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func formatTime () (timeString string) { | func formatTime () (timeString string) { | ||||||
| 	return time.Now().Format("2006-01-02 15:04:05") | 	return time.Now().Format("2006-01-02 15:04:05") | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func tick (label *basic.Label) { | func tick (label *basic.Label, clock *fun.AnalogClock) { | ||||||
| 	for { | 	for { | ||||||
| 		label.SetText(formatTime()) | 		label.SetText(formatTime()) | ||||||
|  | 		clock.SetTime(time.Now()) | ||||||
| 		time.Sleep(time.Second) | 		time.Sleep(time.Second) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user