package ui import ( "image/color" "fyne.io/fyne/v2" "fyne.io/fyne/v2/theme" ) // 主题模式。 const ( ThemeSystem = "system" // 跟随系统 ThemeContrast = "contrast" // 黑白高对比 ThemeLight = "light" // 浅色高对比 ) // themeLabel 返回主题模式的中文名。 func themeLabel(mode string) string { switch mode { case ThemeContrast: return "黑白高对比" case ThemeLight: return "浅色高对比" default: return "跟随系统" } } // themeOptions 返回设置页下拉里的可选项。 func themeOptions() []string { return []string{ themeLabel(ThemeSystem), themeLabel(ThemeContrast), themeLabel(ThemeLight), } } // themeFromLabel 由中文名反查主题模式。 func themeFromLabel(label string) string { for _, mode := range []string{ThemeSystem, ThemeContrast, ThemeLight} { if themeLabel(mode) == label { return mode } } return ThemeSystem } // applyThemeMode 按主题模式切换界面主题。 func applyThemeMode(mode string) { app := fyne.CurrentApp() if app == nil { return } switch mode { case ThemeContrast: app.Settings().SetTheme(newMonoTheme(darkPalette())) case ThemeLight: app.Settings().SetTheme(newMonoTheme(lightPalette())) default: app.Settings().SetTheme(theme.DefaultTheme()) } } // monoTheme 是一套纯灰度主题:所有颜色都去掉彩度,只靠明暗区分层级, // 文字与背景的对比拉到最高。 type monoTheme struct { base fyne.Theme colors map[fyne.ThemeColorName]color.Color } // newMonoTheme 用给定配色造一个主题,其余项沿用默认主题。 func newMonoTheme(palette map[fyne.ThemeColorName]color.Color) fyne.Theme { return &monoTheme{base: theme.DefaultTheme(), colors: palette} } func (t *monoTheme) Color(name fyne.ThemeColorName, variant fyne.ThemeVariant) color.Color { if c, ok := t.colors[name]; ok { return c } return t.base.Color(name, variant) } func (t *monoTheme) Font(style fyne.TextStyle) fyne.Resource { return t.base.Font(style) } func (t *monoTheme) Icon(name fyne.ThemeIconName) fyne.Resource { return t.base.Icon(name) } func (t *monoTheme) Size(name fyne.ThemeSizeName) float32 { return t.base.Size(name) } // rgb 生成不透明灰度色。 func rgb(v uint8) color.NRGBA { return color.NRGBA{R: v, G: v, B: v, A: 0xFF} } // darkPalette 是黑白高对比(纯黑底)的配色。 func darkPalette() map[fyne.ThemeColorName]color.Color { return map[fyne.ThemeColorName]color.Color{ theme.ColorNameBackground: rgb(0x00), theme.ColorNameForeground: rgb(0xFF), theme.ColorNameDisabled: rgb(0x8C), theme.ColorNameDisabledButton: rgb(0x1A), theme.ColorNameButton: rgb(0x2E), theme.ColorNameHover: rgb(0x4A), theme.ColorNamePressed: rgb(0x1E), theme.ColorNameFocus: rgb(0xFF), theme.ColorNamePrimary: rgb(0xFF), theme.ColorNameForegroundOnPrimary: rgb(0x00), theme.ColorNameSelection: rgb(0xFF), theme.ColorNameInputBackground: rgb(0x0B), theme.ColorNameInputBorder: rgb(0xE6), theme.ColorNamePlaceHolder: rgb(0xA6), theme.ColorNameSeparator: rgb(0x5A), theme.ColorNameOverlayBackground: rgb(0x11), theme.ColorNameMenuBackground: rgb(0x16), theme.ColorNameHeaderBackground: rgb(0x1C), theme.ColorNameInnerWindowBorder: rgb(0x3A), theme.ColorNameInnerWindowBorderInactive: rgb(0x26), theme.ColorNameScrollBar: rgb(0x9A), theme.ColorNameScrollBarBackground: rgb(0x1A), theme.ColorNameShadow: rgb(0x00), theme.ColorNameError: rgb(0xFF), theme.ColorNameForegroundOnError: rgb(0x00), theme.ColorNameSuccess: rgb(0xFF), theme.ColorNameForegroundOnSuccess: rgb(0x00), theme.ColorNameWarning: rgb(0xFF), theme.ColorNameForegroundOnWarning: rgb(0x00), theme.ColorNameHyperlink: rgb(0xFF), } } // lightPalette 是浅色高对比(纯白底)的配色。 func lightPalette() map[fyne.ThemeColorName]color.Color { return map[fyne.ThemeColorName]color.Color{ theme.ColorNameBackground: rgb(0xFF), theme.ColorNameForeground: rgb(0x00), theme.ColorNameDisabled: rgb(0x70), theme.ColorNameDisabledButton: rgb(0xF0), theme.ColorNameButton: rgb(0xE0), theme.ColorNameHover: rgb(0xC8), theme.ColorNamePressed: rgb(0xD4), theme.ColorNameFocus: rgb(0x00), theme.ColorNamePrimary: rgb(0x00), theme.ColorNameForegroundOnPrimary: rgb(0xFF), theme.ColorNameSelection: rgb(0x00), theme.ColorNameInputBackground: rgb(0xFF), theme.ColorNameInputBorder: rgb(0x00), theme.ColorNamePlaceHolder: rgb(0x70), theme.ColorNameSeparator: rgb(0x9A), theme.ColorNameOverlayBackground: rgb(0xF4), theme.ColorNameMenuBackground: rgb(0xFA), theme.ColorNameHeaderBackground: rgb(0xEF), theme.ColorNameInnerWindowBorder: rgb(0xC0), theme.ColorNameInnerWindowBorderInactive: rgb(0xD8), theme.ColorNameScrollBar: rgb(0x55), theme.ColorNameScrollBarBackground: rgb(0xED), theme.ColorNameShadow: rgb(0x00), theme.ColorNameError: rgb(0x00), theme.ColorNameForegroundOnError: rgb(0xFF), theme.ColorNameSuccess: rgb(0x00), theme.ColorNameForegroundOnSuccess: rgb(0xFF), theme.ColorNameWarning: rgb(0x00), theme.ColorNameForegroundOnWarning: rgb(0xFF), theme.ColorNameHyperlink: rgb(0x00), } }