begin work on custom theme support
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
package theme
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"image/color"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/dweymouth/supersonic/sharedutil"
|
||||
"github.com/pelletier/go-toml"
|
||||
)
|
||||
|
||||
type ThemeFileHeader struct {
|
||||
Name string
|
||||
Version string
|
||||
SupportsDark bool
|
||||
SupportsLight bool
|
||||
}
|
||||
|
||||
type ThemeFile struct {
|
||||
SupersonicTheme ThemeFileHeader
|
||||
|
||||
DarkColors ThemeColors
|
||||
LightColors ThemeColors
|
||||
}
|
||||
|
||||
type ThemeColors struct {
|
||||
// Supersonic-specific colors
|
||||
|
||||
PageBackground string
|
||||
|
||||
// Fyne colors
|
||||
|
||||
Background string
|
||||
|
||||
Button string
|
||||
|
||||
DisabledButton string
|
||||
|
||||
Disabled string
|
||||
|
||||
Error string
|
||||
|
||||
Focus string
|
||||
|
||||
Foreground string
|
||||
|
||||
Hover string
|
||||
|
||||
InputBackground string
|
||||
|
||||
InputBorder string
|
||||
|
||||
MenuBackground string
|
||||
|
||||
OverlayBackground string
|
||||
|
||||
Placeholder string
|
||||
|
||||
Pressed string
|
||||
|
||||
Primary string
|
||||
|
||||
ScrollBar string
|
||||
|
||||
Selection string
|
||||
|
||||
Separator string
|
||||
|
||||
Shadow string
|
||||
|
||||
Success string
|
||||
|
||||
Warning string
|
||||
}
|
||||
|
||||
func ReadThemeFile(filePath string) (*ThemeFile, error) {
|
||||
f, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
theme := &ThemeFile{}
|
||||
if err := toml.NewDecoder(f).Decode(theme); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if theme.SupersonicTheme.Name == "" || theme.SupersonicTheme.Version != "0.1" {
|
||||
return nil, errors.New("invalid theme file name or version")
|
||||
}
|
||||
if !(theme.SupersonicTheme.SupportsDark || theme.SupersonicTheme.SupportsLight) {
|
||||
return nil, errors.New("invalid theme file: must support one or both of light/dark")
|
||||
}
|
||||
|
||||
return theme, nil
|
||||
}
|
||||
|
||||
// Parses a CSS-style #RRGGBB or #RRGGBBAA string
|
||||
func ColorStringToColor(colorStr string) (color.Color, error) {
|
||||
if !strings.HasPrefix(colorStr, "#") || !sharedutil.SliceContains([]int{7, 9}, len(colorStr)) {
|
||||
return color.Black, errors.New("invalid color string")
|
||||
}
|
||||
colorBytes := make([]byte, 4)
|
||||
n, err := hex.Decode(colorBytes, []byte(colorStr[1:]))
|
||||
if err != nil {
|
||||
return color.Black, fmt.Errorf("invalid color string: %s", err.Error())
|
||||
}
|
||||
if n == 3 {
|
||||
colorBytes[3] = 255 // opaque alpha
|
||||
}
|
||||
return color.RGBA{R: colorBytes[0], G: colorBytes[1], B: colorBytes[2], A: colorBytes[3]}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user