Initial patterm project
This commit is contained in:
86
internal/app/screen_renderer.go
Normal file
86
internal/app/screen_renderer.go
Normal file
@@ -0,0 +1,86 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/harrybrwn/patterm/internal/vt"
|
||||
)
|
||||
|
||||
func renderScreenSnapshot(text string, cursor vt.CursorState, layout terminalLayout) []byte {
|
||||
lines := strings.Split(strings.ReplaceAll(text, "\r\n", "\n"), "\n")
|
||||
cols := int(layout.childCols())
|
||||
rows := int(layout.childRows())
|
||||
|
||||
var b strings.Builder
|
||||
b.WriteString("\x1b[?25l")
|
||||
for r := 0; r < rows; r++ {
|
||||
line := ""
|
||||
if r < len(lines) {
|
||||
line = truncateCells(lines[r], cols)
|
||||
}
|
||||
fmt.Fprintf(&b, "\x1b[%d;%dH%s", int(layout.mainTop)+r, int(layout.mainLeft), padRight(line, cols))
|
||||
}
|
||||
|
||||
if cursor.Visible {
|
||||
row := int(layout.mainTop) + int(cursor.Row)
|
||||
col := int(layout.mainLeft) + int(cursor.Col)
|
||||
if row < int(layout.mainTop) {
|
||||
row = int(layout.mainTop)
|
||||
}
|
||||
maxRow := int(layout.mainTop) + rows - 1
|
||||
if row > maxRow {
|
||||
row = maxRow
|
||||
}
|
||||
if col < int(layout.mainLeft) {
|
||||
col = int(layout.mainLeft)
|
||||
}
|
||||
maxCol := int(layout.mainLeft) + cols - 1
|
||||
if col > maxCol {
|
||||
col = maxCol
|
||||
}
|
||||
fmt.Fprintf(&b, "\x1b[?25h\x1b[%d;%dH", row, col)
|
||||
}
|
||||
return []byte(b.String())
|
||||
}
|
||||
|
||||
func renderCursor(cursor vt.CursorState, layout terminalLayout) []byte {
|
||||
cols := int(layout.childCols())
|
||||
rows := int(layout.childRows())
|
||||
row := int(layout.mainTop) + int(cursor.Row)
|
||||
col := int(layout.mainLeft) + int(cursor.Col)
|
||||
if row < int(layout.mainTop) {
|
||||
row = int(layout.mainTop)
|
||||
}
|
||||
maxRow := int(layout.mainTop) + rows - 1
|
||||
if row > maxRow {
|
||||
row = maxRow
|
||||
}
|
||||
if col < int(layout.mainLeft) {
|
||||
col = int(layout.mainLeft)
|
||||
}
|
||||
maxCol := int(layout.mainLeft) + cols - 1
|
||||
if col > maxCol {
|
||||
col = maxCol
|
||||
}
|
||||
return []byte(fmt.Sprintf("\x1b[?25h\x1b[%d;%dH", row, col))
|
||||
}
|
||||
|
||||
func truncateCells(s string, width int) string {
|
||||
if width <= 0 {
|
||||
return ""
|
||||
}
|
||||
if visibleLen(s) <= width {
|
||||
return s
|
||||
}
|
||||
var b strings.Builder
|
||||
n := 0
|
||||
for _, r := range s {
|
||||
if n >= width {
|
||||
break
|
||||
}
|
||||
b.WriteRune(r)
|
||||
n++
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
Reference in New Issue
Block a user