1
0
mirror of https://github.com/gdamore/tcell.git synced 2025-04-24 13:48:51 +08:00

TextArea: use [][]rune instead of []string in linesModel

This way GetCell() will get full runes, not just bytes. Now accent characters will show properly

Adjust SetLines() and Init() to work on [][]rune instead of []string
This commit is contained in:
VÖRÖSKŐI András 2020-04-12 21:17:06 +02:00 committed by Garrett D'Amore
parent 8572f72a22
commit 1f1f979c1b

View File

@ -33,7 +33,7 @@ type TextArea struct {
} }
type linesModel struct { type linesModel struct {
lines []string runes [][]rune
width int width int
height int height int
x int x int
@ -44,12 +44,11 @@ type linesModel struct {
} }
func (m *linesModel) GetCell(x, y int) (rune, tcell.Style, []rune, int) { func (m *linesModel) GetCell(x, y int) (rune, tcell.Style, []rune, int) {
var ch rune if x < 0 || y < 0 || y >= m.height || x >= len(m.runes[y]) {
if x < 0 || y < 0 || y >= len(m.lines) || x >= len(m.lines[y]) { return 0, m.style, nil, 1
return ch, m.style, nil, 1
} }
// XXX: extend this to support combining and full width chars // XXX: extend this to support combining and full width chars
return rune(m.lines[y][x]), m.style, nil, 1 return m.runes[y][x], m.style, nil, 1
} }
func (m *linesModel) GetBounds() (int, int) { func (m *linesModel) GetBounds() (int, int) {
@ -91,14 +90,22 @@ func (m *linesModel) GetCursor() (int, int, bool, bool) {
func (ta *TextArea) SetLines(lines []string) { func (ta *TextArea) SetLines(lines []string) {
ta.Init() ta.Init()
m := ta.model m := ta.model
m.width = 0
m.height = len(lines) // extend slice before using m.runes[row] to avoid panic
m.lines = append([]string{}, lines...) slice := make([][]rune, len(lines))
for _, l := range lines { m.runes = append(m.runes, slice...)
if len(l) > m.width {
m.width = len(l) for row, line := range lines {
for _, ch := range line {
m.runes[row] = append(m.runes[row], ch)
}
if len(m.runes[row]) > m.width {
m.width = len(m.runes[row])
} }
} }
m.height = len(m.runes)
ta.CellView.SetModel(m) ta.CellView.SetModel(m)
} }
@ -132,7 +139,7 @@ func (ta *TextArea) SetContent(text string) {
// Init initializes the TextArea. // Init initializes the TextArea.
func (ta *TextArea) Init() { func (ta *TextArea) Init() {
ta.once.Do(func() { ta.once.Do(func() {
lm := &linesModel{lines: []string{}, width: 0} lm := &linesModel{runes: [][]rune{}, width: 0}
ta.model = lm ta.model = lm
ta.CellView.Init() ta.CellView.Init()
ta.CellView.SetModel(lm) ta.CellView.SetModel(lm)