Rework the UI framework
Interface is now Driver, and Widget is now a set of interfaces with a struct per widget type. This should make it easier to add other types.
This commit is contained in:
@@ -1,20 +1,97 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
"image"
|
||||
|
||||
"code.ur.gs/lupine/ordoor/internal/menus"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerBuilder(menus.TypeStatic, registerStatic)
|
||||
registerBuilder(menus.TypeHypertext, registerHypertext)
|
||||
registerBuilder(menus.TypeAnimationSample, registerAnimation)
|
||||
}
|
||||
|
||||
// A non-interactive element is not a widget; it merely displays some pixels and
|
||||
// may optionally have a tooltip for display within bounds.
|
||||
//
|
||||
// For non-animated non-interactive elements, just give them a single frame.
|
||||
type noninteractive struct {
|
||||
bounds image.Rectangle
|
||||
frames animation
|
||||
tooltip string
|
||||
frames animation
|
||||
rect image.Rectangle
|
||||
|
||||
hoverImpl
|
||||
}
|
||||
|
||||
func (n *noninteractive) image(step int) *ebiten.Image {
|
||||
return n.frames.image(step)
|
||||
func registerStatic(d *Driver, r *menus.Record) error {
|
||||
// FIXME: SpriteID takes precedence over SHARE if present, but is that right?
|
||||
spriteId := r.Share
|
||||
if len(r.SpriteId) > 0 && r.SpriteId[0] != -1 {
|
||||
spriteId = r.SpriteId[0]
|
||||
}
|
||||
|
||||
sprite, err := d.menu.Sprite(spriteId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ni := &noninteractive{
|
||||
frames: animation{sprite.Image},
|
||||
hoverImpl: hoverImpl{text: r.Desc},
|
||||
rect: sprite.Rect,
|
||||
}
|
||||
|
||||
d.hoverables = append(d.hoverables, ni)
|
||||
d.paintables = append(d.paintables, ni)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func registerHypertext(d *Driver, r *menus.Record) error {
|
||||
sprite, err := d.menu.Sprite(r.Share)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ni := &noninteractive{
|
||||
frames: nil,
|
||||
hoverImpl: hoverImpl{text: r.Desc},
|
||||
rect: sprite.Rect,
|
||||
}
|
||||
|
||||
d.hoverables = append(d.hoverables, ni)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// An animation is a non-interactive element that displays something in a loop
|
||||
func registerAnimation(d *Driver, r *menus.Record) error {
|
||||
sprite, err := d.menu.Sprite(r.SpriteId[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
frames, err := d.menu.Images(r.SpriteId[0], r.DrawType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ani := &noninteractive{
|
||||
frames: animation(frames),
|
||||
hoverImpl: hoverImpl{text: r.Desc},
|
||||
rect: sprite.Rect,
|
||||
}
|
||||
|
||||
d.hoverables = append(d.hoverables, ani)
|
||||
d.paintables = append(d.paintables, ani)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *noninteractive) bounds() image.Rectangle {
|
||||
return n.rect
|
||||
}
|
||||
|
||||
func (n *noninteractive) regions(tick int) []region {
|
||||
return oneRegion(n.bounds().Min, n.frames.image(tick))
|
||||
}
|
||||
|
Reference in New Issue
Block a user