From 0f74bee746407dfe227a729fa6ee64c546b23cbe Mon Sep 17 00:00:00 2001 From: Drew Weymouth Date: Sat, 28 Dec 2024 20:06:15 -0800 Subject: [PATCH] hook up tap handling and action dispatch --- ui/controller/connectactions.go | 10 +++ ui/theme/theme.go | 4 +- ui/widgets/gridview.go | 8 +- ui/widgets/gridviewitem.go | 145 ++++++++++++++++++++++++++------ 4 files changed, 136 insertions(+), 31 deletions(-) diff --git a/ui/controller/connectactions.go b/ui/controller/connectactions.go index d9006c8..e6d08d7 100644 --- a/ui/controller/connectactions.go +++ b/ui/controller/connectactions.go @@ -84,6 +84,11 @@ func (m *Controller) ConnectAlbumGridActions(grid *widgets.GridView) { grid.OnPlay = func(albumID string, shuffle bool) { go m.App.PlaybackManager.PlayAlbum(albumID, 0, shuffle) } + grid.OnFavorite = func(albumID string, favorite bool) { + m.App.ServerManager.Server.SetFavorite(mediaprovider.RatingFavoriteParameters{ + AlbumIDs: []string{albumID}, + }, favorite) + } grid.OnShowItemPage = func(albumID string) { m.NavigateTo(AlbumRoute(albumID)) } @@ -128,6 +133,11 @@ func (m *Controller) ConnectArtistGridActions(grid *widgets.GridView) { go m.DoAddTracksToPlaylistWorkflow( sharedutil.TracksToIDs(m.GetArtistTracks(artistID))) } + grid.OnFavorite = func(artistID string, favorite bool) { + m.App.ServerManager.Server.SetFavorite(mediaprovider.RatingFavoriteParameters{ + ArtistIDs: []string{artistID}, + }, favorite) + } grid.OnDownload = func(artistID string) { go func() { tracks := m.GetArtistTracks(artistID) diff --git a/ui/theme/theme.go b/ui/theme/theme.go index 9d35406..0af1edf 100644 --- a/ui/theme/theme.go +++ b/ui/theme/theme.go @@ -33,8 +33,8 @@ const ( ) var ( - GridViewIconColor color.Color = color.White - GridViewHoveredIconColor color.Color = darkenColor(GridViewIconColor, 0.05) + GridViewHoveredIconColor color.Color = color.White + GridViewIconColor color.Color = darkenColor(color.White, 0.2) AlbumIcon fyne.Resource = theme.NewThemedResource(res.ResDiscSvg) ArtistIcon fyne.Resource = theme.NewThemedResource(res.ResPeopleSvg) diff --git a/ui/widgets/gridview.go b/ui/widgets/gridview.go index f895749..e0e7b05 100644 --- a/ui/widgets/gridview.go +++ b/ui/widgets/gridview.go @@ -133,6 +133,7 @@ type GridViewState struct { OnPlayNext func(id string) OnAddToQueue func(id string) OnAddToPlaylist func(id string) + OnFavorite func(id string, fav bool) OnDownload func(id string) OnShare func(id string) OnShowItemPage func(id string) @@ -280,6 +281,11 @@ func (g *GridView) createNewItemCard() fyne.CanvasObject { card.ImgLoader = util.NewThumbnailLoader(g.imageFetcher, card.Cover.SetImage) card.ImgLoader.OnBeforeLoad = func() { card.Cover.SetImage(nil) } card.OnPlay = func() { g.onPlay(card.ItemID(), false) } + card.OnFavorite = func(fav bool) { + if g.OnFavorite != nil { + g.OnFavorite(card.itemID, fav) + } + } card.OnShowSecondaryPage = func(id string) { if g.OnShowSecondaryPage != nil { g.OnShowSecondaryPage(id) @@ -342,7 +348,7 @@ func (g *GridView) doUpdateItemCard(itemIdx int, card *GridViewItem) { } card.Cover.Im.PlaceholderIcon = g.Placeholder g.stateMutex.Unlock() - card.Update(item) + card.Update(&item) card.ImgLoader.Load(item.CoverArtID) // if user has scrolled near the bottom, fetch more diff --git a/ui/widgets/gridviewitem.go b/ui/widgets/gridviewitem.go index b98413f..689a624 100644 --- a/ui/widgets/gridviewitem.go +++ b/ui/widgets/gridviewitem.go @@ -30,16 +30,20 @@ type coverImage struct { EnableFavorite bool IsFavorite bool - Im *ImagePlaceholder - playbtn *canvas.Image - favoriteButton *canvas.Image - moreButton *canvas.Image - prevTheme fyne.ThemeVariant - bottomPanel *fyne.Container - mouseInsideBtn bool OnPlay func() + OnFavorite func(bool) OnShowPage func() OnShowContextMenu func(fyne.Position) + + Im *ImagePlaceholder + playbtn *canvas.Image + favoriteButton *canvas.Image + moreButton *canvas.Image + prevTheme fyne.ThemeVariant + bottomPanel *fyne.Container + mouseInsidePlay bool + mouseInsideFav bool + mouseInsideMore bool } var ( @@ -131,6 +135,9 @@ func (c *coverImage) CreateRenderer() fyne.WidgetRenderer { } func (c *coverImage) Cursor() desktop.Cursor { + if c.mouseInsideFav || c.mouseInsideMore || c.mouseInsidePlay { + return desktop.DefaultCursor + } return desktop.PointerCursor } @@ -139,10 +146,18 @@ func (c *coverImage) Tapped(e *fyne.PointEvent) { if c.OnPlay != nil { c.OnPlay() } - return - } - if c.OnShowPage != nil { - c.OnShowPage() + } else if c.mouseInsideFav { + if c.OnFavorite != nil { + c.IsFavorite = !c.IsFavorite + c.updateFavoriteIcon(true) + c.OnFavorite(c.IsFavorite) + } + } else if c.mouseInsideMore { + c.TappedSecondary(e) + } else { + if c.OnShowPage != nil { + c.OnShowPage() + } } } @@ -154,36 +169,100 @@ func (c *coverImage) TappedSecondary(e *fyne.PointEvent) { func (a *coverImage) MouseIn(*desktop.MouseEvent) { a.playbtn.Hidden = false - if a.IsFavorite { - a.favoriteButton.Resource = heartFilledResource - } else { - a.favoriteButton.Resource = heartUnfilledResource - } + a.updateFavoriteIcon(false) a.favoriteButton.Hidden = !a.EnableFavorite a.bottomPanel.Hidden = false a.Refresh() } func (a *coverImage) MouseOut() { - a.mouseInsideBtn = false + a.mouseInsidePlay = false + a.mouseInsideFav = false + a.mouseInsideMore = false a.playbtn.Hidden = true a.bottomPanel.Hidden = true a.Refresh() } func (a *coverImage) MouseMoved(e *desktop.MouseEvent) { - if isInside(a.center(), a.playbtn.MinSize().Height/2, e.Position) { - if !a.mouseInsideBtn { + updateMouseInsidePlay := func(in bool) { + if in == a.mouseInsidePlay { + return + } + if in { a.playbtn.SetMinSize(playBtnHoveredSize) - a.playbtn.Refresh() - } - a.mouseInsideBtn = true - } else { - if a.mouseInsideBtn { + } else { a.playbtn.SetMinSize(playBtnSize) - a.playbtn.Refresh() } - a.mouseInsideBtn = false + a.playbtn.Refresh() + a.mouseInsidePlay = in + } + updateMouseInsideFav := func(in bool) { + if in == a.mouseInsideFav { + return + } + if a.IsFavorite { + if in { + a.favoriteButton.Resource = heartFilledHoveredResource + } else { + a.favoriteButton.Resource = heartFilledResource + } + } else { + if in { + a.favoriteButton.Resource = heartUnfilledHoveredResource + } else { + a.favoriteButton.Resource = heartUnfilledResource + } + } + a.favoriteButton.Refresh() + a.mouseInsideFav = in + } + updateMouseInsideMore := func(in bool) { + if in == a.mouseInsideMore { + return + } + if in { + a.moreButton.Resource = moreVerticalHoveredResource + } else { + a.moreButton.Resource = moreVerticalResource + } + a.moreButton.Refresh() + a.mouseInsideMore = in + } + + pad := theme.Padding() + overFavBtn := e.Position.Y > a.Size().Height-inlineIconSize-pad*3 && + e.Position.X > a.Size().Width-inlineIconSize*2-pad*3 && + e.Position.X < a.Size().Height-inlineIconSize-pad + overMoreBtn := e.Position.Y > a.Size().Height-inlineIconSize-pad*3 && + e.Position.X > a.Size().Width-inlineIconSize-pad + if isInside(a.center(), a.playbtn.MinSize().Height/2, e.Position) { + updateMouseInsidePlay(true) + updateMouseInsideFav(false) + updateMouseInsideMore(false) + } else if overFavBtn { + updateMouseInsideFav(true) + updateMouseInsidePlay(false) + updateMouseInsideMore(false) + } else if overMoreBtn { + updateMouseInsideMore(true) + updateMouseInsideFav(false) + updateMouseInsidePlay(false) + } else { + updateMouseInsideFav(false) + updateMouseInsidePlay(false) + updateMouseInsideMore(false) + } +} + +func (a *coverImage) updateFavoriteIcon(refresh bool) { + if a.IsFavorite { + a.favoriteButton.Resource = heartFilledResource + } else { + a.favoriteButton.Resource = heartUnfilledResource + } + if refresh { + a.favoriteButton.Refresh() } } @@ -197,7 +276,7 @@ func (a *coverImage) SetImage(im image.Image) { func (a *coverImage) ResetPlayButton() { a.playbtn.SetMinSize(playBtnSize) - a.mouseInsideBtn = false + a.mouseInsidePlay = false a.playbtn.Hidden = true } @@ -222,6 +301,7 @@ type GridViewItem struct { ShowSuffix bool + model *GridViewItemModel itemID string secondaryIDs []string primaryText *ttwidget.Hyperlink @@ -236,6 +316,7 @@ type GridViewItem struct { ItemIndex int OnPlay func() + OnFavorite func(bool) OnShowContextMenu func(fyne.Position) OnShowItemPage func() OnShowSecondaryPage func(string) @@ -260,6 +341,14 @@ func NewGridViewItem(placeholderResource fyne.Resource) *GridViewItem { g.OnPlay() } } + g.Cover.OnFavorite = func(fav bool) { + if g.model != nil { + g.model.IsFavorite = fav + } + if g.OnFavorite != nil { + g.OnFavorite(fav) + } + } g.Cover.OnShowContextMenu = func(pos fyne.Position) { if g.OnShowContextMenu != nil { g.OnShowContextMenu(pos) @@ -292,7 +381,7 @@ func (g *GridViewItem) NeedsUpdate(model GridViewItemModel) bool { (!g.ShowSuffix && g.secondaryText.Suffix != "") } -func (g *GridViewItem) Update(model GridViewItemModel) { +func (g *GridViewItem) Update(model *GridViewItemModel) { g.Cover.IsFavorite = model.IsFavorite g.Cover.EnableFavorite = model.CanFavorite g.itemID = model.ID