diff --git a/internal/application/setting/setting.go b/internal/application/setting/setting.go index f969edc..b6afe5b 100644 --- a/internal/application/setting/setting.go +++ b/internal/application/setting/setting.go @@ -22,6 +22,11 @@ type SettingContract interface { GetFFplayPath() string SetFFplayPath(path string) + + ThemeInit() + GetThemes() map[string]ThemeInfoContract + GetTheme() ThemeInfoContract + SetTheme(themeInfo ThemeInfoContract) } type setting struct { diff --git a/internal/application/setting/theme.go b/internal/application/setting/theme.go new file mode 100644 index 0000000..b81547b --- /dev/null +++ b/internal/application/setting/theme.go @@ -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) +} diff --git a/internal/controller/menu.go b/internal/controller/menu.go new file mode 100644 index 0000000..ec6dab3 --- /dev/null +++ b/internal/controller/menu.go @@ -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 +} diff --git a/internal/gui/view/mainSettings.go b/internal/gui/view/mainSettings.go new file mode 100644 index 0000000..b9e19e7 --- /dev/null +++ b/internal/gui/view/mainSettings.go @@ -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) +}