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:
136
internal/ui/buttons.go
Normal file
136
internal/ui/buttons.go
Normal file
@@ -0,0 +1,136 @@
|
||||
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)
|
||||
}
|
Reference in New Issue
Block a user