123 lines
2.6 KiB
Go
123 lines
2.6 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"image/color"
|
||
|
"log"
|
||
|
"strings"
|
||
|
"time"
|
||
|
|
||
|
"opslag.de/schobers/geom"
|
||
|
|
||
|
_ "opslag.de/schobers/zntg/addons/dragdrop" // import drag & drop functionality
|
||
|
_ "opslag.de/schobers/zntg/sdlui" // import the renderer for the UI
|
||
|
|
||
|
"opslag.de/schobers/zntg/ui"
|
||
|
)
|
||
|
|
||
|
type dropFiles struct {
|
||
|
ui.StackPanel
|
||
|
|
||
|
ctx ui.Context
|
||
|
files *ui.Paragraph
|
||
|
ping *ping
|
||
|
}
|
||
|
|
||
|
type ping struct {
|
||
|
ui.OverlayBase
|
||
|
|
||
|
circle ui.Texture
|
||
|
position geom.PointF32
|
||
|
over bool
|
||
|
tick time.Time
|
||
|
}
|
||
|
|
||
|
func (p *ping) Render(ctx ui.Context) {
|
||
|
elapsed := time.Since(p.tick)
|
||
|
const animationDuration = 500 * time.Millisecond
|
||
|
if elapsed > animationDuration {
|
||
|
return
|
||
|
}
|
||
|
tint := color.Gray{Y: uint8(elapsed * 255 / animationDuration)}
|
||
|
center := geom.PtF32(float32(p.circle.Width()), float32(p.circle.Height())).Mul(.5)
|
||
|
ctx.Renderer().DrawTexturePointOptions(p.circle, p.position.Sub(center), ui.DrawOptions{Tint: tint})
|
||
|
ctx.Animate()
|
||
|
}
|
||
|
|
||
|
func (d *dropFiles) Handle(ctx ui.Context, e ui.Event) bool {
|
||
|
switch e := e.(type) {
|
||
|
case *ui.DisplayDragMoveEnter:
|
||
|
d.ping.tick = time.Now()
|
||
|
d.ping.position = geom.PtF32(e.X, e.Y)
|
||
|
d.ping.over = true
|
||
|
d.ctx.Animate()
|
||
|
return true
|
||
|
case *ui.DisplayDropEvent:
|
||
|
d.files.Text = "Files dropped:\n" + strings.Join(e.Files, "\n")
|
||
|
d.ping.tick = time.Now()
|
||
|
d.ping.position = geom.PtF32(e.X, e.Y)
|
||
|
d.ping.over = false
|
||
|
d.ctx.Animate()
|
||
|
return true
|
||
|
}
|
||
|
return d.StackPanel.Handle(ctx, e)
|
||
|
}
|
||
|
|
||
|
func newCircle() ui.ImageSource {
|
||
|
const side = 16
|
||
|
center := geom.PtF32(.5*side, .5*side)
|
||
|
return &ui.AlphaPixelImageSource{
|
||
|
ImageAlphaPixelTestFn: func(p geom.PointF32) uint8 {
|
||
|
dist := p.Distance(center)
|
||
|
if dist < 7 {
|
||
|
return 255
|
||
|
} else if dist > 8 {
|
||
|
return 0
|
||
|
}
|
||
|
return uint8((8 - dist) * 255 * 0.5)
|
||
|
},
|
||
|
Size: geom.Pt(side, side),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (d *dropFiles) Init(ctx ui.Context) error {
|
||
|
d.ctx = ctx
|
||
|
|
||
|
_, err := ctx.Fonts().CreateFontPath("default", "../resources/font/OpenSans-Regular.ttf", 14)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
d.files = ui.BuildParagraph("", nil)
|
||
|
|
||
|
pingCircle, err := ctx.Renderer().CreateTexture(newCircle())
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
d.ping = &ping{circle: pingCircle}
|
||
|
ctx.Overlays().AddOnTop("ping", d.ping, true)
|
||
|
|
||
|
d.Background = color.White
|
||
|
d.Children = []ui.Control{
|
||
|
&ui.Label{Text: "Drop files on this window!"},
|
||
|
d.files,
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func run() error {
|
||
|
var render, err = ui.NewRendererDefault("Files Drop Example", 800, 600)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
defer render.Destroy()
|
||
|
|
||
|
return ui.RunWait(render, ui.DefaultStyle(), &dropFiles{}, true)
|
||
|
}
|
||
|
|
||
|
func main() {
|
||
|
var err = run()
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
}
|