|
|
|
@ -285,6 +285,18 @@ type Table struct {
@@ -285,6 +285,18 @@ type Table struct {
|
|
|
|
|
// If set to true, the table's last row will always be visible.
|
|
|
|
|
trackEnd bool |
|
|
|
|
|
|
|
|
|
// The sort function of the table. Defaults to a case-sensitive string comparison.
|
|
|
|
|
sortFunc func(column, i, j int) bool |
|
|
|
|
|
|
|
|
|
// Whether or not the table should be sorted when a fixed row is clicked.
|
|
|
|
|
sortClicked bool |
|
|
|
|
|
|
|
|
|
// The last direction the table was sorted by when clicked.
|
|
|
|
|
sortClickedDescending bool |
|
|
|
|
|
|
|
|
|
// The last column the table was sorted by when clicked.
|
|
|
|
|
sortClickedColumn int |
|
|
|
|
|
|
|
|
|
// The number of visible rows the last time the table was drawn.
|
|
|
|
|
visibleRows int |
|
|
|
|
|
|
|
|
@ -330,6 +342,7 @@ func NewTable() *Table {
@@ -330,6 +342,7 @@ func NewTable() *Table {
|
|
|
|
|
scrollBarColor: Styles.ScrollBarColor, |
|
|
|
|
bordersColor: Styles.GraphicsColor, |
|
|
|
|
separator: ' ', |
|
|
|
|
sortClicked: true, |
|
|
|
|
lastColumn: -1, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -706,7 +719,7 @@ func (t *Table) cellAt(x, y int) (row, column int) {
@@ -706,7 +719,7 @@ func (t *Table) cellAt(x, y int) (row, column int) {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Saerch for the clicked column.
|
|
|
|
|
// Search for the clicked column.
|
|
|
|
|
column = -1 |
|
|
|
|
if x >= rectX { |
|
|
|
|
columnX := rectX |
|
|
|
@ -752,6 +765,59 @@ func (t *Table) ScrollToEnd() *Table {
@@ -752,6 +765,59 @@ func (t *Table) ScrollToEnd() *Table {
|
|
|
|
|
return t |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// SetSortClicked sets a flag which determines whether the table is sorted when
|
|
|
|
|
// a fixed row is clicked. This flag is enabled by default.
|
|
|
|
|
func (t *Table) SetSortClicked(sortClicked bool) *Table { |
|
|
|
|
t.Lock() |
|
|
|
|
defer t.Unlock() |
|
|
|
|
|
|
|
|
|
t.sortClicked = sortClicked |
|
|
|
|
return t |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// SetSortFunc sets the sorting function used for the table. When unset, a
|
|
|
|
|
// case-sensitive string comparison is used.
|
|
|
|
|
func (t *Table) SetSortFunc(sortFunc func(column, i, j int) bool) *Table { |
|
|
|
|
t.Lock() |
|
|
|
|
defer t.Unlock() |
|
|
|
|
|
|
|
|
|
t.sortFunc = sortFunc |
|
|
|
|
return t |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Sort sorts the table by the column at the given index. You may set a custom
|
|
|
|
|
// sorting function with SetSortFunc.
|
|
|
|
|
func (t *Table) Sort(column int, descending bool) *Table { |
|
|
|
|
t.Lock() |
|
|
|
|
defer t.Unlock() |
|
|
|
|
|
|
|
|
|
if len(t.cells) == 0 || column < 0 || column >= len(t.cells[0]) { |
|
|
|
|
return t |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if t.sortFunc == nil { |
|
|
|
|
t.sortFunc = func(column, i, j int) bool { |
|
|
|
|
return t.cells[i][column].Text < t.cells[j][column].Text |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sort.SliceStable(t.cells, func(i, j int) bool { |
|
|
|
|
if i < t.fixedRows { |
|
|
|
|
return i < j |
|
|
|
|
} else if j < t.fixedRows { |
|
|
|
|
return j > i |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if !descending { |
|
|
|
|
return t.sortFunc(column, i, j) |
|
|
|
|
} else { |
|
|
|
|
return t.sortFunc(column, j, i) |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
return t |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Draw draws this primitive onto the screen.
|
|
|
|
|
func (t *Table) Draw(screen tcell.Screen) { |
|
|
|
|
t.Box.Draw(screen) |
|
|
|
@ -1424,9 +1490,31 @@ func (t *Table) MouseHandler() func(action MouseAction, event *tcell.EventMouse,
@@ -1424,9 +1490,31 @@ func (t *Table) MouseHandler() func(action MouseAction, event *tcell.EventMouse,
|
|
|
|
|
|
|
|
|
|
switch action { |
|
|
|
|
case MouseLeftClick: |
|
|
|
|
if t.rowsSelectable || t.columnsSelectable { |
|
|
|
|
_, tableY, _, _ := t.GetInnerRect() |
|
|
|
|
mul := 1 |
|
|
|
|
maxY := tableY |
|
|
|
|
if t.borders { |
|
|
|
|
mul = 2 |
|
|
|
|
maxY = tableY + 1 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if t.sortClicked && t.fixedRows > 0 && (y >= tableY && y < maxY+(t.fixedRows*mul)) { |
|
|
|
|
_, column := t.cellAt(x, y) |
|
|
|
|
if t.sortClickedColumn != column { |
|
|
|
|
t.sortClickedColumn = column |
|
|
|
|
t.sortClickedDescending = false |
|
|
|
|
} else { |
|
|
|
|
t.sortClickedDescending = !t.sortClickedDescending |
|
|
|
|
} |
|
|
|
|
t.Sort(column, t.sortClickedDescending) |
|
|
|
|
|
|
|
|
|
if t.columnsSelectable { |
|
|
|
|
t.selectedColumn = column |
|
|
|
|
} |
|
|
|
|
} else if t.rowsSelectable || t.columnsSelectable { |
|
|
|
|
t.Select(t.cellAt(x, y)) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
consumed = true |
|
|
|
|
setFocus(t) |
|
|
|
|
case MouseScrollUp: |
|
|
|
|