From 0fd8b4621bf2fc4d5a3b6cddaaae1bb4782827d3 Mon Sep 17 00:00:00 2001 From: Drew Weymouth Date: Wed, 28 May 2025 09:21:07 -0700 Subject: [PATCH] Fix #625: Allow customization of grid card size --- backend/app.go | 7 +++++++ backend/config.go | 8 ++++++++ res/translations/en.json | 1 + ui/dialogs/settingsdialog.go | 11 +++++++++++ ui/widgets/gridview.go | 3 +++ ui/widgets/gridviewitem.go | 5 +++++ ui/widgets/imageplaceholder.go | 18 ++++++++++++++---- 7 files changed, 49 insertions(+), 4 deletions(-) diff --git a/backend/app.go b/backend/app.go index 86ace5c..b63bf38 100644 --- a/backend/app.go +++ b/backend/app.go @@ -36,6 +36,8 @@ const ( var ( ErrNoServers = errors.New("no servers set up") ErrAnotherInstance = errors.New("another instance is running") + + appInstance *App ) type App struct { @@ -204,9 +206,14 @@ func StartupApp(appName, displayAppName, appVersion, appVersionTag, latestReleas a.startConfigWriter(a.bgrndCtx) + appInstance = a return a, nil } +func AppInstance() *App { + return appInstance +} + func (a *App) IsFirstLaunch() bool { return a.isFirstLaunch } diff --git a/backend/config.go b/backend/config.go index 9edccc6..44c4891 100644 --- a/backend/config.go +++ b/backend/config.go @@ -89,6 +89,10 @@ type FavoritesPageConfig struct { ShowAlbumYears bool } +type GridViewConfig struct { + CardSize float32 +} + type PlaylistPageConfig struct { TracklistColumns []string } @@ -154,6 +158,7 @@ type Config struct { ArtistPage ArtistPageConfig ArtistsPage ArtistsPageConfig FavoritesPage FavoritesPageConfig + GridView GridViewConfig PlaylistPage PlaylistPageConfig PlaylistsPage PlaylistsPageConfig TracksPage TracksPageConfig @@ -215,6 +220,9 @@ func DefaultConfig(appVersionTag string) *Config { InitialView: "Albums", ShowAlbumYears: false, }, + GridView: GridViewConfig{ + CardSize: 200, + }, PlaylistPage: PlaylistPageConfig{ TracklistColumns: []string{"Album", "Time", "Plays"}, }, diff --git a/res/translations/en.json b/res/translations/en.json index 1ced3f4..2c8ae9d 100644 --- a/res/translations/en.json +++ b/res/translations/en.json @@ -97,6 +97,7 @@ "Genres": "Genres", "Github page": "Github page", "Go to release page": "Go to release page", + "Grid card size": "Grid card size", "Hide": "Hide", "Home": "Home", "Home Page": "Home Page", diff --git a/ui/dialogs/settingsdialog.go b/ui/dialogs/settingsdialog.go index 1198b12..94926e2 100644 --- a/ui/dialogs/settingsdialog.go +++ b/ui/dialogs/settingsdialog.go @@ -519,6 +519,16 @@ func (s *SettingsDialog) createAppearanceTab(window fyne.Window) *container.TabI }) disableDPI.Checked = s.config.Application.DisableDPIDetection + gridCardSize := widget.NewSlider(150, 350) + gridCardSize.SetValue(float64(s.config.GridView.CardSize)) + gridCardSize.Step = 10 + gridCardSize.OnChanged = func(f float64) { + s.config.GridView.CardSize = float32(f) + if s.OnPageNeedsRefresh != nil { + s.OnPageNeedsRefresh() + } + } + return container.NewTabItem(lang.L("Appearance"), container.NewVBox( util.NewHSpace(0), // insert a theme.Padding amount of space at top container.NewBorder(nil, nil, widget.NewLabel(lang.L("Theme")), /*left*/ @@ -527,6 +537,7 @@ func (s *SettingsDialog) createAppearanceTab(window fyne.Window) *container.TabI ), widget.NewRichText(&widget.TextSegment{Text: lang.L("UI Scaling"), Style: util.BoldRichTextStyle}), uiScaleRadio, + container.NewBorder(nil, nil, widget.NewLabel(lang.L("Grid card size")), nil, gridCardSize), disableDPI, s.newSectionSeparator(), widget.NewRichText(&widget.TextSegment{Text: lang.L("Application font"), Style: util.BoldRichTextStyle}), diff --git a/ui/widgets/gridview.go b/ui/widgets/gridview.go index 5855654..cd02fc3 100644 --- a/ui/widgets/gridview.go +++ b/ui/widgets/gridview.go @@ -9,6 +9,7 @@ import ( "fyne.io/fyne/v2/lang" + "github.com/dweymouth/supersonic/backend" "github.com/dweymouth/supersonic/backend/mediaprovider" "github.com/dweymouth/supersonic/sharedutil" myTheme "github.com/dweymouth/supersonic/ui/theme" @@ -282,6 +283,7 @@ func (g *GridView) createGridWrap() { // update func func(itemID widget.GridWrapItemID, obj fyne.CanvasObject) { ac := obj.(*GridViewItem) + ac.SetSize(backend.AppInstance().Config.GridView.CardSize) g.doUpdateItemCard(int(itemID), ac) }, ) @@ -289,6 +291,7 @@ func (g *GridView) createGridWrap() { func (g *GridView) createNewItemCard() fyne.CanvasObject { card := NewGridViewItem(g.Placeholder) + card.SetSize(backend.AppInstance().Config.GridView.CardSize) card.ItemIndex = -1 card.ImgLoader = util.NewThumbnailLoader(g.imageFetcher, card.Cover.SetImage) card.ImgLoader.OnBeforeLoad = func() { card.Cover.SetImage(nil) } diff --git a/ui/widgets/gridviewitem.go b/ui/widgets/gridviewitem.go index 6e7563a..9559fd4 100644 --- a/ui/widgets/gridviewitem.go +++ b/ui/widgets/gridviewitem.go @@ -517,6 +517,10 @@ func (g *GridViewItem) Update(model *GridViewItemModel) { } } +func (g *GridViewItem) SetSize(sideDim float32) { + g.Cover.Im.SetMinSize(fyne.NewSquareSize(sideDim)) +} + func (g *GridViewItem) Refresh() { if g.focused { g.focusRect.Show() @@ -531,6 +535,7 @@ func (g *GridViewItem) Refresh() { g.secondaryText.Suffix = "" g.secondaryText.Refresh() } + canvas.Refresh(g) } func (g *GridViewItem) ItemID() string { diff --git a/ui/widgets/imageplaceholder.go b/ui/widgets/imageplaceholder.go index b7bf6c0..5cc2365 100644 --- a/ui/widgets/imageplaceholder.go +++ b/ui/widgets/imageplaceholder.go @@ -24,18 +24,18 @@ type ImagePlaceholder struct { image image.Image iconImage *canvas.Image border *myTheme.ThemedRectangle - minSize float32 + minSize fyne.Size OnTapped func(*fyne.PointEvent) OnTappedSecondary func(*fyne.PointEvent) } func NewImagePlaceholder(centerIcon fyne.Resource, minSize float32) *ImagePlaceholder { - i := &ImagePlaceholder{minSize: minSize, PlaceholderIcon: centerIcon} + i := &ImagePlaceholder{minSize: fyne.NewSquareSize(minSize), PlaceholderIcon: centerIcon} i.ExtendBaseWidget(i) i.iconImage = canvas.NewImageFromResource(centerIcon) i.iconImage.FillMode = canvas.ImageFillContain - i.iconImage.SetMinSize(fyne.NewSize(minSize/4, minSize/4)) + i.iconImage.SetMinSize(fyne.NewSquareSize(minSize / 4)) i.imageDisp = NewTappableImage(i.onTapped) i.imageDisp.OnTappedSecondary = i.onTappedSecondary i.imageDisp.FillMode = canvas.ImageFillContain @@ -88,8 +88,18 @@ func (i *ImagePlaceholder) onTappedSecondary(e *fyne.PointEvent) { } } +func (i *ImagePlaceholder) SetMinSize(size fyne.Size) { + if i.minSize == size { + return + } + + i.minSize = size + d := fyne.Min(i.minSize.Width, i.minSize.Height) + i.iconImage.SetMinSize(fyne.NewSquareSize(d / 4)) +} + func (i *ImagePlaceholder) MinSize() fyne.Size { - return fyne.NewSize(i.minSize, i.minSize) + return i.minSize } func (i *ImagePlaceholder) Refresh() {