Refactor inventorySelect to build it hierarchically

This commit is contained in:
2020-03-31 23:45:11 +01:00
parent 2ae3611d7f
commit c1925697c9
3 changed files with 52 additions and 33 deletions

View File

@@ -15,10 +15,6 @@ import (
)
func init() {
// These menu types don't need driving, so we can ignore them
registerBuilder(menus.TypeMenu, nil) // Menus are just containers
registerBuilder(menus.TypeDragMenu, nil) // Menus are just containers
// FIXME: these need implementing
// Needed for Keyboard.mnu (main -> options -> keyboard)
@@ -79,6 +75,10 @@ func noChildren(f func(d *Driver, r *menus.Record) error) builderFunc {
}
}
func ownedByMenu(d *Driver, r *menus.Record) ([]*menus.Record, error) {
return nil, fmt.Errorf("This record should be handled by a menu: %v:%v (%#+v)", r.Menu.Name, r.Path(), r)
}
func registerBuilder(t menus.MenuType, f builderFunc) {
if _, ok := widgetBuilders[t]; ok {
panic(fmt.Sprintf("A builder for menu type %v already exists", t))

42
internal/ui/menus.go Normal file
View File

@@ -0,0 +1,42 @@
package ui
import (
"code.ur.gs/lupine/ordoor/internal/menus"
)
func init() {
// These menu types don't need driving, so we can ignore them
registerBuilder(menus.TypeMenu, registerMenu)
registerBuilder(menus.TypeDragMenu, nil) // Menus are just containers
}
func registerMenu(d *Driver, r *menus.Record) ([]*menus.Record, error) {
// Group all inventory selects that share a menu together
var childrenLeft []*menus.Record
var inventorySelects []*inventorySelect
for _, child := range r.Children {
switch child.Type {
case menus.TypeInventorySelect:
is, err := registerInventorySelect(d, child)
if err != nil {
return nil, err
}
inventorySelects = append(inventorySelects, is)
default:
childrenLeft = append(childrenLeft, child)
}
}
if len(inventorySelects) > 0 {
inventorySelects[0].setValue("1") // Always start with one selected
for _, is := range inventorySelects {
is.others = inventorySelects
}
}
// Return all the unhandled children to be processed further
return childrenLeft, nil
}

View File

@@ -12,7 +12,7 @@ import (
func init() {
registerBuilder(menus.TypeCheckbox, noChildren(registerCheckbox))
registerBuilder(menus.TypeSlider, noChildren(registerSlider))
registerBuilder(menus.TypeInventorySelect, noChildren(registerInventorySelect))
registerBuilder(menus.TypeInventorySelect, ownedByMenu)
}
// A checkbox can be a fancy button
@@ -96,10 +96,12 @@ func registerSlider(d *Driver, r *menus.Record) error {
return nil
}
func registerInventorySelect(d *Driver, r *menus.Record) error {
// Called from the menu, which fills "others"
// TODO: make this a single call? A single component with multiple choices?
func registerInventorySelect(d *Driver, r *menus.Record) (*inventorySelect, error) {
sprites, err := d.menu.Sprites(r.Share, 3) // unchecked, checked, disabled
if err != nil {
return err
return nil, err
}
element := &inventorySelect{
@@ -122,32 +124,7 @@ func registerInventorySelect(d *Driver, r *menus.Record) error {
d.paintables = append(d.paintables, element)
d.valueables = append(d.valueables, element)
if r.Parent == nil {
return nil
}
element.parentPath = r.Parent.Path()
// Now update all inventory selects belonging to the same menu so they share
// a list of all inventory selects. This will be replaced several times as
// the menu is built.
var inventorySelects []*inventorySelect
for _, valueable := range d.valueables {
if is, ok := valueable.(*inventorySelect); ok && is.parentPath == element.parentPath {
inventorySelects = append(inventorySelects, is)
}
}
for _, is := range inventorySelects {
is.others = inventorySelects
}
// Select the first in the list
if len(inventorySelects) == 1 {
element.setValue("1")
}
return nil
return element, nil
}
func (c *checkbox) registerMouseClick() {