Merge branch 'bsdavidson-tableFix'

This commit is contained in:
Zack Guo 2017-01-14 00:58:01 -05:00
commit 40027c172a
1 changed files with 86 additions and 75 deletions

161
table.go
View File

@ -2,9 +2,27 @@ package termui
import "strings" import "strings"
/* /* Table is like:
Awesome Table
Col0 | Col1 | Col2 | Col3 | Col4 | Col5 | Col6 |
Some Item #1 | AAA | 123 | CCCCC | EEEEE | GGGGG | IIIII |
Some Item #2 | BBB | 456 | DDDDD | FFFFF | HHHHH | JJJJJ |
Datapoints are a two dimensional array of strings: [][]string
Example:
data := [][]string{
{"Col0", "Col1", "Col3", "Col4", "Col5", "Col6"},
{"Some Item #1", "AAA", "123", "CCCCC", "EEEEE", "GGGGG", "IIIII"},
{"Some Item #2", "BBB", "456", "DDDDD", "FFFFF", "HHHHH", "JJJJJ"},
}
table := termui.NewTable() table := termui.NewTable()
table.Rows = rows table.Rows = data // type [][]string
table.FgColor = termui.ColorWhite table.FgColor = termui.ColorWhite
table.BgColor = termui.ColorDefault table.BgColor = termui.ColorDefault
table.Height = 7 table.Height = 7
@ -14,6 +32,7 @@ import "strings"
table.Border = true table.Border = true
*/ */
// Table tracks all the attributes of a Table instance
type Table struct { type Table struct {
Block Block
Rows [][]string Rows [][]string
@ -22,22 +41,34 @@ type Table struct {
BgColor Attribute BgColor Attribute
FgColors []Attribute FgColors []Attribute
BgColors []Attribute BgColors []Attribute
Seperator bool Separator bool
TextAlign Align TextAlign Align
} }
// NewTable returns a new Table instance
func NewTable() *Table { func NewTable() *Table {
table := &Table{Block: *NewBlock()} table := &Table{Block: *NewBlock()}
table.FgColor = ColorWhite table.FgColor = ColorWhite
table.BgColor = ColorDefault table.BgColor = ColorDefault
table.Seperator = true table.Separator = true
return table return table
} }
func (table *Table) Analysis() { // CellsWidth calculates the width of a cell array and returns an int
func cellsWidth(cells []Cell) int {
width := 0
for _, c := range cells {
width += c.Width()
}
return width
}
// Analysis generates and returns an array of []Cell that represent all columns in the Table
func (table *Table) Analysis() [][]Cell {
var rowCells [][]Cell
length := len(table.Rows) length := len(table.Rows)
if length < 1 { if length < 1 {
return return rowCells
} }
if len(table.FgColors) == 0 { if len(table.FgColors) == 0 {
@ -47,121 +78,101 @@ func (table *Table) Analysis() {
table.BgColors = make([]Attribute, len(table.Rows)) table.BgColors = make([]Attribute, len(table.Rows))
} }
row_width := len(table.Rows[0]) cellWidths := make([]int, len(table.Rows[0]))
cellWidthes := make([]int, row_width)
for index, row := range table.Rows { for y, row := range table.Rows {
for i, str := range row { if table.FgColors[y] == 0 {
if cellWidthes[i] < len(str) { table.FgColors[y] = table.FgColor
cellWidthes[i] = len(str) }
if table.BgColors[y] == 0 {
table.BgColors[y] = table.BgColor
}
for x, str := range row {
cells := DefaultTxBuilder.Build(str, table.FgColors[y], table.BgColors[y])
cw := cellsWidth(cells)
if cellWidths[x] < cw {
cellWidths[x] = cw
} }
} rowCells = append(rowCells, cells)
if table.FgColors[index] == 0 {
table.FgColors[index] = table.FgColor
}
if table.BgColors[index] == 0 {
table.BgColors[index] = table.BgColor
} }
} }
table.CellWidth = cellWidths
table.CellWidth = cellWidthes return rowCells
//width_sum := 2
//for i, width := range cellWidthes {
// width_sum += (width + 2)
// for u, row := range table.Rows {
// switch table.TextAlign {
// case "right":
// row[i] = fmt.Sprintf(" %*s ", width, table.Rows[u][i])
// case "center":
// word_width := len(table.Rows[u][i])
// offset := (width - word_width) / 2
// row[i] = fmt.Sprintf(" %*s ", width, fmt.Sprintf("%-*s", offset+word_width, table.Rows[u][i]))
// default: // left
// row[i] = fmt.Sprintf(" %-*s ", width, table.Rows[u][i])
// }
// }
//}
//if table.Width == 0 {
// table.Width = width_sum
//}
} }
// SetSize calculates the table size and sets the internal value
func (table *Table) SetSize() { func (table *Table) SetSize() {
length := len(table.Rows) length := len(table.Rows)
if table.Seperator { if table.Separator {
table.Height = length*2 + 1 table.Height = length*2 + 1
} else { } else {
table.Height = length + 2 table.Height = length + 2
} }
table.Width = 2 table.Width = 2
if length != 0 { if length != 0 {
for _, cell_width := range table.CellWidth { for _, cellWidth := range table.CellWidth {
table.Width += cell_width + 3 table.Width += cellWidth + 3
} }
} }
} }
func (table *Table) CalculatePosition(x int, y int, x_coordinate *int, y_coordibate *int, cell_beginning *int) { // CalculatePosition ...
if table.Seperator { func (table *Table) CalculatePosition(x int, y int, coordinateX *int, coordinateY *int, cellStart *int) {
*y_coordibate = table.innerArea.Min.Y + y*2 if table.Separator {
*coordinateY = table.innerArea.Min.Y + y*2
} else { } else {
*y_coordibate = table.innerArea.Min.Y + y *coordinateY = table.innerArea.Min.Y + y
} }
if x == 0 { if x == 0 {
*cell_beginning = table.innerArea.Min.X *cellStart = table.innerArea.Min.X
} else { } else {
*cell_beginning += table.CellWidth[x-1] + 3 *cellStart += table.CellWidth[x-1] + 3
} }
switch table.TextAlign { switch table.TextAlign {
case AlignRight: case AlignRight:
*x_coordinate = *cell_beginning + (table.CellWidth[x] - len(table.Rows[y][x])) + 2 *coordinateX = *cellStart + (table.CellWidth[x] - len(table.Rows[y][x])) + 2
case AlignCenter: case AlignCenter:
*x_coordinate = *cell_beginning + (table.CellWidth[x]-len(table.Rows[y][x]))/2 + 2 *coordinateX = *cellStart + (table.CellWidth[x]-len(table.Rows[y][x]))/2 + 2
default: default:
*x_coordinate = *cell_beginning + 2 *coordinateX = *cellStart + 2
} }
} }
// Buffer ...
func (table *Table) Buffer() Buffer { func (table *Table) Buffer() Buffer {
buffer := table.Block.Buffer() buffer := table.Block.Buffer()
table.Analysis() rowCells := table.Analysis()
pointerX := table.innerArea.Min.X + 2
pointer_x := table.innerArea.Min.X + 2 pointerY := table.innerArea.Min.Y
pointer_y := table.innerArea.Min.Y borderPointerX := table.innerArea.Min.X
border_pointer_x := table.innerArea.Min.X
for y, row := range table.Rows { for y, row := range table.Rows {
for x, cell := range row { for x := range row {
table.CalculatePosition(x, y, &pointer_x, &pointer_y, &border_pointer_x) table.CalculatePosition(x, y, &pointerX, &pointerY, &borderPointerX)
backgraound := DefaultTxBuilder.Build(strings.Repeat(" ", table.CellWidth[x]+3), table.BgColors[y], table.BgColors[y]) background := DefaultTxBuilder.Build(strings.Repeat(" ", table.CellWidth[x]+3), table.BgColors[y], table.BgColors[y])
cells := DefaultTxBuilder.Build(cell, table.FgColors[y], table.BgColors[y]) cells := rowCells[y*len(row)+x]
for i, back := range background {
for i, back := range backgraound { buffer.Set(borderPointerX+i, pointerY, back)
buffer.Set(border_pointer_x+i, pointer_y, back)
} }
coordinate_x := pointer_x coordinateX := pointerX
for _, printer := range cells { for _, printer := range cells {
buffer.Set(coordinate_x, pointer_y, printer) buffer.Set(coordinateX, pointerY, printer)
coordinate_x += printer.Width() coordinateX += printer.Width()
} }
if x != 0 { if x != 0 {
devidors := DefaultTxBuilder.Build("|", table.FgColors[y], table.BgColors[y]) dividors := DefaultTxBuilder.Build("|", table.FgColors[y], table.BgColors[y])
for _, devidor := range devidors { for _, dividor := range dividors {
buffer.Set(border_pointer_x, pointer_y, devidor) buffer.Set(borderPointerX, pointerY, dividor)
} }
} }
} }
if table.Seperator { if table.Separator {
border := DefaultTxBuilder.Build(strings.Repeat("─", table.Width-2), table.FgColor, table.BgColor) border := DefaultTxBuilder.Build(strings.Repeat("─", table.Width-2), table.FgColor, table.BgColor)
for i, cell := range border { for i, cell := range border {
buffer.Set(i+1, pointer_y+1, cell) buffer.Set(i+1, pointerY+1, cell)
} }
} }
} }