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 {
|
||||
Properties
|
||||
fmt.Stringer
|
||||
ruiStringer
|
||||
writeTransitionString(tag string, buffer *strings.Builder)
|
||||
animationCSS(session Session) string
|
||||
transitionCSS(buffer *strings.Builder, session Session)
|
||||
hasAnimatedPropery() bool
|
||||
|
@ -176,13 +176,21 @@ func (animation *animationData) animationName() string {
|
|||
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 {
|
||||
if value == nil {
|
||||
animation.Remove(tag)
|
||||
return true
|
||||
}
|
||||
|
||||
switch tag = strings.ToLower(tag); tag {
|
||||
switch tag = animation.normalizeTag(tag); tag {
|
||||
case ID:
|
||||
if text, ok := value.(string); ok {
|
||||
text = strings.Trim(text, " \t\n\r")
|
||||
|
@ -337,7 +345,7 @@ func (animation *animationData) Set(tag string, value interface{}) bool {
|
|||
case IterationCount:
|
||||
return animation.setIntProperty(tag, value)
|
||||
|
||||
case AnimationDirection, Direction:
|
||||
case AnimationDirection:
|
||||
return animation.setEnumProperty(AnimationDirection, value, enumProperties[AnimationDirection].values)
|
||||
|
||||
default:
|
||||
|
@ -348,31 +356,23 @@ func (animation *animationData) Set(tag string, value interface{}) bool {
|
|||
}
|
||||
|
||||
func (animation *animationData) Remove(tag string) {
|
||||
tag = strings.ToLower(tag)
|
||||
if tag == Direction {
|
||||
tag = AnimationDirection
|
||||
}
|
||||
delete(animation.properties, tag)
|
||||
delete(animation.properties, animation.normalizeTag(tag))
|
||||
}
|
||||
|
||||
func (animation *animationData) Get(tag string) interface{} {
|
||||
tag = strings.ToLower(tag)
|
||||
if tag == Direction {
|
||||
tag = AnimationDirection
|
||||
}
|
||||
return animation.getRaw(tag)
|
||||
return animation.getRaw(animation.normalizeTag(tag))
|
||||
}
|
||||
|
||||
func (animation *animationData) String() string {
|
||||
writer := newRUIWriter()
|
||||
animation.ruiString(writer)
|
||||
return writer.finish()
|
||||
}
|
||||
buffer := allocStringBuilder()
|
||||
defer freeStringBuilder(buffer)
|
||||
|
||||
buffer.WriteString("animation {")
|
||||
|
||||
func (animation *animationData) ruiString(writer ruiWriter) {
|
||||
writer.startObject("animation")
|
||||
// TODO
|
||||
writer.endObject()
|
||||
|
||||
buffer.WriteString("}")
|
||||
return buffer.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 {
|
||||
if timingFunction, ok := stringProperty(animation, TimingFunction, session); ok {
|
||||
if timingFunction, ok = session.resolveConstants(timingFunction); ok && validateTimingFunction(timingFunction) {
|
||||
|
|
|
@ -26,6 +26,10 @@ func (player *audioPlayerData) Init(session Session) {
|
|||
player.tag = "AudioPlayer"
|
||||
}
|
||||
|
||||
func (player *audioPlayerData) String() string {
|
||||
return getViewString(player)
|
||||
}
|
||||
|
||||
func (player *audioPlayerData) htmlTag() string {
|
||||
return "audio"
|
||||
}
|
||||
|
|
44
border.go
44
border.go
|
@ -48,8 +48,8 @@ const (
|
|||
// BorderProperty is the interface of a view border data
|
||||
type BorderProperty interface {
|
||||
Properties
|
||||
ruiStringer
|
||||
fmt.Stringer
|
||||
stringWriter
|
||||
ViewBorders(session Session) ViewBorders
|
||||
delete(tag string)
|
||||
cssStyle(builder cssBuilder, session Session)
|
||||
|
@ -202,12 +202,23 @@ func (border *borderProperty) normalizeTag(tag string) string {
|
|||
return tag
|
||||
}
|
||||
|
||||
func (border *borderProperty) ruiString(writer ruiWriter) {
|
||||
writer.startObject("_")
|
||||
func (border *borderProperty) writeString(buffer *strings.Builder, indent string) {
|
||||
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} {
|
||||
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]
|
||||
color, okColor := border.properties[side+"-"+ColorTag]
|
||||
if okStyle || okWidth || okColor {
|
||||
writer.startObjectProperty(side, "_")
|
||||
if comma {
|
||||
buffer.WriteString(", ")
|
||||
comma = false
|
||||
}
|
||||
|
||||
buffer.WriteString(side)
|
||||
buffer.WriteString(" = _{ ")
|
||||
if okStyle {
|
||||
writer.writeProperty(Style, style)
|
||||
write(Style, style)
|
||||
}
|
||||
if okWidth {
|
||||
writer.writeProperty(Width, width)
|
||||
write(Width, width)
|
||||
}
|
||||
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 {
|
||||
writer := newRUIWriter()
|
||||
border.ruiString(writer)
|
||||
return writer.finish()
|
||||
return runStringWriter(border)
|
||||
}
|
||||
|
||||
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
|
||||
type BoundsProperty interface {
|
||||
Properties
|
||||
ruiStringer
|
||||
fmt.Stringer
|
||||
stringWriter
|
||||
Bounds(session Session) Bounds
|
||||
}
|
||||
|
||||
|
@ -54,22 +54,25 @@ func (bounds *boundsPropertyData) normalizeTag(tag string) string {
|
|||
return tag
|
||||
}
|
||||
|
||||
func (bounds *boundsPropertyData) ruiString(writer ruiWriter) {
|
||||
writer.startObject("_")
|
||||
|
||||
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 {
|
||||
return runStringWriter(bounds)
|
||||
}
|
||||
|
||||
func (bounds *boundsPropertyData) String() string {
|
||||
writer := newRUIWriter()
|
||||
bounds.ruiString(writer)
|
||||
return writer.finish()
|
||||
func (bounds *boundsPropertyData) writeString(buffer *strings.Builder, indent string) {
|
||||
buffer.WriteString("_{ ")
|
||||
comma := false
|
||||
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) {
|
||||
|
@ -135,50 +138,6 @@ func (bounds *Bounds) SetAll(value SizeUnit) {
|
|||
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) {
|
||||
bounds.Top = AutoSize()
|
||||
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 {
|
||||
return bounds.Left.Type == Auto &&
|
||||
bounds.Top.Type == Auto &&
|
||||
|
@ -209,7 +169,6 @@ func (bounds *Bounds) allFieldsAuto() bool {
|
|||
bounds.Bottom.Type == Auto
|
||||
}
|
||||
|
||||
/*
|
||||
func (bounds *Bounds) allFieldsZero() bool {
|
||||
return (bounds.Left.Type == Auto || bounds.Left.Value == 0) &&
|
||||
(bounds.Top.Type == Auto || bounds.Top.Value == 0) &&
|
||||
|
@ -231,6 +190,7 @@ func (bounds *Bounds) allFieldsEqual() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
/*
|
||||
func (bounds Bounds) writeCSSString(buffer *strings.Builder, textForAuto string) {
|
||||
buffer.WriteString(bounds.Top.cssString(textForAuto))
|
||||
if !bounds.allFieldsEqual() {
|
||||
|
@ -242,6 +202,7 @@ func (bounds Bounds) writeCSSString(buffer *strings.Builder, textForAuto string)
|
|||
buffer.WriteString(bounds.Left.cssString(textForAuto))
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// String convert Bounds to string
|
||||
func (bounds *Bounds) String() string {
|
||||
|
|
|
@ -36,6 +36,10 @@ func (canvasView *canvasViewData) Init(session Session) {
|
|||
canvasView.tag = "CanvasView"
|
||||
}
|
||||
|
||||
func (canvasView *canvasViewData) String() string {
|
||||
return getViewString(canvasView)
|
||||
}
|
||||
|
||||
func (canvasView *canvasViewData) normalizeTag(tag string) string {
|
||||
tag = strings.ToLower(tag)
|
||||
switch tag {
|
||||
|
|
|
@ -43,6 +43,10 @@ func (button *checkboxData) Init(session Session) {
|
|||
button.checkedListeners = []func(Checkbox, bool){}
|
||||
}
|
||||
|
||||
func (button *checkboxData) String() string {
|
||||
return getViewString(button)
|
||||
}
|
||||
|
||||
func (button *checkboxData) Focusable() bool {
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -39,6 +39,10 @@ func (picker *colorPickerData) Init(session Session) {
|
|||
picker.properties[Padding] = Px(0)
|
||||
}
|
||||
|
||||
func (picker *colorPickerData) String() string {
|
||||
return getViewString(picker)
|
||||
}
|
||||
|
||||
func (picker *colorPickerData) normalizeTag(tag string) string {
|
||||
tag = strings.ToLower(tag)
|
||||
switch tag {
|
||||
|
|
|
@ -63,6 +63,10 @@ func (ColumnLayout *columnLayoutData) Init(session Session) {
|
|||
//ColumnLayout.systemClass = "ruiColumnLayout"
|
||||
}
|
||||
|
||||
func (columnLayout *columnLayoutData) String() string {
|
||||
return getViewString(columnLayout)
|
||||
}
|
||||
|
||||
func (columnLayout *columnLayoutData) normalizeTag(tag string) string {
|
||||
tag = strings.ToLower(tag)
|
||||
switch tag {
|
||||
|
|
|
@ -8,8 +8,8 @@ import (
|
|||
// ColumnSeparatorProperty is the interface of a view separator data
|
||||
type ColumnSeparatorProperty interface {
|
||||
Properties
|
||||
ruiStringer
|
||||
fmt.Stringer
|
||||
stringWriter
|
||||
ViewBorder(session Session) ViewBorder
|
||||
cssValue(session Session) string
|
||||
}
|
||||
|
@ -84,20 +84,26 @@ func (separator *columnSeparatorProperty) normalizeTag(tag string) string {
|
|||
return tag
|
||||
}
|
||||
|
||||
func (separator *columnSeparatorProperty) ruiString(writer ruiWriter) {
|
||||
writer.startObject("_")
|
||||
func (separator *columnSeparatorProperty) writeString(buffer *strings.Builder, indent string) {
|
||||
buffer.WriteString("_{ ")
|
||||
comma := false
|
||||
for _, tag := range []string{Style, Width, ColorTag} {
|
||||
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 {
|
||||
writer := newRUIWriter()
|
||||
separator.ruiString(writer)
|
||||
return writer.finish()
|
||||
return runStringWriter(separator)
|
||||
}
|
||||
|
||||
func (separator *columnSeparatorProperty) Remove(tag string) {
|
||||
|
|
|
@ -91,6 +91,10 @@ func (customView *CustomViewData) Clear() {
|
|||
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
|
||||
func (customView *CustomViewData) Session() Session {
|
||||
return customView.superView.Session()
|
||||
|
@ -249,19 +253,11 @@ func (customView *CustomViewData) RemoveView(index int) View {
|
|||
|
||||
func (customView *CustomViewData) String() string {
|
||||
if customView.superView != nil {
|
||||
writer := newRUIWriter()
|
||||
customView.ruiString(writer)
|
||||
return writer.finish()
|
||||
return getViewString(customView)
|
||||
}
|
||||
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) {
|
||||
if customView.superView != nil {
|
||||
customView.superView.setScroll(x, y, width, height)
|
||||
|
|
|
@ -44,6 +44,10 @@ func (picker *datePickerData) Init(session Session) {
|
|||
picker.dateChangedListeners = []func(DatePicker, time.Time){}
|
||||
}
|
||||
|
||||
func (picker *datePickerData) String() string {
|
||||
return getViewString(picker)
|
||||
}
|
||||
|
||||
func (picker *datePickerData) Focusable() bool {
|
||||
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:
|
||||
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 {
|
||||
switch value := value.(type) {
|
||||
case string:
|
||||
if !GetNotTranslate(detailsView, "") {
|
||||
value, _ = detailsView.session.GetString(value)
|
||||
}
|
||||
buffer.WriteString("<summary>")
|
||||
buffer.WriteString(value)
|
||||
buffer.WriteString("</summary>")
|
||||
|
|
|
@ -41,6 +41,10 @@ func (list *dropDownListData) Init(session Session) {
|
|||
list.dropDownListener = []func(DropDownList, int){}
|
||||
}
|
||||
|
||||
func (list *dropDownListData) String() string {
|
||||
return getViewString(list)
|
||||
}
|
||||
|
||||
func (list *dropDownListData) Focusable() bool {
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -63,6 +63,10 @@ func (edit *editViewData) Init(session Session) {
|
|||
edit.tag = "EditView"
|
||||
}
|
||||
|
||||
func (edit *editViewData) String() string {
|
||||
return getViewString(edit)
|
||||
}
|
||||
|
||||
func (edit *editViewData) Focusable() bool {
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -89,6 +89,10 @@ func (picker *filePickerData) Init(session Session) {
|
|||
picker.fileSelectedListeners = []func(FilePicker, []FileInfo){}
|
||||
}
|
||||
|
||||
func (picker *filePickerData) String() string {
|
||||
return getViewString(picker)
|
||||
}
|
||||
|
||||
func (picker *filePickerData) Focusable() bool {
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -33,6 +33,10 @@ func (gridLayout *gridLayoutData) Init(session Session) {
|
|||
gridLayout.systemClass = "ruiGridLayout"
|
||||
}
|
||||
|
||||
func (gridLayout *gridLayoutData) String() string {
|
||||
return getViewString(gridLayout)
|
||||
}
|
||||
|
||||
func (style *viewStyle) setGridCellSize(tag string, value interface{}) bool {
|
||||
setValues := func(values []string) bool {
|
||||
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 {
|
||||
tag = strings.ToLower(tag)
|
||||
switch tag {
|
||||
|
|
|
@ -49,6 +49,10 @@ func (listLayout *listLayoutData) Init(session Session) {
|
|||
listLayout.systemClass = "ruiListLayout"
|
||||
}
|
||||
|
||||
func (listLayout *listLayoutData) String() string {
|
||||
return getViewString(listLayout)
|
||||
}
|
||||
|
||||
func (listLayout *listLayoutData) Remove(tag string) {
|
||||
listLayout.remove(strings.ToLower(tag))
|
||||
}
|
||||
|
|
|
@ -91,6 +91,10 @@ func (listView *listViewData) Init(session Session) {
|
|||
listView.checkedListeners = []func(ListView, []int){}
|
||||
}
|
||||
|
||||
func (listView *listViewData) String() string {
|
||||
return getViewString(listView)
|
||||
}
|
||||
|
||||
func (listView *listViewData) Views() []View {
|
||||
return listView.items
|
||||
}
|
||||
|
|
|
@ -168,6 +168,10 @@ func (player *mediaPlayerData) Init(session Session) {
|
|||
player.tag = "MediaPlayer"
|
||||
}
|
||||
|
||||
func (player *mediaPlayerData) String() string {
|
||||
return getViewString(player)
|
||||
}
|
||||
|
||||
func (player *mediaPlayerData) Focusable() bool {
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -51,6 +51,10 @@ func (picker *numberPickerData) Init(session Session) {
|
|||
picker.numberChangedListeners = []func(NumberPicker, float64){}
|
||||
}
|
||||
|
||||
func (picker *numberPickerData) String() string {
|
||||
return getViewString(picker)
|
||||
}
|
||||
|
||||
func (picker *numberPickerData) Focusable() bool {
|
||||
return true
|
||||
}
|
||||
|
|
22
outline.go
22
outline.go
|
@ -7,7 +7,7 @@ import (
|
|||
|
||||
type OutlineProperty interface {
|
||||
Properties
|
||||
ruiStringer
|
||||
stringWriter
|
||||
fmt.Stringer
|
||||
ViewOutline(session Session) ViewOutline
|
||||
}
|
||||
|
@ -25,22 +25,26 @@ func NewOutlineProperty(params Params) OutlineProperty {
|
|||
return outline
|
||||
}
|
||||
|
||||
func (outline *outlinePropertyData) ruiString(writer ruiWriter) {
|
||||
writer.startObject("_")
|
||||
|
||||
func (outline *outlinePropertyData) writeString(buffer *strings.Builder, indent string) {
|
||||
buffer.WriteString("_{ ")
|
||||
comma := false
|
||||
for _, tag := range []string{Style, Width, ColorTag} {
|
||||
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 {
|
||||
writer := newRUIWriter()
|
||||
outline.ruiString(writer)
|
||||
return writer.finish()
|
||||
return runStringWriter(outline)
|
||||
}
|
||||
|
||||
func (outline *outlinePropertyData) normalizeTag(tag string) string {
|
||||
|
|
|
@ -36,6 +36,10 @@ func (progress *progressBarData) Init(session Session) {
|
|||
progress.tag = "ProgressBar"
|
||||
}
|
||||
|
||||
func (progress *progressBarData) String() string {
|
||||
return getViewString(progress)
|
||||
}
|
||||
|
||||
func (progress *progressBarData) normalizeTag(tag string) string {
|
||||
tag = strings.ToLower(tag)
|
||||
switch tag {
|
||||
|
|
22
radius.go
22
radius.go
|
@ -97,7 +97,7 @@ const (
|
|||
|
||||
type RadiusProperty interface {
|
||||
Properties
|
||||
ruiStringer
|
||||
stringWriter
|
||||
fmt.Stringer
|
||||
BoxRadius(session Session) BoxRadius
|
||||
}
|
||||
|
@ -125,23 +125,27 @@ func (radius *radiusPropertyData) normalizeTag(tag string) string {
|
|||
return strings.TrimPrefix(strings.ToLower(tag), "radius-")
|
||||
}
|
||||
|
||||
func (radius *radiusPropertyData) ruiString(writer ruiWriter) {
|
||||
writer.startObject("_")
|
||||
|
||||
func (radius *radiusPropertyData) writeString(buffer *strings.Builder, indent string) {
|
||||
buffer.WriteString("_{ ")
|
||||
comma := false
|
||||
for _, tag := range []string{X, Y, TopLeft, TopLeftX, TopLeftY, TopRight, TopRightX, TopRightY,
|
||||
BottomLeft, BottomLeftX, BottomLeftY, BottomRight, BottomRightX, BottomRightY} {
|
||||
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 {
|
||||
writer := newRUIWriter()
|
||||
radius.ruiString(writer)
|
||||
return writer.finish()
|
||||
return runStringWriter(radius)
|
||||
}
|
||||
|
||||
func (radius *radiusPropertyData) delete(tags []string) {
|
||||
|
|
|
@ -61,6 +61,10 @@ func (resizable *resizableData) Init(session Session) {
|
|||
resizable.content = []View{}
|
||||
}
|
||||
|
||||
func (resizable *resizableData) String() string {
|
||||
return getViewString(resizable)
|
||||
}
|
||||
|
||||
func (resizable *resizableData) Views() []View {
|
||||
return resizable.content
|
||||
}
|
||||
|
|
45
ruiWriter.go
45
ruiWriter.go
|
@ -1,5 +1,6 @@
|
|||
package rui
|
||||
|
||||
/*
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
@ -10,6 +11,8 @@ type ruiWriter interface {
|
|||
startObject(tag string)
|
||||
startObjectProperty(tag, objectTag string)
|
||||
endObject()
|
||||
startArrayProperty(tag string)
|
||||
endObArray()
|
||||
writeProperty(tag string, value interface{})
|
||||
finish() string
|
||||
}
|
||||
|
@ -41,23 +44,22 @@ func (writer *ruiWriterData) writeIndent() {
|
|||
}
|
||||
|
||||
func (writer *ruiWriterData) writeString(str string) {
|
||||
esc := map[string]string{"\t": `\t`, "\r": `\r`, "\n": `\n`, "\"": `"`}
|
||||
hasEsc := false
|
||||
for s := range esc {
|
||||
if strings.Contains(str, s) {
|
||||
hasEsc = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if hasEsc || strings.Contains(str, " ") || strings.Contains(str, ",") {
|
||||
hasEsc := strings.ContainsAny(str, "\t\"\r\n")
|
||||
if hasEsc || strings.ContainsAny(str, " ,;'`[]{}()") {
|
||||
if !strings.Contains(str, "`") && (hasEsc || strings.Contains(str, `\`)) {
|
||||
writer.buffer.WriteRune('`')
|
||||
writer.buffer.WriteString(str)
|
||||
writer.buffer.WriteRune('`')
|
||||
} else {
|
||||
str = strings.Replace(str, `\`, `\\`, -1)
|
||||
for oldStr, newStr := range esc {
|
||||
str = strings.Replace(str, oldStr, newStr, -1)
|
||||
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 {
|
||||
str = strings.Replace(str, s.old, s.new, -1)
|
||||
}
|
||||
writer.buffer.WriteRune('"')
|
||||
writer.buffer.WriteString(str)
|
||||
|
@ -80,6 +82,9 @@ func (writer *ruiWriterData) startObjectProperty(tag, objectTag string) {
|
|||
writer.indent += "\t"
|
||||
writer.writeString(tag)
|
||||
writer.writeString(" = ")
|
||||
if objectTag == "" {
|
||||
objectTag = "_"
|
||||
}
|
||||
writer.writeString(objectTag)
|
||||
writer.buffer.WriteString(" {\n")
|
||||
}
|
||||
|
@ -92,6 +97,21 @@ func (writer *ruiWriterData) endObject() {
|
|||
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{}) {
|
||||
|
||||
switch value := value.(type) {
|
||||
|
@ -201,3 +221,4 @@ func (writer *ruiWriterData) finish() string {
|
|||
}
|
||||
return result
|
||||
}
|
||||
*/
|
||||
|
|
23
shadow.go
23
shadow.go
|
@ -31,7 +31,7 @@ const (
|
|||
type ViewShadow interface {
|
||||
Properties
|
||||
fmt.Stringer
|
||||
ruiStringer
|
||||
stringWriter
|
||||
cssStyle(buffer *strings.Builder, session Session, lead string) bool
|
||||
cssTextStyle(buffer *strings.Builder, session Session, lead string) bool
|
||||
visible(session Session) bool
|
||||
|
@ -205,19 +205,24 @@ func (shadow *viewShadowData) visible(session Session) bool {
|
|||
}
|
||||
|
||||
func (shadow *viewShadowData) String() string {
|
||||
writer := newRUIWriter()
|
||||
shadow.ruiString(writer)
|
||||
return writer.finish()
|
||||
return runStringWriter(shadow)
|
||||
}
|
||||
|
||||
func (shadow *viewShadowData) ruiString(writer ruiWriter) {
|
||||
writer.startObject("_")
|
||||
func (shadow *viewShadowData) writeString(buffer *strings.Builder, indent string) {
|
||||
buffer.WriteString("_{ ")
|
||||
comma := false
|
||||
for _, tag := range shadow.AllTags() {
|
||||
if value := shadow.Get(tag); value != nil {
|
||||
writer.writeProperty(tag, value)
|
||||
if value, ok := shadow.properties[tag]; ok {
|
||||
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 {
|
||||
|
|
|
@ -58,6 +58,10 @@ func (layout *stackLayoutData) Init(session Session) {
|
|||
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) {
|
||||
if tag == "ruiPush" {
|
||||
if layout.pushView != nil {
|
||||
|
|
|
@ -268,6 +268,10 @@ func (table *tableViewData) Init(session Session) {
|
|||
table.current.Column = -1
|
||||
}
|
||||
|
||||
func (table *tableViewData) String() string {
|
||||
return getViewString(table)
|
||||
}
|
||||
|
||||
func (table *tableViewData) normalizeTag(tag string) string {
|
||||
switch tag = strings.ToLower(tag); tag {
|
||||
case "top-cell-padding":
|
||||
|
|
|
@ -99,6 +99,10 @@ func (tabsLayout *tabsLayoutData) Init(session Session) {
|
|||
tabsLayout.tabCloseListener = []func(TabsLayout, int){}
|
||||
}
|
||||
|
||||
func (tabsLayout *tabsLayoutData) String() string {
|
||||
return getViewString(tabsLayout)
|
||||
}
|
||||
|
||||
func (tabsLayout *tabsLayoutData) currentItem() int {
|
||||
result, _ := intProperty(tabsLayout, Current, tabsLayout.session, 0)
|
||||
return result
|
||||
|
|
16
textView.go
16
textView.go
|
@ -32,6 +32,10 @@ func (textView *textViewData) Init(session Session) {
|
|||
textView.tag = "TextView"
|
||||
}
|
||||
|
||||
func (textView *textViewData) String() string {
|
||||
return getViewString(textView)
|
||||
}
|
||||
|
||||
func (textView *textViewData) Get(tag string) interface{} {
|
||||
return textView.get(strings.ToLower(tag))
|
||||
}
|
||||
|
@ -103,6 +107,14 @@ func (textView *textViewData) set(tag string, value interface{}) bool {
|
|||
textView.textOverflowUpdated()
|
||||
}
|
||||
|
||||
case NotTranslate:
|
||||
if !textView.viewData.set(tag, value) {
|
||||
return false
|
||||
}
|
||||
if textView.created {
|
||||
updateInnerHTML(textView.htmlID(), textView.Session())
|
||||
}
|
||||
|
||||
default:
|
||||
return textView.viewData.set(tag, value)
|
||||
}
|
||||
|
@ -143,7 +155,9 @@ func textToJS(text string) string {
|
|||
func (textView *textViewData) htmlSubviews(self View, buffer *strings.Builder) {
|
||||
if value := textView.getRaw(Text); value != nil {
|
||||
if text, ok := value.(string); ok {
|
||||
text, _ = textView.session.GetString(text)
|
||||
if !GetNotTranslate(textView, "") {
|
||||
text, _ = textView.session.GetString(text)
|
||||
}
|
||||
buffer.WriteString(textToJS(text))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,10 @@ func (picker *timePickerData) Init(session Session) {
|
|||
picker.timeChangedListeners = []func(TimePicker, time.Time){}
|
||||
}
|
||||
|
||||
func (picker *timePickerData) String() string {
|
||||
return getViewString(picker)
|
||||
}
|
||||
|
||||
func (picker *timePickerData) Focusable() bool {
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -45,6 +45,10 @@ func (player *videoPlayerData) Init(session Session) {
|
|||
player.tag = "VideoPlayer"
|
||||
}
|
||||
|
||||
func (player *videoPlayerData) String() string {
|
||||
return getViewString(player)
|
||||
}
|
||||
|
||||
func (player *videoPlayerData) htmlTag() string {
|
||||
return "video"
|
||||
}
|
||||
|
|
59
view.go
59
view.go
|
@ -30,9 +30,8 @@ func (frame Frame) Bottom() float64 {
|
|||
|
||||
// View - base view interface
|
||||
type View interface {
|
||||
Properties
|
||||
ViewStyle
|
||||
fmt.Stringer
|
||||
ruiStringer
|
||||
|
||||
// Init initializes fields of View by default values
|
||||
Init(session Session)
|
||||
|
@ -616,6 +615,13 @@ 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)
|
||||
}
|
||||
|
||||
|
@ -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)) {
|
||||
if listener == nil {
|
||||
delete(view.changeListener, tag)
|
||||
|
@ -890,3 +851,7 @@ func (view *viewData) SetChangeListener(tag string, listener func(View, string))
|
|||
func (view *viewData) HasFocus() bool {
|
||||
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 {
|
||||
Properties
|
||||
fmt.Stringer
|
||||
ruiStringer
|
||||
stringWriter
|
||||
cssStyle(session Session) string
|
||||
valid(session Session) bool
|
||||
}
|
||||
|
@ -22,6 +22,10 @@ type ellipseClip struct {
|
|||
propertyList
|
||||
}
|
||||
|
||||
type circleClip struct {
|
||||
propertyList
|
||||
}
|
||||
|
||||
type polygonClip struct {
|
||||
points []interface{}
|
||||
}
|
||||
|
@ -47,7 +51,7 @@ func InsetClip(top, right, bottom, left SizeUnit, radius RadiusProperty) ClipSha
|
|||
|
||||
// CircleClip creates a circle View clipping area.
|
||||
func CircleClip(x, y, radius SizeUnit) ClipShape {
|
||||
clip := new(ellipseClip)
|
||||
clip := new(circleClip)
|
||||
clip.init()
|
||||
clip.Set(X, x)
|
||||
clip.Set(Y, y)
|
||||
|
@ -112,39 +116,25 @@ func (clip *insetClip) Set(tag string, value interface{}) bool {
|
|||
}
|
||||
|
||||
func (clip *insetClip) String() string {
|
||||
writer := newRUIWriter()
|
||||
clip.ruiString(writer)
|
||||
return writer.finish()
|
||||
return runStringWriter(clip)
|
||||
}
|
||||
|
||||
func (clip *insetClip) ruiString(writer ruiWriter) {
|
||||
writer.startObject("inset")
|
||||
for _, tag := range []string{Top, Right, Bottom, Left} {
|
||||
func (clip *insetClip) writeString(buffer *strings.Builder, indent string) {
|
||||
buffer.WriteString("inset { ")
|
||||
comma := false
|
||||
for _, tag := range []string{Top, Right, Bottom, Left, Radius} {
|
||||
if value, ok := clip.properties[tag]; ok {
|
||||
switch value := value.(type) {
|
||||
case string:
|
||||
writer.writeProperty(tag, value)
|
||||
|
||||
case fmt.Stringer:
|
||||
writer.writeProperty(tag, value.String())
|
||||
if comma {
|
||||
buffer.WriteString(", ")
|
||||
}
|
||||
buffer.WriteString(tag)
|
||||
buffer.WriteString(" = ")
|
||||
writePropertyValue(buffer, tag, value, indent)
|
||||
comma = true
|
||||
}
|
||||
}
|
||||
|
||||
if value := clip.Get(Radius); value != nil {
|
||||
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()
|
||||
buffer.WriteString(" }")
|
||||
}
|
||||
|
||||
func (clip *insetClip) cssStyle(session Session) string {
|
||||
|
@ -178,83 +168,108 @@ func (clip *insetClip) valid(session Session) bool {
|
|||
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 {
|
||||
if value == nil {
|
||||
clip.Remove(tag)
|
||||
}
|
||||
|
||||
switch strings.ToLower(tag) {
|
||||
case X, Y:
|
||||
case X, Y, RadiusX, RadiusY:
|
||||
return clip.setSizeProperty(tag, value)
|
||||
|
||||
case Radius:
|
||||
result := clip.setSizeProperty(tag, value)
|
||||
if result {
|
||||
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
|
||||
return clip.setSizeProperty(RadiusX, value) &&
|
||||
clip.setSizeProperty(RadiusY, value)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func (clip *ellipseClip) String() string {
|
||||
writer := newRUIWriter()
|
||||
clip.ruiString(writer)
|
||||
return writer.finish()
|
||||
return runStringWriter(clip)
|
||||
}
|
||||
|
||||
func (clip *ellipseClip) ruiString(writer ruiWriter) {
|
||||
writeProperty := func(tag string, value interface{}) {
|
||||
switch value := value.(type) {
|
||||
case string:
|
||||
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} {
|
||||
func (clip *ellipseClip) writeString(buffer *strings.Builder, indent string) {
|
||||
buffer.WriteString("ellipse { ")
|
||||
comma := false
|
||||
for _, tag := range []string{RadiusX, RadiusY, X, Y} {
|
||||
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 {
|
||||
|
@ -262,38 +277,29 @@ func (clip *ellipseClip) cssStyle(session Session) string {
|
|||
buffer := allocStringBuilder()
|
||||
defer freeStringBuilder(buffer)
|
||||
|
||||
if r, ok := sizeProperty(clip, Radius, session); ok {
|
||||
buffer.WriteString("circle(")
|
||||
buffer.WriteString(r.cssString("0"))
|
||||
} else {
|
||||
rx, _ := sizeProperty(clip, RadiusX, session)
|
||||
ry, _ := sizeProperty(clip, RadiusX, session)
|
||||
buffer.WriteString("ellipse(")
|
||||
buffer.WriteString(rx.cssString("0"))
|
||||
buffer.WriteRune(' ')
|
||||
buffer.WriteString(ry.cssString("0"))
|
||||
}
|
||||
rx, _ := sizeProperty(clip, RadiusX, session)
|
||||
ry, _ := sizeProperty(clip, RadiusX, session)
|
||||
buffer.WriteString("ellipse(")
|
||||
buffer.WriteString(rx.cssString("50%"))
|
||||
buffer.WriteRune(' ')
|
||||
buffer.WriteString(ry.cssString("50%"))
|
||||
|
||||
buffer.WriteString(" at ")
|
||||
x, _ := sizeProperty(clip, X, session)
|
||||
buffer.WriteString(x.cssString("0"))
|
||||
buffer.WriteString(x.cssString("50%"))
|
||||
buffer.WriteRune(' ')
|
||||
|
||||
y, _ := sizeProperty(clip, Y, session)
|
||||
buffer.WriteString(y.cssString("0"))
|
||||
buffer.WriteString(y.cssString("50%"))
|
||||
buffer.WriteRune(')')
|
||||
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
func (clip *ellipseClip) valid(session Session) bool {
|
||||
if value, ok := sizeProperty(clip, Radius, session); ok && value.Type != Auto && value.Value != 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
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
|
||||
rx, _ := sizeProperty(clip, RadiusX, session)
|
||||
ry, _ := sizeProperty(clip, RadiusY, session)
|
||||
return rx.Value != 0 && ry.Value != 0
|
||||
}
|
||||
|
||||
func (clip *polygonClip) Get(tag string) interface{} {
|
||||
|
@ -383,47 +389,31 @@ func (clip *polygonClip) AllTags() []string {
|
|||
}
|
||||
|
||||
func (clip *polygonClip) String() string {
|
||||
writer := newRUIWriter()
|
||||
clip.ruiString(writer)
|
||||
return writer.finish()
|
||||
return runStringWriter(clip)
|
||||
}
|
||||
|
||||
func (clip *polygonClip) ruiString(writer ruiWriter) {
|
||||
func (clip *polygonClip) writeString(buffer *strings.Builder, indent string) {
|
||||
|
||||
buffer := allocStringBuilder()
|
||||
defer freeStringBuilder(buffer)
|
||||
|
||||
writer.startObject("polygon")
|
||||
buffer.WriteString("inset { ")
|
||||
|
||||
if clip.points != nil {
|
||||
buffer.WriteString(Points)
|
||||
buffer.WriteString(` = "`)
|
||||
for i, value := range clip.points {
|
||||
if i > 0 {
|
||||
buffer.WriteString(", ")
|
||||
}
|
||||
switch value := value.(type) {
|
||||
case string:
|
||||
buffer.WriteString(value)
|
||||
|
||||
case fmt.Stringer:
|
||||
buffer.WriteString(value.String())
|
||||
|
||||
default:
|
||||
buffer.WriteString("0px")
|
||||
}
|
||||
writePropertyValue(buffer, "", value, indent)
|
||||
}
|
||||
|
||||
writer.writeProperty(Points, buffer.String())
|
||||
buffer.WriteString(`" `)
|
||||
}
|
||||
|
||||
writer.endObject()
|
||||
buffer.WriteRune('}')
|
||||
}
|
||||
|
||||
func (clip *polygonClip) cssStyle(session Session) string {
|
||||
|
||||
if clip.points == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
count := len(clip.points)
|
||||
if count < 2 {
|
||||
return ""
|
||||
|
|
|
@ -77,7 +77,7 @@ const (
|
|||
type ViewFilter interface {
|
||||
Properties
|
||||
fmt.Stringer
|
||||
ruiStringer
|
||||
stringWriter
|
||||
cssStyle(session Session) string
|
||||
}
|
||||
|
||||
|
@ -155,17 +155,25 @@ func (filter *viewFilter) Set(tag string, value interface{}) bool {
|
|||
}
|
||||
|
||||
func (filter *viewFilter) String() string {
|
||||
writer := newRUIWriter()
|
||||
filter.ruiString(writer)
|
||||
return writer.finish()
|
||||
return runStringWriter(filter)
|
||||
}
|
||||
|
||||
func (filter *viewFilter) ruiString(writer ruiWriter) {
|
||||
writer.startObject("filter")
|
||||
for tag, value := range filter.properties {
|
||||
writer.writeProperty(tag, value)
|
||||
func (filter *viewFilter) writeString(buffer *strings.Builder, indent string) {
|
||||
buffer.WriteString("filter { ")
|
||||
comma := false
|
||||
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 {
|
||||
|
|
405
viewStyle.go
405
viewStyle.go
|
@ -2,6 +2,7 @@ package rui
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
@ -22,6 +23,10 @@ type Range struct {
|
|||
First, Last int
|
||||
}
|
||||
|
||||
type stringWriter interface {
|
||||
writeString(buffer *strings.Builder, indent string)
|
||||
}
|
||||
|
||||
// String returns a string representation of the Range struct
|
||||
func (r Range) String() string {
|
||||
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:
|
||||
setObject := func(obj DataObject) bool {
|
||||
if obj != nil {
|
||||
switch obj.Tag() {
|
||||
tag := strings.ToLower(tag)
|
||||
switch tag {
|
||||
case "", "_":
|
||||
ErrorLog("Invalid transition property name")
|
||||
|
||||
default:
|
||||
style.transitions[obj.Tag()] = parseAnimation(obj)
|
||||
style.transitions[tag] = parseAnimation(obj)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -285,18 +286,19 @@ func (style *viewStyle) set(tag string, value interface{}) bool {
|
|||
|
||||
switch value := value.(type) {
|
||||
case Params:
|
||||
result := false
|
||||
result := true
|
||||
for tag, val := range value {
|
||||
if animation, ok := val.(Animation); ok {
|
||||
tag = strings.ToLower(tag)
|
||||
if animation == nil || tag == "" {
|
||||
ErrorLog("Invalid transition property name")
|
||||
} else {
|
||||
style.transitions[tag] = animation
|
||||
result = true
|
||||
}
|
||||
tag = strings.ToLower(strings.Trim(tag, " \t"))
|
||||
if tag == "" {
|
||||
ErrorLog("Invalid transition property name")
|
||||
result = false
|
||||
} else if val == nil {
|
||||
delete(style.transitions, tag)
|
||||
} else if animation, ok := val.(Animation); ok {
|
||||
style.transitions[tag] = animation
|
||||
} else {
|
||||
notCompatibleType(Transition, val)
|
||||
result = false
|
||||
}
|
||||
}
|
||||
return result
|
||||
|
|
|
@ -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{}
|
||||
}
|
||||
|
||||
func (container *viewsContainerData) String() string {
|
||||
return getViewString(container)
|
||||
}
|
||||
|
||||
func (container *viewsContainerData) setParentID(parentID string) {
|
||||
container.viewData.setParentID(parentID)
|
||||
htmlID := container.htmlID()
|
||||
|
|
Loading…
Reference in New Issue