Files
deskview/internal/ui/theme.go
T
2026-10-28 08:47:09 +08:00

165 lines
5.8 KiB
Go

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),
}
}