Added individual styling for selected table cells. Resolves #934

This commit is contained in:
Oliver 2024-04-06 16:14:10 +02:00
parent dfc1d8680f
commit 79d4cc3212
3 changed files with 78 additions and 30 deletions

View File

@ -679,7 +679,7 @@ func (a *Application) draw() *Application {
}
// Resize if requested.
if fullscreen && root != nil {
if fullscreen { // root is not nil here.
width, height := screen.Size()
root.SetRect(0, 0, width, height)
}

8
box.go
View File

@ -437,8 +437,8 @@ func (b *Box) DrawForSubclass(screen tcell.Screen, p Primitive) {
}
// SetFocusFunc sets a callback function which is invoked when this primitive
// receives focus. Container primitives such as Flex or Grid may not be notified
// if one of their descendents receive focus directly.
// receives focus. Container primitives such as [Flex] or [Grid] may not be
// notified if one of their descendents receive focus directly.
//
// Set to nil to remove the callback function.
func (b *Box) SetFocusFunc(callback func()) *Box {
@ -447,8 +447,8 @@ func (b *Box) SetFocusFunc(callback func()) *Box {
}
// SetBlurFunc sets a callback function which is invoked when this primitive
// loses focus. This does not apply to container primitives such as Flex or
// Grid.
// loses focus. This does not apply to container primitives such as [Flex] or
// [Grid].
//
// Set to nil to remove the callback function.
func (b *Box) SetBlurFunc(callback func()) *Box {

View File

@ -30,19 +30,32 @@ type TableCell struct {
// 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. You should not use this anymore, it is only
// here for backwards compatibility. Use the Style field instead.
Color tcell.Color
// The background color of the cell.
// The background color of the cell. You should not use this anymore, it is
// only here for backwards compatibility. Use the Style field instead.
BackgroundColor tcell.Color
// The style attributes of the cell. You should not use this anymore, it is
// only here for backwards compatibility. Use the Style field instead.
Attributes tcell.AttrMask
// The style of the cell. If this is uninitialized (tcell.StyleDefault), the
// Color and BackgroundColor fields are used instead.
Style tcell.Style
// The style of the cell when it is selected. If this is uninitialized
// (tcell.StyleDefault), the table's selected style is used instead. If that
// is uninitialized as well, the cell's background and text color are
// swapped.
SelectedStyle tcell.Style
// If set to true, the BackgroundColor is not used and the cell will have
// the background color of the table.
Transparent bool
// The style attributes of the cell.
Attributes tcell.AttrMask
// If set to true, this cell cannot be selected.
NotSelectable bool
@ -60,11 +73,10 @@ type TableCell struct {
// background (using the background of the Table).
func NewTableCell(text string) *TableCell {
return &TableCell{
Text: text,
Align: AlignLeft,
Color: Styles.PrimaryTextColor,
BackgroundColor: Styles.PrimitiveBackgroundColor,
Transparent: true,
Text: text,
Align: AlignLeft,
Style: tcell.StyleDefault.Foreground(Styles.PrimaryTextColor).Background(Styles.PrimitiveBackgroundColor),
Transparent: true,
}
}
@ -112,14 +124,22 @@ func (c *TableCell) SetExpansion(expansion int) *TableCell {
// SetTextColor sets the cell's text color.
func (c *TableCell) SetTextColor(color tcell.Color) *TableCell {
c.Color = color
if c.Style == tcell.StyleDefault {
c.Color = color
} else {
c.Style = c.Style.Foreground(color)
}
return c
}
// SetBackgroundColor sets the cell's background color. This will also cause the
// cell's Transparent flag to be set to "false".
func (c *TableCell) SetBackgroundColor(color tcell.Color) *TableCell {
c.BackgroundColor = color
if c.Style == tcell.StyleDefault {
c.BackgroundColor = color
} else {
c.Style = c.Style.Background(color)
}
c.Transparent = false
return c
}
@ -137,14 +157,27 @@ func (c *TableCell) SetTransparency(transparent bool) *TableCell {
//
// cell.SetAttributes(tcell.AttrUnderline | tcell.AttrBold)
func (c *TableCell) SetAttributes(attr tcell.AttrMask) *TableCell {
c.Attributes = attr
if c.Style == tcell.StyleDefault {
c.Attributes = attr
} else {
c.Style = c.Style.Attributes(attr)
}
return c
}
// SetStyle sets the cell's style (foreground color, background color, and
// attributes) all at once.
func (c *TableCell) SetStyle(style tcell.Style) *TableCell {
c.Color, c.BackgroundColor, c.Attributes = style.Decompose()
c.Style = style
return c
}
// SetSelectedStyle sets the cell's style when it is selected. If this is
// uninitialized (tcell.StyleDefault), the table's selected style is used
// instead. If that is uninitialized as well, the cell's background and text
// color are swapped.
func (c *TableCell) SetSelectedStyle(style tcell.Style) *TableCell {
c.SelectedStyle = style
return c
}
@ -549,12 +582,12 @@ func (t *Table) SetBordersColor(color tcell.Color) *Table {
}
// 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).
// is set, the cell's background and text color are swapped. If a cell defines
// its own selected style, that will be used instead.
//
// To reset a previous setting to its default, make the following call:
//
// table.SetSelectedStyle(tcell.Style{})
// table.SetSelectedStyle(tcell.StyleDefault)
func (t *Table) SetSelectedStyle(style tcell.Style) *Table {
t.selectedStyle = style
return t
@ -1157,7 +1190,11 @@ func (t *Table) Draw(screen tcell.Screen) {
finalWidth = width - columnX
}
cell.x, cell.y, cell.width = x+columnX, y+rowY, finalWidth
start, end, _ := printWithStyle(screen, cell.Text, x+columnX, y+rowY, 0, finalWidth, cell.Align, tcell.StyleDefault.Foreground(cell.Color).Attributes(cell.Attributes), true)
style := cell.Style
if style == tcell.StyleDefault {
style = tcell.StyleDefault.Background(cell.BackgroundColor).Foreground(cell.Color).Attributes(cell.Attributes)
}
start, end, _ := printWithStyle(screen, cell.Text, x+columnX, y+rowY, 0, finalWidth, cell.Align, style, true)
printed := end - start
if TaggedStringWidth(cell.Text)-printed > 0 && printed > 0 {
_, _, style, _ := screen.GetContent(x+columnX+finalWidth-1, y+rowY)
@ -1272,8 +1309,12 @@ func (t *Table) Draw(screen tcell.Screen) {
}
columnSelected := t.columnsSelectable && !t.rowsSelectable && column == t.selectedColumn
cellSelected := !cell.NotSelectable && (columnSelected || rowSelected || t.rowsSelectable && t.columnsSelectable && column == t.selectedColumn && row == t.selectedRow)
entries, ok := cellsByBackgroundColor[cell.BackgroundColor]
cellsByBackgroundColor[cell.BackgroundColor] = append(entries, &cellInfo{
backgroundColor := cell.BackgroundColor
if cell.Style != tcell.StyleDefault {
_, backgroundColor, _ = cell.Style.Decompose()
}
entries, ok := cellsByBackgroundColor[backgroundColor]
cellsByBackgroundColor[backgroundColor] = append(entries, &cellInfo{
x: bx,
y: by,
w: bw,
@ -1282,7 +1323,7 @@ func (t *Table) Draw(screen tcell.Screen) {
selected: cellSelected,
})
if !ok {
backgroundColors = append(backgroundColors, cell.BackgroundColor)
backgroundColors = append(backgroundColors, backgroundColor)
}
columnX += columnWidth + 1
}
@ -1297,18 +1338,25 @@ func (t *Table) Draw(screen tcell.Screen) {
_, _, lj := c.Hcl()
return li < lj
})
selFg, selBg, selAttr := t.selectedStyle.Decompose()
for _, bgColor := range backgroundColors {
entries := cellsByBackgroundColor[bgColor]
for _, info := range entries {
textColor := info.cell.Color
if info.cell.Style != tcell.StyleDefault {
textColor, _, _ = info.cell.Style.Decompose()
}
if info.selected {
if t.selectedStyle != (tcell.Style{}) {
if info.cell.SelectedStyle != tcell.StyleDefault {
selFg, selBg, selAttr := info.cell.SelectedStyle.Decompose()
defer colorBackground(info.x, info.y, info.w, info.h, selBg, selFg, false, false, selAttr, false)
} else if t.selectedStyle != tcell.StyleDefault {
selFg, selBg, selAttr := t.selectedStyle.Decompose()
defer colorBackground(info.x, info.y, info.w, info.h, selBg, selFg, false, false, selAttr, false)
} else {
defer colorBackground(info.x, info.y, info.w, info.h, bgColor, info.cell.Color, false, false, 0, true)
defer colorBackground(info.x, info.y, info.w, info.h, bgColor, textColor, false, false, 0, true)
}
} else {
colorBackground(info.x, info.y, info.w, info.h, bgColor, info.cell.Color, info.cell.Transparent, true, 0, false)
colorBackground(info.x, info.y, info.w, info.h, bgColor, textColor, info.cell.Transparent, true, 0, false)
}
}
}