diff --git a/buffer.go b/buffer.go index 2c33a1d..ac22934 100644 --- a/buffer.go +++ b/buffer.go @@ -6,6 +6,8 @@ package termui import ( "image" + + rw "github.com/mattn/go-runewidth" ) // Cell represents a viewable terminal cell @@ -65,7 +67,10 @@ func (self *Buffer) Fill(c Cell, rect image.Rectangle) { } func (self *Buffer) SetString(s string, style Style, p image.Point) { - for i, char := range s { - self.SetCell(Cell{char, style}, image.Pt(p.X+i, p.Y)) + runes := []rune(s) + x := 0 + for _, char := range runes { + self.SetCell(Cell{char, style}, image.Pt(p.X+x, p.Y)) + x += rw.RuneWidth(char) } } diff --git a/utils.go b/utils.go index f780451..e53d531 100644 --- a/utils.go +++ b/utils.go @@ -189,8 +189,9 @@ func CellsToString(cells []Cell) string { func TrimCells(cells []Cell, w int) []Cell { s := CellsToString(cells) s = TrimString(s, w) + runes := []rune(s) newCells := []Cell{} - for i, r := range s { + for i, r := range runes { newCells = append(newCells, Cell{r, cells[i].Style}) } return newCells @@ -212,3 +213,18 @@ func SplitCells(cells []Cell, r rune) [][]Cell { } return splitCells } + +type CellWithX struct { + X int + Cell Cell +} + +func BuildCellWithXArray(cells []Cell) []CellWithX { + cellWithXArray := make([]CellWithX, len(cells)) + index := 0 + for i, cell := range cells { + cellWithXArray[i] = CellWithX{X: index, Cell: cell} + index += rw.RuneWidth(cell.Rune) + } + return cellWithXArray +} diff --git a/widgets/list.go b/widgets/list.go index 4e6c463..f85bbad 100644 --- a/widgets/list.go +++ b/widgets/list.go @@ -7,6 +7,8 @@ package widgets import ( "image" + rw "github.com/mattn/go-runewidth" + . "github.com/gizak/termui" ) @@ -57,7 +59,7 @@ func (self *List) Draw(buf *Buffer) { break } else { buf.SetCell(NewCell(cells[j].Rune, style), point) - point = point.Add(image.Pt(1, 0)) + point = point.Add(image.Pt(rw.RuneWidth(cells[j].Rune), 0)) } } } diff --git a/widgets/paragraph.go b/widgets/paragraph.go index 9498f16..7eb56bd 100644 --- a/widgets/paragraph.go +++ b/widgets/paragraph.go @@ -40,7 +40,8 @@ func (self *Paragraph) Draw(buf *Buffer) { break } row = TrimCells(row, self.Inner.Dx()) - for x, cell := range row { + for _, cx := range BuildCellWithXArray(row) { + x, cell := cx.X, cx.Cell buf.SetCell(cell, image.Pt(x, y).Add(self.Inner.Min)) } } diff --git a/widgets/table.go b/widgets/table.go index 14f58ef..6095954 100644 --- a/widgets/table.go +++ b/widgets/table.go @@ -74,7 +74,8 @@ func (self *Table) Draw(buf *Buffer) { col := ParseText(row[j], rowStyle) // draw row cell if len(col) > columnWidths[j] || self.TextAlign == AlignLeft { - for k, cell := range col { + for _, cx := range BuildCellWithXArray(col) { + k, cell := cx.X, cx.Cell if k == columnWidths[j] || colXCoordinate+k == self.Inner.Max.X { cell.Rune = ELLIPSES buf.SetCell(cell, image.Pt(colXCoordinate+k-1, yCoordinate)) @@ -86,12 +87,14 @@ func (self *Table) Draw(buf *Buffer) { } else if self.TextAlign == AlignCenter { xCoordinateOffset := (columnWidths[j] - len(col)) / 2 stringXCoordinate := xCoordinateOffset + colXCoordinate - for k, cell := range col { + for _, cx := range BuildCellWithXArray(col) { + k, cell := cx.X, cx.Cell buf.SetCell(cell, image.Pt(stringXCoordinate+k, yCoordinate)) } } else if self.TextAlign == AlignRight { stringXCoordinate := MinInt(colXCoordinate+columnWidths[j], self.Inner.Max.X) - len(col) - for k, cell := range col { + for _, cx := range BuildCellWithXArray(col) { + k, cell := cx.X, cx.Cell buf.SetCell(cell, image.Pt(stringXCoordinate+k, yCoordinate)) } }