1
0
mirror of https://github.com/rivo/tview.git synced 2025-04-28 13:48:53 +08:00

Added custom higlight styles to Table. Resolves #154

This commit is contained in:
Oliver 2018-09-05 10:39:21 +02:00
parent 77bcb6c6b9
commit 00de4610ae
2 changed files with 47 additions and 18 deletions

View File

@ -124,9 +124,9 @@ func (c *Checkbox) SetChangedFunc(handler func(checked bool)) *Checkbox {
return c return c
} }
// SetDoneFunc sets a handler which is called when the user is done entering // SetDoneFunc sets a handler which is called when the user is done using the
// text. The callback function is provided with the key that was pressed, which // checkbox. The callback function is provided with the key that was pressed,
// is one of the following: // which is one of the following:
// //
// - KeyEscape: Abort text input. // - KeyEscape: Abort text input.
// - KeyTab: Move to the next field. // - KeyTab: Move to the next field.

View File

@ -231,6 +231,10 @@ type Table struct {
// The number of visible rows the last time the table was drawn. // The number of visible rows the last time the table was drawn.
visibleRows int visibleRows int
// The style of the selected rows. If this value is 0, selected rows are
// simply inverted.
selectedStyle tcell.Style
// An optional function which gets called when the user presses Enter on a // An optional function which gets called when the user presses Enter on a
// selected cell. If entire rows selected, the column value is undefined. // selected cell. If entire rows selected, the column value is undefined.
// Likewise for entire columns. // Likewise for entire columns.
@ -276,6 +280,18 @@ func (t *Table) SetBordersColor(color tcell.Color) *Table {
return t return t
} }
// SetSelectedStyle sets a specific style for selected cells. If no such style
// is set, per default, selected cells are inverted (i.e. their foreground and
// background colors are swapped).
//
// To reset a previous setting to its default, make the following call:
//
// table.SetSelectedStyle(tcell.ColorDefault, tcell.ColorDefault, 0)
func (t *Table) SetSelectedStyle(foregroundColor, backgroundColor tcell.Color, attributes tcell.AttrMask) *Table {
t.selectedStyle = tcell.StyleDefault.Foreground(foregroundColor).Background(backgroundColor) | tcell.Style(attributes)
return t
}
// SetSeparator sets the character used to fill the space between two // SetSeparator sets the character used to fill the space between two
// neighboring cells. This is a space character ' ' per default but you may // neighboring cells. This is a space character ' ' per default but you may
// want to set it to Borders.Vertical (or any other rune) if the column // want to set it to Borders.Vertical (or any other rune) if the column
@ -743,12 +759,17 @@ ColumnLoop:
} }
// Helper function which colors the background of a box. // Helper function which colors the background of a box.
colorBackground := func(fromX, fromY, w, h int, backgroundColor, textColor tcell.Color, selected bool) { // backgroundColor == tcell.ColorDefault => Don't color the background.
// textColor == tcell.ColorDefault => Don't change the text color.
// attr == 0 => Don't change attributes.
// invert == true => Ignore attr, set text to backgroundColor or t.backgroundColor;
// set background to textColor.
colorBackground := func(fromX, fromY, w, h int, backgroundColor, textColor tcell.Color, attr tcell.AttrMask, invert bool) {
for by := 0; by < h && fromY+by < y+height; by++ { for by := 0; by < h && fromY+by < y+height; by++ {
for bx := 0; bx < w && fromX+bx < x+width; bx++ { for bx := 0; bx < w && fromX+bx < x+width; bx++ {
m, c, style, _ := screen.GetContent(fromX+bx, fromY+by) m, c, style, _ := screen.GetContent(fromX+bx, fromY+by)
if selected { fg, bg, a := style.Decompose()
fg, _, _ := style.Decompose() if invert {
if fg == textColor || fg == t.bordersColor { if fg == textColor || fg == t.bordersColor {
fg = backgroundColor fg = backgroundColor
} }
@ -757,10 +778,16 @@ ColumnLoop:
} }
style = style.Background(textColor).Foreground(fg) style = style.Background(textColor).Foreground(fg)
} else { } else {
if backgroundColor == tcell.ColorDefault { if backgroundColor != tcell.ColorDefault {
continue bg = backgroundColor
} }
style = style.Background(backgroundColor) if textColor != tcell.ColorDefault {
fg = textColor
}
if attr != 0 {
a = attr
}
style = style.Background(bg).Foreground(fg) | tcell.Style(a)
} }
screen.SetContent(fromX+bx, fromY+by, m, c, style) screen.SetContent(fromX+bx, fromY+by, m, c, style)
} }
@ -769,11 +796,12 @@ ColumnLoop:
// Color the cell backgrounds. To avoid undesirable artefacts, we combine // Color the cell backgrounds. To avoid undesirable artefacts, we combine
// the drawing of a cell by background color, selected cells last. // the drawing of a cell by background color, selected cells last.
cellsByBackgroundColor := make(map[tcell.Color][]*struct { type cellInfo struct {
x, y, w, h int x, y, w, h int
text tcell.Color text tcell.Color
selected bool selected bool
}) }
cellsByBackgroundColor := make(map[tcell.Color][]*cellInfo)
var backgroundColors []tcell.Color var backgroundColors []tcell.Color
for rowY, row := range rows { for rowY, row := range rows {
columnX := 0 columnX := 0
@ -793,11 +821,7 @@ ColumnLoop:
columnSelected := t.columnsSelectable && !t.rowsSelectable && column == t.selectedColumn columnSelected := t.columnsSelectable && !t.rowsSelectable && column == t.selectedColumn
cellSelected := !cell.NotSelectable && (columnSelected || rowSelected || t.rowsSelectable && t.columnsSelectable && column == t.selectedColumn && row == t.selectedRow) cellSelected := !cell.NotSelectable && (columnSelected || rowSelected || t.rowsSelectable && t.columnsSelectable && column == t.selectedColumn && row == t.selectedRow)
entries, ok := cellsByBackgroundColor[cell.BackgroundColor] entries, ok := cellsByBackgroundColor[cell.BackgroundColor]
cellsByBackgroundColor[cell.BackgroundColor] = append(entries, &struct { cellsByBackgroundColor[cell.BackgroundColor] = append(entries, &cellInfo{
x, y, w, h int
text tcell.Color
selected bool
}{
x: bx, x: bx,
y: by, y: by,
w: bw, w: bw,
@ -821,13 +845,18 @@ ColumnLoop:
_, _, lj := c.Hcl() _, _, lj := c.Hcl()
return li < lj return li < lj
}) })
selFg, selBg, selAttr := t.selectedStyle.Decompose()
for _, bgColor := range backgroundColors { for _, bgColor := range backgroundColors {
entries := cellsByBackgroundColor[bgColor] entries := cellsByBackgroundColor[bgColor]
for _, cell := range entries { for _, cell := range entries {
if cell.selected { if cell.selected {
defer colorBackground(cell.x, cell.y, cell.w, cell.h, bgColor, cell.text, true) if t.selectedStyle != 0 {
defer colorBackground(cell.x, cell.y, cell.w, cell.h, selBg, selFg, selAttr, false)
} else { } else {
colorBackground(cell.x, cell.y, cell.w, cell.h, bgColor, cell.text, false) defer colorBackground(cell.x, cell.y, cell.w, cell.h, bgColor, cell.text, 0, true)
}
} else {
colorBackground(cell.x, cell.y, cell.w, cell.h, bgColor, tcell.ColorDefault, 0, false)
} }
} }
} }