rui_orig/border.go

909 lines
25 KiB
Go
Raw Normal View History

2021-09-07 17:36:50 +03:00
package rui
import (
"fmt"
"strings"
)
// Constants related to view's border description
2021-09-07 17:36:50 +03:00
const (
// NoneLine constant specifies that there is no border
NoneLine = 0
2021-09-07 17:36:50 +03:00
// SolidLine constant specifies the border/line as a solid line
SolidLine = 1
2021-09-07 17:36:50 +03:00
// DashedLine constant specifies the border/line as a dashed line
DashedLine = 2
2021-09-07 17:36:50 +03:00
// DottedLine constant specifies the border/line as a dotted line
DottedLine = 3
2021-09-07 17:36:50 +03:00
// DoubleLine constant specifies the border/line as a double solid line
DoubleLine = 4
2021-09-07 17:36:50 +03:00
// DoubleLine constant specifies the border/line as a double solid line
WavyLine = 5
2021-11-04 21:13:34 +03:00
// LeftStyle is the constant for "left-style" property tag.
//
// Used by `BorderProperty`.
// Left border line style.
//
// Supported types: `int`, `string`.
//
// Values:
// `0`(`NoneLine`) or "none" - The border will not be drawn.
// `1`(`SolidLine`) or "solid" - Solid line as a border.
// `2`(`DashedLine`) or "dashed" - Dashed line as a border.
// `3`(`DottedLine`) or "dotted" - Dotted line as a border.
// `4`(`DoubleLine`) or "double" - Double line as a border.
2024-11-13 12:56:39 +03:00
LeftStyle PropertyName = "left-style"
// RightStyle is the constant for "right-style" property tag.
//
// Used by `BorderProperty`.
// Right border line style.
//
// Supported types: `int`, `string`.
//
// Values:
// `0`(`NoneLine`) or "none" - The border will not be drawn.
// `1`(`SolidLine`) or "solid" - Solid line as a border.
// `2`(`DashedLine`) or "dashed" - Dashed line as a border.
// `3`(`DottedLine`) or "dotted" - Dotted line as a border.
// `4`(`DoubleLine`) or "double" - Double line as a border.
2024-11-13 12:56:39 +03:00
RightStyle PropertyName = "right-style"
2021-11-04 21:13:34 +03:00
// TopStyle is the constant for "top-style" property tag.
//
// Used by `BorderProperty`.
// Top border line style.
//
// Supported types: `int`, `string`.
//
// Values:
// `0`(`NoneLine`) or "none" - The border will not be drawn.
// `1`(`SolidLine`) or "solid" - Solid line as a border.
// `2`(`DashedLine`) or "dashed" - Dashed line as a border.
// `3`(`DottedLine`) or "dotted" - Dotted line as a border.
// `4`(`DoubleLine`) or "double" - Double line as a border.
2024-11-13 12:56:39 +03:00
TopStyle PropertyName = "top-style"
2021-11-04 21:13:34 +03:00
// BottomStyle is the constant for "bottom-style" property tag.
//
// Used by `BorderProperty`.
// Bottom border line style.
//
// Supported types: `int`, `string`.
//
// Values:
// `0`(`NoneLine`) or "none" - The border will not be drawn.
// `1`(`SolidLine`) or "solid" - Solid line as a border.
// `2`(`DashedLine`) or "dashed" - Dashed line as a border.
// `3`(`DottedLine`) or "dotted" - Dotted line as a border.
// `4`(`DoubleLine`) or "double" - Double line as a border.
2024-11-13 12:56:39 +03:00
BottomStyle PropertyName = "bottom-style"
2021-11-04 21:13:34 +03:00
// LeftWidth is the constant for "left-width" property tag.
//
// Used by `BorderProperty`.
// Left border line width.
//
// Supported types: `SizeUnit`, `SizeFunc`, `string`, `float`, `int`.
//
// Internal type is `SizeUnit`, other types converted to it during assignment.
// See `SizeUnit` description for more details.
2024-11-13 12:56:39 +03:00
LeftWidth PropertyName = "left-width"
// RightWidth is the constant for "right-width" property tag.
//
// Used by `BorderProperty`.
// Right border line width.
//
// Supported types: `SizeUnit`, `SizeFunc`, `string`, `float`, `int`.
//
// Internal type is `SizeUnit`, other types converted to it during assignment.
// See `SizeUnit` description for more details.
2024-11-13 12:56:39 +03:00
RightWidth PropertyName = "right-width"
2021-11-04 21:13:34 +03:00
// TopWidth is the constant for "top-width" property tag.
//
// Used by `BorderProperty`.
// Top border line width.
//
// Supported types: `SizeUnit`, `SizeFunc`, `string`, `float`, `int`.
//
// Internal type is `SizeUnit`, other types converted to it during assignment.
// See `SizeUnit` description for more details.
2024-11-13 12:56:39 +03:00
TopWidth PropertyName = "top-width"
2021-11-04 21:13:34 +03:00
// BottomWidth is the constant for "bottom-width" property tag.
//
// Used by `BorderProperty`.
// Bottom border line width.
//
// Supported types: `SizeUnit`, `SizeFunc`, `string`, `float`, `int`.
//
// Internal type is `SizeUnit`, other types converted to it during assignment.
// See `SizeUnit` description for more details.
2024-11-13 12:56:39 +03:00
BottomWidth PropertyName = "bottom-width"
2021-11-04 21:13:34 +03:00
// LeftColor is the constant for "left-color" property tag.
//
// Used by `BorderProperty`.
// Left border line color.
//
// Supported types: `Color`, `string`.
//
// Internal type is `Color`, other types converted to it during assignment.
// See `Color` description for more details.
2024-11-13 12:56:39 +03:00
LeftColor PropertyName = "left-color"
// RightColor is the constant for "right-color" property tag.
//
// Used by `BorderProperty`.
// Right border line color.
//
// Supported types: `Color`, `string`.
//
// Internal type is `Color`, other types converted to it during assignment.
// See `Color` description for more details.
2024-11-13 12:56:39 +03:00
RightColor PropertyName = "right-color"
2021-11-04 21:13:34 +03:00
// TopColor is the constant for "top-color" property tag.
//
// Used by `BorderProperty`.
// Top border line color.
//
// Supported types: `Color`, `string`.
//
// Internal type is `Color`, other types converted to it during assignment.
// See `Color` description for more details.
2024-11-13 12:56:39 +03:00
TopColor PropertyName = "top-color"
2021-11-04 21:13:34 +03:00
// BottomColor is the constant for "bottom-color" property tag.
//
// Used by `BorderProperty`.
// Bottom border line color.
//
// Supported types: `Color`, `string`.
//
// Internal type is `Color`, other types converted to it during assignment.
// See `Color` description for more details.
2024-11-13 12:56:39 +03:00
BottomColor PropertyName = "bottom-color"
2021-09-07 17:36:50 +03:00
)
// BorderProperty is the interface of a view border data
type BorderProperty interface {
Properties
fmt.Stringer
2022-05-22 12:54:02 +03:00
stringWriter
// ViewBorders returns top, right, bottom and left borders information all together
2021-09-07 17:36:50 +03:00
ViewBorders(session Session) ViewBorders
2024-11-13 12:56:39 +03:00
deleteTag(tag PropertyName) bool
2021-09-07 17:36:50 +03:00
cssStyle(builder cssBuilder, session Session)
cssWidth(builder cssBuilder, session Session)
cssColor(builder cssBuilder, session Session)
cssStyleValue(session Session) string
cssWidthValue(session Session) string
cssColorValue(session Session) string
}
type borderProperty struct {
2024-11-13 12:56:39 +03:00
dataProperty
2021-09-07 17:36:50 +03:00
}
2022-07-26 18:36:00 +03:00
func newBorderProperty(value any) BorderProperty {
2021-09-07 17:36:50 +03:00
border := new(borderProperty)
2024-11-13 12:56:39 +03:00
border.init()
2021-09-07 17:36:50 +03:00
if value != nil {
switch value := value.(type) {
case BorderProperty:
return value
2022-05-23 15:22:14 +03:00
case DataNode:
if value.Type() == ObjectNode {
_ = border.setBorderObject(value.Object())
} else {
return nil
}
2021-09-07 17:36:50 +03:00
case DataObject:
_ = border.setBorderObject(value)
case ViewBorder:
border.properties[Style] = value.Style
border.properties[Width] = value.Width
border.properties[ColorTag] = value.Color
2021-09-07 17:36:50 +03:00
case ViewBorders:
if value.Left.Style == value.Right.Style &&
value.Left.Style == value.Top.Style &&
value.Left.Style == value.Bottom.Style {
border.properties[Style] = value.Left.Style
} else {
border.properties[LeftStyle] = value.Left.Style
border.properties[RightStyle] = value.Right.Style
border.properties[TopStyle] = value.Top.Style
border.properties[BottomStyle] = value.Bottom.Style
}
if value.Left.Width.Equal(value.Right.Width) &&
value.Left.Width.Equal(value.Top.Width) &&
value.Left.Width.Equal(value.Bottom.Width) {
border.properties[Width] = value.Left.Width
} else {
border.properties[LeftWidth] = value.Left.Width
border.properties[RightWidth] = value.Right.Width
border.properties[TopWidth] = value.Top.Width
border.properties[BottomWidth] = value.Bottom.Width
}
if value.Left.Color == value.Right.Color &&
value.Left.Color == value.Top.Color &&
value.Left.Color == value.Bottom.Color {
border.properties[ColorTag] = value.Left.Color
2021-09-07 17:36:50 +03:00
} else {
border.properties[LeftColor] = value.Left.Color
border.properties[RightColor] = value.Right.Color
border.properties[TopColor] = value.Top.Color
border.properties[BottomColor] = value.Bottom.Color
}
default:
invalidPropertyValue(Border, value)
return nil
}
}
return border
}
2024-10-21 18:37:35 +03:00
// NewBorder creates the new BorderProperty.
// The following properties can be used:
//
// "style" (Style). Determines the line style (int). Valid values: 0 (NoneLine), 1 (SolidLine), 2 (DashedLine), 3 (DottedLine), or 4 (DoubleLine);
//
// "color" (ColorTag). Determines the line color (Color);
//
// "width" (Width). Determines the line thickness (SizeUnit).
2021-09-07 17:36:50 +03:00
func NewBorder(params Params) BorderProperty {
border := new(borderProperty)
2024-11-13 12:56:39 +03:00
border.init()
2021-09-07 17:36:50 +03:00
if params != nil {
2024-11-13 12:56:39 +03:00
for _, tag := range []PropertyName{Style, Width, ColorTag, Left, Right, Top, Bottom,
2021-09-07 17:36:50 +03:00
LeftStyle, RightStyle, TopStyle, BottomStyle,
LeftWidth, RightWidth, TopWidth, BottomWidth,
LeftColor, RightColor, TopColor, BottomColor} {
if value, ok := params[tag]; ok && value != nil {
border.Set(tag, value)
}
}
}
return border
}
2024-11-13 12:56:39 +03:00
func (border *borderProperty) init() {
border.dataProperty.init()
border.normalize = normalizeBorderTag
border.get = borderGet
border.set = borderSet
border.remove = borderRemove
border.supportedProperties = []PropertyName{
Left,
Right,
Top,
Bottom,
Style,
LeftStyle,
RightStyle,
TopStyle,
BottomStyle,
Width,
LeftWidth,
RightWidth,
TopWidth,
BottomWidth,
ColorTag,
LeftColor,
RightColor,
TopColor,
BottomColor,
}
}
func normalizeBorderTag(tag PropertyName) PropertyName {
tag = defaultNormalize(tag)
2021-09-07 17:36:50 +03:00
switch tag {
case BorderLeft, CellBorderLeft:
return Left
case BorderRight, CellBorderRight:
return Right
case BorderTop, CellBorderTop:
return Top
case BorderBottom, CellBorderBottom:
return Bottom
case BorderStyle, CellBorderStyle:
return Style
case BorderLeftStyle, CellBorderLeftStyle, "style-left":
return LeftStyle
case BorderRightStyle, CellBorderRightStyle, "style-right":
return RightStyle
case BorderTopStyle, CellBorderTopStyle, "style-top":
return TopStyle
case BorderBottomStyle, CellBorderBottomStyle, "style-bottom":
return BottomStyle
case BorderWidth, CellBorderWidth:
return Width
case BorderLeftWidth, CellBorderLeftWidth, "width-left":
return LeftWidth
case BorderRightWidth, CellBorderRightWidth, "width-right":
return RightWidth
case BorderTopWidth, CellBorderTopWidth, "width-top":
return TopWidth
case BorderBottomWidth, CellBorderBottomWidth, "width-bottom":
return BottomWidth
case BorderColor, CellBorderColor:
return ColorTag
2021-09-07 17:36:50 +03:00
case BorderLeftColor, CellBorderLeftColor, "color-left":
return LeftColor
case BorderRightColor, CellBorderRightColor, "color-right":
return RightColor
case BorderTopColor, CellBorderTopColor, "color-top":
return TopColor
case BorderBottomColor, CellBorderBottomColor, "color-bottom":
return BottomColor
}
return tag
}
2022-05-22 12:54:02 +03:00
func (border *borderProperty) writeString(buffer *strings.Builder, indent string) {
buffer.WriteString("_{ ")
comma := false
2024-11-13 12:56:39 +03:00
write := func(tag PropertyName, value any) {
2022-05-22 12:54:02 +03:00
if comma {
buffer.WriteString(", ")
}
2024-11-13 12:56:39 +03:00
buffer.WriteString(string(tag))
2022-05-22 12:54:02 +03:00
buffer.WriteString(" = ")
writePropertyValue(buffer, BorderStyle, value, indent)
comma = true
}
2021-09-07 17:36:50 +03:00
2024-11-13 12:56:39 +03:00
for _, tag := range []PropertyName{Style, Width, ColorTag} {
2021-09-07 17:36:50 +03:00
if value, ok := border.properties[tag]; ok {
2022-05-22 12:54:02 +03:00
write(tag, value)
2021-09-07 17:36:50 +03:00
}
}
2024-11-13 12:56:39 +03:00
for _, side := range []PropertyName{Top, Right, Bottom, Left} {
2021-09-07 17:36:50 +03:00
style, okStyle := border.properties[side+"-"+Style]
width, okWidth := border.properties[side+"-"+Width]
color, okColor := border.properties[side+"-"+ColorTag]
2021-09-07 17:36:50 +03:00
if okStyle || okWidth || okColor {
2022-05-22 12:54:02 +03:00
if comma {
buffer.WriteString(", ")
comma = false
}
2024-11-13 12:56:39 +03:00
buffer.WriteString(string(side))
2022-05-22 12:54:02 +03:00
buffer.WriteString(" = _{ ")
2021-09-07 17:36:50 +03:00
if okStyle {
2022-05-22 12:54:02 +03:00
write(Style, style)
2021-09-07 17:36:50 +03:00
}
if okWidth {
2022-05-22 12:54:02 +03:00
write(Width, width)
2021-09-07 17:36:50 +03:00
}
if okColor {
2022-05-22 12:54:02 +03:00
write(ColorTag, color)
2021-09-07 17:36:50 +03:00
}
2022-05-22 12:54:02 +03:00
buffer.WriteString(" }")
comma = true
2021-09-07 17:36:50 +03:00
}
}
2022-05-22 12:54:02 +03:00
buffer.WriteString(" }")
2021-09-07 17:36:50 +03:00
}
func (border *borderProperty) String() string {
2022-05-22 12:54:02 +03:00
return runStringWriter(border)
2021-09-07 17:36:50 +03:00
}
func (border *borderProperty) setBorderObject(obj DataObject) bool {
result := true
2024-11-13 12:56:39 +03:00
for i := 0; i < obj.PropertyCount(); i++ {
if node := obj.Property(i); node != nil {
tag := PropertyName(node.Tag())
switch node.Type() {
case TextNode:
if borderSet(border, tag, node.Text()) == nil {
2021-09-07 17:36:50 +03:00
result = false
}
2024-11-13 12:56:39 +03:00
case ObjectNode:
if borderSet(border, tag, node.Object()) == nil {
2021-09-07 17:36:50 +03:00
result = false
}
2024-11-13 12:56:39 +03:00
default:
2021-09-07 17:36:50 +03:00
result = false
}
2024-11-13 12:56:39 +03:00
} else {
2021-09-07 17:36:50 +03:00
result = false
}
}
return result
}
2024-11-13 12:56:39 +03:00
func borderRemove(properties Properties, tag PropertyName) []PropertyName {
result := []PropertyName{}
removeTag := func(t PropertyName) {
if properties.getRaw(t) != nil {
properties.setRaw(t, nil)
result = append(result, t)
}
}
2021-09-07 17:36:50 +03:00
switch tag {
case Style:
2024-11-13 12:56:39 +03:00
for _, t := range []PropertyName{tag, TopStyle, RightStyle, BottomStyle, LeftStyle} {
removeTag(t)
2021-09-07 17:36:50 +03:00
}
case Width:
2024-11-13 12:56:39 +03:00
for _, t := range []PropertyName{tag, TopWidth, RightWidth, BottomWidth, LeftWidth} {
removeTag(t)
2021-09-07 17:36:50 +03:00
}
case ColorTag:
2024-11-13 12:56:39 +03:00
for _, t := range []PropertyName{tag, TopColor, RightColor, BottomColor, LeftColor} {
removeTag(t)
2021-09-07 17:36:50 +03:00
}
case Left, Right, Top, Bottom:
2024-11-13 12:56:39 +03:00
removeTag(tag + "-style")
removeTag(tag + "-width")
removeTag(tag + "-color")
2021-09-07 17:36:50 +03:00
case LeftStyle, RightStyle, TopStyle, BottomStyle:
2024-11-13 12:56:39 +03:00
removeTag(tag)
if style := properties.getRaw(Style); style != nil {
for _, t := range []PropertyName{TopStyle, RightStyle, BottomStyle, LeftStyle} {
2021-09-07 17:36:50 +03:00
if t != tag {
2024-11-13 12:56:39 +03:00
if properties.getRaw(t) == nil {
properties.setRaw(t, style)
result = append(result, t)
2021-09-07 17:36:50 +03:00
}
}
}
}
case LeftWidth, RightWidth, TopWidth, BottomWidth:
2024-11-13 12:56:39 +03:00
removeTag(tag)
if width := properties.getRaw(Width); width != nil {
for _, t := range []PropertyName{TopWidth, RightWidth, BottomWidth, LeftWidth} {
2021-09-07 17:36:50 +03:00
if t != tag {
2024-11-13 12:56:39 +03:00
if properties.getRaw(t) == nil {
properties.setRaw(t, width)
result = append(result, t)
2021-09-07 17:36:50 +03:00
}
}
}
}
case LeftColor, RightColor, TopColor, BottomColor:
2024-11-13 12:56:39 +03:00
removeTag(tag)
if color := properties.getRaw(ColorTag); color != nil {
for _, t := range []PropertyName{TopColor, RightColor, BottomColor, LeftColor} {
2021-09-07 17:36:50 +03:00
if t != tag {
2024-11-13 12:56:39 +03:00
if properties.getRaw(t) == nil {
properties.setRaw(t, color)
result = append(result, t)
2021-09-07 17:36:50 +03:00
}
}
}
}
default:
ErrorLogF(`"%s" property is not compatible with the BorderProperty`, tag)
}
2024-11-13 12:56:39 +03:00
return result
2021-09-07 17:36:50 +03:00
}
2024-11-13 12:56:39 +03:00
func borderSet(properties Properties, tag PropertyName, value any) []PropertyName {
2021-09-07 17:36:50 +03:00
2024-11-13 12:56:39 +03:00
setSingleBorderObject := func(prefix PropertyName, obj DataObject) []PropertyName {
result := []PropertyName{}
if text, ok := obj.PropertyValue(string(Style)); ok {
props := setEnumProperty(properties, prefix+"-style", text, enumProperties[BorderStyle].values)
if props == nil {
return nil
}
result = append(result, props...)
}
if text, ok := obj.PropertyValue(string(ColorTag)); ok {
props := setColorProperty(properties, prefix+"-color", text)
if props == nil && len(result) == 0 {
return nil
}
result = append(result, props...)
}
if text, ok := obj.PropertyValue("width"); ok {
props := setSizeProperty(properties, prefix+"-width", text)
if props == nil && len(result) == 0 {
return nil
}
result = append(result, props...)
}
if len(result) > 0 {
result = append(result, prefix)
}
return result
}
2021-09-07 17:36:50 +03:00
switch tag {
case Style:
2024-11-13 12:56:39 +03:00
if result := setEnumProperty(properties, Style, value, enumProperties[BorderStyle].values); result != nil {
for _, side := range []PropertyName{TopStyle, RightStyle, BottomStyle, LeftStyle} {
if value := properties.getRaw(side); value != nil {
properties.setRaw(side, nil)
result = append(result, side)
}
2021-09-07 17:36:50 +03:00
}
2024-11-13 12:56:39 +03:00
return result
2021-09-07 17:36:50 +03:00
}
case Width:
2024-11-13 12:56:39 +03:00
if result := setSizeProperty(properties, Width, value); result != nil {
for _, side := range []PropertyName{TopWidth, RightWidth, BottomWidth, LeftWidth} {
if value := properties.getRaw(side); value != nil {
properties.setRaw(side, nil)
result = append(result, side)
}
2021-09-07 17:36:50 +03:00
}
2024-11-13 12:56:39 +03:00
return result
2021-09-07 17:36:50 +03:00
}
case ColorTag:
2024-11-13 12:56:39 +03:00
if result := setColorProperty(properties, ColorTag, value); result != nil {
for _, side := range []PropertyName{TopColor, RightColor, BottomColor, LeftColor} {
if value := properties.getRaw(side); value != nil {
properties.setRaw(side, nil)
result = append(result, side)
}
2021-09-07 17:36:50 +03:00
}
2024-11-13 12:56:39 +03:00
return result
2021-09-07 17:36:50 +03:00
}
case LeftStyle, RightStyle, TopStyle, BottomStyle:
2024-11-13 12:56:39 +03:00
return setEnumProperty(properties, tag, value, enumProperties[BorderStyle].values)
2021-09-07 17:36:50 +03:00
case LeftWidth, RightWidth, TopWidth, BottomWidth:
2024-11-13 12:56:39 +03:00
return setSizeProperty(properties, tag, value)
2021-09-07 17:36:50 +03:00
case LeftColor, RightColor, TopColor, BottomColor:
2024-11-13 12:56:39 +03:00
return setColorProperty(properties, tag, value)
2021-09-07 17:36:50 +03:00
case Left, Right, Top, Bottom:
switch value := value.(type) {
case string:
if obj := ParseDataText(value); obj != nil {
2024-11-13 12:56:39 +03:00
return setSingleBorderObject(tag, obj)
2021-09-07 17:36:50 +03:00
}
case DataObject:
2024-11-13 12:56:39 +03:00
return setSingleBorderObject(tag, value)
2021-09-07 17:36:50 +03:00
case BorderProperty:
2024-11-13 12:56:39 +03:00
result := []PropertyName{}
2021-09-07 17:36:50 +03:00
styleTag := tag + "-" + Style
if style := value.Get(styleTag); value != nil {
2024-11-13 12:56:39 +03:00
properties.setRaw(styleTag, style)
result = append(result, styleTag)
2021-09-07 17:36:50 +03:00
}
colorTag := tag + "-" + ColorTag
2021-09-07 17:36:50 +03:00
if color := value.Get(colorTag); value != nil {
2024-11-13 12:56:39 +03:00
properties.setRaw(colorTag, color)
result = append(result, colorTag)
2021-09-07 17:36:50 +03:00
}
widthTag := tag + "-" + Width
if width := value.Get(widthTag); value != nil {
2024-11-13 12:56:39 +03:00
properties.setRaw(widthTag, width)
result = append(result, widthTag)
2021-09-07 17:36:50 +03:00
}
2024-11-13 12:56:39 +03:00
return result
2021-09-07 17:36:50 +03:00
case ViewBorder:
2024-11-13 12:56:39 +03:00
properties.setRaw(tag+"-"+Style, value.Style)
properties.setRaw(tag+"-"+Width, value.Width)
properties.setRaw(tag+"-"+ColorTag, value.Color)
return []PropertyName{tag + "-" + Style, tag + "-" + Width, tag + "-" + ColorTag}
2021-09-07 17:36:50 +03:00
}
fallthrough
default:
ErrorLogF(`"%s" property is not compatible with the BorderProperty`, tag)
}
2024-11-13 12:56:39 +03:00
return nil
2021-09-07 17:36:50 +03:00
}
2024-11-13 12:56:39 +03:00
func borderGet(properties Properties, tag PropertyName) any {
if result := properties.getRaw(tag); result != nil {
2021-09-07 17:36:50 +03:00
return result
}
switch tag {
case Left, Right, Top, Bottom:
result := newBorderProperty(nil)
2024-11-13 12:56:39 +03:00
if style := properties.getRaw(tag + "-" + Style); style != nil {
2021-09-07 17:36:50 +03:00
result.Set(Style, style)
2024-11-13 12:56:39 +03:00
} else if style := properties.getRaw(Style); style != nil {
2021-09-07 17:36:50 +03:00
result.Set(Style, style)
}
2024-11-13 12:56:39 +03:00
if width := properties.getRaw(tag + "-" + Width); width != nil {
2021-09-07 17:36:50 +03:00
result.Set(Width, width)
2024-11-13 12:56:39 +03:00
} else if width := properties.getRaw(Width); width != nil {
2021-09-07 17:36:50 +03:00
result.Set(Width, width)
}
2024-11-13 12:56:39 +03:00
if color := properties.getRaw(tag + "-" + ColorTag); color != nil {
result.Set(ColorTag, color)
2024-11-13 12:56:39 +03:00
} else if color := properties.getRaw(ColorTag); color != nil {
result.Set(ColorTag, color)
2021-09-07 17:36:50 +03:00
}
return result
case LeftStyle, RightStyle, TopStyle, BottomStyle:
2024-11-13 12:56:39 +03:00
if style := properties.getRaw(tag); style != nil {
2021-09-07 17:36:50 +03:00
return style
}
2024-11-13 12:56:39 +03:00
return properties.getRaw(Style)
2021-09-07 17:36:50 +03:00
case LeftWidth, RightWidth, TopWidth, BottomWidth:
2024-11-13 12:56:39 +03:00
if width := properties.getRaw(tag); width != nil {
2021-09-07 17:36:50 +03:00
return width
}
2024-11-13 12:56:39 +03:00
return properties.getRaw(Width)
2021-09-07 17:36:50 +03:00
case LeftColor, RightColor, TopColor, BottomColor:
2024-11-13 12:56:39 +03:00
if color := properties.getRaw(tag); color != nil {
2021-09-07 17:36:50 +03:00
return color
}
2024-11-13 12:56:39 +03:00
return properties.getRaw(ColorTag)
2021-09-07 17:36:50 +03:00
}
return nil
}
2024-11-13 12:56:39 +03:00
func (border *borderProperty) deleteTag(tag PropertyName) bool {
result := false
removeTags := func(tags []PropertyName) {
for _, tag := range tags {
if border.getRaw(tag) != nil {
border.setRaw(tag, nil)
result = true
}
}
}
2021-09-07 17:36:50 +03:00
switch tag {
case Style:
2024-11-13 12:56:39 +03:00
removeTags([]PropertyName{Style, LeftStyle, RightStyle, TopStyle, BottomStyle})
2021-09-07 17:36:50 +03:00
case Width:
2024-11-13 12:56:39 +03:00
removeTags([]PropertyName{Width, LeftWidth, RightWidth, TopWidth, BottomWidth})
2021-09-07 17:36:50 +03:00
case ColorTag:
2024-11-13 12:56:39 +03:00
removeTags([]PropertyName{ColorTag, LeftColor, RightColor, TopColor, BottomColor})
2021-09-07 17:36:50 +03:00
case Left, Right, Top, Bottom:
if border.Get(Style) != nil {
border.properties[tag+"-"+Style] = 0
2024-11-13 12:56:39 +03:00
result = true
removeTags([]PropertyName{tag + "-" + ColorTag, tag + "-" + Width})
2021-09-07 17:36:50 +03:00
} else {
2024-11-13 12:56:39 +03:00
removeTags([]PropertyName{tag + "-" + Style, tag + "-" + ColorTag, tag + "-" + Width})
2021-09-07 17:36:50 +03:00
}
case LeftStyle, RightStyle, TopStyle, BottomStyle:
2024-11-13 12:56:39 +03:00
if border.getRaw(tag) != nil {
if border.Get(Style) != nil {
border.properties[tag] = 0
result = true
} else {
removeTags([]PropertyName{tag})
}
2021-09-07 17:36:50 +03:00
}
case LeftWidth, RightWidth, TopWidth, BottomWidth:
2024-11-13 12:56:39 +03:00
if border.getRaw(tag) != nil {
if border.Get(Width) != nil {
border.properties[tag] = AutoSize()
result = true
} else {
removeTags([]PropertyName{tag})
}
2021-09-07 17:36:50 +03:00
}
case LeftColor, RightColor, TopColor, BottomColor:
2024-11-13 12:56:39 +03:00
if border.getRaw(tag) != nil {
if border.Get(ColorTag) != nil {
border.properties[tag] = 0
result = true
} else {
removeTags([]PropertyName{tag})
}
2021-09-07 17:36:50 +03:00
}
}
2024-11-13 12:56:39 +03:00
return result
2021-09-07 17:36:50 +03:00
}
func (border *borderProperty) ViewBorders(session Session) ViewBorders {
defStyle, _ := valueToEnum(border.getRaw(Style), BorderStyle, session, NoneLine)
defWidth, _ := sizeProperty(border, Width, session)
defColor, _ := colorProperty(border, ColorTag, session)
2021-09-07 17:36:50 +03:00
2024-11-13 12:56:39 +03:00
getBorder := func(prefix PropertyName) ViewBorder {
2021-09-07 17:36:50 +03:00
var result ViewBorder
var ok bool
if result.Style, ok = valueToEnum(border.getRaw(prefix+Style), BorderStyle, session, NoneLine); !ok {
result.Style = defStyle
}
if result.Width, ok = sizeProperty(border, prefix+Width, session); !ok {
result.Width = defWidth
}
if result.Color, ok = colorProperty(border, prefix+ColorTag, session); !ok {
2021-09-07 17:36:50 +03:00
result.Color = defColor
}
return result
}
return ViewBorders{
Top: getBorder("top-"),
Left: getBorder("left-"),
Right: getBorder("right-"),
Bottom: getBorder("bottom-"),
}
}
func (border *borderProperty) cssStyle(builder cssBuilder, session Session) {
borders := border.ViewBorders(session)
values := enumProperties[BorderStyle].cssValues
if borders.Top.Style == borders.Right.Style &&
borders.Top.Style == borders.Left.Style &&
borders.Top.Style == borders.Bottom.Style {
2024-11-13 12:56:39 +03:00
builder.add(string(BorderStyle), values[borders.Top.Style])
2021-09-07 17:36:50 +03:00
} else {
2024-11-13 12:56:39 +03:00
builder.addValues(string(BorderStyle), " ", values[borders.Top.Style],
2021-09-07 17:36:50 +03:00
values[borders.Right.Style], values[borders.Bottom.Style], values[borders.Left.Style])
}
}
func (border *borderProperty) cssWidth(builder cssBuilder, session Session) {
borders := border.ViewBorders(session)
if borders.Top.Width == borders.Right.Width &&
borders.Top.Width == borders.Left.Width &&
borders.Top.Width == borders.Bottom.Width {
if borders.Top.Width.Type != Auto {
builder.add("border-width", borders.Top.Width.cssString("0", session))
2021-09-07 17:36:50 +03:00
}
} else {
builder.addValues("border-width", " ",
borders.Top.Width.cssString("0", session),
borders.Right.Width.cssString("0", session),
borders.Bottom.Width.cssString("0", session),
borders.Left.Width.cssString("0", session))
2021-09-07 17:36:50 +03:00
}
}
func (border *borderProperty) cssColor(builder cssBuilder, session Session) {
borders := border.ViewBorders(session)
if borders.Top.Color == borders.Right.Color &&
borders.Top.Color == borders.Left.Color &&
borders.Top.Color == borders.Bottom.Color {
if borders.Top.Color != 0 {
builder.add("border-color", borders.Top.Color.cssString())
}
} else {
builder.addValues("border-color", " ", borders.Top.Color.cssString(),
borders.Right.Color.cssString(), borders.Bottom.Color.cssString(), borders.Left.Color.cssString())
}
}
func (border *borderProperty) cssStyleValue(session Session) string {
var builder cssValueBuilder
border.cssStyle(&builder, session)
return builder.finish()
}
func (border *borderProperty) cssWidthValue(session Session) string {
var builder cssValueBuilder
border.cssWidth(&builder, session)
return builder.finish()
}
func (border *borderProperty) cssColorValue(session Session) string {
var builder cssValueBuilder
border.cssColor(&builder, session)
return builder.finish()
}
// ViewBorder describes parameters of a view border
type ViewBorder struct {
// Style of the border line
2021-09-07 17:36:50 +03:00
Style int
// Color of the border line
2021-09-07 17:36:50 +03:00
Color Color
// Width of the border line
2021-09-07 17:36:50 +03:00
Width SizeUnit
}
// ViewBorders describes the top, right, bottom, and left border of a view
type ViewBorders struct {
Top, Right, Bottom, Left ViewBorder
}
// AllTheSame returns true if all borders are the same
func (border *ViewBorders) AllTheSame() bool {
return border.Top.Style == border.Right.Style &&
border.Top.Style == border.Left.Style &&
border.Top.Style == border.Bottom.Style &&
border.Top.Color == border.Right.Color &&
border.Top.Color == border.Left.Color &&
border.Top.Color == border.Bottom.Color &&
border.Top.Width.Equal(border.Right.Width) &&
border.Top.Width.Equal(border.Left.Width) &&
border.Top.Width.Equal(border.Bottom.Width)
}
2024-11-13 12:56:39 +03:00
func getBorderProperty(properties Properties, tag PropertyName) BorderProperty {
if value := properties.getRaw(tag); value != nil {
2021-09-07 17:36:50 +03:00
if border, ok := value.(BorderProperty); ok {
return border
}
}
return nil
}
2024-11-13 12:56:39 +03:00
func setBorderPropertyElement(properties Properties, mainTag, tag PropertyName, value any) []PropertyName {
border := getBorderProperty(properties, mainTag)
if border == nil {
border = NewBorder(nil)
if border.Set(tag, value) {
properties.setRaw(mainTag, border)
return []PropertyName{mainTag, tag}
}
} else if border.Set(tag, value) {
return []PropertyName{mainTag, tag}
}
return nil
}