193 lines
5.4 KiB
Go
193 lines
5.4 KiB
Go
package widgets
|
|
|
|
import (
|
|
"image"
|
|
|
|
"fyne.io/fyne/v2/lang"
|
|
|
|
"github.com/dweymouth/supersonic/backend/mediaprovider"
|
|
myTheme "github.com/dweymouth/supersonic/ui/theme"
|
|
"github.com/dweymouth/supersonic/ui/util"
|
|
|
|
"fyne.io/fyne/v2"
|
|
"fyne.io/fyne/v2/canvas"
|
|
"fyne.io/fyne/v2/container"
|
|
"fyne.io/fyne/v2/layout"
|
|
"fyne.io/fyne/v2/theme"
|
|
"fyne.io/fyne/v2/widget"
|
|
ttwidget "github.com/dweymouth/fyne-tooltip/widget"
|
|
)
|
|
|
|
// Shows the current album art, track name, artist name, and album name
|
|
// for the currently playing track. Placed into the left side of the BottomPanel.
|
|
type NowPlayingCard struct {
|
|
widget.BaseWidget
|
|
|
|
DisableRating bool
|
|
|
|
trackName *OptionHyperlink
|
|
artistName *MultiHyperlink
|
|
albumName *ttwidget.Hyperlink
|
|
cover *ImagePlaceholder
|
|
menu *widget.PopUpMenu
|
|
ratingMenu *fyne.MenuItem
|
|
|
|
OnTrackNameTapped func()
|
|
OnArtistNameTapped func(artistID string)
|
|
OnAlbumNameTapped func()
|
|
OnCoverTapped func()
|
|
OnSetRating func(rating int)
|
|
OnSetFavorite func(favorite bool)
|
|
OnAddToPlaylist func()
|
|
OnShowTrackInfo func()
|
|
OnShare func()
|
|
}
|
|
|
|
func NewNowPlayingCard() *NowPlayingCard {
|
|
n := &NowPlayingCard{
|
|
trackName: NewOptionHyperlink(),
|
|
artistName: NewMultiHyperlink(),
|
|
albumName: ttwidget.NewHyperlink("", nil),
|
|
}
|
|
n.ExtendBaseWidget(n)
|
|
n.cover = NewImagePlaceholder(myTheme.TracksIcon, 85)
|
|
n.cover.OnTapped = n.onShowCoverImage
|
|
n.cover.ScaleMode = canvas.ImageScaleFastest
|
|
n.cover.Hidden = true
|
|
n.trackName.Hidden = true
|
|
n.albumName.Hidden = true
|
|
n.albumName.Truncation = fyne.TextTruncateEllipsis
|
|
n.trackName.SetTextStyle(fyne.TextStyle{Bold: true})
|
|
n.trackName.OnShowMenu = n.showMenu
|
|
n.albumName.OnTapped = n.onAlbumNameTapped
|
|
n.artistName.OnTapped = n.onArtistNameTapped
|
|
n.trackName.SetOnTapped(n.onTrackNameTapped)
|
|
|
|
return n
|
|
}
|
|
|
|
func (n *NowPlayingCard) MinSize() fyne.Size {
|
|
// prop up height for when cover image is hidden
|
|
return fyne.NewSize(n.BaseWidget.MinSize().Width, 85)
|
|
}
|
|
|
|
func (n *NowPlayingCard) onAlbumNameTapped() {
|
|
if n.OnAlbumNameTapped != nil {
|
|
n.OnAlbumNameTapped()
|
|
}
|
|
}
|
|
|
|
func (n *NowPlayingCard) onArtistNameTapped(artistID string) {
|
|
if n.OnArtistNameTapped != nil {
|
|
n.OnArtistNameTapped(artistID)
|
|
}
|
|
}
|
|
|
|
func (n *NowPlayingCard) onTrackNameTapped() {
|
|
if n.OnTrackNameTapped != nil {
|
|
n.OnTrackNameTapped()
|
|
}
|
|
}
|
|
|
|
func (n *NowPlayingCard) onShowCoverImage(*fyne.PointEvent) {
|
|
if n.OnCoverTapped != nil {
|
|
n.OnCoverTapped()
|
|
}
|
|
}
|
|
|
|
func (n *NowPlayingCard) onSetFavorite(fav bool) {
|
|
if n.OnSetFavorite != nil {
|
|
n.OnSetFavorite(fav)
|
|
}
|
|
}
|
|
|
|
func (n *NowPlayingCard) onSetRating(rating int) {
|
|
if n.OnSetRating != nil {
|
|
n.OnSetRating(rating)
|
|
}
|
|
}
|
|
|
|
func (n *NowPlayingCard) onAddToPlaylist() {
|
|
if n.OnAddToPlaylist != nil {
|
|
n.OnAddToPlaylist()
|
|
}
|
|
}
|
|
|
|
func (n *NowPlayingCard) onShowTrackInfo() {
|
|
if n.OnShowTrackInfo != nil {
|
|
n.OnShowTrackInfo()
|
|
}
|
|
}
|
|
|
|
func (n *NowPlayingCard) onShare() {
|
|
if n.OnShare != nil {
|
|
n.OnShare()
|
|
}
|
|
}
|
|
|
|
func (n *NowPlayingCard) CreateRenderer() fyne.WidgetRenderer {
|
|
c := container.New(&layout.CustomPaddedLayout{LeftPadding: -4},
|
|
container.NewBorder(nil, nil, n.cover, nil,
|
|
container.New(&layout.CustomPaddedLayout{TopPadding: -2},
|
|
container.New(layout.NewCustomPaddedVBoxLayout(theme.Padding()-13), n.trackName, n.artistName, n.albumName))),
|
|
)
|
|
return widget.NewSimpleRenderer(c)
|
|
}
|
|
|
|
func (n *NowPlayingCard) Update(track mediaprovider.MediaItem) {
|
|
if track == nil {
|
|
n.trackName.SetTextAndToolTip("")
|
|
n.artistName.BuildSegments([]string{}, []string{})
|
|
n.albumName.SetText("")
|
|
n.albumName.SetToolTip("")
|
|
n.cover.Hidden = true
|
|
} else {
|
|
n.cover.Hidden = false
|
|
n.trackName.SetTextAndToolTip(track.Metadata().Name)
|
|
if tr, ok := track.(*mediaprovider.Track); ok {
|
|
n.artistName.BuildSegments(tr.ArtistNames, tr.ArtistIDs)
|
|
n.albumName.SetText(tr.Album)
|
|
n.albumName.SetToolTip(tr.Album)
|
|
n.cover.PlaceholderIcon = myTheme.TracksIcon
|
|
} else {
|
|
n.artistName.BuildSegments([]string{}, []string{})
|
|
n.albumName.SetText("")
|
|
n.albumName.SetToolTip("")
|
|
n.cover.PlaceholderIcon = myTheme.RadioIcon
|
|
}
|
|
}
|
|
n.trackName.Hidden = n.trackName.Text() == ""
|
|
n.trackName.SetMenuBtnEnabled(n.cover.PlaceholderIcon != myTheme.RadioIcon)
|
|
n.artistName.Hidden = len(n.artistName.Segments) == 0
|
|
n.albumName.Hidden = n.albumName.Text == ""
|
|
n.Refresh()
|
|
}
|
|
|
|
func (n *NowPlayingCard) SetImage(cover image.Image) {
|
|
n.cover.SetImage(cover, true)
|
|
}
|
|
|
|
func (n *NowPlayingCard) showMenu(btnPos fyne.Position) {
|
|
if n.menu == nil {
|
|
n.ratingMenu = util.NewRatingSubmenu(n.onSetRating)
|
|
favorite := fyne.NewMenuItem(lang.L("Set favorite"), func() { n.onSetFavorite(true) })
|
|
favorite.Icon = myTheme.FavoriteIcon
|
|
unfavorite := fyne.NewMenuItem(lang.L("Unset favorite"), func() { n.onSetFavorite(false) })
|
|
unfavorite.Icon = myTheme.NotFavoriteIcon
|
|
playlist := fyne.NewMenuItem(lang.L("Add to playlist")+"...", func() { n.onAddToPlaylist() })
|
|
playlist.Icon = myTheme.PlaylistIcon
|
|
info := fyne.NewMenuItem(lang.L("Show info")+"...", func() { n.onShowTrackInfo() })
|
|
info.Icon = theme.InfoIcon()
|
|
share := fyne.NewMenuItem(lang.L("Share")+"...", func() { n.onShare() })
|
|
share.Icon = myTheme.ShareIcon
|
|
|
|
m := fyne.NewMenu("", favorite, unfavorite, n.ratingMenu, playlist, info, share)
|
|
n.menu = widget.NewPopUpMenu(m, fyne.CurrentApp().Driver().CanvasForObject(n))
|
|
}
|
|
menuSize := n.menu.MinSize()
|
|
n.ratingMenu.Disabled = n.DisableRating
|
|
btnPos.Y -= (menuSize.Height + theme.Padding()*3)
|
|
btnPos.X -= menuSize.Width / 2
|
|
n.menu.ShowAtPosition(btnPos)
|
|
}
|