package ui import ( "image" "code.ur.gs/lupine/ordoor/internal/assetstore" "code.ur.gs/lupine/ordoor/internal/menus" ) func init() { registerBuilder(menus.TypeSimpleButton, noChildren(registerSimpleButton)) registerBuilder(menus.TypeInvokeButton, noChildren(registerInvokeButton)) registerBuilder(menus.TypeMainButton, noChildren(registerMainButton)) registerBuilder(menus.TypeDoorHotspot, noChildren(registerDoorHotspot)) registerBuilder(menus.TypeDoorHotspot2, noChildren(registerDoorHotspot)) registerBuilder(menus.TypeDoorHotspot3, noChildren(registerDoorHotspot)) } // A button without hover animation // FIXME: Keyboard.mnu has TypeSimpleButton instances that seem to include a // hover in the SpriteId field type button struct { path 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 registerSimpleButton(d *Driver, r *menus.Record) error { _, err := registerButton(d, r, r.SpriteId[0]) return err } func registerInvokeButton(d *Driver, r *menus.Record) error { _, err := registerButton(d, r, r.Share) return err } func registerMainButton(d *Driver, r *menus.Record) error { sprites, err := d.menu.Sprites(r.Share, 3) // base, pressed, disabled if err != nil { return err } hovers, err := d.menu.Images(r.SpriteId[0], r.DrawType) if err != nil { return err } btn := &mainButton{ hoverAnim: animation(hovers), button: button{ path: r.Path(), baseSpr: sprites[0], clickSpr: sprites[1], frozenSpr: sprites[2], hoverImpl: hoverImpl{text: r.Text}, }, } d.clickables = append(d.clickables, btn) d.freezables = append(d.freezables, btn) d.hoverables = append(d.hoverables, btn) d.paintables = append(d.paintables, btn) return nil } func registerDoorHotspot(d *Driver, r *menus.Record) error { sprites, err := d.menu.Sprites(r.Share, 2) // base, pressed if err != nil { return err } btn := &button{ path: r.Path(), baseSpr: sprites[0], clickSpr: sprites[1], frozenSpr: sprites[0], // No disabled sprite hoverImpl: hoverImpl{text: r.Text}, } d.clickables = append(d.clickables, btn) d.freezables = append(d.freezables, btn) d.hoverables = append(d.hoverables, btn) d.paintables = append(d.paintables, btn) return nil } func registerButton(d *Driver, r *menus.Record, spriteId int) (*button, error) { sprites, err := d.menu.Sprites(spriteId, 3) // base, pressed, disabled if err != nil { return nil, err } btn := &button{ path: r.Path(), baseSpr: sprites[0], clickSpr: sprites[1], frozenSpr: sprites[2], hoverImpl: hoverImpl{text: r.Text}, } d.clickables = append(d.clickables, btn) d.freezables = append(d.freezables, btn) d.hoverables = append(d.hoverables, btn) d.paintables = append(d.paintables, btn) return btn, nil } func (b *button) id() string { return b.path } 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 { if !m.isFrozen() && !m.mouseDownState() && m.hoverState() { return oneRegion(m.bounds().Min, m.hoverAnim.image(tick)) } return m.button.regions(tick) }