Add WrapText option to Paragraph

This commit is contained in:
Caleb Bassi 2019-01-26 02:47:47 -08:00
parent a5828eb2da
commit 5b78b896c9
5 changed files with 97 additions and 59 deletions

View File

@ -1,8 +1,8 @@
package termui
const (
DOT = '•'
DOTS = '…'
DOT = '•'
ELLIPSES = '…'
)
var (

125
utils.go
View File

@ -30,31 +30,43 @@ func InterfaceSlice(slice interface{}) []interface{} {
return ret
}
func MaxInt(x, y int) int {
if x > y {
return x
}
return y
}
func MinInt(x, y int) int {
if x < y {
return x
}
return y
}
// TrimString trims a string to a max length and adds '…' to the end if it was trimmed.
func TrimString(s string, w int) string {
if w <= 0 {
return ""
}
if rw.StringWidth(s) > w {
return rw.Truncate(s, w, string(DOTS))
return rw.Truncate(s, w, string(ELLIPSES))
}
return s
}
func SelectColor(colors []Color, index int) Color {
return colors[index%len(colors)]
}
func SelectStyle(styles []Style, index int) Style {
return styles[index%len(styles)]
}
// Math ------------------------------------------------------------------------
func SumIntSlice(slice []int) int {
sum := 0
for _, val := range slice {
sum += val
}
return sum
}
func SumFloat64Slice(data []float64) float64 {
sum := 0.0
for _, v := range data {
sum += v
}
return sum
}
func GetMaxIntFromSlice(slice []int) (int, error) {
if len(slice) == 0 {
return 0, fmt.Errorf("cannot get max value from empty slice")
@ -96,42 +108,10 @@ func GetMaxFloat64From2dSlice(slices [][]float64) (float64, error) {
return max, nil
}
func SelectColor(colors []Color, index int) Color {
return colors[index%len(colors)]
}
func SelectStyle(styles []Style, index int) Style {
return styles[index%len(styles)]
}
func CellsToString(cells []Cell) string {
runes := make([]rune, len(cells))
for i, cell := range cells {
runes[i] = cell.Rune
}
return string(runes)
}
func RoundFloat64(x float64) float64 {
return math.Floor(x + 0.5)
}
func SumIntSlice(slice []int) int {
sum := 0
for _, val := range slice {
sum += val
}
return sum
}
func SumFloat64Slice(data []float64) float64 {
sum := 0.0
for _, v := range data {
sum += v
}
return sum
}
func AbsInt(x int) int {
if x >= 0 {
return x
@ -153,6 +133,22 @@ func MaxFloat64(x, y float64) float64 {
return y
}
func MaxInt(x, y int) int {
if x > y {
return x
}
return y
}
func MinInt(x, y int) int {
if x < y {
return x
}
return y
}
// []Cell ----------------------------------------------------------------------
// WrapCells takes []Cell and inserts Cells containing '\n' wherever a linebreak should go.
func WrapCells(cells []Cell, width uint) []Cell {
str := CellsToString(cells)
@ -177,3 +173,38 @@ func RunesToStyledCells(runes []rune, style Style) []Cell {
}
return cells
}
func CellsToString(cells []Cell) string {
runes := make([]rune, len(cells))
for i, cell := range cells {
runes[i] = cell.Rune
}
return string(runes)
}
func TrimCells(cells []Cell, w int) []Cell {
s := CellsToString(cells)
s = TrimString(s, w)
newCells := []Cell{}
for i, r := range s {
newCells = append(newCells, Cell{r, cells[i].Style})
}
return newCells
}
func SplitCells(cells []Cell, r rune) [][]Cell {
splitCells := [][]Cell{}
temp := []Cell{}
for _, cell := range cells {
if cell.Rune == r {
splitCells = append(splitCells, temp)
temp = []Cell{}
} else {
temp = append(temp, cell)
}
}
if len(splitCells) > 0 {
splitCells = append(splitCells, temp)
}
return splitCells
}

View File

@ -39,7 +39,7 @@ func (self *List) Draw(buf *Buffer) {
point = image.Pt(self.Inner.Min.X, point.Y+1)
} else {
if point.X+1 == self.Inner.Max.X+1 && len(cells) > self.Inner.Dx() {
buf.SetCell(NewCell(DOTS, cells[j].Style), point.Add(image.Pt(-1, 0)))
buf.SetCell(NewCell(ELLIPSES, cells[j].Style), point.Add(image.Pt(-1, 0)))
break
} else {
buf.SetCell(cells[j], point)

View File

@ -14,27 +14,34 @@ type Paragraph struct {
Block
Text string
TextStyle Style
WrapText bool
}
func NewParagraph() *Paragraph {
return &Paragraph{
Block: *NewBlock(),
TextStyle: Theme.Paragraph.Text,
WrapText: true,
}
}
func (self *Paragraph) Draw(buf *Buffer) {
self.Block.Draw(buf)
point := self.Inner.Min
cells := WrapCells(ParseText(self.Text, self.TextStyle), uint(self.Inner.Dx()))
cells := ParseText(self.Text, self.TextStyle)
if self.WrapText {
cells = WrapCells(cells, uint(self.Inner.Dx()))
}
for i := 0; i < len(cells) && point.Y < self.Inner.Max.Y; i++ {
if cells[i].Rune == '\n' {
point = image.Pt(self.Inner.Min.X, point.Y+1)
} else {
buf.SetCell(cells[i], point)
point = point.Add(image.Pt(1, 0))
rows := SplitCells(cells, '\n')
for y, row := range rows {
if y+self.Inner.Min.Y >= self.Inner.Max.Y {
break
}
row = TrimCells(row, self.Inner.Dx())
for x, cell := range row {
buf.SetCell(cell, image.Pt(x, y).Add(self.Inner.Min))
}
}
}

View File

@ -61,7 +61,7 @@ func (self *Table) Draw(buf *Buffer) {
if len(col) > columnWidths[j] || self.TextAlign == AlignLeft {
for k, cell := range col {
if k == columnWidths[j] || colXCoordinate+k == self.Inner.Max.X {
cell.Rune = DOTS
cell.Rune = ELLIPSES
buf.SetCell(cell, image.Pt(colXCoordinate+k-1, yCoordinate))
break
} else {