Added expansion factor to table cells which grows columns if there is more space than needed. Resolves #62

This commit is contained in:
Oliver 2018-03-05 14:07:18 +01:00
parent a3971dc430
commit 8cb36ea743
2 changed files with 60 additions and 8 deletions

View File

@ -265,12 +265,14 @@ func Table(nextSlide func()) (title string, content tview.Primitive) {
} else if column == 0 || column >= 4 { } else if column == 0 || column >= 4 {
align = tview.AlignRight align = tview.AlignRight
} }
table.SetCell(row, column, &tview.TableCell{ tableCell := tview.NewTableCell(cell).
Text: cell, SetTextColor(color).
Color: color, SetAlign(align).
Align: align, SetSelectable(row != 0 && column != 0)
NotSelectable: row == 0 || column == 0, if column >= 1 && column <= 3 {
}) tableCell.SetExpansion(1)
}
table.SetCell(row, column, tableCell)
} }
} }
table.SetBorder(true).SetTitle("Table") table.SetBorder(true).SetTitle("Table")

View File

@ -23,6 +23,10 @@ type TableCell struct {
// is cut off. Set to 0 if there is no maximum width. // is cut off. Set to 0 if there is no maximum width.
MaxWidth int MaxWidth int
// If the total table width is less than the available width, this value is
// used to add extra width to a column. See SetExpansion() for details.
Expansion int
// The color of the cell text. // The color of the cell text.
Color tcell.Color Color tcell.Color
@ -69,6 +73,27 @@ func (c *TableCell) SetMaxWidth(maxWidth int) *TableCell {
return c return c
} }
// SetExpansion sets the value by which the column of this cell expands if the
// available width for the table is more than the table width (prior to applying
// this expansion value). This is a proportional value. The amount of unused
// horizontal space is divided into widths to be added to each column. How much
// extra width a column receives depends on the expansion value: A value of 0
// (the default) will not cause the column to increase in width. Other values
// are proportional, e.g. a value of 2 will cause a column to grow by twice
// the amount of a column with a value of 1.
//
// Since this value affects an entire column, the maximum over all visible cells
// in that column is used.
//
// This function panics if a negative value is provided.
func (c *TableCell) SetExpansion(expansion int) *TableCell {
if expansion < 0 {
panic("Table cell expansion values may not be negative")
}
c.Expansion = expansion
return c
}
// SetTextColor sets the cell's text color. // SetTextColor sets the cell's text color.
func (c *TableCell) SetTextColor(color tcell.Color) *TableCell { func (c *TableCell) SetTextColor(color tcell.Color) *TableCell {
c.Color = color c.Color = color
@ -525,7 +550,10 @@ func (t *Table) Draw(screen tcell.Screen) {
break break
} }
} }
var skipped, lastTableWidth int var (
skipped, lastTableWidth, expansionTotal int
expansions []int
)
ColumnLoop: ColumnLoop:
for column := 0; ; column++ { for column := 0; ; column++ {
// If we've moved beyond the right border, we stop or skip a column. // If we've moved beyond the right border, we stop or skip a column.
@ -556,8 +584,9 @@ ColumnLoop:
widths = append(widths[:t.fixedColumns], widths[t.fixedColumns+1:]...) widths = append(widths[:t.fixedColumns], widths[t.fixedColumns+1:]...)
} }
// What's this column's width? // What's this column's width (without expansion)?
maxWidth := -1 maxWidth := -1
expansion := 0
for _, row := range rows { for _, row := range rows {
if cell := getCell(row, column); cell != nil { if cell := getCell(row, column); cell != nil {
cellWidth := StringWidth(cell.Text) cellWidth := StringWidth(cell.Text)
@ -567,6 +596,9 @@ ColumnLoop:
if cellWidth > maxWidth { if cellWidth > maxWidth {
maxWidth = cellWidth maxWidth = cellWidth
} }
if cell.Expansion > expansion {
expansion = cell.Expansion
}
} }
} }
if maxWidth < 0 { if maxWidth < 0 {
@ -578,9 +610,27 @@ ColumnLoop:
widths = append(widths, maxWidth) widths = append(widths, maxWidth)
lastTableWidth = tableWidth lastTableWidth = tableWidth
tableWidth += maxWidth + 1 tableWidth += maxWidth + 1
expansions = append(expansions, expansion)
expansionTotal += expansion
} }
t.columnOffset = skipped t.columnOffset = skipped
// If we have space left, distribute it.
if tableWidth < width {
toDistribute := width - tableWidth
for index := range widths {
if expansionTotal <= 0 {
break
}
expansion := expansions[index]
expWidth := toDistribute * expansion / expansionTotal
widths[index] += expWidth
tableWidth += expWidth
toDistribute -= expWidth
expansionTotal -= expansion
}
}
// Helper function which draws border runes. // Helper function which draws border runes.
borderStyle := tcell.StyleDefault.Background(t.backgroundColor).Foreground(t.bordersColor) borderStyle := tcell.StyleDefault.Background(t.backgroundColor).Foreground(t.bordersColor)
drawBorder := func(colX, rowY int, ch rune) { drawBorder := func(colX, rowY int, ch rune) {