diff --git a/ui/browsing/fullscreenpage.go b/ui/browsing/fullscreenpage.go index d30d7c6..bb28d01 100644 --- a/ui/browsing/fullscreenpage.go +++ b/ui/browsing/fullscreenpage.go @@ -5,6 +5,7 @@ import ( "github.com/dweymouth/supersonic/backend/mediaprovider" "github.com/dweymouth/supersonic/sharedutil" "github.com/dweymouth/supersonic/ui/controller" + "github.com/dweymouth/supersonic/ui/layouts" "github.com/dweymouth/supersonic/ui/util" "github.com/dweymouth/supersonic/ui/widgets" @@ -53,7 +54,10 @@ func NewFullscreenPage( func (a *FullscreenPage) CreateRenderer() fyne.WidgetRenderer { container := container.NewGridWithColumns(2, - a.card, + container.New(&layouts.PercentPadLayout{ + LeftRightObjectPercent: .8, + TopBottomObjectPercent: .8, + }, a.card), layout.NewSpacer(), ) return widget.NewSimpleRenderer(container) diff --git a/ui/layouts/percentpadlayout.go b/ui/layouts/percentpadlayout.go new file mode 100644 index 0000000..1ec8411 --- /dev/null +++ b/ui/layouts/percentpadlayout.go @@ -0,0 +1,44 @@ +package layouts + +import "fyne.io/fyne/v2" + +// Centers and pads a given item by a percent (0-1) +// of the width and height that should be taken by the objects +type PercentPadLayout struct { + LeftRightObjectPercent float32 + TopBottomObjectPercent float32 +} + +func (l *PercentPadLayout) MinSize(objects []fyne.CanvasObject) fyne.Size { + var objMinSize fyne.Size + for _, obj := range objects { + objMinSize = objMinSize.Max(obj.MinSize()) + } + if objMinSize.IsZero() { + return objMinSize + } + + return fyne.Size{ + Width: objMinSize.Width / l.LeftRightObjectPercent, + Height: objMinSize.Height / l.LeftRightObjectPercent, + } +} + +func (l *PercentPadLayout) Layout(objects []fyne.CanvasObject, size fyne.Size) { + if len(objects) == 0 { + return + } + + objSize := fyne.NewSize( + size.Width*l.LeftRightObjectPercent, + size.Height*l.TopBottomObjectPercent, + ) + objPos := fyne.NewPos( + size.Width*(1-l.LeftRightObjectPercent)/2, + size.Height*(1-l.TopBottomObjectPercent)/2, + ) + for _, obj := range objects { + obj.Resize(objSize) + obj.Move(objPos) + } +} diff --git a/ui/widgets/captionedimage.go b/ui/widgets/captionedimage.go index 0c9f4e3..83d858d 100644 --- a/ui/widgets/captionedimage.go +++ b/ui/widgets/captionedimage.go @@ -59,14 +59,14 @@ func (c *captionedImageRenderer) Layout(s fyne.Size) { // aspect ratio of Content if it were maxed out maxedAspect := s.Width / contentMaxedHeight if maxedAspect > aspect { - // Content will use full height, but not full width - contentW := contentMaxedHeight * aspect - content.Resize(fyne.NewSize(contentW, contentMaxedHeight)) - contentX := (s.Width - contentW) / 2 - content.Move(fyne.NewPos(contentX, 0)) + // Will use full height, but not full width + width := contentMaxedHeight * aspect + content.Resize(fyne.NewSize(width, contentMaxedHeight)) + xStart := (s.Width - width) / 2 + content.Move(fyne.NewPos(xStart, 0)) if caption != nil { - caption.Resize(fyne.NewSize(s.Width, captionHeight)) - caption.Move(fyne.NewPos(0, contentMaxedHeight)) + caption.Resize(fyne.NewSize(width, captionHeight)) + caption.Move(fyne.NewPos(xStart, contentMaxedHeight)) } return } diff --git a/ui/widgets/imageplaceholder.go b/ui/widgets/imageplaceholder.go index 03c3a82..de552ae 100644 --- a/ui/widgets/imageplaceholder.go +++ b/ui/widgets/imageplaceholder.go @@ -51,6 +51,13 @@ func NewImagePlaceholder(centerIcon fyne.Resource, minSize float32) *ImagePlaceh return i } +func (i *ImagePlaceholder) Aspect() float32 { + if i.image != nil { + return i.imageDisp.Aspect() + } + return 1.0 +} + func (i *ImagePlaceholder) HaveImage() bool { return i.image != nil } diff --git a/ui/widgets/largenowplayingcard.go b/ui/widgets/largenowplayingcard.go index fda8d89..768f2d6 100644 --- a/ui/widgets/largenowplayingcard.go +++ b/ui/widgets/largenowplayingcard.go @@ -6,13 +6,14 @@ import ( "fyne.io/fyne/v2" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/widget" + "github.com/dweymouth/supersonic/ui/layouts" "github.com/dweymouth/supersonic/ui/theme" ) // 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 LargeNowPlayingCard struct { - widget.BaseWidget + CaptionedImage DisableRating bool @@ -35,9 +36,17 @@ func NewLargeNowPlayingCard() *LargeNowPlayingCard { trackName: widget.NewHyperlink("", nil), artistName: NewMultiHyperlink(), albumName: widget.NewHyperlink("", nil), + cover: NewImagePlaceholder(theme.TracksIcon, 300), } n.ExtendBaseWidget(n) - n.cover = NewImagePlaceholder(theme.TracksIcon, 300) + // set up the layout + n.Content = n.cover + n.Caption = container.New(&layouts.VboxCustomPadding{ExtraPad: -13}, + n.trackName, + n.albumName, + n.artistName, + ) + n.trackName.Hidden = true n.albumName.Hidden = true n.albumName.Truncation = fyne.TextTruncateEllipsis @@ -86,17 +95,6 @@ func (n *LargeNowPlayingCard) onSetRating(rating int) { } } -func (n *LargeNowPlayingCard) CreateRenderer() fyne.WidgetRenderer { - vbox := container.NewVBox( - n.trackName, - n.albumName, - n.artistName, - ) - c := container.NewCenter( - container.NewBorder(nil, vbox, nil, nil, n.cover)) - return widget.NewSimpleRenderer(c) -} - func (n *LargeNowPlayingCard) Update(track string, artists, artistIDs []string, album string) { n.trackName.SetText(track) n.trackName.Hidden = track == ""