zntg/ui/spinner.go

98 lines
2.4 KiB
Go

package ui
import (
"image"
"image/color"
"math"
"time"
"github.com/llgcode/draw2d/draw2dimg"
"opslag.de/schobers/galleg/allegro5"
)
var _ Control = &Spinner{}
type Spinner struct {
ControlBase
Text string
spin float32
circs []*allegro5.Bitmap
}
func createCirle(r, w int, startAngle, a float64, c color.Color) *allegro5.Bitmap {
var width = 2*r + w
dest := image.NewRGBA(image.Rect(0, 0, width, width))
gc := draw2dimg.NewGraphicContext(dest)
gc.SetFillColor(color.Transparent)
gc.Clear()
gc.SetFillColor(c)
gc.SetStrokeColor(c)
gc.SetLineWidth(float64(w))
var rad = float64(r)
var cnt = float64(width) * .5
var dx1, dy1 = cnt + math.Cos(startAngle)*rad, cnt + math.Sin(startAngle)*rad
gc.MoveTo(dx1, dy1)
gc.ArcTo(cnt, cnt, rad, rad, startAngle, a)
gc.Stroke()
bmp, err := allegro5.NewBitmapFromImage(dest, false)
if nil != err {
return nil
}
return bmp
}
func (s *Spinner) Created(ctx Context, p Container) error {
s.ControlBase.Created(ctx, p)
const numCircs = 32
s.circs = make([]*allegro5.Bitmap, numCircs)
var am = math.Pi * 2 / float64(numCircs)
for i := range s.circs {
s.circs[i] = createCirle(8, 3, float64(i)*am, math.Pi, Blue500)
}
return nil
}
func (s *Spinner) Destroyed(ctx Context) {
for _, circ := range s.circs {
circ.Destroy()
}
}
func (s *Spinner) Update(ctx Context, dt time.Duration) {
var spin = float64(s.spin)
spin += dt.Seconds()
for spin > 1. {
spin -= 1.
}
s.spin = float32(spin)
}
func (s *Spinner) Render(ctx Context) {
var disp = ctx.Display()
var fonts = ctx.Fonts()
var width = float32(disp.Width())
var height = float32(disp.Height())
var fnt = fonts.Get("default")
var textW = fnt.TextWidth(s.Text)
allegro5.DrawFilledRectangle(0, 0, width, height, ctx.Palette().Disabled())
const marginH, marginV float32 = 64, 16
const textH float32 = 12
var rectW, rectH float32 = textW + 2*marginH, 3*marginV + textH + 32
var rectX, rectY = (width - rectW) * .5, (height - rectH) * .5
allegro5.DrawFilledRectangle(rectX, rectY, rectX+rectW, rectY+rectH, ctx.Palette().White())
DropShadow(rectX, rectY, rectX+rectW, rectY+rectH)
fnt.Draw(rectX+marginH, rectY+marginV, ctx.Palette().Black(), allegro5.AlignLeft, s.Text)
const numCircs = 32
var i = int(math.Floor(float64(s.spin) * numCircs))
s.circs[i].DrawOptions(width*.5, rectY+2*marginV+2*textH, allegro5.DrawOptions{Center: true})
s.ControlBase.Render(ctx)
}