ui refactoring (create controller pkg) + beginning of add to playlist

This commit is contained in:
Drew Weymouth
2023-02-09 18:59:49 -08:00
parent 46c87944db
commit cd6dce5e3f
6 changed files with 109 additions and 74 deletions
+6 -5
View File
@@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"log" "log"
"supersonic/backend" "supersonic/backend"
"supersonic/ui/controller"
"supersonic/ui/layouts" "supersonic/ui/layouts"
"supersonic/ui/util" "supersonic/ui/util"
"supersonic/ui/widgets" "supersonic/ui/widgets"
@@ -35,7 +36,7 @@ type albumPageState struct {
pm *backend.PlaybackManager pm *backend.PlaybackManager
im *backend.ImageManager im *backend.ImageManager
sm *backend.ServerManager sm *backend.ServerManager
popUpProvider util.PopUpProvider contr *controller.Controller
nav func(Route) nav func(Route)
} }
@@ -45,7 +46,7 @@ func NewAlbumPage(
pm *backend.PlaybackManager, pm *backend.PlaybackManager,
lm *backend.LibraryManager, lm *backend.LibraryManager,
im *backend.ImageManager, im *backend.ImageManager,
popUpProvider util.PopUpProvider, contr *controller.Controller,
nav func(Route), nav func(Route),
) *AlbumPage { ) *AlbumPage {
a := &AlbumPage{ a := &AlbumPage{
@@ -56,7 +57,7 @@ func NewAlbumPage(
lm: lm, lm: lm,
im: im, im: im,
nav: nav, nav: nav,
popUpProvider: popUpProvider, contr: contr,
}, },
} }
a.ExtendBaseWidget(a) a.ExtendBaseWidget(a)
@@ -241,7 +242,7 @@ func (a *AlbumPageHeader) showPopUpCover() {
log.Printf("error getting full size album cover: %s", err.Error()) log.Printf("error getting full size album cover: %s", err.Error())
return return
} }
util.ShowPopUpImage(cover, a.page.popUpProvider) a.page.contr.ShowPopUpImage(cover)
} }
func formatMiscLabelStr(a *subsonic.AlbumID3) string { func formatMiscLabelStr(a *subsonic.AlbumID3) string {
@@ -249,5 +250,5 @@ func formatMiscLabelStr(a *subsonic.AlbumID3) string {
} }
func (s *albumPageState) Restore() Page { func (s *albumPageState) Restore() Page {
return NewAlbumPage(s.albumID, s.sm, s.pm, s.lm, s.im, s.popUpProvider, s.nav) return NewAlbumPage(s.albumID, s.sm, s.pm, s.lm, s.im, s.contr, s.nav)
} }
+6 -5
View File
@@ -7,6 +7,7 @@ import (
"strings" "strings"
"supersonic/backend" "supersonic/backend"
"supersonic/res" "supersonic/res"
"supersonic/ui/controller"
"supersonic/ui/layouts" "supersonic/ui/layouts"
"supersonic/ui/util" "supersonic/ui/util"
"supersonic/ui/widgets" "supersonic/ui/widgets"
@@ -26,7 +27,7 @@ type artistPageState struct {
sm *backend.ServerManager sm *backend.ServerManager
im *backend.ImageManager im *backend.ImageManager
nav func(Route) nav func(Route)
popUpProvider util.PopUpProvider contr *controller.Controller
} }
type ArtistPage struct { type ArtistPage struct {
@@ -40,13 +41,13 @@ type ArtistPage struct {
OnPlayAlbum func(string, int) OnPlayAlbum func(string, int)
} }
func NewArtistPage(artistID string, sm *backend.ServerManager, im *backend.ImageManager, popUp util.PopUpProvider, nav func(Route)) *ArtistPage { func NewArtistPage(artistID string, sm *backend.ServerManager, im *backend.ImageManager, contr *controller.Controller, nav func(Route)) *ArtistPage {
a := &ArtistPage{artistPageState: artistPageState{ a := &ArtistPage{artistPageState: artistPageState{
artistID: artistID, artistID: artistID,
sm: sm, sm: sm,
im: im, im: im,
nav: nav, nav: nav,
popUpProvider: popUp, contr: contr,
}} }}
a.ExtendBaseWidget(a) a.ExtendBaseWidget(a)
a.header = NewArtistPageHeader(a, nav) a.header = NewArtistPageHeader(a, nav)
@@ -111,7 +112,7 @@ func (a *ArtistPage) CreateRenderer() fyne.WidgetRenderer {
} }
func (s *artistPageState) Restore() Page { func (s *artistPageState) Restore() Page {
return NewArtistPage(s.artistID, s.sm, s.im, s.popUpProvider, s.nav) return NewArtistPage(s.artistID, s.sm, s.im, s.contr, s.nav)
} }
type ArtistPageHeader struct { type ArtistPageHeader struct {
@@ -190,7 +191,7 @@ func (a *ArtistPageHeader) UpdateInfo(info *subsonic.ArtistInfo2) {
return return
} }
a.artistImage.OnTapped = func() { a.artistImage.OnTapped = func() {
util.ShowPopUpImage(im, a.artistPage.popUpProvider) a.artistPage.contr.ShowPopUpImage(im)
} }
a.artistImage.SetImage(im, true /*tappable*/) a.artistImage.SetImage(im, true /*tappable*/)
} }
+6 -21
View File
@@ -2,10 +2,8 @@ package browsing
import ( import (
"supersonic/backend" "supersonic/backend"
"supersonic/ui/controller"
"supersonic/ui/util" "supersonic/ui/util"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/widget"
) )
type PageName int type PageName int
@@ -69,42 +67,29 @@ type NavigationHandler interface {
type Router struct { type Router struct {
App *backend.App App *backend.App
MainWindow fyne.Window Controller *controller.Controller
Nav NavigationHandler Nav NavigationHandler
pop util.PopUpProvider pop util.PopUpProvider
} }
func NewRouter(app *backend.App, mainWindow fyne.Window, nav NavigationHandler) Router { func NewRouter(app *backend.App, controller *controller.Controller, nav NavigationHandler) Router {
r := Router{ r := Router{
App: app, App: app,
MainWindow: mainWindow, Controller: controller,
Nav: nav, Nav: nav,
} }
r.pop = &popUpProvider{window: r.MainWindow}
return r return r
} }
type popUpProvider struct {
window fyne.Window
}
func (p *popUpProvider) CreatePopUp(obj fyne.CanvasObject) *widget.PopUp {
return widget.NewPopUp(obj, p.window.Canvas())
}
func (p *popUpProvider) WindowSize() fyne.Size {
return p.window.Canvas().Size()
}
func (r Router) CreatePage(rte Route) Page { func (r Router) CreatePage(rte Route) Page {
switch rte.Page { switch rte.Page {
case Album: case Album:
return NewAlbumPage(rte.Arg, r.App.ServerManager, r.App.PlaybackManager, r.App.LibraryManager, r.App.ImageManager, r.pop, r.OpenRoute) return NewAlbumPage(rte.Arg, r.App.ServerManager, r.App.PlaybackManager, r.App.LibraryManager, r.App.ImageManager, r.Controller, r.OpenRoute)
case Albums: case Albums:
return NewAlbumsPage("Albums", rte.Arg, r.App.LibraryManager, r.App.ImageManager, r.OpenRoute) return NewAlbumsPage("Albums", rte.Arg, r.App.LibraryManager, r.App.ImageManager, r.OpenRoute)
case Artist: case Artist:
return NewArtistPage(rte.Arg, r.App.ServerManager, r.App.ImageManager, r.pop, r.OpenRoute) return NewArtistPage(rte.Arg, r.App.ServerManager, r.App.ImageManager, r.Controller, r.OpenRoute)
case Artists: case Artists:
return NewArtistsGenresPage(false, r.App.ServerManager, r.OpenRoute) return NewArtistsGenresPage(false, r.App.ServerManager, r.OpenRoute)
case Favorites: case Favorites:
+64
View File
@@ -0,0 +1,64 @@
package controller
import (
"image"
"log"
"supersonic/backend"
"supersonic/ui/dialogs"
"supersonic/ui/util"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/widget"
"github.com/dweymouth/go-subsonic"
)
type Controller struct {
MainWindow fyne.Window
App *backend.App
}
func (m *Controller) ShowPopUpImage(img image.Image) {
im := canvas.NewImageFromImage(img)
im.FillMode = canvas.ImageFillContain
pop := widget.NewPopUp(im, m.MainWindow.Canvas())
s := m.MainWindow.Canvas().Size()
var popS fyne.Size
if asp := util.ImageAspect(img); s.Width/s.Height > asp {
// window height is limiting factor
h := s.Height * 0.8
popS = fyne.NewSize(h*asp, h)
} else {
w := s.Width * 0.8
popS = fyne.NewSize(w, w*(1/asp))
}
pop.Resize(popS)
pop.ShowAtPosition(fyne.NewPos(
(s.Width-popS.Width)/2,
(s.Height-popS.Height)/2,
))
}
// Show dialog to prompt for playlist.
// Depending on the results of that dialog, potentially create a new playlist
// Add tracks to the user-specified playlist
func (m *Controller) DoAddTracksToPlaylistWorkflow(tracks []*subsonic.Child) {
pls, err := m.App.LibraryManager.GetUserOwnedPlaylists()
if err != nil {
// TODO: surface this error to user
log.Printf("error getting user-owned playlists: %s", err.Error())
return
}
plNames := make([]string, 0, len(pls))
for _, pl := range pls {
plNames = append(plNames, pl.Name)
}
dlg := dialogs.NewAddToPlaylistDialog("Add to Playlist", plNames)
pop := widget.NewModalPopUp(dlg, m.MainWindow.Canvas())
dlg.OnCanceled = pop.Hide
dlg.OnSubmit = func(playlistChoice int, newPlaylistName string) {
pop.Hide()
// call server to add tracks to playlist
}
}
+7 -1
View File
@@ -4,6 +4,7 @@ import (
"supersonic/backend" "supersonic/backend"
"supersonic/res" "supersonic/res"
"supersonic/ui/browsing" "supersonic/ui/browsing"
"supersonic/ui/controller"
"supersonic/ui/os" "supersonic/ui/os"
"supersonic/ui/widgets" "supersonic/ui/widgets"
@@ -26,6 +27,7 @@ type MainWindow struct {
App *backend.App App *backend.App
Router browsing.Router Router browsing.Router
Controller *controller.Controller
BrowsingPane *browsing.BrowsingPane BrowsingPane *browsing.BrowsingPane
BottomPanel *BottomPanel BottomPanel *BottomPanel
@@ -43,7 +45,11 @@ func NewMainWindow(fyneApp fyne.App, appName string, app *backend.App, size fyne
BrowsingPane: browsing.NewBrowsingPane(app), BrowsingPane: browsing.NewBrowsingPane(app),
} }
m.Router = browsing.NewRouter(app, m.Window, m.BrowsingPane) m.Controller = &controller.Controller{
MainWindow: m.Window,
App: app,
}
m.Router = browsing.NewRouter(app, m.Controller, m.BrowsingPane)
m.BottomPanel = NewBottomPanel(app.Player, m.Router.OpenRoute) m.BottomPanel = NewBottomPanel(app.Player, m.Router.OpenRoute)
m.BottomPanel.SetPlaybackManager(app.PlaybackManager) m.BottomPanel.SetPlaybackManager(app.PlaybackManager)
m.BottomPanel.ImageManager = app.ImageManager m.BottomPanel.ImageManager = app.ImageManager
-22
View File
@@ -7,7 +7,6 @@ import (
"strings" "strings"
"fyne.io/fyne/v2" "fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/widget" "fyne.io/fyne/v2/widget"
"golang.org/x/net/html" "golang.org/x/net/html"
) )
@@ -33,27 +32,6 @@ type PopUpProvider interface {
WindowSize() fyne.Size WindowSize() fyne.Size
} }
func ShowPopUpImage(img image.Image, popUpProvider PopUpProvider) {
im := canvas.NewImageFromImage(img)
im.FillMode = canvas.ImageFillContain
pop := popUpProvider.CreatePopUp(im)
s := popUpProvider.WindowSize()
var popS fyne.Size
if asp := ImageAspect(img); s.Width/s.Height > asp {
// window height is limiting factor
h := s.Height * 0.8
popS = fyne.NewSize(h*asp, h)
} else {
w := s.Width * 0.8
popS = fyne.NewSize(w, w*(1/asp))
}
pop.Resize(popS)
pop.ShowAtPosition(fyne.NewPos(
(s.Width-popS.Width)/2,
(s.Height-popS.Height)/2,
))
}
func RichTextSegsFromHTMLString(s string) []widget.RichTextSegment { func RichTextSegsFromHTMLString(s string) []widget.RichTextSegment {
tokr := html.NewTokenizer(strings.NewReader(s)) tokr := html.NewTokenizer(strings.NewReader(s))
var segs []widget.RichTextSegment var segs []widget.RichTextSegment