2019-10-25 23:37:04 +00:00
|
|
|
package UI
|
2019-10-24 13:31:59 +00:00
|
|
|
|
|
|
|
import (
|
2019-10-24 23:13:30 +00:00
|
|
|
"image/color"
|
|
|
|
|
2019-10-25 23:12:42 +00:00
|
|
|
"github.com/essial/OpenDiablo2/Common"
|
2019-10-25 22:40:27 +00:00
|
|
|
"github.com/essial/OpenDiablo2/Palettes"
|
2019-10-24 13:31:59 +00:00
|
|
|
"github.com/hajimehoshi/ebiten"
|
|
|
|
)
|
|
|
|
|
2019-10-25 23:37:04 +00:00
|
|
|
// LabelAlignment represents a label's alignment
|
|
|
|
type LabelAlignment uint8
|
2019-10-24 23:13:30 +00:00
|
|
|
|
|
|
|
const (
|
2019-10-25 23:37:04 +00:00
|
|
|
// LabelAlignLeft represents a left-aligned label
|
|
|
|
LabelAlignLeft LabelAlignment = 0
|
|
|
|
// LabelAlignCenter represents a center-aligned label
|
|
|
|
LabelAlignCenter LabelAlignment = 1
|
|
|
|
// LabelAlignRight represents a right-aligned label
|
|
|
|
LabelAlignRight LabelAlignment = 2
|
2019-10-24 23:13:30 +00:00
|
|
|
)
|
|
|
|
|
2019-10-25 23:37:04 +00:00
|
|
|
// Label represents a user interface label
|
|
|
|
type Label struct {
|
2019-10-24 13:31:59 +00:00
|
|
|
text string
|
|
|
|
X int
|
|
|
|
Y int
|
|
|
|
Width uint32
|
|
|
|
Height uint32
|
2019-10-25 23:37:04 +00:00
|
|
|
Alignment LabelAlignment
|
|
|
|
font *Font
|
2019-10-24 13:31:59 +00:00
|
|
|
imageData *ebiten.Image
|
2019-10-24 23:13:30 +00:00
|
|
|
ColorMod color.Color
|
2019-10-24 13:31:59 +00:00
|
|
|
}
|
|
|
|
|
2019-10-25 23:37:04 +00:00
|
|
|
// CreateLabel creates a new instance of a UI label
|
|
|
|
func CreateLabel(provider Common.FileProvider, font string, palette Palettes.Palette) *Label {
|
|
|
|
result := &Label{
|
|
|
|
Alignment: LabelAlignLeft,
|
2019-10-24 23:13:30 +00:00
|
|
|
ColorMod: nil,
|
2019-10-25 23:37:04 +00:00
|
|
|
font: GetFont(font, palette, provider),
|
2019-10-24 13:31:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
// Draw draws the label on the screen
|
2019-10-25 23:37:04 +00:00
|
|
|
func (v *Label) Draw(target *ebiten.Image) {
|
2019-10-24 13:31:59 +00:00
|
|
|
if len(v.text) == 0 {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
v.cacheImage()
|
|
|
|
opts := &ebiten.DrawImageOptions{}
|
2019-10-24 23:13:30 +00:00
|
|
|
|
2019-10-25 23:37:04 +00:00
|
|
|
if v.Alignment == LabelAlignCenter {
|
2019-10-24 23:13:30 +00:00
|
|
|
opts.GeoM.Translate(float64(v.X-int(v.Width/2)), float64(v.Y))
|
2019-10-25 23:37:04 +00:00
|
|
|
} else if v.Alignment == LabelAlignRight {
|
2019-10-24 23:13:30 +00:00
|
|
|
opts.GeoM.Translate(float64(v.X-int(v.Width)), float64(v.Y))
|
|
|
|
} else {
|
|
|
|
opts.GeoM.Translate(float64(v.X), float64(v.Y))
|
|
|
|
}
|
2019-10-24 13:31:59 +00:00
|
|
|
opts.CompositeMode = ebiten.CompositeModeSourceAtop
|
|
|
|
opts.Filter = ebiten.FilterNearest
|
|
|
|
target.DrawImage(v.imageData, opts)
|
|
|
|
}
|
|
|
|
|
2019-10-25 23:37:04 +00:00
|
|
|
func (v *Label) calculateSize() (uint32, uint32) {
|
2019-10-24 13:31:59 +00:00
|
|
|
width := uint32(0)
|
|
|
|
height := uint32(0)
|
2019-10-24 23:13:30 +00:00
|
|
|
for _, ch := range v.text {
|
2019-10-24 13:31:59 +00:00
|
|
|
metric := v.font.Metrics[uint8(ch)]
|
|
|
|
width += uint32(metric.Width)
|
2019-10-25 23:12:42 +00:00
|
|
|
height = Common.Max(height, uint32(metric.Height))
|
2019-10-24 13:31:59 +00:00
|
|
|
}
|
|
|
|
return width, height
|
|
|
|
}
|
|
|
|
|
2019-10-25 23:12:42 +00:00
|
|
|
// MoveTo moves the label to the specified location
|
2019-10-25 23:37:04 +00:00
|
|
|
func (v *Label) MoveTo(x, y int) {
|
2019-10-24 13:31:59 +00:00
|
|
|
v.X = x
|
|
|
|
v.Y = y
|
|
|
|
}
|
|
|
|
|
2019-10-25 23:37:04 +00:00
|
|
|
func (v *Label) cacheImage() {
|
2019-10-24 13:31:59 +00:00
|
|
|
if v.imageData != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
width, height := v.calculateSize()
|
|
|
|
v.Width = width
|
|
|
|
v.Height = height
|
|
|
|
v.imageData, _ = ebiten.NewImage(int(width), int(height), ebiten.FilterNearest)
|
|
|
|
x := uint32(0)
|
2019-10-24 23:13:30 +00:00
|
|
|
v.font.FontSprite.ColorMod = v.ColorMod
|
2019-10-24 13:31:59 +00:00
|
|
|
for _, ch := range v.text {
|
|
|
|
char := uint8(ch)
|
|
|
|
metric := v.font.Metrics[char]
|
|
|
|
v.font.FontSprite.Frame = char
|
2019-10-24 23:13:30 +00:00
|
|
|
v.font.FontSprite.MoveTo(int(x), int(height))
|
2019-10-24 13:31:59 +00:00
|
|
|
v.font.FontSprite.Draw(v.imageData)
|
|
|
|
x += uint32(metric.Width)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-25 23:12:42 +00:00
|
|
|
// SetText sets the label's text
|
2019-10-25 23:37:04 +00:00
|
|
|
func (v *Label) SetText(newText string) {
|
2019-10-24 13:31:59 +00:00
|
|
|
if v.text == newText {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
v.text = newText
|
|
|
|
v.imageData = nil
|
|
|
|
}
|