Files
ordoor/internal/ui/group.go

203 lines
5.3 KiB
Go
Raw Permalink Normal View History

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 {
2020-04-19 18:21:08 +01:00
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,
2020-04-19 18:21:08 +01:00
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
}