package ui import ( "image" "github.com/hajimehoshi/ebiten" "code.ur.gs/lupine/ordoor/internal/assetstore" "code.ur.gs/lupine/ordoor/internal/menus" ) // Widget represents an interactive area of the screen. Backgrounds and other // non-interactive areas are not widgets. type Widget struct { // Position on the screen in original (i.e., unscaled) coordinates Bounds image.Rectangle Tooltip string Value string // #dealwithit for bools and ints and so on :p OnHoverEnter func() OnHoverLeave func() // Mouse up can happen without a click taking place if, for instance, the // mouse cursor leaves the bounds while still pressed. OnMouseDown func() OnMouseClick func() OnMouseUp func() disabled bool disabledImage *ebiten.Image // These are expected to have the same dimensions as the Bounds hoverAnimation []*ebiten.Image hoverState bool // FIXME: We assume right mouse button isn't needed here // TODO: down, up, and click hooks. mouseButtonDownImage *ebiten.Image mouseButtonState bool path []int record *menus.Record sprite *assetstore.Sprite valueToImage func() *ebiten.Image } func (w *Widget) Disable() { w.hovering(false) w.mouseButton(false) w.disabled = true } func (w *Widget) hovering(value bool) { if w.OnHoverEnter != nil && !w.hoverState && value { w.OnHoverEnter() } if w.OnHoverLeave != nil && w.hoverState && !value { w.OnHoverLeave() } w.hoverState = value return } func (w *Widget) mouseButton(value bool) { if w.OnMouseDown != nil && !w.mouseButtonState && value { w.OnMouseDown() } if w.mouseButtonState && !value { if w.OnMouseClick != nil && w.hoverState { w.OnMouseClick() } if w.OnMouseUp != nil { w.OnMouseUp() } } w.mouseButtonState = value } func (w *Widget) Image(aniStep int) (*ebiten.Image, error) { if w.disabled { return w.disabledImage, nil } if w.mouseButtonDownImage != nil && w.hoverState && w.mouseButtonState { return w.mouseButtonDownImage, nil } if w.hoverState && len(w.hoverAnimation) > 0 { return w.hoverAnimation[(aniStep)%len(w.hoverAnimation)], nil } if w.valueToImage != nil { return w.valueToImage(), nil } return w.sprite.Image, nil }