add tracklist focus handler

This commit is contained in:
Drew Weymouth
2023-03-04 14:17:42 -08:00
parent 4eddf262cb
commit 773d5a65bb
4 changed files with 108 additions and 39 deletions
+1 -1
View File
@@ -44,4 +44,4 @@ require (
honnef.co/go/js/dom v0.0.0-20210725211120-f030747120f2 // indirect
)
replace fyne.io/fyne/v2 v2.2.4 => github.com/dweymouth/fyne/v2 v2.3.0-rc1.0.20230217050145-ca8ffa6896d6
replace fyne.io/fyne/v2 v2.2.4 => github.com/dweymouth/fyne/v2 v2.3.0-rc1.0.20230304215136-47240a9a5b0a
+2 -2
View File
@@ -75,8 +75,8 @@ github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7h
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dweymouth/fyne/v2 v2.3.0-rc1.0.20230217050145-ca8ffa6896d6 h1:iqaXkEOMiYtKXYuMUd1JTXoNTIIGfv+Bc1bAzNmsN/c=
github.com/dweymouth/fyne/v2 v2.3.0-rc1.0.20230217050145-ca8ffa6896d6/go.mod h1:dl/M+f0r5lJRhy+gdPbmYy97tbu3SWF/RF6/9KXMs+s=
github.com/dweymouth/fyne/v2 v2.3.0-rc1.0.20230304215136-47240a9a5b0a h1:DzABPDAu62cN2rn5JJ1mfqrXACzVHxVx2d1z2C+0020=
github.com/dweymouth/fyne/v2 v2.3.0-rc1.0.20230304215136-47240a9a5b0a/go.mod h1:dl/M+f0r5lJRhy+gdPbmYy97tbu3SWF/RF6/9KXMs+s=
github.com/dweymouth/go-subsonic v0.0.0-20230210044542-537b9238299b h1:8JbTKYDdQg6JKu7ZDbEaVbXxutc3pRF58yNvTVMBHec=
github.com/dweymouth/go-subsonic v0.0.0-20230210044542-537b9238299b/go.mod h1:fUez6NFiEJiQTZizZ1BThZr5GJXAbigzGYjEPNm4tdI=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+94
View File
@@ -0,0 +1,94 @@
package widgets
import (
"time"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
)
var _ fyne.Tappable = (*ListRowBase)(nil)
var _ fyne.Widget = (*ListRowBase)(nil)
var _ fyne.Focusable = (*ListRowBase)(nil)
type ListRowBase struct {
widget.BaseWidget
Content fyne.CanvasObject
Selected bool
Focused bool
OnTapped func()
OnDoubleTapped func()
tappedAt int64 // unixMillis
focusedRect *canvas.Rectangle
selectionRect *canvas.Rectangle
}
// We implement our own double tapping so that the Tapped behavior
// can be triggered instantly.
func (l *ListRowBase) Tapped(*fyne.PointEvent) {
prevTap := l.tappedAt
l.tappedAt = time.Now().UnixMilli()
if l.tappedAt-prevTap < 300 {
if l.OnDoubleTapped != nil {
l.OnDoubleTapped()
}
} else {
if l.OnTapped != nil {
l.OnTapped()
}
}
}
func (l *ListRowBase) FocusGained() {
l.Focused = true
l.Refresh()
}
func (l *ListRowBase) FocusLost() {
l.Focused = false
l.Refresh()
}
func (l *ListRowBase) TypedKey(e *fyne.KeyEvent) {
switch {
case e.Name == fyne.KeySpace:
if l.OnTapped != nil {
l.OnTapped()
}
case e.Name == fyne.KeyReturn || e.Name == fyne.KeyEnter:
if l.OnDoubleTapped != nil {
l.OnDoubleTapped()
} else if l.OnTapped != nil {
l.OnTapped()
}
}
}
func (l *ListRowBase) TypedRune(r rune) {
}
func (l *ListRowBase) Refresh() {
l.focusedRect.Hidden = !l.Focused
l.selectionRect.Hidden = !l.Selected
l.BaseWidget.Refresh()
}
func (l *ListRowBase) CreateRenderer() fyne.WidgetRenderer {
if l.selectionRect == nil {
l.selectionRect = canvas.NewRectangle(theme.SelectionColor())
l.selectionRect.Hidden = !l.Selected
}
if l.focusedRect == nil {
l.focusedRect = canvas.NewRectangle(theme.HoverColor())
l.focusedRect.Hidden = !l.Focused
}
return widget.NewSimpleRenderer(
container.NewMax(l.selectionRect, l.focusedRect, l.Content),
)
}
+11 -36
View File
@@ -12,7 +12,6 @@ import (
"time"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/driver/desktop"
"fyne.io/fyne/v2/theme"
@@ -89,7 +88,7 @@ func NewTracklist(tracks []*subsonic.Child) *Tracklist {
func(itemID widget.ListItemID, item fyne.CanvasObject) {
tr := item.(*TrackRow)
tr.trackIdx = itemID
tr.selectionRect.Hidden = !t.selectionMgr.IsSelected(itemID)
tr.Selected = t.selectionMgr.IsSelected(itemID)
i := -1 // signal that we want to display the actual track num.
if t.AutoNumber {
i = itemID + 1
@@ -343,7 +342,7 @@ func colName(i int) string {
}
type TrackRow struct {
widget.BaseWidget
ListRowBase
// internal state
tracklist *Tracklist
@@ -355,7 +354,6 @@ type TrackRow struct {
isPlaying bool
isFavorite bool
playCount int64
tappedAt int64 // unixMillis
num *widget.RichText
name *widget.RichText
@@ -367,13 +365,9 @@ type TrackRow struct {
bitrate *widget.RichText
plays *widget.RichText
OnTapped func()
OnDoubleTapped func()
OnTappedSecondary func(e *fyne.PointEvent, trackIdx int)
playingIcon fyne.CanvasObject
selectionRect *canvas.Rectangle
container *fyne.Container
playingIcon fyne.CanvasObject
}
func NewTrackRow(tracklist *Tracklist, playingIcon fyne.CanvasObject) *TrackRow {
@@ -399,11 +393,8 @@ func NewTrackRow(tracklist *Tracklist, playingIcon fyne.CanvasObject) *TrackRow
t.bitrate = widget.NewRichTextWithText("")
t.bitrate.Segments[0].(*widget.TextSegment).Style.Alignment = fyne.TextAlignTrailing
t.selectionRect = canvas.NewRectangle(theme.SelectionColor())
t.selectionRect.Hidden = true
t.container = container.NewMax(t.selectionRect,
container.New(tracklist.colLayout,
t.num, t.name, t.artist, t.album, t.dur, t.year, t.favorite, t.plays, t.bitrate))
t.Content = container.New(tracklist.colLayout,
t.num, t.name, t.artist, t.album, t.dur, t.year, t.favorite, t.plays, t.bitrate)
return t
}
@@ -411,6 +402,10 @@ func (t *TrackRow) Update(tr *subsonic.Child, isPlaying bool, rowNum int) {
// Update info that can change if this row is bound to
// a new track (*subsonic.Child)
if tr.ID != t.trackID {
if t.Focused {
fyne.CurrentApp().Driver().CanvasForObject(t).Focus(nil)
t.Focused = false
}
t.trackID = tr.ID
t.artistID = tr.ArtistID
t.albumID = tr.AlbumID
@@ -450,9 +445,9 @@ func (t *TrackRow) Update(tr *subsonic.Child, isPlaying bool, rowNum int) {
t.bitrate.Segments[0].(*widget.TextSegment).Style.TextStyle.Bold = isPlaying
if isPlaying {
t.container.Objects[1].(*fyne.Container).Objects[0] = container.NewCenter(t.playingIcon)
t.Content.(*fyne.Container).Objects[0] = container.NewCenter(t.playingIcon)
} else {
t.container.Objects[1].(*fyne.Container).Objects[0] = t.num
t.Content.(*fyne.Container).Objects[0] = t.num
}
}
@@ -497,26 +492,6 @@ func (t *TrackRow) toggleFavorited() {
}
}
func (t *TrackRow) CreateRenderer() fyne.WidgetRenderer {
return widget.NewSimpleRenderer(t.container)
}
// We implement our own double tapping so that the Tapped behavior
// can be triggered instantly.
func (t *TrackRow) Tapped(*fyne.PointEvent) {
prevTap := t.tappedAt
t.tappedAt = time.Now().UnixMilli()
if t.tappedAt-prevTap < 300 {
if t.OnDoubleTapped != nil {
t.OnDoubleTapped()
}
} else {
if t.OnTapped != nil {
t.OnTapped()
}
}
}
func (t *TrackRow) TappedSecondary(e *fyne.PointEvent) {
if t.OnTappedSecondary != nil {
t.OnTappedSecondary(e, t.trackIdx)