This commit implements loading and saving options from/to config, and enough UI toolkit magic to allow changes to boolean options to be persisted. We now respect the "play movies" setting and take screen resolution from the config file.
186 lines
4.0 KiB
Go
186 lines
4.0 KiB
Go
package ui
|
|
|
|
import (
|
|
"github.com/hajimehoshi/ebiten"
|
|
|
|
"code.ur.gs/lupine/ordoor/internal/menus"
|
|
)
|
|
|
|
// Setup handlers know how to handle each type of widget
|
|
var setupHandlers = map[menus.MenuType]func(i *Interface, r *menus.Record) error {
|
|
menus.TypeStatic: handleStatic,
|
|
menus.TypeMenu: nil,
|
|
menus.TypeButton: handleButton,
|
|
menus.TypeInvokeButton: handleInvokeButton,
|
|
menus.TypeOverlay: handleStatic, // FIXME: more?
|
|
menus.TypeHypertext: nil, // FIXME: handle this
|
|
menus.TypeCheckbox: handleCheckbox,
|
|
menus.TypeAnimationSample: nil, // FIXME: handle this
|
|
menus.TypeMainButton: handleMainButton,
|
|
menus.TypeSlider: nil, // FIXME: handle this
|
|
}
|
|
|
|
func handleStatic(i *Interface, record *menus.Record) error {
|
|
spriteId := record.Share
|
|
|
|
// FIXME: SpriteID takes precedence over SHARE if present, but is that right?
|
|
if len(record.SpriteId) > 0 && record.SpriteId[0] != -1 {
|
|
spriteId = record.SpriteId[0]
|
|
}
|
|
|
|
sprite, err := i.menu.Sprite(spriteId)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
i.static = append(i.static, sprite)
|
|
|
|
return nil
|
|
}
|
|
|
|
// A checkbox has 3 sprites, and 3 states: unchecked, checked, disabled.
|
|
func handleCheckbox(i *Interface, record *menus.Record) error {
|
|
widget, err := i.widgetFromRecord(record, record.Share)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
unchecked := widget.sprite
|
|
disabled, err := i.menu.Sprite(record.Share + 1)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
checked, err := i.menu.Sprite(record.Share + 2)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
widget.Value = "0"
|
|
|
|
widget.OnMouseClick = func() {
|
|
if widget.Value == "1" { // Click disables
|
|
widget.Value = "0"
|
|
} else { // Click enables
|
|
widget.Value = "1"
|
|
}
|
|
}
|
|
|
|
widget.disabledImage = disabled.Image
|
|
widget.valueToImage = func() *ebiten.Image {
|
|
if widget.Value == "1" {
|
|
return checked.Image
|
|
}
|
|
|
|
return unchecked.Image
|
|
}
|
|
|
|
i.widgets = append(i.widgets, widget)
|
|
|
|
return nil
|
|
}
|
|
|
|
func handleButton(i *Interface, record *menus.Record) error {
|
|
spriteId := record.SpriteId[0]
|
|
widget, err := i.widgetFromRecord(record, spriteId)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
pressed, err := i.menu.Sprite(spriteId + 1)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
disabled, err := i.menu.Sprite(spriteId + 2)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
widget.mouseButtonDownImage = pressed.Image
|
|
widget.disabledImage = disabled.Image
|
|
|
|
i.widgets = append(i.widgets, widget)
|
|
|
|
return nil
|
|
}
|
|
|
|
func handleInvokeButton(i *Interface, record *menus.Record) error {
|
|
widget, err := i.widgetFromRecord(record, record.Share)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
pressed, err := i.menu.Sprite(record.Share + 1)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
disabled, err := i.menu.Sprite(record.Share + 2)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
widget.mouseButtonDownImage = pressed.Image
|
|
widget.disabledImage = disabled.Image
|
|
|
|
i.widgets = append(i.widgets, widget)
|
|
|
|
return nil
|
|
}
|
|
|
|
// A main button is quite complex. It has 3 main sprites and a hover animation
|
|
func handleMainButton(i *Interface, record *menus.Record) error {
|
|
widget, err := i.widgetFromRecord(record, record.Share)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
pressed, err := i.menu.Sprite(record.Share + 1)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
disabled, err := i.menu.Sprite(record.Share + 2)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
hovers, err := i.menu.Images(record.SpriteId[0], record.DrawType)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
widget.mouseButtonDownImage = pressed.Image
|
|
widget.disabledImage = disabled.Image
|
|
widget.hoverAnimation = hovers
|
|
|
|
i.widgets = append(i.widgets, widget)
|
|
|
|
return nil
|
|
}
|
|
|
|
|
|
// Widgets need a bounding box determined by a sprite. Different widgets specify
|
|
// their sprites in different attributes, so pass in the right sprite externally
|
|
func (i *Interface) widgetFromRecord(record *menus.Record, spriteId int) (*Widget, error) {
|
|
sprite, err := i.menu.Sprite(spriteId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var path []int
|
|
for r := record; r != nil; r = r.Parent {
|
|
path = append([]int{r.Id}, path...)
|
|
}
|
|
|
|
widget := &Widget{
|
|
Bounds: sprite.Rect,
|
|
Tooltip: record.Desc,
|
|
path: path,
|
|
record: record,
|
|
sprite: sprite,
|
|
}
|
|
|
|
return widget, nil
|
|
}
|