rivo / tview

Terminal UI library with rich, interactive widgets — written in Golang
MIT License
11.17k stars 574 forks source link

Could TableCell.SetClickedFunc callback pass a ref to *TableCell? #871

Closed carpii closed 1 year ago

carpii commented 1 year ago

Issue #470 resulted in TableCell.SetClickedFunc() being added

This allows you to provide a callback fn, when a cell is clicked (even if it is unselectable)

The issue is, the callback provides no way to identify which cell was clicked (and it cannot be retrieved from Table.GetSelection() if the cell is unselectable. Also I suspect this event is triggered before the selection would be updated anyway).

This makes it very difficult to attach a generic click handler to all your header cells - for example if you wanted to install the same callback for all your header cells, then use TableCell.GetReference() to decide how to sort the table

Not sure if I'm missing something, but is there a way to identify the cell which was clicked?

Could the tableCell be passed as a parameter to the callback fn?

digitallyserviced commented 1 year ago

@carpii This is rather simple. Simply supply a handler that has a reference already to the cell.


// the embed way

type MyTableCell struct {
 *tview.TableCell
}

// ... somewhere else
func (mtc *MyTableCell) HandleClicked() {
 mtc.whatever()
 row,col := mtc.GetLastPosition()
}

// somewhere you are setting/supply tablecells
func somewhere(){
 mtc := &MyTableCell{
  TableCell:tview.NewTableCell(),
 }
 mtc.SetClickedFunc(mtc.HandleClicked)
 mytable.SetCell(row, col, mtc.TableCell)
}

Now your method is the handler, it obviously contains the table cell.

// the callback factory way

func getCallBackFor(tc *tview.TableCell)(func () bool){
 return func() bool{
  // i have handle to the tablecell now
  tc.ScratchNuts()
  row,col := tc.GetLastPosition()
 }
}

// define a callback for click
func somewhereelse(){
  tc.SetClickedFunc(getCallbackFor(tc))
}

The callback factory uses a returned function to scope-in the tablecell via the factory function

carpii commented 1 year ago

Good catch, thanks!

Just updating your example, since width is now returned, and callback must return a bool..

func getCallBackFor(tc *tview.TableCell)(func () bool){
    return func() bool{
        // i have handle to the tablecell now
        tc.ScratchNuts()
        row,col,width := tc.GetLastPosition()
        return false
    }
}