Files
ordoor/internal/ui/widget.go
Nick Thomas bfe9fbdf7d Start work on menu interactivity.
With this commit, we get a ui.Interface and ui.Widget type. The
interface monitors hover and mouse click state and tells the widgets
about them; the widgets execute code specified by the application when
events occur.

Next step: have wh40k load the main menu and play sound, etc.
2020-03-22 02:58:52 +00:00

85 lines
1.8 KiB
Go

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 // TODO: show the tooltip when hovering?
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()
// 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
}
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.hoverState && w.mouseButtonState {
return w.mouseButtonDownImage, nil
}
if w.hoverState && len(w.hoverAnimation) > 0 {
return w.hoverAnimation[(aniStep)%len(w.hoverAnimation)], nil
}
return w.sprite.Image, nil
}