203 lines
5.3 KiB
Go
203 lines
5.3 KiB
Go
package ui
|
|
|
|
import (
|
|
"code.ur.gs/lupine/ordoor/internal/menus"
|
|
"fmt"
|
|
"log"
|
|
)
|
|
|
|
func (d *Driver) registerGroup(group *menus.Group) error {
|
|
// log.Printf("Adding group %v: %#+v", group.Locator, group)
|
|
|
|
var dialogue bool
|
|
|
|
switch group.Type {
|
|
case menus.TypeStatic, menus.TypeMainBackground, menus.TypeMenu, menus.TypeDragMenu, menus.TypeRadioMenu:
|
|
case menus.TypeDialogue:
|
|
dialogue = true
|
|
default:
|
|
return fmt.Errorf("Unknown group type: %v", group.Type)
|
|
}
|
|
|
|
var groupWidget *Widget
|
|
// Groups have a background sprite (FIXME: always?)
|
|
if group.BaseSpriteID() >= 0 {
|
|
var err error
|
|
_, groupWidget, err = d.buildStatic(group.Props())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
groupWidget = &Widget{
|
|
Locator: group.Locator,
|
|
Active: group.Active,
|
|
}
|
|
}
|
|
|
|
if dialogue {
|
|
d.dialogues = append(d.dialogues, groupWidget)
|
|
} else {
|
|
d.widgets = append(d.widgets, groupWidget)
|
|
}
|
|
|
|
// TRadioGroup is best handled like this
|
|
records, widget, err := d.maybeBuildInventorySelect(group, group.Records)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if widget != nil {
|
|
groupWidget.Children = append(groupWidget.Children, widget)
|
|
}
|
|
|
|
records, widget, err = d.maybeBuildListBox(group, records)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if widget != nil {
|
|
groupWidget.Children = append(groupWidget.Children, widget)
|
|
}
|
|
|
|
for _, record := range records {
|
|
child, err := d.buildRecord(record)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if child != nil {
|
|
groupWidget.Children = append(groupWidget.Children, child)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (d *Driver) buildRecord(r *menus.Record) (*Widget, error) {
|
|
var widget *Widget
|
|
var err error
|
|
|
|
switch r.Type {
|
|
case menus.SubTypeSimpleButton, menus.SubTypeInvokeButton:
|
|
_, widget, err = d.buildButton(r.Props())
|
|
case menus.SubTypeDoorHotspot1, menus.SubTypeDoorHotspot2:
|
|
_, widget, err = d.buildDoorHotspot(r.Props())
|
|
case menus.SubTypeClickText:
|
|
_, widget, err = d.buildClickText(r.Props())
|
|
case menus.SubTypeOverlay:
|
|
_, widget, err = d.buildOverlay(r.Props())
|
|
case menus.SubTypeHypertext:
|
|
_, widget, err = d.buildHypertext(r.Props())
|
|
case menus.SubTypeCheckbox:
|
|
_, widget, err = d.buildCheckbox(r.Props())
|
|
case menus.SubTypeEditBox:
|
|
log.Printf("Unimplemented: SubTypeEditBox: %v", r.Locator) // TODO
|
|
case menus.SubTypeRadioButton:
|
|
log.Printf("Unimplemented: SubTypeRadioButton: %v", r.Locator) // TODO
|
|
case menus.SubTypeDropdownButton:
|
|
log.Printf("Unimplemented: SubTypeDropdownButton: %v", r.Locator) // TODO
|
|
case menus.SubTypeComboBoxItem:
|
|
log.Printf("Unimplemented: SubTypeComboBoxItem: %v", r.Locator) // TODO
|
|
case menus.SubTypeAnimationSample:
|
|
_, widget, err = d.buildAnimationSample(r.Props())
|
|
case menus.SubTypeAnimationHover:
|
|
_, widget, err = d.buildAnimationHover(r.Props())
|
|
case menus.SubTypeMainButton:
|
|
_, widget, err = d.buildMainButton(r.Props())
|
|
case menus.SubTypeSlider:
|
|
_, widget, err = d.buildSlider(r.Props()) // TODO: take sliders at an earlier point?
|
|
case menus.SubTypeStatusBar:
|
|
log.Printf("Unimplemented: SubTypeStatusBar: %v", r.Locator) // TODO
|
|
default:
|
|
return nil, fmt.Errorf("Unknown record type for %v: %v", r.Locator, r.Type)
|
|
}
|
|
|
|
return widget, err
|
|
}
|
|
|
|
func (d *Driver) maybeBuildInventorySelect(group *menus.Group, records []*menus.Record) ([]*menus.Record, *Widget, error) {
|
|
var untouched []*menus.Record
|
|
var touched []*menus.Record
|
|
|
|
for _, record := range records {
|
|
if record.Type == menus.SubTypeInventorySelect {
|
|
touched = append(touched, record)
|
|
} else {
|
|
untouched = append(untouched, record)
|
|
}
|
|
}
|
|
|
|
if len(touched) == 0 {
|
|
return untouched, nil, nil
|
|
}
|
|
|
|
elements := make([]*inventorySelect, len(touched))
|
|
widget := &Widget{
|
|
Locator: group.Locator,
|
|
Active: group.Active,
|
|
}
|
|
|
|
for i, record := range touched {
|
|
element, childWidget, err := d.buildInventorySelect(record.Props())
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
elements[i] = element
|
|
widget.Children = append(widget.Children, childWidget)
|
|
}
|
|
|
|
elements[0].setValue("1")
|
|
|
|
for _, element := range elements {
|
|
element.others = elements
|
|
}
|
|
|
|
return untouched, widget, nil
|
|
}
|
|
|
|
func (d *Driver) maybeBuildListBox(group *menus.Group, records []*menus.Record) ([]*menus.Record, *Widget, error) {
|
|
// Unless up, down, thumb, and items, are all present, it's not a listbox
|
|
var up *menus.Record
|
|
var down *menus.Record
|
|
var thumb *menus.Record
|
|
var items []*menus.Record
|
|
|
|
var untouched []*menus.Record
|
|
|
|
for _, rec := range records {
|
|
switch rec.Type {
|
|
case menus.SubTypeListBoxUp:
|
|
if up != nil {
|
|
return nil, nil, fmt.Errorf("Duplicate up buttons in menu %v", group.Locator)
|
|
}
|
|
up = rec
|
|
case menus.SubTypeListBoxDown:
|
|
if down != nil {
|
|
return nil, nil, fmt.Errorf("Duplicate down buttons in menu %v", group.Locator)
|
|
}
|
|
down = rec
|
|
case menus.SubTypeLineKbd, menus.SubTypeLineBriefing:
|
|
items = append(items, rec)
|
|
case menus.SubTypeThumb:
|
|
if thumb != nil {
|
|
return nil, nil, fmt.Errorf("Duplicate thumbs in menu %v", group.Locator)
|
|
}
|
|
thumb = rec
|
|
default:
|
|
// e.g. maingame:18.12 includes a button that is not part of the box
|
|
untouched = append(untouched, rec)
|
|
}
|
|
}
|
|
|
|
// Since not all the elements are present, this isn't a listbox
|
|
if len(items) == 0 || thumb == nil || up == nil || down == nil {
|
|
return untouched, nil, nil
|
|
}
|
|
|
|
_, widget, err := d.buildListBox(group, up, down, thumb, items...)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
return untouched, widget, nil
|
|
}
|