diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f7e558..47405b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,13 +3,13 @@ * Added support of binding * Added "binding" argument to CreateViewFromResources, CreateViewFromText, and CreateViewFromObject functions * Added CreatePopupFromResources, CreatePopupFromText, and CreatePopupFromObject functions +* Added All() iterator and IsEmpty() method to Properties interface * Added implementation of Properties interface to Popup * Changed ParseDataText function return values * Added `Properties() iter.Seq[DataNode]` iterator to DataObject interface * Renamed `ArrayElements() []DataValue` method of DataNode interface to `Array() []DataValue` * Added `ArrayElements() iter.Seq[DataValue]` iterator to DataNode interface - # v0.19.0 * Added support of drag-and-drop diff --git a/bounds.go b/bounds.go index 2eb7470..379497d 100644 --- a/bounds.go +++ b/bounds.go @@ -263,7 +263,7 @@ func removeBoundsPropertySide(properties Properties, mainTag, sideTag PropertyNa if bounds := getBoundsProperty(properties, mainTag); bounds != nil { if bounds.getRaw(sideTag) != nil { bounds.Remove(sideTag) - if bounds.empty() { + if bounds.IsEmpty() { bounds = nil } properties.setRaw(mainTag, bounds) diff --git a/customView.go b/customView.go index f848b07..c5a3fbb 100644 --- a/customView.go +++ b/customView.go @@ -1,6 +1,9 @@ package rui -import "strings" +import ( + "iter" + "strings" +) // CustomView defines a custom view interface type CustomView interface { @@ -47,8 +50,8 @@ func (customView *CustomViewData) SuperView() View { func (customView *CustomViewData) setSuperView(view View) { customView.superView = view customView.defaultParams = Params{} - for _, tag := range view.AllTags() { - if value := view.getRaw(tag); value != nil { + for tag, value := range view.All() { + if value != nil { customView.defaultParams[tag] = value } } @@ -107,13 +110,17 @@ func (customView *CustomViewData) Remove(tag PropertyName) { customView.superView.Remove(tag) } -// AllTags returns an array of the set properties func (customView *CustomViewData) AllTags() []PropertyName { return customView.superView.AllTags() } -func (customView *CustomViewData) empty() bool { - return customView.superView.empty() +// AllTags returns an array of the set properties +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 diff --git a/params.go b/params.go index a9ee940..81946fa 100644 --- a/params.go +++ b/params.go @@ -1,6 +1,7 @@ package rui import ( + "iter" "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. func (params Params) AllTags() []PropertyName { tags := make([]PropertyName, 0, len(params)) @@ -57,6 +68,6 @@ func (params Params) AllTags() []PropertyName { return tags } -func (params Params) empty() bool { +func (params Params) IsEmpty() bool { return len(params) == 0 } diff --git a/properties.go b/properties.go index 4d890e4..79e685e 100644 --- a/properties.go +++ b/properties.go @@ -1,6 +1,7 @@ package rui import ( + "iter" "slices" "strings" ) @@ -24,10 +25,13 @@ type Properties interface { // Clear removes all properties Clear() + // All returns an iterator to access the properties + All() iter.Seq2[PropertyName, any] + // AllTags returns an array of the set properties AllTags() []PropertyName - empty() bool + IsEmpty() bool } type propertyList struct { @@ -55,7 +59,7 @@ func (properties *propertyList) init() { //properties.remove = propertiesRemove } -func (properties *propertyList) empty() bool { +func (properties *propertyList) IsEmpty() bool { return len(properties.properties) == 0 } @@ -83,6 +87,16 @@ func (properties *propertyList) Clear() { 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 { tags := make([]PropertyName, 0, len(properties.properties)) for tag := range properties.properties { diff --git a/radius.go b/radius.go index ad87f78..fe26f14 100644 --- a/radius.go +++ b/radius.go @@ -1023,7 +1023,7 @@ func removeRadiusPropertyElement(properties Properties, tag PropertyName) bool { if value := properties.getRaw(Radius); value != nil { radius := getRadiusProperty(properties) radius.Remove(tag) - if radius.empty() { + if radius.IsEmpty() { properties.setRaw(Radius, nil) } else { properties.setRaw(Radius, radius) diff --git a/tableView.go b/tableView.go index 4e59f0e..6dfdc69 100644 --- a/tableView.go +++ b/tableView.go @@ -1328,7 +1328,7 @@ func (table *tableViewData) htmlSubviews(self View, buffer *strings.Builder) { footHeight := GetTableFootHeight(table) cellBorder := table.getCellBorder() cellPadding := getBoundsProperty(table, CellPadding) - if cellPadding == nil || len(cellPadding.AllTags()) == 0 { + if cellPadding == nil || cellPadding.IsEmpty() { cellPadding = nil if style, ok := stringProperty(table, Style, table.Session()); ok { if style, ok := table.Session().resolveConstants(style); ok { diff --git a/theme.go b/theme.go index 736a8a5..f4a7854 100644 --- a/theme.go +++ b/theme.go @@ -964,7 +964,7 @@ func (theme *theme) String() string { buffer.WriteString(" = [\n") 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") writeViewStyle(tag, style, buffer, "\t\t", nil) buffer.WriteString(",\n") @@ -1015,7 +1015,7 @@ func (theme *theme) String() string { buffer.WriteString(" = [\n") 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") writeViewStyle(tag, style, buffer, "\t\t", nil) buffer.WriteString(",\n") diff --git a/transform.go b/transform.go index 7807bd9..e9dd169 100644 --- a/transform.go +++ b/transform.go @@ -362,7 +362,7 @@ func valueToTransformProperty(value any) TransformProperty { } } - if !ok && transform.empty() { + if !ok && transform.IsEmpty() { return nil } return transform diff --git a/view.go b/view.go index 9f03e5f..ff9fc19 100644 --- a/view.go +++ b/view.go @@ -157,10 +157,8 @@ func setInitParams(view View, params Params) { session.setIgnoreViewUpdates(true) defer session.setIgnoreViewUpdates(false) } - for _, tag := range params.AllTags() { - if value, ok := params[tag]; ok { - view.Set(tag, value) - } + for tag, value := range params.All() { + view.Set(tag, value) } } } @@ -554,10 +552,8 @@ func (view *viewData) SetParams(params Params) bool { session := view.Session() session.startUpdateScript(view.htmlID()) result := true - for _, tag := range params.AllTags() { - if value, ok := params[tag]; ok { - result = view.Set(tag, value) && result - } + for tag, value := range params.All() { + result = view.Set(tag, value) && result } session.finishUpdateScript(view.htmlID()) return result diff --git a/viewStyleSet.go b/viewStyleSet.go index 04af494..02a0fb6 100644 --- a/viewStyleSet.go +++ b/viewStyleSet.go @@ -190,7 +190,7 @@ func viewStyleRemove(properties Properties, tag PropertyName) []PropertyName { case OutlineStyle, OutlineWidth, OutlineColor: if outline := getOutlineProperty(properties); outline != nil { outline.Remove(tag) - if outline.empty() { + if outline.IsEmpty() { properties.setRaw(Outline, nil) } return []PropertyName{Outline, tag} diff --git a/viewUtils.go b/viewUtils.go index 42cc6b0..4332166 100644 --- a/viewUtils.go +++ b/viewUtils.go @@ -64,13 +64,9 @@ func SetParams(rootView View, viewID string, params Params) bool { session := rootView.Session() session.startUpdateScript(rootView.htmlID()) result := true - //for tag, value := range params { - // result = rootView.Set(tag, value) && result - //} - for _, tag := range params.AllTags() { - if value, ok := params[tag]; ok { - result = rootView.Set(tag, value) && result - } + + for tag, value := range params.All() { + result = rootView.Set(tag, value) && result } session.finishUpdateScript(rootView.htmlID())