feat(ui): 主题切换 + 语言持久化 + About 对话框

- 新增 light/dark 主题调色板与 Windows 注册表系统主题探测
- 偏好设置对话框:主题三选一 + 语言下拉(en/zh-CN/de),即时生效
- 持久化 Language/Theme/AutoLockMinutes/MinimizeToTray 至 YAML 顶层
- 启动时按 config 中保存的语言初始化 i18n
- About 对话框展示 version/runtime/项目地址/许可证
- 全部硬编码颜色迁移到 themePalette,为深色模式做准备
This commit is contained in:
2026-06-12 03:38:13 +08:00
parent c671f2115e
commit b483360778
19 changed files with 687 additions and 48 deletions
+8 -5
View File
@@ -1,8 +1,6 @@
package ui
import (
"image/color"
"gioui.org/layout"
"gioui.org/unit"
"gioui.org/widget"
@@ -18,6 +16,7 @@ const (
settingsActionNone settingsAction = iota
settingsActionSetPassword
settingsActionImportLegacy
settingsActionPreferences
settingsActionAbout
)
@@ -26,6 +25,7 @@ const (
type settingsMenu struct {
setPwBtn widget.Clickable
importBtn widget.Clickable
prefsBtn widget.Clickable
aboutBtn widget.Clickable
cancelBtn widget.Clickable
}
@@ -39,6 +39,8 @@ func (m *settingsMenu) Pick(gtx layout.Context) (settingsAction, bool) {
return settingsActionSetPassword, true
case m.importBtn.Clicked(gtx):
return settingsActionImportLegacy, true
case m.prefsBtn.Clicked(gtx):
return settingsActionPreferences, true
case m.aboutBtn.Clicked(gtx):
return settingsActionAbout, true
case m.cancelBtn.Clicked(gtx):
@@ -48,7 +50,7 @@ func (m *settingsMenu) Pick(gtx layout.Context) (settingsAction, bool) {
}
func (m *settingsMenu) Layout(gtx layout.Context, th *material.Theme) layout.Dimensions {
fillBackground(gtx, color.NRGBA{R: 0, G: 0, B: 0, A: 0x60})
fillBackground(gtx, activePalette.ScrimBg)
row := func(btn *widget.Clickable, label string) layout.FlexChild {
return layout.Rigid(func(gtx layout.Context) layout.Dimensions {
@@ -63,17 +65,18 @@ func (m *settingsMenu) Layout(gtx layout.Context, th *material.Theme) layout.Dim
return layout.Center.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
gtx.Constraints.Max.X = gtx.Dp(280)
return widget.Border{
Color: color.NRGBA{R: 0x55, G: 0x55, B: 0x55, A: 0xff},
Color: activePalette.DialogBorder,
CornerRadius: unit.Dp(4),
Width: unit.Dp(1),
}.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
fillBackground(gtx, color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff})
fillBackground(gtx, activePalette.DialogBg)
return layout.UniformInset(unit.Dp(16)).Layout(gtx, func(gtx layout.Context) layout.Dimensions {
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
layout.Rigid(material.H6(th, i18n.T("menu_settings")).Layout),
layout.Rigid(layout.Spacer{Height: unit.Dp(12)}.Layout),
row(&m.setPwBtn, i18n.T("menu_set_password")),
row(&m.importBtn, i18n.T("menu_import_legacy")),
row(&m.prefsBtn, i18n.T("menu_preferences")),
row(&m.aboutBtn, i18n.T("menu_about")),
layout.Rigid(layout.Spacer{Height: unit.Dp(8)}.Layout),
layout.Rigid(func(gtx layout.Context) layout.Dimensions {