257 lines
10 KiB
Go
257 lines
10 KiB
Go
package test
|
|
|
|
import (
|
|
"fmt"
|
|
"image/color"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"fyne.io/fyne/v2"
|
|
"fyne.io/fyne/v2/theme"
|
|
)
|
|
|
|
var defaultTheme fyne.Theme
|
|
|
|
// Try to keep these in sync with the existing color names at theme/color.go.
|
|
var knownColorNames = [...]fyne.ThemeColorName{
|
|
theme.ColorNameBackground,
|
|
theme.ColorNameButton,
|
|
theme.ColorNameDisabled,
|
|
theme.ColorNameDisabledButton,
|
|
theme.ColorNameError,
|
|
theme.ColorNameFocus,
|
|
theme.ColorNameForeground,
|
|
theme.ColorNameForegroundOnError,
|
|
theme.ColorNameForegroundOnPrimary,
|
|
theme.ColorNameForegroundOnSuccess,
|
|
theme.ColorNameForegroundOnWarning,
|
|
theme.ColorNameHeaderBackground,
|
|
theme.ColorNameHover,
|
|
theme.ColorNameHyperlink,
|
|
theme.ColorNameInputBackground,
|
|
theme.ColorNameInputBorder,
|
|
theme.ColorNameMenuBackground,
|
|
theme.ColorNameOverlayBackground,
|
|
theme.ColorNamePlaceHolder,
|
|
theme.ColorNamePressed,
|
|
theme.ColorNamePrimary,
|
|
theme.ColorNameScrollBar,
|
|
theme.ColorNameScrollBarBackground,
|
|
theme.ColorNameSelection,
|
|
theme.ColorNameSeparator,
|
|
theme.ColorNameShadow,
|
|
theme.ColorNameSuccess,
|
|
theme.ColorNameWarning,
|
|
}
|
|
|
|
// AssertAllColorNamesDefined asserts that all known color names are defined for the given theme.
|
|
func AssertAllColorNamesDefined(t *testing.T, th fyne.Theme, themeName string) {
|
|
oldApp := fyne.CurrentApp()
|
|
defer fyne.SetCurrentApp(oldApp)
|
|
|
|
for _, primaryName := range theme.PrimaryColorNames() {
|
|
testApp := NewTempApp(t)
|
|
testApp.Settings().(*testSettings).primaryColor = primaryName
|
|
for variantName, variant := range KnownThemeVariants() {
|
|
for _, cn := range knownColorNames {
|
|
assert.NotNil(t, th.Color(cn, variant), "undefined color %s variant %s in theme %s", cn, variantName, themeName)
|
|
// Transparent is used by the default theme as fallback for unknown color names.
|
|
// Built-in color names should have well-defined non-transparent values.
|
|
assert.NotEqual(t, color.Transparent, th.Color(cn, variant), "undefined color %s variant %s in theme %s", cn, variantName, themeName)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// KnownThemeVariants returns the known theme variants mapped by a descriptive key.
|
|
func KnownThemeVariants() map[string]fyne.ThemeVariant {
|
|
// Try to keep this in sync with the existing variants at theme/theme.go
|
|
return map[string]fyne.ThemeVariant{
|
|
"dark": theme.VariantDark,
|
|
"light": theme.VariantLight,
|
|
}
|
|
}
|
|
|
|
// NewTheme returns a new test theme using quiet ugly colors.
|
|
func NewTheme() fyne.Theme {
|
|
blue := func(alpha uint8) color.Color {
|
|
return &color.NRGBA{R: 0, G: 0, B: 255, A: alpha}
|
|
}
|
|
gray := func(level uint8) color.Color {
|
|
return &color.Gray{Y: level}
|
|
}
|
|
green := func(alpha uint8) color.Color {
|
|
return &color.NRGBA{R: 0, G: 255, B: 0, A: alpha}
|
|
}
|
|
red := func(alpha uint8) color.Color {
|
|
return &color.NRGBA{R: 200, G: 0, B: 0, A: alpha}
|
|
}
|
|
|
|
return &configurableTheme{
|
|
colors: map[fyne.ThemeColorName]color.Color{
|
|
theme.ColorNameBackground: red(255),
|
|
theme.ColorNameButton: gray(100),
|
|
theme.ColorNameDisabled: gray(20),
|
|
theme.ColorNameDisabledButton: gray(230),
|
|
theme.ColorNameError: blue(255),
|
|
theme.ColorNameFocus: red(66),
|
|
theme.ColorNameForeground: gray(255),
|
|
theme.ColorNameForegroundOnError: red(210),
|
|
theme.ColorNameForegroundOnPrimary: red(200),
|
|
theme.ColorNameForegroundOnSuccess: blue(201),
|
|
theme.ColorNameForegroundOnWarning: blue(202),
|
|
theme.ColorNameHeaderBackground: red(22),
|
|
theme.ColorNameHover: green(200),
|
|
theme.ColorNameHyperlink: blue(240),
|
|
theme.ColorNameInputBackground: red(30),
|
|
theme.ColorNameInputBorder: gray(10),
|
|
theme.ColorNameMenuBackground: red(50),
|
|
theme.ColorNameOverlayBackground: red(44),
|
|
theme.ColorNamePlaceHolder: blue(200),
|
|
theme.ColorNamePressed: blue(250),
|
|
theme.ColorNamePrimary: green(255),
|
|
theme.ColorNameScrollBar: blue(220),
|
|
theme.ColorNameScrollBarBackground: red(20),
|
|
theme.ColorNameSelection: red(55),
|
|
theme.ColorNameSeparator: gray(30),
|
|
theme.ColorNameShadow: blue(150),
|
|
theme.ColorNameSuccess: green(150),
|
|
theme.ColorNameWarning: red(100),
|
|
},
|
|
fonts: map[fyne.TextStyle]fyne.Resource{
|
|
{}: theme.DefaultTextBoldFont(),
|
|
{Bold: true}: theme.DefaultTextItalicFont(),
|
|
{Bold: true, Italic: true}: theme.DefaultTextMonospaceFont(),
|
|
{Italic: true}: theme.DefaultTextBoldItalicFont(),
|
|
{Monospace: true}: theme.DefaultTextFont(),
|
|
{Symbol: true}: theme.DefaultSymbolFont(),
|
|
},
|
|
name: "Ugly Test Theme",
|
|
sizes: map[fyne.ThemeSizeName]float32{
|
|
theme.SizeNameInlineIcon: float32(24),
|
|
theme.SizeNameInnerPadding: float32(20),
|
|
theme.SizeNameLineSpacing: float32(6),
|
|
theme.SizeNamePadding: float32(10),
|
|
theme.SizeNameScrollBar: float32(10),
|
|
theme.SizeNameScrollBarSmall: float32(2),
|
|
theme.SizeNameSeparatorThickness: float32(1),
|
|
theme.SizeNameText: float32(18),
|
|
theme.SizeNameHeadingText: float32(30.6),
|
|
theme.SizeNameSubHeadingText: float32(24),
|
|
theme.SizeNameCaptionText: float32(15),
|
|
theme.SizeNameInputBorder: float32(5),
|
|
theme.SizeNameInputRadius: float32(2),
|
|
theme.SizeNameSelectionRadius: float32(6),
|
|
theme.SizeNameScrollBarRadius: float32(2),
|
|
},
|
|
}
|
|
}
|
|
|
|
// Theme returns a test theme useful for image based tests.
|
|
func Theme() fyne.Theme {
|
|
if defaultTheme == nil {
|
|
defaultTheme = &configurableTheme{
|
|
colors: map[fyne.ThemeColorName]color.Color{
|
|
theme.ColorNameBackground: color.NRGBA{R: 0x44, G: 0x44, B: 0x44, A: 0xff},
|
|
theme.ColorNameButton: color.NRGBA{R: 0x33, G: 0x33, B: 0x33, A: 0xff},
|
|
theme.ColorNameDisabled: color.NRGBA{R: 0x88, G: 0x88, B: 0x88, A: 0xff},
|
|
theme.ColorNameDisabledButton: color.NRGBA{R: 0x22, G: 0x22, B: 0x22, A: 0xff},
|
|
theme.ColorNameError: color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff},
|
|
theme.ColorNameFocus: color.NRGBA{R: 0x78, G: 0x3a, B: 0x3a, A: 0xff},
|
|
theme.ColorNameForeground: color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff},
|
|
theme.ColorNameForegroundOnError: color.NRGBA{R: 0x08, G: 0x0a, B: 0x0f, A: 0xff},
|
|
theme.ColorNameForegroundOnPrimary: color.NRGBA{R: 0x08, G: 0x0c, B: 0x0f, A: 0xff},
|
|
theme.ColorNameForegroundOnSuccess: color.NRGBA{R: 0x0a, G: 0x0c, B: 0x0f, A: 0xff},
|
|
theme.ColorNameForegroundOnWarning: color.NRGBA{R: 0x08, G: 0x0c, B: 0x0a, A: 0xff},
|
|
theme.ColorNameHeaderBackground: color.NRGBA{R: 0x25, G: 0x25, B: 0x25, A: 0xff},
|
|
theme.ColorNameHover: color.NRGBA{R: 0x88, G: 0xff, B: 0xff, A: 0x22},
|
|
theme.ColorNameHyperlink: color.NRGBA{R: 0xff, G: 0xcc, B: 0x80, A: 0xff},
|
|
theme.ColorNameInputBackground: color.NRGBA{R: 0x66, G: 0x66, B: 0x66, A: 0xff},
|
|
theme.ColorNameInputBorder: color.NRGBA{R: 0x86, G: 0x86, B: 0x86, A: 0xff},
|
|
theme.ColorNameMenuBackground: color.NRGBA{R: 0x56, G: 0x56, B: 0x56, A: 0xff},
|
|
theme.ColorNameOverlayBackground: color.NRGBA{R: 0x28, G: 0x28, B: 0x28, A: 0xff},
|
|
theme.ColorNamePlaceHolder: color.NRGBA{R: 0xaa, G: 0xaa, B: 0xaa, A: 0xff},
|
|
theme.ColorNamePressed: color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x33},
|
|
theme.ColorNamePrimary: color.NRGBA{R: 0xff, G: 0xc0, B: 0x80, A: 0xff},
|
|
theme.ColorNameScrollBar: color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0xaa},
|
|
theme.ColorNameScrollBarBackground: color.NRGBA{R: 0x67, G: 0x66, B: 0x66, A: 0xff},
|
|
theme.ColorNameSelection: color.NRGBA{R: 0x78, G: 0x3a, B: 0x3a, A: 0x99},
|
|
theme.ColorNameSeparator: color.NRGBA{R: 0x90, G: 0x90, B: 0x90, A: 0xff},
|
|
theme.ColorNameShadow: color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x88},
|
|
theme.ColorNameSuccess: color.NRGBA{R: 0x00, G: 0x99, B: 0x00, A: 0xff},
|
|
theme.ColorNameWarning: color.NRGBA{R: 0xee, G: 0xee, B: 0x00, A: 0xff},
|
|
},
|
|
fonts: map[fyne.TextStyle]fyne.Resource{
|
|
{}: theme.DefaultTextFont(),
|
|
{Bold: true}: theme.DefaultTextBoldFont(),
|
|
{Bold: true, Italic: true}: theme.DefaultTextBoldItalicFont(),
|
|
{Italic: true}: theme.DefaultTextItalicFont(),
|
|
{Monospace: true}: theme.DefaultTextMonospaceFont(),
|
|
{Symbol: true}: theme.DefaultSymbolFont(),
|
|
},
|
|
name: "Default Test Theme",
|
|
sizes: map[fyne.ThemeSizeName]float32{
|
|
theme.SizeNameInlineIcon: float32(20),
|
|
theme.SizeNameInnerPadding: float32(8),
|
|
theme.SizeNameLineSpacing: float32(4),
|
|
theme.SizeNamePadding: float32(4),
|
|
theme.SizeNameScrollBar: float32(16),
|
|
theme.SizeNameScrollBarSmall: float32(3),
|
|
theme.SizeNameSeparatorThickness: float32(1),
|
|
theme.SizeNameText: float32(14),
|
|
theme.SizeNameHeadingText: float32(23.8),
|
|
theme.SizeNameSubHeadingText: float32(18),
|
|
theme.SizeNameCaptionText: float32(11),
|
|
theme.SizeNameInputBorder: float32(2),
|
|
theme.SizeNameInputRadius: float32(4),
|
|
theme.SizeNameSelectionRadius: float32(4),
|
|
theme.SizeNameScrollBarRadius: float32(3),
|
|
theme.SizeNameWindowTitleBarHeight: float32(20),
|
|
theme.SizeNameWindowButtonHeight: float32(10),
|
|
theme.SizeNameWindowButtonIcon: float32(8),
|
|
theme.SizeNameWindowButtonRadius: float32(5),
|
|
},
|
|
}
|
|
}
|
|
return defaultTheme
|
|
}
|
|
|
|
type configurableTheme struct {
|
|
colors map[fyne.ThemeColorName]color.Color
|
|
fonts map[fyne.TextStyle]fyne.Resource
|
|
name string
|
|
sizes map[fyne.ThemeSizeName]float32
|
|
}
|
|
|
|
var _ fyne.Theme = (*configurableTheme)(nil)
|
|
|
|
func (t *configurableTheme) Color(n fyne.ThemeColorName, _ fyne.ThemeVariant) color.Color {
|
|
if t.colors[n] == nil {
|
|
fyne.LogError(fmt.Sprintf("color %s not defined in theme %s", n, t.name), nil)
|
|
}
|
|
|
|
return t.colors[n]
|
|
}
|
|
|
|
func (t *configurableTheme) Font(style fyne.TextStyle) fyne.Resource {
|
|
if t.fonts[style] == nil {
|
|
fyne.LogError(fmt.Sprintf("font for style %#v not defined in theme %s", style, t.name), nil)
|
|
}
|
|
|
|
return t.fonts[style]
|
|
}
|
|
|
|
func (t *configurableTheme) Icon(n fyne.ThemeIconName) fyne.Resource {
|
|
return theme.DefaultTheme().Icon(n)
|
|
}
|
|
|
|
func (t *configurableTheme) Size(s fyne.ThemeSizeName) float32 {
|
|
if _, ok := t.sizes[s]; !ok {
|
|
fyne.LogError(fmt.Sprintf("size %s not defined in theme %s", s, t.name), nil)
|
|
return 0
|
|
}
|
|
|
|
return t.sizes[s]
|
|
}
|