Bug fixing

This commit is contained in:
Alexei Anoshenko 2026-08-15 11:33:22 +03:00
parent 20f7cab725
commit 6ca2de5c6c
21 changed files with 61 additions and 49 deletions

View File

@ -593,7 +593,7 @@ func (animation *animationData) String() string {
for _, tag := range animation.AllTags() {
if tag != PropertyTag {
if value, ok := animation.properties[tag]; ok && value != nil {
if value := animation.getRaw(tag); value != nil {
text := propertyValueToString(tag, value, "\t")
if text != "" {
buffer.WriteString("\n\t")

View File

@ -93,7 +93,7 @@ func (animation *animationData) onAnimationEnd(view View, _ PropertyName) {
animationView := animation.view
listener := animation.listener
if value, ok := animation.properties[PropertyTag]; ok {
if value := animation.getRaw(PropertyTag); value != nil {
if props, ok := value.([]AnimatedProperty); ok {
for _, prop := range props {
animationView.setRaw(prop.Tag, prop.To)
@ -119,7 +119,7 @@ func (animation *animationData) onAnimationCancel(view View, _ PropertyName) {
animationView := animation.view
listener := animation.listener
if value, ok := animation.properties[PropertyTag]; ok {
if value := animation.getRaw(PropertyTag); value != nil {
if props, ok := value.([]AnimatedProperty); ok {
for _, prop := range props {
animationView.Set(prop.Tag, prop.To)

View File

@ -141,9 +141,9 @@ func (gradient *backgroundConicGradient) Tag() string {
func (image *backgroundConicGradient) Clone() BackgroundElement {
result := NewBackgroundConicGradient(nil)
for tag, value := range image.properties {
result.setRaw(tag, value)
}
image.mutex.Lock()
result.setAll(image.properties)
image.mutex.Unlock()
return result
}
@ -268,7 +268,7 @@ func (gradient *backgroundConicGradient) parseGradientText(value string) []Backg
func (gradient *backgroundConicGradient) cssStyle(session Session) string {
points := []BackgroundGradientAngle{}
if value, ok := gradient.properties[Gradient]; ok {
if value := gradient.getRaw(Gradient); value != nil {
switch value := value.(type) {
case string:
if text, ok := session.resolveConstants(value); ok && text != "" {

View File

@ -105,9 +105,9 @@ func (image *backgroundImage) Tag() string {
func (image *backgroundImage) Clone() BackgroundElement {
result := NewBackgroundImage(nil)
for tag, value := range image.properties {
result.setRaw(tag, value)
}
image.mutex.Lock()
result.setAll(image.properties)
image.mutex.Unlock()
return result
}

View File

@ -253,8 +253,8 @@ func (point *BackgroundGradientPoint) String() string {
func (gradient *backgroundGradient) writeGradient(session Session, buffer *strings.Builder) bool {
value, ok := gradient.properties[Gradient]
if !ok {
value := gradient.getRaw(Gradient)
if value == nil {
return false
}
@ -322,9 +322,9 @@ func (gradient *backgroundLinearGradient) Tag() string {
func (image *backgroundLinearGradient) Clone() BackgroundElement {
result := NewBackgroundLinearGradient(nil)
for tag, value := range image.properties {
result.setRaw(tag, value)
}
image.mutex.Lock()
result.setAll(image.properties)
image.mutex.Unlock()
return result
}
@ -361,7 +361,7 @@ func (gradient *backgroundLinearGradient) cssStyle(session Session) string {
buffer.WriteString(`linear-gradient(`)
}
if value, ok := gradient.properties[Direction]; ok {
if value := gradient.getRaw(Direction); value != nil {
switch value := value.(type) {
case string:
if text, ok := session.resolveConstants(value); ok {

View File

@ -109,9 +109,9 @@ func (gradient *backgroundRadialGradient) Tag() string {
func (image *backgroundRadialGradient) Clone() BackgroundElement {
result := NewBackgroundRadialGradient(nil)
for tag, value := range image.properties {
result.setRaw(tag, value)
}
image.mutex.Lock()
result.setAll(image.properties)
image.mutex.Unlock()
return result
}
@ -221,7 +221,7 @@ func (gradient *backgroundRadialGradient) cssStyle(session Session) string {
shapeText = `ellipse `
}
if value, ok := gradient.properties[RadialGradientRadius]; ok {
if value := gradient.getRaw(RadialGradientRadius); value != nil {
switch value := value.(type) {
case string:
if text, ok := session.resolveConstants(value); ok {

View File

@ -393,6 +393,9 @@ func (border *borderProperty) writeString(buffer *strings.Builder, indent string
}
}
border.mutex.Lock()
defer border.mutex.Unlock()
for _, tag := range []PropertyName{Style, Width, ColorTag} {
if value, ok := border.properties[tag]; ok {
write(tag, value)
@ -722,7 +725,7 @@ func (border *borderProperty) deleteTag(tag PropertyName) bool {
case Left, Right, Top, Bottom:
if border.Get(Style) != nil {
border.properties[tag+"-"+Style] = 0
border.setRaw(tag+"-"+Style, 0)
result = true
removeTags([]PropertyName{tag + "-" + ColorTag, tag + "-" + Width})
} else {
@ -732,7 +735,7 @@ func (border *borderProperty) deleteTag(tag PropertyName) bool {
case LeftStyle, RightStyle, TopStyle, BottomStyle:
if border.getRaw(tag) != nil {
if border.Get(Style) != nil {
border.properties[tag] = 0
border.setRaw(tag, 0)
result = true
} else {
removeTags([]PropertyName{tag})
@ -742,7 +745,7 @@ func (border *borderProperty) deleteTag(tag PropertyName) bool {
case LeftWidth, RightWidth, TopWidth, BottomWidth:
if border.getRaw(tag) != nil {
if border.Get(Width) != nil {
border.properties[tag] = AutoSize()
border.setRaw(tag, AutoSize())
result = true
} else {
removeTags([]PropertyName{tag})
@ -752,7 +755,7 @@ func (border *borderProperty) deleteTag(tag PropertyName) bool {
case LeftColor, RightColor, TopColor, BottomColor:
if border.getRaw(tag) != nil {
if border.Get(ColorTag) != nil {
border.properties[tag] = 0
border.setRaw(tag, 0)
result = true
} else {
removeTags([]PropertyName{tag})

View File

@ -243,7 +243,7 @@ func (clip *insetClipData) writeString(buffer *strings.Builder, indent string) {
buffer.WriteString("inset { ")
comma := false
for _, tag := range []PropertyName{Top, Right, Bottom, Left, Radius} {
if value, ok := clip.properties[tag]; ok {
if value := clip.getRaw(tag); value != nil {
text := propertyValueToString(tag, value, indent)
if text != "" {
if comma {
@ -319,7 +319,7 @@ func (clip *circleClipData) writeString(buffer *strings.Builder, indent string)
buffer.WriteString("circle { ")
comma := false
for _, tag := range []PropertyName{Radius, X, Y} {
if value, ok := clip.properties[tag]; ok {
if value := clip.getRaw(tag); value != nil {
text := propertyValueToString(tag, value, indent)
if text != "" {
if comma {
@ -399,7 +399,7 @@ func (clip *ellipseClipData) writeString(buffer *strings.Builder, indent string)
buffer.WriteString("ellipse { ")
comma := false
for _, tag := range []PropertyName{RadiusX, RadiusY, X, Y} {
if value, ok := clip.properties[tag]; ok {
if value := clip.getRaw(tag); value != nil {
text := propertyValueToString(tag, value, indent)
if text != "" {
if comma {

View File

@ -165,7 +165,7 @@ func (picker *colorPickerData) handleCommand(self View, command PropertyName, da
if text, ok := data.PropertyValue("text"); ok {
if color, ok := StringToColor(text); ok {
oldColor := GetColorPickerValue(picker)
picker.properties[ColorPickerValue] = color
picker.setRaw(ColorPickerValue, color)
if color != oldColor {
for _, listener := range getTwoArgEventListeners[ColorPicker, Color](picker, nil, ColorChangedEvent) {
listener.Run(picker, color, oldColor)

View File

@ -75,11 +75,8 @@ func (customView *CustomViewData) setRaw(tag PropertyName, value any) {
customView.superView.setRaw(tag, value)
}
func (customView *CustomViewData) setContent(value any) bool {
if container, ok := customView.superView.(ViewsContainer); ok {
return container.setContent(value)
}
return false
func (customView *CustomViewData) setAll(props map[PropertyName]any) {
customView.superView.setAll(props)
}
// Set sets the value (second argument) of the property with name defined by the first argument.

View File

@ -354,7 +354,7 @@ func (picker *datePickerData) handleCommand(self View, command PropertyName, dat
if text, ok := data.PropertyValue("text"); ok {
if value, err := time.Parse(dateFormat, text); err == nil {
oldValue := GetDatePickerValue(picker)
picker.properties[DatePickerValue] = value
picker.setRaw(DatePickerValue, value)
if value != oldValue {
for _, listener := range getTwoArgEventListeners[DatePicker, time.Time](picker, nil, DateChangedEvent) {
listener.Run(picker, value, oldValue)

View File

@ -171,7 +171,7 @@ func (detailsView *detailsViewData) htmlSubviews(self View, buffer *strings.Buil
summary := false
hidden := IsSummaryMarkerHidden(detailsView)
if value, ok := detailsView.properties[Summary]; ok {
if value := detailsView.getRaw(Summary); value != nil {
switch value := value.(type) {
case string:
@ -217,7 +217,7 @@ func (detailsView *detailsViewData) htmlSubviews(self View, buffer *strings.Buil
func (detailsView *detailsViewData) handleCommand(self View, command PropertyName, data DataObject) bool {
if command == "details-open" {
if n, ok := dataIntProperty(data, "open"); ok {
detailsView.properties[Expanded] = (n != 0)
detailsView.setRaw(Expanded, n != 0)
detailsView.runChangeListener(Expanded)
}
return true

View File

@ -255,7 +255,7 @@ func (list *dropDownListData) handleCommand(self View, command PropertyName, dat
items := GetDropDownItems(list)
if GetCurrent(list) != number && number >= 0 && number < len(items) {
old := GetCurrent(list)
list.properties[Current] = number
list.setRaw(Current, number)
for _, listener := range getTwoArgEventListeners[DropDownList, int](list, nil, DropDownEvent) {
listener.Run(list, number, old)
}

View File

@ -268,7 +268,7 @@ func (edit *editViewData) AppendText(text string) {
if textValue, ok := value.(string); ok {
oldText := textValue
textValue += text
edit.properties[Text] = textValue
edit.setRaw(Text, textValue)
edit.session.callFunc("appendToInnerHTML", edit.htmlID(), text)
edit.session.callFunc("appendToInputValue", edit.htmlID(), text)
edit.textChanged(textValue, oldText)

View File

@ -189,7 +189,7 @@ func newFilterProperty(obj DataObject) FilterProperty {
}
}
if len(filter.properties) > 0 {
if !filter.IsEmpty() {
return filter
}
ErrorLog("Empty view filter")

View File

@ -986,7 +986,7 @@ func (listView *listViewData) handleCommand(self View, command PropertyName, dat
}
case "itemUnselected":
if _, ok := listView.properties[Current]; ok {
if listView.getRaw(Current) != nil {
listView.handleCurrent(-1)
}
@ -1003,7 +1003,7 @@ func (listView *listViewData) handleCommand(self View, command PropertyName, dat
}
func (listView *listViewData) handleCurrent(number int) {
listView.properties[Current] = number
listView.setRaw(Current, number)
for _, listener := range getOneArgEventListeners[ListView, int](listView, nil, ListItemSelectedEvent) {
listener.Run(listView, number)
}

View File

@ -289,7 +289,7 @@ func (picker *numberPickerData) handleCommand(self View, command PropertyName, d
if text, ok := data.PropertyValue("text"); ok {
if value, err := strconv.ParseFloat(text, 32); err == nil {
oldValue := GetNumberPickerValue(picker)
picker.properties[NumberPickerValue] = text
picker.setRaw(NumberPickerValue, text)
if value != oldValue {
for _, listener := range getTwoArgEventListeners[NumberPicker, float64](picker, nil, NumberChangedEvent) {
listener.Run(picker, value, oldValue)

View File

@ -1428,11 +1428,13 @@ func (popup *popupData) createLayerView() GridLayout {
CellHorizontalAlign,
}
popup.mutex.Lock()
for tag, value := range popup.properties {
if !slices.Contains(popupProperties, tag) {
params[tag] = value
}
}
popup.mutex.Unlock()
views := make([]View, 0, 3)
if title := popup.createTitleView(); title != nil {
@ -1507,9 +1509,9 @@ func NewPopup(view View, param Params) Popup {
}
popup := new(popupData)
popup.init()
popup.session = view.Session()
popup.contentView = view
popup.properties = map[PropertyName]any{}
popup.hotkeys = map[string]func(Popup){}
for tag, value := range popup.session.PopupDefaultsSeq() {
@ -1547,8 +1549,8 @@ func CreatePopupFromObject(session Session, object DataObject, binding any) Popu
}
popup := new(popupData)
popup.init()
popup.session = session
popup.properties = map[PropertyName]any{}
popup.hotkeys = map[string]func(Popup){}
for key, value := range object.ToParams() {

View File

@ -2,6 +2,7 @@ package rui
import (
"iter"
"maps"
"slices"
"strings"
"sync"
@ -19,6 +20,7 @@ type Properties interface {
// a description of the error is written to the log
Set(tag PropertyName, value any) bool
setRaw(tag PropertyName, value any)
setAll(properties map[PropertyName]any)
// Remove removes the property with name defined by the argument
Remove(tag PropertyName)
@ -56,9 +58,6 @@ func defaultNormalize(tag PropertyName) PropertyName {
func (properties *propertyList) init() {
properties.properties = map[PropertyName]any{}
properties.normalize = defaultNormalize
//properties.getFunc = properties.getRaw
//properties.set = propertiesSet
//properties.remove = propertiesRemove
}
func (properties *propertyList) IsEmpty() bool {
@ -87,6 +86,12 @@ func (properties *propertyList) setRaw(tag PropertyName, value any) {
properties.mutex.Unlock()
}
func (properties *propertyList) setAll(props map[PropertyName]any) {
properties.mutex.Lock()
maps.Copy(properties.properties, props)
properties.mutex.Unlock()
}
/*
func (properties *propertyList) Remove(tag PropertyName) {
properties.remove(properties, properties.normalize(tag))
@ -100,6 +105,8 @@ func (properties *propertyList) Clear() {
}
func (properties *propertyList) All() iter.Seq2[PropertyName, any] {
properties.mutex.Lock()
defer properties.mutex.Unlock()
return func(yield func(PropertyName, any) bool) {
for tag, value := range properties.properties {
if !yield(tag, value) {
@ -204,6 +211,9 @@ func (data *dataProperty) Remove(tag PropertyName) {
}
func (data *dataProperty) writeToBuffer(buffer *strings.Builder, indent string, objectName string, tags []PropertyName) {
data.mutex.Lock()
defer data.mutex.Unlock()
buffer.WriteString(objectName)
buffer.WriteString("{ ")
comma := false

View File

@ -1201,7 +1201,7 @@ func (table *tableViewData) htmlSubviews(self View, buffer *strings.Builder) {
}
}
if len(view.properties) > 0 {
if !view.IsEmpty() {
view.cssStyle(view, &cssBuilder)
}

View File

@ -329,7 +329,7 @@ func (picker *timePickerData) handleCommand(self View, command PropertyName, dat
if text, ok := data.PropertyValue("text"); ok {
if value, ok := stringToTime(text); ok {
oldValue := GetTimePickerValue(picker)
picker.properties[TimePickerValue] = value
picker.setRaw(TimePickerValue, value)
if value != oldValue {
for _, listener := range getTwoArgEventListeners[TimePicker, time.Time](picker, nil, TimeChangedEvent) {
listener.Run(picker, value, oldValue)