package buttons import ( "image/color" "git.vezzani.net/ben/games/common/elements/v1" "git.vezzani.net/ben/games/common/elements/v1/blocks" "git.vezzani.net/ben/games/common/elements/v1/mouse" "git.vezzani.net/ben/games/common/ux/v1" "github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2/text" "golang.org/x/image/font" ) func New(ops ...OptFunc) elements.InitFunc { return func() elements.Element { b := Button{ Block: blocks.Block{}, font: ux.FontFace, color: ux.FontColor, } for op := range ops { ops[op](&b) } return &b } } type Button struct { blocks.Block label string font font.Face color color.Color onClick func(ms mouse.State) onMouseDown func(ms mouse.State) onMouseUp func(ms mouse.State) } func (b *Button) Draw(screen *ebiten.Image) { b.Block.Draw(screen) b.drawLabel(screen) } func (b *Button) drawLabel(screen *ebiten.Image) { if b.label != "" { strBounds, _ := font.BoundString(b.font, b.label) textWidth := strBounds.Max.X - strBounds.Min.X textHeight := strBounds.Max.Y - strBounds.Min.Y bnd := b.Bounds() tx := bnd.Min.X + (bnd.Width / 2) - (textWidth / 2).Round() ty := bnd.Min.Y + (bnd.Height / 2) - (textHeight / 2).Round() text.Draw(screen, b.label, b.font, tx, ty, b.color) } } func (b *Button) HandleMouseEvent(ms mouse.State) bool { bnd := b.Bounds() if !bnd.Contains(ms.Point()) { return false } switch { case b.onClick != nil && (ms.RightClicked || ms.LeftClicked): b.onClick(ms) return true case b.onMouseUp != nil && (ms.RightChanged && !ms.RightDown || ms.LeftChanged && !ms.LeftDown): b.onMouseUp(ms) return true case b.onMouseDown != nil && (ms.RightChanged && ms.RightDown || ms.LeftChanged && ms.LeftDown): b.onMouseDown(ms) return true } return false }