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.DisplayDragMoveEvent: 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) } }