Bug fixing and optimisation

This commit is contained in:
Alexei Anoshenko 2022-05-23 15:22:14 +03:00
parent 9478b1ee4f
commit be2701e59d
13 changed files with 198 additions and 121 deletions

View File

@ -73,6 +73,13 @@ func newBorderProperty(value interface{}) BorderProperty {
case BorderProperty: case BorderProperty:
return value return value
case DataNode:
if value.Type() == ObjectNode {
_ = border.setBorderObject(value.Object())
} else {
return nil
}
case DataObject: case DataObject:
_ = border.setBorderObject(value) _ = border.setBorderObject(value)

View File

@ -261,7 +261,20 @@ func (properties *propertyList) setBounds(tag string, value interface{}) bool {
properties.properties[tag] = value properties.properties[tag] = value
case Bounds: case Bounds:
properties.properties[tag] = value bounds := NewBoundsProperty(nil)
if value.Top.Type != Auto {
bounds.Set(Top, value.Top)
}
if value.Right.Type != Auto {
bounds.Set(Right, value.Right)
}
if value.Bottom.Type != Auto {
bounds.Set(Bottom, value.Bottom)
}
if value.Left.Type != Auto {
bounds.Set(Left, value.Left)
}
properties.properties[tag] = bounds
case BoundsProperty: case BoundsProperty:
properties.properties[tag] = value properties.properties[tag] = value

View File

@ -235,7 +235,7 @@ func GetColorPickerValue(view View, subviewID string) Color {
return result return result
} }
for _, tag := range []string{Value, ColorTag} { for _, tag := range []string{Value, ColorTag} {
if value, ok := valueFromStyle(view, tag); ok { if value := valueFromStyle(view, tag); value != nil {
if result, ok := valueToColor(value, view.Session()); ok { if result, ok := valueToColor(value, view.Session()); ok {
return result return result
} }

View File

@ -186,7 +186,7 @@ func GetColumnSeparator(view View, subviewID string) ViewBorder {
if view != nil { if view != nil {
value := view.Get(ColumnSeparator) value := view.Get(ColumnSeparator)
if value == nil { if value == nil {
value, _ = valueFromStyle(view, ColumnSeparator) value = valueFromStyle(view, ColumnSeparator)
} }
if value != nil { if value != nil {

View File

@ -361,7 +361,7 @@ func getDateProperty(view View, mainTag, shortTag string) (time.Time, bool) {
return result, true return result, true
} }
if value, ok := valueFromStyle(view, shortTag); ok { if value := valueFromStyle(view, shortTag); value != nil {
if result, ok := valueToTime(value); ok { if result, ok := valueToTime(value); ok {
return result, true return result, true
} }

View File

@ -568,9 +568,11 @@ func GetHint(view View, subviewID string) string {
if text, ok := stringProperty(view, Hint, view.Session()); ok { if text, ok := stringProperty(view, Hint, view.Session()); ok {
return text return text
} }
if text, ok := valueFromStyle(view, Hint); ok { if value := valueFromStyle(view, Hint); value != nil {
if text, ok = view.Session().resolveConstants(text); ok { if text, ok := value.(string); ok {
return text if text, ok = view.Session().resolveConstants(text); ok {
return text
}
} }
} }
} }
@ -659,9 +661,11 @@ func GetEditViewPattern(view View, subviewID string) string {
if pattern, ok := stringProperty(view, EditViewPattern, view.Session()); ok { if pattern, ok := stringProperty(view, EditViewPattern, view.Session()); ok {
return pattern return pattern
} }
if pattern, ok := valueFromStyle(view, EditViewPattern); ok { if value := valueFromStyle(view, EditViewPattern); value != nil {
if pattern, ok = view.Session().resolveConstants(pattern); ok { if pattern, ok := value.(string); ok {
return pattern if pattern, ok = view.Session().resolveConstants(pattern); ok {
return pattern
}
} }
} }
} }

View File

@ -260,8 +260,11 @@ func (picker *filePickerData) htmlTag() string {
func (picker *filePickerData) acceptCSS() string { func (picker *filePickerData) acceptCSS() string {
accept, ok := stringProperty(picker, Accept, picker.Session()) accept, ok := stringProperty(picker, Accept, picker.Session())
if !ok { if !ok {
accept, ok = valueFromStyle(picker, Accept) if value := valueFromStyle(picker, Accept); value != nil {
accept, ok = value.(string)
}
} }
if ok { if ok {
buffer := allocStringBuilder() buffer := allocStringBuilder()
defer freeStringBuilder(buffer) defer freeStringBuilder(buffer)
@ -414,7 +417,9 @@ func GetFilePickerAccept(view View, subviewID string) []string {
if view != nil { if view != nil {
accept, ok := stringProperty(view, Accept, view.Session()) accept, ok := stringProperty(view, Accept, view.Session())
if !ok { if !ok {
accept, ok = valueFromStyle(view, Accept) if value := valueFromStyle(view, Accept); value != nil {
accept, ok = value.(string)
}
} }
if ok { if ok {
result := strings.Split(accept, ",") result := strings.Split(accept, ",")

View File

@ -139,7 +139,7 @@ func GetListOrientation(view View, subviewID string) int {
return orientation return orientation
} }
if value, ok := valueFromStyle(view, Orientation); ok { if value := valueFromStyle(view, Orientation); value != nil {
if orientation, ok := valueToOrientation(value, view.Session()); ok { if orientation, ok := valueToOrientation(value, view.Session()); ok {
return orientation return orientation
} }

View File

@ -80,8 +80,7 @@ type Session interface {
viewByHTMLID(id string) View viewByHTMLID(id string) View
nextViewID() string nextViewID() string
styleProperty(styleTag, property string) (string, bool) styleProperty(styleTag, property string) interface{}
stylePropertyNode(styleTag, propertyTag string) DataNode
setBrige(events chan DataObject, brige WebBrige) setBrige(events chan DataObject, brige WebBrige)
writeInitScript(writer *strings.Builder) writeInitScript(writer *strings.Builder)
@ -214,26 +213,11 @@ func (session *sessionData) close() {
} }
} }
func (session *sessionData) styleProperty(styleTag, propertyTag string) (string, bool) { func (session *sessionData) styleProperty(styleTag, propertyTag string) interface{} {
style := session.getCurrentTheme().style(styleTag) if style := session.getCurrentTheme().style(styleTag); style != nil {
if value, ok := style[propertyTag]; ok { return style.getRaw(propertyTag)
if text, ok := value.(string); ok {
return session.resolveConstants(text)
}
} }
//errorLogF(`property "%v" not found`, propertyTag) //errorLogF(`property "%v" not found`, propertyTag)
return "", false
}
func (session *sessionData) stylePropertyNode(styleTag, propertyTag string) DataNode {
style := session.getCurrentTheme().style(styleTag)
if value, ok := style[propertyTag]; ok {
if node, ok := value.(DataNode); ok {
return node
}
}
return nil return nil
} }

View File

@ -1267,72 +1267,68 @@ func (table *tableViewData) htmlSubviews(self View, buffer *strings.Builder) {
} }
func (table *tableViewData) cellPaddingFromStyle(style string) BoundsProperty { func (table *tableViewData) cellPaddingFromStyle(style string) BoundsProperty {
session := table.Session() if value := table.Session().styleProperty(style, CellPadding); value != nil {
var result BoundsProperty = nil switch value := value.(type) {
case SizeUnit:
return NewBoundsProperty(Params{
Top: value,
Right: value,
Bottom: value,
Left: value,
})
if node := session.stylePropertyNode(style, CellPadding); node != nil && node.Type() == ObjectNode { case BoundsProperty:
for _, tag := range []string{Left, Right, Top, Bottom} { return value
if node := node.Object().PropertyWithTag(tag); node != nil && node.Type() == TextNode {
if result == nil { case string:
result = NewBoundsProperty(nil) if value, ok := table.Session().resolveConstants(value); ok {
if strings.Contains(value, ",") {
values := split4Values(value)
switch len(values) {
case 1:
value = values[0]
case 4:
result := NewBoundsProperty(nil)
n := 0
for i, tag := range []string{Top, Right, Bottom, Left} {
if size, ok := StringToSizeUnit(values[i]); ok && size.Type != Auto {
result.Set(tag, size)
n++
}
}
if n > 0 {
return result
}
return nil
default:
return nil
}
}
if size, ok := StringToSizeUnit(value); ok && size.Type != Auto {
return NewBoundsProperty(Params{
Top: size,
Right: size,
Bottom: size,
Left: size,
})
} }
result.Set(tag, node.Text())
} }
} }
} }
for _, tag := range []string{CellPaddingLeft, CellPaddingRight, CellPaddingTop, CellPaddingBottom} { return nil
if value, ok := session.styleProperty(style, CellPadding); ok {
if result == nil {
result = NewBoundsProperty(nil)
}
result.Set(tag, value)
}
}
return result
} }
func (table *tableViewData) cellBorderFromStyle(style string) BorderProperty { func (table *tableViewData) cellBorderFromStyle(style string) BorderProperty {
if value := table.Session().styleProperty(style, CellBorder); value != nil {
border := new(borderProperty) if border, ok := value.(BorderProperty); ok {
border.properties = map[string]interface{}{} return border
session := table.Session()
if node := session.stylePropertyNode(style, CellBorder); node != nil && node.Type() == ObjectNode {
border.setBorderObject(node.Object())
}
for _, tag := range []string{
CellBorderLeft,
CellBorderRight,
CellBorderTop,
CellBorderBottom,
CellBorderStyle,
CellBorderLeftStyle,
CellBorderRightStyle,
CellBorderTopStyle,
CellBorderBottomStyle,
CellBorderWidth,
CellBorderLeftWidth,
CellBorderRightWidth,
CellBorderTopWidth,
CellBorderBottomWidth,
CellBorderColor,
CellBorderLeftColor,
CellBorderRightColor,
CellBorderTopColor,
CellBorderBottomColor,
} {
if value, ok := session.styleProperty(style, tag); ok {
border.Set(tag, value)
} }
} }
return nil
if len(border.properties) == 0 {
return nil
}
return border
} }
func (table *tableViewData) getCellBorder() BorderProperty { func (table *tableViewData) getCellBorder() BorderProperty {

100
theme.go
View File

@ -1,6 +1,7 @@
package rui package rui
import ( import (
"fmt"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
@ -16,7 +17,7 @@ type MediaStyle struct {
Orientation int Orientation int
MaxWidth int MaxWidth int
MaxHeight int MaxHeight int
Styles map[string]Params Styles map[string]ViewStyle
} }
type theme struct { type theme struct {
@ -27,11 +28,12 @@ type theme struct {
darkColors map[string]string darkColors map[string]string
images map[string]string images map[string]string
darkImages map[string]string darkImages map[string]string
styles map[string]Params styles map[string]ViewStyle
mediaStyles []MediaStyle mediaStyles []MediaStyle
} }
type Theme interface { type Theme interface {
fmt.Stringer
Name() string Name() string
Constant(tag string) (string, string) Constant(tag string) (string, string)
SetConstant(tag string, value, touchUIValue string) SetConstant(tag string, value, touchUIValue string)
@ -50,7 +52,7 @@ type Theme interface {
constant(tag string, touchUI bool) string constant(tag string, touchUI bool) string
color(tag string, darkUI bool) string color(tag string, darkUI bool) string
image(tag string, darkUI bool) string image(tag string, darkUI bool) string
style(tag string) Params style(tag string) ViewStyle
cssText(session Session) string cssText(session Session) string
data() *theme data() *theme
} }
@ -87,7 +89,7 @@ func parseMediaRule(text string) (MediaStyle, bool) {
Orientation: DefaultMedia, Orientation: DefaultMedia,
MaxWidth: 0, MaxWidth: 0,
MaxHeight: 0, MaxHeight: 0,
Styles: map[string]Params{}, Styles: map[string]ViewStyle{},
} }
elements := strings.Split(text, ":") elements := strings.Split(text, ":")
@ -170,7 +172,7 @@ func (theme *theme) init() {
theme.darkColors = map[string]string{} theme.darkColors = map[string]string{}
theme.images = map[string]string{} theme.images = map[string]string{}
theme.darkImages = map[string]string{} theme.darkImages = map[string]string{}
theme.styles = map[string]Params{} theme.styles = map[string]ViewStyle{}
theme.mediaStyles = []MediaStyle{} theme.mediaStyles = []MediaStyle{}
} }
@ -352,12 +354,12 @@ func (theme *theme) cssText(session Session) string {
var builder cssStyleBuilder var builder cssStyleBuilder
builder.init() builder.init()
for tag, obj := range theme.styles { for tag, style := range theme.styles {
var style viewStyle /*var style viewStyle
style.init() style.init()
for tag, value := range obj { for tag, value := range obj {
style.Set(tag, value) style.Set(tag, value)
} }*/
builder.startStyle(tag) builder.startStyle(tag)
style.cssViewStyle(&builder, session) style.cssViewStyle(&builder, session)
builder.endStyle() builder.endStyle()
@ -365,12 +367,12 @@ func (theme *theme) cssText(session Session) string {
for _, media := range theme.mediaStyles { for _, media := range theme.mediaStyles {
builder.startMedia(media.cssText()) builder.startMedia(media.cssText())
for tag, obj := range media.Styles { for tag, style := range media.Styles {
var style viewStyle /*var style viewStyle
style.init() style.init()
for tag, value := range obj { for tag, value := range obj {
style.Set(tag, value) style.Set(tag, value)
} }*/
builder.startStyle(tag) builder.startStyle(tag)
style.cssViewStyle(&builder, session) style.cssViewStyle(&builder, session)
builder.endStyle() builder.endStyle()
@ -404,7 +406,7 @@ func (theme *theme) addData(data DataObject) {
func (theme *theme) parseThemeData(data DataObject) { func (theme *theme) parseThemeData(data DataObject) {
count := data.PropertyCount() count := data.PropertyCount()
objToParams := func(obj DataObject) Params { objToStyle := func(obj DataObject) ViewStyle {
params := Params{} params := Params{}
for i := 0; i < obj.PropertyCount(); i++ { for i := 0; i < obj.PropertyCount(); i++ {
if node := obj.Property(i); node != nil { if node := obj.Property(i); node != nil {
@ -420,7 +422,7 @@ func (theme *theme) parseThemeData(data DataObject) {
} }
} }
} }
return params return NewViewStyle(params)
} }
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
@ -504,7 +506,7 @@ func (theme *theme) parseThemeData(data DataObject) {
for k := 0; k < arraySize; k++ { for k := 0; k < arraySize; k++ {
if element := d.ArrayElement(k); element != nil && element.IsObject() { if element := d.ArrayElement(k); element != nil && element.IsObject() {
if obj := element.Object(); obj != nil { if obj := element.Object(); obj != nil {
theme.styles[obj.Tag()] = objToParams(obj) theme.styles[obj.Tag()] = objToStyle(obj)
} }
} }
} }
@ -517,7 +519,7 @@ func (theme *theme) parseThemeData(data DataObject) {
for k := 0; k < arraySize; k++ { for k := 0; k < arraySize; k++ {
if element := d.ArrayElement(k); element != nil && element.IsObject() { if element := d.ArrayElement(k); element != nil && element.IsObject() {
if obj := element.Object(); obj != nil { if obj := element.Object(); obj != nil {
rule.Styles[obj.Tag()] = objToParams(obj) rule.Styles[obj.Tag()] = objToStyle(obj)
} }
} }
} }
@ -586,10 +588,74 @@ func (theme *theme) image(tag string, darkUI bool) string {
return result return result
} }
func (theme *theme) style(tag string) Params { func (theme *theme) style(tag string) ViewStyle {
if style, ok := theme.styles[tag]; ok { if style, ok := theme.styles[tag]; ok {
return style return style
} }
return Params{} return nil
}
func (theme *theme) String() string {
buffer := allocStringBuilder()
defer freeStringBuilder(buffer)
writeString := func(text string) {
if strings.ContainsAny(text, " \t\n\r\\\"'`,;{}[]()") {
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)
}
}
writeConstants := func(tag string, constants map[string]string) {
count := len(constants)
if count == 0 {
return
}
buffer.WriteString("\t")
buffer.WriteString(tag)
buffer.WriteString(" = _{\n")
tags := make([]string, 0, count)
for name := range constants {
tags = append(tags, name)
}
sort.Strings(tags)
for _, name := range tags {
if value, ok := constants[name]; ok && value != "" {
buffer.WriteString("\t\t")
writeString(name)
buffer.WriteString(" = ")
writeString(value)
buffer.WriteString(",\n")
}
}
buffer.WriteString("\t},\n")
}
buffer.WriteString("theme {\n")
writeConstants("colors", theme.colors)
writeConstants("colors:dark", theme.darkColors)
writeConstants("images", theme.images)
writeConstants("images:dark", theme.darkImages)
writeConstants("constants", theme.constants)
writeConstants("constants:touch", theme.touchConstants)
buffer.WriteString("}\n")
return buffer.String()
} }

View File

@ -361,7 +361,7 @@ func getTimeProperty(view View, mainTag, shortTag string) (time.Time, bool) {
return result, true return result, true
} }
if value, ok := valueFromStyle(view, shortTag); ok { if value := valueFromStyle(view, shortTag); value != nil {
if result, ok := valueToTime(value); ok { if result, ok := valueToTime(value); ok {
return result, true return result, true
} }

View File

@ -410,8 +410,10 @@ func GetFontName(view View, subviewID string) string {
if font, ok := stringProperty(view, FontName, view.Session()); ok { if font, ok := stringProperty(view, FontName, view.Session()); ok {
return font return font
} }
if font, ok := valueFromStyle(view, FontName); ok { if value := valueFromStyle(view, FontName); value != nil {
return font if font, ok := value.(string); ok {
return font
}
} }
if parent := view.Parent(); parent != nil { if parent := view.Parent(); parent != nil {
return GetFontName(parent, "") return GetFontName(parent, "")
@ -784,7 +786,7 @@ func GetRow(view View, subviewID string) Range {
if result, ok := rangeProperty(view, Row, session); ok { if result, ok := rangeProperty(view, Row, session); ok {
return result return result
} }
if value, ok := valueFromStyle(view, Row); ok { if value := valueFromStyle(view, Row); value != nil {
if result, ok := valueToRange(value, session); ok { if result, ok := valueToRange(value, session); ok {
return result return result
} }
@ -804,7 +806,7 @@ func GetColumn(view View, subviewID string) Range {
if result, ok := rangeProperty(view, Column, session); ok { if result, ok := rangeProperty(view, Column, session); ok {
return result return result
} }
if value, ok := valueFromStyle(view, Column); ok { if value := valueFromStyle(view, Column); value != nil {
if result, ok := valueToRange(value, session); ok { if result, ok := valueToRange(value, session); ok {
return result return result
} }
@ -954,20 +956,20 @@ func GetNotTranslate(view View, subviewID string) bool {
return false return false
} }
func valueFromStyle(view View, tag string) (string, bool) { func valueFromStyle(view View, tag string) interface{} {
session := view.Session() session := view.Session()
getValue := func(styleTag string) (string, bool) { getValue := func(styleTag string) interface{} {
if style, ok := stringProperty(view, styleTag, session); ok { if style, ok := stringProperty(view, styleTag, session); ok {
if style, ok := session.resolveConstants(style); ok { if style, ok := session.resolveConstants(style); ok {
return session.styleProperty(style, tag) return session.styleProperty(style, tag)
} }
} }
return "", false return nil
} }
if IsDisabled(view, "") { if IsDisabled(view, "") {
if value, ok := getValue(StyleDisabled); ok { if value := getValue(StyleDisabled); value != nil {
return value, true return value
} }
} }
return getValue(Style) return getValue(Style)
@ -977,7 +979,7 @@ func sizeStyledProperty(view View, tag string) (SizeUnit, bool) {
if value, ok := sizeProperty(view, tag, view.Session()); ok { if value, ok := sizeProperty(view, tag, view.Session()); ok {
return value, true return value, true
} }
if value, ok := valueFromStyle(view, tag); ok { if value := valueFromStyle(view, tag); value != nil {
return valueToSizeUnit(value, view.Session()) return valueToSizeUnit(value, view.Session())
} }
return AutoSize(), false return AutoSize(), false
@ -987,7 +989,7 @@ func enumStyledProperty(view View, tag string, defaultValue int) (int, bool) {
if value, ok := enumProperty(view, tag, view.Session(), defaultValue); ok { if value, ok := enumProperty(view, tag, view.Session(), defaultValue); ok {
return value, true return value, true
} }
if value, ok := valueFromStyle(view, tag); ok { if value := valueFromStyle(view, tag); value != nil {
return valueToEnum(value, tag, view.Session(), defaultValue) return valueToEnum(value, tag, view.Session(), defaultValue)
} }
return defaultValue, false return defaultValue, false
@ -997,7 +999,7 @@ func boolStyledProperty(view View, tag string) (bool, bool) {
if value, ok := boolProperty(view, tag, view.Session()); ok { if value, ok := boolProperty(view, tag, view.Session()); ok {
return value, true return value, true
} }
if value, ok := valueFromStyle(view, tag); ok { if value := valueFromStyle(view, tag); value != nil {
return valueToBool(value, view.Session()) return valueToBool(value, view.Session())
} }
return false, false return false, false
@ -1007,7 +1009,7 @@ func intStyledProperty(view View, tag string, defaultValue int) (int, bool) {
if value, ok := intProperty(view, tag, view.Session(), defaultValue); ok { if value, ok := intProperty(view, tag, view.Session(), defaultValue); ok {
return value, true return value, true
} }
if value, ok := valueFromStyle(view, tag); ok { if value := valueFromStyle(view, tag); value != nil {
return valueToInt(value, view.Session(), defaultValue) return valueToInt(value, view.Session(), defaultValue)
} }
return defaultValue, false return defaultValue, false
@ -1017,7 +1019,7 @@ func floatStyledProperty(view View, tag string, defaultValue float64) (float64,
if value, ok := floatProperty(view, tag, view.Session(), defaultValue); ok { if value, ok := floatProperty(view, tag, view.Session(), defaultValue); ok {
return value, true return value, true
} }
if value, ok := valueFromStyle(view, tag); ok { if value := valueFromStyle(view, tag); value != nil {
return valueToFloat(value, view.Session(), defaultValue) return valueToFloat(value, view.Session(), defaultValue)
} }
@ -1028,7 +1030,7 @@ func colorStyledProperty(view View, tag string) (Color, bool) {
if value, ok := colorProperty(view, tag, view.Session()); ok { if value, ok := colorProperty(view, tag, view.Session()); ok {
return value, true return value, true
} }
if value, ok := valueFromStyle(view, tag); ok { if value := valueFromStyle(view, tag); value != nil {
return valueToColor(value, view.Session()) return valueToColor(value, view.Session())
} }
return Color(0), false return Color(0), false