tins2020/label.go

105 lines
2.1 KiB
Go

package tins2020
import (
"strings"
"github.com/veandco/go-sdl2/sdl"
)
type Label struct {
ControlBase
FontColor sdl.Color
FontName string
Text string
Alignment TextAlignment
}
func (l *Label) fontColor() sdl.Color {
var none sdl.Color
if l.FontColor == none {
return MustHexColor("#ffffff")
}
return l.FontColor
}
func (l *Label) fontName() string {
if len(l.FontName) == 0 {
return "default"
}
return l.FontName
}
func (l *Label) Render(ctx *Context) {
font := ctx.Fonts.Font(l.fontName())
color := l.fontColor()
bottom := l.Bounds.Y + l.Bounds.H
switch l.Alignment {
case TextAlignmentCenter:
font.RenderCopyAlign(ctx.Renderer, l.Text, Pt(l.Bounds.X+l.Bounds.W/2, bottom), color, TextAlignmentCenter)
case TextAlignmentLeft:
font.RenderCopyAlign(ctx.Renderer, l.Text, Pt(l.Bounds.X, bottom), color, TextAlignmentLeft)
case TextAlignmentRight:
font.RenderCopyAlign(ctx.Renderer, l.Text, Pt(l.Bounds.X+l.Bounds.W, bottom), color, TextAlignmentRight)
}
}
type Paragraph struct {
Label
}
func (p *Paragraph) Render(ctx *Context) {
font := ctx.Fonts.Font(p.fontName())
color := p.fontColor()
fontHeight := int32(font.Height())
lines := strings.Split(p.Text, "\n")
measure := func(s string) int32 {
w, _, _ := font.SizeUTF8(s)
return int32(w)
}
spaces := func(s string) []int {
var spaces []int
offset := 0
for {
space := strings.Index(s[offset:], " ")
if space == -1 {
return spaces
}
offset += space
spaces = append(spaces, offset)
offset++
}
}
fit := func(s string) string {
if measure(s) < p.Bounds.W {
return s
}
spaces := spaces(s)
for split := len(spaces) - 1; split >= 0; split-- {
clipped := s[:spaces[split]]
if measure(clipped) < p.Bounds.W {
return clipped
}
}
return s
}
offset := p.Bounds.Y
for _, line := range lines {
if len(line) == 0 {
offset += fontHeight
continue
}
for len(line) > 0 {
offset += fontHeight
clipped := fit(line)
line = strings.TrimLeft(line[len(clipped):], " ")
font.RenderCopy(ctx.Renderer, clipped, Pt(p.Bounds.X, offset), color)
}
}
}