handle multiple artists properly in UI
This commit is contained in:
@@ -18,6 +18,7 @@ import (
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"strings"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/dweymouth/supersonic/backend/mediaprovider"
|
"github.com/dweymouth/supersonic/backend/mediaprovider"
|
||||||
@@ -79,7 +80,7 @@ func NewMPMediaHandler(player *player.Player, playbackManager *PlaybackManager)
|
|||||||
|
|
||||||
var artist string
|
var artist string
|
||||||
if len(track.ArtistNames) > 0 {
|
if len(track.ArtistNames) > 0 {
|
||||||
artist = track.ArtistNames[0]
|
artist = strings.Join(track.ArtistNames, ", ")
|
||||||
}
|
}
|
||||||
|
|
||||||
cArtist := C.CString(artist)
|
cArtist := C.CString(artist)
|
||||||
|
|||||||
@@ -7,6 +7,18 @@ import (
|
|||||||
"github.com/dweymouth/supersonic/backend/mediaprovider"
|
"github.com/dweymouth/supersonic/backend/mediaprovider"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func SliceEqual[T comparable](a []T, b []T) bool {
|
||||||
|
if len(a) != len(b) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for i := 0; i < len(a); i++ {
|
||||||
|
if a[i] != b[i] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func SliceContains[T comparable](ts []T, t T) bool {
|
func SliceContains[T comparable](ts []T, t T) bool {
|
||||||
for _, x := range ts {
|
for _, x := range ts {
|
||||||
if x == t {
|
if x == t {
|
||||||
|
|||||||
+4
-4
@@ -76,8 +76,8 @@ func NewBottomPanel(p *player.Player, pm *backend.PlaybackManager, contr *contro
|
|||||||
bp.NowPlaying.OnAlbumNameTapped(func() {
|
bp.NowPlaying.OnAlbumNameTapped(func() {
|
||||||
contr.NavigateTo(controller.AlbumRoute(bp.playbackManager.NowPlaying().AlbumID))
|
contr.NavigateTo(controller.AlbumRoute(bp.playbackManager.NowPlaying().AlbumID))
|
||||||
})
|
})
|
||||||
bp.NowPlaying.OnArtistNameTapped(func() {
|
bp.NowPlaying.OnArtistNameTapped(func(artistID string) {
|
||||||
contr.NavigateTo(controller.ArtistRoute(bp.playbackManager.NowPlaying().ArtistIDs[0]))
|
contr.NavigateTo(controller.ArtistRoute(artistID))
|
||||||
})
|
})
|
||||||
bp.NowPlaying.OnTrackNameTapped(func() {
|
bp.NowPlaying.OnTrackNameTapped(func() {
|
||||||
contr.NavigateTo(controller.NowPlayingRoute(bp.playbackManager.NowPlaying().ID))
|
contr.NavigateTo(controller.NowPlayingRoute(bp.playbackManager.NowPlaying().ID))
|
||||||
@@ -113,7 +113,7 @@ func NewBottomPanel(p *player.Player, pm *backend.PlaybackManager, contr *contro
|
|||||||
|
|
||||||
func (bp *BottomPanel) onSongChange(song, _ *mediaprovider.Track) {
|
func (bp *BottomPanel) onSongChange(song, _ *mediaprovider.Track) {
|
||||||
if song == nil {
|
if song == nil {
|
||||||
bp.NowPlaying.Update("", "", false, "", nil)
|
bp.NowPlaying.Update("", []string{}, []string{}, "", nil)
|
||||||
} else {
|
} else {
|
||||||
bp.coverArtID = song.CoverArtID
|
bp.coverArtID = song.CoverArtID
|
||||||
var im image.Image
|
var im image.Image
|
||||||
@@ -125,7 +125,7 @@ func (bp *BottomPanel) onSongChange(song, _ *mediaprovider.Track) {
|
|||||||
imgTTLSec := song.Duration + 30
|
imgTTLSec := song.Duration + 30
|
||||||
im, _ = bp.ImageManager.GetCoverThumbnailWithTTL(song.CoverArtID, time.Duration(imgTTLSec)*time.Second)
|
im, _ = bp.ImageManager.GetCoverThumbnailWithTTL(song.CoverArtID, time.Duration(imgTTLSec)*time.Second)
|
||||||
}
|
}
|
||||||
bp.NowPlaying.Update(song.Name, song.ArtistNames[0], song.ArtistIDs[0] != "", song.Album, im)
|
bp.NowPlaying.Update(song.Name, song.ArtistNames, song.ArtistIDs, song.Album, im)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ func (a *ArtistPage) showAlbumGrid() {
|
|||||||
Name: al.Name,
|
Name: al.Name,
|
||||||
ID: al.ID,
|
ID: al.ID,
|
||||||
CoverArtID: al.CoverArtID,
|
CoverArtID: al.CoverArtID,
|
||||||
Secondary: strconv.Itoa(al.Year),
|
Secondary: []string{strconv.Itoa(al.Year)},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if g := a.pool.Obtain(util.WidgetTypeGridView); g != nil {
|
if g := a.pool.Obtain(util.WidgetTypeGridView); g != nil {
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ func createArtistsGridViewModel(artists []*mediaprovider.Artist) []widgets.GridV
|
|||||||
Name: ar.Name,
|
Name: ar.Name,
|
||||||
ID: ar.ID,
|
ID: ar.ID,
|
||||||
CoverArtID: ar.CoverArtID,
|
CoverArtID: ar.CoverArtID,
|
||||||
Secondary: fmt.Sprintf("%d %s", ar.AlbumCount, albums),
|
Secondary: []string{fmt.Sprintf("%d %s", ar.AlbumCount, albums)},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -333,7 +333,7 @@ func buildArtistGridViewModel(artists []*mediaprovider.Artist) []widgets.GridVie
|
|||||||
ID: ar.ID,
|
ID: ar.ID,
|
||||||
CoverArtID: ar.CoverArtID,
|
CoverArtID: ar.CoverArtID,
|
||||||
Name: ar.Name,
|
Name: ar.Name,
|
||||||
Secondary: fmt.Sprintf("%d %s", ar.AlbumCount, albums),
|
Secondary: []string{fmt.Sprintf("%d %s", ar.AlbumCount, albums)},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return model
|
return model
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ func createPlaylistGridViewModel(playlists []*mediaprovider.Playlist) []widgets.
|
|||||||
Name: pl.Name,
|
Name: pl.Name,
|
||||||
ID: pl.ID,
|
ID: pl.ID,
|
||||||
CoverArtID: pl.CoverArtID,
|
CoverArtID: pl.CoverArtID,
|
||||||
Secondary: fmt.Sprintf("%d %s", pl.TrackCount, tracks),
|
Secondary: []string{fmt.Sprintf("%d %s", pl.TrackCount, tracks)},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -2,6 +2,7 @@ package ui
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/20after4/configdir"
|
"github.com/20after4/configdir"
|
||||||
"github.com/dweymouth/supersonic/backend"
|
"github.com/dweymouth/supersonic/backend"
|
||||||
@@ -86,7 +87,7 @@ func NewMainWindow(fyneApp fyne.App, appName, displayAppName, appVersion string,
|
|||||||
m.Window.SetTitle(displayAppName)
|
m.Window.SetTitle(displayAppName)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
m.Window.SetTitle(fmt.Sprintf("%s – %s · %s", song.Name, song.ArtistNames[0], displayAppName))
|
m.Window.SetTitle(fmt.Sprintf("%s – %s · %s", song.Name, strings.Join(song.ArtistNames, ", "), displayAppName))
|
||||||
})
|
})
|
||||||
app.ServerManager.OnServerConnected(func() {
|
app.ServerManager.OnServerConnected(func() {
|
||||||
m.BrowsingPane.EnableNavigationButtons()
|
m.BrowsingPane.EnableNavigationButtons()
|
||||||
|
|||||||
@@ -58,8 +58,8 @@ func (g gridViewAlbumIterator) NextN(n int) []GridViewItemModel {
|
|||||||
Name: al.Name,
|
Name: al.Name,
|
||||||
ID: al.ID,
|
ID: al.ID,
|
||||||
CoverArtID: al.CoverArtID,
|
CoverArtID: al.CoverArtID,
|
||||||
Secondary: al.ArtistNames[0],
|
Secondary: al.ArtistNames,
|
||||||
SecondaryID: al.ArtistIDs[0],
|
SecondaryIDs: al.ArtistIDs,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -205,9 +205,9 @@ func (g *GridView) createGridWrap() {
|
|||||||
func() fyne.CanvasObject {
|
func() fyne.CanvasObject {
|
||||||
card := NewGridViewItem(g.Placeholder)
|
card := NewGridViewItem(g.Placeholder)
|
||||||
card.OnPlay = func() { g.onPlay(card.ItemID(), false) }
|
card.OnPlay = func() { g.onPlay(card.ItemID(), false) }
|
||||||
card.OnShowSecondaryPage = func() {
|
card.OnShowSecondaryPage = func(id string) {
|
||||||
if g.OnShowSecondaryPage != nil {
|
if g.OnShowSecondaryPage != nil {
|
||||||
g.OnShowSecondaryPage(card.SecondaryID())
|
g.OnShowSecondaryPage(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
card.OnShowItemPage = func() {
|
card.OnShowItemPage = func() {
|
||||||
|
|||||||
+10
-13
@@ -5,6 +5,7 @@ import (
|
|||||||
"image"
|
"image"
|
||||||
|
|
||||||
"github.com/dweymouth/supersonic/res"
|
"github.com/dweymouth/supersonic/res"
|
||||||
|
"github.com/dweymouth/supersonic/sharedutil"
|
||||||
"github.com/dweymouth/supersonic/ui/layouts"
|
"github.com/dweymouth/supersonic/ui/layouts"
|
||||||
|
|
||||||
"fyne.io/fyne/v2"
|
"fyne.io/fyne/v2"
|
||||||
@@ -125,15 +126,15 @@ type GridViewItemModel struct {
|
|||||||
Name string
|
Name string
|
||||||
ID string
|
ID string
|
||||||
CoverArtID string
|
CoverArtID string
|
||||||
Secondary string
|
Secondary []string
|
||||||
SecondaryID string
|
SecondaryIDs []string
|
||||||
}
|
}
|
||||||
|
|
||||||
type GridViewItem struct {
|
type GridViewItem struct {
|
||||||
widget.BaseWidget
|
widget.BaseWidget
|
||||||
|
|
||||||
itemID string
|
itemID string
|
||||||
secondaryID string
|
secondaryIDs []string
|
||||||
primaryText *widget.Hyperlink
|
primaryText *widget.Hyperlink
|
||||||
secondaryText *MultiHyperlink
|
secondaryText *MultiHyperlink
|
||||||
container *fyne.Container
|
container *fyne.Container
|
||||||
@@ -145,7 +146,7 @@ type GridViewItem struct {
|
|||||||
OnPlay func()
|
OnPlay func()
|
||||||
OnShowContextMenu func(fyne.Position)
|
OnShowContextMenu func(fyne.Position)
|
||||||
OnShowItemPage func()
|
OnShowItemPage func()
|
||||||
OnShowSecondaryPage func()
|
OnShowSecondaryPage func(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGridViewItem(placeholderResource fyne.Resource) *GridViewItem {
|
func NewGridViewItem(placeholderResource fyne.Resource) *GridViewItem {
|
||||||
@@ -174,9 +175,9 @@ func NewGridViewItem(placeholderResource fyne.Resource) *GridViewItem {
|
|||||||
}
|
}
|
||||||
g.Cover.OnShowPage = showItemFn
|
g.Cover.OnShowPage = showItemFn
|
||||||
g.primaryText.OnTapped = showItemFn
|
g.primaryText.OnTapped = showItemFn
|
||||||
g.secondaryText.OnTapped = func(_ string) { // TODO
|
g.secondaryText.OnTapped = func(s string) {
|
||||||
if g.OnShowSecondaryPage != nil {
|
if g.OnShowSecondaryPage != nil {
|
||||||
g.OnShowSecondaryPage()
|
g.OnShowSecondaryPage(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,14 +193,14 @@ func (g *GridViewItem) createContainer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GridViewItem) NeedsUpdate(model GridViewItemModel) bool {
|
func (g *GridViewItem) NeedsUpdate(model GridViewItemModel) bool {
|
||||||
return g.itemID != model.ID || g.secondaryID != model.SecondaryID
|
return g.itemID != model.ID || !sharedutil.SliceEqual(g.secondaryIDs, model.SecondaryIDs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GridViewItem) Update(model GridViewItemModel) {
|
func (g *GridViewItem) Update(model GridViewItemModel) {
|
||||||
g.itemID = model.ID
|
g.itemID = model.ID
|
||||||
g.secondaryID = model.SecondaryID
|
g.secondaryIDs = model.SecondaryIDs
|
||||||
g.primaryText.SetText(model.Name)
|
g.primaryText.SetText(model.Name)
|
||||||
g.secondaryText.Segments = []MultiHyperlinkSegment{{Text: model.Secondary, LinkID: model.SecondaryID}}
|
g.secondaryText.BuildSegments(model.Secondary, model.SecondaryIDs)
|
||||||
g.secondaryText.Refresh()
|
g.secondaryText.Refresh()
|
||||||
g.Cover.ResetPlayButton()
|
g.Cover.ResetPlayButton()
|
||||||
}
|
}
|
||||||
@@ -212,10 +213,6 @@ func (g *GridViewItem) ItemID() string {
|
|||||||
return g.itemID
|
return g.itemID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GridViewItem) SecondaryID() string {
|
|
||||||
return g.secondaryID
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *GridViewItem) CreateRenderer() fyne.WidgetRenderer {
|
func (g *GridViewItem) CreateRenderer() fyne.WidgetRenderer {
|
||||||
return widget.NewSimpleRenderer(g.container)
|
return widget.NewSimpleRenderer(g.container)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,18 @@ func NewMultiHyperlink() *MultiHyperlink {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *MultiHyperlink) BuildSegments(texts, links []string) {
|
||||||
|
l := len(links)
|
||||||
|
m.Segments = nil
|
||||||
|
for i, text := range texts {
|
||||||
|
link := ""
|
||||||
|
if l > i {
|
||||||
|
link = links[i]
|
||||||
|
}
|
||||||
|
m.Segments = append(m.Segments, MultiHyperlinkSegment{Text: text, LinkID: link})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *MultiHyperlink) getMinSegWidth() float32 {
|
func (c *MultiHyperlink) getMinSegWidth() float32 {
|
||||||
if c.minSegWidthCached == 0 {
|
if c.minSegWidthCached == 0 {
|
||||||
c.minSegWidthCached = fyne.MeasureText(", W", theme.TextSize(), fyne.TextStyle{}).Width
|
c.minSegWidthCached = fyne.MeasureText(", W", theme.TextSize(), fyne.TextStyle{}).Width
|
||||||
@@ -82,7 +94,7 @@ func (c *MultiHyperlink) layoutObjects() {
|
|||||||
if seg.LinkID == "" {
|
if seg.LinkID == "" {
|
||||||
obj = c.updateOrReplaceLabel(obj, seg.Text)
|
obj = c.updateOrReplaceLabel(obj, seg.Text)
|
||||||
} else {
|
} else {
|
||||||
obj = c.updateOrReplaceHyperlink(obj, seg.Text)
|
obj = c.updateOrReplaceHyperlink(obj, seg.Text, seg.LinkID)
|
||||||
}
|
}
|
||||||
if appendingSegments {
|
if appendingSegments {
|
||||||
c.content.Objects = append(c.content.Objects, obj)
|
c.content.Objects = append(c.content.Objects, obj)
|
||||||
@@ -124,15 +136,17 @@ func (c *MultiHyperlink) updateOrReplaceLabel(obj fyne.CanvasObject, text string
|
|||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MultiHyperlink) updateOrReplaceHyperlink(obj fyne.CanvasObject, text string) fyne.CanvasObject {
|
func (c *MultiHyperlink) updateOrReplaceHyperlink(obj fyne.CanvasObject, text, link string) fyne.CanvasObject {
|
||||||
if obj != nil {
|
if obj != nil {
|
||||||
if link, ok := obj.(*widget.Hyperlink); ok {
|
if l, ok := obj.(*widget.Hyperlink); ok {
|
||||||
link.Text = text
|
l.Text = text
|
||||||
return link
|
l.OnTapped = func() { c.onSegmentTapped(link) }
|
||||||
|
return l
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
l := widget.NewHyperlink(text, nil)
|
l := widget.NewHyperlink(text, nil)
|
||||||
l.Wrapping = fyne.TextTruncate
|
l.Wrapping = fyne.TextTruncate
|
||||||
|
l.OnTapped = func() { c.onSegmentTapped(link) }
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,7 +214,9 @@ func (c *MultiHyperlink) updateOrReplaceHyperlinkSegment(seg widget.RichTextSegm
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
func (c *MultiHyperlink) onSegmentTapped(linkID string) {
|
func (c *MultiHyperlink) onSegmentTapped(linkID string) {
|
||||||
// TODO
|
if c.OnTapped != nil {
|
||||||
|
c.OnTapped(linkID)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MultiHyperlink) MinSize() fyne.Size {
|
func (c *MultiHyperlink) MinSize() fyne.Size {
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ func NewNowPlayingCard() *NowPlayingCard {
|
|||||||
n.cover = NewTappableImage(n.onShowCoverImage)
|
n.cover = NewTappableImage(n.onShowCoverImage)
|
||||||
n.cover.OnTappedSecondary = n.showMenu
|
n.cover.OnTappedSecondary = n.showMenu
|
||||||
n.trackName.Hidden = true
|
n.trackName.Hidden = true
|
||||||
n.artistName.Hidden = true
|
|
||||||
n.albumName.Hidden = true
|
n.albumName.Hidden = true
|
||||||
n.albumName.Wrapping = fyne.TextTruncate
|
n.albumName.Wrapping = fyne.TextTruncate
|
||||||
n.trackName.Wrapping = fyne.TextTruncate
|
n.trackName.Wrapping = fyne.TextTruncate
|
||||||
@@ -85,19 +84,18 @@ func (n *NowPlayingCard) CreateRenderer() fyne.WidgetRenderer {
|
|||||||
return widget.NewSimpleRenderer(n.c)
|
return widget.NewSimpleRenderer(n.c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NowPlayingCard) Update(track, artist string, artistNavigable bool, album string, cover image.Image) {
|
func (n *NowPlayingCard) Update(track string, artists, artistIDs []string, album string, cover image.Image) {
|
||||||
n.trackName.SetText(track)
|
n.trackName.SetText(track)
|
||||||
n.trackName.Hidden = track == ""
|
n.trackName.Hidden = track == ""
|
||||||
n.artistName.Segments = []MultiHyperlinkSegment{{Text: artist}}
|
n.artistName.BuildSegments(artists, artistIDs)
|
||||||
n.artistName.Hidden = artist == ""
|
|
||||||
n.albumName.SetText(album)
|
n.albumName.SetText(album)
|
||||||
n.albumName.Hidden = album == ""
|
n.albumName.Hidden = album == ""
|
||||||
n.cover.Image.Image = cover
|
n.cover.Image.Image = cover
|
||||||
n.c.Refresh()
|
n.c.Refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NowPlayingCard) OnArtistNameTapped(f func()) {
|
func (n *NowPlayingCard) OnArtistNameTapped(f func(string)) {
|
||||||
//n.artistName.OnTapped = f
|
n.artistName.OnTapped = f
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NowPlayingCard) OnAlbumNameTapped(f func()) {
|
func (n *NowPlayingCard) OnAlbumNameTapped(f func()) {
|
||||||
|
|||||||
@@ -396,7 +396,7 @@ func (t *Tracklist) doSortTracks() {
|
|||||||
case ColumnTitle:
|
case ColumnTitle:
|
||||||
t.stringSort(func(tr *trackModel) string { return tr.track.Name })
|
t.stringSort(func(tr *trackModel) string { return tr.track.Name })
|
||||||
case ColumnArtist:
|
case ColumnArtist:
|
||||||
t.stringSort(func(tr *trackModel) string { return tr.track.ArtistNames[0] })
|
t.stringSort(func(tr *trackModel) string { return strings.Join(tr.track.ArtistNames, ", ") })
|
||||||
case ColumnAlbum:
|
case ColumnAlbum:
|
||||||
t.stringSort(func(tr *trackModel) string { return tr.track.Album })
|
t.stringSort(func(tr *trackModel) string { return tr.track.Album })
|
||||||
case ColumnPath:
|
case ColumnPath:
|
||||||
@@ -698,7 +698,7 @@ func NewTrackRow(tracklist *Tracklist, playingIcon fyne.CanvasObject) *TrackRow
|
|||||||
t.num = newTrailingAlignRichText()
|
t.num = newTrailingAlignRichText()
|
||||||
t.name = newTruncatingRichText()
|
t.name = newTruncatingRichText()
|
||||||
t.artist = NewMultiHyperlink()
|
t.artist = NewMultiHyperlink()
|
||||||
//t.artist.OnTapped = func() { tracklist.onArtistTapped(t.artistID) } // TODO
|
t.artist.OnTapped = tracklist.onArtistTapped
|
||||||
t.album = widget.NewHyperlink("", nil)
|
t.album = widget.NewHyperlink("", nil)
|
||||||
t.album.Wrapping = fyne.TextTruncate
|
t.album.Wrapping = fyne.TextTruncate
|
||||||
t.album.OnTapped = func() { tracklist.onAlbumTapped(t.albumID) }
|
t.album.OnTapped = func() { tracklist.onAlbumTapped(t.albumID) }
|
||||||
@@ -748,7 +748,7 @@ func (t *TrackRow) Update(tm *trackModel, rowNum int) {
|
|||||||
t.albumID = tr.AlbumID
|
t.albumID = tr.AlbumID
|
||||||
|
|
||||||
t.name.Segments[0].(*widget.TextSegment).Text = tr.Name
|
t.name.Segments[0].(*widget.TextSegment).Text = tr.Name
|
||||||
t.artist.Segments = []MultiHyperlinkSegment{{Text: tr.ArtistNames[0], LinkID: tr.ArtistIDs[0]}}
|
t.artist.BuildSegments(tr.ArtistNames, tr.ArtistIDs)
|
||||||
t.album.SetText(tr.Album)
|
t.album.SetText(tr.Album)
|
||||||
t.dur.Segments[0].(*widget.TextSegment).Text = util.SecondsToTimeString(float64(tr.Duration))
|
t.dur.Segments[0].(*widget.TextSegment).Text = util.SecondsToTimeString(float64(tr.Duration))
|
||||||
t.year.Segments[0].(*widget.TextSegment).Text = strconv.Itoa(tr.Year)
|
t.year.Segments[0].(*widget.TextSegment).Text = strconv.Itoa(tr.Year)
|
||||||
|
|||||||
Reference in New Issue
Block a user