From 5e8c450d769fce5a07a057dff49edeb5de99e9b2 Mon Sep 17 00:00:00 2001 From: Drew Weymouth Date: Thu, 20 Apr 2023 17:25:59 -0700 Subject: [PATCH] add TracksPage --- backend/config.go | 8 ++++ ui/browsing/router.go | 2 + ui/browsing/trackspage.go | 82 +++++++++++++++++++++++++++++++++++++++ ui/controller/routes.go | 5 +++ ui/mainwindow.go | 6 ++- 5 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 ui/browsing/trackspage.go diff --git a/backend/config.go b/backend/config.go index 727e601..b925ef4 100644 --- a/backend/config.go +++ b/backend/config.go @@ -55,6 +55,10 @@ type PlaylistPageConfig struct { TracklistColumns []string } +type TracksPageConfig struct { + TracklistColumns []string +} + type LocalPlaybackConfig struct { AudioDeviceName string AudioExclusive bool @@ -83,6 +87,7 @@ type Config struct { FavoritesPage FavoritesPageConfig NowPlayingPage NowPlayingPageConfig PlaylistPage PlaylistPageConfig + TracksPage TracksPageConfig LocalPlayback LocalPlaybackConfig Scrobbling ScrobbleConfig ReplayGain ReplayGainConfig @@ -117,6 +122,9 @@ func DefaultConfig(appVersionTag string) *Config { PlaylistPage: PlaylistPageConfig{ TracklistColumns: []string{"Artist", "Album", "Time", "Plays"}, }, + TracksPage: TracksPageConfig{ + TracklistColumns: []string{"Artist", "Album", "Time", "Plays"}, + }, LocalPlayback: LocalPlaybackConfig{ // "auto" is the name to pass to MPV for autoselecting the output device AudioDeviceName: "auto", diff --git a/ui/browsing/router.go b/ui/browsing/router.go index 70a34f6..4a603b0 100644 --- a/ui/browsing/router.go +++ b/ui/browsing/router.go @@ -46,6 +46,8 @@ func (r Router) CreatePage(rte controller.Route) Page { return NewPlaylistPage(rte.Arg, &r.App.Config.PlaylistPage, r.Controller, r.App.ServerManager, r.App.PlaybackManager, r.App.ImageManager) case controller.Playlists: return NewPlaylistsPage(r.Controller, r.App.ServerManager) + case controller.Tracks: + return NewTracksPage(r.Controller, &r.App.Config.TracksPage, r.App.LibraryManager) } return nil } diff --git a/ui/browsing/trackspage.go b/ui/browsing/trackspage.go new file mode 100644 index 0000000..3403902 --- /dev/null +++ b/ui/browsing/trackspage.go @@ -0,0 +1,82 @@ +package browsing + +import ( + "supersonic/backend" + "supersonic/res" + "supersonic/ui/controller" + "supersonic/ui/layouts" + "supersonic/ui/widgets" + + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/container" + "fyne.io/fyne/v2/layout" + "fyne.io/fyne/v2/widget" +) + +type TracksPage struct { + widget.BaseWidget + + tracksPageState + + title *widget.RichText + tracklist *widgets.Tracklist + loader widgets.TracklistLoader + playRandom *widget.Button + container *fyne.Container +} + +type tracksPageState struct { + contr *controller.Controller + conf *backend.TracksPageConfig + lm *backend.LibraryManager +} + +func NewTracksPage(contr *controller.Controller, conf *backend.TracksPageConfig, lm *backend.LibraryManager) *TracksPage { + t := &TracksPage{tracksPageState: tracksPageState{contr: contr, conf: conf, lm: lm}} + t.ExtendBaseWidget(t) + t.tracklist = widgets.NewTracklist(nil) + t.tracklist.AutoNumber = true + t.tracklist.SetVisibleColumns(conf.TracklistColumns) + contr.ConnectTracklistActions(t.tracklist) + t.title = widget.NewRichTextWithText("All Tracks") + t.title.Segments[0].(*widget.TextSegment).Style.SizeName = widget.RichTextStyleHeading.SizeName + t.playRandom = widget.NewButtonWithIcon("Play random", res.ResShuffleInvertSvg, t.playRandomSongs) + t.createContainer() + t.Reload() + return t +} + +func (t *TracksPage) createContainer() { + playRandomVbox := container.NewVBox(layout.NewSpacer(), t.playRandom, layout.NewSpacer()) + topRow := container.NewHBox(t.title, playRandomVbox, layout.NewSpacer()) //searchVbox, util.NewHSpace(15)) + t.container = container.New(&layouts.MaxPadLayout{PadLeft: 15, PadRight: 15, PadTop: 5, PadBottom: 15}, + container.NewBorder(topRow, nil, nil, nil, t.tracklist)) +} + +func (t *TracksPage) Route() controller.Route { + return controller.TracksRoute() +} + +func (t *TracksPage) Reload() { + t.tracklist.Clear() + iter := t.lm.AllTracksIterator() + // loads asynchronously + t.loader = widgets.NewTracklistLoader(t.tracklist, iter) +} + +func (t *TracksPage) CreateRenderer() fyne.WidgetRenderer { + return widget.NewSimpleRenderer(t.container) +} + +func (t *TracksPage) Save() SavedPage { + state := t.tracksPageState + return &state +} + +func (s *tracksPageState) Restore() Page { + return NewTracksPage(s.contr, s.conf, s.lm) +} + +func (t *TracksPage) playRandomSongs() { + t.contr.App.PlaybackManager.PlayRandomSongs("") +} diff --git a/ui/controller/routes.go b/ui/controller/routes.go index d50a4df..62bfea3 100644 --- a/ui/controller/routes.go +++ b/ui/controller/routes.go @@ -14,6 +14,7 @@ const ( NowPlaying Playlist Playlists + Tracks ) type Route struct { @@ -52,6 +53,10 @@ func PlaylistsRoute() Route { return Route{Page: Playlists} } +func TracksRoute() Route { + return Route{Page: Tracks} +} + func ArtistsRoute() Route { return Route{Page: Artists} } diff --git a/ui/mainwindow.go b/ui/mainwindow.go index ae9e333..1ad6f4e 100644 --- a/ui/mainwindow.go +++ b/ui/mainwindow.go @@ -26,9 +26,10 @@ var ( ShortcutNavFour = desktop.CustomShortcut{KeyName: fyne.Key4, Modifier: os.ControlModifier} ShortcutNavFive = desktop.CustomShortcut{KeyName: fyne.Key5, Modifier: os.ControlModifier} ShortcutNavSix = desktop.CustomShortcut{KeyName: fyne.Key6, Modifier: os.ControlModifier} + ShortcutNavSeven = desktop.CustomShortcut{KeyName: fyne.Key7, Modifier: os.ControlModifier} NavShortcuts = []desktop.CustomShortcut{ShortcutNavOne, ShortcutNavTwo, ShortcutNavThree, - ShortcutNavFour, ShortcutNavFive, ShortcutNavSix} + ShortcutNavFour, ShortcutNavFive, ShortcutNavSix, ShortcutNavSeven} ) type MainWindow struct { @@ -187,6 +188,9 @@ func (m *MainWindow) addNavigationButtons() { m.BrowsingPane.AddNavigationButton(res.ResPlaylistInvertPng, func() { m.Router.NavigateTo(controller.PlaylistsRoute()) }) + m.BrowsingPane.AddNavigationButton(res.ResMusicnotesInvertPng, func() { + m.Router.NavigateTo(controller.TracksRoute()) + }) } func (m *MainWindow) addShortcuts() {