last_light/render/text.go

92 lines
1.7 KiB
Go
Raw Normal View History

2024-04-19 23:11:21 +03:00
package render
import (
"mvvasilev/last_light/util"
"strings"
"unicode/utf8"
"github.com/gdamore/tcell/v2"
"github.com/google/uuid"
)
type Drawable interface {
UniqueId() uuid.UUID
Draw(s tcell.Screen)
}
type text struct {
id uuid.UUID
content []string
position util.Position
size util.Size
style tcell.Style
}
func CreateText(
x, y uint16,
width, height uint16,
content string,
style tcell.Style,
) text {
return text{
id: uuid.New(),
content: strings.Split(content, " "),
style: style,
size: util.SizeOf(width, height),
position: util.PositionAt(x, y),
}
}
func (t text) UniqueId() uuid.UUID {
return t.id
}
func (t text) Draw(s tcell.Screen) {
width := t.size.Width()
height := t.size.Height()
x := t.position.X()
y := t.position.Y()
currentHPos := 0
currentVPos := 0
drawText := func(text string) {
for i, r := range text {
s.SetContent(x+currentHPos+i, y+currentVPos, r, nil, t.style)
}
}
for _, s := range t.content {
runeCount := utf8.RuneCountInString(s)
if currentVPos > height {
break
}
// The current word cannot fit within the remaining space on the line
if runeCount > (width - currentHPos) {
currentVPos += 1 // next line
currentHPos = 0 // reset to start of line
drawText(s + " ")
currentHPos += runeCount + 1
continue
}
// The current word fits exactly within the remaining space on the line
if runeCount == (width - currentHPos) {
drawText(s)
currentVPos += 1 // next line
currentHPos = 0 // reset to start of line
continue
}
// The current word fits within the remaining space, and there's more space left over
drawText(s + " ")
currentHPos += runeCount + 1 // add +1 to account for space after word
}
}