2020-05-10 15:16:18 +00:00
|
|
|
package tins2020
|
|
|
|
|
|
|
|
import (
|
2020-05-23 07:11:08 +00:00
|
|
|
"fmt"
|
|
|
|
"image/color"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"opslag.de/schobers/geom"
|
2020-05-17 08:56:56 +00:00
|
|
|
"opslag.de/schobers/zntg"
|
|
|
|
"opslag.de/schobers/zntg/ui"
|
2020-05-10 15:16:18 +00:00
|
|
|
)
|
|
|
|
|
2020-05-23 07:11:08 +00:00
|
|
|
type TextureCache struct {
|
|
|
|
Value ui.Texture
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *TextureCache) Height() float32 {
|
|
|
|
if c.Value == nil {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
return c.Value.Height()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *TextureCache) Update(update func() (ui.Texture, error)) error {
|
|
|
|
texture, err := update()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if c.Value != nil {
|
|
|
|
c.Value.Destroy()
|
|
|
|
}
|
|
|
|
c.Value = texture
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *TextureCache) Width() float32 {
|
|
|
|
if c.Value == nil {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
return c.Value.Width()
|
|
|
|
}
|
|
|
|
|
|
|
|
func textUpdate(render ui.Renderer, font ui.Font, color color.Color, text string) func() (ui.Texture, error) {
|
|
|
|
return func() (ui.Texture, error) { return render.TextTexture(font, color, text) }
|
|
|
|
}
|
|
|
|
|
2020-05-10 15:16:18 +00:00
|
|
|
type BuyFlowerButton struct {
|
|
|
|
IconButton
|
|
|
|
|
2020-05-23 07:11:08 +00:00
|
|
|
IconDisabled string
|
|
|
|
FlowerID string
|
|
|
|
Flower FlowerDescriptor
|
2020-05-10 18:44:20 +00:00
|
|
|
|
2020-05-17 08:56:56 +00:00
|
|
|
upToDate bool
|
2020-05-23 07:11:08 +00:00
|
|
|
hoverAnimation zntg.Animation
|
|
|
|
hoverOffset float32
|
|
|
|
hoverTexture TextureCache
|
|
|
|
priceTexture TextureCache
|
2020-05-10 15:16:18 +00:00
|
|
|
}
|
|
|
|
|
2020-05-17 08:56:56 +00:00
|
|
|
func NewBuyFlowerButton(icon, iconDisabled, flowerID string, flower FlowerDescriptor, click ui.EventEmptyFn) *BuyFlowerButton {
|
2020-05-10 15:16:18 +00:00
|
|
|
return &BuyFlowerButton{
|
2020-05-17 08:56:56 +00:00
|
|
|
IconButton: *NewIconButtonConfigure(icon, click, func(b *IconButton) {
|
2020-05-23 07:11:08 +00:00
|
|
|
b.Disabled = !flower.Unlocked
|
2020-05-10 15:16:18 +00:00
|
|
|
}),
|
2020-05-23 07:11:08 +00:00
|
|
|
IconDisabled: iconDisabled,
|
|
|
|
FlowerID: flowerID,
|
|
|
|
Flower: flower,
|
2020-05-10 15:16:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-23 07:11:08 +00:00
|
|
|
func (b *BuyFlowerButton) animate() {
|
|
|
|
b.hoverOffset++
|
|
|
|
if b.hoverOffset > b.hoverTexture.Width()+b.Bounds().Dx() {
|
|
|
|
b.hoverOffset = 0
|
|
|
|
}
|
|
|
|
}
|
2020-05-17 08:56:56 +00:00
|
|
|
|
2020-05-23 07:11:08 +00:00
|
|
|
func (b *BuyFlowerButton) fmtTooltipText() string {
|
|
|
|
if !b.Flower.Unlocked {
|
|
|
|
return fmt.Sprintf("%s - %s - %s", FmtMoney(b.Flower.BuyPrice), b.Flower.Name, "Traits are not known yet.")
|
|
|
|
}
|
|
|
|
return fmt.Sprintf("%s - %s - %s", FmtMoney(b.Flower.BuyPrice), b.Flower.Name, b.Flower.Description)
|
|
|
|
}
|
2020-05-17 08:56:56 +00:00
|
|
|
|
|
|
|
func (b *BuyFlowerButton) updateTexts(ctx ui.Context) error {
|
|
|
|
if b.upToDate {
|
|
|
|
return nil
|
2020-05-10 21:00:19 +00:00
|
|
|
}
|
2020-05-23 07:11:08 +00:00
|
|
|
text := b.fmtTooltipText()
|
|
|
|
font := ctx.Fonts().Font("small")
|
|
|
|
color := zntg.MustHexColor("#FFFFFF")
|
|
|
|
if err := b.hoverTexture.Update(textUpdate(ctx.Renderer(), font, color, text)); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := b.priceTexture.Update(textUpdate(ctx.Renderer(), font, color, FmtMoney(b.Flower.BuyPrice))); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-05-17 08:56:56 +00:00
|
|
|
b.upToDate = true
|
2020-05-10 15:16:18 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-05-23 07:11:08 +00:00
|
|
|
func (b *BuyFlowerButton) Handle(ctx ui.Context, e ui.Event) bool {
|
2020-05-17 08:56:56 +00:00
|
|
|
b.updateTexts(ctx)
|
2020-05-23 07:11:08 +00:00
|
|
|
b.IconButton.Handle(ctx, e)
|
|
|
|
if b.IsOver() && !b.hoverAnimation.IsActive() {
|
|
|
|
b.hoverAnimation.Interval = 10 * time.Millisecond
|
|
|
|
b.hoverAnimation.Start()
|
|
|
|
b.hoverOffset = b.priceTexture.Width()
|
|
|
|
} else if !b.IsOver() {
|
|
|
|
b.hoverAnimation.Pause()
|
|
|
|
}
|
2020-05-11 09:44:50 +00:00
|
|
|
return false
|
2020-05-10 15:16:18 +00:00
|
|
|
}
|
|
|
|
|
2020-05-17 08:56:56 +00:00
|
|
|
func (b *BuyFlowerButton) Render(ctx ui.Context) {
|
2020-05-23 07:11:08 +00:00
|
|
|
b.updateTexts(ctx)
|
|
|
|
|
|
|
|
bounds := b.Bounds()
|
|
|
|
pos := bounds.Min
|
|
|
|
|
|
|
|
icon := ctx.Textures().Texture(b.Icon)
|
|
|
|
if !b.Flower.Unlocked {
|
|
|
|
disabled := ctx.Textures().Texture(b.IconDisabled)
|
|
|
|
if disabled != nil {
|
|
|
|
icon = disabled
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ctx.Renderer().DrawTexture(icon, geom.RectRelF32(pos.X, pos.Y-60, bounds.Dx(), 120))
|
|
|
|
b.RenderActive(ctx)
|
|
|
|
|
|
|
|
b.hoverAnimation.AnimateFn(b.animate)
|
|
|
|
|
|
|
|
if b.IsOver() {
|
|
|
|
left := bounds.Dx() - 8 - b.hoverOffset
|
|
|
|
top := pos.Y + bounds.Dy() - 20
|
|
|
|
if left < 0 {
|
|
|
|
part := geom.RectF32(-left, 0, b.hoverTexture.Width(), b.hoverTexture.Height())
|
|
|
|
ctx.Renderer().DrawTexturePointOptions(b.hoverTexture.Value, geom.PtF32(pos.X, top), ui.DrawOptions{Source: &part})
|
|
|
|
} else {
|
|
|
|
ctx.Renderer().DrawTexturePoint(b.hoverTexture.Value, geom.PtF32(pos.X+left, top))
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ctx.Renderer().DrawTexturePoint(b.priceTexture.Value, geom.PtF32(pos.X+bounds.Dx()-8-b.priceTexture.Width(), pos.Y+bounds.Dy()-20))
|
2020-05-10 15:16:18 +00:00
|
|
|
}
|
|
|
|
}
|
2020-05-11 01:09:01 +00:00
|
|
|
|
2020-05-17 08:56:56 +00:00
|
|
|
func (b *BuyFlowerButton) Update(desc FlowerDescriptor) {
|
2020-05-11 01:09:01 +00:00
|
|
|
b.Flower = desc
|
2020-05-17 08:56:56 +00:00
|
|
|
b.upToDate = false
|
2020-05-11 01:09:01 +00:00
|
|
|
}
|