diff --git a/widget/list.go b/widget/list.go index 872e8b4022..daf34038c4 100644 --- a/widget/list.go +++ b/widget/list.go @@ -37,6 +37,11 @@ type List struct { UpdateItem func(id ListItemID, item fyne.CanvasObject) `json:"-"` OnSelected func(id ListItemID) `json:"-"` OnUnselected func(id ListItemID) `json:"-"` + // OnFocused fire an event when a listItem is focused + // Whenever the list loses focus ListItemId will be equals to -1 + // + // Since: 2.6 + OnFocused func(id ListItemID) `json:"-"` // HideSeparators hides the separators between list rows // @@ -107,6 +112,7 @@ func (l *List) FocusGained() { l.focused = true l.scrollTo(l.currentFocus) l.RefreshItem(l.currentFocus) + l.onFocused(l.currentFocus) } // FocusLost is called after this List has lost focus. @@ -114,6 +120,7 @@ func (l *List) FocusGained() { // Implements: fyne.Focusable func (l *List) FocusLost() { l.focused = false + l.onFocused(-1) l.RefreshItem(l.currentFocus) } @@ -305,6 +312,7 @@ func (l *List) TypedKey(event *fyne.KeyEvent) { } l.RefreshItem(l.currentFocus) l.currentFocus++ + l.onFocused(l.currentFocus) l.scrollTo(l.currentFocus) l.RefreshItem(l.currentFocus) case fyne.KeyUp: @@ -313,6 +321,7 @@ func (l *List) TypedKey(event *fyne.KeyEvent) { } l.RefreshItem(l.currentFocus) l.currentFocus-- + l.onFocused(l.currentFocus) l.scrollTo(l.currentFocus) l.RefreshItem(l.currentFocus) } @@ -859,3 +868,9 @@ func createItemAndApplyThemeScope(f func() fyne.CanvasObject, scope fyne.Widget) item.Refresh() return item } + +func (l *List) onFocused(id ListItemID) { + if f := l.OnFocused; f != nil { + f(id) + } +} diff --git a/widget/list_test.go b/widget/list_test.go index 45cd0edbce..27e43cc822 100644 --- a/widget/list_test.go +++ b/widget/list_test.go @@ -75,6 +75,30 @@ func TestList_Resize(t *testing.T) { assert.True(t, resizeCountAllGreaterOrEqual) } +func TestList_OnFocused(t *testing.T) { + l, _, rows := setupList(t) + var selectedId widget.ListItemID + l.OnFocused = func(id widget.ListItemID) { + selectedId = id + } + l.FocusGained() + assert.Equal(t, selectedId, 0) + l.FocusLost() + assert.Equal(t, selectedId, -1) + l.TypedKey(&fyne.KeyEvent{Name: fyne.KeyDown}) + assert.Equal(t, selectedId, 1) + l.TypedKey(&fyne.KeyEvent{Name: fyne.KeyUp}) + assert.Equal(t, selectedId, 0) + for index, _ := range rows { + l.TypedKey(&fyne.KeyEvent{Name: fyne.KeyDown}) + assert.Equal(t, selectedId, index+1) + } + for index, _ := range rows { + l.TypedKey(&fyne.KeyEvent{Name: fyne.KeyUp}) + assert.Equal(t, selectedId, len(rows)-(index+1)) + } +} + func setupList(t *testing.T) (*widget.List, fyne.Window, []*resizeRefreshCountingLabel) { var rows []*resizeRefreshCountingLabel test.NewTempApp(t)