last_light/engine/text.go

124 lines
2.2 KiB
Go
Raw Normal View History

2024-05-06 20:43:35 +03:00
package engine
2024-04-19 23:11:21 +03:00
import (
"strings"
"unicode/utf8"
"github.com/gdamore/tcell/v2"
"github.com/gdamore/tcell/v2/views"
2024-04-19 23:11:21 +03:00
"github.com/google/uuid"
)
2024-04-24 17:11:33 +03:00
type Text struct {
2024-04-19 23:11:21 +03:00
id uuid.UUID
content []string
2024-05-06 21:19:08 +03:00
position Position
size Size
2024-04-19 23:11:21 +03:00
style tcell.Style
}
func CreateText(
x, y int,
width, height int,
2024-04-19 23:11:21 +03:00
content string,
style tcell.Style,
2024-04-24 17:11:33 +03:00
) *Text {
text := new(Text)
text.id = uuid.New()
text.content = strings.Split(content, " ")
text.style = style
2024-05-06 21:19:08 +03:00
text.size = SizeOf(width, height)
text.position = PositionAt(x, y)
2024-04-24 17:11:33 +03:00
return text
2024-04-19 23:11:21 +03:00
}
2024-04-24 17:11:33 +03:00
func (t *Text) UniqueId() uuid.UUID {
2024-04-19 23:11:21 +03:00
return t.id
}
2024-05-06 21:19:08 +03:00
func (t *Text) Position() Position {
2024-04-24 17:11:33 +03:00
return t.position
}
func (t *Text) Content() string {
return strings.Join(t.content, " ")
}
2024-05-06 21:19:08 +03:00
func (t *Text) Size() Size {
2024-04-24 17:11:33 +03:00
return t.size
}
func (t *Text) SetStyle(style tcell.Style) {
t.style = style
}
func (t *Text) Style() tcell.Style {
return t.style
}
func (t *Text) Draw(s views.View) {
2024-04-19 23:11:21 +03:00
width := t.size.Width()
height := t.size.Height()
x := t.position.X()
y := t.position.Y()
currentHPos := 0
currentVPos := 0
drawText := func(text string) {
2024-05-03 13:46:32 +03:00
lastPos := 0
for _, r := range text {
s.SetContent(x+currentHPos+lastPos, y+currentVPos, r, nil, t.style)
lastPos++
2024-04-19 23:11:21 +03:00
}
}
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
}
}
2024-05-30 23:39:54 +03:00
func DrawText(x, y int, content string, style tcell.Style, s views.View) {
currentHPos := 0
currentVPos := 0
lastPos := 0
for _, r := range content {
s.SetContent(x+currentHPos+lastPos, y+currentVPos, r, nil, style)
lastPos++
}
}