package ui import ( "git.solsynth.dev/highland/codingland/pkg/internal/land" "github.com/veandco/go-sdl2/sdl" "github.com/veandco/go-sdl2/ttf" "log" ) type ButtonWidget struct { land.BaseWidget Label string Font *ttf.Font OnClick func(mousePos land.Vector2D) isHovering bool isClicking bool } func (p *ButtonWidget) Draw(pen *sdl.Renderer) { if !p.BaseWidget.IsVisible { return } var borderColor, bgColor sdl.Color if p.isClicking { borderColor = sdl.Color{R: 200, G: 0, B: 0, A: 255} bgColor = sdl.Color{R: 255, G: 0, B: 0, A: 255} } else if p.isHovering { borderColor = sdl.Color{R: 0, G: 200, B: 0, A: 255} bgColor = sdl.Color{R: 0, G: 255, B: 0, A: 255} } else { borderColor = sdl.Color{R: 255, G: 255, B: 255, A: 255} bgColor = sdl.Color{R: 0, G: 0, B: 0, A: 255} } var borderWidth int32 = 2 pen.SetDrawColor(borderColor.R, borderColor.G, borderColor.B, borderColor.A) pen.FillRect(&sdl.Rect{ X: int32(p.Position.X), Y: int32(p.Position.Y), W: int32(p.Size.X), H: int32(p.Size.Y), }) pen.SetDrawColor(bgColor.R, bgColor.G, bgColor.B, bgColor.A) pen.FillRect(&sdl.Rect{ X: int32(p.Position.X) + borderWidth/2, Y: int32(p.Position.Y) + borderWidth/2, W: int32(p.Size.X) - borderWidth, H: int32(p.Size.Y) - borderWidth, }) surface, err := p.Font.RenderUTF8Blended(p.Label, sdl.Color{R: 255, G: 255, B: 255, A: 255}) if err != nil { log.Printf("Failed to render text: %s", err) return } defer surface.Free() texture, err := pen.CreateTextureFromSurface(surface) if err != nil { log.Printf("Failed to create texture: %s", err) return } defer texture.Destroy() textWidth := surface.W textHeight := surface.H textX := int32(p.BaseWidget.Position.X) + (int32(p.BaseWidget.Size.X)-textWidth)/2 textY := int32(p.BaseWidget.Position.Y) + (int32(p.BaseWidget.Size.Y)-textHeight)/2 textRect := sdl.Rect{X: textX, Y: textY, W: textWidth, H: textHeight} pen.Copy(texture, nil, &textRect) } func (p *ButtonWidget) OnEvent(event land.UserEventType, args ...any) { switch event { case land.UserEventMouseDown: p.isClicking = true p.OnClick(args[0].(land.Vector2D)) case land.UserEventMouseUp: p.isClicking = false case land.UserEventMouseMove: p.isHovering = args[1].(bool) } }