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.
137 lines
2.7 KiB
Go
137 lines
2.7 KiB
Go
package ui
|
|
|
|
import (
|
|
"image"
|
|
|
|
"code.ur.gs/lupine/ordoor/internal/assetstore"
|
|
"code.ur.gs/lupine/ordoor/internal/menus"
|
|
)
|
|
|
|
func init() {
|
|
registerBuilder(menus.TypeSimpleButton, registerSimpleButton)
|
|
registerBuilder(menus.TypeInvokeButton, registerInvokeButton)
|
|
registerBuilder(menus.TypeMainButton, registerMainButton)
|
|
}
|
|
|
|
// A button without hover animation
|
|
type button struct {
|
|
path string
|
|
|
|
baseSpr *assetstore.Sprite
|
|
clickSpr *assetstore.Sprite
|
|
frozenSpr *assetstore.Sprite
|
|
|
|
clickImpl
|
|
freezeImpl
|
|
hoverImpl
|
|
}
|
|
|
|
// A button with hover animation
|
|
type mainButton struct {
|
|
hoverAnim animation
|
|
|
|
button
|
|
}
|
|
|
|
func registerSimpleButton(d *Driver, r *menus.Record) error {
|
|
return registerButton(d, r, r.SpriteId[0])
|
|
}
|
|
|
|
func registerInvokeButton(d *Driver, r *menus.Record) error {
|
|
return registerButton(d, r, r.Share)
|
|
}
|
|
|
|
func registerMainButton(d *Driver, r *menus.Record) error {
|
|
sprites, err := d.menu.Sprites(r.Share, 3) // base, pressed, disabled
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
hovers, err := d.menu.Images(r.SpriteId[0], r.DrawType)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
btn := &mainButton{
|
|
hoverAnim: animation(hovers),
|
|
button: button{
|
|
path: r.Path(),
|
|
baseSpr: sprites[0],
|
|
clickSpr: sprites[1],
|
|
frozenSpr: sprites[2],
|
|
hoverImpl: hoverImpl{text: r.Desc},
|
|
},
|
|
}
|
|
|
|
d.clickables = append(d.clickables, btn)
|
|
d.freezables = append(d.freezables, btn)
|
|
d.hoverables = append(d.hoverables, btn)
|
|
d.paintables = append(d.paintables, btn)
|
|
|
|
return nil
|
|
}
|
|
|
|
func registerButton(d *Driver, r *menus.Record, spriteId int) error {
|
|
sprites, err := d.menu.Sprites(spriteId, 3) // base, pressed, disabled
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
btn := &button{
|
|
path: r.Path(),
|
|
baseSpr: sprites[0],
|
|
clickSpr: sprites[1],
|
|
frozenSpr: sprites[2],
|
|
hoverImpl: hoverImpl{text: r.Desc},
|
|
}
|
|
|
|
d.clickables = append(d.clickables, btn)
|
|
d.freezables = append(d.freezables, btn)
|
|
d.hoverables = append(d.hoverables, btn)
|
|
d.paintables = append(d.paintables, btn)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (b *button) id() string {
|
|
return b.path
|
|
}
|
|
|
|
func (b *button) bounds() image.Rectangle {
|
|
return b.baseSpr.Rect
|
|
}
|
|
|
|
func (b *button) mouseDownState() bool {
|
|
if b.isFrozen() {
|
|
return false
|
|
}
|
|
|
|
return b.clickImpl.mouseDownState()
|
|
}
|
|
|
|
func (b *button) registerMouseClick() {
|
|
if !b.isFrozen() {
|
|
b.clickImpl.registerMouseClick()
|
|
}
|
|
}
|
|
|
|
func (b *button) regions(tick int) []region {
|
|
if b.isFrozen() {
|
|
return oneRegion(b.bounds().Min, b.frozenSpr.Image)
|
|
}
|
|
|
|
if b.mouseDownState() {
|
|
return oneRegion(b.bounds().Min, b.clickSpr.Image)
|
|
}
|
|
|
|
return oneRegion(b.bounds().Min, b.baseSpr.Image)
|
|
}
|
|
|
|
func (m *mainButton) regions(tick int) []region {
|
|
if !m.isFrozen() && !m.mouseDownState() && m.hoverState() {
|
|
return oneRegion(m.bounds().Min, m.hoverAnim.image(tick))
|
|
}
|
|
|
|
return m.button.regions(tick)
|
|
}
|