Add main settings view and theme management functionality

Introduce a new `MainSettings` view for managing application settings, including language and theme selection. Implement theme management methods in the `setting` package to handle theme initialization, retrieval, and updates.
This commit is contained in:
Leonid Nikitin 2025-06-09 00:27:40 +05:00
parent 690f84e2c8
commit fc4e585620
Signed by: kor-elf
GPG Key ID: DAB5355A11C22541
4 changed files with 243 additions and 0 deletions

View File

@ -22,6 +22,11 @@ type SettingContract interface {
GetFFplayPath() string GetFFplayPath() string
SetFFplayPath(path string) SetFFplayPath(path string)
ThemeInit()
GetThemes() map[string]ThemeInfoContract
GetTheme() ThemeInfoContract
SetTheme(themeInfo ThemeInfoContract)
} }
type setting struct { type setting struct {

View File

@ -0,0 +1,110 @@
package setting
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/lang"
"fyne.io/fyne/v2/theme"
"image/color"
)
func (s *setting) GetTheme() ThemeInfoContract {
name := s.fyneApp.Preferences().String("theme")
if name != "" {
if _, ok := s.GetThemes()[name]; ok {
return s.GetThemes()[name]
}
}
return s.GetThemes()["default"]
}
func (s *setting) SetTheme(themeInfo ThemeInfoContract) {
s.fyneApp.Preferences().SetString("theme", themeInfo.GetName())
if themeInfo.GetName() == "default" {
s.fyneApp.Settings().SetTheme(theme.DefaultTheme())
return
}
s.fyneApp.Settings().SetTheme(&forcedVariant{theme: theme.DefaultTheme(), variant: themeInfo.GetVariant()})
}
func (s *setting) ThemeInit() {
themeInfo := s.GetTheme()
if themeInfo.GetName() == "default" {
s.fyneApp.Settings().SetTheme(theme.DefaultTheme())
return
}
s.fyneApp.Settings().SetTheme(&forcedVariant{theme: theme.DefaultTheme(), variant: themeInfo.GetVariant()})
}
func (s *setting) GetThemes() map[string]ThemeInfoContract {
themesNameDefault := &themeInfo{
name: "default",
title: lang.L("themesNameDefault"),
}
themesNameLight := &themeInfo{
name: "light",
title: lang.L("themesNameLight"),
variant: theme.VariantLight,
}
themesNameDark := &themeInfo{
name: "dark",
title: lang.L("themesNameDark"),
variant: theme.VariantDark,
}
list := map[string]ThemeInfoContract{
"default": themesNameDefault,
"light": themesNameLight,
"dark": themesNameDark,
}
return list
}
type ThemeInfoContract interface {
GetName() string
GetTitle() string
GetVariant() fyne.ThemeVariant
}
type themeInfo struct {
name string
title string
variant fyne.ThemeVariant
}
func (inf *themeInfo) GetName() string {
return inf.name
}
func (inf *themeInfo) GetTitle() string {
return inf.title
}
func (inf *themeInfo) GetVariant() fyne.ThemeVariant {
return inf.variant
}
type forcedVariant struct {
theme fyne.Theme
variant fyne.ThemeVariant
}
func (f *forcedVariant) Color(name fyne.ThemeColorName, _ fyne.ThemeVariant) color.Color {
return f.theme.Color(name, f.variant)
}
func (f *forcedVariant) Font(style fyne.TextStyle) fyne.Resource {
return theme.DefaultTheme().Font(style)
}
func (f *forcedVariant) Icon(name fyne.ThemeIconName) fyne.Resource {
return theme.DefaultTheme().Icon(name)
}
func (f *forcedVariant) Size(name fyne.ThemeSizeName) float32 {
return theme.DefaultTheme().Size(name)
}

View File

@ -0,0 +1,36 @@
package controller
import (
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/gui/view"
)
func (c *controller) actionSettingConvertor() {
c.settingConvertor(true)
}
func (c *controller) actionMainSettings() {
currentLang, _ := c.app.GetSetting().GetCurrentLangOrDefaultLang()
content := view.MainSettings(
currentLang,
c.app.GetSetting().GetLanguages(),
c.app.GetSetting().GetTheme(),
c.app.GetSetting().GetThemes(),
c.actionMainSettingsSave,
c.convertor,
)
c.window.SetContent(content)
}
func (c *controller) actionMainSettingsSave(setting *view.MainSettingForm) error {
err := c.app.GetSetting().SetLang(setting.Language)
if err != nil {
return err
}
c.app.GetSetting().SetTheme(setting.ThemeInfo)
c.initLayout()
c.convertor()
return nil
}

View File

@ -0,0 +1,92 @@
package view
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/lang"
"fyne.io/fyne/v2/widget"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application/setting"
"image/color"
)
type MainSettingForm struct {
Language setting.Lang
ThemeInfo setting.ThemeInfoContract
}
func MainSettings(
currentLang setting.Lang,
langList []setting.Lang,
themeInfo setting.ThemeInfoContract,
themeList map[string]setting.ThemeInfoContract,
save func(form *MainSettingForm) error,
cancel func(),
) fyne.CanvasObject {
errorMessage := canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
errorMessage.TextSize = 16
errorMessage.TextStyle = fyne.TextStyle{Bold: true}
viewSettingForm := &MainSettingForm{
Language: currentLang,
ThemeInfo: themeInfo,
}
var languageItems []string
langByTitle := map[string]setting.Lang{}
for _, language := range langList {
languageItems = append(languageItems, language.Title)
langByTitle[language.Title] = language
}
selectLanguage := widget.NewSelect(languageItems, func(s string) {
if lang, ok := langByTitle[s]; ok {
viewSettingForm.Language = lang
}
})
selectLanguage.Selected = currentLang.Title
var themeItems []string
themeByTitle := map[string]setting.ThemeInfoContract{}
for _, themeInfo := range themeList {
themeItems = append(themeItems, themeInfo.GetTitle())
themeByTitle[themeInfo.GetTitle()] = themeInfo
}
selectTheme := widget.NewSelect(themeItems, func(s string) {
if themeInfo, ok := themeByTitle[s]; ok {
viewSettingForm.ThemeInfo = themeInfo
}
})
selectTheme.Selected = themeInfo.GetTitle()
form := &widget.Form{
Items: []*widget.FormItem{
{
Text: lang.L("menuSettingsLanguage"),
Widget: selectLanguage,
},
{
Text: lang.L("menuSettingsTheme"),
Widget: selectTheme,
},
{
Widget: errorMessage,
},
},
SubmitText: lang.L("save"),
OnSubmit: func() {
err := save(viewSettingForm)
if err != nil {
errorMessage.Text = err.Error()
}
},
}
if cancel != nil {
form.OnCancel = cancel
form.CancelText = lang.L("cancel")
}
messageHead := lang.L("settings")
return widget.NewCard(messageHead, "", form)
}