mirror of https://github.com/anoshenko/rui.git
				
				
				
			Bug fixing
This commit is contained in:
		
							parent
							
								
									fcea1c89a3
								
							
						
					
					
						commit
						9478b1ee4f
					
				
							
								
								
									
										80
									
								
								animation.go
								
								
								
								
							
							
						
						
									
										80
									
								
								animation.go
								
								
								
								
							| 
						 | 
					@ -124,7 +124,7 @@ type animationData struct {
 | 
				
			||||||
type Animation interface {
 | 
					type Animation interface {
 | 
				
			||||||
	Properties
 | 
						Properties
 | 
				
			||||||
	fmt.Stringer
 | 
						fmt.Stringer
 | 
				
			||||||
	ruiStringer
 | 
						writeTransitionString(tag string, buffer *strings.Builder)
 | 
				
			||||||
	animationCSS(session Session) string
 | 
						animationCSS(session Session) string
 | 
				
			||||||
	transitionCSS(buffer *strings.Builder, session Session)
 | 
						transitionCSS(buffer *strings.Builder, session Session)
 | 
				
			||||||
	hasAnimatedPropery() bool
 | 
						hasAnimatedPropery() bool
 | 
				
			||||||
| 
						 | 
					@ -176,13 +176,21 @@ func (animation *animationData) animationName() string {
 | 
				
			||||||
	return animation.keyFramesName
 | 
						return animation.keyFramesName
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (animation *animationData) normalizeTag(tag string) string {
 | 
				
			||||||
 | 
						tag = strings.ToLower(tag)
 | 
				
			||||||
 | 
						if tag == Direction {
 | 
				
			||||||
 | 
							return AnimationDirection
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return tag
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (animation *animationData) Set(tag string, value interface{}) bool {
 | 
					func (animation *animationData) Set(tag string, value interface{}) bool {
 | 
				
			||||||
	if value == nil {
 | 
						if value == nil {
 | 
				
			||||||
		animation.Remove(tag)
 | 
							animation.Remove(tag)
 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch tag = strings.ToLower(tag); tag {
 | 
						switch tag = animation.normalizeTag(tag); tag {
 | 
				
			||||||
	case ID:
 | 
						case ID:
 | 
				
			||||||
		if text, ok := value.(string); ok {
 | 
							if text, ok := value.(string); ok {
 | 
				
			||||||
			text = strings.Trim(text, " \t\n\r")
 | 
								text = strings.Trim(text, " \t\n\r")
 | 
				
			||||||
| 
						 | 
					@ -337,7 +345,7 @@ func (animation *animationData) Set(tag string, value interface{}) bool {
 | 
				
			||||||
	case IterationCount:
 | 
						case IterationCount:
 | 
				
			||||||
		return animation.setIntProperty(tag, value)
 | 
							return animation.setIntProperty(tag, value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case AnimationDirection, Direction:
 | 
						case AnimationDirection:
 | 
				
			||||||
		return animation.setEnumProperty(AnimationDirection, value, enumProperties[AnimationDirection].values)
 | 
							return animation.setEnumProperty(AnimationDirection, value, enumProperties[AnimationDirection].values)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
| 
						 | 
					@ -348,31 +356,23 @@ func (animation *animationData) Set(tag string, value interface{}) bool {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (animation *animationData) Remove(tag string) {
 | 
					func (animation *animationData) Remove(tag string) {
 | 
				
			||||||
	tag = strings.ToLower(tag)
 | 
						delete(animation.properties, animation.normalizeTag(tag))
 | 
				
			||||||
	if tag == Direction {
 | 
					 | 
				
			||||||
		tag = AnimationDirection
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	delete(animation.properties, tag)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (animation *animationData) Get(tag string) interface{} {
 | 
					func (animation *animationData) Get(tag string) interface{} {
 | 
				
			||||||
	tag = strings.ToLower(tag)
 | 
						return animation.getRaw(animation.normalizeTag(tag))
 | 
				
			||||||
	if tag == Direction {
 | 
					 | 
				
			||||||
		tag = AnimationDirection
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return animation.getRaw(tag)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (animation *animationData) String() string {
 | 
					func (animation *animationData) String() string {
 | 
				
			||||||
	writer := newRUIWriter()
 | 
						buffer := allocStringBuilder()
 | 
				
			||||||
	animation.ruiString(writer)
 | 
						defer freeStringBuilder(buffer)
 | 
				
			||||||
	return writer.finish()
 | 
					
 | 
				
			||||||
}
 | 
						buffer.WriteString("animation {")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (animation *animationData) ruiString(writer ruiWriter) {
 | 
					 | 
				
			||||||
	writer.startObject("animation")
 | 
					 | 
				
			||||||
	// TODO
 | 
						// TODO
 | 
				
			||||||
	writer.endObject()
 | 
					
 | 
				
			||||||
 | 
						buffer.WriteString("}")
 | 
				
			||||||
 | 
						return buffer.String()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (animation *animationData) animationCSS(session Session) string {
 | 
					func (animation *animationData) animationCSS(session Session) string {
 | 
				
			||||||
| 
						 | 
					@ -448,6 +448,46 @@ func (animation *animationData) transitionCSS(buffer *strings.Builder, session S
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (animation *animationData) writeTransitionString(tag string, buffer *strings.Builder) {
 | 
				
			||||||
 | 
						buffer.WriteString(tag)
 | 
				
			||||||
 | 
						buffer.WriteString("{")
 | 
				
			||||||
 | 
						lead := " "
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeFloatProperty := func(name string) bool {
 | 
				
			||||||
 | 
							if value := animation.getRaw(name); value != nil {
 | 
				
			||||||
 | 
								buffer.WriteString(lead)
 | 
				
			||||||
 | 
								buffer.WriteString(name)
 | 
				
			||||||
 | 
								buffer.WriteString(" = ")
 | 
				
			||||||
 | 
								writePropertyValue(buffer, name, value, "")
 | 
				
			||||||
 | 
								lead = ", "
 | 
				
			||||||
 | 
								return true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if !writeFloatProperty(Duration) {
 | 
				
			||||||
 | 
							buffer.WriteString(" duration = 1")
 | 
				
			||||||
 | 
							lead = ", "
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeFloatProperty(Delay)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if value := animation.getRaw(TimingFunction); value != nil {
 | 
				
			||||||
 | 
							if timingFunction, ok := value.(string); ok && timingFunction != "" {
 | 
				
			||||||
 | 
								buffer.WriteString(lead)
 | 
				
			||||||
 | 
								buffer.WriteString(TimingFunction)
 | 
				
			||||||
 | 
								buffer.WriteString(" = ")
 | 
				
			||||||
 | 
								if strings.ContainsAny(timingFunction, " ,()") {
 | 
				
			||||||
 | 
									buffer.WriteRune('"')
 | 
				
			||||||
 | 
									buffer.WriteString(timingFunction)
 | 
				
			||||||
 | 
									buffer.WriteRune('"')
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer.WriteString(" }")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (animation *animationData) timingFunctionCSS(session Session) string {
 | 
					func (animation *animationData) timingFunctionCSS(session Session) string {
 | 
				
			||||||
	if timingFunction, ok := stringProperty(animation, TimingFunction, session); ok {
 | 
						if timingFunction, ok := stringProperty(animation, TimingFunction, session); ok {
 | 
				
			||||||
		if timingFunction, ok = session.resolveConstants(timingFunction); ok && validateTimingFunction(timingFunction) {
 | 
							if timingFunction, ok = session.resolveConstants(timingFunction); ok && validateTimingFunction(timingFunction) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,6 +26,10 @@ func (player *audioPlayerData) Init(session Session) {
 | 
				
			||||||
	player.tag = "AudioPlayer"
 | 
						player.tag = "AudioPlayer"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (player *audioPlayerData) String() string {
 | 
				
			||||||
 | 
						return getViewString(player)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (player *audioPlayerData) htmlTag() string {
 | 
					func (player *audioPlayerData) htmlTag() string {
 | 
				
			||||||
	return "audio"
 | 
						return "audio"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										44
									
								
								border.go
								
								
								
								
							
							
						
						
									
										44
									
								
								border.go
								
								
								
								
							| 
						 | 
					@ -48,8 +48,8 @@ const (
 | 
				
			||||||
// BorderProperty is the interface of a view border data
 | 
					// BorderProperty is the interface of a view border data
 | 
				
			||||||
type BorderProperty interface {
 | 
					type BorderProperty interface {
 | 
				
			||||||
	Properties
 | 
						Properties
 | 
				
			||||||
	ruiStringer
 | 
					 | 
				
			||||||
	fmt.Stringer
 | 
						fmt.Stringer
 | 
				
			||||||
 | 
						stringWriter
 | 
				
			||||||
	ViewBorders(session Session) ViewBorders
 | 
						ViewBorders(session Session) ViewBorders
 | 
				
			||||||
	delete(tag string)
 | 
						delete(tag string)
 | 
				
			||||||
	cssStyle(builder cssBuilder, session Session)
 | 
						cssStyle(builder cssBuilder, session Session)
 | 
				
			||||||
| 
						 | 
					@ -202,12 +202,23 @@ func (border *borderProperty) normalizeTag(tag string) string {
 | 
				
			||||||
	return tag
 | 
						return tag
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (border *borderProperty) ruiString(writer ruiWriter) {
 | 
					func (border *borderProperty) writeString(buffer *strings.Builder, indent string) {
 | 
				
			||||||
	writer.startObject("_")
 | 
						buffer.WriteString("_{ ")
 | 
				
			||||||
 | 
						comma := false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						write := func(tag string, value interface{}) {
 | 
				
			||||||
 | 
							if comma {
 | 
				
			||||||
 | 
								buffer.WriteString(", ")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							buffer.WriteString(tag)
 | 
				
			||||||
 | 
							buffer.WriteString(" = ")
 | 
				
			||||||
 | 
							writePropertyValue(buffer, BorderStyle, value, indent)
 | 
				
			||||||
 | 
							comma = true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, tag := range []string{Style, Width, ColorTag} {
 | 
						for _, tag := range []string{Style, Width, ColorTag} {
 | 
				
			||||||
		if value, ok := border.properties[tag]; ok {
 | 
							if value, ok := border.properties[tag]; ok {
 | 
				
			||||||
			writer.writeProperty(Style, value)
 | 
								write(tag, value)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -216,27 +227,32 @@ func (border *borderProperty) ruiString(writer ruiWriter) {
 | 
				
			||||||
		width, okWidth := border.properties[side+"-"+Width]
 | 
							width, okWidth := border.properties[side+"-"+Width]
 | 
				
			||||||
		color, okColor := border.properties[side+"-"+ColorTag]
 | 
							color, okColor := border.properties[side+"-"+ColorTag]
 | 
				
			||||||
		if okStyle || okWidth || okColor {
 | 
							if okStyle || okWidth || okColor {
 | 
				
			||||||
			writer.startObjectProperty(side, "_")
 | 
								if comma {
 | 
				
			||||||
 | 
									buffer.WriteString(", ")
 | 
				
			||||||
 | 
									comma = false
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								buffer.WriteString(side)
 | 
				
			||||||
 | 
								buffer.WriteString(" = _{ ")
 | 
				
			||||||
			if okStyle {
 | 
								if okStyle {
 | 
				
			||||||
				writer.writeProperty(Style, style)
 | 
									write(Style, style)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if okWidth {
 | 
								if okWidth {
 | 
				
			||||||
				writer.writeProperty(Width, width)
 | 
									write(Width, width)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if okColor {
 | 
								if okColor {
 | 
				
			||||||
				writer.writeProperty(ColorTag, color)
 | 
									write(ColorTag, color)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			writer.endObject()
 | 
								buffer.WriteString(" }")
 | 
				
			||||||
 | 
								comma = true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// TODO
 | 
					
 | 
				
			||||||
	writer.endObject()
 | 
						buffer.WriteString(" }")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (border *borderProperty) String() string {
 | 
					func (border *borderProperty) String() string {
 | 
				
			||||||
	writer := newRUIWriter()
 | 
						return runStringWriter(border)
 | 
				
			||||||
	border.ruiString(writer)
 | 
					 | 
				
			||||||
	return writer.finish()
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (border *borderProperty) setSingleBorderObject(prefix string, obj DataObject) bool {
 | 
					func (border *borderProperty) setSingleBorderObject(prefix string, obj DataObject) bool {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										81
									
								
								bounds.go
								
								
								
								
							
							
						
						
									
										81
									
								
								bounds.go
								
								
								
								
							| 
						 | 
					@ -8,8 +8,8 @@ import (
 | 
				
			||||||
// BorderProperty is the interface of a bounds property data
 | 
					// BorderProperty is the interface of a bounds property data
 | 
				
			||||||
type BoundsProperty interface {
 | 
					type BoundsProperty interface {
 | 
				
			||||||
	Properties
 | 
						Properties
 | 
				
			||||||
	ruiStringer
 | 
					 | 
				
			||||||
	fmt.Stringer
 | 
						fmt.Stringer
 | 
				
			||||||
 | 
						stringWriter
 | 
				
			||||||
	Bounds(session Session) Bounds
 | 
						Bounds(session Session) Bounds
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,22 +54,25 @@ func (bounds *boundsPropertyData) normalizeTag(tag string) string {
 | 
				
			||||||
	return tag
 | 
						return tag
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (bounds *boundsPropertyData) ruiString(writer ruiWriter) {
 | 
					func (bounds *boundsPropertyData) String() string {
 | 
				
			||||||
	writer.startObject("_")
 | 
						return runStringWriter(bounds)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	for _, tag := range []string{Top, Right, Bottom, Left} {
 | 
					 | 
				
			||||||
		if value, ok := bounds.properties[tag]; ok {
 | 
					 | 
				
			||||||
			writer.writeProperty(Style, value)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	writer.endObject()
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (bounds *boundsPropertyData) String() string {
 | 
					func (bounds *boundsPropertyData) writeString(buffer *strings.Builder, indent string) {
 | 
				
			||||||
	writer := newRUIWriter()
 | 
						buffer.WriteString("_{ ")
 | 
				
			||||||
	bounds.ruiString(writer)
 | 
						comma := false
 | 
				
			||||||
	return writer.finish()
 | 
						for _, tag := range []string{Top, Right, Bottom, Left} {
 | 
				
			||||||
 | 
							if value, ok := bounds.properties[tag]; ok {
 | 
				
			||||||
 | 
								if comma {
 | 
				
			||||||
 | 
									buffer.WriteString(", ")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								buffer.WriteString(tag)
 | 
				
			||||||
 | 
								buffer.WriteString(" = ")
 | 
				
			||||||
 | 
								writePropertyValue(buffer, tag, value, indent)
 | 
				
			||||||
 | 
								comma = true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						buffer.WriteString(" }")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (bounds *boundsPropertyData) Remove(tag string) {
 | 
					func (bounds *boundsPropertyData) Remove(tag string) {
 | 
				
			||||||
| 
						 | 
					@ -135,50 +138,6 @@ func (bounds *Bounds) SetAll(value SizeUnit) {
 | 
				
			||||||
	bounds.Left = value
 | 
						bounds.Left = value
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (bounds *Bounds) parse(value string, session Session) bool {
 | 
					 | 
				
			||||||
	var ok bool
 | 
					 | 
				
			||||||
	if value, ok = session.resolveConstants(value); !ok {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	values := strings.Split(value, ",")
 | 
					 | 
				
			||||||
	switch len(values) {
 | 
					 | 
				
			||||||
	case 1:
 | 
					 | 
				
			||||||
		if bounds.Left, ok = StringToSizeUnit(values[0]); !ok {
 | 
					 | 
				
			||||||
			return false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		bounds.Right.Type = bounds.Left.Type
 | 
					 | 
				
			||||||
		bounds.Right.Value = bounds.Left.Value
 | 
					 | 
				
			||||||
		bounds.Top.Type = bounds.Left.Type
 | 
					 | 
				
			||||||
		bounds.Top.Value = bounds.Left.Value
 | 
					 | 
				
			||||||
		bounds.Bottom.Type = bounds.Left.Type
 | 
					 | 
				
			||||||
		bounds.Bottom.Value = bounds.Left.Value
 | 
					 | 
				
			||||||
		return true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case 5:
 | 
					 | 
				
			||||||
		if values[4] != "" {
 | 
					 | 
				
			||||||
			ErrorLog("invalid Bounds value '" + value + "' (needs 1 or 4 elements separeted by comma)")
 | 
					 | 
				
			||||||
			return false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		fallthrough
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case 4:
 | 
					 | 
				
			||||||
		if bounds.Top, ok = StringToSizeUnit(values[0]); ok {
 | 
					 | 
				
			||||||
			if bounds.Right, ok = StringToSizeUnit(values[1]); ok {
 | 
					 | 
				
			||||||
				if bounds.Bottom, ok = StringToSizeUnit(values[2]); ok {
 | 
					 | 
				
			||||||
					if bounds.Left, ok = StringToSizeUnit(values[3]); ok {
 | 
					 | 
				
			||||||
						return true
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ErrorLog("invalid Bounds value '" + value + "' (needs 1 or 4 elements separeted by comma)")
 | 
					 | 
				
			||||||
	return false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (bounds *Bounds) setFromProperties(tag, topTag, rightTag, bottomTag, leftTag string, properties Properties, session Session) {
 | 
					func (bounds *Bounds) setFromProperties(tag, topTag, rightTag, bottomTag, leftTag string, properties Properties, session Session) {
 | 
				
			||||||
	bounds.Top = AutoSize()
 | 
						bounds.Top = AutoSize()
 | 
				
			||||||
	if size, ok := sizeProperty(properties, tag, session); ok {
 | 
						if size, ok := sizeProperty(properties, tag, session); ok {
 | 
				
			||||||
| 
						 | 
					@ -202,6 +161,7 @@ func (bounds *Bounds) setFromProperties(tag, topTag, rightTag, bottomTag, leftTa
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
func (bounds *Bounds) allFieldsAuto() bool {
 | 
					func (bounds *Bounds) allFieldsAuto() bool {
 | 
				
			||||||
	return bounds.Left.Type == Auto &&
 | 
						return bounds.Left.Type == Auto &&
 | 
				
			||||||
		bounds.Top.Type == Auto &&
 | 
							bounds.Top.Type == Auto &&
 | 
				
			||||||
| 
						 | 
					@ -209,7 +169,6 @@ func (bounds *Bounds) allFieldsAuto() bool {
 | 
				
			||||||
		bounds.Bottom.Type == Auto
 | 
							bounds.Bottom.Type == Auto
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
func (bounds *Bounds) allFieldsZero() bool {
 | 
					func (bounds *Bounds) allFieldsZero() bool {
 | 
				
			||||||
	return (bounds.Left.Type == Auto || bounds.Left.Value == 0) &&
 | 
						return (bounds.Left.Type == Auto || bounds.Left.Value == 0) &&
 | 
				
			||||||
		(bounds.Top.Type == Auto || bounds.Top.Value == 0) &&
 | 
							(bounds.Top.Type == Auto || bounds.Top.Value == 0) &&
 | 
				
			||||||
| 
						 | 
					@ -231,6 +190,7 @@ func (bounds *Bounds) allFieldsEqual() bool {
 | 
				
			||||||
	return false
 | 
						return false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
func (bounds Bounds) writeCSSString(buffer *strings.Builder, textForAuto string) {
 | 
					func (bounds Bounds) writeCSSString(buffer *strings.Builder, textForAuto string) {
 | 
				
			||||||
	buffer.WriteString(bounds.Top.cssString(textForAuto))
 | 
						buffer.WriteString(bounds.Top.cssString(textForAuto))
 | 
				
			||||||
	if !bounds.allFieldsEqual() {
 | 
						if !bounds.allFieldsEqual() {
 | 
				
			||||||
| 
						 | 
					@ -242,6 +202,7 @@ func (bounds Bounds) writeCSSString(buffer *strings.Builder, textForAuto string)
 | 
				
			||||||
		buffer.WriteString(bounds.Left.cssString(textForAuto))
 | 
							buffer.WriteString(bounds.Left.cssString(textForAuto))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// String convert Bounds to string
 | 
					// String convert Bounds to string
 | 
				
			||||||
func (bounds *Bounds) String() string {
 | 
					func (bounds *Bounds) String() string {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,6 +36,10 @@ func (canvasView *canvasViewData) Init(session Session) {
 | 
				
			||||||
	canvasView.tag = "CanvasView"
 | 
						canvasView.tag = "CanvasView"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (canvasView *canvasViewData) String() string {
 | 
				
			||||||
 | 
						return getViewString(canvasView)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (canvasView *canvasViewData) normalizeTag(tag string) string {
 | 
					func (canvasView *canvasViewData) normalizeTag(tag string) string {
 | 
				
			||||||
	tag = strings.ToLower(tag)
 | 
						tag = strings.ToLower(tag)
 | 
				
			||||||
	switch tag {
 | 
						switch tag {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,6 +43,10 @@ func (button *checkboxData) Init(session Session) {
 | 
				
			||||||
	button.checkedListeners = []func(Checkbox, bool){}
 | 
						button.checkedListeners = []func(Checkbox, bool){}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (button *checkboxData) String() string {
 | 
				
			||||||
 | 
						return getViewString(button)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (button *checkboxData) Focusable() bool {
 | 
					func (button *checkboxData) Focusable() bool {
 | 
				
			||||||
	return true
 | 
						return true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,6 +39,10 @@ func (picker *colorPickerData) Init(session Session) {
 | 
				
			||||||
	picker.properties[Padding] = Px(0)
 | 
						picker.properties[Padding] = Px(0)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (picker *colorPickerData) String() string {
 | 
				
			||||||
 | 
						return getViewString(picker)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (picker *colorPickerData) normalizeTag(tag string) string {
 | 
					func (picker *colorPickerData) normalizeTag(tag string) string {
 | 
				
			||||||
	tag = strings.ToLower(tag)
 | 
						tag = strings.ToLower(tag)
 | 
				
			||||||
	switch tag {
 | 
						switch tag {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,6 +63,10 @@ func (ColumnLayout *columnLayoutData) Init(session Session) {
 | 
				
			||||||
	//ColumnLayout.systemClass = "ruiColumnLayout"
 | 
						//ColumnLayout.systemClass = "ruiColumnLayout"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (columnLayout *columnLayoutData) String() string {
 | 
				
			||||||
 | 
						return getViewString(columnLayout)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (columnLayout *columnLayoutData) normalizeTag(tag string) string {
 | 
					func (columnLayout *columnLayoutData) normalizeTag(tag string) string {
 | 
				
			||||||
	tag = strings.ToLower(tag)
 | 
						tag = strings.ToLower(tag)
 | 
				
			||||||
	switch tag {
 | 
						switch tag {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,8 +8,8 @@ import (
 | 
				
			||||||
// ColumnSeparatorProperty is the interface of a view separator data
 | 
					// ColumnSeparatorProperty is the interface of a view separator data
 | 
				
			||||||
type ColumnSeparatorProperty interface {
 | 
					type ColumnSeparatorProperty interface {
 | 
				
			||||||
	Properties
 | 
						Properties
 | 
				
			||||||
	ruiStringer
 | 
					 | 
				
			||||||
	fmt.Stringer
 | 
						fmt.Stringer
 | 
				
			||||||
 | 
						stringWriter
 | 
				
			||||||
	ViewBorder(session Session) ViewBorder
 | 
						ViewBorder(session Session) ViewBorder
 | 
				
			||||||
	cssValue(session Session) string
 | 
						cssValue(session Session) string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -84,20 +84,26 @@ func (separator *columnSeparatorProperty) normalizeTag(tag string) string {
 | 
				
			||||||
	return tag
 | 
						return tag
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (separator *columnSeparatorProperty) ruiString(writer ruiWriter) {
 | 
					func (separator *columnSeparatorProperty) writeString(buffer *strings.Builder, indent string) {
 | 
				
			||||||
	writer.startObject("_")
 | 
						buffer.WriteString("_{ ")
 | 
				
			||||||
 | 
						comma := false
 | 
				
			||||||
	for _, tag := range []string{Style, Width, ColorTag} {
 | 
						for _, tag := range []string{Style, Width, ColorTag} {
 | 
				
			||||||
		if value, ok := separator.properties[tag]; ok {
 | 
							if value, ok := separator.properties[tag]; ok {
 | 
				
			||||||
			writer.writeProperty(Style, value)
 | 
								if comma {
 | 
				
			||||||
 | 
									buffer.WriteString(", ")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								buffer.WriteString(tag)
 | 
				
			||||||
 | 
								buffer.WriteString(" = ")
 | 
				
			||||||
 | 
								writePropertyValue(buffer, BorderStyle, value, indent)
 | 
				
			||||||
 | 
								comma = true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	writer.endObject()
 | 
					
 | 
				
			||||||
 | 
						buffer.WriteString(" }")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (separator *columnSeparatorProperty) String() string {
 | 
					func (separator *columnSeparatorProperty) String() string {
 | 
				
			||||||
	writer := newRUIWriter()
 | 
						return runStringWriter(separator)
 | 
				
			||||||
	separator.ruiString(writer)
 | 
					 | 
				
			||||||
	return writer.finish()
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (separator *columnSeparatorProperty) Remove(tag string) {
 | 
					func (separator *columnSeparatorProperty) Remove(tag string) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -91,6 +91,10 @@ func (customView *CustomViewData) Clear() {
 | 
				
			||||||
func (customView *CustomViewData) Init(session Session) {
 | 
					func (customView *CustomViewData) Init(session Session) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (customView *CustomViewData) cssViewStyle(buffer cssBuilder, session Session) {
 | 
				
			||||||
 | 
						customView.superView.cssViewStyle(buffer, session)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Session returns a current Session interface
 | 
					// Session returns a current Session interface
 | 
				
			||||||
func (customView *CustomViewData) Session() Session {
 | 
					func (customView *CustomViewData) Session() Session {
 | 
				
			||||||
	return customView.superView.Session()
 | 
						return customView.superView.Session()
 | 
				
			||||||
| 
						 | 
					@ -249,19 +253,11 @@ func (customView *CustomViewData) RemoveView(index int) View {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (customView *CustomViewData) String() string {
 | 
					func (customView *CustomViewData) String() string {
 | 
				
			||||||
	if customView.superView != nil {
 | 
						if customView.superView != nil {
 | 
				
			||||||
		writer := newRUIWriter()
 | 
							return getViewString(customView)
 | 
				
			||||||
		customView.ruiString(writer)
 | 
					 | 
				
			||||||
		return writer.finish()
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return customView.tag + " { }"
 | 
						return customView.tag + " { }"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (customView *CustomViewData) ruiString(writer ruiWriter) {
 | 
					 | 
				
			||||||
	if customView.superView != nil {
 | 
					 | 
				
			||||||
		ruiViewString(customView.superView, customView.tag, writer)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (customView *CustomViewData) setScroll(x, y, width, height float64) {
 | 
					func (customView *CustomViewData) setScroll(x, y, width, height float64) {
 | 
				
			||||||
	if customView.superView != nil {
 | 
						if customView.superView != nil {
 | 
				
			||||||
		customView.superView.setScroll(x, y, width, height)
 | 
							customView.superView.setScroll(x, y, width, height)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,6 +44,10 @@ func (picker *datePickerData) Init(session Session) {
 | 
				
			||||||
	picker.dateChangedListeners = []func(DatePicker, time.Time){}
 | 
						picker.dateChangedListeners = []func(DatePicker, time.Time){}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (picker *datePickerData) String() string {
 | 
				
			||||||
 | 
						return getViewString(picker)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (picker *datePickerData) Focusable() bool {
 | 
					func (picker *datePickerData) Focusable() bool {
 | 
				
			||||||
	return true
 | 
						return true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -117,6 +117,14 @@ func (detailsView *detailsViewData) set(tag string, value interface{}) bool {
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case NotTranslate:
 | 
				
			||||||
 | 
							if !detailsView.viewData.set(tag, value) {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if detailsView.created {
 | 
				
			||||||
 | 
								updateInnerHTML(detailsView.htmlID(), detailsView.Session())
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return detailsView.viewsContainerData.Set(tag, value)
 | 
							return detailsView.viewsContainerData.Set(tag, value)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -149,6 +157,9 @@ func (detailsView *detailsViewData) htmlSubviews(self View, buffer *strings.Buil
 | 
				
			||||||
	if value, ok := detailsView.properties[Summary]; ok {
 | 
						if value, ok := detailsView.properties[Summary]; ok {
 | 
				
			||||||
		switch value := value.(type) {
 | 
							switch value := value.(type) {
 | 
				
			||||||
		case string:
 | 
							case string:
 | 
				
			||||||
 | 
								if !GetNotTranslate(detailsView, "") {
 | 
				
			||||||
 | 
									value, _ = detailsView.session.GetString(value)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			buffer.WriteString("<summary>")
 | 
								buffer.WriteString("<summary>")
 | 
				
			||||||
			buffer.WriteString(value)
 | 
								buffer.WriteString(value)
 | 
				
			||||||
			buffer.WriteString("</summary>")
 | 
								buffer.WriteString("</summary>")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,6 +41,10 @@ func (list *dropDownListData) Init(session Session) {
 | 
				
			||||||
	list.dropDownListener = []func(DropDownList, int){}
 | 
						list.dropDownListener = []func(DropDownList, int){}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (list *dropDownListData) String() string {
 | 
				
			||||||
 | 
						return getViewString(list)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (list *dropDownListData) Focusable() bool {
 | 
					func (list *dropDownListData) Focusable() bool {
 | 
				
			||||||
	return true
 | 
						return true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,6 +63,10 @@ func (edit *editViewData) Init(session Session) {
 | 
				
			||||||
	edit.tag = "EditView"
 | 
						edit.tag = "EditView"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (edit *editViewData) String() string {
 | 
				
			||||||
 | 
						return getViewString(edit)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (edit *editViewData) Focusable() bool {
 | 
					func (edit *editViewData) Focusable() bool {
 | 
				
			||||||
	return true
 | 
						return true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -89,6 +89,10 @@ func (picker *filePickerData) Init(session Session) {
 | 
				
			||||||
	picker.fileSelectedListeners = []func(FilePicker, []FileInfo){}
 | 
						picker.fileSelectedListeners = []func(FilePicker, []FileInfo){}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (picker *filePickerData) String() string {
 | 
				
			||||||
 | 
						return getViewString(picker)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (picker *filePickerData) Focusable() bool {
 | 
					func (picker *filePickerData) Focusable() bool {
 | 
				
			||||||
	return true
 | 
						return true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,6 +33,10 @@ func (gridLayout *gridLayoutData) Init(session Session) {
 | 
				
			||||||
	gridLayout.systemClass = "ruiGridLayout"
 | 
						gridLayout.systemClass = "ruiGridLayout"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (gridLayout *gridLayoutData) String() string {
 | 
				
			||||||
 | 
						return getViewString(gridLayout)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (style *viewStyle) setGridCellSize(tag string, value interface{}) bool {
 | 
					func (style *viewStyle) setGridCellSize(tag string, value interface{}) bool {
 | 
				
			||||||
	setValues := func(values []string) bool {
 | 
						setValues := func(values []string) bool {
 | 
				
			||||||
		count := len(values)
 | 
							count := len(values)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,6 +55,10 @@ func (imageView *imageViewData) Init(session Session) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (imageView *imageViewData) String() string {
 | 
				
			||||||
 | 
						return getViewString(imageView)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (imageView *imageViewData) normalizeTag(tag string) string {
 | 
					func (imageView *imageViewData) normalizeTag(tag string) string {
 | 
				
			||||||
	tag = strings.ToLower(tag)
 | 
						tag = strings.ToLower(tag)
 | 
				
			||||||
	switch tag {
 | 
						switch tag {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,6 +49,10 @@ func (listLayout *listLayoutData) Init(session Session) {
 | 
				
			||||||
	listLayout.systemClass = "ruiListLayout"
 | 
						listLayout.systemClass = "ruiListLayout"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (listLayout *listLayoutData) String() string {
 | 
				
			||||||
 | 
						return getViewString(listLayout)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (listLayout *listLayoutData) Remove(tag string) {
 | 
					func (listLayout *listLayoutData) Remove(tag string) {
 | 
				
			||||||
	listLayout.remove(strings.ToLower(tag))
 | 
						listLayout.remove(strings.ToLower(tag))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -91,6 +91,10 @@ func (listView *listViewData) Init(session Session) {
 | 
				
			||||||
	listView.checkedListeners = []func(ListView, []int){}
 | 
						listView.checkedListeners = []func(ListView, []int){}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (listView *listViewData) String() string {
 | 
				
			||||||
 | 
						return getViewString(listView)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (listView *listViewData) Views() []View {
 | 
					func (listView *listViewData) Views() []View {
 | 
				
			||||||
	return listView.items
 | 
						return listView.items
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -168,6 +168,10 @@ func (player *mediaPlayerData) Init(session Session) {
 | 
				
			||||||
	player.tag = "MediaPlayer"
 | 
						player.tag = "MediaPlayer"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (player *mediaPlayerData) String() string {
 | 
				
			||||||
 | 
						return getViewString(player)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (player *mediaPlayerData) Focusable() bool {
 | 
					func (player *mediaPlayerData) Focusable() bool {
 | 
				
			||||||
	return true
 | 
						return true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,6 +51,10 @@ func (picker *numberPickerData) Init(session Session) {
 | 
				
			||||||
	picker.numberChangedListeners = []func(NumberPicker, float64){}
 | 
						picker.numberChangedListeners = []func(NumberPicker, float64){}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (picker *numberPickerData) String() string {
 | 
				
			||||||
 | 
						return getViewString(picker)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (picker *numberPickerData) Focusable() bool {
 | 
					func (picker *numberPickerData) Focusable() bool {
 | 
				
			||||||
	return true
 | 
						return true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										22
									
								
								outline.go
								
								
								
								
							
							
						
						
									
										22
									
								
								outline.go
								
								
								
								
							| 
						 | 
					@ -7,7 +7,7 @@ import (
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type OutlineProperty interface {
 | 
					type OutlineProperty interface {
 | 
				
			||||||
	Properties
 | 
						Properties
 | 
				
			||||||
	ruiStringer
 | 
						stringWriter
 | 
				
			||||||
	fmt.Stringer
 | 
						fmt.Stringer
 | 
				
			||||||
	ViewOutline(session Session) ViewOutline
 | 
						ViewOutline(session Session) ViewOutline
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -25,22 +25,26 @@ func NewOutlineProperty(params Params) OutlineProperty {
 | 
				
			||||||
	return outline
 | 
						return outline
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (outline *outlinePropertyData) ruiString(writer ruiWriter) {
 | 
					func (outline *outlinePropertyData) writeString(buffer *strings.Builder, indent string) {
 | 
				
			||||||
	writer.startObject("_")
 | 
						buffer.WriteString("_{ ")
 | 
				
			||||||
 | 
						comma := false
 | 
				
			||||||
	for _, tag := range []string{Style, Width, ColorTag} {
 | 
						for _, tag := range []string{Style, Width, ColorTag} {
 | 
				
			||||||
		if value, ok := outline.properties[tag]; ok {
 | 
							if value, ok := outline.properties[tag]; ok {
 | 
				
			||||||
			writer.writeProperty(Style, value)
 | 
								if comma {
 | 
				
			||||||
 | 
									buffer.WriteString(", ")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								buffer.WriteString(tag)
 | 
				
			||||||
 | 
								buffer.WriteString(" = ")
 | 
				
			||||||
 | 
								writePropertyValue(buffer, BorderStyle, value, indent)
 | 
				
			||||||
 | 
								comma = true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	writer.endObject()
 | 
						buffer.WriteString(" }")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (outline *outlinePropertyData) String() string {
 | 
					func (outline *outlinePropertyData) String() string {
 | 
				
			||||||
	writer := newRUIWriter()
 | 
						return runStringWriter(outline)
 | 
				
			||||||
	outline.ruiString(writer)
 | 
					 | 
				
			||||||
	return writer.finish()
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (outline *outlinePropertyData) normalizeTag(tag string) string {
 | 
					func (outline *outlinePropertyData) normalizeTag(tag string) string {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,6 +36,10 @@ func (progress *progressBarData) Init(session Session) {
 | 
				
			||||||
	progress.tag = "ProgressBar"
 | 
						progress.tag = "ProgressBar"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (progress *progressBarData) String() string {
 | 
				
			||||||
 | 
						return getViewString(progress)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (progress *progressBarData) normalizeTag(tag string) string {
 | 
					func (progress *progressBarData) normalizeTag(tag string) string {
 | 
				
			||||||
	tag = strings.ToLower(tag)
 | 
						tag = strings.ToLower(tag)
 | 
				
			||||||
	switch tag {
 | 
						switch tag {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										22
									
								
								radius.go
								
								
								
								
							
							
						
						
									
										22
									
								
								radius.go
								
								
								
								
							| 
						 | 
					@ -97,7 +97,7 @@ const (
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type RadiusProperty interface {
 | 
					type RadiusProperty interface {
 | 
				
			||||||
	Properties
 | 
						Properties
 | 
				
			||||||
	ruiStringer
 | 
						stringWriter
 | 
				
			||||||
	fmt.Stringer
 | 
						fmt.Stringer
 | 
				
			||||||
	BoxRadius(session Session) BoxRadius
 | 
						BoxRadius(session Session) BoxRadius
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -125,23 +125,27 @@ func (radius *radiusPropertyData) normalizeTag(tag string) string {
 | 
				
			||||||
	return strings.TrimPrefix(strings.ToLower(tag), "radius-")
 | 
						return strings.TrimPrefix(strings.ToLower(tag), "radius-")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (radius *radiusPropertyData) ruiString(writer ruiWriter) {
 | 
					func (radius *radiusPropertyData) writeString(buffer *strings.Builder, indent string) {
 | 
				
			||||||
	writer.startObject("_")
 | 
						buffer.WriteString("_{ ")
 | 
				
			||||||
 | 
						comma := false
 | 
				
			||||||
	for _, tag := range []string{X, Y, TopLeft, TopLeftX, TopLeftY, TopRight, TopRightX, TopRightY,
 | 
						for _, tag := range []string{X, Y, TopLeft, TopLeftX, TopLeftY, TopRight, TopRightX, TopRightY,
 | 
				
			||||||
		BottomLeft, BottomLeftX, BottomLeftY, BottomRight, BottomRightX, BottomRightY} {
 | 
							BottomLeft, BottomLeftX, BottomLeftY, BottomRight, BottomRightX, BottomRightY} {
 | 
				
			||||||
		if value, ok := radius.properties[tag]; ok {
 | 
							if value, ok := radius.properties[tag]; ok {
 | 
				
			||||||
			writer.writeProperty(Style, value)
 | 
								if comma {
 | 
				
			||||||
 | 
									buffer.WriteString(", ")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								buffer.WriteString(tag)
 | 
				
			||||||
 | 
								buffer.WriteString(" = ")
 | 
				
			||||||
 | 
								writePropertyValue(buffer, tag, value, indent)
 | 
				
			||||||
 | 
								comma = true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	writer.endObject()
 | 
						buffer.WriteString(" }")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (radius *radiusPropertyData) String() string {
 | 
					func (radius *radiusPropertyData) String() string {
 | 
				
			||||||
	writer := newRUIWriter()
 | 
						return runStringWriter(radius)
 | 
				
			||||||
	radius.ruiString(writer)
 | 
					 | 
				
			||||||
	return writer.finish()
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (radius *radiusPropertyData) delete(tags []string) {
 | 
					func (radius *radiusPropertyData) delete(tags []string) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -61,6 +61,10 @@ func (resizable *resizableData) Init(session Session) {
 | 
				
			||||||
	resizable.content = []View{}
 | 
						resizable.content = []View{}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (resizable *resizableData) String() string {
 | 
				
			||||||
 | 
						return getViewString(resizable)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (resizable *resizableData) Views() []View {
 | 
					func (resizable *resizableData) Views() []View {
 | 
				
			||||||
	return resizable.content
 | 
						return resizable.content
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										45
									
								
								ruiWriter.go
								
								
								
								
							
							
						
						
									
										45
									
								
								ruiWriter.go
								
								
								
								
							| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
package rui
 | 
					package rui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
| 
						 | 
					@ -10,6 +11,8 @@ type ruiWriter interface {
 | 
				
			||||||
	startObject(tag string)
 | 
						startObject(tag string)
 | 
				
			||||||
	startObjectProperty(tag, objectTag string)
 | 
						startObjectProperty(tag, objectTag string)
 | 
				
			||||||
	endObject()
 | 
						endObject()
 | 
				
			||||||
 | 
						startArrayProperty(tag string)
 | 
				
			||||||
 | 
						endObArray()
 | 
				
			||||||
	writeProperty(tag string, value interface{})
 | 
						writeProperty(tag string, value interface{})
 | 
				
			||||||
	finish() string
 | 
						finish() string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -41,23 +44,22 @@ func (writer *ruiWriterData) writeIndent() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (writer *ruiWriterData) writeString(str string) {
 | 
					func (writer *ruiWriterData) writeString(str string) {
 | 
				
			||||||
	esc := map[string]string{"\t": `\t`, "\r": `\r`, "\n": `\n`, "\"": `"`}
 | 
						hasEsc := strings.ContainsAny(str, "\t\"\r\n")
 | 
				
			||||||
	hasEsc := false
 | 
						if hasEsc || strings.ContainsAny(str, " ,;'`[]{}()") {
 | 
				
			||||||
	for s := range esc {
 | 
					 | 
				
			||||||
		if strings.Contains(str, s) {
 | 
					 | 
				
			||||||
			hasEsc = true
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if hasEsc || strings.Contains(str, " ") || strings.Contains(str, ",") {
 | 
					 | 
				
			||||||
		if !strings.Contains(str, "`") && (hasEsc || strings.Contains(str, `\`)) {
 | 
							if !strings.Contains(str, "`") && (hasEsc || strings.Contains(str, `\`)) {
 | 
				
			||||||
			writer.buffer.WriteRune('`')
 | 
								writer.buffer.WriteRune('`')
 | 
				
			||||||
			writer.buffer.WriteString(str)
 | 
								writer.buffer.WriteString(str)
 | 
				
			||||||
			writer.buffer.WriteRune('`')
 | 
								writer.buffer.WriteRune('`')
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			str = strings.Replace(str, `\`, `\\`, -1)
 | 
								replace := []struct{ old, new string }{
 | 
				
			||||||
			for oldStr, newStr := range esc {
 | 
									{old: `\`, new: `\\`},
 | 
				
			||||||
				str = strings.Replace(str, oldStr, newStr, -1)
 | 
									{old: "\t", new: `\t`},
 | 
				
			||||||
 | 
									{old: "\r", new: `\r`},
 | 
				
			||||||
 | 
									{old: "\n", new: `\n`},
 | 
				
			||||||
 | 
									{old: "\"", new: `\"`},
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								for _, s := range replace {
 | 
				
			||||||
 | 
									str = strings.Replace(str, s.old, s.new, -1)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			writer.buffer.WriteRune('"')
 | 
								writer.buffer.WriteRune('"')
 | 
				
			||||||
			writer.buffer.WriteString(str)
 | 
								writer.buffer.WriteString(str)
 | 
				
			||||||
| 
						 | 
					@ -80,6 +82,9 @@ func (writer *ruiWriterData) startObjectProperty(tag, objectTag string) {
 | 
				
			||||||
	writer.indent += "\t"
 | 
						writer.indent += "\t"
 | 
				
			||||||
	writer.writeString(tag)
 | 
						writer.writeString(tag)
 | 
				
			||||||
	writer.writeString(" = ")
 | 
						writer.writeString(" = ")
 | 
				
			||||||
 | 
						if objectTag == "" {
 | 
				
			||||||
 | 
							objectTag = "_"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	writer.writeString(objectTag)
 | 
						writer.writeString(objectTag)
 | 
				
			||||||
	writer.buffer.WriteString(" {\n")
 | 
						writer.buffer.WriteString(" {\n")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -92,6 +97,21 @@ func (writer *ruiWriterData) endObject() {
 | 
				
			||||||
	writer.buffer.WriteRune('}')
 | 
						writer.buffer.WriteRune('}')
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (writer *ruiWriterData) startArrayProperty(tag string) {
 | 
				
			||||||
 | 
						writer.writeIndent()
 | 
				
			||||||
 | 
						writer.writeString(tag)
 | 
				
			||||||
 | 
						writer.buffer.WriteString(" = [\n")
 | 
				
			||||||
 | 
						writer.indent += "\t"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (writer *ruiWriterData) endObArray() {
 | 
				
			||||||
 | 
						if len(writer.indent) > 0 {
 | 
				
			||||||
 | 
							writer.indent = writer.indent[1:]
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						writer.writeIndent()
 | 
				
			||||||
 | 
						writer.buffer.WriteString("],\n")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (writer *ruiWriterData) writeValue(value interface{}) {
 | 
					func (writer *ruiWriterData) writeValue(value interface{}) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch value := value.(type) {
 | 
						switch value := value.(type) {
 | 
				
			||||||
| 
						 | 
					@ -201,3 +221,4 @@ func (writer *ruiWriterData) finish() string {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return result
 | 
						return result
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										23
									
								
								shadow.go
								
								
								
								
							
							
						
						
									
										23
									
								
								shadow.go
								
								
								
								
							| 
						 | 
					@ -31,7 +31,7 @@ const (
 | 
				
			||||||
type ViewShadow interface {
 | 
					type ViewShadow interface {
 | 
				
			||||||
	Properties
 | 
						Properties
 | 
				
			||||||
	fmt.Stringer
 | 
						fmt.Stringer
 | 
				
			||||||
	ruiStringer
 | 
						stringWriter
 | 
				
			||||||
	cssStyle(buffer *strings.Builder, session Session, lead string) bool
 | 
						cssStyle(buffer *strings.Builder, session Session, lead string) bool
 | 
				
			||||||
	cssTextStyle(buffer *strings.Builder, session Session, lead string) bool
 | 
						cssTextStyle(buffer *strings.Builder, session Session, lead string) bool
 | 
				
			||||||
	visible(session Session) bool
 | 
						visible(session Session) bool
 | 
				
			||||||
| 
						 | 
					@ -205,19 +205,24 @@ func (shadow *viewShadowData) visible(session Session) bool {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (shadow *viewShadowData) String() string {
 | 
					func (shadow *viewShadowData) String() string {
 | 
				
			||||||
	writer := newRUIWriter()
 | 
						return runStringWriter(shadow)
 | 
				
			||||||
	shadow.ruiString(writer)
 | 
					 | 
				
			||||||
	return writer.finish()
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (shadow *viewShadowData) ruiString(writer ruiWriter) {
 | 
					func (shadow *viewShadowData) writeString(buffer *strings.Builder, indent string) {
 | 
				
			||||||
	writer.startObject("_")
 | 
						buffer.WriteString("_{ ")
 | 
				
			||||||
 | 
						comma := false
 | 
				
			||||||
	for _, tag := range shadow.AllTags() {
 | 
						for _, tag := range shadow.AllTags() {
 | 
				
			||||||
		if value := shadow.Get(tag); value != nil {
 | 
							if value, ok := shadow.properties[tag]; ok {
 | 
				
			||||||
			writer.writeProperty(tag, value)
 | 
								if comma {
 | 
				
			||||||
 | 
									buffer.WriteString(", ")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								buffer.WriteString(tag)
 | 
				
			||||||
 | 
								buffer.WriteString(" = ")
 | 
				
			||||||
 | 
								writePropertyValue(buffer, tag, value, indent)
 | 
				
			||||||
 | 
								comma = true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	writer.endObject()
 | 
						buffer.WriteString(" }")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (properties *propertyList) setShadow(tag string, value interface{}) bool {
 | 
					func (properties *propertyList) setShadow(tag string, value interface{}) bool {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,6 +58,10 @@ func (layout *stackLayoutData) Init(session Session) {
 | 
				
			||||||
	layout.properties[TransitionEndEvent] = []func(View, string){layout.pushFinished, layout.popFinished}
 | 
						layout.properties[TransitionEndEvent] = []func(View, string){layout.pushFinished, layout.popFinished}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (layout *stackLayoutData) String() string {
 | 
				
			||||||
 | 
						return getViewString(layout)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (layout *stackLayoutData) pushFinished(view View, tag string) {
 | 
					func (layout *stackLayoutData) pushFinished(view View, tag string) {
 | 
				
			||||||
	if tag == "ruiPush" {
 | 
						if tag == "ruiPush" {
 | 
				
			||||||
		if layout.pushView != nil {
 | 
							if layout.pushView != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -268,6 +268,10 @@ func (table *tableViewData) Init(session Session) {
 | 
				
			||||||
	table.current.Column = -1
 | 
						table.current.Column = -1
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (table *tableViewData) String() string {
 | 
				
			||||||
 | 
						return getViewString(table)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (table *tableViewData) normalizeTag(tag string) string {
 | 
					func (table *tableViewData) normalizeTag(tag string) string {
 | 
				
			||||||
	switch tag = strings.ToLower(tag); tag {
 | 
						switch tag = strings.ToLower(tag); tag {
 | 
				
			||||||
	case "top-cell-padding":
 | 
						case "top-cell-padding":
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -99,6 +99,10 @@ func (tabsLayout *tabsLayoutData) Init(session Session) {
 | 
				
			||||||
	tabsLayout.tabCloseListener = []func(TabsLayout, int){}
 | 
						tabsLayout.tabCloseListener = []func(TabsLayout, int){}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (tabsLayout *tabsLayoutData) String() string {
 | 
				
			||||||
 | 
						return getViewString(tabsLayout)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (tabsLayout *tabsLayoutData) currentItem() int {
 | 
					func (tabsLayout *tabsLayoutData) currentItem() int {
 | 
				
			||||||
	result, _ := intProperty(tabsLayout, Current, tabsLayout.session, 0)
 | 
						result, _ := intProperty(tabsLayout, Current, tabsLayout.session, 0)
 | 
				
			||||||
	return result
 | 
						return result
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										16
									
								
								textView.go
								
								
								
								
							
							
						
						
									
										16
									
								
								textView.go
								
								
								
								
							| 
						 | 
					@ -32,6 +32,10 @@ func (textView *textViewData) Init(session Session) {
 | 
				
			||||||
	textView.tag = "TextView"
 | 
						textView.tag = "TextView"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (textView *textViewData) String() string {
 | 
				
			||||||
 | 
						return getViewString(textView)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (textView *textViewData) Get(tag string) interface{} {
 | 
					func (textView *textViewData) Get(tag string) interface{} {
 | 
				
			||||||
	return textView.get(strings.ToLower(tag))
 | 
						return textView.get(strings.ToLower(tag))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -103,6 +107,14 @@ func (textView *textViewData) set(tag string, value interface{}) bool {
 | 
				
			||||||
			textView.textOverflowUpdated()
 | 
								textView.textOverflowUpdated()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case NotTranslate:
 | 
				
			||||||
 | 
							if !textView.viewData.set(tag, value) {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if textView.created {
 | 
				
			||||||
 | 
								updateInnerHTML(textView.htmlID(), textView.Session())
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return textView.viewData.set(tag, value)
 | 
							return textView.viewData.set(tag, value)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -143,7 +155,9 @@ func textToJS(text string) string {
 | 
				
			||||||
func (textView *textViewData) htmlSubviews(self View, buffer *strings.Builder) {
 | 
					func (textView *textViewData) htmlSubviews(self View, buffer *strings.Builder) {
 | 
				
			||||||
	if value := textView.getRaw(Text); value != nil {
 | 
						if value := textView.getRaw(Text); value != nil {
 | 
				
			||||||
		if text, ok := value.(string); ok {
 | 
							if text, ok := value.(string); ok {
 | 
				
			||||||
			text, _ = textView.session.GetString(text)
 | 
								if !GetNotTranslate(textView, "") {
 | 
				
			||||||
 | 
									text, _ = textView.session.GetString(text)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			buffer.WriteString(textToJS(text))
 | 
								buffer.WriteString(textToJS(text))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,6 +44,10 @@ func (picker *timePickerData) Init(session Session) {
 | 
				
			||||||
	picker.timeChangedListeners = []func(TimePicker, time.Time){}
 | 
						picker.timeChangedListeners = []func(TimePicker, time.Time){}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (picker *timePickerData) String() string {
 | 
				
			||||||
 | 
						return getViewString(picker)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (picker *timePickerData) Focusable() bool {
 | 
					func (picker *timePickerData) Focusable() bool {
 | 
				
			||||||
	return true
 | 
						return true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,6 +45,10 @@ func (player *videoPlayerData) Init(session Session) {
 | 
				
			||||||
	player.tag = "VideoPlayer"
 | 
						player.tag = "VideoPlayer"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (player *videoPlayerData) String() string {
 | 
				
			||||||
 | 
						return getViewString(player)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (player *videoPlayerData) htmlTag() string {
 | 
					func (player *videoPlayerData) htmlTag() string {
 | 
				
			||||||
	return "video"
 | 
						return "video"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										59
									
								
								view.go
								
								
								
								
							
							
						
						
									
										59
									
								
								view.go
								
								
								
								
							| 
						 | 
					@ -30,9 +30,8 @@ func (frame Frame) Bottom() float64 {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// View - base view interface
 | 
					// View - base view interface
 | 
				
			||||||
type View interface {
 | 
					type View interface {
 | 
				
			||||||
	Properties
 | 
						ViewStyle
 | 
				
			||||||
	fmt.Stringer
 | 
						fmt.Stringer
 | 
				
			||||||
	ruiStringer
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Init initializes fields of View by default values
 | 
						// Init initializes fields of View by default values
 | 
				
			||||||
	Init(session Session)
 | 
						Init(session Session)
 | 
				
			||||||
| 
						 | 
					@ -616,6 +615,13 @@ func (view *viewData) Get(tag string) interface{} {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (view *viewData) get(tag string) interface{} {
 | 
					func (view *viewData) get(tag string) interface{} {
 | 
				
			||||||
 | 
						if tag == ID {
 | 
				
			||||||
 | 
							if view.viewID != "" {
 | 
				
			||||||
 | 
								return view.viewID
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return view.viewStyle.get(tag)
 | 
						return view.viewStyle.get(tag)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -834,51 +840,6 @@ func (view *viewData) handleCommand(self View, command string, data DataObject)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func ruiViewString(view View, viewTag string, writer ruiWriter) {
 | 
					 | 
				
			||||||
	writer.startObject(viewTag)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	tags := view.AllTags()
 | 
					 | 
				
			||||||
	count := len(tags)
 | 
					 | 
				
			||||||
	if count > 0 {
 | 
					 | 
				
			||||||
		if count > 1 {
 | 
					 | 
				
			||||||
			tagToStart := func(tag string) {
 | 
					 | 
				
			||||||
				for i, t := range tags {
 | 
					 | 
				
			||||||
					if t == tag {
 | 
					 | 
				
			||||||
						if i > 0 {
 | 
					 | 
				
			||||||
							for n := i; n > 0; n-- {
 | 
					 | 
				
			||||||
								tags[n] = tags[n-1]
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							tags[0] = tag
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
						return
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			tagToStart(StyleDisabled)
 | 
					 | 
				
			||||||
			tagToStart(Style)
 | 
					 | 
				
			||||||
			tagToStart(ID)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		for _, tag := range tags {
 | 
					 | 
				
			||||||
			if value := view.Get(tag); value != nil {
 | 
					 | 
				
			||||||
				writer.writeProperty(tag, value)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	writer.endObject()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (view *viewData) ruiString(writer ruiWriter) {
 | 
					 | 
				
			||||||
	ruiViewString(view, view.Tag(), writer)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (view *viewData) String() string {
 | 
					 | 
				
			||||||
	writer := newRUIWriter()
 | 
					 | 
				
			||||||
	view.ruiString(writer)
 | 
					 | 
				
			||||||
	return writer.finish()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (view *viewData) SetChangeListener(tag string, listener func(View, string)) {
 | 
					func (view *viewData) SetChangeListener(tag string, listener func(View, string)) {
 | 
				
			||||||
	if listener == nil {
 | 
						if listener == nil {
 | 
				
			||||||
		delete(view.changeListener, tag)
 | 
							delete(view.changeListener, tag)
 | 
				
			||||||
| 
						 | 
					@ -890,3 +851,7 @@ func (view *viewData) SetChangeListener(tag string, listener func(View, string))
 | 
				
			||||||
func (view *viewData) HasFocus() bool {
 | 
					func (view *viewData) HasFocus() bool {
 | 
				
			||||||
	return view.hasFocus
 | 
						return view.hasFocus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (view *viewData) String() string {
 | 
				
			||||||
 | 
						return getViewString(view)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										248
									
								
								viewClip.go
								
								
								
								
							
							
						
						
									
										248
									
								
								viewClip.go
								
								
								
								
							| 
						 | 
					@ -9,7 +9,7 @@ import (
 | 
				
			||||||
type ClipShape interface {
 | 
					type ClipShape interface {
 | 
				
			||||||
	Properties
 | 
						Properties
 | 
				
			||||||
	fmt.Stringer
 | 
						fmt.Stringer
 | 
				
			||||||
	ruiStringer
 | 
						stringWriter
 | 
				
			||||||
	cssStyle(session Session) string
 | 
						cssStyle(session Session) string
 | 
				
			||||||
	valid(session Session) bool
 | 
						valid(session Session) bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -22,6 +22,10 @@ type ellipseClip struct {
 | 
				
			||||||
	propertyList
 | 
						propertyList
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type circleClip struct {
 | 
				
			||||||
 | 
						propertyList
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type polygonClip struct {
 | 
					type polygonClip struct {
 | 
				
			||||||
	points []interface{}
 | 
						points []interface{}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -47,7 +51,7 @@ func InsetClip(top, right, bottom, left SizeUnit, radius RadiusProperty) ClipSha
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CircleClip creates a circle View clipping area.
 | 
					// CircleClip creates a circle View clipping area.
 | 
				
			||||||
func CircleClip(x, y, radius SizeUnit) ClipShape {
 | 
					func CircleClip(x, y, radius SizeUnit) ClipShape {
 | 
				
			||||||
	clip := new(ellipseClip)
 | 
						clip := new(circleClip)
 | 
				
			||||||
	clip.init()
 | 
						clip.init()
 | 
				
			||||||
	clip.Set(X, x)
 | 
						clip.Set(X, x)
 | 
				
			||||||
	clip.Set(Y, y)
 | 
						clip.Set(Y, y)
 | 
				
			||||||
| 
						 | 
					@ -112,39 +116,25 @@ func (clip *insetClip) Set(tag string, value interface{}) bool {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (clip *insetClip) String() string {
 | 
					func (clip *insetClip) String() string {
 | 
				
			||||||
	writer := newRUIWriter()
 | 
						return runStringWriter(clip)
 | 
				
			||||||
	clip.ruiString(writer)
 | 
					 | 
				
			||||||
	return writer.finish()
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (clip *insetClip) ruiString(writer ruiWriter) {
 | 
					func (clip *insetClip) writeString(buffer *strings.Builder, indent string) {
 | 
				
			||||||
	writer.startObject("inset")
 | 
						buffer.WriteString("inset { ")
 | 
				
			||||||
	for _, tag := range []string{Top, Right, Bottom, Left} {
 | 
						comma := false
 | 
				
			||||||
 | 
						for _, tag := range []string{Top, Right, Bottom, Left, Radius} {
 | 
				
			||||||
		if value, ok := clip.properties[tag]; ok {
 | 
							if value, ok := clip.properties[tag]; ok {
 | 
				
			||||||
			switch value := value.(type) {
 | 
								if comma {
 | 
				
			||||||
			case string:
 | 
									buffer.WriteString(", ")
 | 
				
			||||||
				writer.writeProperty(tag, value)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			case fmt.Stringer:
 | 
					 | 
				
			||||||
				writer.writeProperty(tag, value.String())
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								buffer.WriteString(tag)
 | 
				
			||||||
 | 
								buffer.WriteString(" = ")
 | 
				
			||||||
 | 
								writePropertyValue(buffer, tag, value, indent)
 | 
				
			||||||
 | 
								comma = true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if value := clip.Get(Radius); value != nil {
 | 
						buffer.WriteString(" }")
 | 
				
			||||||
		switch value := value.(type) {
 | 
					 | 
				
			||||||
		case RadiusProperty:
 | 
					 | 
				
			||||||
			writer.writeProperty(Radius, value.String())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case SizeUnit:
 | 
					 | 
				
			||||||
			writer.writeProperty(Radius, value.String())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case string:
 | 
					 | 
				
			||||||
			writer.writeProperty(Radius, value)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	writer.endObject()
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (clip *insetClip) cssStyle(session Session) string {
 | 
					func (clip *insetClip) cssStyle(session Session) string {
 | 
				
			||||||
| 
						 | 
					@ -178,83 +168,108 @@ func (clip *insetClip) valid(session Session) bool {
 | 
				
			||||||
	return false
 | 
						return false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (clip *circleClip) Set(tag string, value interface{}) bool {
 | 
				
			||||||
 | 
						if value == nil {
 | 
				
			||||||
 | 
							clip.Remove(tag)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch strings.ToLower(tag) {
 | 
				
			||||||
 | 
						case X, Y, Radius:
 | 
				
			||||||
 | 
							return clip.setSizeProperty(tag, value)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ErrorLogF(`"%s" property is not supported by the circle clip shape`, tag)
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (clip *circleClip) String() string {
 | 
				
			||||||
 | 
						return runStringWriter(clip)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (clip *circleClip) writeString(buffer *strings.Builder, indent string) {
 | 
				
			||||||
 | 
						buffer.WriteString("circle { ")
 | 
				
			||||||
 | 
						comma := false
 | 
				
			||||||
 | 
						for _, tag := range []string{Radius, X, Y} {
 | 
				
			||||||
 | 
							if value, ok := clip.properties[tag]; ok {
 | 
				
			||||||
 | 
								if comma {
 | 
				
			||||||
 | 
									buffer.WriteString(", ")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								buffer.WriteString(tag)
 | 
				
			||||||
 | 
								buffer.WriteString(" = ")
 | 
				
			||||||
 | 
								writePropertyValue(buffer, tag, value, indent)
 | 
				
			||||||
 | 
								comma = true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer.WriteString(" }")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (clip *circleClip) cssStyle(session Session) string {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer := allocStringBuilder()
 | 
				
			||||||
 | 
						defer freeStringBuilder(buffer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer.WriteString("circle(")
 | 
				
			||||||
 | 
						r, _ := sizeProperty(clip, Radius, session)
 | 
				
			||||||
 | 
						buffer.WriteString(r.cssString("50%"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer.WriteString(" at ")
 | 
				
			||||||
 | 
						x, _ := sizeProperty(clip, X, session)
 | 
				
			||||||
 | 
						buffer.WriteString(x.cssString("50%"))
 | 
				
			||||||
 | 
						buffer.WriteRune(' ')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						y, _ := sizeProperty(clip, Y, session)
 | 
				
			||||||
 | 
						buffer.WriteString(y.cssString("50%"))
 | 
				
			||||||
 | 
						buffer.WriteRune(')')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return buffer.String()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (clip *circleClip) valid(session Session) bool {
 | 
				
			||||||
 | 
						if value, ok := sizeProperty(clip, Radius, session); ok && value.Value == 0 {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (clip *ellipseClip) Set(tag string, value interface{}) bool {
 | 
					func (clip *ellipseClip) Set(tag string, value interface{}) bool {
 | 
				
			||||||
	if value == nil {
 | 
						if value == nil {
 | 
				
			||||||
		clip.Remove(tag)
 | 
							clip.Remove(tag)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch strings.ToLower(tag) {
 | 
						switch strings.ToLower(tag) {
 | 
				
			||||||
	case X, Y:
 | 
						case X, Y, RadiusX, RadiusY:
 | 
				
			||||||
		return clip.setSizeProperty(tag, value)
 | 
							return clip.setSizeProperty(tag, value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case Radius:
 | 
						case Radius:
 | 
				
			||||||
		result := clip.setSizeProperty(tag, value)
 | 
							return clip.setSizeProperty(RadiusX, value) &&
 | 
				
			||||||
		if result {
 | 
								clip.setSizeProperty(RadiusY, value)
 | 
				
			||||||
			delete(clip.properties, RadiusX)
 | 
					 | 
				
			||||||
			delete(clip.properties, RadiusY)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return result
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case RadiusX:
 | 
					 | 
				
			||||||
		result := clip.setSizeProperty(tag, value)
 | 
					 | 
				
			||||||
		if result {
 | 
					 | 
				
			||||||
			if r, ok := clip.properties[Radius]; ok {
 | 
					 | 
				
			||||||
				clip.properties[RadiusY] = r
 | 
					 | 
				
			||||||
				delete(clip.properties, Radius)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return result
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case RadiusY:
 | 
					 | 
				
			||||||
		result := clip.setSizeProperty(tag, value)
 | 
					 | 
				
			||||||
		if result {
 | 
					 | 
				
			||||||
			if r, ok := clip.properties[Radius]; ok {
 | 
					 | 
				
			||||||
				clip.properties[RadiusX] = r
 | 
					 | 
				
			||||||
				delete(clip.properties, Radius)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return result
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ErrorLogF(`"%s" property is not supported by the inset clip shape`, tag)
 | 
						ErrorLogF(`"%s" property is not supported by the ellipse clip shape`, tag)
 | 
				
			||||||
	return false
 | 
						return false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (clip *ellipseClip) String() string {
 | 
					func (clip *ellipseClip) String() string {
 | 
				
			||||||
	writer := newRUIWriter()
 | 
						return runStringWriter(clip)
 | 
				
			||||||
	clip.ruiString(writer)
 | 
					 | 
				
			||||||
	return writer.finish()
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (clip *ellipseClip) ruiString(writer ruiWriter) {
 | 
					func (clip *ellipseClip) writeString(buffer *strings.Builder, indent string) {
 | 
				
			||||||
	writeProperty := func(tag string, value interface{}) {
 | 
						buffer.WriteString("ellipse { ")
 | 
				
			||||||
		switch value := value.(type) {
 | 
						comma := false
 | 
				
			||||||
		case string:
 | 
						for _, tag := range []string{RadiusX, RadiusY, X, Y} {
 | 
				
			||||||
			writer.writeProperty(tag, value)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case fmt.Stringer:
 | 
					 | 
				
			||||||
			writer.writeProperty(tag, value.String())
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if r, ok := clip.properties[Radius]; ok {
 | 
					 | 
				
			||||||
		writer.startObject("circle")
 | 
					 | 
				
			||||||
		writeProperty(Radius, r)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		writer.startObject("ellipse")
 | 
					 | 
				
			||||||
		for _, tag := range []string{RadiusX, RadiusY} {
 | 
					 | 
				
			||||||
			if value, ok := clip.properties[tag]; ok {
 | 
					 | 
				
			||||||
				writeProperty(tag, value)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for _, tag := range []string{X, Y} {
 | 
					 | 
				
			||||||
		if value, ok := clip.properties[tag]; ok {
 | 
							if value, ok := clip.properties[tag]; ok {
 | 
				
			||||||
			writeProperty(tag, value)
 | 
								if comma {
 | 
				
			||||||
 | 
									buffer.WriteString(", ")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								buffer.WriteString(tag)
 | 
				
			||||||
 | 
								buffer.WriteString(" = ")
 | 
				
			||||||
 | 
								writePropertyValue(buffer, tag, value, indent)
 | 
				
			||||||
 | 
								comma = true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	writer.endObject()
 | 
					
 | 
				
			||||||
 | 
						buffer.WriteString(" }")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (clip *ellipseClip) cssStyle(session Session) string {
 | 
					func (clip *ellipseClip) cssStyle(session Session) string {
 | 
				
			||||||
| 
						 | 
					@ -262,38 +277,29 @@ func (clip *ellipseClip) cssStyle(session Session) string {
 | 
				
			||||||
	buffer := allocStringBuilder()
 | 
						buffer := allocStringBuilder()
 | 
				
			||||||
	defer freeStringBuilder(buffer)
 | 
						defer freeStringBuilder(buffer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if r, ok := sizeProperty(clip, Radius, session); ok {
 | 
						rx, _ := sizeProperty(clip, RadiusX, session)
 | 
				
			||||||
		buffer.WriteString("circle(")
 | 
						ry, _ := sizeProperty(clip, RadiusX, session)
 | 
				
			||||||
		buffer.WriteString(r.cssString("0"))
 | 
						buffer.WriteString("ellipse(")
 | 
				
			||||||
	} else {
 | 
						buffer.WriteString(rx.cssString("50%"))
 | 
				
			||||||
		rx, _ := sizeProperty(clip, RadiusX, session)
 | 
						buffer.WriteRune(' ')
 | 
				
			||||||
		ry, _ := sizeProperty(clip, RadiusX, session)
 | 
						buffer.WriteString(ry.cssString("50%"))
 | 
				
			||||||
		buffer.WriteString("ellipse(")
 | 
					 | 
				
			||||||
		buffer.WriteString(rx.cssString("0"))
 | 
					 | 
				
			||||||
		buffer.WriteRune(' ')
 | 
					 | 
				
			||||||
		buffer.WriteString(ry.cssString("0"))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	buffer.WriteString(" at ")
 | 
						buffer.WriteString(" at ")
 | 
				
			||||||
	x, _ := sizeProperty(clip, X, session)
 | 
						x, _ := sizeProperty(clip, X, session)
 | 
				
			||||||
	buffer.WriteString(x.cssString("0"))
 | 
						buffer.WriteString(x.cssString("50%"))
 | 
				
			||||||
	buffer.WriteRune(' ')
 | 
						buffer.WriteRune(' ')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	y, _ := sizeProperty(clip, Y, session)
 | 
						y, _ := sizeProperty(clip, Y, session)
 | 
				
			||||||
	buffer.WriteString(y.cssString("0"))
 | 
						buffer.WriteString(y.cssString("50%"))
 | 
				
			||||||
	buffer.WriteRune(')')
 | 
						buffer.WriteRune(')')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return buffer.String()
 | 
						return buffer.String()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (clip *ellipseClip) valid(session Session) bool {
 | 
					func (clip *ellipseClip) valid(session Session) bool {
 | 
				
			||||||
	if value, ok := sizeProperty(clip, Radius, session); ok && value.Type != Auto && value.Value != 0 {
 | 
						rx, _ := sizeProperty(clip, RadiusX, session)
 | 
				
			||||||
		return true
 | 
						ry, _ := sizeProperty(clip, RadiusY, session)
 | 
				
			||||||
	}
 | 
						return rx.Value != 0 && ry.Value != 0
 | 
				
			||||||
 | 
					 | 
				
			||||||
	rx, okX := sizeProperty(clip, RadiusX, session)
 | 
					 | 
				
			||||||
	ry, okY := sizeProperty(clip, RadiusY, session)
 | 
					 | 
				
			||||||
	return okX && okY && rx.Type != Auto && rx.Value != 0 && ry.Type != Auto && ry.Value != 0
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (clip *polygonClip) Get(tag string) interface{} {
 | 
					func (clip *polygonClip) Get(tag string) interface{} {
 | 
				
			||||||
| 
						 | 
					@ -383,47 +389,31 @@ func (clip *polygonClip) AllTags() []string {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (clip *polygonClip) String() string {
 | 
					func (clip *polygonClip) String() string {
 | 
				
			||||||
	writer := newRUIWriter()
 | 
						return runStringWriter(clip)
 | 
				
			||||||
	clip.ruiString(writer)
 | 
					 | 
				
			||||||
	return writer.finish()
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (clip *polygonClip) ruiString(writer ruiWriter) {
 | 
					func (clip *polygonClip) writeString(buffer *strings.Builder, indent string) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	buffer := allocStringBuilder()
 | 
						buffer.WriteString("inset { ")
 | 
				
			||||||
	defer freeStringBuilder(buffer)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	writer.startObject("polygon")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if clip.points != nil {
 | 
						if clip.points != nil {
 | 
				
			||||||
 | 
							buffer.WriteString(Points)
 | 
				
			||||||
 | 
							buffer.WriteString(` = "`)
 | 
				
			||||||
		for i, value := range clip.points {
 | 
							for i, value := range clip.points {
 | 
				
			||||||
			if i > 0 {
 | 
								if i > 0 {
 | 
				
			||||||
				buffer.WriteString(", ")
 | 
									buffer.WriteString(", ")
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			switch value := value.(type) {
 | 
								writePropertyValue(buffer, "", value, indent)
 | 
				
			||||||
			case string:
 | 
					 | 
				
			||||||
				buffer.WriteString(value)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			case fmt.Stringer:
 | 
					 | 
				
			||||||
				buffer.WriteString(value.String())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			default:
 | 
					 | 
				
			||||||
				buffer.WriteString("0px")
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		writer.writeProperty(Points, buffer.String())
 | 
							buffer.WriteString(`" `)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	writer.endObject()
 | 
						buffer.WriteRune('}')
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (clip *polygonClip) cssStyle(session Session) string {
 | 
					func (clip *polygonClip) cssStyle(session Session) string {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if clip.points == nil {
 | 
					 | 
				
			||||||
		return ""
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	count := len(clip.points)
 | 
						count := len(clip.points)
 | 
				
			||||||
	if count < 2 {
 | 
						if count < 2 {
 | 
				
			||||||
		return ""
 | 
							return ""
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -77,7 +77,7 @@ const (
 | 
				
			||||||
type ViewFilter interface {
 | 
					type ViewFilter interface {
 | 
				
			||||||
	Properties
 | 
						Properties
 | 
				
			||||||
	fmt.Stringer
 | 
						fmt.Stringer
 | 
				
			||||||
	ruiStringer
 | 
						stringWriter
 | 
				
			||||||
	cssStyle(session Session) string
 | 
						cssStyle(session Session) string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -155,17 +155,25 @@ func (filter *viewFilter) Set(tag string, value interface{}) bool {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (filter *viewFilter) String() string {
 | 
					func (filter *viewFilter) String() string {
 | 
				
			||||||
	writer := newRUIWriter()
 | 
						return runStringWriter(filter)
 | 
				
			||||||
	filter.ruiString(writer)
 | 
					 | 
				
			||||||
	return writer.finish()
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (filter *viewFilter) ruiString(writer ruiWriter) {
 | 
					func (filter *viewFilter) writeString(buffer *strings.Builder, indent string) {
 | 
				
			||||||
	writer.startObject("filter")
 | 
						buffer.WriteString("filter { ")
 | 
				
			||||||
	for tag, value := range filter.properties {
 | 
						comma := false
 | 
				
			||||||
		writer.writeProperty(tag, value)
 | 
						tags := filter.AllTags()
 | 
				
			||||||
 | 
						for _, tag := range tags {
 | 
				
			||||||
 | 
							if value, ok := filter.properties[tag]; ok {
 | 
				
			||||||
 | 
								if comma {
 | 
				
			||||||
 | 
									buffer.WriteString(", ")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								buffer.WriteString(tag)
 | 
				
			||||||
 | 
								buffer.WriteString(" = ")
 | 
				
			||||||
 | 
								writePropertyValue(buffer, tag, value, indent)
 | 
				
			||||||
 | 
								comma = true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	writer.endObject()
 | 
						buffer.WriteString(" }")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (filter *viewFilter) cssStyle(session Session) string {
 | 
					func (filter *viewFilter) cssStyle(session Session) string {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										405
									
								
								viewStyle.go
								
								
								
								
							
							
						
						
									
										405
									
								
								viewStyle.go
								
								
								
								
							| 
						 | 
					@ -2,6 +2,7 @@ package rui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"sort"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					@ -22,6 +23,10 @@ type Range struct {
 | 
				
			||||||
	First, Last int
 | 
						First, Last int
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type stringWriter interface {
 | 
				
			||||||
 | 
						writeString(buffer *strings.Builder, indent string)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// String returns a string representation of the Range struct
 | 
					// String returns a string representation of the Range struct
 | 
				
			||||||
func (r Range) String() string {
 | 
					func (r Range) String() string {
 | 
				
			||||||
	if r.First == r.Last {
 | 
						if r.First == r.Last {
 | 
				
			||||||
| 
						 | 
					@ -416,3 +421,403 @@ func (style *viewStyle) cssViewStyle(builder cssBuilder, session Session) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func valueToOrientation(value interface{}, session Session) (int, bool) {
 | 
				
			||||||
 | 
						if value != nil {
 | 
				
			||||||
 | 
							switch value := value.(type) {
 | 
				
			||||||
 | 
							case int:
 | 
				
			||||||
 | 
								return value, true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case string:
 | 
				
			||||||
 | 
								text, ok := session.resolveConstants(value)
 | 
				
			||||||
 | 
								if !ok {
 | 
				
			||||||
 | 
									return 0, false
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								text = strings.ToLower(strings.Trim(text, " \t\n\r"))
 | 
				
			||||||
 | 
								switch text {
 | 
				
			||||||
 | 
								case "vertical":
 | 
				
			||||||
 | 
									return TopDownOrientation, true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								case "horizontal":
 | 
				
			||||||
 | 
									return StartToEndOrientation, true
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if result, ok := enumStringToInt(text, enumProperties[Orientation].values, true); ok {
 | 
				
			||||||
 | 
									return result, true
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0, false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (style *viewStyle) Get(tag string) interface{} {
 | 
				
			||||||
 | 
						return style.get(strings.ToLower(tag))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (style *viewStyle) get(tag string) interface{} {
 | 
				
			||||||
 | 
						switch tag {
 | 
				
			||||||
 | 
						case Border, CellBorder:
 | 
				
			||||||
 | 
							return getBorder(&style.propertyList, tag)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case BorderLeft, BorderRight, BorderTop, BorderBottom,
 | 
				
			||||||
 | 
							BorderStyle, BorderLeftStyle, BorderRightStyle, BorderTopStyle, BorderBottomStyle,
 | 
				
			||||||
 | 
							BorderColor, BorderLeftColor, BorderRightColor, BorderTopColor, BorderBottomColor,
 | 
				
			||||||
 | 
							BorderWidth, BorderLeftWidth, BorderRightWidth, BorderTopWidth, BorderBottomWidth:
 | 
				
			||||||
 | 
							if border := getBorder(style, Border); border != nil {
 | 
				
			||||||
 | 
								return border.Get(tag)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case CellBorderLeft, CellBorderRight, CellBorderTop, CellBorderBottom,
 | 
				
			||||||
 | 
							CellBorderStyle, CellBorderLeftStyle, CellBorderRightStyle, CellBorderTopStyle, CellBorderBottomStyle,
 | 
				
			||||||
 | 
							CellBorderColor, CellBorderLeftColor, CellBorderRightColor, CellBorderTopColor, CellBorderBottomColor,
 | 
				
			||||||
 | 
							CellBorderWidth, CellBorderLeftWidth, CellBorderRightWidth, CellBorderTopWidth, CellBorderBottomWidth:
 | 
				
			||||||
 | 
							if border := getBorder(style, CellBorder); border != nil {
 | 
				
			||||||
 | 
								return border.Get(tag)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case RadiusX, RadiusY, RadiusTopLeft, RadiusTopLeftX, RadiusTopLeftY,
 | 
				
			||||||
 | 
							RadiusTopRight, RadiusTopRightX, RadiusTopRightY,
 | 
				
			||||||
 | 
							RadiusBottomLeft, RadiusBottomLeftX, RadiusBottomLeftY,
 | 
				
			||||||
 | 
							RadiusBottomRight, RadiusBottomRightX, RadiusBottomRightY:
 | 
				
			||||||
 | 
							return getRadiusElement(style, tag)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case ColumnSeparator:
 | 
				
			||||||
 | 
							if val, ok := style.properties[ColumnSeparator]; ok {
 | 
				
			||||||
 | 
								return val.(ColumnSeparatorProperty)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case ColumnSeparatorStyle, ColumnSeparatorWidth, ColumnSeparatorColor:
 | 
				
			||||||
 | 
							if val, ok := style.properties[ColumnSeparator]; ok {
 | 
				
			||||||
 | 
								separator := val.(ColumnSeparatorProperty)
 | 
				
			||||||
 | 
								return separator.Get(tag)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case Transition:
 | 
				
			||||||
 | 
							if len(style.transitions) == 0 {
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							result := map[string]Animation{}
 | 
				
			||||||
 | 
							for tag, animation := range style.transitions {
 | 
				
			||||||
 | 
								result[tag] = animation
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return result
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return style.propertyList.getRaw(tag)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (style *viewStyle) AllTags() []string {
 | 
				
			||||||
 | 
						result := style.propertyList.AllTags()
 | 
				
			||||||
 | 
						if len(style.transitions) > 0 {
 | 
				
			||||||
 | 
							result = append(result, Transition)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return result
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func supportedPropertyValue(value interface{}) bool {
 | 
				
			||||||
 | 
						switch value.(type) {
 | 
				
			||||||
 | 
						case string:
 | 
				
			||||||
 | 
						case []string:
 | 
				
			||||||
 | 
						case bool:
 | 
				
			||||||
 | 
						case float32:
 | 
				
			||||||
 | 
						case float64:
 | 
				
			||||||
 | 
						case int:
 | 
				
			||||||
 | 
						case stringWriter:
 | 
				
			||||||
 | 
						case fmt.Stringer:
 | 
				
			||||||
 | 
						case []ViewShadow:
 | 
				
			||||||
 | 
						case []View:
 | 
				
			||||||
 | 
						case []interface{}:
 | 
				
			||||||
 | 
						case map[string]Animation:
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func writePropertyValue(buffer *strings.Builder, tag string, value interface{}, indent string) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeString := func(text string) {
 | 
				
			||||||
 | 
							simple := (tag != Text && tag != Title && tag != Summary)
 | 
				
			||||||
 | 
							if simple {
 | 
				
			||||||
 | 
								if len(text) == 1 {
 | 
				
			||||||
 | 
									simple = (text[0] >= '0' && text[0] <= '9') || (text[0] >= 'A' && text[0] <= 'Z') || (text[0] >= 'a' && text[0] <= 'z')
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									for _, ch := range text {
 | 
				
			||||||
 | 
										if (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') ||
 | 
				
			||||||
 | 
											ch == '+' || ch == '-' || ch == '@' || ch == '/' || ch == '_' || ch == ':' {
 | 
				
			||||||
 | 
										} else {
 | 
				
			||||||
 | 
											simple = false
 | 
				
			||||||
 | 
											break
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if !simple {
 | 
				
			||||||
 | 
								replace := []struct{ old, new string }{
 | 
				
			||||||
 | 
									{old: "\\", new: `\\`},
 | 
				
			||||||
 | 
									{old: "\t", new: `\t`},
 | 
				
			||||||
 | 
									{old: "\r", new: `\r`},
 | 
				
			||||||
 | 
									{old: "\n", new: `\n`},
 | 
				
			||||||
 | 
									{old: "\"", new: `\"`},
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								for _, s := range replace {
 | 
				
			||||||
 | 
									text = strings.Replace(text, s.old, s.new, -1)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								buffer.WriteRune('"')
 | 
				
			||||||
 | 
								buffer.WriteString(text)
 | 
				
			||||||
 | 
								buffer.WriteRune('"')
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								buffer.WriteString(text)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch value := value.(type) {
 | 
				
			||||||
 | 
						case string:
 | 
				
			||||||
 | 
							writeString(value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case []string:
 | 
				
			||||||
 | 
							if len(value) == 0 {
 | 
				
			||||||
 | 
								buffer.WriteString("[]")
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								size := 0
 | 
				
			||||||
 | 
								for _, text := range value {
 | 
				
			||||||
 | 
									size += len(text) + 2
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if size < 80 {
 | 
				
			||||||
 | 
									lead := "["
 | 
				
			||||||
 | 
									for _, text := range value {
 | 
				
			||||||
 | 
										buffer.WriteString(lead)
 | 
				
			||||||
 | 
										writeString(text)
 | 
				
			||||||
 | 
										lead = ", "
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									buffer.WriteString("[\n")
 | 
				
			||||||
 | 
									for _, text := range value {
 | 
				
			||||||
 | 
										buffer.WriteString(indent)
 | 
				
			||||||
 | 
										buffer.WriteRune('\t')
 | 
				
			||||||
 | 
										writeString(text)
 | 
				
			||||||
 | 
										buffer.WriteString(",\n")
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								buffer.WriteString(indent)
 | 
				
			||||||
 | 
								buffer.WriteRune(']')
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case bool:
 | 
				
			||||||
 | 
							if value {
 | 
				
			||||||
 | 
								buffer.WriteString("true")
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								buffer.WriteString("false")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case float32:
 | 
				
			||||||
 | 
							buffer.WriteString(fmt.Sprintf("%g", float64(value)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case float64:
 | 
				
			||||||
 | 
							buffer.WriteString(fmt.Sprintf("%g", value))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case int:
 | 
				
			||||||
 | 
							if prop, ok := enumProperties[tag]; ok && value >= 0 && value < len(prop.values) {
 | 
				
			||||||
 | 
								buffer.WriteString(prop.values[value])
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								buffer.WriteString(strconv.Itoa(value))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case stringWriter:
 | 
				
			||||||
 | 
							value.writeString(buffer, indent+"\t")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case fmt.Stringer:
 | 
				
			||||||
 | 
							buffer.WriteString(value.String())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case []ViewShadow:
 | 
				
			||||||
 | 
							switch len(value) {
 | 
				
			||||||
 | 
							case 0:
 | 
				
			||||||
 | 
								// do nothing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case 1:
 | 
				
			||||||
 | 
								value[0].writeString(buffer, indent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								buffer.WriteString("[")
 | 
				
			||||||
 | 
								indent2 := "\n" + indent + "\t"
 | 
				
			||||||
 | 
								for _, shadow := range value {
 | 
				
			||||||
 | 
									buffer.WriteString(indent2)
 | 
				
			||||||
 | 
									shadow.writeString(buffer, indent)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								buffer.WriteRune('\n')
 | 
				
			||||||
 | 
								buffer.WriteString(indent)
 | 
				
			||||||
 | 
								buffer.WriteRune(']')
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case []View:
 | 
				
			||||||
 | 
							switch len(value) {
 | 
				
			||||||
 | 
							case 0:
 | 
				
			||||||
 | 
								buffer.WriteString("[]\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case 1:
 | 
				
			||||||
 | 
								writeViewStyle(value[0].Tag(), value[0], buffer, indent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								buffer.WriteString("[\n")
 | 
				
			||||||
 | 
								indent2 := indent + "\t"
 | 
				
			||||||
 | 
								for _, v := range value {
 | 
				
			||||||
 | 
									buffer.WriteString(indent2)
 | 
				
			||||||
 | 
									writeViewStyle(v.Tag(), v, buffer, indent2)
 | 
				
			||||||
 | 
									buffer.WriteString(",\n")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								buffer.WriteString(indent)
 | 
				
			||||||
 | 
								buffer.WriteRune(']')
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case []interface{}:
 | 
				
			||||||
 | 
							switch count := len(value); count {
 | 
				
			||||||
 | 
							case 0:
 | 
				
			||||||
 | 
								buffer.WriteString("[]")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case 1:
 | 
				
			||||||
 | 
								writePropertyValue(buffer, tag, value[0], indent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								buffer.WriteString("[ ")
 | 
				
			||||||
 | 
								comma := false
 | 
				
			||||||
 | 
								for _, v := range value {
 | 
				
			||||||
 | 
									if comma {
 | 
				
			||||||
 | 
										buffer.WriteString(", ")
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									writePropertyValue(buffer, tag, v, indent)
 | 
				
			||||||
 | 
									comma = true
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								buffer.WriteString(" ]")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case map[string]Animation:
 | 
				
			||||||
 | 
							switch count := len(value); count {
 | 
				
			||||||
 | 
							case 0:
 | 
				
			||||||
 | 
								buffer.WriteString("[]")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case 1:
 | 
				
			||||||
 | 
								for tag, animation := range value {
 | 
				
			||||||
 | 
									animation.writeTransitionString(tag, buffer)
 | 
				
			||||||
 | 
									break
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								tags := make([]string, 0, len(value))
 | 
				
			||||||
 | 
								for tag := range value {
 | 
				
			||||||
 | 
									tags = append(tags, tag)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								sort.Strings(tags)
 | 
				
			||||||
 | 
								buffer.WriteString("[\n")
 | 
				
			||||||
 | 
								indent2 := indent + "\t"
 | 
				
			||||||
 | 
								for _, tag := range tags {
 | 
				
			||||||
 | 
									if animation := value[tag]; animation != nil {
 | 
				
			||||||
 | 
										buffer.WriteString(indent2)
 | 
				
			||||||
 | 
										animation.writeTransitionString(tag, buffer)
 | 
				
			||||||
 | 
										buffer.WriteString("\n")
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								buffer.WriteString(indent)
 | 
				
			||||||
 | 
								buffer.WriteRune(']')
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func writeViewStyle(name string, view ViewStyle, buffer *strings.Builder, indent string) {
 | 
				
			||||||
 | 
						buffer.WriteString(name)
 | 
				
			||||||
 | 
						buffer.WriteString(" {\n")
 | 
				
			||||||
 | 
						indent += "\t"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeProperty := func(tag string, value interface{}) {
 | 
				
			||||||
 | 
							if supportedPropertyValue(value) {
 | 
				
			||||||
 | 
								buffer.WriteString(indent)
 | 
				
			||||||
 | 
								buffer.WriteString(tag)
 | 
				
			||||||
 | 
								buffer.WriteString(" = ")
 | 
				
			||||||
 | 
								writePropertyValue(buffer, tag, value, indent)
 | 
				
			||||||
 | 
								buffer.WriteString(",\n")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tags := view.AllTags()
 | 
				
			||||||
 | 
						removeTag := func(tag string) {
 | 
				
			||||||
 | 
							for i, t := range tags {
 | 
				
			||||||
 | 
								if t == tag {
 | 
				
			||||||
 | 
									if i == 0 {
 | 
				
			||||||
 | 
										tags = tags[1:]
 | 
				
			||||||
 | 
									} else if i == len(tags)-1 {
 | 
				
			||||||
 | 
										tags = tags[:i]
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										tags = append(tags[:i], tags[i+1:]...)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tagOrder := []string{
 | 
				
			||||||
 | 
							ID, Row, Column, Top, Right, Bottom, Left, Semantics, Cursor, Visibility,
 | 
				
			||||||
 | 
							Opacity, ZIndex, Width, Height, MinWidth, MinHeight, MaxWidth, MaxHeight,
 | 
				
			||||||
 | 
							Margin, Padding, BackgroundClip, BackgroundColor, Background, Border, Radius, Outline, Shadow,
 | 
				
			||||||
 | 
							Orientation, Wrap, VerticalAlign, HorizontalAlign, CellWidth, CellHeight,
 | 
				
			||||||
 | 
							CellVerticalAlign, CellHorizontalAlign, GridRowGap, GridColumnGap,
 | 
				
			||||||
 | 
							ColumnCount, ColumnWidth, ColumnSeparator, ColumnGap, AvoidBreak,
 | 
				
			||||||
 | 
							Current, Expanded, Side, ResizeBorderWidth, EditViewType, MaxLength, Hint, Text,
 | 
				
			||||||
 | 
							TextOverflow, FontName, TextSize, TextColor, TextWeight, Italic, SmallCaps,
 | 
				
			||||||
 | 
							Strikethrough, Overline, Underline, TextLineStyle, TextLineThickness,
 | 
				
			||||||
 | 
							TextLineColor, TextTransform, TextAlign, WhiteSpace, WordBreak, TextShadow, TextIndent,
 | 
				
			||||||
 | 
							LetterSpacing, WordSpacing, LineHeight, TextDirection, WritingMode, VerticalTextOrientation,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, tag := range tagOrder {
 | 
				
			||||||
 | 
							if value := view.Get(tag); value != nil {
 | 
				
			||||||
 | 
								removeTag(tag)
 | 
				
			||||||
 | 
								writeProperty(tag, value)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						finalTags := []string{
 | 
				
			||||||
 | 
							Perspective, PerspectiveOriginX, PerspectiveOriginY, BackfaceVisible, OriginX, OriginY, OriginZ,
 | 
				
			||||||
 | 
							TranslateX, TranslateY, TranslateZ, ScaleX, ScaleY, ScaleZ, Rotate, RotateX, RotateY, RotateZ,
 | 
				
			||||||
 | 
							SkewX, SkewY, Clip, Filter, Summary, Content, Transition}
 | 
				
			||||||
 | 
						for _, tag := range finalTags {
 | 
				
			||||||
 | 
							removeTag(tag)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, tag := range tags {
 | 
				
			||||||
 | 
							if value := view.Get(tag); value != nil {
 | 
				
			||||||
 | 
								writeProperty(tag, value)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, tag := range finalTags {
 | 
				
			||||||
 | 
							if value := view.Get(tag); value != nil {
 | 
				
			||||||
 | 
								writeProperty(tag, value)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						indent = indent[:len(indent)-1]
 | 
				
			||||||
 | 
						buffer.WriteString(indent)
 | 
				
			||||||
 | 
						buffer.WriteString("}")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getViewString(view View) string {
 | 
				
			||||||
 | 
						buffer := allocStringBuilder()
 | 
				
			||||||
 | 
						defer freeStringBuilder(buffer)
 | 
				
			||||||
 | 
						writeViewStyle(view.Tag(), view, buffer, "")
 | 
				
			||||||
 | 
						return buffer.String()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func runStringWriter(writer stringWriter) string {
 | 
				
			||||||
 | 
						buffer := allocStringBuilder()
 | 
				
			||||||
 | 
						defer freeStringBuilder(buffer)
 | 
				
			||||||
 | 
						writer.writeString(buffer, "")
 | 
				
			||||||
 | 
						return buffer.String()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,89 +0,0 @@
 | 
				
			||||||
package rui
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func valueToOrientation(value interface{}, session Session) (int, bool) {
 | 
					 | 
				
			||||||
	if value != nil {
 | 
					 | 
				
			||||||
		switch value := value.(type) {
 | 
					 | 
				
			||||||
		case int:
 | 
					 | 
				
			||||||
			return value, true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case string:
 | 
					 | 
				
			||||||
			text, ok := session.resolveConstants(value)
 | 
					 | 
				
			||||||
			if !ok {
 | 
					 | 
				
			||||||
				return 0, false
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			text = strings.ToLower(strings.Trim(text, " \t\n\r"))
 | 
					 | 
				
			||||||
			switch text {
 | 
					 | 
				
			||||||
			case "vertical":
 | 
					 | 
				
			||||||
				return TopDownOrientation, true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			case "horizontal":
 | 
					 | 
				
			||||||
				return StartToEndOrientation, true
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if result, ok := enumStringToInt(text, enumProperties[Orientation].values, true); ok {
 | 
					 | 
				
			||||||
				return result, true
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return 0, false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
func getOrientation(style Properties, session Session) (int, bool) {
 | 
					 | 
				
			||||||
	return valueToOrientation(style.Get(Orientation), session)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
func (style *viewStyle) Get(tag string) interface{} {
 | 
					 | 
				
			||||||
	return style.get(strings.ToLower(tag))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (style *viewStyle) get(tag string) interface{} {
 | 
					 | 
				
			||||||
	switch tag {
 | 
					 | 
				
			||||||
	case Border, CellBorder:
 | 
					 | 
				
			||||||
		return getBorder(&style.propertyList, tag)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case BorderLeft, BorderRight, BorderTop, BorderBottom,
 | 
					 | 
				
			||||||
		BorderStyle, BorderLeftStyle, BorderRightStyle, BorderTopStyle, BorderBottomStyle,
 | 
					 | 
				
			||||||
		BorderColor, BorderLeftColor, BorderRightColor, BorderTopColor, BorderBottomColor,
 | 
					 | 
				
			||||||
		BorderWidth, BorderLeftWidth, BorderRightWidth, BorderTopWidth, BorderBottomWidth:
 | 
					 | 
				
			||||||
		if border := getBorder(style, Border); border != nil {
 | 
					 | 
				
			||||||
			return border.Get(tag)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case CellBorderLeft, CellBorderRight, CellBorderTop, CellBorderBottom,
 | 
					 | 
				
			||||||
		CellBorderStyle, CellBorderLeftStyle, CellBorderRightStyle, CellBorderTopStyle, CellBorderBottomStyle,
 | 
					 | 
				
			||||||
		CellBorderColor, CellBorderLeftColor, CellBorderRightColor, CellBorderTopColor, CellBorderBottomColor,
 | 
					 | 
				
			||||||
		CellBorderWidth, CellBorderLeftWidth, CellBorderRightWidth, CellBorderTopWidth, CellBorderBottomWidth:
 | 
					 | 
				
			||||||
		if border := getBorder(style, CellBorder); border != nil {
 | 
					 | 
				
			||||||
			return border.Get(tag)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case RadiusX, RadiusY, RadiusTopLeft, RadiusTopLeftX, RadiusTopLeftY,
 | 
					 | 
				
			||||||
		RadiusTopRight, RadiusTopRightX, RadiusTopRightY,
 | 
					 | 
				
			||||||
		RadiusBottomLeft, RadiusBottomLeftX, RadiusBottomLeftY,
 | 
					 | 
				
			||||||
		RadiusBottomRight, RadiusBottomRightX, RadiusBottomRightY:
 | 
					 | 
				
			||||||
		return getRadiusElement(style, tag)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case ColumnSeparator:
 | 
					 | 
				
			||||||
		if val, ok := style.properties[ColumnSeparator]; ok {
 | 
					 | 
				
			||||||
			return val.(ColumnSeparatorProperty)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case ColumnSeparatorStyle, ColumnSeparatorWidth, ColumnSeparatorColor:
 | 
					 | 
				
			||||||
		if val, ok := style.properties[ColumnSeparator]; ok {
 | 
					 | 
				
			||||||
			separator := val.(ColumnSeparatorProperty)
 | 
					 | 
				
			||||||
			return separator.Get(tag)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return style.propertyList.getRaw(tag)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -271,12 +271,13 @@ func (style *viewStyle) set(tag string, value interface{}) bool {
 | 
				
			||||||
	case Transition:
 | 
						case Transition:
 | 
				
			||||||
		setObject := func(obj DataObject) bool {
 | 
							setObject := func(obj DataObject) bool {
 | 
				
			||||||
			if obj != nil {
 | 
								if obj != nil {
 | 
				
			||||||
				switch obj.Tag() {
 | 
									tag := strings.ToLower(tag)
 | 
				
			||||||
 | 
									switch tag {
 | 
				
			||||||
				case "", "_":
 | 
									case "", "_":
 | 
				
			||||||
					ErrorLog("Invalid transition property name")
 | 
										ErrorLog("Invalid transition property name")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				default:
 | 
									default:
 | 
				
			||||||
					style.transitions[obj.Tag()] = parseAnimation(obj)
 | 
										style.transitions[tag] = parseAnimation(obj)
 | 
				
			||||||
					return true
 | 
										return true
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					@ -285,18 +286,19 @@ func (style *viewStyle) set(tag string, value interface{}) bool {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		switch value := value.(type) {
 | 
							switch value := value.(type) {
 | 
				
			||||||
		case Params:
 | 
							case Params:
 | 
				
			||||||
			result := false
 | 
								result := true
 | 
				
			||||||
			for tag, val := range value {
 | 
								for tag, val := range value {
 | 
				
			||||||
				if animation, ok := val.(Animation); ok {
 | 
									tag = strings.ToLower(strings.Trim(tag, " \t"))
 | 
				
			||||||
					tag = strings.ToLower(tag)
 | 
									if tag == "" {
 | 
				
			||||||
					if animation == nil || tag == "" {
 | 
										ErrorLog("Invalid transition property name")
 | 
				
			||||||
						ErrorLog("Invalid transition property name")
 | 
										result = false
 | 
				
			||||||
					} else {
 | 
									} else if val == nil {
 | 
				
			||||||
						style.transitions[tag] = animation
 | 
										delete(style.transitions, tag)
 | 
				
			||||||
						result = true
 | 
									} else if animation, ok := val.(Animation); ok {
 | 
				
			||||||
					}
 | 
										style.transitions[tag] = animation
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					notCompatibleType(Transition, val)
 | 
										notCompatibleType(Transition, val)
 | 
				
			||||||
 | 
										result = false
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return result
 | 
								return result
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,131 +0,0 @@
 | 
				
			||||||
package rui
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
	"testing"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestViewStyleCreate(t *testing.T) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	app := new(application)
 | 
					 | 
				
			||||||
	app.init("")
 | 
					 | 
				
			||||||
	session := newSession(app, 1, "", false, false)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var style viewStyle
 | 
					 | 
				
			||||||
	style.init()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	data := []struct{ property, value string }{
 | 
					 | 
				
			||||||
		{Width, "100%"},
 | 
					 | 
				
			||||||
		{Height, "400px"},
 | 
					 | 
				
			||||||
		{Margin, "4px"},
 | 
					 | 
				
			||||||
		{Margin + "-bottom", "auto"},
 | 
					 | 
				
			||||||
		{Padding, "1em"},
 | 
					 | 
				
			||||||
		{Font, "Arial"},
 | 
					 | 
				
			||||||
		{BackgroundColor, "#FF008000"},
 | 
					 | 
				
			||||||
		{TextColor, "#FF000000"},
 | 
					 | 
				
			||||||
		{TextSize, "1.25em"},
 | 
					 | 
				
			||||||
		{TextWeight, "bold"},
 | 
					 | 
				
			||||||
		{TextAlign, "center"},
 | 
					 | 
				
			||||||
		{TextTransform, "uppercase"},
 | 
					 | 
				
			||||||
		{TextIndent, "0.25em"},
 | 
					 | 
				
			||||||
		{LetterSpacing, "1.5em"},
 | 
					 | 
				
			||||||
		{WordSpacing, "8px"},
 | 
					 | 
				
			||||||
		{LineHeight, "2em"},
 | 
					 | 
				
			||||||
		{Italic, "on"},
 | 
					 | 
				
			||||||
		{TextDecoration, "strikethrough | overline | underline"},
 | 
					 | 
				
			||||||
		{SmallCaps, "on"},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for _, prop := range data {
 | 
					 | 
				
			||||||
		style.Set(prop.property, prop.value)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	style.AddShadow(NewViewShadow(SizeUnit{Auto, 0}, SizeUnit{Auto, 0}, Px(4), Px(6), 0xFF808080))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	expected := `width: 100%; height: 400px; font-size: 1.25rem; text-indent: 0.25rem; letter-spacing: 1.5rem; word-spacing: 8px; ` +
 | 
					 | 
				
			||||||
		`line-height: 2rem; padding: 1rem; margin-left: 4px; margin-top: 4px; margin-right: 4px; box-shadow: 0 0 4px 6px rgb(128,128,128); ` +
 | 
					 | 
				
			||||||
		`background-color: rgb(0,128,0); color: rgb(0,0,0); font-family: Arial; font-weight: bold; font-style: italic; font-variant: small-caps; ` +
 | 
					 | 
				
			||||||
		`text-align: center; text-decoration: line-through overline underline; text-transform: uppercase;`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	buffer := strings.Builder{}
 | 
					 | 
				
			||||||
	style.cssViewStyle(&buffer, session)
 | 
					 | 
				
			||||||
	if text := strings.Trim(buffer.String(), " "); text != expected {
 | 
					 | 
				
			||||||
		t.Error("\nresult  : " + text + "\nexpected: " + expected)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		w := newCompactDataWriter()
 | 
					 | 
				
			||||||
		w.StartObject("_")
 | 
					 | 
				
			||||||
		style.writeStyle(w)
 | 
					 | 
				
			||||||
		w.FinishObject()
 | 
					 | 
				
			||||||
		expected2 := `_{width=100%,height=400px,margin="4px,4px,auto,4px",padding=1em,background-color=#FF008000,shadow=_{color=#FF808080,blur=4px,spread-radius=6px},font=Arial,text-color=#FF000000,text-size=1.25em,text-weight=bold,italic=on,small-caps=on,text-decoration=strikethrough|overline|underline,text-align=center,text-indent=0.25em,letter-spacing=1.5em,word-spacing=8px,line-height=2em,text-transform=uppercase}`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if text := w.String(); text != expected2 {
 | 
					 | 
				
			||||||
			t.Error("\n result: " + text + "\nexpected: " + expected2)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		var style1 viewStyle
 | 
					 | 
				
			||||||
		style1.init()
 | 
					 | 
				
			||||||
		if obj, err := ParseDataText(expected2); err == nil {
 | 
					 | 
				
			||||||
			style1.parseStyle(obj, new(sessionData))
 | 
					 | 
				
			||||||
			buffer.Reset()
 | 
					 | 
				
			||||||
			style.cssStyle(&buffer)
 | 
					 | 
				
			||||||
			if text := buffer.String(); text != expected {
 | 
					 | 
				
			||||||
				t.Error("\n result: " + text + "\nexpected: " + expected)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			t.Error(err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		var style2 viewStyle
 | 
					 | 
				
			||||||
		style2.init()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		style2.textWeight = 4
 | 
					 | 
				
			||||||
		style2.textAlign = RightAlign
 | 
					 | 
				
			||||||
		style2.textTransform = LowerCaseTextTransform
 | 
					 | 
				
			||||||
		style2.textDecoration = NoneDecoration
 | 
					 | 
				
			||||||
		style2.italic = Off
 | 
					 | 
				
			||||||
		style2.smallCaps = Off
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		expected = `font-weight: normal; font-style: normal; font-variant: normal; text-align: right; text-decoration: none; text-transform: lowercase; `
 | 
					 | 
				
			||||||
		buffer.Reset()
 | 
					 | 
				
			||||||
		style2.cssStyle(&buffer)
 | 
					 | 
				
			||||||
		if text := buffer.String(); text != expected {
 | 
					 | 
				
			||||||
			t.Error("\n result: " + text + "\nexpected: " + expected)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		w.Reset()
 | 
					 | 
				
			||||||
		w.StartObject("_")
 | 
					 | 
				
			||||||
		style2.writeStyle(w)
 | 
					 | 
				
			||||||
		w.FinishObject()
 | 
					 | 
				
			||||||
		expected = `_{text-weight=normal,italic=off,small-caps=off,text-decoration=none,text-align=right,text-transform=lowercase}`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if text := w.String(); text != expected {
 | 
					 | 
				
			||||||
			t.Error("\n result: " + text + "\nexpected: " + expected)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		style2.textWeight = 5
 | 
					 | 
				
			||||||
		style2.textAlign = JustifyTextAlign
 | 
					 | 
				
			||||||
		style2.textTransform = CapitalizeTextTransform
 | 
					 | 
				
			||||||
		style2.textDecoration = Inherit
 | 
					 | 
				
			||||||
		style2.italic = Inherit
 | 
					 | 
				
			||||||
		style2.smallCaps = Inherit
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		expected = `font-weight: 500; text-align: justify; text-transform: capitalize; `
 | 
					 | 
				
			||||||
		buffer.Reset()
 | 
					 | 
				
			||||||
		style2.cssStyle(&buffer)
 | 
					 | 
				
			||||||
		if text := buffer.String(); text != expected {
 | 
					 | 
				
			||||||
			t.Error("\n  result: " + text + "\nexpected: " + expected)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		w.Reset()
 | 
					 | 
				
			||||||
		w.StartObject("_")
 | 
					 | 
				
			||||||
		style2.writeStyle(w)
 | 
					 | 
				
			||||||
		w.FinishObject()
 | 
					 | 
				
			||||||
		expected = `_{text-weight=5,text-align=justify,text-transform=capitalize}`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if text := w.String(); text != expected {
 | 
					 | 
				
			||||||
			t.Error("\n  result: " + text + "\nexpected: " + expected)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
| 
						 | 
					@ -31,6 +31,10 @@ func (container *viewsContainerData) Init(session Session) {
 | 
				
			||||||
	container.views = []View{}
 | 
						container.views = []View{}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (container *viewsContainerData) String() string {
 | 
				
			||||||
 | 
						return getViewString(container)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (container *viewsContainerData) setParentID(parentID string) {
 | 
					func (container *viewsContainerData) setParentID(parentID string) {
 | 
				
			||||||
	container.viewData.setParentID(parentID)
 | 
						container.viewData.setParentID(parentID)
 | 
				
			||||||
	htmlID := container.htmlID()
 | 
						htmlID := container.htmlID()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue