WIP - doesn't quite work yet

This commit is contained in:
Drew Weymouth
2024-05-29 20:04:06 -07:00
parent a9b6d0cc2a
commit 680cfb42d2
11 changed files with 112 additions and 44 deletions
+16
View File
@@ -25,6 +25,10 @@ type FocusListRow interface {
fyne.Focusable
ItemID() widget.ListItemID
SetItemID(widget.ListItemID)
SetOnTapped(func())
SetOnDoubleTapped(func())
SetOnFocusNeighbor(func(up bool))
}
func NewFocusList(len func() int, create func() fyne.CanvasObject, update func(widget.GridWrapItemID, fyne.CanvasObject)) *FocusList {
@@ -102,6 +106,18 @@ type FocusListRowBase struct {
selectionRect *canvas.Rectangle
}
func (l *FocusListRowBase) SetOnTapped(f func()) {
l.OnTapped = f
}
func (l *FocusListRowBase) SetOnDoubleTapped(f func()) {
l.OnDoubleTapped = f
}
func (l *FocusListRowBase) SetOnFocusNeighbor(f func(up bool)) {
l.OnFocusNeighbor = f
}
func (l *FocusListRowBase) ItemID() widget.ListItemID {
return l.ListItemID
}
+3 -1
View File
@@ -21,6 +21,8 @@ import (
"github.com/dweymouth/supersonic/ui/util"
)
const playQueueListThumbnailSize = 52
type PlayQueueList struct {
widget.BaseWidget
@@ -296,7 +298,7 @@ func NewPlayQueueListRow(playQueueList *PlayQueueList, im *backend.ImageManager,
playingIcon: playingIcon,
playQueueList: playQueueList,
num: widget.NewLabel(""),
cover: NewImagePlaceholder(myTheme.TracksIcon, tracklistThumbnailSize),
cover: NewImagePlaceholder(myTheme.TracksIcon, playQueueListThumbnailSize),
title: util.NewTruncatingLabel(),
artist: NewMultiHyperlink(),
time: util.NewTrailingAlignLabel(),
+73 -31
View File
@@ -7,6 +7,7 @@ import (
"strings"
"sync"
"github.com/dweymouth/supersonic/backend"
"github.com/dweymouth/supersonic/backend/mediaprovider"
"github.com/dweymouth/supersonic/sharedutil"
"github.com/dweymouth/supersonic/ui/layouts"
@@ -79,6 +80,8 @@ type TracklistOptions struct {
type Tracklist struct {
widget.BaseWidget
compactRows bool
Options TracklistOptions
// user action callbacks
@@ -118,16 +121,22 @@ type Tracklist struct {
container *fyne.Container
}
func NewTracklist(tracks []*mediaprovider.Track) *Tracklist {
t := &Tracklist{visibleColumns: make([]bool, numColumns)}
func NewTracklist(tracks []*mediaprovider.Track, im *backend.ImageManager, useCompactRows bool) *Tracklist {
t := &Tracklist{visibleColumns: make([]bool, numColumns), compactRows: useCompactRows}
t.ExtendBaseWidget(t)
if len(tracks) > 0 {
t._setTracks(tracks)
}
// #, Title, Artist, Album, Time, Year, Favorite, Rating, Plays, Comment, Bitrate, Size, Path
t.colLayout = layouts.NewColumnsLayout([]float32{40, -1, -1, -1, 60, 60, 55, 100, 65, -1, 75, 75, -1})
// #, Title/Artist, Album, Time, Year, Favorite, Rating, Plays, Comment, Bitrate, Size, Path
colWidths := []float32{40, -1, -1, 60, 60, 55, 100, 65, -1, 75, 75, -1}
if useCompactRows {
// #, Title, Artist, Album, Time, Year, Favorite, Rating, Plays, Comment, Bitrate, Size, Path
colWidths = []float32{40, -1, -1, -1, 60, 60, 55, 100, 65, -1, 75, 75, -1}
}
t.colLayout = layouts.NewColumnsLayout(colWidths)
t.buildHeader()
t.hdr.OnColumnSortChanged = t.onSorted
t.hdr.OnColumnVisibilityChanged = t.setColumnVisible
@@ -144,17 +153,22 @@ func NewTracklist(tracks []*mediaprovider.Track) *Tracklist {
t.list = NewFocusList(
t.lenTracks,
func() fyne.CanvasObject {
tr := NewCompactTracklistRow(t, playingIcon)
tr.OnTapped = func() {
t.onSelectTrack(tr.ListItemID)
}
tr.OnTappedSecondary = t.onShowContextMenu
tr.OnDoubleTapped = func() {
t.onPlayTrackAt(tr.ListItemID)
}
tr.OnFocusNeighbor = func(up bool) {
t.list.FocusNeighbor(tr.ListItemID, up)
var tr TracklistRow
if t.compactRows {
tr = NewCompactTracklistRow(t, playingIcon)
} else {
tr = NewExpandedTracklistRow(t, im, playingIcon)
}
tr.SetOnTapped(func() {
t.onSelectTrack(tr.ItemID())
})
tr.SetOnTappedSecondary(t.onShowContextMenu)
tr.SetOnDoubleTapped(func() {
t.onPlayTrackAt(tr.ItemID())
})
tr.SetOnFocusNeighbor(func(up bool) {
t.list.FocusNeighbor(tr.ItemID(), up)
})
return tr
},
func(itemID widget.ListItemID, item fyne.CanvasObject) {
@@ -199,21 +213,31 @@ func (t *Tracklist) Scroll(amount float32) {
}
func (t *Tracklist) buildHeader() {
t.hdr = NewListHeader([]ListColumn{
{Text: "#", Alignment: fyne.TextAlignTrailing, CanToggleVisible: false},
{Text: "Title", Alignment: fyne.TextAlignLeading, CanToggleVisible: false},
{Text: "Artist", Alignment: fyne.TextAlignLeading, CanToggleVisible: true},
{Text: "Album", Alignment: fyne.TextAlignLeading, CanToggleVisible: true},
{Text: "Time", Alignment: fyne.TextAlignTrailing, CanToggleVisible: true},
{Text: "Year", Alignment: fyne.TextAlignTrailing, CanToggleVisible: true},
{Text: " Fav.", Alignment: fyne.TextAlignCenter, CanToggleVisible: true},
{Text: "Rating", Alignment: fyne.TextAlignLeading, CanToggleVisible: true},
{Text: "Plays", Alignment: fyne.TextAlignTrailing, CanToggleVisible: true},
{Text: "Comment", Alignment: fyne.TextAlignLeading, CanToggleVisible: true},
{Text: "Bitrate", Alignment: fyne.TextAlignTrailing, CanToggleVisible: true},
{Text: "Size", Alignment: fyne.TextAlignTrailing, CanToggleVisible: true},
{Text: "File Path", Alignment: fyne.TextAlignLeading, CanToggleVisible: true}},
t.colLayout)
cols := []ListColumn{{Text: "#", Alignment: fyne.TextAlignTrailing, CanToggleVisible: false}}
if t.compactRows {
cols = append(cols,
ListColumn{Text: "Title", Alignment: fyne.TextAlignLeading, CanToggleVisible: false},
ListColumn{Text: "Artist", Alignment: fyne.TextAlignLeading, CanToggleVisible: true},
)
} else {
cols = append(cols,
ListColumn{Text: " Title / Aritst", Alignment: fyne.TextAlignLeading, CanToggleVisible: false},
)
}
cols = append(cols,
ListColumn{Text: "Album", Alignment: fyne.TextAlignLeading, CanToggleVisible: true},
ListColumn{Text: "Time", Alignment: fyne.TextAlignTrailing, CanToggleVisible: true},
ListColumn{Text: "Year", Alignment: fyne.TextAlignTrailing, CanToggleVisible: true},
ListColumn{Text: " Fav.", Alignment: fyne.TextAlignCenter, CanToggleVisible: true},
ListColumn{Text: "Rating", Alignment: fyne.TextAlignLeading, CanToggleVisible: true},
ListColumn{Text: "Plays", Alignment: fyne.TextAlignTrailing, CanToggleVisible: true},
ListColumn{Text: "Comment", Alignment: fyne.TextAlignLeading, CanToggleVisible: true},
ListColumn{Text: "Bitrate", Alignment: fyne.TextAlignTrailing, CanToggleVisible: true},
ListColumn{Text: "Size", Alignment: fyne.TextAlignTrailing, CanToggleVisible: true},
ListColumn{Text: "File Path", Alignment: fyne.TextAlignLeading, CanToggleVisible: true},
)
t.hdr = NewListHeader(cols, t.colLayout)
}
// Gets the track at the given index. Thread-safe.
@@ -230,15 +254,30 @@ func (t *Tracklist) TrackAt(idx int) *mediaprovider.Track {
func (t *Tracklist) SetVisibleColumns(cols []string) {
t.visibleColumns[0] = true
t.visibleColumns[1] = true
for i := 2; i < len(t.visibleColumns); i++ {
t.visibleColumns[i] = false
if !t.compactRows {
// hard-code artist column to visible since it's part of title col
t.visibleColumns[2] = true
}
l := len(t.visibleColumns)
if !t.compactRows {
l-- // expanded rows have one fewer column due to merged title/artist
}
for i := 2; i < l; i++ {
t.hdr.SetColumnVisible(i, false)
}
for _, col := range cols {
if num := ColNumber(col); num < 0 {
log.Printf("Unknown tracklist column %q", col)
} else {
if num == 2 && !t.compactRows {
// Artist column is hard-coded visible (part of title), skip
continue
}
t.visibleColumns[num] = true
if !t.compactRows && num >= 3 {
num -= 1 // shift cols by 1 to account for Title/Artist combined col
}
t.hdr.SetColumnVisible(num, true)
}
}
@@ -259,6 +298,9 @@ func (t *Tracklist) setColumnVisible(colNum int, vis bool) {
log.Printf("error: Tracklist.SetColumnVisible: column index %d out of range", colNum)
return
}
if !t.compactRows && colNum >= 2 {
colNum++ // account for off-by-one from merged title/artist column
}
t.visibleColumns[colNum] = vis
t.list.Refresh()
if t.OnVisibleColumnsChanged != nil {
+8 -2
View File
@@ -15,7 +15,7 @@ import (
"github.com/dweymouth/supersonic/ui/util"
)
const tracklistThumbnailSize = 52
const tracklistThumbnailSize = 48
type tracklistRowBase struct {
FocusListRowBase
@@ -49,8 +49,11 @@ type tracklistRowBase struct {
}
type TracklistRow interface {
fyne.CanvasObject
FocusListRow
SetOnTappedSecondary(func(_ *fyne.PointEvent, trackNum int))
TrackID() string
Update(model *util.TrackListModel, rowNum int)
}
@@ -87,7 +90,7 @@ func NewExpandedTracklistRow(tracklist *Tracklist, im *backend.ImageManager, pla
titleArtistImg := container.NewBorder(nil, nil,
container.NewPadded(t.img) /*left*/, nil,
container.New(layout.NewCustomPaddedVBoxLayout(theme.Padding()-15),
container.New(layout.NewCustomPaddedVBoxLayout(theme.Padding()-16),
t.name, t.artist))
v := makeVerticallyCentered // func alias
@@ -138,6 +141,9 @@ func (t *tracklistRowBase) create(tracklist *Tracklist) {
t.path = util.NewTruncatingLabel()
}
func (t *tracklistRowBase) SetOnTappedSecondary(f func(*fyne.PointEvent, int)) {
t.OnTappedSecondary = f
}
func (t *tracklistRowBase) TrackID() string {
return t.trackID
}