2021-09-07 17:36:50 +03:00
|
|
|
package rui
|
|
|
|
|
|
|
|
import (
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
2022-07-26 18:36:00 +03:00
|
|
|
func (style *viewStyle) setRange(tag string, value any) bool {
|
2021-09-07 17:36:50 +03:00
|
|
|
switch value := value.(type) {
|
|
|
|
case string:
|
|
|
|
if strings.Contains(value, "@") {
|
|
|
|
style.properties[tag] = value
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
var r Range
|
|
|
|
if !r.setValue(value) {
|
|
|
|
invalidPropertyValue(tag, value)
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
style.properties[tag] = r
|
|
|
|
|
|
|
|
case int:
|
|
|
|
style.properties[tag] = Range{First: value, Last: value}
|
|
|
|
|
|
|
|
case Range:
|
|
|
|
style.properties[tag] = value
|
|
|
|
|
|
|
|
default:
|
|
|
|
notCompatibleType(tag, value)
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2022-07-26 18:36:00 +03:00
|
|
|
func (style *viewStyle) setBackground(value any) bool {
|
2024-04-22 19:14:58 +03:00
|
|
|
background := []BackgroundElement{}
|
|
|
|
|
2021-09-07 17:36:50 +03:00
|
|
|
switch value := value.(type) {
|
|
|
|
case BackgroundElement:
|
2024-04-22 19:14:58 +03:00
|
|
|
background = []BackgroundElement{value}
|
2021-09-07 17:36:50 +03:00
|
|
|
|
|
|
|
case []BackgroundElement:
|
2024-04-22 19:14:58 +03:00
|
|
|
background = value
|
|
|
|
|
|
|
|
case []DataValue:
|
|
|
|
for _, el := range value {
|
|
|
|
if el.IsObject() {
|
|
|
|
if element := createBackground(el.Object()); element != nil {
|
|
|
|
background = append(background, element)
|
|
|
|
}
|
|
|
|
} else if obj := ParseDataText(el.Value()); obj != nil {
|
|
|
|
if element := createBackground(obj); element != nil {
|
|
|
|
background = append(background, element)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-09-07 17:36:50 +03:00
|
|
|
|
|
|
|
case DataObject:
|
|
|
|
if element := createBackground(value); element != nil {
|
2024-04-22 19:14:58 +03:00
|
|
|
background = []BackgroundElement{element}
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
case []DataObject:
|
|
|
|
for _, obj := range value {
|
|
|
|
if element := createBackground(obj); element != nil {
|
|
|
|
background = append(background, element)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
case string:
|
|
|
|
if obj := ParseDataText(value); obj != nil {
|
|
|
|
if element := createBackground(obj); element != nil {
|
2024-04-22 19:14:58 +03:00
|
|
|
background = []BackgroundElement{element}
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-22 19:14:58 +03:00
|
|
|
if len(background) > 0 {
|
|
|
|
style.properties[Background] = background
|
|
|
|
return true
|
|
|
|
}
|
2021-09-07 17:36:50 +03:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2024-06-29 12:05:27 +03:00
|
|
|
func (style *viewStyle) setTransition(tag string, value any) bool {
|
|
|
|
setObject := func(obj DataObject) bool {
|
|
|
|
if obj != nil {
|
|
|
|
tag := strings.ToLower(tag)
|
|
|
|
switch tag {
|
|
|
|
case "", "_":
|
|
|
|
ErrorLog("Invalid transition property name")
|
|
|
|
|
|
|
|
default:
|
|
|
|
style.transitions[tag] = parseAnimation(obj)
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
switch value := value.(type) {
|
|
|
|
case Params:
|
|
|
|
result := true
|
|
|
|
for tag, val := range value {
|
|
|
|
tag = strings.ToLower(strings.Trim(tag, " \t"))
|
|
|
|
if tag == "" {
|
|
|
|
ErrorLog("Invalid transition property name")
|
|
|
|
result = false
|
|
|
|
} else if val == nil {
|
|
|
|
delete(style.transitions, tag)
|
|
|
|
} else if animation, ok := val.(Animation); ok {
|
|
|
|
style.transitions[tag] = animation
|
|
|
|
} else {
|
|
|
|
notCompatibleType(Transition, val)
|
|
|
|
result = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
|
|
|
|
case DataObject:
|
|
|
|
return setObject(value)
|
|
|
|
|
|
|
|
case DataNode:
|
|
|
|
switch value.Type() {
|
|
|
|
case ObjectNode:
|
|
|
|
return setObject(value.Object())
|
|
|
|
|
|
|
|
case ArrayNode:
|
|
|
|
result := true
|
|
|
|
for i := 0; i < value.ArraySize(); i++ {
|
|
|
|
if obj := value.ArrayElement(i).Object(); obj != nil {
|
|
|
|
result = setObject(obj) && result
|
|
|
|
} else {
|
|
|
|
notCompatibleType(tag, value.ArrayElement(i))
|
|
|
|
result = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
notCompatibleType(tag, value)
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (style *viewStyle) setAnimation(tag string, value any) bool {
|
2024-07-01 19:17:03 +03:00
|
|
|
|
|
|
|
set := func(animations []Animation) {
|
|
|
|
style.properties[tag] = animations
|
|
|
|
for _, animation := range animations {
|
|
|
|
animation.used()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-29 12:05:27 +03:00
|
|
|
switch value := value.(type) {
|
|
|
|
case Animation:
|
2024-07-01 19:17:03 +03:00
|
|
|
set([]Animation{value})
|
2024-06-29 12:05:27 +03:00
|
|
|
return true
|
|
|
|
|
|
|
|
case []Animation:
|
2024-07-01 19:17:03 +03:00
|
|
|
set(value)
|
2024-06-29 12:05:27 +03:00
|
|
|
return true
|
|
|
|
|
|
|
|
case DataObject:
|
|
|
|
if animation := parseAnimation(value); animation.hasAnimatedProperty() {
|
2024-07-01 19:17:03 +03:00
|
|
|
set([]Animation{animation})
|
2024-06-29 12:05:27 +03:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
case DataNode:
|
|
|
|
animations := []Animation{}
|
|
|
|
result := true
|
|
|
|
for i := 0; i < value.ArraySize(); i++ {
|
|
|
|
if obj := value.ArrayElement(i).Object(); obj != nil {
|
|
|
|
if anim := parseAnimation(obj); anim.hasAnimatedProperty() {
|
|
|
|
animations = append(animations, anim)
|
|
|
|
} else {
|
|
|
|
result = false
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
notCompatibleType(tag, value.ArrayElement(i))
|
|
|
|
result = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if result && len(animations) > 0 {
|
2024-07-01 19:17:03 +03:00
|
|
|
set(animations)
|
2024-06-29 12:05:27 +03:00
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
notCompatibleType(tag, value)
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2021-09-07 17:36:50 +03:00
|
|
|
func (style *viewStyle) Remove(tag string) {
|
|
|
|
style.remove(strings.ToLower(tag))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (style *viewStyle) remove(tag string) {
|
|
|
|
switch tag {
|
|
|
|
case BorderStyle, BorderColor, BorderWidth,
|
|
|
|
BorderLeft, BorderLeftStyle, BorderLeftColor, BorderLeftWidth,
|
|
|
|
BorderRight, BorderRightStyle, BorderRightColor, BorderRightWidth,
|
|
|
|
BorderTop, BorderTopStyle, BorderTopColor, BorderTopWidth,
|
|
|
|
BorderBottom, BorderBottomStyle, BorderBottomColor, BorderBottomWidth:
|
|
|
|
if border := getBorder(style, Border); border != nil {
|
|
|
|
border.delete(tag)
|
|
|
|
}
|
|
|
|
|
|
|
|
case CellBorderStyle, CellBorderColor, CellBorderWidth,
|
|
|
|
CellBorderLeft, CellBorderLeftStyle, CellBorderLeftColor, CellBorderLeftWidth,
|
|
|
|
CellBorderRight, CellBorderRightStyle, CellBorderRightColor, CellBorderRightWidth,
|
|
|
|
CellBorderTop, CellBorderTopStyle, CellBorderTopColor, CellBorderTopWidth,
|
|
|
|
CellBorderBottom, CellBorderBottomStyle, CellBorderBottomColor, CellBorderBottomWidth:
|
|
|
|
if border := getBorder(style, CellBorder); border != nil {
|
|
|
|
border.delete(tag)
|
|
|
|
}
|
|
|
|
|
|
|
|
case MarginTop, MarginRight, MarginBottom, MarginLeft,
|
|
|
|
"top-margin", "right-margin", "bottom-margin", "left-margin":
|
|
|
|
style.removeBoundsSide(Margin, tag)
|
|
|
|
|
|
|
|
case PaddingTop, PaddingRight, PaddingBottom, PaddingLeft,
|
|
|
|
"top-padding", "right-padding", "bottom-padding", "left-padding":
|
|
|
|
style.removeBoundsSide(Padding, tag)
|
|
|
|
|
|
|
|
case CellPaddingTop, CellPaddingRight, CellPaddingBottom, CellPaddingLeft:
|
|
|
|
style.removeBoundsSide(CellPadding, tag)
|
|
|
|
|
|
|
|
case RadiusX, RadiusY, RadiusTopLeft, RadiusTopLeftX, RadiusTopLeftY,
|
|
|
|
RadiusTopRight, RadiusTopRightX, RadiusTopRightY,
|
|
|
|
RadiusBottomLeft, RadiusBottomLeftX, RadiusBottomLeftY,
|
|
|
|
RadiusBottomRight, RadiusBottomRightX, RadiusBottomRightY:
|
|
|
|
style.removeRadiusElement(tag)
|
|
|
|
|
|
|
|
case OutlineStyle, OutlineWidth, OutlineColor:
|
|
|
|
if outline := getOutline(style); outline != nil {
|
|
|
|
outline.Remove(tag)
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
style.propertyList.remove(tag)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-26 18:36:00 +03:00
|
|
|
func (style *viewStyle) Set(tag string, value any) bool {
|
2021-09-07 17:36:50 +03:00
|
|
|
return style.set(strings.ToLower(tag), value)
|
|
|
|
}
|
|
|
|
|
2022-07-26 18:36:00 +03:00
|
|
|
func (style *viewStyle) set(tag string, value any) bool {
|
2021-09-07 17:36:50 +03:00
|
|
|
if value == nil {
|
|
|
|
style.remove(tag)
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
switch tag {
|
|
|
|
case Shadow, TextShadow:
|
|
|
|
return style.setShadow(tag, value)
|
|
|
|
|
|
|
|
case Background:
|
|
|
|
return style.setBackground(value)
|
|
|
|
|
|
|
|
case Border, CellBorder:
|
|
|
|
if border := newBorderProperty(value); border != nil {
|
|
|
|
style.properties[tag] = border
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
case BorderStyle, BorderColor, BorderWidth,
|
|
|
|
BorderLeft, BorderLeftStyle, BorderLeftColor, BorderLeftWidth,
|
|
|
|
BorderRight, BorderRightStyle, BorderRightColor, BorderRightWidth,
|
|
|
|
BorderTop, BorderTopStyle, BorderTopColor, BorderTopWidth,
|
|
|
|
BorderBottom, BorderBottomStyle, BorderBottomColor, BorderBottomWidth:
|
|
|
|
|
|
|
|
border := getBorder(style, Border)
|
|
|
|
if border == nil {
|
|
|
|
border = NewBorder(nil)
|
|
|
|
if border.Set(tag, value) {
|
|
|
|
style.properties[Border] = border
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return border.Set(tag, value)
|
|
|
|
|
|
|
|
case CellBorderStyle, CellBorderColor, CellBorderWidth,
|
|
|
|
CellBorderLeft, CellBorderLeftStyle, CellBorderLeftColor, CellBorderLeftWidth,
|
|
|
|
CellBorderRight, CellBorderRightStyle, CellBorderRightColor, CellBorderRightWidth,
|
|
|
|
CellBorderTop, CellBorderTopStyle, CellBorderTopColor, CellBorderTopWidth,
|
|
|
|
CellBorderBottom, CellBorderBottomStyle, CellBorderBottomColor, CellBorderBottomWidth:
|
|
|
|
|
|
|
|
border := getBorder(style, CellBorder)
|
|
|
|
if border == nil {
|
|
|
|
border = NewBorder(nil)
|
|
|
|
if border.Set(tag, value) {
|
|
|
|
style.properties[CellBorder] = border
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return border.Set(tag, value)
|
|
|
|
|
|
|
|
case Radius:
|
|
|
|
return style.setRadius(value)
|
|
|
|
|
|
|
|
case RadiusX, RadiusY, RadiusTopLeft, RadiusTopLeftX, RadiusTopLeftY,
|
|
|
|
RadiusTopRight, RadiusTopRightX, RadiusTopRightY,
|
|
|
|
RadiusBottomLeft, RadiusBottomLeftX, RadiusBottomLeftY,
|
|
|
|
RadiusBottomRight, RadiusBottomRightX, RadiusBottomRightY:
|
|
|
|
return style.setRadiusElement(tag, value)
|
|
|
|
|
|
|
|
case Margin, Padding, CellPadding:
|
|
|
|
return style.setBounds(tag, value)
|
|
|
|
|
|
|
|
case MarginTop, MarginRight, MarginBottom, MarginLeft,
|
|
|
|
"top-margin", "right-margin", "bottom-margin", "left-margin":
|
|
|
|
return style.setBoundsSide(Margin, tag, value)
|
|
|
|
|
|
|
|
case PaddingTop, PaddingRight, PaddingBottom, PaddingLeft,
|
|
|
|
"top-padding", "right-padding", "bottom-padding", "left-padding":
|
|
|
|
return style.setBoundsSide(Padding, tag, value)
|
|
|
|
|
|
|
|
case CellPaddingTop, CellPaddingRight, CellPaddingBottom, CellPaddingLeft:
|
|
|
|
return style.setBoundsSide(CellPadding, tag, value)
|
|
|
|
|
2023-05-04 16:45:03 +03:00
|
|
|
case HeadStyle, FootStyle:
|
|
|
|
switch value := value.(type) {
|
|
|
|
case string:
|
|
|
|
style.properties[tag] = value
|
|
|
|
return true
|
|
|
|
|
|
|
|
case Params:
|
|
|
|
style.properties[tag] = value
|
|
|
|
return true
|
|
|
|
|
|
|
|
case DataObject:
|
|
|
|
if params := value.ToParams(); len(params) > 0 {
|
|
|
|
style.properties[tag] = params
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
case CellStyle, ColumnStyle, RowStyle:
|
|
|
|
switch value := value.(type) {
|
|
|
|
case string:
|
|
|
|
style.properties[tag] = value
|
|
|
|
return true
|
|
|
|
|
|
|
|
case Params:
|
|
|
|
style.properties[tag] = value
|
|
|
|
return true
|
|
|
|
|
|
|
|
case DataObject:
|
|
|
|
if params := value.ToParams(); len(params) > 0 {
|
|
|
|
style.properties[tag] = params
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
|
|
|
|
case DataNode:
|
|
|
|
switch value.Type() {
|
|
|
|
case TextNode:
|
|
|
|
if text := value.Text(); text != "" {
|
|
|
|
style.properties[tag] = text
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
|
|
|
|
case ObjectNode:
|
|
|
|
if obj := value.Object(); obj != nil {
|
|
|
|
if params := obj.ToParams(); len(params) > 0 {
|
|
|
|
style.properties[tag] = params
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
case ArrayNode:
|
|
|
|
// TODO
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-07 17:36:50 +03:00
|
|
|
case Outline:
|
|
|
|
return style.setOutline(value)
|
|
|
|
|
|
|
|
case OutlineStyle, OutlineWidth, OutlineColor:
|
|
|
|
if outline := getOutline(style); outline != nil {
|
|
|
|
return outline.Set(tag, value)
|
|
|
|
}
|
|
|
|
style.properties[Outline] = NewOutlineProperty(Params{tag: value})
|
|
|
|
return true
|
|
|
|
|
2024-08-13 13:52:47 +03:00
|
|
|
case TransformTag:
|
|
|
|
return style.setTransform(value)
|
|
|
|
|
|
|
|
case RotateX, RotateY, RotateZ, Rotate, SkewX, SkewY, ScaleX, ScaleY, ScaleZ,
|
|
|
|
TranslateX, TranslateY, TranslateZ:
|
|
|
|
return style.setTransformProperty(tag, value)
|
|
|
|
|
2021-09-07 17:36:50 +03:00
|
|
|
case Orientation:
|
|
|
|
if text, ok := value.(string); ok {
|
|
|
|
switch strings.ToLower(text) {
|
|
|
|
case "vertical":
|
|
|
|
style.properties[Orientation] = TopDownOrientation
|
|
|
|
return true
|
|
|
|
|
|
|
|
case "horizontal":
|
|
|
|
style.properties[Orientation] = StartToEndOrientation
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
case TextWeight:
|
|
|
|
if n, ok := value.(int); ok && n >= 100 && n%100 == 0 {
|
|
|
|
n /= 100
|
|
|
|
if n > 0 && n <= 9 {
|
2024-06-29 12:05:27 +03:00
|
|
|
style.properties[TextWeight] = n
|
2021-09-07 17:36:50 +03:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
case Row, Column:
|
|
|
|
return style.setRange(tag, value)
|
|
|
|
|
|
|
|
case CellWidth, CellHeight:
|
|
|
|
return style.setGridCellSize(tag, value)
|
|
|
|
|
|
|
|
case ColumnSeparator:
|
|
|
|
if separator := newColumnSeparatorProperty(value); separator != nil {
|
|
|
|
style.properties[ColumnSeparator] = separator
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
|
|
|
|
case ColumnSeparatorStyle, ColumnSeparatorWidth, ColumnSeparatorColor:
|
|
|
|
var separator ColumnSeparatorProperty = nil
|
|
|
|
if val, ok := style.properties[ColumnSeparator]; ok {
|
|
|
|
separator = val.(ColumnSeparatorProperty)
|
|
|
|
}
|
|
|
|
if separator == nil {
|
|
|
|
separator = newColumnSeparatorProperty(nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
if separator.Set(tag, value) {
|
|
|
|
style.properties[ColumnSeparator] = separator
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
|
|
|
|
case Clip, ShapeOutside:
|
|
|
|
return style.setClipShape(tag, value)
|
|
|
|
|
Added some properties and functions
* Added "resize", "grid-auto-flow", "caret-color", and "backdrop-filter" properties
* Added BlurView, BlurViewByID, GetResize, GetGridAutoFlow, GetCaretColor, GetBackdropFilter functions
* The "warp" property for ListView and ListLayout renamed to "list-warp"
* The "warp" property for EditView renamed to "edit-warp"
* Added CertFile and KeyFile optional fields to the AppParams struct.If they are set, then an https connection is created, otherwise http.
2022-06-07 13:07:10 +03:00
|
|
|
case Filter, BackdropFilter:
|
|
|
|
return style.setFilter(tag, value)
|
2021-10-04 17:58:17 +03:00
|
|
|
|
|
|
|
case Transition:
|
2024-06-29 12:05:27 +03:00
|
|
|
return style.setTransition(tag, value)
|
2021-10-04 17:58:17 +03:00
|
|
|
|
|
|
|
case AnimationTag:
|
2024-06-29 12:05:27 +03:00
|
|
|
return style.setAnimation(tag, value)
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return style.propertyList.set(tag, value)
|
|
|
|
}
|