Make animations work in the options screen
This commit is contained in:
@@ -1,19 +1,25 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"flag"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"code.ur.gs/lupine/ordoor/internal/ordoor"
|
"code.ur.gs/lupine/ordoor/internal/ordoor"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
winX = flag.Int("win-x", 0, "Pre-scaled window X dimension override")
|
||||||
|
winY = flag.Int("win-y", 0, "Pre-scaled window Y dimension override")
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
configFile := "config.toml"
|
configFile := "config.toml"
|
||||||
if len(os.Args) == 2 {
|
if len(os.Args) == 2 {
|
||||||
configFile = os.Args[1]
|
configFile = os.Args[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ordoor.Run(configFile); err != nil {
|
if err := ordoor.Run(configFile, *winX, *winY); err != nil {
|
||||||
log.Fatalf(err.Error())
|
log.Fatalf(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -24,6 +24,7 @@ var (
|
|||||||
|
|
||||||
type env struct {
|
type env struct {
|
||||||
obj *assetstore.Object
|
obj *assetstore.Object
|
||||||
|
spr *assetstore.Sprite
|
||||||
step int
|
step int
|
||||||
|
|
||||||
state state
|
state state
|
||||||
@@ -92,10 +93,17 @@ func main() {
|
|||||||
|
|
||||||
func (e *env) Update(screenX, screenY int) error {
|
func (e *env) Update(screenX, screenY int) error {
|
||||||
if e.step == 0 || e.lastState != e.state {
|
if e.step == 0 || e.lastState != e.state {
|
||||||
|
sprite, err := e.obj.Sprite(e.state.spriteIdx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
e.spr = sprite
|
||||||
|
|
||||||
log.Printf(
|
log.Printf(
|
||||||
"new state: sprite=%d/%d zoom=%.2f, origin=%+v",
|
"new state: sprite=%d/%d bounds=%+#v zoom=%.2f, origin=%+v",
|
||||||
e.state.spriteIdx,
|
e.state.spriteIdx,
|
||||||
e.obj.NumSprites,
|
e.obj.NumSprites,
|
||||||
|
e.spr.Rect,
|
||||||
e.state.zoom,
|
e.state.zoom,
|
||||||
e.state.origin,
|
e.state.origin,
|
||||||
)
|
)
|
||||||
|
@@ -233,3 +233,13 @@ func (m *Menu) Internationalize(replacer Replacer) {
|
|||||||
record.Internationalize(replacer)
|
record.Internationalize(replacer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Record) Path() string {
|
||||||
|
var path []string
|
||||||
|
|
||||||
|
for rec := r; rec != nil; rec = rec.Parent {
|
||||||
|
path = append([]string{strconv.Itoa(rec.Id)}, path...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(path, ".")
|
||||||
|
}
|
||||||
|
@@ -28,11 +28,11 @@ func (o *Ordoor) ifaceMain() (*ui.Interface, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: clicking these buttons should load other interfaces
|
// TODO: clicking these buttons should load other interfaces
|
||||||
try(wireupClick(main, func() {}, 2, 1), &err) // New game
|
try(wireupClick(main, func() {}, "2.1"), &err) // New game
|
||||||
try(wireupClick(main, func() {}, 2, 2), &err) // Load game
|
try(wireupClick(main, func() {}, "2.2"), &err) // Load game
|
||||||
try(disableWidget(main, 2, 3), &err) // Multiplayer - disable for now
|
try(disableWidget(main, "2.3"), &err) // Multiplayer - disable for now
|
||||||
try(wireupClick(main, func() { o.iface = options }, 2, 4), &err) // Options
|
try(wireupClick(main, func() { o.iface = options }, "2.4"), &err) // Options
|
||||||
try(wireupClick(main, func() { o.nextState = StateExit }, 2, 5), &err) // Quit
|
try(wireupClick(main, func() { o.nextState = StateExit }, "2.5"), &err) // Quit
|
||||||
|
|
||||||
return main, err
|
return main, err
|
||||||
}
|
}
|
||||||
@@ -49,10 +49,10 @@ func (o *Ordoor) ifaceOptions(main *ui.Interface) (*ui.Interface, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: load current options state into UI
|
// TODO: load current options state into UI
|
||||||
try(wireupClick(options, func() {}, 2, 8), &err) // Keyboard settings button
|
try(wireupClick(options, func() {}, "2.8"), &err) // Keyboard settings button
|
||||||
// Resolution slider is 2,9
|
// Resolution slider is 2.9
|
||||||
// Music volume slider is 2,10
|
// Music volume slider is 2.10
|
||||||
// Sound FX volume slider is 2,11
|
// Sound FX volume slider is 2.11
|
||||||
|
|
||||||
// Accept button
|
// Accept button
|
||||||
try(wireupClick(
|
try(wireupClick(
|
||||||
@@ -65,7 +65,7 @@ func (o *Ordoor) ifaceOptions(main *ui.Interface) (*ui.Interface, error) {
|
|||||||
o.iface = main
|
o.iface = main
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
2, 12,
|
"2.12",
|
||||||
), &err)
|
), &err)
|
||||||
|
|
||||||
// 13...23 are "hypertext"
|
// 13...23 are "hypertext"
|
||||||
@@ -84,7 +84,7 @@ func (o *Ordoor) ifaceOptions(main *ui.Interface) (*ui.Interface, error) {
|
|||||||
o.iface = main
|
o.iface = main
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
2, 24,
|
"2.24",
|
||||||
), &err)
|
), &err)
|
||||||
// Unit speed slider is 2,26
|
// Unit speed slider is 2,26
|
||||||
// Looping effect speed slider is 2,27
|
// Looping effect speed slider is 2,27
|
||||||
@@ -100,14 +100,14 @@ func (o *Ordoor) configIntoOptions(options *ui.Interface) error {
|
|||||||
cfg := &o.config.Options
|
cfg := &o.config.Options
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
try(setWidgetValueBool(options, cfg.PlayMovies, 2, 1), &err)
|
try(setWidgetValueBool(options, cfg.PlayMovies, "2.1"), &err)
|
||||||
try(setWidgetValueBool(options, cfg.Animations, 2, 2), &err)
|
try(setWidgetValueBool(options, cfg.Animations, "2.2"), &err)
|
||||||
try(setWidgetValueBool(options, cfg.PlayMusic, 2, 3), &err)
|
try(setWidgetValueBool(options, cfg.PlayMusic, "2.3"), &err)
|
||||||
try(setWidgetValueBool(options, cfg.CombatVoices, 2, 4), &err)
|
try(setWidgetValueBool(options, cfg.CombatVoices, "2.4"), &err)
|
||||||
try(setWidgetValueBool(options, cfg.ShowGrid, 2, 5), &err)
|
try(setWidgetValueBool(options, cfg.ShowGrid, "2.5"), &err)
|
||||||
try(setWidgetValueBool(options, cfg.ShowPaths, 2, 6), &err)
|
try(setWidgetValueBool(options, cfg.ShowPaths, "2.6"), &err)
|
||||||
try(setWidgetValueBool(options, cfg.PointSaving, 2, 7), &err)
|
try(setWidgetValueBool(options, cfg.PointSaving, "2.7"), &err)
|
||||||
try(setWidgetValueBool(options, cfg.AutoCutLevel, 2, 25), &err)
|
try(setWidgetValueBool(options, cfg.AutoCutLevel, "2.25"), &err)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -116,20 +116,34 @@ func (o *Ordoor) optionsIntoConfig(options *ui.Interface) error {
|
|||||||
cfg := &o.config.Options
|
cfg := &o.config.Options
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
try(getWidgetValueBool(options, &cfg.PlayMovies, 2, 1), &err)
|
try(getWidgetValueBool(options, &cfg.PlayMovies, "2.1"), &err)
|
||||||
try(getWidgetValueBool(options, &cfg.Animations, 2, 2), &err)
|
try(getWidgetValueBool(options, &cfg.Animations, "2.2"), &err)
|
||||||
try(getWidgetValueBool(options, &cfg.PlayMusic, 2, 3), &err)
|
try(getWidgetValueBool(options, &cfg.PlayMusic, "2.3"), &err)
|
||||||
try(getWidgetValueBool(options, &cfg.CombatVoices, 2, 4), &err)
|
try(getWidgetValueBool(options, &cfg.CombatVoices, "2.4"), &err)
|
||||||
try(getWidgetValueBool(options, &cfg.ShowGrid, 2, 5), &err)
|
try(getWidgetValueBool(options, &cfg.ShowGrid, "2.5"), &err)
|
||||||
try(getWidgetValueBool(options, &cfg.ShowPaths, 2, 6), &err)
|
try(getWidgetValueBool(options, &cfg.ShowPaths, "2.6"), &err)
|
||||||
try(getWidgetValueBool(options, &cfg.PointSaving, 2, 7), &err)
|
try(getWidgetValueBool(options, &cfg.PointSaving, "2.7"), &err)
|
||||||
try(getWidgetValueBool(options, &cfg.AutoCutLevel, 2, 25), &err)
|
try(getWidgetValueBool(options, &cfg.AutoCutLevel, "2.25"), &err)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return o.config.Save()
|
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) buildInterface(name string) (*ui.Interface, error) {
|
func (o *Ordoor) buildInterface(name string) (*ui.Interface, error) {
|
||||||
@@ -146,8 +160,8 @@ func (o *Ordoor) buildInterface(name string) (*ui.Interface, error) {
|
|||||||
return iface, nil
|
return iface, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func findWidget(iface *ui.Interface, spec ...int) (*ui.Widget, error) {
|
func findWidget(iface *ui.Interface, spec string) (*ui.Widget, error) {
|
||||||
widget, err := iface.Widget(spec...)
|
widget, err := iface.Widget(spec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Couldn't find widget %v:%+v", iface.Name, spec)
|
return nil, fmt.Errorf("Couldn't find widget %v:%+v", iface.Name, spec)
|
||||||
}
|
}
|
||||||
@@ -155,8 +169,8 @@ func findWidget(iface *ui.Interface, spec ...int) (*ui.Widget, error) {
|
|||||||
return widget, nil
|
return widget, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getWidgetValue(iface *ui.Interface, spec ...int) (string, error) {
|
func getWidgetValue(iface *ui.Interface, spec string) (string, error) {
|
||||||
widget, err := findWidget(iface, spec...)
|
widget, err := findWidget(iface, spec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -164,8 +178,8 @@ func getWidgetValue(iface *ui.Interface, spec ...int) (string, error) {
|
|||||||
return widget.Value, nil
|
return widget.Value, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setWidgetValue(iface *ui.Interface, value string, spec ...int) error {
|
func setWidgetValue(iface *ui.Interface, value string, spec string) error {
|
||||||
widget, err := findWidget(iface, spec...)
|
widget, err := findWidget(iface, spec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -175,8 +189,8 @@ func setWidgetValue(iface *ui.Interface, value string, spec ...int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getWidgetValueBool(iface *ui.Interface, into *bool, spec ...int) error {
|
func getWidgetValueBool(iface *ui.Interface, into *bool, spec string) error {
|
||||||
vStr, err := getWidgetValue(iface, spec...)
|
vStr, err := getWidgetValue(iface, spec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -185,17 +199,17 @@ func getWidgetValueBool(iface *ui.Interface, into *bool, spec ...int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setWidgetValueBool(iface *ui.Interface, value bool, spec ...int) error {
|
func setWidgetValueBool(iface *ui.Interface, value bool, spec string) error {
|
||||||
vStr := "0"
|
vStr := "0"
|
||||||
if value {
|
if value {
|
||||||
vStr = "1"
|
vStr = "1"
|
||||||
}
|
}
|
||||||
|
|
||||||
return setWidgetValue(iface, vStr, spec...)
|
return setWidgetValue(iface, vStr, spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
func wireupClick(iface *ui.Interface, f func(), spec ...int) error {
|
func wireupClick(iface *ui.Interface, f func(), spec string) error {
|
||||||
widget, err := findWidget(iface, spec...)
|
widget, err := findWidget(iface, spec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -209,8 +223,8 @@ func wireupClick(iface *ui.Interface, f func(), spec ...int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func disableWidget(iface *ui.Interface, spec ...int) error {
|
func disableWidget(iface *ui.Interface, spec string) error {
|
||||||
widget, err := findWidget(iface, spec...)
|
widget, err := findWidget(iface, spec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@@ -42,7 +42,7 @@ type Ordoor struct {
|
|||||||
iface *ui.Interface
|
iface *ui.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func Run(configFile string) error {
|
func Run(configFile string, overrideX, overrideY int) error {
|
||||||
cfg, err := config.Load(configFile)
|
cfg, err := config.Load(configFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Couldn't load config file: %v", err)
|
return fmt.Errorf("Couldn't load config file: %v", err)
|
||||||
@@ -64,7 +64,15 @@ func Run(configFile string) error {
|
|||||||
nextState: StateInterface,
|
nextState: StateInterface,
|
||||||
}
|
}
|
||||||
|
|
||||||
win, err := ui.NewWindow(ordoor, "Ordoor", cfg.Options.XRes, cfg.Options.YRes)
|
x, y := cfg.Options.XRes, cfg.Options.YRes
|
||||||
|
if overrideX > 0 {
|
||||||
|
x = overrideX
|
||||||
|
}
|
||||||
|
if overrideY > 0 {
|
||||||
|
y = overrideY
|
||||||
|
}
|
||||||
|
|
||||||
|
win, err := ui.NewWindow(ordoor, "Ordoor", x, y)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to create window: %v", err)
|
return fmt.Errorf("Failed to create window: %v", err)
|
||||||
}
|
}
|
||||||
@@ -112,7 +120,10 @@ func (o *Ordoor) PlayMusic(name string) error {
|
|||||||
return fmt.Errorf("Failed to generate music player for %v: %v", name, err)
|
return fmt.Errorf("Failed to generate music player for %v: %v", name, err)
|
||||||
}
|
}
|
||||||
o.music = player
|
o.music = player
|
||||||
|
|
||||||
|
if o.config.Options.PlayMusic {
|
||||||
player.Play()
|
player.Play()
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
15
internal/ui/animation.go
Normal file
15
internal/ui/animation.go
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package ui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hajimehoshi/ebiten"
|
||||||
|
)
|
||||||
|
|
||||||
|
type animation []*ebiten.Image
|
||||||
|
|
||||||
|
func (a animation) image(step int) *ebiten.Image {
|
||||||
|
if len(a) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return a[step%len(a)]
|
||||||
|
}
|
@@ -4,7 +4,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
"log"
|
"log"
|
||||||
"reflect" // For DeepEqual
|
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten"
|
"github.com/hajimehoshi/ebiten"
|
||||||
"github.com/hajimehoshi/ebiten/ebitenutil"
|
"github.com/hajimehoshi/ebiten/ebitenutil"
|
||||||
@@ -23,7 +22,7 @@ import (
|
|||||||
type Interface struct {
|
type Interface struct {
|
||||||
Name string
|
Name string
|
||||||
menu *assetstore.Menu
|
menu *assetstore.Menu
|
||||||
static []*staticElement
|
static []*noninteractive
|
||||||
ticks int
|
ticks int
|
||||||
widgets []*Widget
|
widgets []*Widget
|
||||||
}
|
}
|
||||||
@@ -44,14 +43,14 @@ func NewInterface(menu *assetstore.Menu) (*Interface, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find a widget by its hierarchical ID path
|
// Find a widget by its hierarchical ID path
|
||||||
func (i *Interface) Widget(path ...int) (*Widget, error) {
|
func (i *Interface) Widget(path string) (*Widget, error) {
|
||||||
for _, widget := range i.widgets {
|
for _, widget := range i.widgets {
|
||||||
if reflect.DeepEqual(path, widget.path) {
|
if path == widget.path {
|
||||||
return widget, nil
|
return widget, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("Couldn't find widget %#+v", path)
|
return nil, fmt.Errorf("Couldn't find widget %v", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Interface) Update(screenX, screenY int) error {
|
func (i *Interface) Update(screenX, screenY int) error {
|
||||||
@@ -82,9 +81,9 @@ func (i *Interface) Draw(screen *ebiten.Image) error {
|
|||||||
do := &ebiten.DrawImageOptions{GeoM: geo}
|
do := &ebiten.DrawImageOptions{GeoM: geo}
|
||||||
|
|
||||||
for _, s := range i.static {
|
for _, s := range i.static {
|
||||||
if s.image != nil {
|
if image := s.image(i.ticks); image != nil {
|
||||||
do.GeoM.Translate(geo.Apply(float64(s.bounds.Min.X), float64(s.bounds.Min.X)))
|
do.GeoM.Translate(geo.Apply(float64(s.bounds.Min.X), float64(s.bounds.Min.Y)))
|
||||||
if err := screen.DrawImage(s.image, do); err != nil {
|
if err := screen.DrawImage(image, do); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
do.GeoM = geo
|
do.GeoM = geo
|
||||||
|
20
internal/ui/noninteractive.go
Normal file
20
internal/ui/noninteractive.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package ui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hajimehoshi/ebiten"
|
||||||
|
"image"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *noninteractive) image(step int) *ebiten.Image {
|
||||||
|
return n.frames.image(step)
|
||||||
|
}
|
@@ -17,7 +17,7 @@ var setupHandlers = map[menus.MenuType]func(i *Interface, r *menus.Record) error
|
|||||||
menus.TypeOverlay: nil, // FIXME: What's it for?
|
menus.TypeOverlay: nil, // FIXME: What's it for?
|
||||||
menus.TypeHypertext: handleHypertext,
|
menus.TypeHypertext: handleHypertext,
|
||||||
menus.TypeCheckbox: handleCheckbox,
|
menus.TypeCheckbox: handleCheckbox,
|
||||||
menus.TypeAnimationSample: nil, // FIXME: handle this
|
menus.TypeAnimationSample: handleAnimation,
|
||||||
menus.TypeMainButton: handleMainButton,
|
menus.TypeMainButton: handleMainButton,
|
||||||
menus.TypeSlider: nil, // FIXME: handle this
|
menus.TypeSlider: nil, // FIXME: handle this
|
||||||
}
|
}
|
||||||
@@ -35,9 +35,9 @@ func handleStatic(i *Interface, record *menus.Record) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
static := &staticElement{
|
static := &noninteractive{
|
||||||
bounds: sprite.Rect,
|
bounds: sprite.Rect,
|
||||||
image: sprite.Image,
|
frames: animation{sprite.Image},
|
||||||
tooltip: record.Desc,
|
tooltip: record.Desc,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,9 +54,9 @@ func handleHypertext(i *Interface, record *menus.Record) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
static := &staticElement{
|
static := &noninteractive{
|
||||||
bounds: sprite.Rect,
|
bounds: sprite.Rect,
|
||||||
image: nil,
|
frames: nil,
|
||||||
tooltip: record.Desc,
|
tooltip: record.Desc,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,6 +106,29 @@ func handleCheckbox(i *Interface, record *menus.Record) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// An animation is a non-interactive element that displays something in a loop
|
||||||
|
func handleAnimation(i *Interface, record *menus.Record) error {
|
||||||
|
sprite, err := i.menu.Sprite(record.SpriteId[0])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
frames, err := i.menu.Images(record.SpriteId[0], record.DrawType)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ani := &noninteractive{
|
||||||
|
bounds: sprite.Rect,
|
||||||
|
frames: animation(frames),
|
||||||
|
tooltip: record.Desc,
|
||||||
|
}
|
||||||
|
|
||||||
|
i.static = append(i.static, ani)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func handleButton(i *Interface, record *menus.Record) error {
|
func handleButton(i *Interface, record *menus.Record) error {
|
||||||
spriteId := record.SpriteId[0]
|
spriteId := record.SpriteId[0]
|
||||||
widget, err := i.widgetFromRecord(record, spriteId)
|
widget, err := i.widgetFromRecord(record, spriteId)
|
||||||
@@ -179,7 +202,7 @@ func handleMainButton(i *Interface, record *menus.Record) error {
|
|||||||
|
|
||||||
widget.mouseButtonDownImage = pressed.Image
|
widget.mouseButtonDownImage = pressed.Image
|
||||||
widget.disabledImage = disabled.Image
|
widget.disabledImage = disabled.Image
|
||||||
widget.hoverAnimation = hovers
|
widget.hoverAnimation = animation(hovers)
|
||||||
|
|
||||||
i.widgets = append(i.widgets, widget)
|
i.widgets = append(i.widgets, widget)
|
||||||
|
|
||||||
@@ -194,15 +217,10 @@ func (i *Interface) widgetFromRecord(record *menus.Record, spriteId int) (*Widge
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var path []int
|
|
||||||
for r := record; r != nil; r = r.Parent {
|
|
||||||
path = append([]int{r.Id}, path...)
|
|
||||||
}
|
|
||||||
|
|
||||||
widget := &Widget{
|
widget := &Widget{
|
||||||
Bounds: sprite.Rect,
|
Bounds: sprite.Rect,
|
||||||
Tooltip: record.Desc,
|
Tooltip: record.Desc,
|
||||||
path: path,
|
path: record.Path(),
|
||||||
record: record,
|
record: record,
|
||||||
sprite: sprite,
|
sprite: sprite,
|
||||||
}
|
}
|
||||||
|
@@ -1,15 +0,0 @@
|
|||||||
package ui
|
|
||||||
|
|
||||||
import (
|
|
||||||
"image"
|
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A static element is not a widget; it merely displays some pixels and may
|
|
||||||
// optionally have a tooltip for display within bounds
|
|
||||||
type staticElement struct {
|
|
||||||
bounds image.Rectangle
|
|
||||||
image *ebiten.Image
|
|
||||||
tooltip string
|
|
||||||
}
|
|
@@ -30,7 +30,7 @@ type Widget struct {
|
|||||||
disabledImage *ebiten.Image
|
disabledImage *ebiten.Image
|
||||||
|
|
||||||
// These are expected to have the same dimensions as the Bounds
|
// These are expected to have the same dimensions as the Bounds
|
||||||
hoverAnimation []*ebiten.Image
|
hoverAnimation animation
|
||||||
hoverState bool
|
hoverState bool
|
||||||
|
|
||||||
// FIXME: We assume right mouse button isn't needed here
|
// FIXME: We assume right mouse button isn't needed here
|
||||||
@@ -38,7 +38,7 @@ type Widget struct {
|
|||||||
mouseButtonDownImage *ebiten.Image
|
mouseButtonDownImage *ebiten.Image
|
||||||
mouseButtonState bool
|
mouseButtonState bool
|
||||||
|
|
||||||
path []int
|
path string
|
||||||
record *menus.Record
|
record *menus.Record
|
||||||
sprite *assetstore.Sprite
|
sprite *assetstore.Sprite
|
||||||
|
|
||||||
@@ -97,8 +97,8 @@ func (w *Widget) Image(aniStep int) (*ebiten.Image, error) {
|
|||||||
return w.mouseButtonDownImage, nil
|
return w.mouseButtonDownImage, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if w.hoverState && len(w.hoverAnimation) > 0 {
|
if w.hoverState && w.hoverAnimation != nil {
|
||||||
return w.hoverAnimation[(aniStep)%len(w.hoverAnimation)], nil
|
return w.hoverAnimation.image(aniStep), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if w.valueToImage != nil {
|
if w.valueToImage != nil {
|
||||||
|
Reference in New Issue
Block a user