From 6c81db439873c1e6c58849cb4fb0eb5250a37992 Mon Sep 17 00:00:00 2001 From: Drew Weymouth Date: Mon, 1 May 2023 17:24:31 -0700 Subject: [PATCH] switch to simpler way of themeing PNG icons --- main.go | 10 ++--- ui/browsing/albumpage.go | 2 +- ui/browsing/artistpage.go | 4 +- ui/browsing/browsingpane.go | 10 ++--- ui/browsing/genrepage.go | 6 +-- ui/browsing/playlistpage.go | 2 +- ui/mainwindow.go | 12 +++--- ui/theme/theme.go | 73 +++++++++++++++++++++++++++++------- ui/widgets/favoritebutton.go | 6 +-- ui/widgets/themed.go | 46 ----------------------- ui/widgets/tracklist.go | 12 +++--- 11 files changed, 91 insertions(+), 92 deletions(-) diff --git a/main.go b/main.go index 1a9592e..3c8f15b 100644 --- a/main.go +++ b/main.go @@ -27,11 +27,11 @@ func main() { } fyneApp := app.New() - fyneApp.Settings().SetTheme(&theme.MyTheme{ - NormalFont: myApp.Config.Application.FontNormalTTF, - BoldFont: myApp.Config.Application.FontBoldTTF, - Config: &myApp.Config.Theme, - }) + theme := theme.NewMyTheme(&myApp.Config.Theme) + theme.NormalFont = myApp.Config.Application.FontNormalTTF + theme.BoldFont = myApp.Config.Application.FontBoldTTF + fyneApp.Settings().SetTheme(theme) + w := float32(myApp.Config.Application.WindowWidth) if w <= 1 { w = 1000 diff --git a/ui/browsing/albumpage.go b/ui/browsing/albumpage.go index f25fb01..de65621 100644 --- a/ui/browsing/albumpage.go +++ b/ui/browsing/albumpage.go @@ -170,7 +170,7 @@ func NewAlbumPageHeader(page *AlbumPage) *AlbumPageHeader { playButton := widget.NewButtonWithIcon("Play", theme.MediaPlayIcon(), func() { go page.pm.PlayAlbum(page.albumID, 0) }) - shuffleBtn := widgets.NewThemedIconButton(myTheme.IconNameShuffle, " Shuffle", func() { + shuffleBtn := widget.NewButtonWithIcon(" Shuffle", myTheme.ShuffleIcon, func() { page.pm.LoadTracks(page.tracklist.Tracks, false, true) page.pm.PlayFromBeginning() }) diff --git a/ui/browsing/artistpage.go b/ui/browsing/artistpage.go index b1967aa..48c9078 100644 --- a/ui/browsing/artistpage.go +++ b/ui/browsing/artistpage.go @@ -254,7 +254,7 @@ type ArtistPageHeader struct { similarArtists *fyne.Container favoriteBtn *widgets.FavoriteButton playBtn *widget.Button - playRadioBtn *widgets.ThemedIconButton + playRadioBtn *widget.Button container *fyne.Container } @@ -276,7 +276,7 @@ func NewArtistPageHeader(page *ArtistPage) *ArtistPageHeader { } a.favoriteBtn = widgets.NewFavoriteButton(func() { go a.toggleFavorited() }) a.playBtn = widget.NewButtonWithIcon("Play Discography", theme.MediaPlayIcon(), page.playAllTracks) - a.playRadioBtn = widgets.NewThemedIconButton(myTheme.IconNameShuffle, " Play Artist Radio", page.playArtistRadio) + a.playRadioBtn = widget.NewButtonWithIcon(" Play Artist Radio", myTheme.ShuffleIcon, page.playArtistRadio) a.biographyDisp.Wrapping = fyne.TextWrapWord a.ExtendBaseWidget(a) a.createContainer() diff --git a/ui/browsing/browsingpane.go b/ui/browsing/browsingpane.go index 34b4446..e9676bd 100644 --- a/ui/browsing/browsingpane.go +++ b/ui/browsing/browsingpane.go @@ -107,25 +107,25 @@ func (b *BrowsingPane) AddSettingsMenuItem(label string, action func()) { fyne.NewMenuItem(label, action)) } -func (b *BrowsingPane) AddNavigationButton(iconName fyne.ThemeIconName, action func()) { - b.navBtnsContainer.Add(widgets.NewThemedIconButton(iconName, "", action)) +func (b *BrowsingPane) AddNavigationButton(icon fyne.Resource, action func()) { + b.navBtnsContainer.Add(widget.NewButtonWithIcon("", icon, action)) } func (b *BrowsingPane) DisableNavigationButtons() { for _, obj := range b.navBtnsContainer.Objects { - obj.(*widgets.ThemedIconButton).Disable() + obj.(*widget.Button).Disable() } } func (b *BrowsingPane) EnableNavigationButtons() { for _, obj := range b.navBtnsContainer.Objects { - obj.(*widgets.ThemedIconButton).Enable() + obj.(*widget.Button).Enable() } } func (b *BrowsingPane) ActivateNavigationButton(num int) { if num < len(b.navBtnsContainer.Objects) { - btn := b.navBtnsContainer.Objects[num].(*widgets.ThemedIconButton) + btn := b.navBtnsContainer.Objects[num].(*widget.Button) if !btn.Disabled() { btn.OnTapped() } diff --git a/ui/browsing/genrepage.go b/ui/browsing/genrepage.go index 84ce6c5..2d23272 100644 --- a/ui/browsing/genrepage.go +++ b/ui/browsing/genrepage.go @@ -29,7 +29,7 @@ type GenrePage struct { searcher *widgets.Searcher searchText string titleDisp *widget.RichText - playRandom *widgets.ThemedIconButton + playRandom *widget.Button OnPlayAlbum func(string, int) @@ -50,7 +50,7 @@ func NewGenrePage(genre string, contr *controller.Controller, pm *backend.Playba g.titleDisp.Segments[0].(*widget.TextSegment).Style = widget.RichTextStyle{ SizeName: theme.SizeNameHeadingText, } - g.playRandom = widgets.NewThemedIconButton(myTheme.IconNameShuffle, " Play random", g.playRandomSongs) + g.playRandom = widget.NewButtonWithIcon(" Play random", myTheme.ShuffleIcon, g.playRandomSongs) iter := g.lm.GenreIter(g.genre) g.grid = widgets.NewGridView(widgets.NewGridViewAlbumIterator(iter), g.im) g.grid.OnPlay = g.onPlayAlbum @@ -93,7 +93,7 @@ func restoreGenrePage(saved *savedGenrePage) *GenrePage { g.titleDisp.Segments[0].(*widget.TextSegment).Style = widget.RichTextStyle{ SizeName: theme.SizeNameHeadingText, } - g.playRandom = widgets.NewThemedIconButton(myTheme.IconNameShuffle, "Play random", g.playRandomSongs) + g.playRandom = widget.NewButtonWithIcon("Play random", myTheme.ShuffleIcon, g.playRandomSongs) g.grid = widgets.NewAlbumGridFromState(saved.gridState) g.searcher = widgets.NewSearcher() g.searcher.OnSearched = g.OnSearched diff --git a/ui/browsing/playlistpage.go b/ui/browsing/playlistpage.go index ff54876..f7212b0 100644 --- a/ui/browsing/playlistpage.go +++ b/ui/browsing/playlistpage.go @@ -206,7 +206,7 @@ func NewPlaylistPageHeader(page *PlaylistPage) *PlaylistPageHeader { page.pm.PlayFromBeginning() }) // TODO: find way to pad shuffle svg rather than using a space in the label string - shuffleBtn := widgets.NewThemedIconButton(myTheme.IconNameShuffle, " Shuffle", func() { + shuffleBtn := widget.NewButtonWithIcon(" Shuffle", myTheme.ShuffleIcon, func() { page.pm.LoadTracks(page.tracklist.Tracks, false /*append*/, true /*shuffle*/) page.pm.PlayFromBeginning() }) diff --git a/ui/mainwindow.go b/ui/mainwindow.go index be2ae54..66a95ab 100644 --- a/ui/mainwindow.go +++ b/ui/mainwindow.go @@ -178,22 +178,22 @@ func (m *MainWindow) ShowNewVersionDialog(appName, versionTag string) { } func (m *MainWindow) addNavigationButtons() { - m.BrowsingPane.AddNavigationButton(theme.IconNameNowPlaying, func() { + m.BrowsingPane.AddNavigationButton(theme.NowPlayingIcon, func() { m.Router.NavigateTo(controller.NowPlayingRoute("")) }) - m.BrowsingPane.AddNavigationButton(theme.IconNameFavorite, func() { + m.BrowsingPane.AddNavigationButton(theme.FavoriteIcon, func() { m.Router.NavigateTo(controller.FavoritesRoute()) }) - m.BrowsingPane.AddNavigationButton(theme.IconNameAlbum, func() { + m.BrowsingPane.AddNavigationButton(theme.AlbumIcon, func() { m.Router.NavigateTo(controller.AlbumsRoute()) }) - m.BrowsingPane.AddNavigationButton(theme.IconNameArtist, func() { + m.BrowsingPane.AddNavigationButton(theme.ArtistIcon, func() { m.Router.NavigateTo(controller.ArtistsRoute()) }) - m.BrowsingPane.AddNavigationButton(theme.IconNameGenre, func() { + m.BrowsingPane.AddNavigationButton(theme.GenreIcon, func() { m.Router.NavigateTo(controller.GenresRoute()) }) - m.BrowsingPane.AddNavigationButton(theme.IconNamePlaylist, func() { + m.BrowsingPane.AddNavigationButton(theme.PlaylistIcon, func() { m.Router.NavigateTo(controller.PlaylistsRoute()) }) m.BrowsingPane.AddNavigationButton(res.ResMusicnotesInvertPng, func() { diff --git a/ui/theme/theme.go b/ui/theme/theme.go index c7bd999..dcd4ec5 100644 --- a/ui/theme/theme.go +++ b/ui/theme/theme.go @@ -16,17 +16,6 @@ import ( const ColorNamePageBackground fyne.ThemeColorName = "PageBackground" -const ( - IconNameNowPlaying fyne.ThemeIconName = "NowPlaying" - IconNameFavorite fyne.ThemeIconName = "Favorite" - IconNameNotFavorite fyne.ThemeIconName = "NotFavorite" - IconNameAlbum fyne.ThemeIconName = "Album" - IconNameArtist fyne.ThemeIconName = "Artist" - IconNameGenre fyne.ThemeIconName = "Genre" - IconNamePlaylist fyne.ThemeIconName = "Playlist" - IconNameShuffle fyne.ThemeIconName = "Shuffle" -) - type AppearanceMode string const ( @@ -43,11 +32,17 @@ var ( type MyTheme struct { NormalFont string BoldFont string - Config *backend.ThemeConfig + config *backend.ThemeConfig } var _ fyne.Theme = (*MyTheme)(nil) +func NewMyTheme(config *backend.ThemeConfig) *MyTheme { + m := &MyTheme{config: config} + m.createThemeIcons() + return m +} + func (m *MyTheme) Color(name fyne.ThemeColorName, _ fyne.ThemeVariant) color.Color { variant := m.getVariant() switch name { @@ -87,6 +82,7 @@ func (m *MyTheme) Color(name fyne.ThemeColorName, _ fyne.ThemeVariant) color.Col return theme.DefaultTheme().Color(name, variant) } +<<<<<<< HEAD func (m *MyTheme) Icon(name fyne.ThemeIconName) fyne.Resource { variant := m.getVariant() switch name { @@ -135,6 +131,55 @@ func (m *MyTheme) Icon(name fyne.ThemeIconName) fyne.Resource { } } +type myThemedResource struct { + myTheme MyTheme + darkVariant *fyne.StaticResource + lightVariant *fyne.StaticResource +} + +var _ fyne.Resource = myThemedResource{} + +func (p myThemedResource) Content() []byte { + if p.myTheme.getVariant() == theme.VariantDark { + return p.darkVariant.StaticContent + } + return p.lightVariant.StaticContent +} + +func (p myThemedResource) Name() string { + if p.myTheme.getVariant() == theme.VariantDark { + return p.darkVariant.StaticName + } + return p.lightVariant.StaticName +} + +var ( + AlbumIcon fyne.Resource + ArtistIcon fyne.Resource + FavoriteIcon fyne.Resource + NotFavoriteIcon fyne.Resource + GenreIcon fyne.Resource + NowPlayingIcon fyne.Resource + PlaylistIcon fyne.Resource + ShuffleIcon fyne.Resource +) + +// MUST be called at startup! +func (m MyTheme) createThemeIcons() { + AlbumIcon = myThemedResource{myTheme: m, darkVariant: res.ResDiscInvertPng, lightVariant: res.ResDiscPng} + ArtistIcon = myThemedResource{myTheme: m, darkVariant: res.ResPeopleInvertPng, lightVariant: res.ResPeoplePng} + FavoriteIcon = myThemedResource{myTheme: m, darkVariant: res.ResHeartFilledInvertPng, lightVariant: res.ResHeartFilledPng} + NotFavoriteIcon = myThemedResource{myTheme: m, darkVariant: res.ResHeartOutlineInvertPng, lightVariant: res.ResHeartOutlinePng} + GenreIcon = myThemedResource{myTheme: m, darkVariant: res.ResTheatermasksInvertPng, lightVariant: res.ResTheatermasksPng} + NowPlayingIcon = myThemedResource{myTheme: m, darkVariant: res.ResHeadphonesInvertPng, lightVariant: res.ResHeadphonesPng} + PlaylistIcon = myThemedResource{myTheme: m, darkVariant: res.ResPlaylistInvertPng, lightVariant: res.ResPlaylistPng} + ShuffleIcon = myThemedResource{myTheme: m, darkVariant: res.ResShuffleInvertSvg, lightVariant: res.ResShuffleSvg} +} + +func (m MyTheme) Icon(name fyne.ThemeIconName) fyne.Resource { + return theme.DefaultTheme().Icon(name) +} + <<<<<<< HEAD func (m *MyTheme) Font(style fyne.TextStyle) fyne.Resource { switch style { @@ -176,8 +221,8 @@ func (m *MyTheme) getVariant() fyne.ThemeVariant { v := "Dark" // default if config has invalid or missing setting if sharedutil.StringSliceContains( []string{string(AppearanceLight), string(AppearanceDark), string(AppearanceAuto)}, - m.Config.Appearance) { - v = m.Config.Appearance + m.config.Appearance) { + v = m.config.Appearance } if AppearanceMode(v) == AppearanceDark { diff --git a/ui/widgets/favoritebutton.go b/ui/widgets/favoritebutton.go index bac50e4..4c49733 100644 --- a/ui/widgets/favoritebutton.go +++ b/ui/widgets/favoritebutton.go @@ -32,12 +32,10 @@ func (f *FavoriteButton) Tapped(e *fyne.PointEvent) { } func (f *FavoriteButton) Refresh() { - var iconName fyne.ThemeIconName if f.IsFavorited { - iconName = theme.IconNameFavorite + f.Icon = theme.FavoriteIcon } else { - iconName = theme.IconNameNotFavorite + f.Icon = theme.NotFavoriteIcon } - f.Icon = fyne.CurrentApp().Settings().Theme().Icon(iconName) f.Button.Refresh() } diff --git a/ui/widgets/themed.go b/ui/widgets/themed.go index 9e7036f..26d7e13 100644 --- a/ui/widgets/themed.go +++ b/ui/widgets/themed.go @@ -6,34 +6,6 @@ import ( "fyne.io/fyne/v2/widget" ) -type ThemedIconButton struct { - widget.Button - - IconName fyne.ThemeIconName -} - -func NewThemedIconButton(iconName fyne.ThemeIconName, text string, action func()) *ThemedIconButton { - b := &ThemedIconButton{ - IconName: iconName, - Button: widget.Button{ - Text: text, - OnTapped: action, - }, - } - b.updateIcon() - b.ExtendBaseWidget(b) - return b -} - -func (b *ThemedIconButton) updateIcon() { - b.Icon = fyne.CurrentApp().Settings().Theme().Icon(b.IconName) -} - -func (b *ThemedIconButton) Refresh() { - b.updateIcon() - b.Button.Refresh() -} - type ThemedRectangle struct { widget.BaseWidget @@ -61,21 +33,3 @@ func (t *ThemedRectangle) Refresh() { func (t *ThemedRectangle) CreateRenderer() fyne.WidgetRenderer { return widget.NewSimpleRenderer(t.rect) } - -type ThemedTappableIcon struct { - TappableIcon - - IconName fyne.ThemeIconName -} - -func NewThemedTappableIcon(iconName fyne.ThemeIconName) *ThemedTappableIcon { - t := &ThemedTappableIcon{IconName: iconName} - t.ExtendBaseWidget(t) - return t -} - -func (t *ThemedTappableIcon) Refresh() { - icon := fyne.CurrentApp().Settings().Theme().Icon(t.IconName) - t.TappableIcon.Icon.Resource = icon - t.TappableIcon.Refresh() -} diff --git a/ui/widgets/tracklist.go b/ui/widgets/tracklist.go index 2a2cdce..684a414 100644 --- a/ui/widgets/tracklist.go +++ b/ui/widgets/tracklist.go @@ -4,6 +4,8 @@ import ( "fmt" "log" "strconv" + "time" + "supersonic/sharedutil" "supersonic/ui/layouts" "supersonic/ui/os" @@ -524,7 +526,7 @@ func NewTrackRow(tracklist *Tracklist, playingIcon fyne.CanvasObject) *TrackRow t.album.OnTapped = func() { tracklist.onAlbumTapped(t.albumID) } t.dur = newTrailingAlignRichText() t.year = newTrailingAlignRichText() - favorite := NewThemedTappableIcon(myTheme.IconNameNotFavorite) + favorite := NewTappbaleIcon(myTheme.NotFavoriteIcon) favorite.OnTapped = t.toggleFavorited t.favorite = container.NewCenter(favorite) t.rating = NewStarRating() @@ -623,10 +625,10 @@ func (t *TrackRow) Update(tr *subsonic.Child, rowNum int) { // Render favorite column if tr.Starred.IsZero() { t.isFavorite = false - t.favorite.Objects[0].(*ThemedTappableIcon).IconName = myTheme.IconNameNotFavorite + t.favorite.Objects[0].(*TappableIcon).Resource = myTheme.NotFavoriteIcon } else { t.isFavorite = true - t.favorite.Objects[0].(*ThemedTappableIcon).IconName = myTheme.IconNameFavorite + t.favorite.Objects[0].(*TappableIcon).Resource = myTheme.FavoriteIcon } t.rating.Rating = tr.UserRating @@ -648,12 +650,12 @@ func (t *TrackRow) Update(tr *subsonic.Child, rowNum int) { func (t *TrackRow) toggleFavorited() { if t.isFavorite { - t.favorite.Objects[0].(*ThemedTappableIcon).IconName = myTheme.IconNameNotFavorite + t.favorite.Objects[0].(*TappableIcon).Resource = myTheme.NotFavoriteIcon t.favorite.Refresh() t.isFavorite = false t.tracklist.onSetFavorite(t.trackID, false) } else { - t.favorite.Objects[0].(*ThemedTappableIcon).IconName = myTheme.IconNameFavorite + t.favorite.Objects[0].(*TappableIcon).Resource = myTheme.FavoriteIcon t.favorite.Refresh() t.isFavorite = true t.tracklist.onSetFavorite(t.trackID, true)