Added All() iterator and IsEmpty() method to Properties interface

This commit is contained in:
Alexei Anoshenko 2025-07-03 17:47:05 +03:00
parent 4c76000254
commit 8066fb92ba
12 changed files with 56 additions and 32 deletions

View File

@ -3,13 +3,13 @@
* Added support of binding * Added support of binding
* Added "binding" argument to CreateViewFromResources, CreateViewFromText, and CreateViewFromObject functions * Added "binding" argument to CreateViewFromResources, CreateViewFromText, and CreateViewFromObject functions
* Added CreatePopupFromResources, CreatePopupFromText, and CreatePopupFromObject functions * Added CreatePopupFromResources, CreatePopupFromText, and CreatePopupFromObject functions
* Added All() iterator and IsEmpty() method to Properties interface
* Added implementation of Properties interface to Popup * Added implementation of Properties interface to Popup
* Changed ParseDataText function return values * Changed ParseDataText function return values
* Added `Properties() iter.Seq[DataNode]` iterator to DataObject interface * Added `Properties() iter.Seq[DataNode]` iterator to DataObject interface
* Renamed `ArrayElements() []DataValue` method of DataNode interface to `Array() []DataValue` * Renamed `ArrayElements() []DataValue` method of DataNode interface to `Array() []DataValue`
* Added `ArrayElements() iter.Seq[DataValue]` iterator to DataNode interface * Added `ArrayElements() iter.Seq[DataValue]` iterator to DataNode interface
# v0.19.0 # v0.19.0
* Added support of drag-and-drop * Added support of drag-and-drop

View File

@ -263,7 +263,7 @@ func removeBoundsPropertySide(properties Properties, mainTag, sideTag PropertyNa
if bounds := getBoundsProperty(properties, mainTag); bounds != nil { if bounds := getBoundsProperty(properties, mainTag); bounds != nil {
if bounds.getRaw(sideTag) != nil { if bounds.getRaw(sideTag) != nil {
bounds.Remove(sideTag) bounds.Remove(sideTag)
if bounds.empty() { if bounds.IsEmpty() {
bounds = nil bounds = nil
} }
properties.setRaw(mainTag, bounds) properties.setRaw(mainTag, bounds)

View File

@ -1,6 +1,9 @@
package rui package rui
import "strings" import (
"iter"
"strings"
)
// CustomView defines a custom view interface // CustomView defines a custom view interface
type CustomView interface { type CustomView interface {
@ -47,8 +50,8 @@ func (customView *CustomViewData) SuperView() View {
func (customView *CustomViewData) setSuperView(view View) { func (customView *CustomViewData) setSuperView(view View) {
customView.superView = view customView.superView = view
customView.defaultParams = Params{} customView.defaultParams = Params{}
for _, tag := range view.AllTags() { for tag, value := range view.All() {
if value := view.getRaw(tag); value != nil { if value != nil {
customView.defaultParams[tag] = value customView.defaultParams[tag] = value
} }
} }
@ -107,13 +110,17 @@ func (customView *CustomViewData) Remove(tag PropertyName) {
customView.superView.Remove(tag) customView.superView.Remove(tag)
} }
// AllTags returns an array of the set properties
func (customView *CustomViewData) AllTags() []PropertyName { func (customView *CustomViewData) AllTags() []PropertyName {
return customView.superView.AllTags() return customView.superView.AllTags()
} }
func (customView *CustomViewData) empty() bool { // AllTags returns an array of the set properties
return customView.superView.empty() func (customView *CustomViewData) All() iter.Seq2[PropertyName, any] {
return customView.superView.All()
}
func (customView *CustomViewData) IsEmpty() bool {
return customView.superView.IsEmpty()
} }
// Clear removes all properties // Clear removes all properties

View File

@ -1,6 +1,7 @@
package rui package rui
import ( import (
"iter"
"slices" "slices"
) )
@ -47,6 +48,16 @@ func (params Params) Clear() {
} }
} }
func (params Params) All() iter.Seq2[PropertyName, any] {
return func(yield func(PropertyName, any) bool) {
for tag, value := range params {
if !yield(tag, value) {
return
}
}
}
}
// AllTags returns a sorted slice of all properties. // AllTags returns a sorted slice of all properties.
func (params Params) AllTags() []PropertyName { func (params Params) AllTags() []PropertyName {
tags := make([]PropertyName, 0, len(params)) tags := make([]PropertyName, 0, len(params))
@ -57,6 +68,6 @@ func (params Params) AllTags() []PropertyName {
return tags return tags
} }
func (params Params) empty() bool { func (params Params) IsEmpty() bool {
return len(params) == 0 return len(params) == 0
} }

View File

@ -1,6 +1,7 @@
package rui package rui
import ( import (
"iter"
"slices" "slices"
"strings" "strings"
) )
@ -24,10 +25,13 @@ type Properties interface {
// Clear removes all properties // Clear removes all properties
Clear() Clear()
// All returns an iterator to access the properties
All() iter.Seq2[PropertyName, any]
// AllTags returns an array of the set properties // AllTags returns an array of the set properties
AllTags() []PropertyName AllTags() []PropertyName
empty() bool IsEmpty() bool
} }
type propertyList struct { type propertyList struct {
@ -55,7 +59,7 @@ func (properties *propertyList) init() {
//properties.remove = propertiesRemove //properties.remove = propertiesRemove
} }
func (properties *propertyList) empty() bool { func (properties *propertyList) IsEmpty() bool {
return len(properties.properties) == 0 return len(properties.properties) == 0
} }
@ -83,6 +87,16 @@ func (properties *propertyList) Clear() {
properties.properties = map[PropertyName]any{} properties.properties = map[PropertyName]any{}
} }
func (properties *propertyList) All() iter.Seq2[PropertyName, any] {
return func(yield func(PropertyName, any) bool) {
for tag, value := range properties.properties {
if !yield(tag, value) {
return
}
}
}
}
func (properties *propertyList) AllTags() []PropertyName { func (properties *propertyList) AllTags() []PropertyName {
tags := make([]PropertyName, 0, len(properties.properties)) tags := make([]PropertyName, 0, len(properties.properties))
for tag := range properties.properties { for tag := range properties.properties {

View File

@ -1023,7 +1023,7 @@ func removeRadiusPropertyElement(properties Properties, tag PropertyName) bool {
if value := properties.getRaw(Radius); value != nil { if value := properties.getRaw(Radius); value != nil {
radius := getRadiusProperty(properties) radius := getRadiusProperty(properties)
radius.Remove(tag) radius.Remove(tag)
if radius.empty() { if radius.IsEmpty() {
properties.setRaw(Radius, nil) properties.setRaw(Radius, nil)
} else { } else {
properties.setRaw(Radius, radius) properties.setRaw(Radius, radius)

View File

@ -1328,7 +1328,7 @@ func (table *tableViewData) htmlSubviews(self View, buffer *strings.Builder) {
footHeight := GetTableFootHeight(table) footHeight := GetTableFootHeight(table)
cellBorder := table.getCellBorder() cellBorder := table.getCellBorder()
cellPadding := getBoundsProperty(table, CellPadding) cellPadding := getBoundsProperty(table, CellPadding)
if cellPadding == nil || len(cellPadding.AllTags()) == 0 { if cellPadding == nil || cellPadding.IsEmpty() {
cellPadding = nil cellPadding = nil
if style, ok := stringProperty(table, Style, table.Session()); ok { if style, ok := stringProperty(table, Style, table.Session()); ok {
if style, ok := table.Session().resolveConstants(style); ok { if style, ok := table.Session().resolveConstants(style); ok {

View File

@ -964,7 +964,7 @@ func (theme *theme) String() string {
buffer.WriteString(" = [\n") buffer.WriteString(" = [\n")
for _, tag := range tags { for _, tag := range tags {
if style, ok := styles[tag]; ok && len(style.AllTags()) > 0 { if style, ok := styles[tag]; ok && !style.IsEmpty() {
buffer.WriteString("\t\t") buffer.WriteString("\t\t")
writeViewStyle(tag, style, buffer, "\t\t", nil) writeViewStyle(tag, style, buffer, "\t\t", nil)
buffer.WriteString(",\n") buffer.WriteString(",\n")
@ -1015,7 +1015,7 @@ func (theme *theme) String() string {
buffer.WriteString(" = [\n") buffer.WriteString(" = [\n")
for _, tag := range tags { for _, tag := range tags {
if style, ok := media.styles[tag]; ok && len(style.AllTags()) > 0 { if style, ok := media.styles[tag]; ok && !style.IsEmpty() {
buffer.WriteString("\t\t") buffer.WriteString("\t\t")
writeViewStyle(tag, style, buffer, "\t\t", nil) writeViewStyle(tag, style, buffer, "\t\t", nil)
buffer.WriteString(",\n") buffer.WriteString(",\n")

View File

@ -362,7 +362,7 @@ func valueToTransformProperty(value any) TransformProperty {
} }
} }
if !ok && transform.empty() { if !ok && transform.IsEmpty() {
return nil return nil
} }
return transform return transform

12
view.go
View File

@ -157,10 +157,8 @@ func setInitParams(view View, params Params) {
session.setIgnoreViewUpdates(true) session.setIgnoreViewUpdates(true)
defer session.setIgnoreViewUpdates(false) defer session.setIgnoreViewUpdates(false)
} }
for _, tag := range params.AllTags() { for tag, value := range params.All() {
if value, ok := params[tag]; ok { view.Set(tag, value)
view.Set(tag, value)
}
} }
} }
} }
@ -554,10 +552,8 @@ func (view *viewData) SetParams(params Params) bool {
session := view.Session() session := view.Session()
session.startUpdateScript(view.htmlID()) session.startUpdateScript(view.htmlID())
result := true result := true
for _, tag := range params.AllTags() { for tag, value := range params.All() {
if value, ok := params[tag]; ok { result = view.Set(tag, value) && result
result = view.Set(tag, value) && result
}
} }
session.finishUpdateScript(view.htmlID()) session.finishUpdateScript(view.htmlID())
return result return result

View File

@ -190,7 +190,7 @@ func viewStyleRemove(properties Properties, tag PropertyName) []PropertyName {
case OutlineStyle, OutlineWidth, OutlineColor: case OutlineStyle, OutlineWidth, OutlineColor:
if outline := getOutlineProperty(properties); outline != nil { if outline := getOutlineProperty(properties); outline != nil {
outline.Remove(tag) outline.Remove(tag)
if outline.empty() { if outline.IsEmpty() {
properties.setRaw(Outline, nil) properties.setRaw(Outline, nil)
} }
return []PropertyName{Outline, tag} return []PropertyName{Outline, tag}

View File

@ -64,13 +64,9 @@ func SetParams(rootView View, viewID string, params Params) bool {
session := rootView.Session() session := rootView.Session()
session.startUpdateScript(rootView.htmlID()) session.startUpdateScript(rootView.htmlID())
result := true result := true
//for tag, value := range params {
// result = rootView.Set(tag, value) && result for tag, value := range params.All() {
//} result = rootView.Set(tag, value) && result
for _, tag := range params.AllTags() {
if value, ok := params[tag]; ok {
result = rootView.Set(tag, value) && result
}
} }
session.finishUpdateScript(rootView.htmlID()) session.finishUpdateScript(rootView.htmlID())