forked from mbk-lab/rui_orig
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