From 105adf4e08623f1e90489faecbc68389120ce7c8 Mon Sep 17 00:00:00 2001 From: Drew Weymouth Date: Wed, 28 Dec 2022 17:48:28 -0800 Subject: [PATCH] Add sort order selector to albums page --- backend/albumiterator.go | 44 +++++++++++++++++++----- ui/albumspage.go | 73 ++++++++++++++++++++++++++++++++++------ ui/browsingpane.go | 23 +------------ ui/widgets/hspace.go | 27 +++++++++++++++ 4 files changed, 125 insertions(+), 42 deletions(-) create mode 100644 ui/widgets/hspace.go diff --git a/backend/albumiterator.go b/backend/albumiterator.go index 3443d23..a5d6ace 100644 --- a/backend/albumiterator.go +++ b/backend/albumiterator.go @@ -26,22 +26,48 @@ func NewLibraryManager(s *ServerManager) *LibraryManager { } } -func (l *LibraryManager) RecentlyAddedIter() AlbumIterator { - return l.newBaseIter("newest") -} +type AlbumSortOrder string -func (l *LibraryManager) RecentlyPlayedIter() AlbumIterator { - return l.newBaseIter("recent") +const ( + RecentlyAdded AlbumSortOrder = "Recently Added" + RecentlyPlayed AlbumSortOrder = "Recently Played" + FrequentlyPlayed AlbumSortOrder = "Frequently Played" + TitleAZ AlbumSortOrder = "Title (A-Z)" + ArtistAZ AlbumSortOrder = "Artist (A-Z)" +) + +var ( + AlbumSortOrders []string = []string{ + string(RecentlyAdded), + string(RecentlyPlayed), + string(FrequentlyPlayed), + string(TitleAZ), + string(ArtistAZ), + } +) + +func (l *LibraryManager) AlbumsIter(sort AlbumSortOrder) AlbumIterator { + switch sort { + case RecentlyAdded: + return l.newBaseIter("newest") + case RecentlyPlayed: + return l.newBaseIter("recent") + case FrequentlyPlayed: + return l.newBaseIter("frequent") + case TitleAZ: + return l.newBaseIter("alphabeticalByName") + case ArtistAZ: + return l.newBaseIter("alphabeticalByArtist") + default: + log.Printf("Undefined album sort order: %s", sort) + return nil + } } func (l *LibraryManager) StarredIter() AlbumIterator { return l.newBaseIter("starred") } -func (l *LibraryManager) FrequentlyPlayedIter() AlbumIterator { - return l.newBaseIter("frequent") -} - func (l *LibraryManager) SearchIter(query string) AlbumIterator { return l.newSearchIter(query) } diff --git a/ui/albumspage.go b/ui/albumspage.go index 8777529..221bcb1 100644 --- a/ui/albumspage.go +++ b/ui/albumspage.go @@ -2,9 +2,12 @@ package ui import ( "supersonic/backend" + "supersonic/ui/widgets" "fyne.io/fyne/v2" "fyne.io/fyne/v2/container" + "fyne.io/fyne/v2/layout" + "fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/widget" ) @@ -13,12 +16,36 @@ var _ fyne.Widget = (*AlbumsPage)(nil) type AlbumsPage struct { widget.BaseWidget - im *backend.ImageManager - lm *backend.LibraryManager - grid *AlbumGrid - searchGrid *AlbumGrid - gridContainer *fyne.Container - OnPlayAlbum func(string) + im *backend.ImageManager + lm *backend.LibraryManager + grid *AlbumGrid + searchGrid *AlbumGrid + searchText string + titleDisp *widget.RichText + sortOrder *selectWidget + container *fyne.Container + OnPlayAlbum func(string) +} + +type selectWidget struct { + widget.Select + height float32 +} + +func NewSelect(options []string, onChanged func(string)) *selectWidget { + s := &selectWidget{ + Select: widget.Select{ + Options: options, + OnChanged: onChanged, + }, + } + s.height = widget.NewSelect(nil, nil).MinSize().Height + s.ExtendBaseWidget(s) + return s +} + +func (s *selectWidget) MinSize() fyne.Size { + return fyne.NewSize(170, s.height) } func NewAlbumsPage(title string, lm *backend.LibraryManager, im *backend.ImageManager) *AlbumsPage { @@ -27,22 +54,38 @@ func NewAlbumsPage(title string, lm *backend.LibraryManager, im *backend.ImageMa im: im, } a.ExtendBaseWidget(a) - a.grid = NewAlbumGrid(lm.RecentlyAddedIter(), im.GetAlbumThumbnail) + + a.titleDisp = widget.NewRichTextWithText(title) + a.titleDisp.Segments[0].(*widget.TextSegment).Style = widget.RichTextStyle{ + SizeName: theme.SizeNameHeadingText, + } + a.sortOrder = NewSelect(backend.AlbumSortOrders, nil) + a.sortOrder.Selected = a.sortOrder.Options[0] + a.sortOrder.OnChanged = a.onSortOrderChanged + sortVbox := container.NewVBox(layout.NewSpacer(), a.sortOrder, layout.NewSpacer()) + a.grid = NewAlbumGrid(lm.AlbumsIter(backend.AlbumSortOrder(a.sortOrder.Selected)), im.GetAlbumThumbnail) a.grid.OnPlayAlbum = a.onPlayAlbum - a.gridContainer = container.NewMax(a.grid) + a.container = container.NewBorder( + container.NewHBox(widgets.NewHSpace(15), a.titleDisp, sortVbox), + nil, + nil, + nil, + a.grid, + ) return a } func (a *AlbumsPage) OnSearched(query string) { + a.searchText = query if query == "" { - a.gridContainer.Objects[0] = a.grid + a.container.Objects[0] = a.grid a.searchGrid = nil a.Refresh() return } a.searchGrid = NewAlbumGrid(a.lm.SearchIter(query), a.im.GetAlbumThumbnail) a.searchGrid.OnPlayAlbum = a.onPlayAlbum - a.gridContainer.Objects[0] = a.searchGrid + a.container.Objects[0] = a.searchGrid a.Refresh() } @@ -52,7 +95,15 @@ func (a *AlbumsPage) onPlayAlbum(albumID string) { } } +func (a *AlbumsPage) onSortOrderChanged(order string) { + a.grid = NewAlbumGrid(a.lm.AlbumsIter(backend.AlbumSortOrder(order)), a.im.GetAlbumThumbnail) + if a.searchText == "" { + a.container.Objects[0] = a.grid + a.Refresh() + } +} + func (a *AlbumsPage) CreateRenderer() fyne.WidgetRenderer { a.ExtendBaseWidget(a) - return widget.NewSimpleRenderer(a.gridContainer) + return widget.NewSimpleRenderer(a.container) } diff --git a/ui/browsingpane.go b/ui/browsingpane.go index 764b339..110a97e 100644 --- a/ui/browsingpane.go +++ b/ui/browsingpane.go @@ -7,7 +7,6 @@ import ( "fyne.io/fyne/v2" "fyne.io/fyne/v2/container" - "fyne.io/fyne/v2/layout" "fyne.io/fyne/v2/widget" ) @@ -35,26 +34,6 @@ type blankPage struct { widget.Separator } -type hspace struct { - widget.BaseWidget - - Width float32 -} - -func newHSpace(w float32) *hspace { - h := &hspace{Width: w} - h.ExtendBaseWidget(h) - return h -} - -func (h *hspace) MinSize() fyne.Size { - return fyne.NewSize(h.Width, 0) -} - -func (h *hspace) CreateRenderer() fyne.WidgetRenderer { - return widget.NewSimpleRenderer(layout.NewSpacer()) -} - func NewBrowsingPane() *BrowsingPane { b := &BrowsingPane{} b.ExtendBaseWidget(b) @@ -62,7 +41,7 @@ func NewBrowsingPane() *BrowsingPane { b.searchBar.OnTextChanged = b.onSearchTextChanged b.curPage = &blankPage{} b.container = container.NewBorder( - container.NewHBox(newHSpace(15), b.searchBar), + container.NewHBox(widgets.NewHSpace(15), b.searchBar), nil, nil, nil, b.curPage) return b } diff --git a/ui/widgets/hspace.go b/ui/widgets/hspace.go new file mode 100644 index 0000000..8ea39c3 --- /dev/null +++ b/ui/widgets/hspace.go @@ -0,0 +1,27 @@ +package widgets + +import ( + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/layout" + "fyne.io/fyne/v2/widget" +) + +type HSpace struct { + widget.BaseWidget + + Width float32 +} + +func NewHSpace(w float32) *HSpace { + h := &HSpace{Width: w} + h.ExtendBaseWidget(h) + return h +} + +func (h *HSpace) MinSize() fyne.Size { + return fyne.NewSize(h.Width, 0) +} + +func (h *HSpace) CreateRenderer() fyne.WidgetRenderer { + return widget.NewSimpleRenderer(layout.NewSpacer()) +}