Allow menu records to be processed hierarchically by the UI driver
Nothing is actually processed in this way yet, but there is a new assertion forbidding certain types of records from having children. Because of this new assertion, our menutype tweaks must be moved up a layer into internal/menus. They fit better there anyway.
This commit is contained in:
@@ -23,7 +23,7 @@ const (
|
||||
TypeDoorHotspot MenuType = 30 // Like a button I guess? "FONTTYPE is animation speed"
|
||||
TypeDoorHotspot2 MenuType = 31 // Seems like a duplicate of the above? What's different?
|
||||
TypeLineKbd MenuType = 40
|
||||
TypeThumb MenuType = 45
|
||||
TypeThumb MenuType = 45 // A "thumb" appears to be a vertical slider
|
||||
TypeLineBriefing MenuType = 41
|
||||
TypeInvokeButton MenuType = 50
|
||||
TypeDoorHotspot3 MenuType = 60 // Maybe? Appears in Arrange.mnu
|
||||
@@ -67,6 +67,20 @@ var TextOverrides = map[string]map[string]string{
|
||||
},
|
||||
}
|
||||
|
||||
// FIXME: The menu is specified as type 2 (button) in these cases, which is
|
||||
// weird. Make it a menu for now.
|
||||
var TypeOverrides = map[string]map[string]MenuType{
|
||||
"levelply": {
|
||||
"2": TypeMenu,
|
||||
},
|
||||
"savegame": {
|
||||
"2": TypeMenu,
|
||||
},
|
||||
"loadgame": {
|
||||
"2": TypeMenu,
|
||||
},
|
||||
}
|
||||
|
||||
type Record struct {
|
||||
Menu *Menu
|
||||
Parent *Record
|
||||
@@ -262,6 +276,13 @@ func setProperty(r *Record, k, v string) {
|
||||
r.Id = vInt
|
||||
case "MENUTYPE", "SUBMENUTYPE":
|
||||
r.Type = MenuType(vInt)
|
||||
|
||||
// FIXME: Type override. Note that MENUID is specified first, so this works
|
||||
if overrides, ok := TypeOverrides[r.Menu.Name]; ok {
|
||||
if newType, ok := overrides[r.Path()]; ok {
|
||||
r.Type = newType
|
||||
}
|
||||
}
|
||||
case "ACTIVE":
|
||||
r.Active = (vInt != 0)
|
||||
case "SPRITEID":
|
||||
|
@@ -8,12 +8,12 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerBuilder(menus.TypeSimpleButton, registerSimpleButton)
|
||||
registerBuilder(menus.TypeInvokeButton, registerInvokeButton)
|
||||
registerBuilder(menus.TypeMainButton, registerMainButton)
|
||||
registerBuilder(menus.TypeDoorHotspot, registerDoorHotspot)
|
||||
registerBuilder(menus.TypeDoorHotspot2, registerDoorHotspot)
|
||||
registerBuilder(menus.TypeDoorHotspot3, registerDoorHotspot)
|
||||
registerBuilder(menus.TypeSimpleButton, noChildren(registerSimpleButton))
|
||||
registerBuilder(menus.TypeInvokeButton, noChildren(registerInvokeButton))
|
||||
registerBuilder(menus.TypeMainButton, noChildren(registerMainButton))
|
||||
registerBuilder(menus.TypeDoorHotspot, noChildren(registerDoorHotspot))
|
||||
registerBuilder(menus.TypeDoorHotspot2, noChildren(registerDoorHotspot))
|
||||
registerBuilder(menus.TypeDoorHotspot3, noChildren(registerDoorHotspot))
|
||||
}
|
||||
|
||||
// A button without hover animation
|
||||
@@ -39,11 +39,6 @@ type mainButton struct {
|
||||
}
|
||||
|
||||
func registerSimpleButton(d *Driver, r *menus.Record) error {
|
||||
// FIXME: LevelPly.mnu specifies a menu oddly. This tweak gets us past it
|
||||
if d.Name == "levelply" && r.Id == 2 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return registerButton(d, r, r.SpriteId[0])
|
||||
}
|
||||
|
||||
|
@@ -56,18 +56,26 @@ var (
|
||||
)
|
||||
|
||||
// Used to add widgets to a driver
|
||||
type builderFunc func(d *Driver, r *menus.Record) error
|
||||
type builderFunc func(d *Driver, r *menus.Record) (children []*menus.Record, err error)
|
||||
|
||||
func registerDebug(reason string, onward builderFunc) builderFunc {
|
||||
return func(d *Driver, r *menus.Record) error {
|
||||
return func(d *Driver, r *menus.Record) ([]*menus.Record, error) {
|
||||
log.Printf("%v: %#+v", reason, r)
|
||||
if onward == nil {
|
||||
return registerStatic(d, r)
|
||||
} else {
|
||||
return onward(d, r)
|
||||
return r.Children, nil
|
||||
}
|
||||
|
||||
return nil
|
||||
return onward(d, r)
|
||||
}
|
||||
}
|
||||
|
||||
func noChildren(f func(d *Driver, r *menus.Record) error) builderFunc {
|
||||
return func(d *Driver, r *menus.Record) ([]*menus.Record, error) {
|
||||
if len(r.Children) > 0 {
|
||||
return nil, fmt.Errorf("Children in record %v:%v (%#+v)", r.Menu.Name, r.Path(), r)
|
||||
}
|
||||
|
||||
return nil, f(d, r)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +140,7 @@ func (d *Driver) Value(id string, into *string) error {
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("Couldn't find valueable widget %q", id)
|
||||
return fmt.Errorf("Couldn't find valueable widget %v:%v", d.menu.Name, id)
|
||||
}
|
||||
|
||||
func (d *Driver) SetValue(id, value string) error {
|
||||
@@ -143,7 +151,7 @@ func (d *Driver) SetValue(id, value string) error {
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("Couldn't find valueable widget %q", id)
|
||||
return fmt.Errorf("Couldn't find valueable widget %v:%v", d.menu.Name, id)
|
||||
}
|
||||
|
||||
func (d *Driver) ValueBool(id string, into *bool) error {
|
||||
@@ -173,7 +181,7 @@ func (d *Driver) SetFreeze(id string, value bool) error {
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("Couldn't find clickable widget %q", id)
|
||||
return fmt.Errorf("Couldn't find clickable widget %v:%v", d.menu.Name, id)
|
||||
}
|
||||
|
||||
func (d *Driver) OnClick(id string, f func()) error {
|
||||
@@ -184,7 +192,7 @@ func (d *Driver) OnClick(id string, f func()) error {
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("Couldn't find clickable widget %q", id)
|
||||
return fmt.Errorf("Couldn't find clickable widget %v:%v", d.menu.Name, id)
|
||||
}
|
||||
|
||||
// FIXME: HURK. Surely I'm missing something? steps is value:offset
|
||||
@@ -197,7 +205,7 @@ func (d *Driver) ConfigureSlider(id string, steps map[int]int) error {
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("Couldn't find slider %q", id)
|
||||
return fmt.Errorf("Couldn't find slider %v:%v", d.menu.Name, id)
|
||||
}
|
||||
|
||||
func (d *Driver) ValueInt(id string, into *int) error {
|
||||
@@ -306,6 +314,7 @@ func (d *Driver) Draw(screen *ebiten.Image) error {
|
||||
|
||||
func (d *Driver) addRecord(record *menus.Record) error {
|
||||
//log.Printf("Adding record: %#+v", record)
|
||||
children := record.Children
|
||||
|
||||
handler, ok := widgetBuilders[record.Type]
|
||||
if !ok {
|
||||
@@ -313,13 +322,15 @@ func (d *Driver) addRecord(record *menus.Record) error {
|
||||
}
|
||||
|
||||
if handler != nil {
|
||||
if err := handler(d, record); err != nil {
|
||||
var err error
|
||||
children, err = handler(d, record)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Recursively add all children of this record
|
||||
for _, record := range record.Children {
|
||||
// Recursively add all remaining children of this record
|
||||
for _, record := range children {
|
||||
if err := d.addRecord(record); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@@ -10,11 +10,11 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerBuilder(menus.TypeStatic, registerStatic)
|
||||
registerBuilder(menus.TypeHypertext, registerHypertext)
|
||||
registerBuilder(menus.TypeOverlay, registerOverlay)
|
||||
registerBuilder(menus.TypeAnimationSample, registerAnimation)
|
||||
registerBuilder(menus.TypeAnimationHover, registerAnimationHover)
|
||||
registerBuilder(menus.TypeStatic, noChildren(registerStatic))
|
||||
registerBuilder(menus.TypeHypertext, noChildren(registerHypertext))
|
||||
registerBuilder(menus.TypeOverlay, noChildren(registerOverlay))
|
||||
registerBuilder(menus.TypeAnimationSample, noChildren(registerAnimation))
|
||||
registerBuilder(menus.TypeAnimationHover, noChildren(registerAnimationHover))
|
||||
}
|
||||
|
||||
// A non-interactive element is not a widget; it merely displays some pixels and
|
||||
|
@@ -10,9 +10,9 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerBuilder(menus.TypeCheckbox, registerCheckbox)
|
||||
registerBuilder(menus.TypeSlider, registerSlider)
|
||||
registerBuilder(menus.TypeInventorySelect, registerInventorySelect)
|
||||
registerBuilder(menus.TypeCheckbox, noChildren(registerCheckbox))
|
||||
registerBuilder(menus.TypeSlider, noChildren(registerSlider))
|
||||
registerBuilder(menus.TypeInventorySelect, noChildren(registerInventorySelect))
|
||||
}
|
||||
|
||||
// A checkbox can be a fancy button
|
||||
|
Reference in New Issue
Block a user