package mouse import ( "git.vezzani.net/ben/games/common/elements/v1" "github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2/inpututil" ) type NopHandler struct{} func (n NopHandler) HandleMouseEvent(s State) bool { return false } type ChildrenProvider interface { GetChildren() []elements.Element } type EventHandler interface { HandleMouseEvent(s State) bool } type State struct { X, Y int LeftDown, RightDown bool LeftChanged, RightChanged bool LeftClicked, RightClicked bool Clicked bool } func Handler(e elements.Element) func() bool { newState := StateBuilder() ms := newState() return func() bool { ms = newState() return propagateMouse(e, ms) } } func propagateMouse(e elements.Element, ms State) bool { if p, ok := e.(ChildrenProvider); ok { for _, c := range p.GetChildren() { if propagateMouse(c, ms) { return true } } } if e, ok := e.(EventHandler); ok { return e.HandleMouseEvent(ms) } return false } func StateBuilder() func() State { prevState := State{} state := State{} return func() State { state = prevState state.X, state.Y = ebiten.CursorPosition() if inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonLeft) { state.LeftDown = true } if inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonRight) { state.RightDown = true } if inpututil.IsMouseButtonJustReleased(ebiten.MouseButtonLeft) { state.LeftDown = false if !state.RightDown { state.Clicked = true } } if inpututil.IsMouseButtonJustReleased(ebiten.MouseButtonRight) { state.RightDown = false if !state.LeftDown { state.Clicked = true } } state.Clicked = state.Clicked && !prevState.Clicked state.LeftChanged = state.LeftDown != prevState.LeftDown state.RightChanged = state.RightDown != prevState.RightDown state.LeftClicked = state.LeftChanged && state.LeftDown state.RightClicked = state.RightChanged && state.RightDown prevState = state return state } }