Files
ordoor/internal/ordoor/interfaces.go
Nick Thomas 69971b2825 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.
2020-03-24 20:21:55 +00:00

156 lines
4.1 KiB
Go

package ordoor
import (
"log"
"code.ur.gs/lupine/ordoor/internal/ui"
)
func try(result error, into *error) {
if *into == nil {
*into = result
}
}
// These are UI interfaces covering the game entrypoint
func (o *Ordoor) mainDriver() (*ui.Driver, error) {
// Start in the "main" menu
main, err := o.buildDriver("main")
if err != nil {
return nil, err
}
options, err := o.optionsDriver(main)
if err != nil {
return nil, err
}
// TODO: clicking these buttons should load other interfaces
try(main.OnClick("2.1", func() {}), &err) // New game
try(main.OnClick("2.2", func() {}), &err) // Load game
try(main.SetFreeze("2.3", true), &err) // Multiplayer - disable for now
try(main.OnClick("2.4", func() { o.driver = options }), &err) // Options
try(main.OnClick("2.5", func() { o.nextState = StateExit }), &err) // Quit
return main, err
}
// Options needs to know how to go back to main
func (o *Ordoor) optionsDriver(main *ui.Driver) (*ui.Driver, error) {
options, err := o.buildDriver("options")
if err != nil {
return nil, err
}
if err := o.configIntoOptions(options); err != nil {
return nil, err
}
// TODO: load current options state into UI
try(options.OnClick("2.8", func() {}), &err) // Keyboard settings button
// Resolution slider is 2.9
// Music volume slider is 2.10
// Sound FX volume slider is 2.11
try(options.OnClick("2.12", acceptOptionsFn(o, main, options)), &err)
// 13...23 are "hypertext"
try(options.OnClick("2.24", cancelOptionsFn(o, main, options)), &err)
// Unit speed slider is 2,26
// Looping effect speed slider is 2,27
// Sample of unit speed animation is 2,28
// Sample of effect speed animation is 2,29
// 30...35 are "hypertext"
return options, err
}
// FIXME: exiting is a bit OTT. Perhaps display "save failed"?
func acceptOptionsFn(o *Ordoor, main, options *ui.Driver) func() {
return func() {
if err := o.optionsIntoConfig(options); err != nil {
log.Printf("Saving options to config failed: %v", err)
o.nextState = StateExit
} else {
o.driver = main
}
}
}
// FIXME: again, exiting is OTT. We're just resetting the state of
// the interface to the values in config.
func cancelOptionsFn(o *Ordoor, main, options *ui.Driver) func() {
return func() {
if err := o.configIntoOptions(options); err != nil {
log.Printf("Saving options to config failed: %v", err)
o.nextState = StateExit
} else {
o.driver = main
}
}
}
func (o *Ordoor) configIntoOptions(options *ui.Driver) error {
cfg := &o.config.Options
var err error
try(options.SetValueBool("2.1", cfg.PlayMovies), &err)
try(options.SetValueBool("2.1", cfg.Animations), &err)
try(options.SetValueBool("2.3", cfg.PlayMusic), &err)
try(options.SetValueBool("2.4", cfg.CombatVoices), &err)
try(options.SetValueBool("2.5", cfg.ShowGrid), &err)
try(options.SetValueBool("2.6", cfg.ShowPaths), &err)
try(options.SetValueBool("2.7", cfg.PointSaving), &err)
try(options.SetValueBool("2.25", cfg.AutoCutLevel), &err)
return err
}
func (o *Ordoor) optionsIntoConfig(options *ui.Driver) error {
cfg := &o.config.Options
var err error
try(options.ValueBool("2.1", &cfg.PlayMovies), &err)
try(options.ValueBool("2.2", &cfg.Animations), &err)
try(options.ValueBool("2.3", &cfg.PlayMusic), &err)
try(options.ValueBool("2.4", &cfg.CombatVoices), &err)
try(options.ValueBool("2.5", &cfg.ShowGrid), &err)
try(options.ValueBool("2.6", &cfg.ShowPaths), &err)
try(options.ValueBool("2.7", &cfg.PointSaving), &err)
try(options.ValueBool("2.25", &cfg.AutoCutLevel), &err)
if err != nil {
return err
}
if err := o.config.Save(); err != nil {
return err
}
// TODO: emit events, rather than just modifying state here
if o.music != nil && o.music.IsPlaying() != cfg.PlayMusic {
if cfg.PlayMusic {
o.music.Rewind()
o.music.Play()
} else {
o.music.Pause()
}
}
return nil
}
func (o *Ordoor) buildDriver(name string) (*ui.Driver, error) {
menu, err := o.assets.Menu(name)
if err != nil {
return nil, err
}
driver, err := ui.NewDriver(menu)
if err != nil {
return nil, err
}
return driver, nil
}