More work for MainGame.mnu
This commit is contained in:
@@ -241,9 +241,37 @@ func (f *Flow) playNextScenario(from driverName) func() {
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Flow) setActive(driver driverName, id string, value bool) func() {
|
||||
return func() {
|
||||
if f.exit != nil {
|
||||
return
|
||||
}
|
||||
|
||||
f.exit = maybeErr(driver, f.setActiveNow(driver, id, value))
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Flow) setActiveNow(driver driverName, id string, value bool) error {
|
||||
return f.drivers[driver].SetActive(locator(driver, id), value)
|
||||
}
|
||||
|
||||
func (f *Flow) toggleActive(driver driverName, id string) func() {
|
||||
return func() {
|
||||
if f.exit != nil {
|
||||
return
|
||||
}
|
||||
|
||||
f.exit = maybeErr(driver, f.drivers[driver].ToggleActive(locator(driver, id)))
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Flow) showDialogue(driver driverName, id string) func() {
|
||||
return func() {
|
||||
f.drivers[driver].ShowDialogue(locator(driver, id))
|
||||
if f.exit != nil {
|
||||
return
|
||||
}
|
||||
|
||||
f.exit = maybeErr(driver, f.drivers[driver].ShowDialogue(locator(driver, id)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -4,13 +4,34 @@ package flow
|
||||
// to duplicate everything for both?
|
||||
|
||||
func (f *Flow) linkMainGame() {
|
||||
// 3: Action menu
|
||||
// 3: Action menu. These are mostly predicated on selected character state
|
||||
// 3.1: Aimed shot
|
||||
// 3.2: Shooting
|
||||
// 3.3: Walk
|
||||
// 3.4: Run
|
||||
// 3.5: Crouch/Stand
|
||||
// 3.6: Hand to hand (commented out)
|
||||
// 3.7: Retrieve
|
||||
// 3.8: Door
|
||||
// 3.9: Switch
|
||||
// 3.10: Overwatch
|
||||
// 3.11: Rally/Formation
|
||||
// 3.12: Board/Disembark
|
||||
// FIXME: for now, this is "end scenario", for convenience
|
||||
f.onClick(mainGame, "3.13", func() { // End turn button.
|
||||
f.scenario = nil
|
||||
f.returnToLastDriverNow(mainGame)
|
||||
})
|
||||
// 3.14: Special action heal
|
||||
// 3.15: Special action techmarine
|
||||
// 3.16: Special action jump pack
|
||||
// 3.17: Special action spell
|
||||
|
||||
// 4: Interface options menu
|
||||
f.onClick(mainGame, "4.1", f.setReturningDriver(mainGame, options)) // Options button
|
||||
// 4.2: Map button
|
||||
f.onClick(mainGame, "4.2", f.toggleActive(mainGame, "14")) // Map button
|
||||
// 4.3: Mission objectives button
|
||||
// 4.4: Inventory
|
||||
f.onClick(mainGame, "4.4", f.showDialogue(mainGame, "12")) // Inventory
|
||||
// 4.5: Next man
|
||||
// 4.6: Next enemy
|
||||
// 4.7: Total enemy text
|
||||
@@ -22,31 +43,31 @@ func (f *Flow) linkMainGame() {
|
||||
// 9: Visible enemy menu
|
||||
// 10: Friendly squad menu
|
||||
// 11: Psyker spell dialogue
|
||||
|
||||
// FIXME: lots and lots and lots of wiring up to do.
|
||||
// For now, just link all the exit buttons to go back to the bridge
|
||||
f.onClick(mainGame, "11.6", func() {
|
||||
f.scenario = nil
|
||||
f.returnToLastDriverNow(mainGame)
|
||||
})
|
||||
|
||||
// 12: Inventory dialogue
|
||||
f.onClick(mainGame, "12.21", func() {
|
||||
f.scenario = nil
|
||||
f.returnToLastDriverNow(mainGame)
|
||||
})
|
||||
|
||||
// 13: Exchange menu
|
||||
|
||||
f.onClick(mainGame, "13.1", func() {
|
||||
f.scenario = nil
|
||||
f.returnToLastDriverNow(mainGame)
|
||||
})
|
||||
f.onClick(mainGame, "12.21", f.hideDialogue(mainGame)) // Exit
|
||||
// 13: exchange menu
|
||||
|
||||
// 14: Map
|
||||
// 14.1: MAP_SPRITE
|
||||
// 14.2: Multiplier button (2x)
|
||||
f.onClick(mainGame, "14.3", f.setActive(mainGame, "14", false))
|
||||
// 14.4: Area
|
||||
|
||||
// 15: Interface wing left
|
||||
// 16: Interface wing right
|
||||
// FIXME: the display of left and right interface buttons is hidden by these
|
||||
// sprites, because we draw in strict numeric order. Just hide them for now.
|
||||
//
|
||||
// FIXME: The child element is already set to hidden, while the menu itself
|
||||
// is set to active, so maybe this is a hint that menus shouldn't be drawn?
|
||||
//
|
||||
// FIXME: the approach taken by the original binary in resolutions greater
|
||||
// than 640x480 is to draw the menu elements *unscaled*. They are centered,
|
||||
// and the dead space is filled by the "interface wing" sprites in the
|
||||
// background. Should we replicate this, or keep with the current scaling
|
||||
// behaviour? Which is better?
|
||||
//
|
||||
// FIXME: the menu bar should be at the bottom, not top, of the screen
|
||||
f.exit = maybeErr(mainGame, f.setActiveNow(mainGame, "15", false)) // Interface wing left
|
||||
f.exit = maybeErr(mainGame, f.setActiveNow(mainGame, "16", false)) // Interface wing right
|
||||
// 17: Grenade dialogue
|
||||
// 18: Info dialogue
|
||||
// 19: Turn start dialogue
|
||||
|
@@ -44,6 +44,7 @@ func (d *Driver) buildButton(p *menus.Properties) (*button, *Widget, error) {
|
||||
}
|
||||
|
||||
widget := &Widget{
|
||||
Active: p.Active,
|
||||
ownClickables: []clickable{btn},
|
||||
ownFreezables: []freezable{btn},
|
||||
ownHoverables: []hoverable{btn},
|
||||
@@ -76,6 +77,7 @@ func (d *Driver) buildMainButton(p *menus.Properties) (*mainButton, *Widget, err
|
||||
}
|
||||
|
||||
widget := &Widget{
|
||||
Active: p.Active,
|
||||
ownClickables: []clickable{btn},
|
||||
ownFreezables: []freezable{btn},
|
||||
ownHoverables: []hoverable{btn},
|
||||
@@ -100,6 +102,7 @@ func (d *Driver) buildDoorHotspot(p *menus.Properties) (*button, *Widget, error)
|
||||
}
|
||||
|
||||
widget := &Widget{
|
||||
Active: p.Active,
|
||||
ownClickables: []clickable{btn},
|
||||
ownFreezables: []freezable{btn},
|
||||
ownHoverables: []hoverable{btn},
|
||||
|
@@ -19,6 +19,7 @@ func (d *Driver) ShowDialogue(locator string) error {
|
||||
if dialogue.Locator == locator {
|
||||
|
||||
// FIXME: we should unhover and mouseup the non-dialogue elements
|
||||
dialogue.Active = true
|
||||
d.activeDialogue = dialogue
|
||||
|
||||
return nil
|
||||
@@ -28,5 +29,9 @@ func (d *Driver) ShowDialogue(locator string) error {
|
||||
}
|
||||
|
||||
func (d *Driver) HideDialogue() {
|
||||
if d.activeDialogue != nil {
|
||||
d.activeDialogue.Active = false
|
||||
}
|
||||
|
||||
d.activeDialogue = nil
|
||||
}
|
||||
|
@@ -169,11 +169,11 @@ func (d *Driver) allClickables() []clickable {
|
||||
var out []clickable
|
||||
|
||||
for _, widget := range d.widgets {
|
||||
out = append(out, widget.clickables()...)
|
||||
out = append(out, widget.allClickables()...)
|
||||
}
|
||||
|
||||
for _, widget := range d.dialogues {
|
||||
out = append(out, widget.clickables()...)
|
||||
out = append(out, widget.allClickables()...)
|
||||
}
|
||||
|
||||
return out
|
||||
@@ -182,11 +182,11 @@ func (d *Driver) allClickables() []clickable {
|
||||
func (d *Driver) allFreezables() []freezable {
|
||||
var out []freezable
|
||||
for _, widget := range d.widgets {
|
||||
out = append(out, widget.freezables()...)
|
||||
out = append(out, widget.allFreezables()...)
|
||||
}
|
||||
|
||||
for _, widget := range d.dialogues {
|
||||
out = append(out, widget.freezables()...)
|
||||
out = append(out, widget.allFreezables()...)
|
||||
}
|
||||
|
||||
return out
|
||||
@@ -196,11 +196,11 @@ func (d *Driver) allValueables() []valueable {
|
||||
var out []valueable
|
||||
|
||||
for _, widget := range d.widgets {
|
||||
out = append(out, widget.valueables()...)
|
||||
out = append(out, widget.allValueables()...)
|
||||
}
|
||||
|
||||
for _, widget := range d.dialogues {
|
||||
out = append(out, widget.valueables()...)
|
||||
out = append(out, widget.allValueables()...)
|
||||
}
|
||||
|
||||
return out
|
||||
@@ -208,12 +208,12 @@ func (d *Driver) allValueables() []valueable {
|
||||
|
||||
func (d *Driver) activeClickables() []clickable {
|
||||
if d.activeDialogue != nil {
|
||||
return d.activeDialogue.clickables()
|
||||
return d.activeDialogue.activeClickables()
|
||||
}
|
||||
|
||||
var out []clickable
|
||||
for _, widget := range d.widgets {
|
||||
out = append(out, widget.clickables()...)
|
||||
out = append(out, widget.activeClickables()...)
|
||||
}
|
||||
|
||||
return out
|
||||
@@ -221,12 +221,12 @@ func (d *Driver) activeClickables() []clickable {
|
||||
|
||||
func (d *Driver) activeHoverables() []hoverable {
|
||||
if d.activeDialogue != nil {
|
||||
return d.activeDialogue.hoverables()
|
||||
return d.activeDialogue.activeHoverables()
|
||||
}
|
||||
|
||||
var out []hoverable
|
||||
for _, widget := range d.widgets {
|
||||
out = append(out, widget.hoverables()...)
|
||||
out = append(out, widget.activeHoverables()...)
|
||||
}
|
||||
|
||||
return out
|
||||
@@ -234,12 +234,12 @@ func (d *Driver) activeHoverables() []hoverable {
|
||||
|
||||
func (d *Driver) activeMouseables() []mouseable {
|
||||
if d.activeDialogue != nil {
|
||||
return d.activeDialogue.mouseables()
|
||||
return d.activeDialogue.activeMouseables()
|
||||
}
|
||||
|
||||
var out []mouseable
|
||||
for _, widget := range d.widgets {
|
||||
out = append(out, widget.mouseables()...)
|
||||
out = append(out, widget.activeMouseables()...)
|
||||
}
|
||||
|
||||
return out
|
||||
@@ -249,12 +249,23 @@ func (d *Driver) activePaintables() []paintable {
|
||||
var out []paintable
|
||||
|
||||
for _, widget := range d.widgets {
|
||||
out = append(out, widget.paintables()...)
|
||||
out = append(out, widget.activePaintables()...)
|
||||
}
|
||||
|
||||
if d.activeDialogue != nil {
|
||||
out = append(out, d.activeDialogue.paintables()...)
|
||||
out = append(out, d.activeDialogue.activePaintables()...)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (d *Driver) findWidget(locator string) *Widget {
|
||||
toplevels := append(d.widgets, d.dialogues...)
|
||||
for _, widget := range toplevels {
|
||||
if w := widget.findWidget(locator); w != nil {
|
||||
return w
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@@ -28,7 +28,10 @@ func (d *Driver) registerGroup(group *menus.Group) error {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
groupWidget = &Widget{Locator: group.Locator}
|
||||
groupWidget = &Widget{
|
||||
Locator: group.Locator,
|
||||
Active: group.Active,
|
||||
}
|
||||
}
|
||||
|
||||
if dialogue {
|
||||
@@ -127,6 +130,7 @@ func (d *Driver) maybeBuildInventorySelect(group *menus.Group, records []*menus.
|
||||
elements := make([]*inventorySelect, len(touched))
|
||||
widget := &Widget{
|
||||
Locator: group.Locator,
|
||||
Active: group.Active,
|
||||
}
|
||||
|
||||
for i, record := range touched {
|
||||
|
@@ -27,6 +27,7 @@ func (d *Driver) buildInventorySelect(p *menus.Properties) (*inventorySelect, *W
|
||||
|
||||
element := &inventorySelect{checkbox: *c}
|
||||
widget := &Widget{
|
||||
Active: p.Active,
|
||||
ownClickables: []clickable{element},
|
||||
ownFreezables: []freezable{element},
|
||||
ownHoverables: []hoverable{element},
|
||||
|
@@ -77,6 +77,7 @@ func (d *Driver) buildListBox(group *menus.Group, up, down, thumb *menus.Record,
|
||||
// mostly self-registered at the moment.
|
||||
widget := &Widget{
|
||||
Children: []*Widget{upWidget, downWidget},
|
||||
Active: group.Active, // FIXME: children have their own active state
|
||||
ownPaintables: []paintable{element},
|
||||
ownValueables: []valueable{element},
|
||||
}
|
||||
|
@@ -83,6 +83,7 @@ func (d *Driver) buildStatic(p *menus.Properties) (*noninteractive, *Widget, err
|
||||
|
||||
widget := &Widget{
|
||||
Locator: ni.locator,
|
||||
Active: p.Active,
|
||||
ownClickables: []clickable{ni}, // FIXME: credits background needs to be clickable
|
||||
ownHoverables: []hoverable{ni},
|
||||
ownPaintables: []paintable{ni},
|
||||
@@ -100,6 +101,7 @@ func (d *Driver) buildHypertext(p *menus.Properties) (*noninteractive, *Widget,
|
||||
// FIXME: check if this is still needed on the bridge -> briefing transition
|
||||
widget := &Widget{
|
||||
Locator: ni.locator,
|
||||
Active: p.Active,
|
||||
ownClickables: []clickable{ni},
|
||||
ownHoverables: []hoverable{ni},
|
||||
}
|
||||
@@ -116,6 +118,7 @@ func (d *Driver) buildOverlay(p *menus.Properties) (*noninteractive, *Widget, er
|
||||
|
||||
widget := &Widget{
|
||||
Locator: ni.locator,
|
||||
Active: p.Active,
|
||||
ownPaintables: []paintable{ni},
|
||||
}
|
||||
|
||||
@@ -155,6 +158,7 @@ func (d *Driver) buildAnimationSample(p *menus.Properties) (*noninteractive, *Wi
|
||||
}
|
||||
|
||||
widget := &Widget{
|
||||
Active: p.Active,
|
||||
ownHoverables: []hoverable{ani},
|
||||
ownPaintables: []paintable{ani},
|
||||
}
|
||||
@@ -190,6 +194,7 @@ func (d *Driver) buildAnimationHover(p *menus.Properties) (*animationHover, *Wid
|
||||
}
|
||||
|
||||
widget := &Widget{
|
||||
Active: p.Active,
|
||||
ownHoverables: []hoverable{ani},
|
||||
ownPaintables: []paintable{ani},
|
||||
}
|
||||
|
@@ -51,6 +51,8 @@ func (d *Driver) buildCheckbox(p *menus.Properties) (*checkbox, *Widget, error)
|
||||
}
|
||||
|
||||
widget := &Widget{
|
||||
Locator: p.Locator,
|
||||
Active: p.Active,
|
||||
ownClickables: []clickable{checkbox},
|
||||
ownFreezables: []freezable{checkbox},
|
||||
ownHoverables: []hoverable{checkbox},
|
||||
@@ -76,6 +78,8 @@ func (d *Driver) buildSlider(p *menus.Properties) (*slider, *Widget, error) {
|
||||
}
|
||||
|
||||
widget := &Widget{
|
||||
Locator: p.Locator,
|
||||
Active: p.Active,
|
||||
ownClickables: []clickable{slider},
|
||||
ownMouseables: []mouseable{slider},
|
||||
ownPaintables: []paintable{slider},
|
||||
|
@@ -61,6 +61,26 @@ func (d *Driver) SetFreeze(id string, value bool) error {
|
||||
return fmt.Errorf("Couldn't find clickable widget %v:%v", d.menu.Name, id)
|
||||
}
|
||||
|
||||
func (d *Driver) ToggleActive(locator string) error {
|
||||
if widget := d.findWidget(locator); widget != nil {
|
||||
widget.Active = !widget.Active
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("Couldn't find activatable widget %v to toggle", locator)
|
||||
}
|
||||
|
||||
func (d *Driver) SetActive(locator string, value bool) error {
|
||||
if widget := d.findWidget(locator); widget != nil {
|
||||
widget.Active = value
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("Couldn't find activeatable widget %v to set to %v", locator, value)
|
||||
}
|
||||
|
||||
func (d *Driver) OnClick(id string, f func()) error {
|
||||
for _, clickable := range d.allClickables() {
|
||||
if clickable.id() == d.realId(id) {
|
||||
|
@@ -3,6 +3,7 @@ package ui
|
||||
type Widget struct {
|
||||
Locator string
|
||||
Children []*Widget
|
||||
Active bool
|
||||
|
||||
ownClickables []clickable
|
||||
ownFreezables []freezable
|
||||
@@ -12,62 +13,130 @@ type Widget struct {
|
||||
ownValueables []valueable
|
||||
}
|
||||
|
||||
func (w *Widget) clickables() []clickable {
|
||||
func (w *Widget) allClickables() []clickable {
|
||||
out := w.ownClickables
|
||||
|
||||
for _, widget := range w.Children {
|
||||
out = append(out, widget.clickables()...)
|
||||
out = append(out, widget.allClickables()...)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (w *Widget) freezables() []freezable {
|
||||
func (w *Widget) allFreezables() []freezable {
|
||||
out := w.ownFreezables
|
||||
|
||||
for _, widget := range w.Children {
|
||||
out = append(out, widget.freezables()...)
|
||||
out = append(out, widget.allFreezables()...)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (w *Widget) hoverables() []hoverable {
|
||||
out := w.ownHoverables
|
||||
|
||||
for _, widget := range w.Children {
|
||||
out = append(out, widget.hoverables()...)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (w *Widget) mouseables() []mouseable {
|
||||
out := w.ownMouseables
|
||||
|
||||
for _, widget := range w.Children {
|
||||
out = append(out, widget.mouseables()...)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (w *Widget) paintables() []paintable {
|
||||
out := w.ownPaintables
|
||||
|
||||
for _, widget := range w.Children {
|
||||
out = append(out, widget.paintables()...)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (w *Widget) valueables() []valueable {
|
||||
func (w *Widget) allValueables() []valueable {
|
||||
out := w.ownValueables
|
||||
|
||||
for _, widget := range w.Children {
|
||||
out = append(out, widget.valueables()...)
|
||||
out = append(out, widget.allValueables()...)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (w *Widget) activeClickables() []clickable {
|
||||
if !w.Active {
|
||||
return nil
|
||||
}
|
||||
|
||||
out := w.ownClickables
|
||||
|
||||
for _, widget := range w.Children {
|
||||
out = append(out, widget.activeClickables()...)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (w *Widget) activeFreezables() []freezable {
|
||||
if !w.Active {
|
||||
return nil
|
||||
}
|
||||
|
||||
out := w.ownFreezables
|
||||
|
||||
for _, widget := range w.Children {
|
||||
out = append(out, widget.activeFreezables()...)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (w *Widget) activeHoverables() []hoverable {
|
||||
if !w.Active {
|
||||
return nil
|
||||
}
|
||||
|
||||
out := w.ownHoverables
|
||||
|
||||
for _, widget := range w.Children {
|
||||
out = append(out, widget.activeHoverables()...)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (w *Widget) activeMouseables() []mouseable {
|
||||
if !w.Active {
|
||||
return nil
|
||||
}
|
||||
|
||||
out := w.ownMouseables
|
||||
|
||||
for _, widget := range w.Children {
|
||||
out = append(out, widget.activeMouseables()...)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (w *Widget) activePaintables() []paintable {
|
||||
if !w.Active {
|
||||
return nil
|
||||
}
|
||||
|
||||
out := w.ownPaintables
|
||||
|
||||
for _, widget := range w.Children {
|
||||
out = append(out, widget.activePaintables()...)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (w *Widget) activeValueables() []valueable {
|
||||
if !w.Active {
|
||||
return nil
|
||||
}
|
||||
|
||||
out := w.ownValueables
|
||||
|
||||
for _, widget := range w.Children {
|
||||
out = append(out, widget.activeValueables()...)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (w *Widget) findWidget(locator string) *Widget {
|
||||
if w.Locator == locator {
|
||||
return w
|
||||
}
|
||||
|
||||
for _, child := range w.Children {
|
||||
if found := child.findWidget(locator); found != nil {
|
||||
return found
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user