package ui import ( "image" "code.ur.gs/lupine/ordoor/internal/assetstore" "code.ur.gs/lupine/ordoor/internal/menus" ) // A button without hover animation // FIXME: Keyboard.mnu has TypeSimpleButton instances that seem to include a // hover in the SpriteId field type button struct { locator string baseSpr *assetstore.Sprite clickSpr *assetstore.Sprite frozenSpr *assetstore.Sprite clickImpl freezeImpl hoverImpl } // A button with hover animation type mainButton struct { hoverAnim animation button } func (d *Driver) buildButton(p *menus.Properties) (*button, *Widget, error) { sprites, err := d.menu.Sprites(p.ObjectIdx, p.BaseSpriteID(), 3) // base, pressed, disabled if err != nil { return nil, nil, err } btn := &button{ locator: p.Locator, baseSpr: sprites[0], clickSpr: sprites[1], frozenSpr: sprites[2], hoverImpl: hoverImpl{text: p.Text}, } widget := &Widget{ Active: p.Active, ownClickables: []clickable{btn}, ownFreezables: []freezable{btn}, ownHoverables: []hoverable{btn}, ownPaintables: []paintable{btn}, } return btn, widget, nil } func (d *Driver) buildMainButton(p *menus.Properties) (*mainButton, *Widget, error) { sprites, err := d.menu.Sprites(p.ObjectIdx, p.Share, 3) // base, pressed, disabled if err != nil { return nil, nil, err } hovers, err := d.menu.Images(p.ObjectIdx, p.SpriteId[0], p.DrawType) if err != nil { return nil, nil, err } btn := &mainButton{ hoverAnim: animation(hovers), button: button{ locator: p.Locator, baseSpr: sprites[0], clickSpr: sprites[1], frozenSpr: sprites[2], hoverImpl: hoverImpl{text: p.Text}, }, } widget := &Widget{ Active: p.Active, ownClickables: []clickable{btn}, ownFreezables: []freezable{btn}, ownHoverables: []hoverable{btn}, ownPaintables: []paintable{btn}, } return btn, widget, nil } func (d *Driver) buildDoorHotspot(p *menus.Properties) (*button, *Widget, error) { sprites, err := d.menu.Sprites(p.ObjectIdx, p.Share, 2) // base, pressed if err != nil { return nil, nil, err } btn := &button{ locator: p.Locator, baseSpr: sprites[0], clickSpr: sprites[1], frozenSpr: sprites[0], // No disabled sprite hoverImpl: hoverImpl{text: p.Text}, } widget := &Widget{ Active: p.Active, ownClickables: []clickable{btn}, ownFreezables: []freezable{btn}, ownHoverables: []hoverable{btn}, ownPaintables: []paintable{btn}, } return btn, widget, nil } func (b *button) id() string { return b.locator } func (b *button) bounds() image.Rectangle { return b.baseSpr.Rect } func (b *button) mouseDownState() bool { if b.isFrozen() { return false } return b.clickImpl.mouseDownState() } func (b *button) registerMouseClick() { if !b.isFrozen() { b.clickImpl.registerMouseClick() } } func (b *button) regions(tick int) []region { if b.isFrozen() { return oneRegion(b.bounds().Min, b.frozenSpr.Image) } if b.mouseDownState() { return oneRegion(b.bounds().Min, b.clickSpr.Image) } return oneRegion(b.bounds().Min, b.baseSpr.Image) } func (m *mainButton) regions(tick int) []region { // FIXME: main button should complete its animation when we mouse away if !m.isFrozen() && !m.mouseDownState() && m.hoverState() { return oneRegion(m.bounds().Min, m.hoverAnim.image(tick)) } return m.button.regions(tick) }