hook custom themes up to Settings dialog

This commit is contained in:
Drew Weymouth
2023-06-20 18:33:37 -07:00
parent 4a399c51b7
commit 02cac23d9a
5 changed files with 57 additions and 32 deletions
+1 -1
View File
@@ -37,7 +37,7 @@ func main() {
if h <= 1 { if h <= 1 {
h = 800 h = 800
} }
mainWindow := ui.NewMainWindow(fyneApp, displayName, appVersion, myApp, fyne.NewSize(w, h)) mainWindow := ui.NewMainWindow(fyneApp, appname, displayName, appVersion, myApp, fyne.NewSize(w, h))
myApp.OnReactivate = mainWindow.Show myApp.OnReactivate = mainWindow.Show
go func() { go func() {
+2 -2
View File
@@ -441,14 +441,14 @@ func (c *Controller) ShowAboutDialog() {
pop.Show() pop.Show()
} }
func (c *Controller) ShowSettingsDialog(themeUpdateCallbk func()) { func (c *Controller) ShowSettingsDialog(themeUpdateCallbk func(), themeFiles map[string]string) {
devs, err := c.App.Player.ListAudioDevices() devs, err := c.App.Player.ListAudioDevices()
if err != nil { if err != nil {
log.Printf("error listing audio devices: %v", err) log.Printf("error listing audio devices: %v", err)
devs = []player.AudioDevice{{Name: "auto", Description: "Autoselect device"}} devs = []player.AudioDevice{{Name: "auto", Description: "Autoselect device"}}
} }
dlg := dialogs.NewSettingsDialog(c.App.Config, devs, c.MainWindow) dlg := dialogs.NewSettingsDialog(c.App.Config, devs, themeFiles, c.MainWindow)
dlg.OnReplayGainSettingsChanged = func() { dlg.OnReplayGainSettingsChanged = func() {
c.App.PlaybackManager.SetReplayGainOptions(c.App.Config.ReplayGain) c.App.PlaybackManager.SetReplayGainOptions(c.App.Config.ReplayGain)
} }
+37 -13
View File
@@ -38,14 +38,15 @@ type SettingsDialog struct {
config *backend.Config config *backend.Config
audioDevices []player.AudioDevice audioDevices []player.AudioDevice
themeFiles map[string]string // filename -> displayName
promptText *widget.RichText promptText *widget.RichText
content fyne.CanvasObject content fyne.CanvasObject
} }
// TODO: having this depend on the player package for the AudioDevice type is kinda gross. Refactor. // TODO: having this depend on the player package for the AudioDevice type is kinda gross. Refactor.
func NewSettingsDialog(config *backend.Config, audioDeviceList []player.AudioDevice, window fyne.Window) *SettingsDialog { func NewSettingsDialog(config *backend.Config, audioDeviceList []player.AudioDevice, themeFileList map[string]string, window fyne.Window) *SettingsDialog {
s := &SettingsDialog{config: config, audioDevices: audioDeviceList} s := &SettingsDialog{config: config, audioDevices: audioDeviceList, themeFiles: themeFileList}
s.ExtendBaseWidget(s) s.ExtendBaseWidget(s)
tabs := container.NewAppTabs( tabs := container.NewAppTabs(
@@ -69,19 +70,39 @@ func NewSettingsDialog(config *backend.Config, audioDeviceList []player.AudioDev
} }
func (s *SettingsDialog) createGeneralTab() *container.TabItem { func (s *SettingsDialog) createGeneralTab() *container.TabItem {
themeSelect := widget.NewSelect([]string{ themeNames := []string{"Default"}
string(myTheme.AppearanceDark), themeFileNames := []string{""}
string(myTheme.AppearanceLight), i, selIndex := 1, 0
string(myTheme.AppearanceAuto)}, nil) for filename, displayname := range s.themeFiles {
themeSelect.OnChanged = func(_ string) { themeFileNames = append(themeFileNames, filename)
s.config.Theme.Appearance = themeSelect.Options[themeSelect.SelectedIndex()] themeNames = append(themeNames, displayname)
if strings.EqualFold(filename, s.config.Theme.ThemeFile) {
selIndex = i
}
i++
}
themeFileSelect := widget.NewSelect(themeNames, nil)
themeFileSelect.SetSelectedIndex(selIndex)
themeFileSelect.OnChanged = func(_ string) {
s.config.Theme.ThemeFile = themeFileNames[themeFileSelect.SelectedIndex()]
if s.OnThemeSettingChanged != nil { if s.OnThemeSettingChanged != nil {
s.OnThemeSettingChanged() s.OnThemeSettingChanged()
} }
} }
themeSelect.SetSelected(s.config.Theme.Appearance) themeModeSelect := widget.NewSelect([]string{
if themeSelect.Selected == "" { string(myTheme.AppearanceDark),
themeSelect.SetSelectedIndex(0) string(myTheme.AppearanceLight),
string(myTheme.AppearanceAuto)}, nil)
themeModeSelect.OnChanged = func(_ string) {
s.config.Theme.Appearance = themeModeSelect.Options[themeModeSelect.SelectedIndex()]
if s.OnThemeSettingChanged != nil {
s.OnThemeSettingChanged()
}
}
themeModeSelect.SetSelected(s.config.Theme.Appearance)
if themeModeSelect.Selected == "" {
themeModeSelect.SetSelectedIndex(0)
} }
startupPage := widget.NewSelect(backend.SupportedStartupPages, func(choice string) { startupPage := widget.NewSelect(backend.SupportedStartupPages, func(choice string) {
@@ -183,8 +204,11 @@ func (s *SettingsDialog) createGeneralTab() *container.TabItem {
scrobbleEnabled.Checked = s.config.Scrobbling.Enabled scrobbleEnabled.Checked = s.config.Scrobbling.Enabled
return container.NewTabItem("General", container.NewVBox( return container.NewTabItem("General", container.NewVBox(
container.New(layout.NewFormLayout(), container.NewBorder(nil, nil, widget.NewLabel("Theme"), /*left*/
widget.NewLabel("Appearance"), container.NewGridWithColumns(2, themeSelect), container.NewHBox(widget.NewLabel("Mode"), themeModeSelect, util.NewHSpace(5)), // right
themeFileSelect, // center
),
container.NewHBox(
widget.NewLabel("Startup page"), container.NewGridWithColumns(2, startupPage), widget.NewLabel("Startup page"), container.NewGridWithColumns(2, startupPage),
), ),
container.NewHBox(systemTrayEnable, closeToTray), container.NewHBox(systemTrayEnable, closeToTray),
+12 -11
View File
@@ -3,6 +3,7 @@ package ui
import ( import (
"fmt" "fmt"
"github.com/20after4/configdir"
"github.com/dweymouth/supersonic/backend" "github.com/dweymouth/supersonic/backend"
"github.com/dweymouth/supersonic/backend/mediaprovider" "github.com/dweymouth/supersonic/backend/mediaprovider"
"github.com/dweymouth/supersonic/res" "github.com/dweymouth/supersonic/res"
@@ -49,12 +50,12 @@ type MainWindow struct {
container *fyne.Container container *fyne.Container
} }
func NewMainWindow(fyneApp fyne.App, appName, appVersion string, app *backend.App, size fyne.Size) MainWindow { func NewMainWindow(fyneApp fyne.App, appName, displayAppName, appVersion string, app *backend.App, size fyne.Size) MainWindow {
m := MainWindow{ m := MainWindow{
App: app, App: app,
Window: fyneApp.NewWindow(appName), Window: fyneApp.NewWindow(displayAppName),
BrowsingPane: browsing.NewBrowsingPane(app), BrowsingPane: browsing.NewBrowsingPane(app),
theme: theme.NewMyTheme(&app.Config.Theme), theme: theme.NewMyTheme(&app.Config.Theme, configdir.LocalConfig(appName, "themes")),
} }
m.theme.NormalFont = app.Config.Application.FontNormalTTF m.theme.NormalFont = app.Config.Application.FontNormalTTF
@@ -62,7 +63,7 @@ func NewMainWindow(fyneApp fyne.App, appName, appVersion string, app *backend.Ap
fyneApp.Settings().SetTheme(m.theme) fyneApp.Settings().SetTheme(m.theme)
if app.Config.Application.EnableSystemTray { if app.Config.Application.EnableSystemTray {
m.SetupSystemTrayMenu(appName, fyneApp) m.SetupSystemTrayMenu(displayAppName, fyneApp)
} }
m.Controller = &controller.Controller{ m.Controller = &controller.Controller{
AppVersion: appVersion, AppVersion: appVersion,
@@ -82,10 +83,10 @@ func NewMainWindow(fyneApp fyne.App, appName, appVersion string, app *backend.Ap
m.Window.Resize(size) m.Window.Resize(size)
app.PlaybackManager.OnSongChange(func(song, _ *mediaprovider.Track) { app.PlaybackManager.OnSongChange(func(song, _ *mediaprovider.Track) {
if song == nil { if song == nil {
m.Window.SetTitle(appName) m.Window.SetTitle(displayAppName)
return return
} }
m.Window.SetTitle(fmt.Sprintf("%s %s · %s", song.Name, song.ArtistNames[0], appName)) m.Window.SetTitle(fmt.Sprintf("%s %s · %s", song.Name, song.ArtistNames[0], displayAppName))
}) })
app.ServerManager.OnServerConnected(func() { app.ServerManager.OnServerConnected(func() {
m.BrowsingPane.EnableNavigationButtons() m.BrowsingPane.EnableNavigationButtons()
@@ -93,7 +94,7 @@ func NewMainWindow(fyneApp fyne.App, appName, appVersion string, app *backend.Ap
// check if found new version on startup // check if found new version on startup
if t := app.UpdateChecker.VersionTagFound(); t != "" && t != app.Config.Application.LastCheckedVersion { if t := app.UpdateChecker.VersionTagFound(); t != "" && t != app.Config.Application.LastCheckedVersion {
if t != app.VersionTag() { if t != app.VersionTag() {
m.ShowNewVersionDialog(appName, t) m.ShowNewVersionDialog(displayAppName, t)
} }
m.App.Config.Application.LastCheckedVersion = t m.App.Config.Application.LastCheckedVersion = t
} }
@@ -101,7 +102,7 @@ func NewMainWindow(fyneApp fyne.App, appName, appVersion string, app *backend.Ap
m.App.UpdateChecker.OnUpdatedVersionFound = func() { m.App.UpdateChecker.OnUpdatedVersionFound = func() {
t := m.App.UpdateChecker.VersionTagFound() t := m.App.UpdateChecker.VersionTagFound()
if t != app.VersionTag() { if t != app.VersionTag() {
m.ShowNewVersionDialog(appName, t) m.ShowNewVersionDialog(displayAppName, t)
} }
m.App.Config.Application.LastCheckedVersion = t m.App.Config.Application.LastCheckedVersion = t
} }
@@ -117,10 +118,10 @@ func NewMainWindow(fyneApp fyne.App, appName, appVersion string, app *backend.Ap
m.BrowsingPane.AddSettingsMenuItem("Check for Updates", func() { m.BrowsingPane.AddSettingsMenuItem("Check for Updates", func() {
go func() { go func() {
if t := app.UpdateChecker.CheckLatestVersionTag(); t != "" && t != app.VersionTag() { if t := app.UpdateChecker.CheckLatestVersionTag(); t != "" && t != app.VersionTag() {
m.ShowNewVersionDialog(appName, t) m.ShowNewVersionDialog(displayAppName, t)
} else { } else {
dialog.ShowInformation("No new version found", dialog.ShowInformation("No new version found",
"You are running the latest version of "+appName, "You are running the latest version of "+displayAppName,
m.Window) m.Window)
} }
}() }()
@@ -128,7 +129,7 @@ func NewMainWindow(fyneApp fyne.App, appName, appVersion string, app *backend.Ap
m.BrowsingPane.AddSettingsMenuItem("Settings...", func() { m.BrowsingPane.AddSettingsMenuItem("Settings...", func() {
m.Controller.ShowSettingsDialog(func() { m.Controller.ShowSettingsDialog(func() {
fyneApp.Settings().SetTheme(m.theme) fyneApp.Settings().SetTheme(m.theme)
}) }, m.theme.ListThemeFiles())
}) })
m.BrowsingPane.AddSettingsMenuItem("About...", m.Controller.ShowAboutDialog) m.BrowsingPane.AddSettingsMenuItem("About...", m.Controller.ShowAboutDialog)
m.addNavigationButtons() m.addNavigationButtons()
+5 -5
View File
@@ -48,8 +48,8 @@ type MyTheme struct {
var _ fyne.Theme = (*MyTheme)(nil) var _ fyne.Theme = (*MyTheme)(nil)
func NewMyTheme(config *backend.ThemeConfig) *MyTheme { func NewMyTheme(config *backend.ThemeConfig, themeFileDir string) *MyTheme {
m := &MyTheme{config: config} m := &MyTheme{config: config, themeFileDir: themeFileDir}
m.defaultThemeFile, _ = DecodeThemeFile(bytes.NewReader(res.ResDefaultToml.StaticContent)) m.defaultThemeFile, _ = DecodeThemeFile(bytes.NewReader(res.ResDefaultToml.StaticContent))
m.createThemeIcons() m.createThemeIcons()
return m return m
@@ -142,9 +142,9 @@ func (m *MyTheme) Icon(name fyne.ThemeIconName) fyne.Resource {
func (m *MyTheme) ListThemeFiles() map[string]string { func (m *MyTheme) ListThemeFiles() map[string]string {
files, _ := filepath.Glob(m.themeFileDir + "/*.toml") files, _ := filepath.Glob(m.themeFileDir + "/*.toml")
result := make(map[string]string) result := make(map[string]string)
for _, filename := range files { for _, filepath := range files {
if themeFile, err := ReadThemeFile(path.Join(m.themeFileDir, filename)); err == nil { if themeFile, err := ReadThemeFile(filepath); err == nil {
result[filename] = themeFile.SupersonicTheme.Name result[path.Base(filepath)] = themeFile.SupersonicTheme.Name
} }
} }
return result return result