98 lines
2.4 KiB
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)
|
||
|
}
|