Skip to content

Commit

Permalink
Updates #22: add focus arrow key navigation to tracklist
Browse files Browse the repository at this point in the history
  • Loading branch information
dweymouth committed Feb 16, 2024
1 parent 0cc497e commit b97b029
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 6 deletions.
2 changes: 2 additions & 0 deletions ui/widgets/gridviewitem.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ func (g *GridViewItem) TypedKey(e *fyne.KeyEvent) {
focusArg = 3
case fyne.KeyEnter:
fallthrough
case fyne.KeyReturn:
fallthrough
case fyne.KeySpace:
if g.OnShowItemPage != nil {
g.OnShowItemPage()
Expand Down
20 changes: 18 additions & 2 deletions ui/widgets/listrowbase.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ type ListRowBase struct {
Selected bool
Focused bool

OnTapped func()
OnDoubleTapped func()
OnTapped func()
OnDoubleTapped func()
OnFocusNeighbor func(up bool) //TODO: func(up, selecting bool)

tappedAt int64 // unixMillis
focusedRect *canvas.Rectangle
Expand Down Expand Up @@ -57,7 +58,22 @@ func (l *ListRowBase) FocusLost() {
}

func (l *ListRowBase) TypedKey(e *fyne.KeyEvent) {
/**
// TODO: enable shift+arrows for selection, but it's complicated to implement in the widgets
desktop, ok := fyne.CurrentApp().Driver().(desktop.Driver)
isSelecting := func() bool {
return ok && desktop.CurrentKeyModifiers()&fyne.KeyModifierShift != 0
}
*/
switch {
case e.Name == fyne.KeyUp:
if l.OnFocusNeighbor != nil {
l.OnFocusNeighbor(true)
}
case e.Name == fyne.KeyDown:
if l.OnFocusNeighbor != nil {
l.OnFocusNeighbor(false)
}
case e.Name == fyne.KeySpace:
if l.OnTapped != nil {
l.OnTapped()
Expand Down
38 changes: 34 additions & 4 deletions ui/widgets/tracklist.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ type Tracklist struct {
tracksMutex sync.RWMutex
tracks []*trackModel
tracksOrigOrder []*trackModel
itemForIndex map[int]*TrackRow

nowPlayingID string
colLayout *layouts.ColumnsLayout
Expand All @@ -117,7 +118,7 @@ type trackModel struct {
}

func NewTracklist(tracks []*mediaprovider.Track) *Tracklist {
t := &Tracklist{visibleColumns: make([]bool, numColumns)}
t := &Tracklist{visibleColumns: make([]bool, numColumns), itemForIndex: make(map[int]*TrackRow)}
t.ExtendBaseWidget(t)

if len(tracks) > 0 {
Expand All @@ -143,9 +144,28 @@ func NewTracklist(tracks []*mediaprovider.Track) *Tracklist {
t.lenTracks,
func() fyne.CanvasObject {
tr := NewTrackRow(t, playingIcon)
tr.OnTapped = func() { t.onSelectTrack(tr.trackIdx) }
tr.OnTapped = func() {
t.onSelectTrack(tr.trackIdx)
}
tr.OnTappedSecondary = t.onShowContextMenu
tr.OnDoubleTapped = func() { t.onPlayTrackAt(tr.trackIdx) }
tr.OnDoubleTapped = func() {
t.onPlayTrackAt(tr.trackIdx)
}
tr.OnFocusNeighbor = func(up bool) {
focusIdx := tr.trackIdx + 1
if up {
focusIdx = tr.trackIdx - 1
}
if focusIdx >= 0 && focusIdx < t.lenTracks() {
t.list.ScrollTo(focusIdx)
}
t.tracksMutex.RLock()
other, ok := t.itemForIndex[focusIdx]
t.tracksMutex.RUnlock()
if ok {
fyne.CurrentApp().Driver().CanvasForObject(t).Focus(other)
}
}
return tr
},
func(itemID widget.ListItemID, item fyne.CanvasObject) {
Expand All @@ -161,7 +181,15 @@ func NewTracklist(tracks []*mediaprovider.Track) *Tracklist {
t.tracksMutex.RUnlock()

tr := item.(*TrackRow)
tr.trackIdx = itemID
if tr.trackID != model.track.ID || tr.trackIdx != itemID {
t.tracksMutex.Lock()
if other, ok := t.itemForIndex[itemID]; ok && other == tr {
delete(t.itemForIndex, other.trackIdx)
}
t.itemForIndex[itemID] = tr
t.tracksMutex.Unlock()
tr.trackIdx = itemID
}
i := -1 // signal that we want to display the actual track num.
if t.Options.AutoNumber {
i = itemID + 1
Expand Down Expand Up @@ -299,6 +327,7 @@ func (t *Tracklist) Clear() {
defer t.tracksMutex.Unlock()
t.tracks = nil
t.tracksOrigOrder = nil
t.itemForIndex = make(map[int]*TrackRow)
}

// Sets the tracks in the tracklist. Thread-safe.
Expand All @@ -310,6 +339,7 @@ func (t *Tracklist) SetTracks(trs []*mediaprovider.Track) {
func (t *Tracklist) _setTracks(trs []*mediaprovider.Track) {
t.tracksMutex.Lock()
defer t.tracksMutex.Unlock()
t.itemForIndex = make(map[int]*TrackRow)
t.tracksOrigOrder = toTrackModels(trs)
t.doSortTracks()
}
Expand Down

0 comments on commit b97b029

Please sign in to comment.