mirror of https://github.com/anoshenko/rui.git
Fixed background radial gradient
This commit is contained in:
parent
26abd1f632
commit
61ee6c03f2
33
angleUnit.go
33
angleUnit.go
|
@ -67,31 +67,27 @@ func angleUnitSuffixes() map[AngleUnitType]string {
|
|||
|
||||
// StringToAngleUnit converts the string argument to AngleUnit
|
||||
func StringToAngleUnit(value string) (AngleUnit, bool) {
|
||||
var angle AngleUnit
|
||||
ok, err := angle.setValue(value)
|
||||
if !ok {
|
||||
ErrorLog(err)
|
||||
angle, err := stringToAngleUnit(value)
|
||||
if err != nil {
|
||||
ErrorLog(err.Error())
|
||||
return angle, false
|
||||
}
|
||||
return angle, ok
|
||||
return angle, true
|
||||
}
|
||||
|
||||
func (angle *AngleUnit) setValue(value string) (bool, string) {
|
||||
func stringToAngleUnit(value string) (AngleUnit, error) {
|
||||
value = strings.ToLower(strings.Trim(value, " \t\n\r"))
|
||||
|
||||
setValue := func(suffix string, unitType AngleUnitType) (bool, string) {
|
||||
setValue := func(suffix string, unitType AngleUnitType) (AngleUnit, error) {
|
||||
val, err := strconv.ParseFloat(value[:len(value)-len(suffix)], 64)
|
||||
if err != nil {
|
||||
return false, `AngleUnit.SetValue("` + value + `") error: ` + err.Error()
|
||||
return AngleUnit{}, err
|
||||
}
|
||||
angle.Value = val
|
||||
angle.Type = unitType
|
||||
return true, ""
|
||||
return AngleUnit{Value: val, Type: unitType}, nil
|
||||
}
|
||||
|
||||
if value == "π" {
|
||||
angle.Value = 1
|
||||
angle.Type = PiRadian
|
||||
return true, ""
|
||||
return AngleUnit{Value: 1, Type: PiRadian}, nil
|
||||
}
|
||||
|
||||
if strings.HasSuffix(value, "π") {
|
||||
|
@ -108,13 +104,12 @@ func (angle *AngleUnit) setValue(value string) (bool, string) {
|
|||
}
|
||||
}
|
||||
|
||||
if val, err := strconv.ParseFloat(value, 64); err == nil {
|
||||
angle.Value = val
|
||||
angle.Type = Radian
|
||||
return true, ""
|
||||
val, err := strconv.ParseFloat(value, 64)
|
||||
if err != nil {
|
||||
return AngleUnit{}, err
|
||||
}
|
||||
|
||||
return false, `AngleUnit.SetValue("` + value + `") error: invalid argument`
|
||||
return AngleUnit{Value: val, Type: Radian}, nil
|
||||
}
|
||||
|
||||
// String - convert AngleUnit to string
|
||||
|
|
|
@ -161,7 +161,8 @@ func (gradient *backgroundGradient) Set(tag string, value interface{}) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
return gradient.backgroundElement.Set(tag, value)
|
||||
ErrorLogF("Property %s is not supported by a background gradient", tag)
|
||||
return false
|
||||
}
|
||||
|
||||
func (point *BackgroundGradientPoint) setValue(text string) bool {
|
||||
|
@ -303,8 +304,10 @@ func (gradient *backgroundLinearGradient) Set(tag string, value interface{}) boo
|
|||
return true
|
||||
|
||||
case string:
|
||||
var angle AngleUnit
|
||||
if ok, _ := angle.setValue(value); ok {
|
||||
if gradient.setSimpleProperty(tag, value) {
|
||||
return true
|
||||
}
|
||||
if angle, ok := StringToAngleUnit(value); ok {
|
||||
gradient.properties[Direction] = angle
|
||||
return true
|
||||
}
|
||||
|
@ -404,8 +407,60 @@ func (gradient *backgroundRadialGradient) Set(tag string, value interface{}) boo
|
|||
switch tag {
|
||||
case RadialGradientRadius:
|
||||
switch value := value.(type) {
|
||||
case string, SizeUnit:
|
||||
return gradient.propertyList.Set(RadialGradientRadius, value)
|
||||
case []SizeUnit:
|
||||
switch len(value) {
|
||||
case 0:
|
||||
delete(gradient.properties, RadialGradientRadius)
|
||||
return true
|
||||
|
||||
case 1:
|
||||
if value[0].Type == Auto {
|
||||
delete(gradient.properties, RadialGradientRadius)
|
||||
} else {
|
||||
gradient.properties[RadialGradientRadius] = value[0]
|
||||
}
|
||||
return true
|
||||
|
||||
default:
|
||||
gradient.properties[RadialGradientRadius] = value
|
||||
return true
|
||||
}
|
||||
|
||||
case []interface{}:
|
||||
switch len(value) {
|
||||
case 0:
|
||||
delete(gradient.properties, RadialGradientRadius)
|
||||
return true
|
||||
|
||||
case 1:
|
||||
return gradient.Set(RadialGradientRadius, value[0])
|
||||
|
||||
default:
|
||||
gradient.properties[RadialGradientRadius] = value
|
||||
return true
|
||||
}
|
||||
|
||||
case string:
|
||||
if gradient.setSimpleProperty(RadialGradientRadius, value) {
|
||||
return true
|
||||
}
|
||||
if size, err := stringToSizeUnit(value); err == nil {
|
||||
if size.Type == Auto {
|
||||
delete(gradient.properties, RadialGradientRadius)
|
||||
} else {
|
||||
gradient.properties[RadialGradientRadius] = size
|
||||
}
|
||||
return true
|
||||
}
|
||||
return gradient.setEnumProperty(RadialGradientRadius, value, enumProperties[RadialGradientRadius].values)
|
||||
|
||||
case SizeUnit:
|
||||
if value.Type == Auto {
|
||||
delete(gradient.properties, RadialGradientRadius)
|
||||
} else {
|
||||
gradient.properties[RadialGradientRadius] = value
|
||||
}
|
||||
return true
|
||||
|
||||
case int:
|
||||
n := value
|
||||
|
@ -415,10 +470,7 @@ func (gradient *backgroundRadialGradient) Set(tag string, value interface{}) boo
|
|||
}
|
||||
ErrorLogF(`Invalid value of "%s" property: %v`, tag, value)
|
||||
|
||||
case RadialGradientShape:
|
||||
return gradient.propertyList.Set(RadialGradientShape, value)
|
||||
|
||||
case CenterX, CenterY:
|
||||
case RadialGradientShape, CenterX, CenterY:
|
||||
return gradient.propertyList.Set(tag, value)
|
||||
}
|
||||
|
||||
|
@ -439,10 +491,11 @@ func (gradient *backgroundRadialGradient) cssStyle(session Session) string {
|
|||
buffer.WriteString(`radial-gradient(`)
|
||||
}
|
||||
|
||||
var shapeText string
|
||||
if shape, ok := enumProperty(gradient, RadialGradientShape, session, EllipseGradient); ok && shape == CircleGradient {
|
||||
buffer.WriteString(`circle `)
|
||||
shapeText = `circle `
|
||||
} else {
|
||||
buffer.WriteString(`ellipse `)
|
||||
shapeText = `ellipse `
|
||||
}
|
||||
|
||||
if value, ok := gradient.properties[RadialGradientRadius]; ok {
|
||||
|
@ -451,10 +504,16 @@ func (gradient *backgroundRadialGradient) cssStyle(session Session) string {
|
|||
if text, ok := session.resolveConstants(value); ok {
|
||||
values := enumProperties[RadialGradientRadius]
|
||||
if n, ok := enumStringToInt(text, values.values, false); ok {
|
||||
buffer.WriteString(shapeText)
|
||||
shapeText = ""
|
||||
buffer.WriteString(values.cssValues[n])
|
||||
buffer.WriteString(" ")
|
||||
} else {
|
||||
if r, ok := StringToSizeUnit(text); ok && r.Type != Auto {
|
||||
buffer.WriteString("ellipse ")
|
||||
shapeText = ""
|
||||
buffer.WriteString(r.cssString(""))
|
||||
buffer.WriteString(" ")
|
||||
buffer.WriteString(r.cssString(""))
|
||||
buffer.WriteString(" ")
|
||||
} else {
|
||||
|
@ -468,6 +527,8 @@ func (gradient *backgroundRadialGradient) cssStyle(session Session) string {
|
|||
case int:
|
||||
values := enumProperties[RadialGradientRadius].cssValues
|
||||
if value >= 0 && value < len(values) {
|
||||
buffer.WriteString(shapeText)
|
||||
shapeText = ""
|
||||
buffer.WriteString(values[value])
|
||||
buffer.WriteString(" ")
|
||||
} else {
|
||||
|
@ -476,8 +537,55 @@ func (gradient *backgroundRadialGradient) cssStyle(session Session) string {
|
|||
|
||||
case SizeUnit:
|
||||
if value.Type != Auto {
|
||||
buffer.WriteString("ellipse ")
|
||||
shapeText = ""
|
||||
buffer.WriteString(value.cssString(""))
|
||||
buffer.WriteString(" ")
|
||||
buffer.WriteString(value.cssString(""))
|
||||
buffer.WriteString(" ")
|
||||
}
|
||||
|
||||
case []SizeUnit:
|
||||
count := len(value)
|
||||
if count > 2 {
|
||||
count = 2
|
||||
}
|
||||
buffer.WriteString("ellipse ")
|
||||
shapeText = ""
|
||||
for i := 0; i < count; i++ {
|
||||
buffer.WriteString(value[i].cssString("50%"))
|
||||
buffer.WriteString(" ")
|
||||
}
|
||||
|
||||
case []interface{}:
|
||||
count := len(value)
|
||||
if count > 2 {
|
||||
count = 2
|
||||
}
|
||||
buffer.WriteString("ellipse ")
|
||||
shapeText = ""
|
||||
for i := 0; i < count; i++ {
|
||||
if value[i] != nil {
|
||||
switch value := value[i].(type) {
|
||||
case SizeUnit:
|
||||
buffer.WriteString(value.cssString("50%"))
|
||||
buffer.WriteString(" ")
|
||||
|
||||
case string:
|
||||
if text, ok := session.resolveConstants(value); ok {
|
||||
if size, err := stringToSizeUnit(text); err == nil {
|
||||
buffer.WriteString(size.cssString("50%"))
|
||||
buffer.WriteString(" ")
|
||||
} else {
|
||||
buffer.WriteString("50% ")
|
||||
}
|
||||
} else {
|
||||
buffer.WriteString("50% ")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
buffer.WriteString("50% ")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -485,6 +593,9 @@ func (gradient *backgroundRadialGradient) cssStyle(session Session) string {
|
|||
x, _ := sizeProperty(gradient, CenterX, session)
|
||||
y, _ := sizeProperty(gradient, CenterX, session)
|
||||
if x.Type != Auto || y.Type != Auto {
|
||||
if shapeText != "" {
|
||||
buffer.WriteString(shapeText)
|
||||
}
|
||||
buffer.WriteString("at ")
|
||||
buffer.WriteString(x.cssString("50%"))
|
||||
buffer.WriteString(" ")
|
||||
|
|
36
color.go
36
color.go
|
@ -2,6 +2,7 @@ package rui
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -71,43 +72,49 @@ func (color Color) cssString() string {
|
|||
|
||||
// StringToColor converts the string argument to Color value
|
||||
func StringToColor(text string) (Color, bool) {
|
||||
color, err := stringToColor(text)
|
||||
if err != nil {
|
||||
ErrorLog(err.Error())
|
||||
return color, false
|
||||
}
|
||||
return color, true
|
||||
}
|
||||
|
||||
func stringToColor(text string) (Color, error) {
|
||||
|
||||
text = strings.Trim(text, " \t\r\n")
|
||||
if text == "" {
|
||||
ErrorLog(`Invalid color value: ""`)
|
||||
return 0, false
|
||||
return 0, errors.New(`Invalid color value: ""`)
|
||||
}
|
||||
|
||||
if text[0] == '#' {
|
||||
c, err := strconv.ParseUint(text[1:], 16, 32)
|
||||
if err != nil {
|
||||
ErrorLog("Set color value error: " + err.Error())
|
||||
return 0, false
|
||||
return 0, errors.New("Set color value error: " + err.Error())
|
||||
}
|
||||
|
||||
switch len(text) - 1 {
|
||||
case 8:
|
||||
return Color(c), true
|
||||
return Color(c), nil
|
||||
|
||||
case 6:
|
||||
return Color(c | 0xFF000000), true
|
||||
return Color(c | 0xFF000000), nil
|
||||
|
||||
case 4:
|
||||
a := (c >> 12) & 0xF
|
||||
r := (c >> 8) & 0xF
|
||||
g := (c >> 4) & 0xF
|
||||
b := c & 0xF
|
||||
return Color((a << 28) | (a << 24) | (r << 20) | (r << 16) | (g << 12) | (g << 8) | (b << 4) | b), true
|
||||
return Color((a << 28) | (a << 24) | (r << 20) | (r << 16) | (g << 12) | (g << 8) | (b << 4) | b), nil
|
||||
|
||||
case 3:
|
||||
r := (c >> 8) & 0xF
|
||||
g := (c >> 4) & 0xF
|
||||
b := c & 0xF
|
||||
return Color(0xFF000000 | (r << 20) | (r << 16) | (g << 12) | (g << 8) | (b << 4) | b), true
|
||||
return Color(0xFF000000 | (r << 20) | (r << 16) | (g << 12) | (g << 8) | (b << 4) | b), nil
|
||||
}
|
||||
|
||||
ErrorLog(`Invalid color format: "` + text + `". Valid formats: #AARRGGBB, #RRGGBB, #ARGB, #RGB`)
|
||||
return 0, false
|
||||
return 0, errors.New(`Invalid color format: "` + text + `". Valid formats: #AARRGGBB, #RRGGBB, #ARGB, #RGB`)
|
||||
}
|
||||
|
||||
parseRGB := func(args string) []int {
|
||||
|
@ -155,23 +162,22 @@ func StringToColor(text string) (Color, bool) {
|
|||
if strings.HasPrefix(text, "rgba") {
|
||||
args := parseRGB(text[4:])
|
||||
if len(args) == 4 {
|
||||
return Color((args[3] << 24) | (args[0] << 16) | (args[1] << 8) | args[2]), true
|
||||
return Color((args[3] << 24) | (args[0] << 16) | (args[1] << 8) | args[2]), nil
|
||||
}
|
||||
}
|
||||
|
||||
if strings.HasPrefix(text, "rgb") {
|
||||
args := parseRGB(text[3:])
|
||||
if len(args) == 3 {
|
||||
return Color(0xFF000000 | (args[0] << 16) | (args[1] << 8) | args[2]), true
|
||||
return Color(0xFF000000 | (args[0] << 16) | (args[1] << 8) | args[2]), nil
|
||||
}
|
||||
}
|
||||
|
||||
// TODO hsl(360,100%,50%), hsla(360,100%,50%,.5)
|
||||
|
||||
if color, ok := colorConstants[text]; ok {
|
||||
return color, true
|
||||
return color, nil
|
||||
}
|
||||
|
||||
ErrorLog(`Invalid color format: "` + text + `"`)
|
||||
return 0, false
|
||||
return 0, errors.New(`Invalid color format: "` + text + `"`)
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ func (style *viewStyle) setGridCellSize(tag string, value interface{}) bool {
|
|||
val = strings.Trim(val, " \t\n\r")
|
||||
if isConstantName(val) {
|
||||
sizes[i] = val
|
||||
} else if size, ok := StringToSizeUnit(val); ok {
|
||||
} else if size, err := stringToSizeUnit(val); err == nil {
|
||||
sizes[i] = size
|
||||
} else {
|
||||
invalidPropertyValue(tag, value)
|
||||
|
@ -52,7 +52,7 @@ func (style *viewStyle) setGridCellSize(tag string, value interface{}) bool {
|
|||
style.properties[tag] = sizes
|
||||
} else if isConstantName(values[0]) {
|
||||
style.properties[tag] = values[0]
|
||||
} else if size, ok := StringToSizeUnit(values[0]); ok {
|
||||
} else if size, err := stringToSizeUnit(values[0]); err == nil {
|
||||
style.properties[tag] = size
|
||||
} else {
|
||||
invalidPropertyValue(tag, value)
|
||||
|
@ -110,7 +110,7 @@ func (style *viewStyle) setGridCellSize(tag string, value interface{}) bool {
|
|||
case string:
|
||||
if isConstantName(val) {
|
||||
sizes[i] = val
|
||||
} else if size, ok := StringToSizeUnit(val); ok {
|
||||
} else if size, err := stringToSizeUnit(val); err == nil {
|
||||
sizes[i] = size
|
||||
} else {
|
||||
invalidPropertyValue(tag, value)
|
||||
|
@ -291,7 +291,7 @@ func gridCellSizes(properties Properties, tag string, session Session) []SizeUni
|
|||
|
||||
case string:
|
||||
if text, ok := session.resolveConstants(val); ok {
|
||||
result[i], _ = StringToSizeUnit(text)
|
||||
result[i], _ = stringToSizeUnit(text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -302,7 +302,7 @@ func gridCellSizes(properties Properties, tag string, session Session) []SizeUni
|
|||
values := strings.Split(text, ",")
|
||||
result := make([]SizeUnit, len(values))
|
||||
for i, val := range values {
|
||||
result[i], _ = StringToSizeUnit(val)
|
||||
result[i], _ = stringToSizeUnit(val)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -586,8 +586,8 @@ func (properties *propertyList) setColorProperty(tag string, value interface{})
|
|||
var result Color
|
||||
switch value := value.(type) {
|
||||
case string:
|
||||
var ok bool
|
||||
if result, ok = StringToColor(value); !ok {
|
||||
var err error
|
||||
if result, err = stringToColor(value); err != nil {
|
||||
invalidPropertyValue(tag, value)
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -166,9 +166,9 @@ func (session *sessionData) Color(tag string) (Color, bool) {
|
|||
}
|
||||
|
||||
if len(result) == 0 || result[0] != '@' {
|
||||
color, ok := StringToColor(result)
|
||||
if !ok {
|
||||
ErrorLogF(`invalid value "%v" of "%v" color constant`, result, tag)
|
||||
color, err := stringToColor(result)
|
||||
if err != nil {
|
||||
ErrorLogF(`invalid value "%v" of "%v" color constant (%s)`, result, tag, err.Error())
|
||||
return 0, false
|
||||
}
|
||||
return color, true
|
||||
|
|
21
sizeUnit.go
21
sizeUnit.go
|
@ -1,6 +1,7 @@
|
|||
package rui
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -120,15 +121,23 @@ func sizeUnitSuffixes() map[SizeUnitType]string {
|
|||
|
||||
// StringToSizeUnit converts the string argument to SizeUnit
|
||||
func StringToSizeUnit(value string) (SizeUnit, bool) {
|
||||
size, err := stringToSizeUnit(value)
|
||||
if err != nil {
|
||||
ErrorLog(err.Error())
|
||||
return size, false
|
||||
}
|
||||
return size, true
|
||||
}
|
||||
|
||||
func stringToSizeUnit(value string) (SizeUnit, error) {
|
||||
value = strings.Trim(value, " \t\n\r")
|
||||
|
||||
switch value {
|
||||
case "auto", "none", "":
|
||||
return SizeUnit{Type: Auto, Value: 0}, true
|
||||
return SizeUnit{Type: Auto, Value: 0}, nil
|
||||
|
||||
case "0":
|
||||
return SizeUnit{Type: SizeInPixel, Value: 0}, true
|
||||
return SizeUnit{Type: SizeInPixel, Value: 0}, nil
|
||||
}
|
||||
|
||||
suffixes := sizeUnitSuffixes()
|
||||
|
@ -137,15 +146,13 @@ func StringToSizeUnit(value string) (SizeUnit, bool) {
|
|||
var err error
|
||||
var val float64
|
||||
if val, err = strconv.ParseFloat(value[:len(value)-len(suffix)], 64); err != nil {
|
||||
ErrorLog(err.Error())
|
||||
return SizeUnit{Type: Auto, Value: 0}, false
|
||||
return SizeUnit{Type: Auto, Value: 0}, err
|
||||
}
|
||||
return SizeUnit{Type: unitType, Value: val}, true
|
||||
return SizeUnit{Type: unitType, Value: val}, nil
|
||||
}
|
||||
}
|
||||
|
||||
ErrorLog(`Invalid SizeUnit value: "` + value + `"`)
|
||||
return SizeUnit{Type: Auto, Value: 0}, false
|
||||
return SizeUnit{Type: Auto, Value: 0}, errors.New(`Invalid SizeUnit value: "` + value + `"`)
|
||||
}
|
||||
|
||||
// String - convert SizeUnit to string
|
||||
|
|
Loading…
Reference in New Issue