mirror of https://github.com/anoshenko/rui.git
				
				
				
			Improved binding for 2 args listeners
This commit is contained in:
		
							parent
							
								
									3c3c09b043
								
							
						
					
					
						commit
						4b00299878
					
				| 
						 | 
					@ -106,13 +106,13 @@ func (picker *colorPickerData) propertyChanged(tag PropertyName) {
 | 
				
			||||||
		color := GetColorPickerValue(picker)
 | 
							color := GetColorPickerValue(picker)
 | 
				
			||||||
		picker.Session().callFunc("setInputValue", picker.htmlID(), color.rgbString())
 | 
							picker.Session().callFunc("setInputValue", picker.htmlID(), color.rgbString())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if listeners := GetColorChangedListeners(picker); len(listeners) > 0 {
 | 
							if listeners := getTwoArgEventListeners[ColorPicker, Color](picker, nil, ColorChangedEvent); len(listeners) > 0 {
 | 
				
			||||||
			oldColor := Color(0)
 | 
								oldColor := Color(0)
 | 
				
			||||||
			if value := picker.getRaw("old-color"); value != nil {
 | 
								if value := picker.getRaw("old-color"); value != nil {
 | 
				
			||||||
				oldColor = value.(Color)
 | 
									oldColor = value.(Color)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			for _, listener := range listeners {
 | 
								for _, listener := range listeners {
 | 
				
			||||||
				listener(picker, color, oldColor)
 | 
									listener.Run(picker, color, oldColor)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -156,8 +156,8 @@ func (picker *colorPickerData) handleCommand(self View, command PropertyName, da
 | 
				
			||||||
				oldColor := GetColorPickerValue(picker)
 | 
									oldColor := GetColorPickerValue(picker)
 | 
				
			||||||
				picker.properties[ColorPickerValue] = color
 | 
									picker.properties[ColorPickerValue] = color
 | 
				
			||||||
				if color != oldColor {
 | 
									if color != oldColor {
 | 
				
			||||||
					for _, listener := range GetColorChangedListeners(picker) {
 | 
										for _, listener := range getTwoArgEventListeners[ColorPicker, Color](picker, nil, ColorChangedEvent) {
 | 
				
			||||||
						listener(picker, color, oldColor)
 | 
											listener.Run(picker, color, oldColor)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					if listener, ok := picker.changeListener[ColorPickerValue]; ok {
 | 
										if listener, ok := picker.changeListener[ColorPickerValue]; ok {
 | 
				
			||||||
						listener(picker, ColorPickerValue)
 | 
											listener(picker, ColorPickerValue)
 | 
				
			||||||
| 
						 | 
					@ -194,8 +194,17 @@ func GetColorPickerValue(view View, subviewID ...string) Color {
 | 
				
			||||||
// GetColorChangedListeners returns the ColorChangedListener list of an ColorPicker subview.
 | 
					// GetColorChangedListeners returns the ColorChangedListener list of an ColorPicker subview.
 | 
				
			||||||
// If there are no listeners then the empty list is returned
 | 
					// If there are no listeners then the empty list is returned
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					// Result elements can be of the following types:
 | 
				
			||||||
 | 
					//   - func(rui.ColorPicker, rui.Color, rui.Color),
 | 
				
			||||||
 | 
					//   - func(rui.ColorPicker, rui.Color),
 | 
				
			||||||
 | 
					//   - func(rui.ColorPicker),
 | 
				
			||||||
 | 
					//   - func(rui.Color, rui.Color),
 | 
				
			||||||
 | 
					//   - func(rui.Color),
 | 
				
			||||||
 | 
					//   - func(),
 | 
				
			||||||
 | 
					//   - string.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
// The second argument (subviewID) specifies the path to the child element whose value needs to be returned.
 | 
					// The second argument (subviewID) specifies the path to the child element whose value needs to be returned.
 | 
				
			||||||
// If it is not specified then a value from the first argument (view) is returned.
 | 
					// If it is not specified then a value from the first argument (view) is returned.
 | 
				
			||||||
func GetColorChangedListeners(view View, subviewID ...string) []func(ColorPicker, Color, Color) {
 | 
					func GetColorChangedListeners(view View, subviewID ...string) []any {
 | 
				
			||||||
	return getTwoArgEventListeners[ColorPicker, Color](view, subviewID, ColorChangedEvent)
 | 
						return getTwoArgEventRawListeners[ColorPicker, Color](view, subviewID, ColorChangedEvent)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -274,7 +274,7 @@ func (picker *datePickerData) propertyChanged(tag PropertyName) {
 | 
				
			||||||
		date := GetDatePickerValue(picker)
 | 
							date := GetDatePickerValue(picker)
 | 
				
			||||||
		session.callFunc("setInputValue", picker.htmlID(), date.Format(dateFormat))
 | 
							session.callFunc("setInputValue", picker.htmlID(), date.Format(dateFormat))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if listeners := GetDateChangedListeners(picker); len(listeners) > 0 {
 | 
							if listeners := getTwoArgEventListeners[DatePicker, time.Time](picker, nil, DateChangedEvent); len(listeners) > 0 {
 | 
				
			||||||
			oldDate := time.Now()
 | 
								oldDate := time.Now()
 | 
				
			||||||
			if value := picker.getRaw("old-date"); value != nil {
 | 
								if value := picker.getRaw("old-date"); value != nil {
 | 
				
			||||||
				if date, ok := value.(time.Time); ok {
 | 
									if date, ok := value.(time.Time); ok {
 | 
				
			||||||
| 
						 | 
					@ -282,7 +282,7 @@ func (picker *datePickerData) propertyChanged(tag PropertyName) {
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			for _, listener := range listeners {
 | 
								for _, listener := range listeners {
 | 
				
			||||||
				listener(picker, date, oldDate)
 | 
									listener.Run(picker, date, oldDate)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -348,8 +348,8 @@ func (picker *datePickerData) handleCommand(self View, command PropertyName, dat
 | 
				
			||||||
				oldValue := GetDatePickerValue(picker)
 | 
									oldValue := GetDatePickerValue(picker)
 | 
				
			||||||
				picker.properties[DatePickerValue] = value
 | 
									picker.properties[DatePickerValue] = value
 | 
				
			||||||
				if value != oldValue {
 | 
									if value != oldValue {
 | 
				
			||||||
					for _, listener := range GetDateChangedListeners(picker) {
 | 
										for _, listener := range getTwoArgEventListeners[DatePicker, time.Time](picker, nil, DateChangedEvent) {
 | 
				
			||||||
						listener(picker, value, oldValue)
 | 
											listener.Run(picker, value, oldValue)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					if listener, ok := picker.changeListener[DatePickerValue]; ok {
 | 
										if listener, ok := picker.changeListener[DatePickerValue]; ok {
 | 
				
			||||||
						listener(picker, DatePickerValue)
 | 
											listener(picker, DatePickerValue)
 | 
				
			||||||
| 
						 | 
					@ -445,8 +445,17 @@ func GetDatePickerValue(view View, subviewID ...string) time.Time {
 | 
				
			||||||
// GetDateChangedListeners returns the DateChangedListener list of an DatePicker subview.
 | 
					// GetDateChangedListeners returns the DateChangedListener list of an DatePicker subview.
 | 
				
			||||||
// If there are no listeners then the empty list is returned
 | 
					// If there are no listeners then the empty list is returned
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					// Result elements can be of the following types:
 | 
				
			||||||
 | 
					//   - func(rui.DatePicker, time.Time, time.Time),
 | 
				
			||||||
 | 
					//   - func(rui.DatePicker, time.Time),
 | 
				
			||||||
 | 
					//   - func(rui.DatePicker),
 | 
				
			||||||
 | 
					//   - func(time.Time, time.Time),
 | 
				
			||||||
 | 
					//   - func(time.Time),
 | 
				
			||||||
 | 
					//   - func(),
 | 
				
			||||||
 | 
					//   - string.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
// The second argument (subviewID) specifies the path to the child element whose value needs to be returned.
 | 
					// The second argument (subviewID) specifies the path to the child element whose value needs to be returned.
 | 
				
			||||||
// If it is not specified then a value from the first argument (view) is returned.
 | 
					// If it is not specified then a value from the first argument (view) is returned.
 | 
				
			||||||
func GetDateChangedListeners(view View, subviewID ...string) []func(DatePicker, time.Time, time.Time) {
 | 
					func GetDateChangedListeners(view View, subviewID ...string) []any {
 | 
				
			||||||
	return getTwoArgEventListeners[DatePicker, time.Time](view, subviewID, DateChangedEvent)
 | 
						return getTwoArgEventRawListeners[DatePicker, time.Time](view, subviewID, DateChangedEvent)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -104,8 +104,8 @@ func (list *dropDownListData) propertyChanged(tag PropertyName) {
 | 
				
			||||||
		list.Session().callFunc("selectDropDownListItem", list.htmlID(), current)
 | 
							list.Session().callFunc("selectDropDownListItem", list.htmlID(), current)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		oldCurrent, _ := intProperty(list, "old-current", list.Session(), -1)
 | 
							oldCurrent, _ := intProperty(list, "old-current", list.Session(), -1)
 | 
				
			||||||
		for _, listener := range GetDropDownListeners(list) {
 | 
							for _, listener := range getTwoArgEventListeners[DropDownList, int](list, nil, DropDownEvent) {
 | 
				
			||||||
			listener(list, current, oldCurrent)
 | 
								listener.Run(list, current, oldCurrent)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
| 
						 | 
					@ -245,8 +245,8 @@ func (list *dropDownListData) handleCommand(self View, command PropertyName, dat
 | 
				
			||||||
				if GetCurrent(list) != number && number >= 0 && number < len(items) {
 | 
									if GetCurrent(list) != number && number >= 0 && number < len(items) {
 | 
				
			||||||
					old := GetCurrent(list)
 | 
										old := GetCurrent(list)
 | 
				
			||||||
					list.properties[Current] = number
 | 
										list.properties[Current] = number
 | 
				
			||||||
					for _, listener := range GetDropDownListeners(list) {
 | 
										for _, listener := range getTwoArgEventListeners[DropDownList, int](list, nil, DropDownEvent) {
 | 
				
			||||||
						listener(list, number, old)
 | 
											listener.Run(list, number, old)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					if listener, ok := list.changeListener[Current]; ok {
 | 
										if listener, ok := list.changeListener[Current]; ok {
 | 
				
			||||||
						listener(list, Current)
 | 
											listener(list, Current)
 | 
				
			||||||
| 
						 | 
					@ -265,10 +265,19 @@ func (list *dropDownListData) handleCommand(self View, command PropertyName, dat
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetDropDownListeners returns the "drop-down-event" listener list. If there are no listeners then the empty list is returned.
 | 
					// GetDropDownListeners returns the "drop-down-event" listener list. If there are no listeners then the empty list is returned.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					// Result elements can be of the following types:
 | 
				
			||||||
 | 
					//   - func(rui.DropDownList, int, int),
 | 
				
			||||||
 | 
					//   - func(rui.DropDownList, int),
 | 
				
			||||||
 | 
					//   - func(rui.DropDownList),
 | 
				
			||||||
 | 
					//   - func(int, int),
 | 
				
			||||||
 | 
					//   - func(int),
 | 
				
			||||||
 | 
					//   - func(),
 | 
				
			||||||
 | 
					//   - string.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
// The second argument (subviewID) specifies the path to the child element whose value needs to be returned.
 | 
					// The second argument (subviewID) specifies the path to the child element whose value needs to be returned.
 | 
				
			||||||
// If it is not specified then a value from the first argument (view) is returned.
 | 
					// If it is not specified then a value from the first argument (view) is returned.
 | 
				
			||||||
func GetDropDownListeners(view View, subviewID ...string) []func(DropDownList, int, int) {
 | 
					func GetDropDownListeners(view View, subviewID ...string) []any {
 | 
				
			||||||
	return getTwoArgEventListeners[DropDownList, int](view, subviewID, DropDownEvent)
 | 
						return getTwoArgEventRawListeners[DropDownList, int](view, subviewID, DropDownEvent)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetDropDownItems return the DropDownList items list.
 | 
					// GetDropDownItems return the DropDownList items list.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										17
									
								
								editView.go
								
								
								
								
							
							
						
						
									
										17
									
								
								editView.go
								
								
								
								
							| 
						 | 
					@ -268,8 +268,8 @@ func (edit *editViewData) AppendText(text string) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (edit *editViewData) textChanged(newText, oldText string) {
 | 
					func (edit *editViewData) textChanged(newText, oldText string) {
 | 
				
			||||||
	for _, listener := range GetTextChangedListeners(edit) {
 | 
						for _, listener := range getTwoArgEventListeners[EditView, string](edit, nil, EditTextChangedEvent) {
 | 
				
			||||||
		listener(edit, newText, oldText)
 | 
							listener.Run(edit, newText, oldText)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if listener, ok := edit.changeListener[Text]; ok {
 | 
						if listener, ok := edit.changeListener[Text]; ok {
 | 
				
			||||||
		listener(edit, Text)
 | 
							listener(edit, Text)
 | 
				
			||||||
| 
						 | 
					@ -461,10 +461,19 @@ func IsSpellcheck(view View, subviewID ...string) bool {
 | 
				
			||||||
// GetTextChangedListeners returns the TextChangedListener list of an EditView or MultiLineEditView subview.
 | 
					// GetTextChangedListeners returns the TextChangedListener list of an EditView or MultiLineEditView subview.
 | 
				
			||||||
// If there are no listeners then the empty list is returned
 | 
					// If there are no listeners then the empty list is returned
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					// Result elements can be of the following types:
 | 
				
			||||||
 | 
					//   - func(rui.EditView, string, string),
 | 
				
			||||||
 | 
					//   - func(rui.EditView, string),
 | 
				
			||||||
 | 
					//   - func(rui.EditView),
 | 
				
			||||||
 | 
					//   - func(string, string),
 | 
				
			||||||
 | 
					//   - func(string),
 | 
				
			||||||
 | 
					//   - func(),
 | 
				
			||||||
 | 
					//   - string.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
// The second argument (subviewID) specifies the path to the child element whose value needs to be returned.
 | 
					// The second argument (subviewID) specifies the path to the child element whose value needs to be returned.
 | 
				
			||||||
// If it is not specified then a value from the first argument (view) is returned.
 | 
					// If it is not specified then a value from the first argument (view) is returned.
 | 
				
			||||||
func GetTextChangedListeners(view View, subviewID ...string) []func(EditView, string, string) {
 | 
					func GetTextChangedListeners(view View, subviewID ...string) []any {
 | 
				
			||||||
	return getTwoArgEventListeners[EditView, string](view, subviewID, EditTextChangedEvent)
 | 
						return getTwoArgEventRawListeners[EditView, string](view, subviewID, EditTextChangedEvent)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetEditViewType returns a value of the Type property of EditView.
 | 
					// GetEditViewType returns a value of the Type property of EditView.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										589
									
								
								events.go
								
								
								
								
							
							
						
						
									
										589
									
								
								events.go
								
								
								
								
							| 
						 | 
					@ -41,161 +41,32 @@ var eventJsFunc = map[PropertyName]struct{ jsEvent, jsFunc string }{
 | 
				
			||||||
	DragLeaveEvent:          {jsEvent: "ondragleave", jsFunc: "dragLeaveEvent"},
 | 
						DragLeaveEvent:          {jsEvent: "ondragleave", jsFunc: "dragLeaveEvent"},
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					func viewEventsHtml[T any](view View, events []PropertyName, buffer *strings.Builder) {
 | 
				
			||||||
type oneArgListener[V View, E any] interface {
 | 
						for _, tag := range events {
 | 
				
			||||||
	call(V, E)
 | 
							if js, ok := eventJsFunc[tag]; ok {
 | 
				
			||||||
	listener() func(V, E)
 | 
								if value := getOneArgEventListeners[View, T](view, nil, tag); len(value) > 0 {
 | 
				
			||||||
	rawListener() any
 | 
									buffer.WriteString(js.jsEvent)
 | 
				
			||||||
}
 | 
									buffer.WriteString(`="`)
 | 
				
			||||||
 | 
									buffer.WriteString(js.jsFunc)
 | 
				
			||||||
type oneArgListener0[V View, E any] struct {
 | 
									buffer.WriteString(`(this, event)" `)
 | 
				
			||||||
	fn func()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type oneArgListenerV[V View, E any] struct {
 | 
					 | 
				
			||||||
	fn func(V)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type oneArgListenerE[V View, E any] struct {
 | 
					 | 
				
			||||||
	fn func(E)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type oneArgListenerVE[V View, E any] struct {
 | 
					 | 
				
			||||||
	fn func(V, E)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type oneArgListenerBinding[V View, E any] struct {
 | 
					 | 
				
			||||||
	name string
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func newOneArgListener0[V View, E any](fn func()) oneArgListener[V, E] {
 | 
					 | 
				
			||||||
	obj := new(oneArgListener0[V, E])
 | 
					 | 
				
			||||||
	obj.fn = fn
 | 
					 | 
				
			||||||
	return obj
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (data *oneArgListener0[V, E]) call(_ V, _ E) {
 | 
					 | 
				
			||||||
	data.fn()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (data *oneArgListener0[V, E]) listener() func(V, E) {
 | 
					 | 
				
			||||||
	return data.call
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (data *oneArgListener0[V, E]) rawListener() any {
 | 
					 | 
				
			||||||
	return data.fn
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func newOneArgListenerV[V View, E any](fn func(V)) oneArgListener[V, E] {
 | 
					 | 
				
			||||||
	obj := new(oneArgListenerV[V, E])
 | 
					 | 
				
			||||||
	obj.fn = fn
 | 
					 | 
				
			||||||
	return obj
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (data *oneArgListenerV[V, E]) call(view V, _ E) {
 | 
					 | 
				
			||||||
	data.fn(view)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (data *oneArgListenerV[V, E]) listener() func(V, E) {
 | 
					 | 
				
			||||||
	return data.call
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (data *oneArgListenerV[V, E]) rawListener() any {
 | 
					 | 
				
			||||||
	return data.fn
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func newOneArgListenerE[V View, E any](fn func(E)) oneArgListener[V, E] {
 | 
					 | 
				
			||||||
	obj := new(oneArgListenerE[V, E])
 | 
					 | 
				
			||||||
	obj.fn = fn
 | 
					 | 
				
			||||||
	return obj
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (data *oneArgListenerE[V, E]) call(_ V, event E) {
 | 
					 | 
				
			||||||
	data.fn(event)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (data *oneArgListenerE[V, E]) listener() func(V, E) {
 | 
					 | 
				
			||||||
	return data.call
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (data *oneArgListenerE[V, E]) rawListener() any {
 | 
					 | 
				
			||||||
	return data.fn
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func newOneArgListenerVE[V View, E any](fn func(V, E)) oneArgListener[V, E] {
 | 
					 | 
				
			||||||
	obj := new(oneArgListenerVE[V, E])
 | 
					 | 
				
			||||||
	obj.fn = fn
 | 
					 | 
				
			||||||
	return obj
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (data *oneArgListenerVE[V, E]) call(view V, arg E) {
 | 
					 | 
				
			||||||
	data.fn(view, arg)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (data *oneArgListenerVE[V, E]) listener() func(V, E) {
 | 
					 | 
				
			||||||
	return data.fn
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (data *oneArgListenerVE[V, E]) rawListener() any {
 | 
					 | 
				
			||||||
	return data.fn
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func newOneArgListenerBinding[V View, E any](name string) oneArgListener[V, E] {
 | 
					 | 
				
			||||||
	obj := new(oneArgListenerBinding[V, E])
 | 
					 | 
				
			||||||
	obj.name = name
 | 
					 | 
				
			||||||
	return obj
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (data *oneArgListenerBinding[V, E]) call(view V, event E) {
 | 
					 | 
				
			||||||
	bind := view.binding()
 | 
					 | 
				
			||||||
	if bind == nil {
 | 
					 | 
				
			||||||
		ErrorLogF(`There is no a binding object for call "%s"`, data.name)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	val := reflect.ValueOf(bind)
 | 
					 | 
				
			||||||
	method := val.MethodByName(data.name)
 | 
					 | 
				
			||||||
	if !method.IsValid() {
 | 
					 | 
				
			||||||
		ErrorLogF(`The "%s" method is not valid`, data.name)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	methodType := method.Type()
 | 
					 | 
				
			||||||
	var args []reflect.Value = nil
 | 
					 | 
				
			||||||
	switch methodType.NumIn() {
 | 
					 | 
				
			||||||
	case 0:
 | 
					 | 
				
			||||||
		args = []reflect.Value{}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case 1:
 | 
					 | 
				
			||||||
		inType := methodType.In(0)
 | 
					 | 
				
			||||||
		if inType == reflect.TypeOf(view) {
 | 
					 | 
				
			||||||
			args = []reflect.Value{reflect.ValueOf(view)}
 | 
					 | 
				
			||||||
		} else if inType == reflect.TypeOf(event) {
 | 
					 | 
				
			||||||
			args = []reflect.Value{reflect.ValueOf(event)}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case 2:
 | 
					 | 
				
			||||||
		if methodType.In(0) == reflect.TypeOf(view) && methodType.In(1) == reflect.TypeOf(event) {
 | 
					 | 
				
			||||||
			args = []reflect.Value{reflect.ValueOf(view), reflect.ValueOf(event)}
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if args != nil {
 | 
					func updateEventListenerHtml(view View, tag PropertyName) {
 | 
				
			||||||
		method.Call(args)
 | 
						if js, ok := eventJsFunc[tag]; ok {
 | 
				
			||||||
 | 
							value := view.getRaw(tag)
 | 
				
			||||||
 | 
							session := view.Session()
 | 
				
			||||||
 | 
							htmlID := view.htmlID()
 | 
				
			||||||
 | 
							if value == nil {
 | 
				
			||||||
 | 
								session.removeProperty(view.htmlID(), js.jsEvent)
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
		ErrorLogF(`Unsupported prototype of "%s" method`, data.name)
 | 
								session.updateProperty(htmlID, js.jsEvent, js.jsFunc+"(this, event)")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (data *oneArgListenerBinding[V, E]) listener() func(V, E) {
 | 
					 | 
				
			||||||
	return data.call
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (data *oneArgListenerBinding[V, E]) rawListener() any {
 | 
					 | 
				
			||||||
	return data.name
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func valueToNoArgEventListeners[V any](view View, value any) ([]func(V), bool) {
 | 
					func valueToNoArgEventListeners[V any](view View, value any) ([]func(V), bool) {
 | 
				
			||||||
	if value == nil {
 | 
						if value == nil {
 | 
				
			||||||
		return nil, true
 | 
							return nil, true
 | 
				
			||||||
| 
						 | 
					@ -303,326 +174,6 @@ func valueToNoArgEventListeners[V any](view View, value any) ([]func(V), bool) {
 | 
				
			||||||
	return nil, false
 | 
						return nil, false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
	func valueToOneArgEventListeners[V View, E any](view View, value any) ([]oneArgListener[V, E], bool) {
 | 
					 | 
				
			||||||
		if value == nil {
 | 
					 | 
				
			||||||
			return nil, true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		switch value := value.(type) {
 | 
					 | 
				
			||||||
		case string:
 | 
					 | 
				
			||||||
			return []oneArgListener[V, E]{newOneArgListenerBinding[V, E](value)}, true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case func(V, E):
 | 
					 | 
				
			||||||
			return []oneArgListener[V, E]{newOneArgListenerVE[V, E](value)}, true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case func(V):
 | 
					 | 
				
			||||||
			return []oneArgListener[V, E]{newOneArgListenerV[V, E](value)}, true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case func(E):
 | 
					 | 
				
			||||||
			return []oneArgListener[V, E]{newOneArgListenerE[V, E](value)}, true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case func():
 | 
					 | 
				
			||||||
			return []oneArgListener[V, E]{newOneArgListener0[V, E](value)}, true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case []func(V, E):
 | 
					 | 
				
			||||||
			result := make([]oneArgListener[V, E], 0, len(value))
 | 
					 | 
				
			||||||
			for _, fn := range value {
 | 
					 | 
				
			||||||
				if fn != nil {
 | 
					 | 
				
			||||||
					result = append(result, newOneArgListenerVE[V, E](fn))
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return result, len(result) > 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case []func(E):
 | 
					 | 
				
			||||||
			result := make([]oneArgListener[V, E], 0, len(value))
 | 
					 | 
				
			||||||
			for _, fn := range value {
 | 
					 | 
				
			||||||
				if fn != nil {
 | 
					 | 
				
			||||||
					result = append(result, newOneArgListenerE[V, E](fn))
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return result, len(result) > 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case []func(V):
 | 
					 | 
				
			||||||
			result := make([]oneArgListener[V, E], 0, len(value))
 | 
					 | 
				
			||||||
			for _, fn := range value {
 | 
					 | 
				
			||||||
				if fn != nil {
 | 
					 | 
				
			||||||
					result = append(result, newOneArgListenerV[V, E](fn))
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return result, len(result) > 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case []func():
 | 
					 | 
				
			||||||
			result := make([]oneArgListener[V, E], 0, len(value))
 | 
					 | 
				
			||||||
			for _, fn := range value {
 | 
					 | 
				
			||||||
				if fn != nil {
 | 
					 | 
				
			||||||
					result = append(result, newOneArgListener0[V, E](fn))
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return result, len(result) > 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		case []any:
 | 
					 | 
				
			||||||
			result := make([]oneArgListener[V, E], 0, len(value))
 | 
					 | 
				
			||||||
			for _, v := range value {
 | 
					 | 
				
			||||||
				if v != nil {
 | 
					 | 
				
			||||||
					switch v := v.(type) {
 | 
					 | 
				
			||||||
					case func(V, E):
 | 
					 | 
				
			||||||
						result = append(result, newOneArgListenerVE[V, E](v))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					case func(E):
 | 
					 | 
				
			||||||
						result = append(result, newOneArgListenerE[V, E](v))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					case func(V):
 | 
					 | 
				
			||||||
						result = append(result, newOneArgListenerV[V, E](v))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					case func():
 | 
					 | 
				
			||||||
						result = append(result, newOneArgListener0[V, E](v))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					case string:
 | 
					 | 
				
			||||||
						result = append(result, newOneArgListenerBinding[V, E](v))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					default:
 | 
					 | 
				
			||||||
						return nil, false
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return result, len(result) > 0
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return nil, false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
func valueToTwoArgEventListeners[V View, E any](view View, value any) ([]func(V, E, E), bool) {
 | 
					 | 
				
			||||||
	if value == nil {
 | 
					 | 
				
			||||||
		return nil, true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch value := value.(type) {
 | 
					 | 
				
			||||||
	case string:
 | 
					 | 
				
			||||||
		fn := func(view V, val1 E, val2 E) {
 | 
					 | 
				
			||||||
			bind := view.binding()
 | 
					 | 
				
			||||||
			if bind == nil {
 | 
					 | 
				
			||||||
				ErrorLogF(`There is no a binding object for call "%s"`, value)
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			val := reflect.ValueOf(bind)
 | 
					 | 
				
			||||||
			method := val.MethodByName(value)
 | 
					 | 
				
			||||||
			if !method.IsValid() {
 | 
					 | 
				
			||||||
				ErrorLogF(`The "%s" method is not valid`, value)
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			methodType := method.Type()
 | 
					 | 
				
			||||||
			var args []reflect.Value = nil
 | 
					 | 
				
			||||||
			switch methodType.NumIn() {
 | 
					 | 
				
			||||||
			case 0:
 | 
					 | 
				
			||||||
				args = []reflect.Value{}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			case 1:
 | 
					 | 
				
			||||||
				inType := methodType.In(0)
 | 
					 | 
				
			||||||
				if inType == reflect.TypeOf(view) {
 | 
					 | 
				
			||||||
					args = []reflect.Value{reflect.ValueOf(view)}
 | 
					 | 
				
			||||||
				} else if inType == reflect.TypeOf(val1) {
 | 
					 | 
				
			||||||
					args = []reflect.Value{reflect.ValueOf(val1)}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			case 2:
 | 
					 | 
				
			||||||
				valType := reflect.TypeOf(val1)
 | 
					 | 
				
			||||||
				if methodType.In(0) == reflect.TypeOf(view) && methodType.In(1) == valType {
 | 
					 | 
				
			||||||
					args = []reflect.Value{reflect.ValueOf(view), reflect.ValueOf(val1)}
 | 
					 | 
				
			||||||
				} else if methodType.In(0) == valType && methodType.In(1) == valType {
 | 
					 | 
				
			||||||
					args = []reflect.Value{reflect.ValueOf(val1), reflect.ValueOf(val2)}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			case 3:
 | 
					 | 
				
			||||||
				valType := reflect.TypeOf(val1)
 | 
					 | 
				
			||||||
				if methodType.In(0) == reflect.TypeOf(view) && methodType.In(1) == valType && methodType.In(2) == valType {
 | 
					 | 
				
			||||||
					args = []reflect.Value{reflect.ValueOf(view), reflect.ValueOf(val1), reflect.ValueOf(val2)}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if args != nil {
 | 
					 | 
				
			||||||
				method.Call(args)
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				ErrorLogF(`Unsupported prototype of "%s" method`, value)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return []func(V, E, E){fn}, true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case func(V, E, E):
 | 
					 | 
				
			||||||
		return []func(V, E, E){value}, true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case func(V, E):
 | 
					 | 
				
			||||||
		fn := func(v V, val, _ E) {
 | 
					 | 
				
			||||||
			value(v, val)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return []func(V, E, E){fn}, true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case func(E, E):
 | 
					 | 
				
			||||||
		fn := func(_ V, val, old E) {
 | 
					 | 
				
			||||||
			value(val, old)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return []func(V, E, E){fn}, true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case func(E):
 | 
					 | 
				
			||||||
		fn := func(_ V, val, _ E) {
 | 
					 | 
				
			||||||
			value(val)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return []func(V, E, E){fn}, true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case func(V):
 | 
					 | 
				
			||||||
		fn := func(v V, _, _ E) {
 | 
					 | 
				
			||||||
			value(v)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return []func(V, E, E){fn}, true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case func():
 | 
					 | 
				
			||||||
		fn := func(V, E, E) {
 | 
					 | 
				
			||||||
			value()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return []func(V, E, E){fn}, true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case []func(V, E, E):
 | 
					 | 
				
			||||||
		if len(value) == 0 {
 | 
					 | 
				
			||||||
			return nil, true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		for _, fn := range value {
 | 
					 | 
				
			||||||
			if fn == nil {
 | 
					 | 
				
			||||||
				return nil, false
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return value, true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case []func(V, E):
 | 
					 | 
				
			||||||
		count := len(value)
 | 
					 | 
				
			||||||
		if count == 0 {
 | 
					 | 
				
			||||||
			return nil, true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		listeners := make([]func(V, E, E), count)
 | 
					 | 
				
			||||||
		for i, fn := range value {
 | 
					 | 
				
			||||||
			if fn == nil {
 | 
					 | 
				
			||||||
				return nil, false
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			listeners[i] = func(view V, val, _ E) {
 | 
					 | 
				
			||||||
				fn(view, val)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return listeners, true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case []func(E):
 | 
					 | 
				
			||||||
		count := len(value)
 | 
					 | 
				
			||||||
		if count == 0 {
 | 
					 | 
				
			||||||
			return nil, true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		listeners := make([]func(V, E, E), count)
 | 
					 | 
				
			||||||
		for i, fn := range value {
 | 
					 | 
				
			||||||
			if fn == nil {
 | 
					 | 
				
			||||||
				return nil, false
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			listeners[i] = func(_ V, val, _ E) {
 | 
					 | 
				
			||||||
				fn(val)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return listeners, true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case []func(E, E):
 | 
					 | 
				
			||||||
		count := len(value)
 | 
					 | 
				
			||||||
		if count == 0 {
 | 
					 | 
				
			||||||
			return nil, true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		listeners := make([]func(V, E, E), count)
 | 
					 | 
				
			||||||
		for i, fn := range value {
 | 
					 | 
				
			||||||
			if fn == nil {
 | 
					 | 
				
			||||||
				return nil, false
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			listeners[i] = func(_ V, val, old E) {
 | 
					 | 
				
			||||||
				fn(val, old)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return listeners, true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case []func(V):
 | 
					 | 
				
			||||||
		count := len(value)
 | 
					 | 
				
			||||||
		if count == 0 {
 | 
					 | 
				
			||||||
			return nil, true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		listeners := make([]func(V, E, E), count)
 | 
					 | 
				
			||||||
		for i, fn := range value {
 | 
					 | 
				
			||||||
			if fn == nil {
 | 
					 | 
				
			||||||
				return nil, false
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			listeners[i] = func(view V, _, _ E) {
 | 
					 | 
				
			||||||
				fn(view)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return listeners, true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case []func():
 | 
					 | 
				
			||||||
		count := len(value)
 | 
					 | 
				
			||||||
		if count == 0 {
 | 
					 | 
				
			||||||
			return nil, true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		listeners := make([]func(V, E, E), count)
 | 
					 | 
				
			||||||
		for i, fn := range value {
 | 
					 | 
				
			||||||
			if fn == nil {
 | 
					 | 
				
			||||||
				return nil, false
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			listeners[i] = func(V, E, E) {
 | 
					 | 
				
			||||||
				fn()
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return listeners, true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case []any:
 | 
					 | 
				
			||||||
		count := len(value)
 | 
					 | 
				
			||||||
		if count == 0 {
 | 
					 | 
				
			||||||
			return nil, true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		listeners := make([]func(V, E, E), count)
 | 
					 | 
				
			||||||
		for i, v := range value {
 | 
					 | 
				
			||||||
			if v == nil {
 | 
					 | 
				
			||||||
				return nil, false
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			switch fn := v.(type) {
 | 
					 | 
				
			||||||
			case func(V, E, E):
 | 
					 | 
				
			||||||
				listeners[i] = fn
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			case func(V, E):
 | 
					 | 
				
			||||||
				listeners[i] = func(view V, val, _ E) {
 | 
					 | 
				
			||||||
					fn(view, val)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			case func(E, E):
 | 
					 | 
				
			||||||
				listeners[i] = func(_ V, val, old E) {
 | 
					 | 
				
			||||||
					fn(val, old)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			case func(E):
 | 
					 | 
				
			||||||
				listeners[i] = func(_ V, val, _ E) {
 | 
					 | 
				
			||||||
					fn(val)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			case func(V):
 | 
					 | 
				
			||||||
				listeners[i] = func(view V, _, _ E) {
 | 
					 | 
				
			||||||
					fn(view)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			case func():
 | 
					 | 
				
			||||||
				listeners[i] = func(V, E, E) {
 | 
					 | 
				
			||||||
					fn()
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			default:
 | 
					 | 
				
			||||||
				return nil, false
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return listeners, true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil, false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func getNoArgEventListeners[V View](view View, subviewID []string, tag PropertyName) []func(V) {
 | 
					func getNoArgEventListeners[V View](view View, subviewID []string, tag PropertyName) []func(V) {
 | 
				
			||||||
	if view = getSubview(view, subviewID); view != nil {
 | 
						if view = getSubview(view, subviewID); view != nil {
 | 
				
			||||||
		if value := view.Get(tag); value != nil {
 | 
							if value := view.Get(tag); value != nil {
 | 
				
			||||||
| 
						 | 
					@ -634,38 +185,6 @@ func getNoArgEventListeners[V View](view View, subviewID []string, tag PropertyN
 | 
				
			||||||
	return []func(V){}
 | 
						return []func(V){}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
	func getOneArgEventListeners[V View, E any](view View, subviewID []string, tag PropertyName) []oneArgListener[V, E] {
 | 
					 | 
				
			||||||
		if view = getSubview(view, subviewID); view != nil {
 | 
					 | 
				
			||||||
			if value := view.Get(tag); value != nil {
 | 
					 | 
				
			||||||
				if result, ok := value.([]oneArgListener[V, E]); ok {
 | 
					 | 
				
			||||||
					return result
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return []oneArgListener[V, E]{}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	func getOneArgEventRawListeners[V View, E any](view View, subviewID []string, tag PropertyName) []any {
 | 
					 | 
				
			||||||
		listeners := getOneArgEventListeners[V, E](view, subviewID, tag)
 | 
					 | 
				
			||||||
		result := make([]any, len(listeners))
 | 
					 | 
				
			||||||
		for i, l := range listeners {
 | 
					 | 
				
			||||||
			result[i] = l.rawListener()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return result
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
func getTwoArgEventListeners[V View, E any](view View, subviewID []string, tag PropertyName) []func(V, E, E) {
 | 
					 | 
				
			||||||
	if view = getSubview(view, subviewID); view != nil {
 | 
					 | 
				
			||||||
		if value := view.Get(tag); value != nil {
 | 
					 | 
				
			||||||
			if result, ok := value.([]func(V, E, E)); ok {
 | 
					 | 
				
			||||||
				return result
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return []func(V, E, E){}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func setNoArgEventListener[V View](view View, tag PropertyName, value any) []PropertyName {
 | 
					func setNoArgEventListener[V View](view View, tag PropertyName, value any) []PropertyName {
 | 
				
			||||||
	if listeners, ok := valueToNoArgEventListeners[V](view, value); ok {
 | 
						if listeners, ok := valueToNoArgEventListeners[V](view, value); ok {
 | 
				
			||||||
		if len(listeners) > 0 {
 | 
							if len(listeners) > 0 {
 | 
				
			||||||
| 
						 | 
					@ -680,73 +199,3 @@ func setNoArgEventListener[V View](view View, tag PropertyName, value any) []Pro
 | 
				
			||||||
	notCompatibleType(tag, value)
 | 
						notCompatibleType(tag, value)
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
func setOneArgEventListener[V View, T any](view View, tag PropertyName, value any) []PropertyName {
 | 
					 | 
				
			||||||
	if listeners, ok := valueToOneArgEventListeners[V, T](view, value); ok {
 | 
					 | 
				
			||||||
		if len(listeners) > 0 {
 | 
					 | 
				
			||||||
			view.setRaw(tag, listeners)
 | 
					 | 
				
			||||||
		} else if view.getRaw(tag) != nil {
 | 
					 | 
				
			||||||
			view.setRaw(tag, nil)
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			return []PropertyName{}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return []PropertyName{tag}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	notCompatibleType(tag, value)
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func setTwoArgEventListener[V View, T any](view View, tag PropertyName, value any) []PropertyName {
 | 
					 | 
				
			||||||
	listeners, ok := valueToTwoArgEventListeners[V, T](view, value)
 | 
					 | 
				
			||||||
	if !ok {
 | 
					 | 
				
			||||||
		notCompatibleType(tag, value)
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(listeners) > 0 {
 | 
					 | 
				
			||||||
		view.setRaw(tag, listeners)
 | 
					 | 
				
			||||||
	} else if view.getRaw(tag) != nil {
 | 
					 | 
				
			||||||
		view.setRaw(tag, nil)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		return []PropertyName{}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return []PropertyName{tag}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func viewEventsHtml[T any](view View, events []PropertyName, buffer *strings.Builder) {
 | 
					 | 
				
			||||||
	for _, tag := range events {
 | 
					 | 
				
			||||||
		if js, ok := eventJsFunc[tag]; ok {
 | 
					 | 
				
			||||||
			if value := getOneArgEventListeners[View, T](view, nil, tag); len(value) > 0 {
 | 
					 | 
				
			||||||
				buffer.WriteString(js.jsEvent)
 | 
					 | 
				
			||||||
				buffer.WriteString(`="`)
 | 
					 | 
				
			||||||
				buffer.WriteString(js.jsFunc)
 | 
					 | 
				
			||||||
				buffer.WriteString(`(this, event)" `)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		/*if value := view.getRaw(tag); value != nil {
 | 
					 | 
				
			||||||
			if js, ok := eventJsFunc[tag]; ok {
 | 
					 | 
				
			||||||
				if listeners, ok := value.([] func(View, T)); ok && len(listeners) > 0 {
 | 
					 | 
				
			||||||
					buffer.WriteString(js.jsEvent)
 | 
					 | 
				
			||||||
					buffer.WriteString(`="`)
 | 
					 | 
				
			||||||
					buffer.WriteString(js.jsFunc)
 | 
					 | 
				
			||||||
					buffer.WriteString(`(this, event)" `)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		*/
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func updateEventListenerHtml(view View, tag PropertyName) {
 | 
					 | 
				
			||||||
	if js, ok := eventJsFunc[tag]; ok {
 | 
					 | 
				
			||||||
		value := view.getRaw(tag)
 | 
					 | 
				
			||||||
		session := view.Session()
 | 
					 | 
				
			||||||
		htmlID := view.htmlID()
 | 
					 | 
				
			||||||
		if value == nil {
 | 
					 | 
				
			||||||
			session.removeProperty(view.htmlID(), js.jsEvent)
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			session.updateProperty(htmlID, js.jsEvent, js.jsFunc+"(this, event)")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,339 @@
 | 
				
			||||||
 | 
					package rui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "reflect"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type twoArgListener[V View, E any] interface {
 | 
				
			||||||
 | 
						Run(V, E, E)
 | 
				
			||||||
 | 
						rawListener() any
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type twoArgListener0[V View, E any] struct {
 | 
				
			||||||
 | 
						fn func()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type twoArgListenerV[V View, E any] struct {
 | 
				
			||||||
 | 
						fn func(V)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type twoArgListenerE[V View, E any] struct {
 | 
				
			||||||
 | 
						fn func(E)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type twoArgListenerVE[V View, E any] struct {
 | 
				
			||||||
 | 
						fn func(V, E)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type twoArgListenerEE[V View, E any] struct {
 | 
				
			||||||
 | 
						fn func(E, E)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type twoArgListenerVEE[V View, E any] struct {
 | 
				
			||||||
 | 
						fn func(V, E, E)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type twoArgListenerBinding[V View, E any] struct {
 | 
				
			||||||
 | 
						name string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func newTwoArgListener0[V View, E any](fn func()) twoArgListener[V, E] {
 | 
				
			||||||
 | 
						obj := new(twoArgListener0[V, E])
 | 
				
			||||||
 | 
						obj.fn = fn
 | 
				
			||||||
 | 
						return obj
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (data *twoArgListener0[V, E]) Run(_ V, _ E, _ E) {
 | 
				
			||||||
 | 
						data.fn()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (data *twoArgListener0[V, E]) rawListener() any {
 | 
				
			||||||
 | 
						return data.fn
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func newTwoArgListenerV[V View, E any](fn func(V)) twoArgListener[V, E] {
 | 
				
			||||||
 | 
						obj := new(twoArgListenerV[V, E])
 | 
				
			||||||
 | 
						obj.fn = fn
 | 
				
			||||||
 | 
						return obj
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (data *twoArgListenerV[V, E]) Run(view V, _ E, _ E) {
 | 
				
			||||||
 | 
						data.fn(view)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (data *twoArgListenerV[V, E]) rawListener() any {
 | 
				
			||||||
 | 
						return data.fn
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func newTwoArgListenerE[V View, E any](fn func(E)) twoArgListener[V, E] {
 | 
				
			||||||
 | 
						obj := new(twoArgListenerE[V, E])
 | 
				
			||||||
 | 
						obj.fn = fn
 | 
				
			||||||
 | 
						return obj
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (data *twoArgListenerE[V, E]) Run(_ V, arg E, _ E) {
 | 
				
			||||||
 | 
						data.fn(arg)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (data *twoArgListenerE[V, E]) rawListener() any {
 | 
				
			||||||
 | 
						return data.fn
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func newTwoArgListenerVE[V View, E any](fn func(V, E)) twoArgListener[V, E] {
 | 
				
			||||||
 | 
						obj := new(twoArgListenerVE[V, E])
 | 
				
			||||||
 | 
						obj.fn = fn
 | 
				
			||||||
 | 
						return obj
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (data *twoArgListenerVE[V, E]) Run(view V, arg E, _ E) {
 | 
				
			||||||
 | 
						data.fn(view, arg)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (data *twoArgListenerVE[V, E]) rawListener() any {
 | 
				
			||||||
 | 
						return data.fn
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func newTwoArgListenerEE[V View, E any](fn func(E, E)) twoArgListener[V, E] {
 | 
				
			||||||
 | 
						obj := new(twoArgListenerEE[V, E])
 | 
				
			||||||
 | 
						obj.fn = fn
 | 
				
			||||||
 | 
						return obj
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (data *twoArgListenerEE[V, E]) Run(_ V, arg1 E, arg2 E) {
 | 
				
			||||||
 | 
						data.fn(arg1, arg2)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (data *twoArgListenerEE[V, E]) rawListener() any {
 | 
				
			||||||
 | 
						return data.fn
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func newTwoArgListenerVEE[V View, E any](fn func(V, E, E)) twoArgListener[V, E] {
 | 
				
			||||||
 | 
						obj := new(twoArgListenerVEE[V, E])
 | 
				
			||||||
 | 
						obj.fn = fn
 | 
				
			||||||
 | 
						return obj
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (data *twoArgListenerVEE[V, E]) Run(view V, arg1 E, arg2 E) {
 | 
				
			||||||
 | 
						data.fn(view, arg1, arg2)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (data *twoArgListenerVEE[V, E]) rawListener() any {
 | 
				
			||||||
 | 
						return data.fn
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func newTwoArgListenerBinding[V View, E any](name string) twoArgListener[V, E] {
 | 
				
			||||||
 | 
						obj := new(twoArgListenerBinding[V, E])
 | 
				
			||||||
 | 
						obj.name = name
 | 
				
			||||||
 | 
						return obj
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (data *twoArgListenerBinding[V, E]) Run(view V, arg1 E, arg2 E) {
 | 
				
			||||||
 | 
						bind := view.binding()
 | 
				
			||||||
 | 
						if bind == nil {
 | 
				
			||||||
 | 
							ErrorLogF(`There is no a binding object for call "%s"`, data.name)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						val := reflect.ValueOf(bind)
 | 
				
			||||||
 | 
						method := val.MethodByName(data.name)
 | 
				
			||||||
 | 
						if !method.IsValid() {
 | 
				
			||||||
 | 
							ErrorLogF(`The "%s" method is not valid`, data.name)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						methodType := method.Type()
 | 
				
			||||||
 | 
						var args []reflect.Value = nil
 | 
				
			||||||
 | 
						switch methodType.NumIn() {
 | 
				
			||||||
 | 
						case 0:
 | 
				
			||||||
 | 
							args = []reflect.Value{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case 1:
 | 
				
			||||||
 | 
							inType := methodType.In(0)
 | 
				
			||||||
 | 
							if inType == reflect.TypeOf(view) {
 | 
				
			||||||
 | 
								args = []reflect.Value{reflect.ValueOf(view)}
 | 
				
			||||||
 | 
							} else if inType == reflect.TypeOf(arg1) {
 | 
				
			||||||
 | 
								args = []reflect.Value{reflect.ValueOf(arg1)}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case 2:
 | 
				
			||||||
 | 
							valType := reflect.TypeOf(arg1)
 | 
				
			||||||
 | 
							if methodType.In(0) == reflect.TypeOf(view) && methodType.In(1) == valType {
 | 
				
			||||||
 | 
								args = []reflect.Value{reflect.ValueOf(view), reflect.ValueOf(arg1)}
 | 
				
			||||||
 | 
							} else if methodType.In(0) == valType && methodType.In(1) == valType {
 | 
				
			||||||
 | 
								args = []reflect.Value{reflect.ValueOf(arg1), reflect.ValueOf(arg2)}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case 3:
 | 
				
			||||||
 | 
							valType := reflect.TypeOf(arg1)
 | 
				
			||||||
 | 
							if methodType.In(0) == reflect.TypeOf(view) && methodType.In(1) == valType && methodType.In(2) == valType {
 | 
				
			||||||
 | 
								args = []reflect.Value{reflect.ValueOf(view), reflect.ValueOf(arg1), reflect.ValueOf(arg2)}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if args != nil {
 | 
				
			||||||
 | 
							method.Call(args)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							ErrorLogF(`Unsupported prototype of "%s" method`, data.name)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (data *twoArgListenerBinding[V, E]) rawListener() any {
 | 
				
			||||||
 | 
						return data.name
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func valueToTwoArgEventListeners[V View, E any](value any) ([]twoArgListener[V, E], bool) {
 | 
				
			||||||
 | 
						if value == nil {
 | 
				
			||||||
 | 
							return nil, true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch value := value.(type) {
 | 
				
			||||||
 | 
						case []twoArgListener[V, E]:
 | 
				
			||||||
 | 
							return value, true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case twoArgListener[V, E]:
 | 
				
			||||||
 | 
							return []twoArgListener[V, E]{value}, true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case string:
 | 
				
			||||||
 | 
							return []twoArgListener[V, E]{newTwoArgListenerBinding[V, E](value)}, true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case func(V, E):
 | 
				
			||||||
 | 
							return []twoArgListener[V, E]{newTwoArgListenerVE(value)}, true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case func(V):
 | 
				
			||||||
 | 
							return []twoArgListener[V, E]{newTwoArgListenerV[V, E](value)}, true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case func(E):
 | 
				
			||||||
 | 
							return []twoArgListener[V, E]{newTwoArgListenerE[V](value)}, true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case func():
 | 
				
			||||||
 | 
							return []twoArgListener[V, E]{newTwoArgListener0[V, E](value)}, true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case func(E, E):
 | 
				
			||||||
 | 
							return []twoArgListener[V, E]{newTwoArgListenerEE[V](value)}, true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case func(V, E, E):
 | 
				
			||||||
 | 
							return []twoArgListener[V, E]{newTwoArgListenerVEE(value)}, true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case []func(V, E):
 | 
				
			||||||
 | 
							result := make([]twoArgListener[V, E], 0, len(value))
 | 
				
			||||||
 | 
							for _, fn := range value {
 | 
				
			||||||
 | 
								if fn != nil {
 | 
				
			||||||
 | 
									result = append(result, newTwoArgListenerVE(fn))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return result, len(result) > 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case []func(E):
 | 
				
			||||||
 | 
							result := make([]twoArgListener[V, E], 0, len(value))
 | 
				
			||||||
 | 
							for _, fn := range value {
 | 
				
			||||||
 | 
								if fn != nil {
 | 
				
			||||||
 | 
									result = append(result, newTwoArgListenerE[V](fn))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return result, len(result) > 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case []func(V):
 | 
				
			||||||
 | 
							result := make([]twoArgListener[V, E], 0, len(value))
 | 
				
			||||||
 | 
							for _, fn := range value {
 | 
				
			||||||
 | 
								if fn != nil {
 | 
				
			||||||
 | 
									result = append(result, newTwoArgListenerV[V, E](fn))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return result, len(result) > 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case []func():
 | 
				
			||||||
 | 
							result := make([]twoArgListener[V, E], 0, len(value))
 | 
				
			||||||
 | 
							for _, fn := range value {
 | 
				
			||||||
 | 
								if fn != nil {
 | 
				
			||||||
 | 
									result = append(result, newTwoArgListener0[V, E](fn))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return result, len(result) > 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case []func(E, E):
 | 
				
			||||||
 | 
							result := make([]twoArgListener[V, E], 0, len(value))
 | 
				
			||||||
 | 
							for _, fn := range value {
 | 
				
			||||||
 | 
								if fn != nil {
 | 
				
			||||||
 | 
									result = append(result, newTwoArgListenerEE[V](fn))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return result, len(result) > 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case []func(V, E, E):
 | 
				
			||||||
 | 
							result := make([]twoArgListener[V, E], 0, len(value))
 | 
				
			||||||
 | 
							for _, fn := range value {
 | 
				
			||||||
 | 
								if fn != nil {
 | 
				
			||||||
 | 
									result = append(result, newTwoArgListenerVEE(fn))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return result, len(result) > 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case []any:
 | 
				
			||||||
 | 
							result := make([]twoArgListener[V, E], 0, len(value))
 | 
				
			||||||
 | 
							for _, v := range value {
 | 
				
			||||||
 | 
								if v != nil {
 | 
				
			||||||
 | 
									switch v := v.(type) {
 | 
				
			||||||
 | 
									case func(V, E):
 | 
				
			||||||
 | 
										result = append(result, newTwoArgListenerVE(v))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									case func(E):
 | 
				
			||||||
 | 
										result = append(result, newTwoArgListenerE[V](v))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									case func(V):
 | 
				
			||||||
 | 
										result = append(result, newTwoArgListenerV[V, E](v))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									case func():
 | 
				
			||||||
 | 
										result = append(result, newTwoArgListener0[V, E](v))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									case func(E, E):
 | 
				
			||||||
 | 
										result = append(result, newTwoArgListenerEE[V](v))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									case func(V, E, E):
 | 
				
			||||||
 | 
										result = append(result, newTwoArgListenerVEE(v))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									case string:
 | 
				
			||||||
 | 
										result = append(result, newTwoArgListenerBinding[V, E](v))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									default:
 | 
				
			||||||
 | 
										return nil, false
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return result, len(result) > 0
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil, false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func setTwoArgEventListener[V View, T any](view View, tag PropertyName, value any) []PropertyName {
 | 
				
			||||||
 | 
						if listeners, ok := valueToTwoArgEventListeners[V, T](value); ok {
 | 
				
			||||||
 | 
							if len(listeners) > 0 {
 | 
				
			||||||
 | 
								view.setRaw(tag, listeners)
 | 
				
			||||||
 | 
							} else if view.getRaw(tag) != nil {
 | 
				
			||||||
 | 
								view.setRaw(tag, nil)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								return []PropertyName{}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return []PropertyName{tag}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						notCompatibleType(tag, value)
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getTwoArgEventListeners[V View, E any](view View, subviewID []string, tag PropertyName) []twoArgListener[V, E] {
 | 
				
			||||||
 | 
						if view = getSubview(view, subviewID); view != nil {
 | 
				
			||||||
 | 
							if value := view.Get(tag); value != nil {
 | 
				
			||||||
 | 
								if result, ok := value.([]twoArgListener[V, E]); ok {
 | 
				
			||||||
 | 
									return result
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return []twoArgListener[V, E]{}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getTwoArgEventRawListeners[V View, E any](view View, subviewID []string, tag PropertyName) []any {
 | 
				
			||||||
 | 
						listeners := getTwoArgEventListeners[V, E](view, subviewID, tag)
 | 
				
			||||||
 | 
						result := make([]any, len(listeners))
 | 
				
			||||||
 | 
						for i, l := range listeners {
 | 
				
			||||||
 | 
							result[i] = l.rawListener()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return result
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -201,7 +201,7 @@ func (picker *numberPickerData) propertyChanged(tag PropertyName) {
 | 
				
			||||||
		format := picker.numberFormat()
 | 
							format := picker.numberFormat()
 | 
				
			||||||
		picker.Session().callFunc("setInputValue", picker.htmlID(), fmt.Sprintf(format, value))
 | 
							picker.Session().callFunc("setInputValue", picker.htmlID(), fmt.Sprintf(format, value))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if listeners := GetNumberChangedListeners(picker); len(listeners) > 0 {
 | 
							if listeners := getTwoArgEventListeners[NumberPicker, float64](picker, nil, NumberChangedEvent); len(listeners) > 0 {
 | 
				
			||||||
			old := 0.0
 | 
								old := 0.0
 | 
				
			||||||
			if val := picker.getRaw("old-number"); val != nil {
 | 
								if val := picker.getRaw("old-number"); val != nil {
 | 
				
			||||||
				if n, ok := val.(float64); ok {
 | 
									if n, ok := val.(float64); ok {
 | 
				
			||||||
| 
						 | 
					@ -210,7 +210,7 @@ func (picker *numberPickerData) propertyChanged(tag PropertyName) {
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if old != value {
 | 
								if old != value {
 | 
				
			||||||
				for _, listener := range listeners {
 | 
									for _, listener := range listeners {
 | 
				
			||||||
					listener(picker, value, old)
 | 
										listener.Run(picker, value, old)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -280,8 +280,8 @@ func (picker *numberPickerData) handleCommand(self View, command PropertyName, d
 | 
				
			||||||
				oldValue := GetNumberPickerValue(picker)
 | 
									oldValue := GetNumberPickerValue(picker)
 | 
				
			||||||
				picker.properties[NumberPickerValue] = text
 | 
									picker.properties[NumberPickerValue] = text
 | 
				
			||||||
				if value != oldValue {
 | 
									if value != oldValue {
 | 
				
			||||||
					for _, listener := range GetNumberChangedListeners(picker) {
 | 
										for _, listener := range getTwoArgEventListeners[NumberPicker, float64](picker, nil, NumberChangedEvent) {
 | 
				
			||||||
						listener(picker, value, oldValue)
 | 
											listener.Run(picker, value, oldValue)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					if listener, ok := picker.changeListener[NumberPickerValue]; ok {
 | 
										if listener, ok := picker.changeListener[NumberPickerValue]; ok {
 | 
				
			||||||
						listener(picker, NumberPickerValue)
 | 
											listener(picker, NumberPickerValue)
 | 
				
			||||||
| 
						 | 
					@ -359,10 +359,19 @@ func GetNumberPickerValue(view View, subviewID ...string) float64 {
 | 
				
			||||||
// GetNumberChangedListeners returns the NumberChangedListener list of an NumberPicker subview.
 | 
					// GetNumberChangedListeners returns the NumberChangedListener list of an NumberPicker subview.
 | 
				
			||||||
// If there are no listeners then the empty list is returned
 | 
					// If there are no listeners then the empty list is returned
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					// Result elements can be of the following types:
 | 
				
			||||||
 | 
					//   - func(rui.NumberPicker, float64, float64),
 | 
				
			||||||
 | 
					//   - func(rui.NumberPicker, float64),
 | 
				
			||||||
 | 
					//   - func(rui.NumberPicker),
 | 
				
			||||||
 | 
					//   - func(float64, float64),
 | 
				
			||||||
 | 
					//   - func(float64),
 | 
				
			||||||
 | 
					//   - func(),
 | 
				
			||||||
 | 
					//   - string.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
// The second argument (subviewID) specifies the path to the child element whose value needs to be returned.
 | 
					// The second argument (subviewID) specifies the path to the child element whose value needs to be returned.
 | 
				
			||||||
// If it is not specified then a value from the first argument (view) is returned.
 | 
					// If it is not specified then a value from the first argument (view) is returned.
 | 
				
			||||||
func GetNumberChangedListeners(view View, subviewID ...string) []func(NumberPicker, float64, float64) {
 | 
					func GetNumberChangedListeners(view View, subviewID ...string) []any {
 | 
				
			||||||
	return getTwoArgEventListeners[NumberPicker, float64](view, subviewID, NumberChangedEvent)
 | 
						return getTwoArgEventRawListeners[NumberPicker, float64](view, subviewID, NumberChangedEvent)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetNumberPickerPrecision returns the precision of displaying fractional part in editor of NumberPicker subview.
 | 
					// GetNumberPickerPrecision returns the precision of displaying fractional part in editor of NumberPicker subview.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										19
									
								
								tableView.go
								
								
								
								
							
							
						
						
									
										19
									
								
								tableView.go
								
								
								
								
							| 
						 | 
					@ -845,8 +845,17 @@ func (table *tableViewData) propertyChanged(tag PropertyName) {
 | 
				
			||||||
			current := tableViewCurrent(table)
 | 
								current := tableViewCurrent(table)
 | 
				
			||||||
			session.callFunc("setTableCellCursorByID", htmlID, current.Row, current.Column)
 | 
								session.callFunc("setTableCellCursorByID", htmlID, current.Row, current.Column)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								for _, listener := range getTwoArgEventListeners[TableView, int](table, nil, TableCellSelectedEvent) {
 | 
				
			||||||
 | 
									listener.Run(table, current.Row, current.Column)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case RowSelection:
 | 
							case RowSelection:
 | 
				
			||||||
			session.callFunc("setTableRowCursorByID", htmlID, tableViewCurrent(table).Row)
 | 
								current := tableViewCurrent(table)
 | 
				
			||||||
 | 
								session.callFunc("setTableRowCursorByID", htmlID, current.Row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								for _, listener := range getOneArgEventListeners[TableView, int](table, nil, TableRowSelectedEvent) {
 | 
				
			||||||
 | 
									listener.Run(table, current.Row)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case Gap:
 | 
						case Gap:
 | 
				
			||||||
| 
						 | 
					@ -1687,8 +1696,8 @@ func (table *tableViewData) handleCommand(self View, command PropertyName, data
 | 
				
			||||||
						listener(table, Current)
 | 
											listener(table, Current)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					for _, listener := range GetTableCellSelectedListeners(table) {
 | 
										for _, listener := range getTwoArgEventListeners[TableView, int](table, nil, TableCellSelectedEvent) {
 | 
				
			||||||
						listener(table, row, column)
 | 
											listener.Run(table, row, column)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					@ -1704,8 +1713,8 @@ func (table *tableViewData) handleCommand(self View, command PropertyName, data
 | 
				
			||||||
	case "cellClick":
 | 
						case "cellClick":
 | 
				
			||||||
		if row, ok := dataIntProperty(data, "row"); ok {
 | 
							if row, ok := dataIntProperty(data, "row"); ok {
 | 
				
			||||||
			if column, ok := dataIntProperty(data, "column"); ok {
 | 
								if column, ok := dataIntProperty(data, "column"); ok {
 | 
				
			||||||
				for _, listener := range GetTableCellClickedListeners(table) {
 | 
									for _, listener := range getTwoArgEventListeners[TableView, int](table, nil, TableCellClickedEvent) {
 | 
				
			||||||
					listener(table, row, column)
 | 
										listener.Run(table, row, column)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -149,19 +149,37 @@ func GetTableCurrent(view View, subviewID ...string) CellIndex {
 | 
				
			||||||
// GetTableCellClickedListeners returns listeners of event which occurs when the user clicks on a table cell.
 | 
					// GetTableCellClickedListeners returns listeners of event which occurs when the user clicks on a table cell.
 | 
				
			||||||
// If there are no listeners then the empty list is returned.
 | 
					// If there are no listeners then the empty list is returned.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					// Result elements can be of the following types:
 | 
				
			||||||
 | 
					//   - func(rui.TableView, int, int),
 | 
				
			||||||
 | 
					//   - func(rui.TableView, int),
 | 
				
			||||||
 | 
					//   - func(rui.TableView),
 | 
				
			||||||
 | 
					//   - func(int, int),
 | 
				
			||||||
 | 
					//   - func(int),
 | 
				
			||||||
 | 
					//   - func(),
 | 
				
			||||||
 | 
					//   - string.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
// The second argument (subviewID) specifies the path to the child element whose value needs to be returned.
 | 
					// The second argument (subviewID) specifies the path to the child element whose value needs to be returned.
 | 
				
			||||||
// If it is not specified then a value from the first argument (view) is returned.
 | 
					// If it is not specified then a value from the first argument (view) is returned.
 | 
				
			||||||
func GetTableCellClickedListeners(view View, subviewID ...string) []func(TableView, int, int) {
 | 
					func GetTableCellClickedListeners(view View, subviewID ...string) []any {
 | 
				
			||||||
	return getTwoArgEventListeners[TableView, int](view, subviewID, TableCellClickedEvent)
 | 
						return getTwoArgEventRawListeners[TableView, int](view, subviewID, TableCellClickedEvent)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetTableCellSelectedListeners returns listeners of event which occurs when a table cell becomes selected.
 | 
					// GetTableCellSelectedListeners returns listeners of event which occurs when a table cell becomes selected.
 | 
				
			||||||
// If there are no listeners then the empty list is returned.
 | 
					// If there are no listeners then the empty list is returned.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					// Result elements can be of the following types:
 | 
				
			||||||
 | 
					//   - func(rui.TableView, int, int),
 | 
				
			||||||
 | 
					//   - func(rui.TableView, int),
 | 
				
			||||||
 | 
					//   - func(rui.TableView),
 | 
				
			||||||
 | 
					//   - func(int, int),
 | 
				
			||||||
 | 
					//   - func(int),
 | 
				
			||||||
 | 
					//   - func(),
 | 
				
			||||||
 | 
					//   - string.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
// The second argument (subviewID) specifies the path to the child element whose value needs to be returned.
 | 
					// The second argument (subviewID) specifies the path to the child element whose value needs to be returned.
 | 
				
			||||||
// If it is not specified then a value from the first argument (view) is returned.
 | 
					// If it is not specified then a value from the first argument (view) is returned.
 | 
				
			||||||
func GetTableCellSelectedListeners(view View, subviewID ...string) []func(TableView, int, int) {
 | 
					func GetTableCellSelectedListeners(view View, subviewID ...string) []any {
 | 
				
			||||||
	return getTwoArgEventListeners[TableView, int](view, subviewID, TableCellSelectedEvent)
 | 
						return getTwoArgEventRawListeners[TableView, int](view, subviewID, TableCellSelectedEvent)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetTableRowClickedListeners returns listeners of event which occurs when the user clicks on a table row.
 | 
					// GetTableRowClickedListeners returns listeners of event which occurs when the user clicks on a table row.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -211,7 +211,7 @@ func (tabsLayout *tabsLayoutData) propertyChanged(tag PropertyName) {
 | 
				
			||||||
		if listeners := getTwoArgEventListeners[TabsLayout, int](tabsLayout, nil, CurrentTabChangedEvent); len(listeners) > 0 {
 | 
							if listeners := getTwoArgEventListeners[TabsLayout, int](tabsLayout, nil, CurrentTabChangedEvent); len(listeners) > 0 {
 | 
				
			||||||
			oldCurrent, _ := intProperty(tabsLayout, "old-current", session, -1)
 | 
								oldCurrent, _ := intProperty(tabsLayout, "old-current", session, -1)
 | 
				
			||||||
			for _, listener := range listeners {
 | 
								for _, listener := range listeners {
 | 
				
			||||||
				listener(tabsLayout, current, oldCurrent)
 | 
									listener.Run(tabsLayout, current, oldCurrent)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -427,7 +427,7 @@ func (tabsLayout *tabsLayoutData) Insert(view View, index int) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (tabsLayout *tabsLayoutData) currentChanged(newCurrent, oldCurrent int) {
 | 
					func (tabsLayout *tabsLayoutData) currentChanged(newCurrent, oldCurrent int) {
 | 
				
			||||||
	for _, listener := range getTwoArgEventListeners[TabsLayout, int](tabsLayout, nil, CurrentTabChangedEvent) {
 | 
						for _, listener := range getTwoArgEventListeners[TabsLayout, int](tabsLayout, nil, CurrentTabChangedEvent) {
 | 
				
			||||||
		listener(tabsLayout, newCurrent, oldCurrent)
 | 
							listener.Run(tabsLayout, newCurrent, oldCurrent)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if listener, ok := tabsLayout.changeListener[Current]; ok {
 | 
						if listener, ok := tabsLayout.changeListener[Current]; ok {
 | 
				
			||||||
		listener(tabsLayout, Current)
 | 
							listener(tabsLayout, Current)
 | 
				
			||||||
| 
						 | 
					@ -766,3 +766,20 @@ func (tabsLayout *tabsLayoutData) handleCommand(self View, command PropertyName,
 | 
				
			||||||
func GetTabCloseEventListeners(view View, subviewID ...string) []any {
 | 
					func GetTabCloseEventListeners(view View, subviewID ...string) []any {
 | 
				
			||||||
	return getOneArgEventRawListeners[TabsLayout, int](view, subviewID, TabCloseEvent)
 | 
						return getOneArgEventRawListeners[TabsLayout, int](view, subviewID, TabCloseEvent)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetCurrentTabChangedEventListeners returns the "current-tab-changed" listener list. If there are no listeners then the empty list is returned.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Result elements can be of the following types:
 | 
				
			||||||
 | 
					//   - func(rui.TabsLayout, int, int),
 | 
				
			||||||
 | 
					//   - func(rui.TabsLayout, int),
 | 
				
			||||||
 | 
					//   - func(rui.TabsLayout),
 | 
				
			||||||
 | 
					//   - func(int, int),
 | 
				
			||||||
 | 
					//   - func(int),
 | 
				
			||||||
 | 
					//   - func(),
 | 
				
			||||||
 | 
					//   - string.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The second argument (subviewID) specifies the path to the child element whose value needs to be returned.
 | 
				
			||||||
 | 
					// If it is not specified then a value from the first argument (view) is returned.
 | 
				
			||||||
 | 
					func GetCurrentTabChangedEventListeners(view View, subviewID ...string) []any {
 | 
				
			||||||
 | 
						return getTwoArgEventRawListeners[TabsLayout, int](view, subviewID, CurrentTabChangedEvent)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -246,7 +246,7 @@ func (picker *timePickerData) propertyChanged(tag PropertyName) {
 | 
				
			||||||
		value := GetTimePickerValue(picker)
 | 
							value := GetTimePickerValue(picker)
 | 
				
			||||||
		session.callFunc("setInputValue", picker.htmlID(), value.Format(timeFormat))
 | 
							session.callFunc("setInputValue", picker.htmlID(), value.Format(timeFormat))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if listeners := GetTimeChangedListeners(picker); len(listeners) > 0 {
 | 
							if listeners := getTwoArgEventListeners[TimePicker, time.Time](picker, nil, TimeChangedEvent); len(listeners) > 0 {
 | 
				
			||||||
			oldTime := time.Now()
 | 
								oldTime := time.Now()
 | 
				
			||||||
			if val := picker.getRaw("old-time"); val != nil {
 | 
								if val := picker.getRaw("old-time"); val != nil {
 | 
				
			||||||
				if time, ok := val.(time.Time); ok {
 | 
									if time, ok := val.(time.Time); ok {
 | 
				
			||||||
| 
						 | 
					@ -254,7 +254,7 @@ func (picker *timePickerData) propertyChanged(tag PropertyName) {
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			for _, listener := range listeners {
 | 
								for _, listener := range listeners {
 | 
				
			||||||
				listener(picker, value, oldTime)
 | 
									listener.Run(picker, value, oldTime)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -320,8 +320,8 @@ func (picker *timePickerData) handleCommand(self View, command PropertyName, dat
 | 
				
			||||||
				oldValue := GetTimePickerValue(picker)
 | 
									oldValue := GetTimePickerValue(picker)
 | 
				
			||||||
				picker.properties[TimePickerValue] = value
 | 
									picker.properties[TimePickerValue] = value
 | 
				
			||||||
				if value != oldValue {
 | 
									if value != oldValue {
 | 
				
			||||||
					for _, listener := range GetTimeChangedListeners(picker) {
 | 
										for _, listener := range getTwoArgEventListeners[TimePicker, time.Time](picker, nil, TimeChangedEvent) {
 | 
				
			||||||
						listener(picker, value, oldValue)
 | 
											listener.Run(picker, value, oldValue)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					if listener, ok := picker.changeListener[TimePickerValue]; ok {
 | 
										if listener, ok := picker.changeListener[TimePickerValue]; ok {
 | 
				
			||||||
						listener(picker, TimePickerValue)
 | 
											listener(picker, TimePickerValue)
 | 
				
			||||||
| 
						 | 
					@ -418,8 +418,17 @@ func GetTimePickerValue(view View, subviewID ...string) time.Time {
 | 
				
			||||||
// GetTimeChangedListeners returns the TimeChangedListener list of an TimePicker subview.
 | 
					// GetTimeChangedListeners returns the TimeChangedListener list of an TimePicker subview.
 | 
				
			||||||
// If there are no listeners then the empty list is returned
 | 
					// If there are no listeners then the empty list is returned
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					// Result elements can be of the following types:
 | 
				
			||||||
 | 
					//   - func(rui.TimePicker, time.Time, time.Time),
 | 
				
			||||||
 | 
					//   - func(rui.TimePicker, time.Time),
 | 
				
			||||||
 | 
					//   - func(rui.TimePicker),
 | 
				
			||||||
 | 
					//   - func(time.Time, time.Time),
 | 
				
			||||||
 | 
					//   - func(time.Time),
 | 
				
			||||||
 | 
					//   - func(),
 | 
				
			||||||
 | 
					//   - string.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
// The second argument (subviewID) specifies the path to the child element whose value needs to be returned.
 | 
					// The second argument (subviewID) specifies the path to the child element whose value needs to be returned.
 | 
				
			||||||
// If it is not specified then a value from the first argument (view) is returned.
 | 
					// If it is not specified then a value from the first argument (view) is returned.
 | 
				
			||||||
func GetTimeChangedListeners(view View, subviewID ...string) []func(TimePicker, time.Time, time.Time) {
 | 
					func GetTimeChangedListeners(view View, subviewID ...string) []any {
 | 
				
			||||||
	return getTwoArgEventListeners[TimePicker, time.Time](view, subviewID, TimeChangedEvent)
 | 
						return getTwoArgEventRawListeners[TimePicker, time.Time](view, subviewID, TimeChangedEvent)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue