Files
supersonic/ui/theme/theme.go
T

193 lines
4.8 KiB
Go

package theme
import (
"errors"
"image/color"
"io/ioutil"
"log"
"strings"
"supersonic/res"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/theme"
)
const ColorNamePageBackground fyne.ThemeColorName = "PageBackground"
const (
IconNameNowPlaying fyne.ThemeIconName = "NowPlaying"
IconNameFavorite fyne.ThemeIconName = "Favorite"
IconNameNotFavorite fyne.ThemeIconName = "NotFavorite"
IconNameAlbum fyne.ThemeIconName = "Album"
IconNameArtist fyne.ThemeIconName = "Artist"
IconNameGenre fyne.ThemeIconName = "Genre"
IconNamePlaylist fyne.ThemeIconName = "Playlist"
IconNameShuffle fyne.ThemeIconName = "Shuffle"
)
type VariantMode int
const (
VariantModeAuto VariantMode = iota
VariantModeDark
VariantModeLight
)
var (
normalFont fyne.Resource
boldFont fyne.Resource
)
type MyTheme struct {
NormalFont string
BoldFont string
VariantMode VariantMode
}
var _ fyne.Theme = (*MyTheme)(nil)
func (m *MyTheme) Color(name fyne.ThemeColorName, _ fyne.ThemeVariant) color.Color {
variant := m.getVariant()
switch name {
case ColorNamePageBackground:
if variant == theme.VariantDark {
return color.RGBA{R: 15, G: 15, B: 15, A: 255}
}
return color.RGBA{R: 250, G: 250, B: 250, A: 255}
case theme.ColorNameBackground:
if variant == theme.VariantDark {
return color.RGBA{R: 35, G: 35, B: 35, A: 255}
}
return color.RGBA{R: 225, G: 223, B: 225, A: 255}
case theme.ColorNameScrollBar:
if variant == theme.VariantDark {
return theme.DarkTheme().Color(theme.ColorNameForeground, variant)
}
return theme.LightTheme().Color(theme.ColorNameForeground, variant)
case theme.ColorNameButton:
if variant == theme.VariantDark {
return color.RGBA{R: 20, G: 20, B: 20, A: 50}
}
return color.RGBA{R: 200, G: 200, B: 200, A: 240}
case theme.ColorNameInputBackground:
if variant == theme.VariantDark {
return color.RGBA{R: 20, G: 20, B: 20, A: 50}
}
case theme.ColorNameForeground:
if variant == theme.VariantLight {
return color.RGBA{R: 10, G: 10, B: 10, A: 255}
}
case theme.ColorNamePrimary:
if variant == theme.VariantLight {
return color.RGBA{R: 25, G: 25, B: 250, A: 255}
}
}
return theme.DefaultTheme().Color(name, variant)
}
func (m *MyTheme) Icon(name fyne.ThemeIconName) fyne.Resource {
variant := m.getVariant()
switch name {
case IconNameAlbum:
if variant == theme.VariantDark {
return res.ResDiscInvertPng
}
return res.ResDiscPng
case IconNameArtist:
if variant == theme.VariantDark {
return res.ResPeopleInvertPng
}
return res.ResPeoplePng
case IconNameFavorite:
if variant == theme.VariantDark {
return res.ResHeartFilledInvertPng
}
return res.ResHeartFilledPng
case IconNameNotFavorite:
if variant == theme.VariantDark {
return res.ResHeartOutlineInvertPng
}
return res.ResHeartOutlinePng
case IconNameGenre:
if variant == theme.VariantDark {
return res.ResTheatermasksInvertPng
}
return res.ResTheatermasksPng
case IconNameNowPlaying:
if variant == theme.VariantDark {
return res.ResHeadphonesInvertPng
}
return res.ResHeadphonesPng
case IconNamePlaylist:
if variant == theme.VariantDark {
return res.ResPlaylistInvertPng
}
return res.ResPlaylistPng
case IconNameShuffle:
if variant == theme.VariantDark {
return res.ResShuffleInvertSvg
}
return res.ResShuffleSvg
default:
return theme.DefaultTheme().Icon(name)
}
}
func (m *MyTheme) Font(style fyne.TextStyle) fyne.Resource {
switch style {
case fyne.TextStyle{}:
if m.NormalFont != "" && normalFont == nil {
if content, err := readTTFFile(m.NormalFont); err != nil {
m.NormalFont = ""
m.BoldFont = ""
} else {
normalFont = fyne.NewStaticResource("normalFont", content)
}
}
if normalFont != nil {
return normalFont
}
case fyne.TextStyle{Bold: true}:
if m.BoldFont != "" && boldFont == nil {
if content, err := ioutil.ReadFile(m.BoldFont); err != nil {
m.BoldFont = ""
} else {
normalFont = fyne.NewStaticResource("boldFont", content)
}
}
if boldFont != nil {
return boldFont
}
if normalFont != nil {
return normalFont
}
}
return theme.DefaultTheme().Font(style)
}
func (m *MyTheme) Size(name fyne.ThemeSizeName) float32 {
return theme.DefaultTheme().Size(name)
}
func (m *MyTheme) getVariant() fyne.ThemeVariant {
if m.VariantMode == VariantModeDark {
return theme.VariantDark
} else if m.VariantMode == VariantModeLight {
return theme.VariantLight
}
return fyne.CurrentApp().Settings().ThemeVariant()
}
func readTTFFile(filepath string) ([]byte, error) {
if !strings.HasSuffix(filepath, ".ttf") {
err := errors.New("only .ttf fonts are supported")
log.Printf("error loading custom font %q: %s", filepath, err.Error())
return nil, err
}
content, err := ioutil.ReadFile(filepath)
if err != nil {
log.Printf("error loading custom font %q: %s", filepath, err.Error())
}
return content, err
}