Allow dialogues to be hidden or shown
To do this, MENU and SUBMENU are split into two types (at last), and a Widget type is introduced. This should allow lots of code to be removed at some point.
This commit is contained in:
@@ -8,15 +8,6 @@ import (
|
||||
"code.ur.gs/lupine/ordoor/internal/menus"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerBuilder(menus.TypeLineKbd, ownedByMenu)
|
||||
registerBuilder(menus.TypeLineBriefing, ownedByMenu)
|
||||
|
||||
registerBuilder(menus.TypeThumb, ownedByMenu)
|
||||
registerBuilder(menus.TypeListBoxUp, ownedByMenu)
|
||||
registerBuilder(menus.TypeListBoxDown, ownedByMenu)
|
||||
}
|
||||
|
||||
// listBox is a TListBox in VCL terms. It has a number of lines of text, one of
|
||||
// which may be selected, and a slider with up and down buttons to scroll if the
|
||||
// options in the box exceed its viewing capacity.
|
||||
@@ -30,7 +21,6 @@ type listBox struct {
|
||||
thumbBase *assetstore.Sprite // Bounds are given by this
|
||||
thumbImg *assetstore.Sprite // This is displayed at offset * (height / steps)
|
||||
|
||||
base *noninteractive // The menu itself has a sprite to display
|
||||
lines []*noninteractive // We display to these
|
||||
|
||||
// The list box acts as a window onto these
|
||||
@@ -40,87 +30,31 @@ type listBox struct {
|
||||
offset int
|
||||
}
|
||||
|
||||
func registerListBox(d *Driver, menu *menus.Record) ([]*menus.Record, error) {
|
||||
var upBtn *menus.Record
|
||||
var downBtn *menus.Record
|
||||
var thumb *menus.Record
|
||||
var items []*menus.Record
|
||||
var otherChildren []*menus.Record
|
||||
|
||||
for _, rec := range menu.Children {
|
||||
switch rec.Type {
|
||||
case menus.TypeListBoxUp:
|
||||
if upBtn != nil {
|
||||
return nil, fmt.Errorf("Duplicate up buttons in menu %v", menu.Locator())
|
||||
}
|
||||
upBtn = rec
|
||||
case menus.TypeListBoxDown:
|
||||
if downBtn != nil {
|
||||
return nil, fmt.Errorf("Duplicate down buttons in menu %v", menu.Locator())
|
||||
}
|
||||
downBtn = rec
|
||||
case menus.TypeLineKbd, menus.TypeLineBriefing:
|
||||
items = append(items, rec)
|
||||
case menus.TypeThumb:
|
||||
if thumb != nil {
|
||||
return nil, fmt.Errorf("Duplicate thumbs in menu %v", menu.Locator())
|
||||
}
|
||||
thumb = rec
|
||||
default:
|
||||
// e.g. maingame:18.12 includes a button that is not part of the box
|
||||
otherChildren = append(otherChildren, rec)
|
||||
}
|
||||
}
|
||||
|
||||
if len(items) == 0 || thumb == nil || upBtn == nil || downBtn == nil {
|
||||
return nil, fmt.Errorf("Missing items in menu %v", menu.Locator())
|
||||
}
|
||||
|
||||
// Now build the wonderful thing
|
||||
baseElem, err := registerNoninteractive(d, menu)
|
||||
func (d *Driver) buildListBox(group *menus.Group, up, down, thumb *menus.Record, items ...*menus.Record) (*listBox, *Widget, error) {
|
||||
upElem, upWidget, err := d.buildButton(up.Props())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
upSprId := upBtn.SpriteId[0]
|
||||
if upSprId == -1 {
|
||||
upSprId = upBtn.Share
|
||||
}
|
||||
|
||||
elemUp, err := registerButton(d, upBtn, upSprId)
|
||||
downElem, downWidget, err := d.buildButton(down.Props())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
dnSprId := downBtn.SpriteId[0]
|
||||
if dnSprId == -1 {
|
||||
dnSprId = downBtn.Share
|
||||
}
|
||||
elemDown, err := registerButton(d, downBtn, dnSprId)
|
||||
thumbBaseSpr, err := d.menu.Sprite(thumb.ObjectIdx, thumb.Share)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
thumbBaseSpr, err := d.menu.Sprite(menu.ObjectIdx, thumb.Share)
|
||||
thumbImgSpr, err := d.menu.Sprite(thumb.ObjectIdx, thumb.BaseSpriteID())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
thumbSprId := thumb.SpriteId[0]
|
||||
if thumbSprId == -1 {
|
||||
thumbSprId = thumb.Share
|
||||
}
|
||||
|
||||
thumbImgSpr, err := d.menu.Sprite(menu.ObjectIdx, thumbSprId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
element := &listBox{
|
||||
base: baseElem,
|
||||
// TODO: upBtn needs to be frozen when offset == 0; downBtn when offset == max
|
||||
upBtn: elemUp,
|
||||
downBtn: elemDown,
|
||||
upBtn: upElem,
|
||||
downBtn: downElem,
|
||||
|
||||
// TODO: need to be able to drag the thumb
|
||||
thumbBase: thumbBaseSpr,
|
||||
@@ -128,8 +62,8 @@ func registerListBox(d *Driver, menu *menus.Record) ([]*menus.Record, error) {
|
||||
}
|
||||
|
||||
// Internal wiring-up
|
||||
elemUp.onClick(element.up)
|
||||
elemDown.onClick(element.down)
|
||||
upElem.onClick(element.up)
|
||||
downElem.onClick(element.down)
|
||||
|
||||
// FIXME: Test data for now
|
||||
for i := 0; i < 50; i++ {
|
||||
@@ -138,30 +72,34 @@ func registerListBox(d *Driver, menu *menus.Record) ([]*menus.Record, error) {
|
||||
|
||||
// Register everything. Since we're a composite of other controls, they are
|
||||
// mostly self-registered at the moment.
|
||||
d.paintables = append(d.paintables, element)
|
||||
widget := &Widget{
|
||||
Children: []*Widget{upWidget, downWidget},
|
||||
ownPaintables: []paintable{element},
|
||||
}
|
||||
|
||||
// FIXME: we should be able to freeze/unfreeze as a group.
|
||||
|
||||
// HURK: These need to be registered after the other elements so they are
|
||||
// drawn in the correct order to be visible
|
||||
for _, rec := range items {
|
||||
ni, err := registerNoninteractive(d, rec)
|
||||
ni, niWidget, err := d.buildStatic(rec.Props())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// TODO: pick the correct font
|
||||
ni.label = &label{
|
||||
align: AlignModeLeft,
|
||||
font: d.menu.Font(0),
|
||||
rect: ni.rect,
|
||||
}
|
||||
|
||||
element.lines = append(element.lines, ni)
|
||||
widget.Children = append(widget.Children, niWidget)
|
||||
}
|
||||
|
||||
element.refresh()
|
||||
|
||||
return otherChildren, nil
|
||||
return element, widget, nil
|
||||
}
|
||||
|
||||
func (l *listBox) SetStrings(to []string) {
|
||||
|
Reference in New Issue
Block a user