109 lines
2.2 KiB
Go
109 lines
2.2 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) Arrange(ctx *Context, bounds Rectangle) {
|
||
|
// p.Label.Arrange(ctx, bounds)
|
||
|
// }
|
||
|
|
||
|
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)
|
||
|
}
|
||
|
}
|
||
|
}
|