Add Table.Sort, Table.SetSortFunc and Table.SetSortClicked

Resolves #33.
This commit is contained in:
Trevor Slocum 2020-09-01 15:44:43 -07:00
parent 2ebdbde722
commit f35f86924a
2 changed files with 91 additions and 2 deletions

View File

@ -1,5 +1,6 @@
v1.4.9 (WIP)
- Add InputField.GetCursorPosition and InputField.SetCursorPosition
- Add Table.Sort, Table.SetSortFunc and Table.SetSortClicked
- Upgrade tcell to v2: includes strikethrough support
v1.4.8 (2020-08-11)

View File

@ -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 {
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) {
}
}
// 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 {
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,
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: