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:
@@ -1,6 +1,7 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
"log"
|
||||
|
||||
@@ -15,22 +16,14 @@ const (
|
||||
AlignModeLeft AlignMode = 1
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerBuilder(menus.TypeStatic, registerStatic) // MainGame has a hypertext child
|
||||
registerBuilder(menus.TypeHypertext, noChildren(registerHypertext))
|
||||
registerBuilder(menus.TypeOverlay, noChildren(registerOverlay))
|
||||
registerBuilder(menus.TypeAnimationSample, noChildren(registerAnimation))
|
||||
registerBuilder(menus.TypeAnimationHover, noChildren(registerAnimationHover))
|
||||
}
|
||||
|
||||
// A non-interactive element is not a widget; it merely displays some pixels and
|
||||
// may optionally have a tooltip for display within bounds.
|
||||
//
|
||||
// For non-animated non-interactive elements, just give them a single frame.
|
||||
type noninteractive struct {
|
||||
path string
|
||||
frames animation
|
||||
rect image.Rectangle
|
||||
locator string
|
||||
frames animation
|
||||
rect image.Rectangle
|
||||
|
||||
// Some non-interactives, e.g., overlays, are an image + text to be shown
|
||||
label *label
|
||||
@@ -58,145 +51,153 @@ type animationHover struct {
|
||||
closing bool
|
||||
}
|
||||
|
||||
func registerStatic(d *Driver, r *menus.Record) ([]*menus.Record, error) {
|
||||
_, err := registerNoninteractive(d, r)
|
||||
return r.Children, err
|
||||
}
|
||||
|
||||
func registerNoninteractive(d *Driver, r *menus.Record) (*noninteractive, error) {
|
||||
// FIXME: SpriteID takes precedence over SHARE if present, but is that right?
|
||||
spriteId := r.Share
|
||||
if len(r.SpriteId) > 0 && r.SpriteId[0] != -1 {
|
||||
spriteId = r.SpriteId[0]
|
||||
func (d *Driver) buildNoninteractive(p *menus.Properties) (*noninteractive, error) {
|
||||
// FIXME: SpriteID takes precedence over SHARE if present, but is that
|
||||
// always right?
|
||||
spriteId := p.BaseSpriteID()
|
||||
if spriteId < 0 {
|
||||
return nil, fmt.Errorf("No base sprite for %v", p.Locator)
|
||||
}
|
||||
|
||||
sprite, err := d.menu.Sprite(r.ObjectIdx, spriteId)
|
||||
sprite, err := d.menu.Sprite(p.ObjectIdx, spriteId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ni := &noninteractive{
|
||||
path: r.Path(),
|
||||
frames: animation{sprite.Image},
|
||||
hoverImpl: hoverImpl{text: r.Text},
|
||||
rect: sprite.Rect,
|
||||
locator: p.Locator,
|
||||
frames: animation{sprite.Image},
|
||||
rect: sprite.Rect,
|
||||
}
|
||||
|
||||
d.hoverables = append(d.hoverables, ni)
|
||||
d.paintables = append(d.paintables, ni)
|
||||
|
||||
return ni, nil
|
||||
}
|
||||
|
||||
func registerHypertext(d *Driver, r *menus.Record) error {
|
||||
sprite, err := d.menu.Sprite(r.ObjectIdx, r.Share)
|
||||
func (d *Driver) buildStatic(p *menus.Properties) (*noninteractive, *Widget, error) {
|
||||
ni, err := d.buildNoninteractive(p)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ni := &noninteractive{
|
||||
path: r.Path(),
|
||||
hoverImpl: hoverImpl{text: r.Text},
|
||||
rect: sprite.Rect,
|
||||
ni.hoverImpl.text = p.Text
|
||||
|
||||
widget := &Widget{
|
||||
Locator: ni.locator,
|
||||
ownHoverables: []hoverable{ni},
|
||||
ownPaintables: []paintable{ni},
|
||||
}
|
||||
|
||||
d.clickables = append(d.clickables, ni)
|
||||
d.hoverables = append(d.hoverables, ni)
|
||||
return ni, widget, nil
|
||||
}
|
||||
|
||||
return nil
|
||||
func (d *Driver) buildHypertext(p *menus.Properties) (*noninteractive, *Widget, error) {
|
||||
ni, err := d.buildNoninteractive(p)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// FIXME: check if this is still needed on the bridge -> briefing transition
|
||||
widget := &Widget{
|
||||
Locator: ni.locator,
|
||||
ownClickables: []clickable{ni},
|
||||
ownHoverables: []hoverable{ni},
|
||||
}
|
||||
|
||||
return ni, widget, nil
|
||||
}
|
||||
|
||||
// An overlay is a static image + some text that needs to be rendered
|
||||
func registerOverlay(d *Driver, r *menus.Record) error {
|
||||
sprite, err := d.menu.Sprite(r.ObjectIdx, r.Share)
|
||||
func (d *Driver) buildOverlay(p *menus.Properties) (*noninteractive, *Widget, error) {
|
||||
ni, err := d.buildNoninteractive(p)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ni := &noninteractive{
|
||||
path: r.Path(),
|
||||
frames: animation{sprite.Image},
|
||||
rect: sprite.Rect,
|
||||
widget := &Widget{
|
||||
Locator: ni.locator,
|
||||
ownPaintables: []paintable{ni},
|
||||
}
|
||||
|
||||
d.paintables = append(d.paintables, ni)
|
||||
|
||||
if r.Text != "" {
|
||||
if p.Text != "" {
|
||||
// FIXME: is this always right? Seems to make sense for Main.mnu
|
||||
fnt := d.menu.Font(r.FontType/10 - 1)
|
||||
fnt := d.menu.Font(p.FontType/10 - 1)
|
||||
|
||||
ni.label = &label{
|
||||
font: fnt,
|
||||
rect: ni.rect, // We will be centered by default
|
||||
text: r.Text,
|
||||
text: p.Text,
|
||||
}
|
||||
} else {
|
||||
log.Printf("Overlay without text detected: %#+v", r)
|
||||
log.Printf("Overlay without text detected in %v", p.Locator)
|
||||
}
|
||||
|
||||
return nil
|
||||
return ni, widget, nil
|
||||
}
|
||||
|
||||
// An animation is a non-interactive element that displays something in a loop
|
||||
func registerAnimation(d *Driver, r *menus.Record) error {
|
||||
sprite, err := d.menu.Sprite(r.ObjectIdx, r.SpriteId[0])
|
||||
func (d *Driver) buildAnimationSample(p *menus.Properties) (*noninteractive, *Widget, error) {
|
||||
sprite, err := d.menu.Sprite(p.ObjectIdx, p.SpriteId[0])
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
frames, err := d.menu.Images(r.ObjectIdx, r.SpriteId[0], r.DrawType)
|
||||
frames, err := d.menu.Images(p.ObjectIdx, p.SpriteId[0], p.DrawType)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ani := &noninteractive{
|
||||
path: r.Path(),
|
||||
locator: p.Locator,
|
||||
frames: animation(frames),
|
||||
hoverImpl: hoverImpl{text: r.Text},
|
||||
hoverImpl: hoverImpl{text: p.Text},
|
||||
rect: sprite.Rect,
|
||||
}
|
||||
|
||||
d.hoverables = append(d.hoverables, ani)
|
||||
d.paintables = append(d.paintables, ani)
|
||||
widget := &Widget{
|
||||
ownHoverables: []hoverable{ani},
|
||||
ownPaintables: []paintable{ani},
|
||||
}
|
||||
|
||||
return nil
|
||||
return ani, widget, nil
|
||||
}
|
||||
|
||||
func registerAnimationHover(d *Driver, r *menus.Record) error {
|
||||
sprite, err := d.menu.Sprite(r.ObjectIdx, r.SpriteId[0])
|
||||
func (d *Driver) buildAnimationHover(p *menus.Properties) (*animationHover, *Widget, error) {
|
||||
sprite, err := d.menu.Sprite(p.ObjectIdx, p.SpriteId[0])
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
enterFrames, err := d.menu.Images(r.ObjectIdx, r.SpriteId[0], r.DrawType)
|
||||
enterFrames, err := d.menu.Images(p.ObjectIdx, p.SpriteId[0], p.DrawType)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
exitFrames, err := d.menu.Images(r.ObjectIdx, r.SpriteId[0]+r.DrawType, r.DrawType)
|
||||
exitFrames, err := d.menu.Images(p.ObjectIdx, p.SpriteId[0]+p.DrawType, p.DrawType)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ani := &animationHover{
|
||||
noninteractive: noninteractive{
|
||||
path: r.Path(),
|
||||
locator: p.Locator,
|
||||
frames: animation(enterFrames),
|
||||
hoverImpl: hoverImpl{text: r.Text},
|
||||
hoverImpl: hoverImpl{text: p.Text},
|
||||
rect: sprite.Rect,
|
||||
},
|
||||
|
||||
exitFrames: animation(exitFrames),
|
||||
}
|
||||
|
||||
d.hoverables = append(d.hoverables, ani)
|
||||
d.paintables = append(d.paintables, ani)
|
||||
widget := &Widget{
|
||||
ownHoverables: []hoverable{ani},
|
||||
ownPaintables: []paintable{ani},
|
||||
}
|
||||
|
||||
return nil
|
||||
return ani, widget, nil
|
||||
}
|
||||
|
||||
func (n *noninteractive) id() string {
|
||||
return n.path
|
||||
return n.locator
|
||||
}
|
||||
|
||||
func (n *noninteractive) bounds() image.Rectangle {
|
||||
|
Reference in New Issue
Block a user