Added binding support

This commit is contained in:
Alexei Anoshenko 2025-06-17 21:08:16 +03:00
parent ec2c5393f1
commit 3c3c09b043
40 changed files with 1674 additions and 791 deletions

View File

@ -209,7 +209,7 @@ type animationData struct {
usageCounter int usageCounter int
view View view View
listener func(view View, animation AnimationProperty, event PropertyName) listener func(view View, animation AnimationProperty, event PropertyName)
oldListeners map[PropertyName][]func(View, PropertyName) oldListeners map[PropertyName][]oneArgListener[View, PropertyName]
oldAnimation []AnimationProperty oldAnimation []AnimationProperty
} }
@ -1083,7 +1083,9 @@ func SetAnimated(rootView View, viewID string, tag PropertyName, value any, anim
} }
// IsAnimationPaused returns "true" if an animation of the subview is paused, "false" otherwise. // IsAnimationPaused returns "true" if an animation of the subview is paused, "false" otherwise.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func IsAnimationPaused(view View, subviewID ...string) bool { func IsAnimationPaused(view View, subviewID ...string) bool {
return boolStyledProperty(view, subviewID, AnimationPaused, false) return boolStyledProperty(view, subviewID, AnimationPaused, false)
} }

View File

@ -156,45 +156,6 @@ const (
AnimationIterationEvent PropertyName = "animation-iteration-event" AnimationIterationEvent PropertyName = "animation-iteration-event"
) )
/*
func setTransitionListener(properties Properties, tag PropertyName, value any) bool {
if listeners, ok := valueToOneArgEventListeners[View, string](value); ok {
if len(listeners) == 0 {
properties.setRaw(tag, nil)
} else {
properties.setRaw(tag, listeners)
}
return true
}
notCompatibleType(tag, value)
return false
}
func (view *viewData) removeTransitionListener(tag PropertyName) {
delete(view.properties, tag)
if view.created {
if js, ok := eventJsFunc[tag]; ok {
view.session.removeProperty(view.htmlID(), js.jsEvent)
}
}
}
func transitionEventsHtml(view View, buffer *strings.Builder) {
for _, tag := range []PropertyName{TransitionRunEvent, TransitionStartEvent, TransitionEndEvent, TransitionCancelEvent} {
if value := view.getRaw(tag); value != nil {
if js, ok := eventJsFunc[tag]; ok {
if listeners, ok := value.([]func(View, string)); ok && len(listeners) > 0 {
buffer.WriteString(js.jsEvent)
buffer.WriteString(`="`)
buffer.WriteString(js.jsFunc)
buffer.WriteString(`(this, event)" `)
}
}
}
}
}
*/
func (view *viewData) handleTransitionEvents(tag PropertyName, data DataObject) { func (view *viewData) handleTransitionEvents(tag PropertyName, data DataObject) {
if propertyName, ok := data.PropertyValue("property"); ok { if propertyName, ok := data.PropertyValue("property"); ok {
property := PropertyName(propertyName) property := PropertyName(propertyName)
@ -208,50 +169,11 @@ func (view *viewData) handleTransitionEvents(tag PropertyName, data DataObject)
} }
for _, listener := range getOneArgEventListeners[View, PropertyName](view, nil, tag) { for _, listener := range getOneArgEventListeners[View, PropertyName](view, nil, tag) {
listener(view, property) listener.Run(view, property)
} }
} }
} }
/*
func setAnimationListener(properties Properties, tag PropertyName, value any) bool {
if listeners, ok := valueToOneArgEventListeners[View, string](value); ok {
if len(listeners) == 0 {
properties.setRaw(tag, nil)
} else {
properties.setRaw(tag, listeners)
}
return true
}
notCompatibleType(tag, value)
return false
}
func (view *viewData) removeAnimationListener(tag PropertyName) {
delete(view.properties, tag)
if view.created {
if js, ok := eventJsFunc[tag]; ok {
view.session.removeProperty(view.htmlID(), js.jsEvent)
}
}
}
func animationEventsHtml(view View, buffer *strings.Builder) {
for _, tag := range []PropertyName{AnimationStartEvent, AnimationEndEvent, AnimationIterationEvent, AnimationCancelEvent} {
if value := view.getRaw(tag); value != nil {
if js, ok := eventJsFunc[tag]; ok {
if listeners, ok := value.([]func(View, string)); ok && len(listeners) > 0 {
buffer.WriteString(js.jsEvent)
buffer.WriteString(`="`)
buffer.WriteString(js.jsFunc)
buffer.WriteString(`(this, event)" `)
}
}
}
}
}
*/
func (view *viewData) handleAnimationEvents(tag PropertyName, data DataObject) { func (view *viewData) handleAnimationEvents(tag PropertyName, data DataObject) {
if listeners := getOneArgEventListeners[View, string](view, nil, tag); len(listeners) > 0 { if listeners := getOneArgEventListeners[View, string](view, nil, tag); len(listeners) > 0 {
id := "" id := ""
@ -263,63 +185,135 @@ func (view *viewData) handleAnimationEvents(tag PropertyName, data DataObject) {
} }
} }
for _, listener := range listeners { for _, listener := range listeners {
listener(view, id) listener.Run(view, id)
} }
} }
} }
// GetTransitionRunListeners returns the "transition-run-event" listener list. // GetTransitionRunListeners returns the "transition-run-event" listener list.
// If there are no listeners then the empty list is returned. // If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetTransitionRunListeners(view View, subviewID ...string) []func(View, string) { // Result elements can be of the following types:
return getOneArgEventListeners[View, string](view, subviewID, TransitionRunEvent) // - func(rui.View, string),
// - func(rui.View),
// - func(string),
// - 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 GetTransitionRunListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, string](view, subviewID, TransitionRunEvent)
} }
// GetTransitionStartListeners returns the "transition-start-event" listener list. // GetTransitionStartListeners returns the "transition-start-event" listener list.
// If there are no listeners then the empty list is returned. // If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetTransitionStartListeners(view View, subviewID ...string) []func(View, string) { // Result elements can be of the following types:
return getOneArgEventListeners[View, string](view, subviewID, TransitionStartEvent) // - func(rui.View, string),
// - func(rui.View),
// - func(string),
// - 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 GetTransitionStartListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, string](view, subviewID, TransitionStartEvent)
} }
// GetTransitionEndListeners returns the "transition-end-event" listener list. // GetTransitionEndListeners returns the "transition-end-event" listener list.
// If there are no listeners then the empty list is returned. // If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetTransitionEndListeners(view View, subviewID ...string) []func(View, string) { // Result elements can be of the following types:
return getOneArgEventListeners[View, string](view, subviewID, TransitionEndEvent) // - func(rui.View, string),
// - func(rui.View),
// - func(string),
// - 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 GetTransitionEndListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, string](view, subviewID, TransitionEndEvent)
} }
// GetTransitionCancelListeners returns the "transition-cancel-event" listener list. // GetTransitionCancelListeners returns the "transition-cancel-event" listener list.
// If there are no listeners then the empty list is returned. // If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetTransitionCancelListeners(view View, subviewID ...string) []func(View, string) { // Result elements can be of the following types:
return getOneArgEventListeners[View, string](view, subviewID, TransitionCancelEvent) // - func(rui.View, string),
// - func(rui.View),
// - func(string),
// - 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 GetTransitionCancelListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, string](view, subviewID, TransitionCancelEvent)
} }
// GetAnimationStartListeners returns the "animation-start-event" listener list. // GetAnimationStartListeners returns the "animation-start-event" listener list.
// If there are no listeners then the empty list is returned. // If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetAnimationStartListeners(view View, subviewID ...string) []func(View, string) { // Result elements can be of the following types:
return getOneArgEventListeners[View, string](view, subviewID, AnimationStartEvent) // - func(rui.View, string),
// - func(rui.View),
// - func(string),
// - 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 GetAnimationStartListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, string](view, subviewID, AnimationStartEvent)
} }
// GetAnimationEndListeners returns the "animation-end-event" listener list. // GetAnimationEndListeners returns the "animation-end-event" listener list.
// If there are no listeners then the empty list is returned. // If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetAnimationEndListeners(view View, subviewID ...string) []func(View, string) { // Result elements can be of the following types:
return getOneArgEventListeners[View, string](view, subviewID, AnimationEndEvent) // - func(rui.View, string),
// - func(rui.View),
// - func(string),
// - 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 GetAnimationEndListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, string](view, subviewID, AnimationEndEvent)
} }
// GetAnimationCancelListeners returns the "animation-cancel-event" listener list. // GetAnimationCancelListeners returns the "animation-cancel-event" listener list.
// If there are no listeners then the empty list is returned. // If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetAnimationCancelListeners(view View, subviewID ...string) []func(View, string) { // Result elements can be of the following types:
return getOneArgEventListeners[View, string](view, subviewID, AnimationCancelEvent) // - func(rui.View, string),
// - func(rui.View),
// - func(string),
// - 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 GetAnimationCancelListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, string](view, subviewID, AnimationCancelEvent)
} }
// GetAnimationIterationListeners returns the "animation-iteration-event" listener list. // GetAnimationIterationListeners returns the "animation-iteration-event" listener list.
// If there are no listeners then the empty list is returned. // If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetAnimationIterationListeners(view View, subviewID ...string) []func(View, string) { // Result elements can be of the following types:
return getOneArgEventListeners[View, string](view, subviewID, AnimationIterationEvent) // - func(rui.View, string),
// - func(rui.View),
// - func(string),
// - 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 GetAnimationIterationListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, string](view, subviewID, AnimationIterationEvent)
} }

View File

@ -1,5 +1,7 @@
package rui package rui
import "slices"
func (animation *animationData) Start(view View, listener func(view View, animation AnimationProperty, event PropertyName)) bool { func (animation *animationData) Start(view View, listener func(view View, animation AnimationProperty, event PropertyName)) bool {
if view == nil { if view == nil {
ErrorLog("nil View in animation.Start() function") ErrorLog("nil View in animation.Start() function")
@ -13,28 +15,22 @@ func (animation *animationData) Start(view View, listener func(view View, animat
animation.listener = listener animation.listener = listener
animation.oldAnimation = nil animation.oldAnimation = nil
//if getOneArgEventListeners[View, PropertyName](view, nil, Animation)
if value := view.Get(Animation); value != nil { if value := view.Get(Animation); value != nil {
if oldAnimation, ok := value.([]AnimationProperty); ok && len(oldAnimation) > 0 { if oldAnimation, ok := value.([]AnimationProperty); ok && len(oldAnimation) > 0 {
animation.oldAnimation = oldAnimation animation.oldAnimation = oldAnimation
} }
} }
animation.oldListeners = map[PropertyName][]func(View, PropertyName){} animation.oldListeners = map[PropertyName][]oneArgListener[View, PropertyName]{}
setListeners := func(event PropertyName, listener func(View, PropertyName)) { setListeners := func(event PropertyName, listener func(View, PropertyName)) {
var listeners []func(View, PropertyName) = nil listeners := getOneArgEventListeners[View, PropertyName](view, nil, event)
if value := view.Get(event); value != nil { if len(listeners) > 0 {
if oldListeners, ok := value.([]func(View, PropertyName)); ok && len(oldListeners) > 0 { animation.oldListeners[event] = slices.Clone(listeners)
listeners = oldListeners
}
}
if listeners == nil {
view.Set(event, listener)
} else {
animation.oldListeners[event] = listeners
view.Set(event, append(listeners, listener))
} }
view.Set(event, append(listeners, newOneArgListenerVE(listener)))
} }
setListeners(AnimationStartEvent, animation.onAnimationStart) setListeners(AnimationStartEvent, animation.onAnimationStart)
@ -49,7 +45,7 @@ func (animation *animationData) Start(view View, listener func(view View, animat
func (animation *animationData) finish() { func (animation *animationData) finish() {
if animation.view != nil { if animation.view != nil {
for _, event := range []PropertyName{AnimationStartEvent, AnimationEndEvent, AnimationCancelEvent, AnimationIterationEvent} { for _, event := range []PropertyName{AnimationStartEvent, AnimationEndEvent, AnimationCancelEvent, AnimationIterationEvent} {
if listeners, ok := animation.oldListeners[event]; ok { if listeners, ok := animation.oldListeners[event]; ok && len(listeners) > 0 {
animation.view.Set(event, listeners) animation.view.Set(event, listeners)
} else { } else {
animation.view.Remove(event) animation.view.Remove(event)
@ -63,7 +59,7 @@ func (animation *animationData) finish() {
animation.view.Set(Animation, "") animation.view.Set(Animation, "")
} }
animation.oldListeners = map[PropertyName][]func(View, PropertyName){} animation.oldListeners = map[PropertyName][]oneArgListener[View, PropertyName]{}
animation.view = nil animation.view = nil
animation.listener = nil animation.listener = nil

View File

@ -268,14 +268,16 @@ func backgroundStyledPropery(view View, subviewID []string, tag PropertyName) []
// GetBackground returns the view background. // GetBackground returns the view background.
// //
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetBackground(view View, subviewID ...string) []BackgroundElement { func GetBackground(view View, subviewID ...string) []BackgroundElement {
return backgroundStyledPropery(view, subviewID, Background) return backgroundStyledPropery(view, subviewID, Background)
} }
// GetMask returns the view mask. // GetMask returns the view mask.
// //
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetMask(view View, subviewID ...string) []BackgroundElement { func GetMask(view View, subviewID ...string) []BackgroundElement {
return backgroundStyledPropery(view, subviewID, Mask) return backgroundStyledPropery(view, subviewID, Mask)
} }
@ -284,7 +286,8 @@ func GetMask(view View, subviewID ...string) []BackgroundElement {
// //
// BorderBox (0), PaddingBox (1), ContentBox (2) // BorderBox (0), PaddingBox (1), ContentBox (2)
// //
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetBackgroundClip(view View, subviewID ...string) int { func GetBackgroundClip(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, BackgroundClip, 0, false) return enumStyledProperty(view, subviewID, BackgroundClip, 0, false)
} }
@ -293,7 +296,8 @@ func GetBackgroundClip(view View, subviewID ...string) int {
// //
// BorderBox (0), PaddingBox (1), ContentBox (2) // BorderBox (0), PaddingBox (1), ContentBox (2)
// //
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetBackgroundOrigin(view View, subviewID ...string) int { func GetBackgroundOrigin(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, BackgroundOrigin, 0, false) return enumStyledProperty(view, subviewID, BackgroundOrigin, 0, false)
} }
@ -302,7 +306,8 @@ func GetBackgroundOrigin(view View, subviewID ...string) int {
// //
// BorderBox (0), PaddingBox (1), ContentBox (2) // BorderBox (0), PaddingBox (1), ContentBox (2)
// //
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetMaskClip(view View, subviewID ...string) int { func GetMaskClip(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, MaskClip, 0, false) return enumStyledProperty(view, subviewID, MaskClip, 0, false)
} }
@ -311,7 +316,8 @@ func GetMaskClip(view View, subviewID ...string) int {
// //
// BorderBox (0), PaddingBox (1), ContentBox (2) // BorderBox (0), PaddingBox (1), ContentBox (2)
// //
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetMaskOrigin(view View, subviewID ...string) int { func GetMaskOrigin(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, MaskOrigin, 0, false) return enumStyledProperty(view, subviewID, MaskOrigin, 0, false)
} }

View File

@ -53,8 +53,8 @@ func (button *checkboxData) init(session Session) {
button.remove = button.removeFunc button.remove = button.removeFunc
button.changed = button.propertyChanged button.changed = button.propertyChanged
button.setRaw(ClickEvent, []func(View, MouseEvent){checkboxClickListener}) button.setRaw(ClickEvent, []oneArgListener[View, MouseEvent]{newOneArgListenerVE(checkboxClickListener)})
button.setRaw(KeyDownEvent, []func(View, KeyEvent){checkboxKeyListener}) button.setRaw(KeyDownEvent, []oneArgListener[View, KeyEvent]{newOneArgListenerVE(checkboxKeyListener)})
} }
func (button *checkboxData) Focusable() bool { func (button *checkboxData) Focusable() bool {
@ -67,9 +67,9 @@ func (button *checkboxData) propertyChanged(tag PropertyName) {
case Checked: case Checked:
session := button.Session() session := button.Session()
checked := IsCheckboxChecked(button) checked := IsCheckboxChecked(button)
if listeners := GetCheckboxChangedListeners(button); len(listeners) > 0 { if listeners := getOneArgEventListeners[Checkbox, bool](button, nil, CheckboxChangedEvent); len(listeners) > 0 {
for _, listener := range listeners { for _, listener := range listeners {
listener(button, checked) listener.Run(button, checked)
} }
} }
@ -103,7 +103,7 @@ func (button *checkboxData) setFunc(tag PropertyName, value any) []PropertyName
switch tag { switch tag {
case ClickEvent: case ClickEvent:
if listeners, ok := valueToOneArgEventListeners[View, MouseEvent](value); ok && listeners != nil { if listeners, ok := valueToOneArgEventListeners[View, MouseEvent](value); ok && listeners != nil {
listeners = append(listeners, checkboxClickListener) listeners = append(listeners, newOneArgListenerVE(checkboxClickListener))
button.setRaw(tag, listeners) button.setRaw(tag, listeners)
return []PropertyName{tag} return []PropertyName{tag}
} }
@ -111,7 +111,7 @@ func (button *checkboxData) setFunc(tag PropertyName, value any) []PropertyName
case KeyDownEvent: case KeyDownEvent:
if listeners, ok := valueToOneArgEventListeners[View, KeyEvent](value); ok && listeners != nil { if listeners, ok := valueToOneArgEventListeners[View, KeyEvent](value); ok && listeners != nil {
listeners = append(listeners, checkboxKeyListener) listeners = append(listeners, newOneArgListenerVE(checkboxKeyListener))
button.setRaw(tag, listeners) button.setRaw(tag, listeners)
return []PropertyName{tag} return []PropertyName{tag}
} }
@ -134,31 +134,17 @@ func (button *checkboxData) setFunc(tag PropertyName, value any) []PropertyName
func (button *checkboxData) removeFunc(tag PropertyName) []PropertyName { func (button *checkboxData) removeFunc(tag PropertyName) []PropertyName {
switch tag { switch tag {
case ClickEvent: case ClickEvent:
button.setRaw(ClickEvent, []func(View, MouseEvent){checkboxClickListener}) button.setRaw(ClickEvent, []oneArgListener[View, MouseEvent]{newOneArgListenerVE(checkboxClickListener)})
return []PropertyName{ClickEvent} return []PropertyName{ClickEvent}
case KeyDownEvent: case KeyDownEvent:
button.setRaw(KeyDownEvent, []func(View, KeyEvent){checkboxKeyListener}) button.setRaw(KeyDownEvent, []oneArgListener[View, KeyEvent]{newOneArgListenerVE(checkboxKeyListener)})
return []PropertyName{ClickEvent} return []PropertyName{ClickEvent}
} }
return button.viewsContainerData.removeFunc(tag) return button.viewsContainerData.removeFunc(tag)
} }
/*
func (button *checkboxData) changedCheckboxState(state bool) {
for _, listener := range GetCheckboxChangedListeners(button) {
listener(button, state)
}
buffer := allocStringBuilder()
defer freeStringBuilder(buffer)
button.htmlCheckbox(buffer, state)
button.Session().updateInnerHTML(button.htmlID()+"checkbox", buffer.String())
}
*/
func checkboxClickListener(view View, _ MouseEvent) { func checkboxClickListener(view View, _ MouseEvent) {
view.Set(Checked, !IsCheckboxChecked(view)) view.Set(Checked, !IsCheckboxChecked(view))
BlurView(view) BlurView(view)
@ -302,26 +288,41 @@ func checkboxVerticalAlignCSS(view View) string {
} }
// IsCheckboxChecked returns true if the Checkbox is checked, false otherwise. // IsCheckboxChecked returns true if the Checkbox is checked, false otherwise.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func IsCheckboxChecked(view View, subviewID ...string) bool { func IsCheckboxChecked(view View, subviewID ...string) bool {
return boolStyledProperty(view, subviewID, Checked, false) return boolStyledProperty(view, subviewID, Checked, false)
} }
// GetCheckboxVerticalAlign return the vertical align of a Checkbox subview: TopAlign (0), BottomAlign (1), CenterAlign (2) // GetCheckboxVerticalAlign return the vertical align of a Checkbox subview: TopAlign (0), BottomAlign (1), CenterAlign (2)
// If the second argument (subviewID) is not specified or it is "" then a left position of the first argument (view) is 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.
func GetCheckboxVerticalAlign(view View, subviewID ...string) int { func GetCheckboxVerticalAlign(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, CheckboxVerticalAlign, LeftAlign, false) return enumStyledProperty(view, subviewID, CheckboxVerticalAlign, LeftAlign, false)
} }
// GetCheckboxHorizontalAlign return the vertical align of a Checkbox subview: LeftAlign (0), RightAlign (1), CenterAlign (2) // GetCheckboxHorizontalAlign return the vertical align of a Checkbox subview: LeftAlign (0), RightAlign (1), CenterAlign (2)
// If the second argument (subviewID) is not specified or it is "" then a left position of the first argument (view) is 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.
func GetCheckboxHorizontalAlign(view View, subviewID ...string) int { func GetCheckboxHorizontalAlign(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, CheckboxHorizontalAlign, TopAlign, false) return enumStyledProperty(view, subviewID, CheckboxHorizontalAlign, TopAlign, false)
} }
// GetCheckboxChangedListeners returns the CheckboxChangedListener list of an Checkbox subview. // GetCheckboxChangedListeners returns the CheckboxChangedListener list of an Checkbox subview.
// If there are no listeners then the empty list is returned // If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetCheckboxChangedListeners(view View, subviewID ...string) []func(Checkbox, bool) { // Result elements can be of the following types:
return getOneArgEventListeners[Checkbox, bool](view, subviewID, CheckboxChangedEvent) // - func(Checkbox, bool),
// - func(Checkbox),
// - func(bool),
// - 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 GetCheckboxChangedListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[Checkbox, bool](view, subviewID, CheckboxChangedEvent)
} }

View File

@ -172,7 +172,9 @@ func (picker *colorPickerData) handleCommand(self View, command PropertyName, da
} }
// GetColorPickerValue returns the value of ColorPicker subview. // GetColorPickerValue returns the value of ColorPicker subview.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetColorPickerValue(view View, subviewID ...string) Color { func GetColorPickerValue(view View, subviewID ...string) Color {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
if value, ok := colorProperty(view, ColorPickerValue, view.Session()); ok { if value, ok := colorProperty(view, ColorPickerValue, view.Session()); ok {
@ -191,7 +193,9 @@ 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
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetColorChangedListeners(view View, subviewID ...string) []func(ColorPicker, Color, Color) { func GetColorChangedListeners(view View, subviewID ...string) []func(ColorPicker, Color, Color) {
return getTwoArgEventListeners[ColorPicker, Color](view, subviewID, ColorChangedEvent) return getTwoArgEventListeners[ColorPicker, Color](view, subviewID, ColorChangedEvent)
} }

View File

@ -249,13 +249,17 @@ func GetColumnSeparatorColor(view View, subviewID ...string) Color {
// GetColumnFill returns a "column-fill" property value of the subview. // GetColumnFill returns a "column-fill" property value of the subview.
// Returns one of next values: ColumnFillBalance (0) or ColumnFillAuto (1) // Returns one of next values: ColumnFillBalance (0) or ColumnFillAuto (1)
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetColumnFill(view View, subviewID ...string) int { func GetColumnFill(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, ColumnFill, ColumnFillBalance, true) return enumStyledProperty(view, subviewID, ColumnFill, ColumnFillBalance, true)
} }
// IsColumnSpanAll returns a "column-span-all" property value of the subview. // IsColumnSpanAll returns a "column-span-all" property value of the subview.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func IsColumnSpanAll(view View, subviewID ...string) bool { func IsColumnSpanAll(view View, subviewID ...string) bool {
return boolStyledProperty(view, subviewID, ColumnSpanAll, false) return boolStyledProperty(view, subviewID, ColumnSpanAll, false)
} }

View File

@ -352,3 +352,10 @@ func (customView *CustomViewData) LoadFile(file FileInfo, result func(FileInfo,
customView.superView.LoadFile(file, result) customView.superView.LoadFile(file, result)
} }
} }
func (customView *CustomViewData) binding() any {
if customView.superView != nil {
return customView.superView.binding()
}
return nil
}

View File

@ -312,7 +312,9 @@ func dataListHtmlProperties(view View, buffer *strings.Builder) {
} }
// GetDataList returns the data list of an editor. // GetDataList returns the data list of an editor.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetDataList(view View, subviewID ...string) []string { func GetDataList(view View, subviewID ...string) []string {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
return getDataListProperty(view) return getDataListProperty(view)

View File

@ -400,7 +400,9 @@ func getDateProperty(view View, mainTag, shortTag PropertyName) (time.Time, bool
// GetDatePickerMin returns the min date of DatePicker subview and "true" as the second value if the min date is set, // GetDatePickerMin returns the min date of DatePicker subview and "true" as the second value if the min date is set,
// "false" as the second value otherwise. // "false" as the second value otherwise.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetDatePickerMin(view View, subviewID ...string) (time.Time, bool) { func GetDatePickerMin(view View, subviewID ...string) (time.Time, bool) {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
return getDateProperty(view, DatePickerMin, Min) return getDateProperty(view, DatePickerMin, Min)
@ -410,7 +412,9 @@ func GetDatePickerMin(view View, subviewID ...string) (time.Time, bool) {
// GetDatePickerMax returns the max date of DatePicker subview and "true" as the second value if the min date is set, // GetDatePickerMax returns the max date of DatePicker subview and "true" as the second value if the min date is set,
// "false" as the second value otherwise. // "false" as the second value otherwise.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetDatePickerMax(view View, subviewID ...string) (time.Time, bool) { func GetDatePickerMax(view View, subviewID ...string) (time.Time, bool) {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
return getDateProperty(view, DatePickerMax, Max) return getDateProperty(view, DatePickerMax, Max)
@ -419,13 +423,17 @@ func GetDatePickerMax(view View, subviewID ...string) (time.Time, bool) {
} }
// GetDatePickerStep returns the date changing step in days of DatePicker subview. // GetDatePickerStep returns the date changing step in days of DatePicker subview.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetDatePickerStep(view View, subviewID ...string) int { func GetDatePickerStep(view View, subviewID ...string) int {
return intStyledProperty(view, subviewID, DatePickerStep, 0) return intStyledProperty(view, subviewID, DatePickerStep, 0)
} }
// GetDatePickerValue returns the date of DatePicker subview. // GetDatePickerValue returns the date of DatePicker subview.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetDatePickerValue(view View, subviewID ...string) time.Time { func GetDatePickerValue(view View, subviewID ...string) time.Time {
if view = getSubview(view, subviewID); view == nil { if view = getSubview(view, subviewID); view == nil {
return time.Now() return time.Now()
@ -436,7 +444,9 @@ 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
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetDateChangedListeners(view View, subviewID ...string) []func(DatePicker, time.Time, time.Time) { func GetDateChangedListeners(view View, subviewID ...string) []func(DatePicker, time.Time, time.Time) {
return getTwoArgEventListeners[DatePicker, time.Time](view, subviewID, DateChangedEvent) return getTwoArgEventListeners[DatePicker, time.Time](view, subviewID, DateChangedEvent)
} }

View File

@ -202,7 +202,9 @@ func (detailsView *detailsViewData) handleCommand(self View, command PropertyNam
} }
// GetDetailsSummary returns a value of the Summary property of DetailsView. // GetDetailsSummary returns a value of the Summary property of DetailsView.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetDetailsSummary(view View, subviewID ...string) View { func GetDetailsSummary(view View, subviewID ...string) View {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
if value := view.Get(Summary); value != nil { if value := view.Get(Summary); value != nil {
@ -219,13 +221,17 @@ func GetDetailsSummary(view View, subviewID ...string) View {
} }
// IsDetailsExpanded returns a value of the Expanded property of DetailsView. // IsDetailsExpanded returns a value of the Expanded property of DetailsView.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func IsDetailsExpanded(view View, subviewID ...string) bool { func IsDetailsExpanded(view View, subviewID ...string) bool {
return boolStyledProperty(view, subviewID, Expanded, false) return boolStyledProperty(view, subviewID, Expanded, false)
} }
// IsDetailsExpanded returns a value of the HideSummaryMarker property of DetailsView. // IsDetailsExpanded returns a value of the HideSummaryMarker property of DetailsView.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func IsSummaryMarkerHidden(view View, subviewID ...string) bool { func IsSummaryMarkerHidden(view View, subviewID ...string) bool {
return boolStyledProperty(view, subviewID, HideSummaryMarker, false) return boolStyledProperty(view, subviewID, HideSummaryMarker, false)
} }

View File

@ -336,7 +336,7 @@ func handleDragAndDropEvents(view View, tag PropertyName, data DataObject) {
event.init(view.Session(), data) event.init(view.Session(), data)
for _, listener := range listeners { for _, listener := range listeners {
listener(view, event) listener.Run(view, event)
} }
} }
} }
@ -434,41 +434,99 @@ func (view *viewData) LoadFile(file FileInfo, result func(FileInfo, []byte)) {
} }
// GetDragStartEventListeners returns the "drag-start-event" listener list. If there are no listeners then the empty list is returned. // GetDragStartEventListeners returns the "drag-start-event" listener list. If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetDragStartEventListeners(view View, subviewID ...string) []func(View, DragAndDropEvent) { // Result elements can be of the following types:
return getOneArgEventListeners[View, DragAndDropEvent](view, subviewID, DragStartEvent) // - func(rui.View, rui.DragAndDropEvent),
// - func(rui.View),
// - func(rui.DragAndDropEvent),
// - 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 GetDragStartEventListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, DragAndDropEvent](view, subviewID, DragStartEvent)
} }
// GetDragEndEventListeners returns the "drag-end-event" listener list. If there are no listeners then the empty list is returned. // GetDragEndEventListeners returns the "drag-end-event" listener list. If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetDragEndEventListeners(view View, subviewID ...string) []func(View, DragAndDropEvent) { // Result elements can be of the following types:
return getOneArgEventListeners[View, DragAndDropEvent](view, subviewID, DragEndEvent) // - func(rui.View, rui.DragAndDropEvent),
// - func(rui.View),
// - func(rui.DragAndDropEvent),
// - 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 GetDragEndEventListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, DragAndDropEvent](view, subviewID, DragEndEvent)
} }
// GetDragEnterEventListeners returns the "drag-enter-event" listener list. If there are no listeners then the empty list is returned. // GetDragEnterEventListeners returns the "drag-enter-event" listener list. If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetDragEnterEventListeners(view View, subviewID ...string) []func(View, DragAndDropEvent) { // Result elements can be of the following types:
return getOneArgEventListeners[View, DragAndDropEvent](view, subviewID, DragEnterEvent) // - func(rui.View, rui.DragAndDropEvent),
// - func(rui.View),
// - func(rui.DragAndDropEvent),
// - 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 GetDragEnterEventListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, DragAndDropEvent](view, subviewID, DragEnterEvent)
} }
// GetDragLeaveEventListeners returns the "drag-leave-event" listener list. If there are no listeners then the empty list is returned. // GetDragLeaveEventListeners returns the "drag-leave-event" listener list. If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetDragLeaveEventListeners(view View, subviewID ...string) []func(View, DragAndDropEvent) { // Result elements can be of the following types:
return getOneArgEventListeners[View, DragAndDropEvent](view, subviewID, DragLeaveEvent) // - func(rui.View, rui.DragAndDropEvent),
// - func(rui.View),
// - func(rui.DragAndDropEvent),
// - 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 GetDragLeaveEventListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, DragAndDropEvent](view, subviewID, DragLeaveEvent)
} }
// GetDragOverEventListeners returns the "drag-over-event" listener list. If there are no listeners then the empty list is returned. // GetDragOverEventListeners returns the "drag-over-event" listener list. If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetDragOverEventListeners(view View, subviewID ...string) []func(View, DragAndDropEvent) { // Result elements can be of the following types:
return getOneArgEventListeners[View, DragAndDropEvent](view, subviewID, DragOverEvent) // - func(rui.View, rui.DragAndDropEvent),
// - func(rui.View),
// - func(rui.DragAndDropEvent),
// - 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 GetDragOverEventListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, DragAndDropEvent](view, subviewID, DragOverEvent)
} }
// GetDropEventListeners returns the "drag-start-event" listener list. If there are no listeners then the empty list is returned. // GetDropEventListeners returns the "drag-start-event" listener list. If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetDropEventListeners(view View, subviewID ...string) []func(View, DragAndDropEvent) { // Result elements can be of the following types:
return getOneArgEventListeners[View, DragAndDropEvent](view, subviewID, DropEvent) // - func(rui.View, rui.DragAndDropEvent),
// - func(rui.View),
// - func(rui.DragAndDropEvent),
// - 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 GetDropEventListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, DragAndDropEvent](view, subviewID, DropEvent)
} }
// GetDropEventListeners returns the "drag-data" data.
//
// 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 GetDragData(view View, subviewID ...string) map[string]string { func GetDragData(view View, subviewID ...string) map[string]string {
result := map[string]string{} result := map[string]string{}
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
@ -483,7 +541,9 @@ func GetDragData(view View, subviewID ...string) map[string]string {
} }
// GetDragImage returns the drag feedback image. // GetDragImage returns the drag feedback image.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetDragImage(view View, subviewID ...string) string { func GetDragImage(view View, subviewID ...string) string {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
value := view.getRaw(DragImage) value := view.getRaw(DragImage)
@ -508,13 +568,17 @@ func GetDragImage(view View, subviewID ...string) string {
} }
// GetDragImageXOffset returns the horizontal offset in pixels within the drag feedback image. // GetDragImageXOffset returns the horizontal offset in pixels within the drag feedback image.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetDragImageXOffset(view View, subviewID ...string) float64 { func GetDragImageXOffset(view View, subviewID ...string) float64 {
return floatStyledProperty(view, subviewID, DragImageXOffset, 0) return floatStyledProperty(view, subviewID, DragImageXOffset, 0)
} }
// GetDragImageYOffset returns the vertical offset in pixels within the drag feedback image. // GetDragImageYOffset returns the vertical offset in pixels within the drag feedback image.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetDragImageYOffset(view View, subviewID ...string) float64 { func GetDragImageYOffset(view View, subviewID ...string) float64 {
return floatStyledProperty(view, subviewID, DragImageYOffset, 0) return floatStyledProperty(view, subviewID, DragImageYOffset, 0)
} }
@ -529,7 +593,8 @@ func GetDragImageYOffset(view View, subviewID ...string) float64 {
// - 2 (DropEffectMove) - An item may be moved to a new location. // - 2 (DropEffectMove) - An item may be moved to a new location.
// - 4 (DropEffectLink) - A link may be established to the source at the new location. // - 4 (DropEffectLink) - A link may be established to the source at the new location.
// //
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetDropEffect(view View, subviewID ...string) int { func GetDropEffect(view View, subviewID ...string) int {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
value := view.getRaw(DropEffect) value := view.getRaw(DropEffect)
@ -573,7 +638,8 @@ func GetDropEffect(view View, subviewID ...string) int {
// - 6 (DropEffectLinkMove) - A link or move operation is permitted. // - 6 (DropEffectLinkMove) - A link or move operation is permitted.
// - 7 (DropEffectAll) - All operations are permitted. // - 7 (DropEffectAll) - All operations are permitted.
// //
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetDropEffectAllowed(view View, subviewID ...string) int { func GetDropEffectAllowed(view View, subviewID ...string) int {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
value := view.getRaw(DropEffectAllowed) value := view.getRaw(DropEffectAllowed)

View File

@ -264,13 +264,17 @@ 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.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetDropDownListeners(view View, subviewID ...string) []func(DropDownList, int, int) { func GetDropDownListeners(view View, subviewID ...string) []func(DropDownList, int, int) {
return getTwoArgEventListeners[DropDownList, int](view, subviewID, DropDownEvent) return getTwoArgEventListeners[DropDownList, int](view, subviewID, DropDownEvent)
} }
// GetDropDownItems return the DropDownList items list. // GetDropDownItems return the DropDownList items list.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetDropDownItems(view View, subviewID ...string) []string { func GetDropDownItems(view View, subviewID ...string) []string {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
if value := view.Get(Items); value != nil { if value := view.Get(Items); value != nil {
@ -313,14 +317,18 @@ func getIndicesArray(view View, tag PropertyName) []int {
} }
// GetDropDownDisabledItems return an array of disabled(non selectable) items indices of DropDownList. // GetDropDownDisabledItems return an array of disabled(non selectable) items indices of DropDownList.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetDropDownDisabledItems(view View, subviewID ...string) []int { func GetDropDownDisabledItems(view View, subviewID ...string) []int {
view = getSubview(view, subviewID) view = getSubview(view, subviewID)
return getIndicesArray(view, DisabledItems) return getIndicesArray(view, DisabledItems)
} }
// GetDropDownItemSeparators return an array of indices of DropDownList items after which a separator should be added. // GetDropDownItemSeparators return an array of indices of DropDownList items after which a separator should be added.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetDropDownItemSeparators(view View, subviewID ...string) []int { func GetDropDownItemSeparators(view View, subviewID ...string) []int {
view = getSubview(view, subviewID) view = getSubview(view, subviewID)
return getIndicesArray(view, ItemSeparators) return getIndicesArray(view, ItemSeparators)

View File

@ -451,26 +451,34 @@ func IsReadOnly(view View, subviewID ...string) bool {
} }
// IsSpellcheck returns a value of the Spellcheck property of EditView. // IsSpellcheck returns a value of the Spellcheck property of EditView.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func IsSpellcheck(view View, subviewID ...string) bool { func IsSpellcheck(view View, subviewID ...string) bool {
return boolStyledProperty(view, subviewID, Spellcheck, false) return boolStyledProperty(view, subviewID, Spellcheck, false)
} }
// 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
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTextChangedListeners(view View, subviewID ...string) []func(EditView, string, string) { func GetTextChangedListeners(view View, subviewID ...string) []func(EditView, string, string) {
return getTwoArgEventListeners[EditView, string](view, subviewID, EditTextChangedEvent) return getTwoArgEventListeners[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.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetEditViewType(view View, subviewID ...string) int { func GetEditViewType(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, EditViewType, SingleLineText, false) return enumStyledProperty(view, subviewID, EditViewType, SingleLineText, false)
} }
// GetEditViewPattern returns a value of the Pattern property of EditView. // GetEditViewPattern returns a value of the Pattern property of EditView.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetEditViewPattern(view View, subviewID ...string) string { func GetEditViewPattern(view View, subviewID ...string) string {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
if pattern, ok := stringProperty(view, EditViewPattern, view.Session()); ok { if pattern, ok := stringProperty(view, EditViewPattern, view.Session()); ok {
@ -488,13 +496,17 @@ func GetEditViewPattern(view View, subviewID ...string) string {
} }
// IsEditViewWrap returns a value of the EditWrap property of MultiLineEditView. // IsEditViewWrap returns a value of the EditWrap property of MultiLineEditView.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func IsEditViewWrap(view View, subviewID ...string) bool { func IsEditViewWrap(view View, subviewID ...string) bool {
return boolStyledProperty(view, subviewID, EditWrap, false) return boolStyledProperty(view, subviewID, EditWrap, false)
} }
// AppendEditText appends the text to the EditView content. // AppendEditText appends the text to the EditView content.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func AppendEditText(view View, subviewID string, text string) { func AppendEditText(view View, subviewID string, text string) {
if subviewID != "" { if subviewID != "" {
if edit := EditViewByID(view, subviewID); edit != nil { if edit := EditViewByID(view, subviewID); edit != nil {
@ -509,7 +521,9 @@ func AppendEditText(view View, subviewID string, text string) {
} }
// GetCaretColor returns the color of the text input caret. // GetCaretColor returns the color of the text input caret.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetCaretColor(view View, subviewID ...string) Color { func GetCaretColor(view View, subviewID ...string) Color {
return colorStyledProperty(view, subviewID, CaretColor, false) return colorStyledProperty(view, subviewID, CaretColor, false)
} }

436
events.go
View File

@ -1,6 +1,9 @@
package rui package rui
import "strings" import (
"reflect"
"strings"
)
var eventJsFunc = map[PropertyName]struct{ jsEvent, jsFunc string }{ var eventJsFunc = map[PropertyName]struct{ jsEvent, jsFunc string }{
FocusEvent: {jsEvent: "onfocus", jsFunc: "focusEvent"}, FocusEvent: {jsEvent: "onfocus", jsFunc: "focusEvent"},
@ -38,12 +41,203 @@ var eventJsFunc = map[PropertyName]struct{ jsEvent, jsFunc string }{
DragLeaveEvent: {jsEvent: "ondragleave", jsFunc: "dragLeaveEvent"}, DragLeaveEvent: {jsEvent: "ondragleave", jsFunc: "dragLeaveEvent"},
} }
func valueToNoArgEventListeners[V any](value any) ([]func(V), bool) { /*
type oneArgListener[V View, E any] interface {
call(V, E)
listener() func(V, E)
rawListener() any
}
type oneArgListener0[V View, E any] struct {
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 {
method.Call(args)
} else {
ErrorLogF(`Unsupported prototype of "%s" method`, data.name)
}
}
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) {
if value == nil { if value == nil {
return nil, true return nil, true
} }
switch value := value.(type) { switch value := value.(type) {
case string:
fn := func(arg V) {
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(arg) {
args = []reflect.Value{reflect.ValueOf(arg)}
}
}
if args != nil {
method.Call(args)
} else {
ErrorLogF(`Unsupported prototype of "%s" method`, value)
}
}
return []func(V){fn}, true
case func(V): case func(V):
return []func(V){value}, true return []func(V){value}, true
@ -109,137 +303,153 @@ func valueToNoArgEventListeners[V any](value any) ([]func(V), bool) {
return nil, false return nil, false
} }
func valueToOneArgEventListeners[V View, E any](value any) ([]func(V, E), bool) { /*
func valueToOneArgEventListeners[V View, E any](view View, value any) ([]oneArgListener[V, E], bool) {
if value == nil { if value == nil {
return nil, true return nil, true
} }
switch value := value.(type) { switch value := value.(type) {
case func(V, E): case string:
return []func(V, E){value}, true return []oneArgListener[V, E]{newOneArgListenerBinding[V, E](value)}, true
case func(E): case func(V, E):
fn := func(_ V, event E) { return []oneArgListener[V, E]{newOneArgListenerVE[V, E](value)}, true
value(event)
}
return []func(V, E){fn}, true
case func(V): case func(V):
fn := func(view V, _ E) { return []oneArgListener[V, E]{newOneArgListenerV[V, E](value)}, true
value(view)
} case func(E):
return []func(V, E){fn}, true return []oneArgListener[V, E]{newOneArgListenerE[V, E](value)}, true
case func(): case func():
fn := func(V, E) { return []oneArgListener[V, E]{newOneArgListener0[V, E](value)}, true
value()
}
return []func(V, E){fn}, true
case []func(V, E): case []func(V, E):
if len(value) == 0 { result := make([]oneArgListener[V, E], 0, len(value))
return nil, true
}
for _, fn := range value { for _, fn := range value {
if fn == nil { if fn != nil {
return nil, false result = append(result, newOneArgListenerVE[V, E](fn))
} }
} }
return value, true return result, len(result) > 0
case []func(E): case []func(E):
count := len(value) result := make([]oneArgListener[V, E], 0, len(value))
if count == 0 { for _, fn := range value {
return nil, true if fn != nil {
} result = append(result, newOneArgListenerE[V, E](fn))
listeners := make([]func(V, E), count)
for i, v := range value {
if v == nil {
return nil, false
}
listeners[i] = func(_ V, event E) {
v(event)
} }
} }
return listeners, true return result, len(result) > 0
case []func(V): case []func(V):
count := len(value) result := make([]oneArgListener[V, E], 0, len(value))
if count == 0 { for _, fn := range value {
return nil, true if fn != nil {
} result = append(result, newOneArgListenerV[V, E](fn))
listeners := make([]func(V, E), count)
for i, v := range value {
if v == nil {
return nil, false
}
listeners[i] = func(view V, _ E) {
v(view)
} }
} }
return listeners, true return result, len(result) > 0
case []func(): case []func():
count := len(value) result := make([]oneArgListener[V, E], 0, len(value))
if count == 0 { for _, fn := range value {
return nil, true if fn != nil {
} result = append(result, newOneArgListener0[V, E](fn))
listeners := make([]func(V, E), count)
for i, v := range value {
if v == nil {
return nil, false
}
listeners[i] = func(V, E) {
v()
} }
} }
return listeners, true return result, len(result) > 0
case []any: case []any:
count := len(value) result := make([]oneArgListener[V, E], 0, len(value))
if count == 0 { for _, v := range value {
return nil, true if v != nil {
}
listeners := make([]func(V, E), count)
for i, v := range value {
if v == nil {
return nil, false
}
switch v := v.(type) { switch v := v.(type) {
case func(V, E): case func(V, E):
listeners[i] = v result = append(result, newOneArgListenerVE[V, E](v))
case func(E): case func(E):
listeners[i] = func(_ V, event E) { result = append(result, newOneArgListenerE[V, E](v))
v(event)
}
case func(V): case func(V):
listeners[i] = func(view V, _ E) { result = append(result, newOneArgListenerV[V, E](v))
v(view)
}
case func(): case func():
listeners[i] = func(V, E) { result = append(result, newOneArgListener0[V, E](v))
v()
} case string:
result = append(result, newOneArgListenerBinding[V, E](v))
default: default:
return nil, false return nil, false
} }
} }
return listeners, true }
return result, len(result) > 0
} }
return nil, false return nil, false
} }
*/
func valueToTwoArgEventListeners[V View, E any](value any) ([]func(V, E, E), bool) { func valueToTwoArgEventListeners[V View, E any](view View, value any) ([]func(V, E, E), bool) {
if value == nil { if value == nil {
return nil, true return nil, true
} }
switch value := value.(type) { 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): case func(V, E, E):
return []func(V, E, E){value}, true return []func(V, E, E){value}, true
@ -424,17 +634,27 @@ 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) []func(V, E) { /*
func getOneArgEventListeners[V View, E any](view View, subviewID []string, tag PropertyName) []oneArgListener[V, E] {
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 {
if result, ok := value.([]func(V, E)); ok { if result, ok := value.([]oneArgListener[V, E]); ok {
return result return result
} }
} }
} }
return []func(V, E){} 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) { func getTwoArgEventListeners[V View, E any](view View, subviewID []string, tag PropertyName) []func(V, E, E) {
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 {
@ -446,12 +666,12 @@ func getTwoArgEventListeners[V View, E any](view View, subviewID []string, tag P
return []func(V, E, E){} return []func(V, E, E){}
} }
func setNoArgEventListener[V View](properties Properties, tag PropertyName, value any) []PropertyName { func setNoArgEventListener[V View](view View, tag PropertyName, value any) []PropertyName {
if listeners, ok := valueToNoArgEventListeners[V](value); ok { if listeners, ok := valueToNoArgEventListeners[V](view, value); ok {
if len(listeners) > 0 { if len(listeners) > 0 {
properties.setRaw(tag, listeners) view.setRaw(tag, listeners)
} else if properties.getRaw(tag) != nil { } else if view.getRaw(tag) != nil {
properties.setRaw(tag, nil) view.setRaw(tag, nil)
} else { } else {
return []PropertyName{} return []PropertyName{}
} }
@ -461,12 +681,13 @@ func setNoArgEventListener[V View](properties Properties, tag PropertyName, valu
return nil return nil
} }
func setOneArgEventListener[V View, T any](properties Properties, tag PropertyName, value any) []PropertyName { /*
if listeners, ok := valueToOneArgEventListeners[V, T](value); ok { 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 { if len(listeners) > 0 {
properties.setRaw(tag, listeners) view.setRaw(tag, listeners)
} else if properties.getRaw(tag) != nil { } else if view.getRaw(tag) != nil {
properties.setRaw(tag, nil) view.setRaw(tag, nil)
} else { } else {
return []PropertyName{} return []PropertyName{}
} }
@ -475,16 +696,18 @@ func setOneArgEventListener[V View, T any](properties Properties, tag PropertyNa
notCompatibleType(tag, value) notCompatibleType(tag, value)
return nil return nil
} }
*/
func setTwoArgEventListener[V View, T any](properties Properties, tag PropertyName, value any) []PropertyName { func setTwoArgEventListener[V View, T any](view View, tag PropertyName, value any) []PropertyName {
listeners, ok := valueToTwoArgEventListeners[V, T](value) listeners, ok := valueToTwoArgEventListeners[V, T](view, value)
if !ok { if !ok {
notCompatibleType(tag, value) notCompatibleType(tag, value)
return nil return nil
} else if len(listeners) > 0 { }
properties.setRaw(tag, listeners) if len(listeners) > 0 {
} else if properties.getRaw(tag) != nil { view.setRaw(tag, listeners)
properties.setRaw(tag, nil) } else if view.getRaw(tag) != nil {
view.setRaw(tag, nil)
} else { } else {
return []PropertyName{} return []PropertyName{}
} }
@ -493,7 +716,15 @@ func setTwoArgEventListener[V View, T any](properties Properties, tag PropertyNa
func viewEventsHtml[T any](view View, events []PropertyName, buffer *strings.Builder) { func viewEventsHtml[T any](view View, events []PropertyName, buffer *strings.Builder) {
for _, tag := range events { for _, tag := range events {
if value := view.getRaw(tag); value != nil { 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 js, ok := eventJsFunc[tag]; ok {
if listeners, ok := value.([] func(View, T)); ok && len(listeners) > 0 { if listeners, ok := value.([] func(View, T)); ok && len(listeners) > 0 {
buffer.WriteString(js.jsEvent) buffer.WriteString(js.jsEvent)
@ -503,6 +734,7 @@ func viewEventsHtml[T any](view View, events []PropertyName, buffer *strings.Bui
} }
} }
} }
*/
} }
} }

266
events1arg.go Normal file
View File

@ -0,0 +1,266 @@
package rui
import (
"reflect"
)
type oneArgListener[V View, E any] interface {
Run(V, E)
rawListener() any
}
type oneArgListener0[V View, E any] struct {
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]) Run(_ V, _ E) {
data.fn()
}
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]) Run(view V, _ E) {
data.fn(view)
}
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]) Run(_ V, event E) {
data.fn(event)
}
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]) Run(view V, arg E) {
data.fn(view, arg)
}
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]) Run(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 {
method.Call(args)
} else {
ErrorLogF(`Unsupported prototype of "%s" method`, data.name)
}
}
func (data *oneArgListenerBinding[V, E]) rawListener() any {
return data.name
}
func valueToOneArgEventListeners[V View, E any](value any) ([]oneArgListener[V, E], bool) {
if value == nil {
return nil, true
}
switch value := value.(type) {
case []oneArgListener[V, E]:
return value, true
case oneArgListener[V, E]:
return []oneArgListener[V, E]{value}, true
case string:
return []oneArgListener[V, E]{newOneArgListenerBinding[V, E](value)}, true
case func(V, E):
return []oneArgListener[V, E]{newOneArgListenerVE(value)}, true
case func(V):
return []oneArgListener[V, E]{newOneArgListenerV[V, E](value)}, true
case func(E):
return []oneArgListener[V, E]{newOneArgListenerE[V](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(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](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))
case func(E):
result = append(result, newOneArgListenerE[V](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 setOneArgEventListener[V View, T any](view View, tag PropertyName, value any) []PropertyName {
if listeners, ok := valueToOneArgEventListeners[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 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
}

View File

@ -282,8 +282,8 @@ func (picker *filePickerData) handleCommand(self View, command PropertyName, dat
case "fileSelected": case "fileSelected":
if files := parseFilesTag(data); files != nil { if files := parseFilesTag(data); files != nil {
picker.files = files picker.files = files
for _, listener := range GetFileSelectedListeners(picker) { for _, listener := range getOneArgEventListeners[FilePicker, []FileInfo](picker, nil, FileSelectedEvent) {
listener(picker, files) listener.Run(picker, files)
} }
} }
return true return true
@ -317,13 +317,17 @@ func LoadFilePickerFile(view View, subviewID string, file FileInfo, result func(
} }
// IsMultipleFilePicker returns "true" if multiple files can be selected in the FilePicker, "false" otherwise. // IsMultipleFilePicker returns "true" if multiple files can be selected in the FilePicker, "false" otherwise.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func IsMultipleFilePicker(view View, subviewID ...string) bool { func IsMultipleFilePicker(view View, subviewID ...string) bool {
return boolStyledProperty(view, subviewID, Multiple, false) return boolStyledProperty(view, subviewID, Multiple, false)
} }
// GetFilePickerAccept returns sets the list of allowed file extensions or MIME types. // GetFilePickerAccept returns sets the list of allowed file extensions or MIME types.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetFilePickerAccept(view View, subviewID ...string) []string { func GetFilePickerAccept(view View, subviewID ...string) []string {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
accept, ok := stringProperty(view, Accept, view.Session()) accept, ok := stringProperty(view, Accept, view.Session())
@ -345,7 +349,16 @@ func GetFilePickerAccept(view View, subviewID ...string) []string {
// GetFileSelectedListeners returns the "file-selected-event" listener list. // GetFileSelectedListeners returns the "file-selected-event" listener list.
// If there are no listeners then the empty list is returned. // If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetFileSelectedListeners(view View, subviewID ...string) []func(FilePicker, []FileInfo) { // Result elements can be of the following types:
return getOneArgEventListeners[FilePicker, []FileInfo](view, subviewID, FileSelectedEvent) // - func(rui.View, []rui.FileInfo),
// - func(rui.View),
// - func([]rui.FileInfo),
// - 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 GetFileSelectedListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[FilePicker, []FileInfo](view, subviewID, FileSelectedEvent)
} }

View File

@ -49,13 +49,17 @@ func focusEventsHtml(view View, buffer *strings.Builder) {
} }
// GetFocusListeners returns a FocusListener list. If there are no listeners then the empty list is returned // GetFocusListeners returns a FocusListener list. If there are no listeners then the empty list is returned
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetFocusListeners(view View, subviewID ...string) []func(View) { func GetFocusListeners(view View, subviewID ...string) []func(View) {
return getNoArgEventListeners[View](view, subviewID, FocusEvent) return getNoArgEventListeners[View](view, subviewID, FocusEvent)
} }
// GetLostFocusListeners returns a LostFocusListener list. If there are no listeners then the empty list is returned // GetLostFocusListeners returns a LostFocusListener list. If there are no listeners then the empty list is returned
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetLostFocusListeners(view View, subviewID ...string) []func(View) { func GetLostFocusListeners(view View, subviewID ...string) []func(View) {
return getNoArgEventListeners[View](view, subviewID, LostFocusEvent) return getNoArgEventListeners[View](view, subviewID, LostFocusEvent)
} }

View File

@ -506,26 +506,34 @@ func gridCellSizes(properties Properties, tag PropertyName, session Session) []S
} }
// GetCellVerticalAlign returns the vertical align of a GridLayout cell content: TopAlign (0), BottomAlign (1), CenterAlign (2), StretchAlign (3) // GetCellVerticalAlign returns the vertical align of a GridLayout cell content: TopAlign (0), BottomAlign (1), CenterAlign (2), StretchAlign (3)
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetCellVerticalAlign(view View, subviewID ...string) int { func GetCellVerticalAlign(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, CellVerticalAlign, StretchAlign, false) return enumStyledProperty(view, subviewID, CellVerticalAlign, StretchAlign, false)
} }
// GetCellHorizontalAlign returns the vertical align of a GridLayout cell content: LeftAlign (0), RightAlign (1), CenterAlign (2), StretchAlign (3) // GetCellHorizontalAlign returns the vertical align of a GridLayout cell content: LeftAlign (0), RightAlign (1), CenterAlign (2), StretchAlign (3)
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetCellHorizontalAlign(view View, subviewID ...string) int { func GetCellHorizontalAlign(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, CellHorizontalAlign, StretchAlign, false) return enumStyledProperty(view, subviewID, CellHorizontalAlign, StretchAlign, false)
} }
// GetGridAutoFlow returns the value of the "grid-auto-flow" property // GetGridAutoFlow returns the value of the "grid-auto-flow" property
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetGridAutoFlow(view View, subviewID ...string) int { func GetGridAutoFlow(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, GridAutoFlow, 0, false) return enumStyledProperty(view, subviewID, GridAutoFlow, 0, false)
} }
// GetCellWidth returns the width of a GridLayout cell. If the result is an empty array, then the width is not set. // GetCellWidth returns the width of a GridLayout cell. If the result is an empty array, then the width is not set.
// If the result is a single value array, then the width of all cell is equal. // If the result is a single value array, then the width of all cell is equal.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetCellWidth(view View, subviewID ...string) []SizeUnit { func GetCellWidth(view View, subviewID ...string) []SizeUnit {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
return gridCellSizes(view, CellWidth, view.Session()) return gridCellSizes(view, CellWidth, view.Session())
@ -535,7 +543,9 @@ func GetCellWidth(view View, subviewID ...string) []SizeUnit {
// GetCellHeight returns the height of a GridLayout cell. If the result is an empty array, then the height is not set. // GetCellHeight returns the height of a GridLayout cell. If the result is an empty array, then the height is not set.
// If the result is a single value array, then the height of all cell is equal. // If the result is a single value array, then the height of all cell is equal.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetCellHeight(view View, subviewID ...string) []SizeUnit { func GetCellHeight(view View, subviewID ...string) []SizeUnit {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
return gridCellSizes(view, CellHeight, view.Session()) return gridCellSizes(view, CellHeight, view.Session())
@ -544,13 +554,17 @@ func GetCellHeight(view View, subviewID ...string) []SizeUnit {
} }
// GetGridRowGap returns the gap between GridLayout rows. // GetGridRowGap returns the gap between GridLayout rows.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetGridRowGap(view View, subviewID ...string) SizeUnit { func GetGridRowGap(view View, subviewID ...string) SizeUnit {
return sizeStyledProperty(view, subviewID, GridRowGap, false) return sizeStyledProperty(view, subviewID, GridRowGap, false)
} }
// GetGridColumnGap returns the gap between GridLayout columns. // GetGridColumnGap returns the gap between GridLayout columns.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetGridColumnGap(view View, subviewID ...string) SizeUnit { func GetGridColumnGap(view View, subviewID ...string) SizeUnit {
return sizeStyledProperty(view, subviewID, GridColumnGap, false) return sizeStyledProperty(view, subviewID, GridColumnGap, false)
} }

View File

@ -434,15 +434,13 @@ func (event *KeyEvent) init(data DataObject) {
} }
func keyEventsHtml(view View, buffer *strings.Builder) { func keyEventsHtml(view View, buffer *strings.Builder) {
if len(getOneArgEventListeners[View, KeyEvent](view, nil, KeyDownEvent)) > 0 { if len(getOneArgEventListeners[View, KeyEvent](view, nil, KeyDownEvent)) > 0 ||
(view.Focusable() && len(getOneArgEventListeners[View, MouseEvent](view, nil, ClickEvent)) > 0) {
buffer.WriteString(`onkeydown="keyDownEvent(this, event)" `) buffer.WriteString(`onkeydown="keyDownEvent(this, event)" `)
} else if view.Focusable() {
if len(getOneArgEventListeners[View, MouseEvent](view, nil, ClickEvent)) > 0 {
buffer.WriteString(`onkeydown="keyDownEvent(this, event)" `)
}
} }
if listeners := getOneArgEventListeners[View, KeyEvent](view, nil, KeyUpEvent); len(listeners) > 0 { if len(getOneArgEventListeners[View, KeyEvent](view, nil, KeyUpEvent)) > 0 {
buffer.WriteString(`onkeyup="keyUpEvent(this, event)" `) buffer.WriteString(`onkeyup="keyUpEvent(this, event)" `)
} }
} }
@ -454,7 +452,7 @@ func handleKeyEvents(view View, tag PropertyName, data DataObject) {
if len(listeners) > 0 { if len(listeners) > 0 {
for _, listener := range listeners { for _, listener := range listeners {
listener(view, event) listener.Run(view, event)
} }
return return
} }
@ -477,20 +475,38 @@ func handleKeyEvents(view View, tag PropertyName, data DataObject) {
ScreenY: view.Frame().Top + view.Frame().Height/2, ScreenY: view.Frame().Top + view.Frame().Height/2,
} }
for _, listener := range listeners { for _, listener := range listeners {
listener(view, clickEvent) listener.Run(view, clickEvent)
} }
} }
} }
} }
// GetKeyDownListeners returns the "key-down-event" listener list. If there are no listeners then the empty list is returned. // GetKeyDownListeners returns the "key-down-event" listener list. If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetKeyDownListeners(view View, subviewID ...string) []func(View, KeyEvent) { // Result elements can be of the following types:
return getOneArgEventListeners[View, KeyEvent](view, subviewID, KeyDownEvent) // - func(rui.View, rui.KeyEvent),
// - func(rui.View),
// - func(rui.KeyEvent),
// - 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 GetKeyDownListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, KeyEvent](view, subviewID, KeyDownEvent)
} }
// GetKeyUpListeners returns the "key-up-event" listener list. If there are no listeners then the empty list is returned. // GetKeyUpListeners returns the "key-up-event" listener list. If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetKeyUpListeners(view View, subviewID ...string) []func(View, KeyEvent) { // Result elements can be of the following types:
return getOneArgEventListeners[View, KeyEvent](view, subviewID, KeyUpEvent) // - func(rui.View, rui.KeyEvent),
// - func(rui.View),
// - func(rui.KeyEvent),
// - 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 GetKeyUpListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, KeyEvent](view, subviewID, KeyUpEvent)
} }

View File

@ -205,21 +205,27 @@ func (listLayout *listLayoutData) UpdateContent() {
// GetListVerticalAlign returns the vertical align of a ListLayout or ListView sibview: // GetListVerticalAlign returns the vertical align of a ListLayout or ListView sibview:
// TopAlign (0), BottomAlign (1), CenterAlign (2), or StretchAlign (3) // TopAlign (0), BottomAlign (1), CenterAlign (2), or StretchAlign (3)
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetListVerticalAlign(view View, subviewID ...string) int { func GetListVerticalAlign(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, VerticalAlign, TopAlign, false) return enumStyledProperty(view, subviewID, VerticalAlign, TopAlign, false)
} }
// GetListHorizontalAlign returns the vertical align of a ListLayout or ListView subview: // GetListHorizontalAlign returns the vertical align of a ListLayout or ListView subview:
// LeftAlign (0), RightAlign (1), CenterAlign (2), or StretchAlign (3) // LeftAlign (0), RightAlign (1), CenterAlign (2), or StretchAlign (3)
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetListHorizontalAlign(view View, subviewID ...string) int { func GetListHorizontalAlign(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, HorizontalAlign, LeftAlign, false) return enumStyledProperty(view, subviewID, HorizontalAlign, LeftAlign, false)
} }
// GetListOrientation returns the orientation of a ListLayout or ListView subview: // GetListOrientation returns the orientation of a ListLayout or ListView subview:
// TopDownOrientation (0), StartToEndOrientation (1), BottomUpOrientation (2), or EndToStartOrientation (3) // TopDownOrientation (0), StartToEndOrientation (1), BottomUpOrientation (2), or EndToStartOrientation (3)
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetListOrientation(view View, subviewID ...string) int { func GetListOrientation(view View, subviewID ...string) int {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
if orientation, ok := valueToOrientation(view.Get(Orientation), view.Session()); ok { if orientation, ok := valueToOrientation(view.Get(Orientation), view.Session()); ok {
@ -238,19 +244,25 @@ func GetListOrientation(view View, subviewID ...string) int {
// GetListWrap returns the wrap type of a ListLayout or ListView subview: // GetListWrap returns the wrap type of a ListLayout or ListView subview:
// ListWrapOff (0), ListWrapOn (1), or ListWrapReverse (2) // ListWrapOff (0), ListWrapOn (1), or ListWrapReverse (2)
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetListWrap(view View, subviewID ...string) int { func GetListWrap(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, ListWrap, ListWrapOff, false) return enumStyledProperty(view, subviewID, ListWrap, ListWrapOff, false)
} }
// GetListRowGap returns the gap between ListLayout or ListView rows. // GetListRowGap returns the gap between ListLayout or ListView rows.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetListRowGap(view View, subviewID ...string) SizeUnit { func GetListRowGap(view View, subviewID ...string) SizeUnit {
return sizeStyledProperty(view, subviewID, ListRowGap, false) return sizeStyledProperty(view, subviewID, ListRowGap, false)
} }
// GetListColumnGap returns the gap between ListLayout or ListView columns. // GetListColumnGap returns the gap between ListLayout or ListView columns.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetListColumnGap(view View, subviewID ...string) SizeUnit { func GetListColumnGap(view View, subviewID ...string) SizeUnit {
return sizeStyledProperty(view, subviewID, ListColumnGap, false) return sizeStyledProperty(view, subviewID, ListColumnGap, false)
} }

View File

@ -122,19 +122,13 @@ type ListView interface {
// ReloadListViewData updates ListView content // ReloadListViewData updates ListView content
ReloadListViewData() ReloadListViewData()
//getCheckedItems() []int
getItemFrames() []Frame getItemFrames() []Frame
} }
type listViewData struct { type listViewData struct {
viewData viewData
//adapter ListAdapter
//clickedListeners []func(ListView, int)
//selectedListeners []func(ListView, int)
//checkedListeners []func(ListView, []int)
items []View items []View
itemFrame []Frame itemFrame []Frame
//checkedItem []int
} }
// NewListView creates the new list view // NewListView creates the new list view
@ -279,7 +273,7 @@ func (listView *listViewData) propertyChanged(tag PropertyName) {
if listeners := getOneArgEventListeners[ListView, int](listView, nil, ListItemSelectedEvent); len(listeners) > 0 { if listeners := getOneArgEventListeners[ListView, int](listView, nil, ListItemSelectedEvent); len(listeners) > 0 {
current := GetCurrent(listView) current := GetCurrent(listView)
for _, listener := range listeners { for _, listener := range listeners {
listener(listView, current) listener.Run(listView, current)
} }
} }
@ -288,7 +282,7 @@ func (listView *listViewData) propertyChanged(tag PropertyName) {
if listeners := getOneArgEventListeners[ListView, []int](listView, nil, ListItemCheckedEvent); len(listeners) > 0 { if listeners := getOneArgEventListeners[ListView, []int](listView, nil, ListItemCheckedEvent); len(listeners) > 0 {
checked := GetListViewCheckedItems(listView) checked := GetListViewCheckedItems(listView)
for _, listener := range listeners { for _, listener := range listeners {
listener(listView, checked) listener.Run(listView, checked)
} }
} }
@ -966,7 +960,7 @@ func (listView *listViewData) handleCommand(self View, command PropertyName, dat
func (listView *listViewData) handleCurrent(number int) { func (listView *listViewData) handleCurrent(number int) {
listView.properties[Current] = number listView.properties[Current] = number
for _, listener := range getOneArgEventListeners[ListView, int](listView, nil, ListItemSelectedEvent) { for _, listener := range getOneArgEventListeners[ListView, int](listView, nil, ListItemSelectedEvent) {
listener(listView, number) listener.Run(listView, number)
} }
if listener, ok := listView.changeListener[Current]; ok { if listener, ok := listView.changeListener[Current]; ok {
listener(listView, Current) listener(listView, Current)
@ -1032,12 +1026,12 @@ func (listView *listViewData) onItemClick(number int) {
} }
for _, listener := range getOneArgEventListeners[ListView, []int](listView, nil, ListItemCheckedEvent) { for _, listener := range getOneArgEventListeners[ListView, []int](listView, nil, ListItemCheckedEvent) {
listener(listView, checkedItem) listener.Run(listView, checkedItem)
} }
} }
for _, listener := range getOneArgEventListeners[ListView, int](listView, nil, ListItemClickedEvent) { for _, listener := range getOneArgEventListeners[ListView, int](listView, nil, ListItemClickedEvent) {
listener(listView, number) listener.Run(listView, number)
} }
} }
@ -1054,58 +1048,97 @@ func (listView *listViewData) onItemResize(self View, index string, x, y, width,
} }
// GetVerticalAlign return the vertical align of a list: TopAlign (0), BottomAlign (1), CenterAlign (2), StretchAlign (3) // GetVerticalAlign return the vertical align of a list: TopAlign (0), BottomAlign (1), CenterAlign (2), StretchAlign (3)
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetVerticalAlign(view View, subviewID ...string) int { func GetVerticalAlign(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, VerticalAlign, TopAlign, false) return enumStyledProperty(view, subviewID, VerticalAlign, TopAlign, false)
} }
// GetHorizontalAlign return the vertical align of a list/checkbox: LeftAlign (0), RightAlign (1), CenterAlign (2), StretchAlign (3) // GetHorizontalAlign return the vertical align of a list/checkbox: LeftAlign (0), RightAlign (1), CenterAlign (2), StretchAlign (3)
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetHorizontalAlign(view View, subviewID ...string) int { func GetHorizontalAlign(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, HorizontalAlign, LeftAlign, false) return enumStyledProperty(view, subviewID, HorizontalAlign, LeftAlign, false)
} }
// GetListItemClickedListeners returns a ListItemClickedListener of the ListView. // GetListItemClickedListeners returns a ListItemClickedListener of the ListView.
// If there are no listeners then the empty list is returned // If there are no listeners then the empty list is returned
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetListItemClickedListeners(view View, subviewID ...string) []func(ListView, int) { // Result elements can be of the following types:
return getOneArgEventListeners[ListView, int](view, subviewID, ListItemClickedEvent) // - func(rui.ListView, int),
// - func(rui.ListView),
// - 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 GetListItemClickedListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[ListView, int](view, subviewID, ListItemClickedEvent)
} }
// GetListItemSelectedListeners returns a ListItemSelectedListener of the ListView. // GetListItemSelectedListeners returns a ListItemSelectedListener of the ListView.
// If there are no listeners then the empty list is returned // If there are no listeners then the empty list is returned
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetListItemSelectedListeners(view View, subviewID ...string) []func(ListView, int) { // Result elements can be of the following types:
return getOneArgEventListeners[ListView, int](view, subviewID, ListItemSelectedEvent) // - func(rui.ListView, int),
// - func(rui.ListView),
// - 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 GetListItemSelectedListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[ListView, int](view, subviewID, ListItemSelectedEvent)
} }
// GetListItemCheckedListeners returns a ListItemCheckedListener of the ListView. // GetListItemCheckedListeners returns a ListItemCheckedListener of the ListView.
// If there are no listeners then the empty list is returned // If there are no listeners then the empty list is returned
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetListItemCheckedListeners(view View, subviewID ...string) []func(ListView, []int) { // Result elements can be of the following types:
return getOneArgEventListeners[ListView, []int](view, subviewID, ListItemCheckedEvent) // - func(rui.ListView, []int),
// - func(rui.ListView),
// - 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 GetListItemCheckedListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[ListView, []int](view, subviewID, ListItemCheckedEvent)
} }
// GetListItemWidth returns the width of a ListView item. // GetListItemWidth returns the width of a ListView item.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetListItemWidth(view View, subviewID ...string) SizeUnit { func GetListItemWidth(view View, subviewID ...string) SizeUnit {
return sizeStyledProperty(view, subviewID, ItemWidth, false) return sizeStyledProperty(view, subviewID, ItemWidth, false)
} }
// GetListItemHeight returns the height of a ListView item. // GetListItemHeight returns the height of a ListView item.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetListItemHeight(view View, subviewID ...string) SizeUnit { func GetListItemHeight(view View, subviewID ...string) SizeUnit {
return sizeStyledProperty(view, subviewID, ItemHeight, false) return sizeStyledProperty(view, subviewID, ItemHeight, false)
} }
// GetListViewCheckbox returns the ListView checkbox type: NoneCheckbox (0), SingleCheckbox (1), or MultipleCheckbox (2). // GetListViewCheckbox returns the ListView checkbox type: NoneCheckbox (0), SingleCheckbox (1), or MultipleCheckbox (2).
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetListViewCheckbox(view View, subviewID ...string) int { func GetListViewCheckbox(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, ItemCheckbox, 0, false) return enumStyledProperty(view, subviewID, ItemCheckbox, 0, false)
} }
// GetListViewCheckedItems returns the array of ListView checked items. // GetListViewCheckedItems returns the array of ListView checked items.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetListViewCheckedItems(view View, subviewID ...string) []int { func GetListViewCheckedItems(view View, subviewID ...string) []int {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
if value := view.getRaw(Checked); value != nil { if value := view.getRaw(Checked); value != nil {
@ -1138,34 +1171,44 @@ func IsListViewCheckedItem(view View, subviewID string, index int) bool {
// GetListViewCheckboxVerticalAlign returns the vertical align of the ListView checkbox: // GetListViewCheckboxVerticalAlign returns the vertical align of the ListView checkbox:
// TopAlign (0), BottomAlign (1), CenterAlign (2) // TopAlign (0), BottomAlign (1), CenterAlign (2)
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetListViewCheckboxVerticalAlign(view View, subviewID ...string) int { func GetListViewCheckboxVerticalAlign(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, CheckboxVerticalAlign, TopAlign, false) return enumStyledProperty(view, subviewID, CheckboxVerticalAlign, TopAlign, false)
} }
// GetListViewCheckboxHorizontalAlign returns the horizontal align of the ListView checkbox: // GetListViewCheckboxHorizontalAlign returns the horizontal align of the ListView checkbox:
// LeftAlign (0), RightAlign (1), CenterAlign (2) // LeftAlign (0), RightAlign (1), CenterAlign (2)
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetListViewCheckboxHorizontalAlign(view View, subviewID ...string) int { func GetListViewCheckboxHorizontalAlign(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, CheckboxHorizontalAlign, LeftAlign, false) return enumStyledProperty(view, subviewID, CheckboxHorizontalAlign, LeftAlign, false)
} }
// GetListItemVerticalAlign returns the vertical align of the ListView item content: // GetListItemVerticalAlign returns the vertical align of the ListView item content:
// TopAlign (0), BottomAlign (1), CenterAlign (2) // TopAlign (0), BottomAlign (1), CenterAlign (2)
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetListItemVerticalAlign(view View, subviewID ...string) int { func GetListItemVerticalAlign(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, ItemVerticalAlign, TopAlign, false) return enumStyledProperty(view, subviewID, ItemVerticalAlign, TopAlign, false)
} }
// ItemHorizontalAlign returns the horizontal align of the ListView item content: // ItemHorizontalAlign returns the horizontal align of the ListView item content:
// LeftAlign (0), RightAlign (1), CenterAlign (2), StretchAlign (3) // LeftAlign (0), RightAlign (1), CenterAlign (2), StretchAlign (3)
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetListItemHorizontalAlign(view View, subviewID ...string) int { func GetListItemHorizontalAlign(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, ItemHorizontalAlign, LeftAlign, false) return enumStyledProperty(view, subviewID, ItemHorizontalAlign, LeftAlign, false)
} }
// GetListItemFrame - returns the location and size of the ListView item in pixels. // GetListItemFrame - returns the location and size of the ListView item in pixels.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetListItemFrame(view View, subviewID string, index int) Frame { func GetListItemFrame(view View, subviewID string, index int) Frame {
if subviewID != "" { if subviewID != "" {
view = ViewByID(view, subviewID) view = ViewByID(view, subviewID)
@ -1182,7 +1225,9 @@ func GetListItemFrame(view View, subviewID string, index int) Frame {
} }
// GetListViewAdapter - returns the ListView adapter. // GetListViewAdapter - returns the ListView adapter.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetListViewAdapter(view View, subviewID ...string) ListAdapter { func GetListViewAdapter(view View, subviewID ...string) ListAdapter {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
if value := view.Get(Items); value != nil { if value := view.Get(Items); value != nil {

View File

@ -280,56 +280,128 @@ func handleMouseEvents(view View, tag PropertyName, data DataObject) {
event.init(data) event.init(data)
for _, listener := range listeners { for _, listener := range listeners {
listener(view, event) listener.Run(view, event)
} }
} }
} }
// GetClickListeners returns the "click-event" listener list. If there are no listeners then the empty list is returned. // GetClickListeners returns the "click-event" listener list. If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetClickListeners(view View, subviewID ...string) []func(View, MouseEvent) { // Result elements can be of the following types:
return getOneArgEventListeners[View, MouseEvent](view, subviewID, ClickEvent) // - func(View, MouseEvent),
// - func(View),
// - func(MouseEvent),
// - 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 GetClickListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, MouseEvent](view, subviewID, ClickEvent)
} }
// GetDoubleClickListeners returns the "double-click-event" listener list. If there are no listeners then the empty list is returned. // GetDoubleClickListeners returns the "double-click-event" listener list. If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetDoubleClickListeners(view View, subviewID ...string) []func(View, MouseEvent) { // Result elements can be of the following types:
return getOneArgEventListeners[View, MouseEvent](view, subviewID, DoubleClickEvent) // - func(View, MouseEvent),
// - func(View),
// - func(MouseEvent),
// - 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 GetDoubleClickListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, MouseEvent](view, subviewID, DoubleClickEvent)
} }
// GetContextMenuListeners returns the "context-menu" listener list. // GetContextMenuListeners returns the "context-menu" listener list.
// If there are no listeners then the empty list is returned. // If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetContextMenuListeners(view View, subviewID ...string) []func(View, MouseEvent) { // Result elements can be of the following types:
return getOneArgEventListeners[View, MouseEvent](view, subviewID, ContextMenuEvent) // - func(View, MouseEvent),
// - func(View),
// - func(MouseEvent),
// - 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 GetContextMenuListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, MouseEvent](view, subviewID, ContextMenuEvent)
} }
// GetMouseDownListeners returns the "mouse-down" listener list. If there are no listeners then the empty list is returned. // GetMouseDownListeners returns the "mouse-down" listener list. If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetMouseDownListeners(view View, subviewID ...string) []func(View, MouseEvent) { // Result elements can be of the following types:
return getOneArgEventListeners[View, MouseEvent](view, subviewID, MouseDown) // - func(View, MouseEvent),
// - func(View),
// - func(MouseEvent),
// - 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 GetMouseDownListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, MouseEvent](view, subviewID, MouseDown)
} }
// GetMouseUpListeners returns the "mouse-up" listener list. If there are no listeners then the empty list is returned. // GetMouseUpListeners returns the "mouse-up" listener list. If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetMouseUpListeners(view View, subviewID ...string) []func(View, MouseEvent) { // Result elements can be of the following types:
return getOneArgEventListeners[View, MouseEvent](view, subviewID, MouseUp) // - func(View, MouseEvent),
// - func(View),
// - func(MouseEvent),
// - 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 GetMouseUpListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, MouseEvent](view, subviewID, MouseUp)
} }
// GetMouseMoveListeners returns the "mouse-move" listener list. If there are no listeners then the empty list is returned. // GetMouseMoveListeners returns the "mouse-move" listener list. If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetMouseMoveListeners(view View, subviewID ...string) []func(View, MouseEvent) { // Result elements can be of the following types:
return getOneArgEventListeners[View, MouseEvent](view, subviewID, MouseMove) // - func(View, MouseEvent),
// - func(View),
// - func(MouseEvent),
// - 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 GetMouseMoveListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, MouseEvent](view, subviewID, MouseMove)
} }
// GetMouseOverListeners returns the "mouse-over" listener list. If there are no listeners then the empty list is returned. // GetMouseOverListeners returns the "mouse-over" listener list. If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetMouseOverListeners(view View, subviewID ...string) []func(View, MouseEvent) { // Result elements can be of the following types:
return getOneArgEventListeners[View, MouseEvent](view, subviewID, MouseOver) // - func(View, MouseEvent),
// - func(View),
// - func(MouseEvent),
// - 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 GetMouseOverListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, MouseEvent](view, subviewID, MouseOver)
} }
// GetMouseOutListeners returns the "mouse-out" listener list. If there are no listeners then the empty list is returned. // GetMouseOutListeners returns the "mouse-out" listener list. If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetMouseOutListeners(view View, subviewID ...string) []func(View, MouseEvent) { // Result elements can be of the following types:
return getOneArgEventListeners[View, MouseEvent](view, subviewID, MouseOut) // - func(View, MouseEvent),
// - func(View),
// - func(MouseEvent),
// - 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 GetMouseOutListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, MouseEvent](view, subviewID, MouseOut)
} }

View File

@ -298,13 +298,17 @@ func (picker *numberPickerData) handleCommand(self View, command PropertyName, d
// GetNumberPickerType returns the type of NumberPicker subview. Valid values: // GetNumberPickerType returns the type of NumberPicker subview. Valid values:
// NumberEditor (0) - NumberPicker is presented by editor (default type); // NumberEditor (0) - NumberPicker is presented by editor (default type);
// NumberSlider (1) - NumberPicker is presented by slider. // NumberSlider (1) - NumberPicker is presented by slider.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetNumberPickerType(view View, subviewID ...string) int { func GetNumberPickerType(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, NumberPickerType, NumberEditor, false) return enumStyledProperty(view, subviewID, NumberPickerType, NumberEditor, false)
} }
// GetNumberPickerMinMax returns the min and max value of NumberPicker subview. // GetNumberPickerMinMax returns the min and max value of NumberPicker subview.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetNumberPickerMinMax(view View, subviewID ...string) (float64, float64) { func GetNumberPickerMinMax(view View, subviewID ...string) (float64, float64) {
view = getSubview(view, subviewID) view = getSubview(view, subviewID)
pickerType := GetNumberPickerType(view) pickerType := GetNumberPickerType(view)
@ -328,7 +332,9 @@ func GetNumberPickerMinMax(view View, subviewID ...string) (float64, float64) {
} }
// GetNumberPickerStep returns the value changing step of NumberPicker subview. // GetNumberPickerStep returns the value changing step of NumberPicker subview.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetNumberPickerStep(view View, subviewID ...string) float64 { func GetNumberPickerStep(view View, subviewID ...string) float64 {
view = getSubview(view, subviewID) view = getSubview(view, subviewID)
_, max := GetNumberPickerMinMax(view) _, max := GetNumberPickerMinMax(view)
@ -341,7 +347,9 @@ func GetNumberPickerStep(view View, subviewID ...string) float64 {
} }
// GetNumberPickerValue returns the value of NumberPicker subview. // GetNumberPickerValue returns the value of NumberPicker subview.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetNumberPickerValue(view View, subviewID ...string) float64 { func GetNumberPickerValue(view View, subviewID ...string) float64 {
view = getSubview(view, subviewID) view = getSubview(view, subviewID)
min, _ := GetNumberPickerMinMax(view) min, _ := GetNumberPickerMinMax(view)
@ -350,13 +358,17 @@ 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
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetNumberChangedListeners(view View, subviewID ...string) []func(NumberPicker, float64, float64) { func GetNumberChangedListeners(view View, subviewID ...string) []func(NumberPicker, float64, float64) {
return getTwoArgEventListeners[NumberPicker, float64](view, subviewID, NumberChangedEvent) return getTwoArgEventListeners[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.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetNumberPickerPrecision(view View, subviewID ...string) int { func GetNumberPickerPrecision(view View, subviewID ...string) int {
return intStyledProperty(view, subviewID, NumberPickerPrecision, 0) return intStyledProperty(view, subviewID, NumberPickerPrecision, 0)
} }

View File

@ -192,42 +192,96 @@ func handlePointerEvents(view View, tag PropertyName, data DataObject) {
event.init(data) event.init(data)
for _, listener := range listeners { for _, listener := range listeners {
listener(view, event) listener.Run(view, event)
} }
} }
// GetPointerDownListeners returns the "pointer-down" listener list. If there are no listeners then the empty list is returned. // GetPointerDownListeners returns the "pointer-down" listener list. If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetPointerDownListeners(view View, subviewID ...string) []func(View, PointerEvent) { // Result elements can be of the following types:
return getOneArgEventListeners[View, PointerEvent](view, subviewID, PointerDown) // - func(View, PointerEvent),
// - func(View),
// - func(PointerEvent),
// - 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 GetPointerDownListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, PointerEvent](view, subviewID, PointerDown)
} }
// GetPointerUpListeners returns the "pointer-up" listener list. If there are no listeners then the empty list is returned. // GetPointerUpListeners returns the "pointer-up" listener list. If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetPointerUpListeners(view View, subviewID ...string) []func(View, PointerEvent) { // Result elements can be of the following types:
return getOneArgEventListeners[View, PointerEvent](view, subviewID, PointerUp) // - func(View, PointerEvent),
// - func(View),
// - func(PointerEvent),
// - 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 GetPointerUpListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, PointerEvent](view, subviewID, PointerUp)
} }
// GetPointerMoveListeners returns the "pointer-move" listener list. If there are no listeners then the empty list is returned. // GetPointerMoveListeners returns the "pointer-move" listener list. If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetPointerMoveListeners(view View, subviewID ...string) []func(View, PointerEvent) { // Result elements can be of the following types:
return getOneArgEventListeners[View, PointerEvent](view, subviewID, PointerMove) // - func(View, PointerEvent),
// - func(View),
// - func(PointerEvent),
// - 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 GetPointerMoveListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, PointerEvent](view, subviewID, PointerMove)
} }
// GetPointerCancelListeners returns the "pointer-cancel" listener list. If there are no listeners then the empty list is returned. // GetPointerCancelListeners returns the "pointer-cancel" listener list. If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetPointerCancelListeners(view View, subviewID ...string) []func(View, PointerEvent) { // Result elements can be of the following types:
return getOneArgEventListeners[View, PointerEvent](view, subviewID, PointerCancel) // - func(View, PointerEvent),
// - func(View),
// - func(PointerEvent),
// - 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 GetPointerCancelListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, PointerEvent](view, subviewID, PointerCancel)
} }
// GetPointerOverListeners returns the "pointer-over" listener list. If there are no listeners then the empty list is returned. // GetPointerOverListeners returns the "pointer-over" listener list. If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetPointerOverListeners(view View, subviewID ...string) []func(View, PointerEvent) { // Result elements can be of the following types:
return getOneArgEventListeners[View, PointerEvent](view, subviewID, PointerOver) // - func(View, PointerEvent),
// - func(View),
// - func(PointerEvent),
// - 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 GetPointerOverListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, PointerEvent](view, subviewID, PointerOver)
} }
// GetPointerOutListeners returns the "pointer-out" listener list. If there are no listeners then the empty list is returned. // GetPointerOutListeners returns the "pointer-out" listener list. If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetPointerOutListeners(view View, subviewID ...string) []func(View, PointerEvent) { // Result elements can be of the following types:
return getOneArgEventListeners[View, PointerEvent](view, subviewID, PointerOut) // - func(View, PointerEvent),
// - func(View),
// - func(PointerEvent),
// - 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 GetPointerOutListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, PointerEvent](view, subviewID, PointerOut)
} }

View File

@ -649,7 +649,7 @@ func (popup *popupData) init(view View, popupParams Params) {
} }
case DismissEvent: case DismissEvent:
if listeners, ok := valueToNoArgEventListeners[Popup](value); ok { if listeners, ok := valueToNoArgEventListeners[Popup](popup.contentView, value); ok {
if listeners != nil { if listeners != nil {
popup.dismissListener = listeners popup.dismissListener = listeners
} }

View File

@ -101,13 +101,17 @@ func (progress *progressBarData) htmlProperties(self View, buffer *strings.Build
} }
// GetProgressBarMax returns the max value of ProgressBar subview. // GetProgressBarMax returns the max value of ProgressBar subview.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetProgressBarMax(view View, subviewID ...string) float64 { func GetProgressBarMax(view View, subviewID ...string) float64 {
return floatStyledProperty(view, subviewID, ProgressBarMax, 1) return floatStyledProperty(view, subviewID, ProgressBarMax, 1)
} }
// GetProgressBarValue returns the value of ProgressBar subview. // GetProgressBarValue returns the value of ProgressBar subview.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetProgressBarValue(view View, subviewID ...string) float64 { func GetProgressBarValue(view View, subviewID ...string) float64 {
return floatStyledProperty(view, subviewID, ProgressBarValue, 0) return floatStyledProperty(view, subviewID, ProgressBarValue, 0)
} }

View File

@ -2723,4 +2723,6 @@ const (
// //
// Supported types: string. // Supported types: string.
Tooltip PropertyName = "tooltip" Tooltip PropertyName = "tooltip"
Binding PropertyName = "binding"
) )

View File

@ -25,8 +25,8 @@ func (view *viewData) onResize(self View, x, y, width, height float64) {
view.frame.Top = y view.frame.Top = y
view.frame.Width = width view.frame.Width = width
view.frame.Height = height view.frame.Height = height
for _, listener := range GetResizeListeners(view) { for _, listener := range getOneArgEventListeners[View, Frame](view, nil, ResizeEvent) {
listener(self, view.frame) listener.Run(self, view.frame)
} }
} }
@ -73,7 +73,9 @@ func (view *viewData) Frame() Frame {
} }
// GetViewFrame returns the size and location of view's viewport. // GetViewFrame returns the size and location of view's viewport.
// If the second argument (subviewID) is not specified or it is "" then the value of the first argument (view) is 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.
func GetViewFrame(view View, subviewID ...string) Frame { func GetViewFrame(view View, subviewID ...string) Frame {
view = getSubview(view, subviewID) view = getSubview(view, subviewID)
if view == nil { if view == nil {
@ -83,7 +85,16 @@ func GetViewFrame(view View, subviewID ...string) Frame {
} }
// GetResizeListeners returns the list of "resize-event" listeners. If there are no listeners then the empty list is returned // GetResizeListeners returns the list of "resize-event" listeners. If there are no listeners then the empty list is returned
// If the second argument (subviewID) is not specified or it is "" then the listeners list of the first argument (view) is returned //
func GetResizeListeners(view View, subviewID ...string) []func(View, Frame) { // Result elements can be of the following types:
return getOneArgEventListeners[View, Frame](view, subviewID, ResizeEvent) // - func(rui.View, rui.Frame),
// - func(rui.View),
// - func(rui.Frame),
// - 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 GetResizeListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, Frame](view, subviewID, ResizeEvent)
} }

View File

@ -25,8 +25,8 @@ func (view *viewData) onScroll(self View, x, y, width, height float64) {
view.scroll.Top = y view.scroll.Top = y
view.scroll.Width = width view.scroll.Width = width
view.scroll.Height = height view.scroll.Height = height
for _, listener := range GetScrollListeners(view) { for _, listener := range getOneArgEventListeners[View, Frame](view, nil, ScrollEvent) {
listener(self, view.scroll) listener.Run(self, view.scroll)
} }
} }
@ -42,7 +42,9 @@ func (view *viewData) setScroll(x, y, width, height float64) {
} }
// GetViewScroll returns ... // GetViewScroll returns ...
// If the second argument (subviewID) is not specified or it is "" then a value of the first argument (view) is 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.
func GetViewScroll(view View, subviewID ...string) Frame { func GetViewScroll(view View, subviewID ...string) Frame {
view = getSubview(view, subviewID) view = getSubview(view, subviewID)
if view == nil { if view == nil {
@ -52,13 +54,24 @@ func GetViewScroll(view View, subviewID ...string) Frame {
} }
// GetScrollListeners returns the list of "scroll-event" listeners. If there are no listeners then the empty list is returned // GetScrollListeners returns the list of "scroll-event" listeners. If there are no listeners then the empty list is returned
// If the second argument (subviewID) is not specified or it is "" then the listeners list of the first argument (view) is returned //
func GetScrollListeners(view View, subviewID ...string) []func(View, Frame) { // Result elements can be of the following types:
return getOneArgEventListeners[View, Frame](view, subviewID, ResizeEvent) // - func(rui.View, rui.Frame),
// - func(rui.View),
// - func(rui.Frame),
// - 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 GetScrollListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, Frame](view, subviewID, ScrollEvent)
} }
// ScrollTo scrolls the view's content to the given position. // ScrollTo scrolls the view's content to the given position.
// If the second argument (subviewID) is "" then the first argument (view) is used //
// 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 ScrollViewTo(view View, subviewID string, x, y float64) { func ScrollViewTo(view View, subviewID string, x, y float64) {
if subviewID != "" { if subviewID != "" {
view = ViewByID(view, subviewID) view = ViewByID(view, subviewID)
@ -69,7 +82,9 @@ func ScrollViewTo(view View, subviewID string, x, y float64) {
} }
// ScrollViewToEnd scrolls the view's content to the start of view. // ScrollViewToEnd scrolls the view's content to the start of view.
// If the second argument (subviewID) is not specified or it is "" then the first argument (view) is used //
// 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 ScrollViewToStart(view View, subviewID ...string) { func ScrollViewToStart(view View, subviewID ...string) {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
view.Session().callFunc("scrollToStart", view.htmlID()) view.Session().callFunc("scrollToStart", view.htmlID())
@ -77,7 +92,9 @@ func ScrollViewToStart(view View, subviewID ...string) {
} }
// ScrollViewToEnd scrolls the view's content to the end of view. // ScrollViewToEnd scrolls the view's content to the end of view.
// If the second argument (subviewID) is not specified or it is "" then the first argument (view) is used //
// 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 ScrollViewToEnd(view View, subviewID ...string) { func ScrollViewToEnd(view View, subviewID ...string) {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
view.Session().callFunc("scrollToEnd", view.htmlID()) view.Session().callFunc("scrollToEnd", view.htmlID())

View File

@ -334,7 +334,9 @@ func (layout *stackLayoutData) init(session Session) {
layout.remove = layout.removeFunc layout.remove = layout.removeFunc
layout.changed = layout.propertyChanged layout.changed = layout.propertyChanged
layout.setRaw(TransitionEndEvent, []func(View, PropertyName){layout.transitionFinished}) layout.setRaw(TransitionEndEvent, []oneArgListener[View, PropertyName]{
newOneArgListenerVE(layout.transitionFinished),
})
if session.TextDirection() == RightToLeftDirection { if session.TextDirection() == RightToLeftDirection {
layout.setRaw(PushTransform, NewTransformProperty(Params{TranslateX: Percent(-100)})) layout.setRaw(PushTransform, NewTransformProperty(Params{TranslateX: Percent(-100)}))
} else { } else {
@ -434,7 +436,7 @@ func (layout *stackLayoutData) setFunc(tag PropertyName, value any) []PropertyNa
// TODO // TODO
listeners, ok := valueToOneArgEventListeners[View, PropertyName](value) listeners, ok := valueToOneArgEventListeners[View, PropertyName](value)
if ok && listeners != nil { if ok && listeners != nil {
listeners = append(listeners, layout.transitionFinished) listeners = append(listeners, newOneArgListenerVE(layout.transitionFinished))
layout.setRaw(TransitionEndEvent, listeners) layout.setRaw(TransitionEndEvent, listeners)
return []PropertyName{tag} return []PropertyName{tag}
} }
@ -464,7 +466,9 @@ func (layout *stackLayoutData) propertyChanged(tag PropertyName) {
func (layout *stackLayoutData) removeFunc(tag PropertyName) []PropertyName { func (layout *stackLayoutData) removeFunc(tag PropertyName) []PropertyName {
switch tag { switch tag {
case TransitionEndEvent: case TransitionEndEvent:
layout.setRaw(TransitionEndEvent, []func(View, PropertyName){layout.transitionFinished}) layout.setRaw(TransitionEndEvent, []oneArgListener[View, PropertyName]{
newOneArgListenerVE(layout.transitionFinished),
})
return []PropertyName{tag} return []PropertyName{tag}
} }
return layout.viewsContainerData.removeFunc(tag) return layout.viewsContainerData.removeFunc(tag)
@ -914,7 +918,9 @@ func (layout *stackLayoutData) htmlSubviews(self View, buffer *strings.Builder)
} }
// IsMoveToFrontAnimation returns "true" if an animation is used when calling the MoveToFront/MoveToFrontByID method of StackLayout interface. // IsMoveToFrontAnimation returns "true" if an animation is used when calling the MoveToFront/MoveToFrontByID method of StackLayout interface.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func IsMoveToFrontAnimation(view View, subviewID ...string) bool { func IsMoveToFrontAnimation(view View, subviewID ...string) bool {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
if value, ok := boolProperty(view, MoveToFrontAnimation, view.Session()); ok { if value, ok := boolProperty(view, MoveToFrontAnimation, view.Session()); ok {
@ -950,7 +956,9 @@ func GetPushTiming(view View, subviewID ...string) string {
// GetPushTransform returns the start transform (translation, scale and rotation over x, y and z axes as well as a distortion) // GetPushTransform returns the start transform (translation, scale and rotation over x, y and z axes as well as a distortion)
// for an animated pushing of a child view. // for an animated pushing of a child view.
// The default value is nil (no transform). // The default value is nil (no transform).
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetPushTransform(view View, subviewID ...string) TransformProperty { func GetPushTransform(view View, subviewID ...string) TransformProperty {
return transformStyledProperty(view, subviewID, PushTransform) return transformStyledProperty(view, subviewID, PushTransform)
} }

View File

@ -592,14 +592,6 @@ func (table *tableViewData) init(session Session) {
table.tag = "TableView" table.tag = "TableView"
table.cellViews = []View{} table.cellViews = []View{}
table.cellFrame = []Frame{} table.cellFrame = []Frame{}
/*
table.cellSelectedListener = []func(TableView, int, int){}
table.cellClickedListener = []func(TableView, int, int){}
table.rowSelectedListener = []func(TableView, int){}
table.rowClickedListener = []func(TableView, int){}
table.current.Row = -1
table.current.Column = -1
*/
table.normalize = normalizeTableViewTag table.normalize = normalizeTableViewTag
table.set = table.setFunc table.set = table.setFunc
table.changed = table.propertyChanged table.changed = table.propertyChanged
@ -955,63 +947,6 @@ func tableViewCurrentInactiveStyle(view View) string {
return "ruiCurrentTableCell" return "ruiCurrentTableCell"
} }
/*
func (table *tableViewData) valueToCellListeners(value any) []func(TableView, int, int) {
if value == nil {
return []func(TableView, int, int){}
}
switch value := value.(type) {
case func(TableView, int, int):
return []func(TableView, int, int){value}
case func(int, int):
fn := func(_ TableView, row, column int) {
value(row, column)
}
return []func(TableView, int, int){fn}
case []func(TableView, int, int):
return value
case []func(int, int):
listeners := make([]func(TableView, int, int), len(value))
for i, val := range value {
if val == nil {
return nil
}
listeners[i] = func(_ TableView, row, column int) {
val(row, column)
}
}
return listeners
case []any:
listeners := make([]func(TableView, int, int), len(value))
for i, val := range value {
if val == nil {
return nil
}
switch val := val.(type) {
case func(TableView, int, int):
listeners[i] = val
case func(int, int):
listeners[i] = func(_ TableView, row, column int) {
val(row, column)
}
default:
return nil
}
}
return listeners
}
return nil
}
*/
func (table *tableViewData) htmlTag() string { func (table *tableViewData) htmlTag() string {
return "table" return "table"
} }
@ -1735,8 +1670,8 @@ func (table *tableViewData) handleCommand(self View, command PropertyName, data
listener(table, Current) listener(table, Current)
} }
for _, listener := range GetTableRowSelectedListeners(table) { for _, listener := range getOneArgEventListeners[TableView, int](table, nil, TableRowSelectedEvent) {
listener(table, row) listener.Run(table, row)
} }
} }
@ -1761,8 +1696,8 @@ func (table *tableViewData) handleCommand(self View, command PropertyName, data
case "rowClick": case "rowClick":
if row, ok := dataIntProperty(data, "row"); ok { if row, ok := dataIntProperty(data, "row"); ok {
for _, listener := range GetTableRowClickedListeners(table) { for _, listener := range getOneArgEventListeners[TableView, int](table, nil, TableRowClickedEvent) {
listener(table, row) listener.Run(table, row)
} }
} }

View File

@ -26,7 +26,9 @@ func (cell *tableCellView) cssStyle(self View, builder cssBuilder) {
} }
// GetTableContent returns a TableAdapter which defines the TableView content. // GetTableContent returns a TableAdapter which defines the TableView content.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTableContent(view View, subviewID ...string) TableAdapter { func GetTableContent(view View, subviewID ...string) TableAdapter {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
if content := view.getRaw(Content); content != nil { if content := view.getRaw(Content); content != nil {
@ -40,7 +42,9 @@ func GetTableContent(view View, subviewID ...string) TableAdapter {
} }
// GetTableRowStyle returns a TableRowStyle which defines styles of TableView rows. // GetTableRowStyle returns a TableRowStyle which defines styles of TableView rows.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTableRowStyle(view View, subviewID ...string) TableRowStyle { func GetTableRowStyle(view View, subviewID ...string) TableRowStyle {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
for _, tag := range []PropertyName{RowStyle, Content} { for _, tag := range []PropertyName{RowStyle, Content} {
@ -56,7 +60,9 @@ func GetTableRowStyle(view View, subviewID ...string) TableRowStyle {
} }
// GetTableColumnStyle returns a TableColumnStyle which defines styles of TableView columns. // GetTableColumnStyle returns a TableColumnStyle which defines styles of TableView columns.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTableColumnStyle(view View, subviewID ...string) TableColumnStyle { func GetTableColumnStyle(view View, subviewID ...string) TableColumnStyle {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
for _, tag := range []PropertyName{ColumnStyle, Content} { for _, tag := range []PropertyName{ColumnStyle, Content} {
@ -72,7 +78,9 @@ func GetTableColumnStyle(view View, subviewID ...string) TableColumnStyle {
} }
// GetTableCellStyle returns a TableCellStyle which defines styles of TableView cells. // GetTableCellStyle returns a TableCellStyle which defines styles of TableView cells.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTableCellStyle(view View, subviewID ...string) TableCellStyle { func GetTableCellStyle(view View, subviewID ...string) TableCellStyle {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
for _, tag := range []PropertyName{CellStyle, Content} { for _, tag := range []PropertyName{CellStyle, Content} {
@ -90,26 +98,34 @@ func GetTableCellStyle(view View, subviewID ...string) TableCellStyle {
// GetTableSelectionMode returns the mode of the TableView elements selection. // GetTableSelectionMode returns the mode of the TableView elements selection.
// Valid values are NoneSelection (0), CellSelection (1), and RowSelection (2). // Valid values are NoneSelection (0), CellSelection (1), and RowSelection (2).
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTableSelectionMode(view View, subviewID ...string) int { func GetTableSelectionMode(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, SelectionMode, NoneSelection, false) return enumStyledProperty(view, subviewID, SelectionMode, NoneSelection, false)
} }
// GetTableVerticalAlign returns a vertical align in a TableView cell. Returns one of next values: // GetTableVerticalAlign returns a vertical align in a TableView cell. Returns one of next values:
// TopAlign (0), BottomAlign (1), CenterAlign (2), and BaselineAlign (3) // TopAlign (0), BottomAlign (1), CenterAlign (2), and BaselineAlign (3)
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTableVerticalAlign(view View, subviewID ...string) int { func GetTableVerticalAlign(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, TableVerticalAlign, TopAlign, false) return enumStyledProperty(view, subviewID, TableVerticalAlign, TopAlign, false)
} }
// GetTableHeadHeight returns the number of rows in the table header. // GetTableHeadHeight returns the number of rows in the table header.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTableHeadHeight(view View, subviewID ...string) int { func GetTableHeadHeight(view View, subviewID ...string) int {
return intStyledProperty(view, subviewID, HeadHeight, 0) return intStyledProperty(view, subviewID, HeadHeight, 0)
} }
// GetTableFootHeight returns the number of rows in the table footer. // GetTableFootHeight returns the number of rows in the table footer.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTableFootHeight(view View, subviewID ...string) int { func GetTableFootHeight(view View, subviewID ...string) int {
return intStyledProperty(view, subviewID, FootHeight, 0) return intStyledProperty(view, subviewID, FootHeight, 0)
} }
@ -118,7 +134,9 @@ func GetTableFootHeight(view View, subviewID ...string) int {
// If there is no selected cell/row or the selection mode is NoneSelection (0), // If there is no selected cell/row or the selection mode is NoneSelection (0),
// then a value of the row and column index less than 0 is returned. // then a value of the row and column index less than 0 is returned.
// If the selection mode is RowSelection (2) then the returned column index is less than 0. // If the selection mode is RowSelection (2) then the returned column index is less than 0.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTableCurrent(view View, subviewID ...string) CellIndex { func GetTableCurrent(view View, subviewID ...string) CellIndex {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
if selectionMode := GetTableSelectionMode(view); selectionMode != NoneSelection { if selectionMode := GetTableSelectionMode(view); selectionMode != NoneSelection {
@ -130,30 +148,52 @@ 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.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTableCellClickedListeners(view View, subviewID ...string) []func(TableView, int, int) { func GetTableCellClickedListeners(view View, subviewID ...string) []func(TableView, int, int) {
return getTwoArgEventListeners[TableView, int](view, subviewID, TableCellClickedEvent) return getTwoArgEventListeners[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.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTableCellSelectedListeners(view View, subviewID ...string) []func(TableView, int, int) { func GetTableCellSelectedListeners(view View, subviewID ...string) []func(TableView, int, int) {
return getTwoArgEventListeners[TableView, int](view, subviewID, TableCellSelectedEvent) return getTwoArgEventListeners[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.
// If there are no listeners then the empty list is returned. // If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetTableRowClickedListeners(view View, subviewID ...string) []func(TableView, int) { // Result elements can be of the following types:
return getOneArgEventListeners[TableView, int](view, subviewID, TableRowClickedEvent) // - func(rui.TableView, int),
// - func(rui.TableView),
// - 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 GetTableRowClickedListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[TableView, int](view, subviewID, TableRowClickedEvent)
} }
// GetTableRowSelectedListeners returns listeners of event which occurs when a table row becomes selected. // GetTableRowSelectedListeners returns listeners of event which occurs when a table row becomes selected.
// If there are no listeners then the empty list is returned. // If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetTableRowSelectedListeners(view View, subviewID ...string) []func(TableView, int) { // Result elements can be of the following types:
return getOneArgEventListeners[TableView, int](view, subviewID, TableRowSelectedEvent) // - func(rui.TableView, int),
// - func(rui.TableView),
// - 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 GetTableRowSelectedListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[TableView, int](view, subviewID, TableRowSelectedEvent)
} }
// ReloadTableViewData updates TableView // ReloadTableViewData updates TableView

View File

@ -238,155 +238,6 @@ func (tabsLayout *tabsLayoutData) propertyChanged(tag PropertyName) {
} }
} }
/*
func (tabsLayout *tabsLayoutData) valueToTabListeners(value any) []func(TabsLayout, int, int) {
if value == nil {
return []func(TabsLayout, int, int){}
}
switch value := value.(type) {
case func(TabsLayout, int, int):
return []func(TabsLayout, int, int){value}
case func(TabsLayout, int):
fn := func(view TabsLayout, current, _ int) {
value(view, current)
}
return []func(TabsLayout, int, int){fn}
case func(TabsLayout):
fn := func(view TabsLayout, _, _ int) {
value(view)
}
return []func(TabsLayout, int, int){fn}
case func(int, int):
fn := func(_ TabsLayout, current, old int) {
value(current, old)
}
return []func(TabsLayout, int, int){fn}
case func(int):
fn := func(_ TabsLayout, current, _ int) {
value(current)
}
return []func(TabsLayout, int, int){fn}
case func():
fn := func(TabsLayout, int, int) {
value()
}
return []func(TabsLayout, int, int){fn}
case []func(TabsLayout, int, int):
return value
case []func(TabsLayout, int):
listeners := make([]func(TabsLayout, int, int), len(value))
for i, val := range value {
if val == nil {
return nil
}
listeners[i] = func(view TabsLayout, current, _ int) {
val(view, current)
}
}
return listeners
case []func(TabsLayout):
listeners := make([]func(TabsLayout, int, int), len(value))
for i, val := range value {
if val == nil {
return nil
}
listeners[i] = func(view TabsLayout, _, _ int) {
val(view)
}
}
return listeners
case []func(int, int):
listeners := make([]func(TabsLayout, int, int), len(value))
for i, val := range value {
if val == nil {
return nil
}
listeners[i] = func(_ TabsLayout, current, old int) {
val(current, old)
}
}
return listeners
case []func(int):
listeners := make([]func(TabsLayout, int, int), len(value))
for i, val := range value {
if val == nil {
return nil
}
listeners[i] = func(_ TabsLayout, current, _ int) {
val(current)
}
}
return listeners
case []func():
listeners := make([]func(TabsLayout, int, int), len(value))
for i, val := range value {
if val == nil {
return nil
}
listeners[i] = func(TabsLayout, int, int) {
val()
}
}
return listeners
case []any:
listeners := make([]func(TabsLayout, int, int), len(value))
for i, val := range value {
if val == nil {
return nil
}
switch val := val.(type) {
case func(TabsLayout, int, int):
listeners[i] = val
case func(TabsLayout, int):
listeners[i] = func(view TabsLayout, current, _ int) {
val(view, current)
}
case func(TabsLayout):
listeners[i] = func(view TabsLayout, _, _ int) {
val(view)
}
case func(int, int):
listeners[i] = func(_ TabsLayout, current, old int) {
val(current, old)
}
case func(int):
listeners[i] = func(_ TabsLayout, current, _ int) {
val(current)
}
case func():
listeners[i] = func(TabsLayout, int, int) {
val()
}
default:
return nil
}
}
return listeners
}
return nil
}
*/
func (tabsLayout *tabsLayoutData) tabsLocation() int { func (tabsLayout *tabsLayoutData) tabsLocation() int {
tabs, _ := enumProperty(tabsLayout, Tabs, tabsLayout.session, 0) tabs, _ := enumProperty(tabsLayout, Tabs, tabsLayout.session, 0)
return tabs return tabs
@ -504,7 +355,7 @@ func (tabsLayout *tabsLayoutData) ListItem(index int, session Session) View {
Content: "✕", Content: "✕",
ClickEvent: func() { ClickEvent: func() {
for _, listener := range getOneArgEventListeners[TabsLayout, int](tabsLayout, nil, TabCloseEvent) { for _, listener := range getOneArgEventListeners[TabsLayout, int](tabsLayout, nil, TabCloseEvent) {
listener(tabsLayout, index) listener.Run(tabsLayout, index)
} }
}, },
})) }))
@ -892,7 +743,7 @@ func (tabsLayout *tabsLayoutData) handleCommand(self View, command PropertyName,
if numberText, ok := data.PropertyValue("number"); ok { if numberText, ok := data.PropertyValue("number"); ok {
if number, err := strconv.Atoi(numberText); err == nil { if number, err := strconv.Atoi(numberText); err == nil {
for _, listener := range getOneArgEventListeners[TabsLayout, int](tabsLayout, nil, TabCloseEvent) { for _, listener := range getOneArgEventListeners[TabsLayout, int](tabsLayout, nil, TabCloseEvent) {
listener(tabsLayout, number) listener.Run(tabsLayout, number)
} }
} }
} }
@ -900,3 +751,18 @@ func (tabsLayout *tabsLayoutData) handleCommand(self View, command PropertyName,
} }
return tabsLayout.viewsContainerData.handleCommand(self, command, data) return tabsLayout.viewsContainerData.handleCommand(self, command, data)
} }
// GetTabCloseEventListeners returns the "tab-close-event" 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),
// - func(rui.TabsLayout),
// - 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 GetTabCloseEventListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[TabsLayout, int](view, subviewID, TabCloseEvent)
}

View File

@ -111,7 +111,9 @@ func (textView *textViewData) htmlSubviews(self View, buffer *strings.Builder) {
// GetTextOverflow returns a value of the "text-overflow" property: // GetTextOverflow returns a value of the "text-overflow" property:
// TextOverflowClip (0) or TextOverflowEllipsis (1). // TextOverflowClip (0) or TextOverflowEllipsis (1).
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTextOverflow(view View, subviewID ...string) int { func GetTextOverflow(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, TextOverflow, SingleLineText, false) return enumStyledProperty(view, subviewID, TextOverflow, SingleLineText, false)
} }

View File

@ -373,7 +373,9 @@ func getTimeProperty(view View, mainTag, shortTag PropertyName) (time.Time, bool
// GetTimePickerMin returns the min time of TimePicker subview and "true" as the second value if the min time is set, // GetTimePickerMin returns the min time of TimePicker subview and "true" as the second value if the min time is set,
// "false" as the second value otherwise. // "false" as the second value otherwise.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTimePickerMin(view View, subviewID ...string) (time.Time, bool) { func GetTimePickerMin(view View, subviewID ...string) (time.Time, bool) {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
return getTimeProperty(view, TimePickerMin, Min) return getTimeProperty(view, TimePickerMin, Min)
@ -383,7 +385,9 @@ func GetTimePickerMin(view View, subviewID ...string) (time.Time, bool) {
// GetTimePickerMax returns the max time of TimePicker subview and "true" as the second value if the min time is set, // GetTimePickerMax returns the max time of TimePicker subview and "true" as the second value if the min time is set,
// "false" as the second value otherwise. // "false" as the second value otherwise.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTimePickerMax(view View, subviewID ...string) (time.Time, bool) { func GetTimePickerMax(view View, subviewID ...string) (time.Time, bool) {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
return getTimeProperty(view, TimePickerMax, Max) return getTimeProperty(view, TimePickerMax, Max)
@ -392,13 +396,17 @@ func GetTimePickerMax(view View, subviewID ...string) (time.Time, bool) {
} }
// GetTimePickerStep returns the time changing step in seconds of TimePicker subview. // GetTimePickerStep returns the time changing step in seconds of TimePicker subview.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTimePickerStep(view View, subviewID ...string) int { func GetTimePickerStep(view View, subviewID ...string) int {
return intStyledProperty(view, subviewID, TimePickerStep, 60) return intStyledProperty(view, subviewID, TimePickerStep, 60)
} }
// GetTimePickerValue returns the time of TimePicker subview. // GetTimePickerValue returns the time of TimePicker subview.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTimePickerValue(view View, subviewID ...string) time.Time { func GetTimePickerValue(view View, subviewID ...string) time.Time {
if view = getSubview(view, subviewID); view == nil { if view = getSubview(view, subviewID); view == nil {
return time.Now() return time.Now()
@ -409,7 +417,9 @@ 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
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTimeChangedListeners(view View, subviewID ...string) []func(TimePicker, time.Time, time.Time) { func GetTimeChangedListeners(view View, subviewID ...string) []func(TimePicker, time.Time, time.Time) {
return getTwoArgEventListeners[TimePicker, time.Time](view, subviewID, TimeChangedEvent) return getTwoArgEventListeners[TimePicker, time.Time](view, subviewID, TimeChangedEvent)
} }

View File

@ -193,30 +193,66 @@ func handleTouchEvents(view View, tag PropertyName, data DataObject) {
event.init(data) event.init(data)
for _, listener := range listeners { for _, listener := range listeners {
listener(view, event) listener.Run(view, event)
} }
} }
// GetTouchStartListeners returns the "touch-start" listener list. If there are no listeners then the empty list is returned. // GetTouchStartListeners returns the "touch-start" listener list. If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetTouchStartListeners(view View, subviewID ...string) []func(View, TouchEvent) { // Result elements can be of the following types:
return getOneArgEventListeners[View, TouchEvent](view, subviewID, TouchStart) // - func(rui.View, rui.TouchEvent),
// - func(rui.View),
// - func(rui.TouchEvent),
// - 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 GetTouchStartListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, TouchEvent](view, subviewID, TouchStart)
} }
// GetTouchEndListeners returns the "touch-end" listener list. If there are no listeners then the empty list is returned. // GetTouchEndListeners returns the "touch-end" listener list. If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetTouchEndListeners(view View, subviewID ...string) []func(View, TouchEvent) { // Result elements can be of the following types:
return getOneArgEventListeners[View, TouchEvent](view, subviewID, TouchEnd) // - func(rui.View, rui.TouchEvent),
// - func(rui.View),
// - func(rui.TouchEvent),
// - 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 GetTouchEndListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, TouchEvent](view, subviewID, TouchEnd)
} }
// GetTouchMoveListeners returns the "touch-move" listener list. If there are no listeners then the empty list is returned. // GetTouchMoveListeners returns the "touch-move" listener list. If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetTouchMoveListeners(view View, subviewID ...string) []func(View, TouchEvent) { // Result elements can be of the following types:
return getOneArgEventListeners[View, TouchEvent](view, subviewID, TouchMove) // - func(rui.View, rui.TouchEvent),
// - func(rui.View),
// - func(rui.TouchEvent),
// - 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 GetTouchMoveListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, TouchEvent](view, subviewID, TouchMove)
} }
// GetTouchCancelListeners returns the "touch-cancel" listener list. If there are no listeners then the empty list is returned. // GetTouchCancelListeners returns the "touch-cancel" listener list. If there are no listeners then the empty list is returned.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned. //
func GetTouchCancelListeners(view View, subviewID ...string) []func(View, TouchEvent) { // Result elements can be of the following types:
return getOneArgEventListeners[View, TouchEvent](view, subviewID, TouchCancel) // - func(rui.View, rui.TouchEvent),
// - func(rui.View),
// - func(rui.TouchEvent),
// - 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 GetTouchCancelListeners(view View, subviewID ...string) []any {
return getOneArgEventRawListeners[View, TouchEvent](view, subviewID, TouchCancel)
} }

View File

@ -647,7 +647,9 @@ func transformOriginCSS(x, y, z SizeUnit, session Session) string {
// GetTransform returns a view transform: translation, scale and rotation over x, y and z axes as well as a distortion of a view along x and y axes. // GetTransform returns a view transform: translation, scale and rotation over x, y and z axes as well as a distortion of a view along x and y axes.
// The default value is nil (no transform) // The default value is nil (no transform)
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTransform(view View, subviewID ...string) TransformProperty { func GetTransform(view View, subviewID ...string) TransformProperty {
return transformStyledProperty(view, subviewID, Transform) return transformStyledProperty(view, subviewID, Transform)
} }
@ -655,14 +657,18 @@ func GetTransform(view View, subviewID ...string) TransformProperty {
// GetPerspective returns a distance between the z = 0 plane and the user in order to give a 3D-positioned // GetPerspective returns a distance between the z = 0 plane and the user in order to give a 3D-positioned
// element some perspective. Each 3D element with z > 0 becomes larger; each 3D-element with z < 0 becomes smaller. // element some perspective. Each 3D element with z > 0 becomes larger; each 3D-element with z < 0 becomes smaller.
// The default value is 0 (no 3D effects). // The default value is 0 (no 3D effects).
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetPerspective(view View, subviewID ...string) SizeUnit { func GetPerspective(view View, subviewID ...string) SizeUnit {
return sizeStyledProperty(view, subviewID, Perspective, false) return sizeStyledProperty(view, subviewID, Perspective, false)
} }
// GetPerspectiveOrigin returns a x- and y-coordinate of the position at which the viewer is looking. // GetPerspectiveOrigin returns a x- and y-coordinate of the position at which the viewer is looking.
// It is used as the vanishing point by the Perspective property. The default value is (50%, 50%). // It is used as the vanishing point by the Perspective property. The default value is (50%, 50%).
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetPerspectiveOrigin(view View, subviewID ...string) (SizeUnit, SizeUnit) { func GetPerspectiveOrigin(view View, subviewID ...string) (SizeUnit, SizeUnit) {
view = getSubview(view, subviewID) view = getSubview(view, subviewID)
if view == nil { if view == nil {
@ -675,14 +681,18 @@ func GetPerspectiveOrigin(view View, subviewID ...string) (SizeUnit, SizeUnit) {
// visible when turned towards the user. Values: // visible when turned towards the user. Values:
// true - the back face is visible when turned towards the user (default value). // true - the back face is visible when turned towards the user (default value).
// false - the back face is hidden, effectively making the element invisible when turned away from the user. // false - the back face is hidden, effectively making the element invisible when turned away from the user.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetBackfaceVisible(view View, subviewID ...string) bool { func GetBackfaceVisible(view View, subviewID ...string) bool {
return boolStyledProperty(view, subviewID, BackfaceVisible, false) return boolStyledProperty(view, subviewID, BackfaceVisible, false)
} }
// GetTransformOrigin returns a x-, y-, and z-coordinate of the point around which a view transformation is applied. // GetTransformOrigin returns a x-, y-, and z-coordinate of the point around which a view transformation is applied.
// The default value is (50%, 50%, 50%). // The default value is (50%, 50%, 50%).
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTransformOrigin(view View, subviewID ...string) (SizeUnit, SizeUnit, SizeUnit) { func GetTransformOrigin(view View, subviewID ...string) (SizeUnit, SizeUnit, SizeUnit) {
view = getSubview(view, subviewID) view = getSubview(view, subviewID)
if view == nil { if view == nil {
@ -692,7 +702,9 @@ func GetTransformOrigin(view View, subviewID ...string) (SizeUnit, SizeUnit, Siz
} }
// GetTranslate returns a x-, y-, and z-axis translation value of a 2D/3D translation // GetTranslate returns a x-, y-, and z-axis translation value of a 2D/3D translation
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTranslate(view View, subviewID ...string) (SizeUnit, SizeUnit, SizeUnit) { func GetTranslate(view View, subviewID ...string) (SizeUnit, SizeUnit, SizeUnit) {
if transform := GetTransform(view, subviewID...); transform != nil { if transform := GetTransform(view, subviewID...); transform != nil {
return transform.getTranslate(view.Session()) return transform.getTranslate(view.Session())
@ -702,7 +714,9 @@ func GetTranslate(view View, subviewID ...string) (SizeUnit, SizeUnit, SizeUnit)
// GetSkew returns a angles to use to distort the element along the abscissa (x-axis) // GetSkew returns a angles to use to distort the element along the abscissa (x-axis)
// and the ordinate (y-axis). The default value is 0. // and the ordinate (y-axis). The default value is 0.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetSkew(view View, subviewID ...string) (AngleUnit, AngleUnit) { func GetSkew(view View, subviewID ...string) (AngleUnit, AngleUnit) {
if transform := GetTransform(view, subviewID...); transform != nil { if transform := GetTransform(view, subviewID...); transform != nil {
x, y, _ := transform.getSkew(view.Session()) x, y, _ := transform.getSkew(view.Session())
@ -712,7 +726,9 @@ func GetSkew(view View, subviewID ...string) (AngleUnit, AngleUnit) {
} }
// GetScale returns a x-, y-, and z-axis scaling value of a 2D/3D scale. The default value is 1. // GetScale returns a x-, y-, and z-axis scaling value of a 2D/3D scale. The default value is 1.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetScale(view View, subviewID ...string) (float64, float64, float64) { func GetScale(view View, subviewID ...string) (float64, float64, float64) {
if transform := GetTransform(view, subviewID...); transform != nil { if transform := GetTransform(view, subviewID...); transform != nil {
session := view.Session() session := view.Session()
@ -725,7 +741,9 @@ func GetScale(view View, subviewID ...string) (float64, float64, float64) {
} }
// GetRotate returns a x-, y, z-coordinate of the vector denoting the axis of rotation, and the angle of the view rotation // GetRotate returns a x-, y, z-coordinate of the vector denoting the axis of rotation, and the angle of the view rotation
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetRotate(view View, subviewID ...string) (float64, float64, float64, AngleUnit) { func GetRotate(view View, subviewID ...string) (float64, float64, float64, AngleUnit) {
if transform := GetTransform(view, subviewID...); transform != nil { if transform := GetTransform(view, subviewID...); transform != nil {
session := view.Session() session := view.Session()

42
view.go
View File

@ -92,6 +92,7 @@ type View interface {
addToCSSStyle(addCSS map[string]string) addToCSSStyle(addCSS map[string]string)
exscludeTags() []PropertyName exscludeTags() []PropertyName
htmlDisabledProperty() bool htmlDisabledProperty() bool
binding() any
onResize(self View, x, y, width, height float64) onResize(self View, x, y, width, height float64)
onItemResize(self View, index string, x, y, width, height float64) onItemResize(self View, index string, x, y, width, height float64)
@ -195,6 +196,18 @@ func (view *viewData) ID() string {
return view.viewID return view.viewID
} }
func (view *viewData) binding() any {
if result := view.getRaw(Binding); result != nil {
return result
}
if parent := view.Parent(); parent != nil {
return parent.binding()
}
return nil
}
func (view *viewData) ViewByID(id string) View { func (view *viewData) ViewByID(id string) View {
if id == view.ID() { if id == view.ID() {
if v := view.session.viewByHTMLID(view.htmlID()); v != nil { if v := view.session.viewByHTMLID(view.htmlID()); v != nil {
@ -304,6 +317,14 @@ func (view *viewData) removeFunc(tag PropertyName) []PropertyName {
changedTags = []PropertyName{} changedTags = []PropertyName{}
} }
case Binding:
if view.getRaw(Binding) != nil {
view.setRaw(Binding, nil)
changedTags = []PropertyName{Binding}
} else {
changedTags = []PropertyName{}
}
case Animation: case Animation:
if val := view.getRaw(Animation); val != nil { if val := view.getRaw(Animation); val != nil {
if animations, ok := val.([]AnimationProperty); ok { if animations, ok := val.([]AnimationProperty); ok {
@ -336,6 +357,10 @@ func (view *viewData) setFunc(tag PropertyName, value any) []PropertyName {
notCompatibleType(ID, value) notCompatibleType(ID, value)
return nil return nil
case Binding:
view.setRaw(Binding, value)
return []PropertyName{Binding}
case Animation: case Animation:
oldAnimations := []AnimationProperty{} oldAnimations := []AnimationProperty{}
if val := view.getRaw(Animation); val != nil { if val := view.getRaw(Animation); val != nil {
@ -386,20 +411,15 @@ func (view *viewData) setFunc(tag PropertyName, value any) []PropertyName {
case TransitionRunEvent, TransitionStartEvent, TransitionEndEvent, TransitionCancelEvent: case TransitionRunEvent, TransitionStartEvent, TransitionEndEvent, TransitionCancelEvent:
result := setOneArgEventListener[View, PropertyName](view, tag, value) result := setOneArgEventListener[View, PropertyName](view, tag, value)
if result == nil { if result == nil {
result = setOneArgEventListener[View, string](view, tag, value) if listeners, ok := valueToOneArgEventListeners[View, string](view); ok && len(listeners) > 0 {
if result != nil { newListeners := make([]oneArgListener[View, PropertyName], len(listeners))
if listeners, ok := view.getRaw(tag).([]func(View, string)); ok {
newListeners := make([]func(View, PropertyName), len(listeners))
for i, listener := range listeners { for i, listener := range listeners {
newListeners[i] = func(view View, name PropertyName) { newListeners[i] = newOneArgListenerVE(func(view View, name PropertyName) {
listener(view, string(name)) listener.Run(view, string(name))
} })
} }
view.setRaw(tag, newListeners) view.setRaw(tag, newListeners)
return result result = []PropertyName{tag}
}
view.setRaw(tag, nil)
return nil
} }
} }
return result return result

View File

@ -355,31 +355,41 @@ func GetTextShadows(view View, subviewID ...string) []ShadowProperty {
} }
// GetBackgroundColor returns a background color of the subview. // GetBackgroundColor returns a background color of the subview.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetBackgroundColor(view View, subviewID ...string) Color { func GetBackgroundColor(view View, subviewID ...string) Color {
return colorStyledProperty(view, subviewID, BackgroundColor, false) return colorStyledProperty(view, subviewID, BackgroundColor, false)
} }
// GetAccentColor returns the accent color for UI controls generated by some elements. // GetAccentColor returns the accent color for UI controls generated by some elements.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetAccentColor(view View, subviewID ...string) Color { func GetAccentColor(view View, subviewID ...string) Color {
return colorStyledProperty(view, subviewID, AccentColor, false) return colorStyledProperty(view, subviewID, AccentColor, false)
} }
// GetFontName returns the subview font. // GetFontName returns the subview font.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetFontName(view View, subviewID ...string) string { func GetFontName(view View, subviewID ...string) string {
return stringStyledProperty(view, nil, FontName, true) return stringStyledProperty(view, nil, FontName, true)
} }
// GetTextColor returns a text color of the subview. // GetTextColor returns a text color of the subview.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTextColor(view View, subviewID ...string) Color { func GetTextColor(view View, subviewID ...string) Color {
return colorStyledProperty(view, subviewID, TextColor, true) return colorStyledProperty(view, subviewID, TextColor, true)
} }
// GetTextSize returns a text size of the subview. // GetTextSize returns a text size of the subview.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTextSize(view View, subviewID ...string) SizeUnit { func GetTextSize(view View, subviewID ...string) SizeUnit {
return sizeStyledProperty(view, subviewID, TextSize, true) return sizeStyledProperty(view, subviewID, TextSize, true)
} }
@ -392,7 +402,9 @@ func GetTabSize(view View, subviewID ...string) int {
// GetTextWeight returns a text weight of the subview. Returns one of next values: // GetTextWeight returns a text weight of the subview. Returns one of next values:
// 1, 2, 3, 4 (normal text), 5, 6, 7 (bold text), 8 and 9 // 1, 2, 3, 4 (normal text), 5, 6, 7 (bold text), 8 and 9
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTextWeight(view View, subviewID ...string) int { func GetTextWeight(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, TextWeight, NormalFont, true) return enumStyledProperty(view, subviewID, TextWeight, NormalFont, true)
} }
@ -401,7 +413,8 @@ func GetTextWeight(view View, subviewID ...string) int {
// //
// LeftAlign = 0, RightAlign = 1, CenterAlign = 2, JustifyAlign = 3 // LeftAlign = 0, RightAlign = 1, CenterAlign = 2, JustifyAlign = 3
// //
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTextAlign(view View, subviewID ...string) int { func GetTextAlign(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, TextAlign, LeftAlign, true) return enumStyledProperty(view, subviewID, TextAlign, LeftAlign, true)
} }
@ -410,89 +423,116 @@ func GetTextAlign(view View, subviewID ...string) int {
// //
// TextWrapOn = 0, TextWrapOff = 1, TextWrapBalance = 3 // TextWrapOn = 0, TextWrapOff = 1, TextWrapBalance = 3
// //
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTextWrap(view View, subviewID ...string) int { func GetTextWrap(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, TextWrap, TextWrapOn, true) return enumStyledProperty(view, subviewID, TextWrap, TextWrapOn, true)
} }
// GetTextIndent returns a text indent of the subview. // GetTextIndent returns a text indent of the subview.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTextIndent(view View, subviewID ...string) SizeUnit { func GetTextIndent(view View, subviewID ...string) SizeUnit {
return sizeStyledProperty(view, subviewID, TextIndent, true) return sizeStyledProperty(view, subviewID, TextIndent, true)
} }
// GetLetterSpacing returns a letter spacing of the subview. // GetLetterSpacing returns a letter spacing of the subview.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetLetterSpacing(view View, subviewID ...string) SizeUnit { func GetLetterSpacing(view View, subviewID ...string) SizeUnit {
return sizeStyledProperty(view, subviewID, LetterSpacing, true) return sizeStyledProperty(view, subviewID, LetterSpacing, true)
} }
// GetWordSpacing returns a word spacing of the subview. // GetWordSpacing returns a word spacing of the subview.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetWordSpacing(view View, subviewID ...string) SizeUnit { func GetWordSpacing(view View, subviewID ...string) SizeUnit {
return sizeStyledProperty(view, subviewID, WordSpacing, true) return sizeStyledProperty(view, subviewID, WordSpacing, true)
} }
// GetLineHeight returns a height of a text line of the subview. // GetLineHeight returns a height of a text line of the subview.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetLineHeight(view View, subviewID ...string) SizeUnit { func GetLineHeight(view View, subviewID ...string) SizeUnit {
return sizeStyledProperty(view, subviewID, LineHeight, true) return sizeStyledProperty(view, subviewID, LineHeight, true)
} }
// IsItalic returns "true" if a text font of the subview is displayed in italics, "false" otherwise. // IsItalic returns "true" if a text font of the subview is displayed in italics, "false" otherwise.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func IsItalic(view View, subviewID ...string) bool { func IsItalic(view View, subviewID ...string) bool {
return boolStyledProperty(view, subviewID, Italic, true) return boolStyledProperty(view, subviewID, Italic, true)
} }
// IsSmallCaps returns "true" if a text font of the subview is displayed in small caps, "false" otherwise. // IsSmallCaps returns "true" if a text font of the subview is displayed in small caps, "false" otherwise.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func IsSmallCaps(view View, subviewID ...string) bool { func IsSmallCaps(view View, subviewID ...string) bool {
return boolStyledProperty(view, subviewID, SmallCaps, true) return boolStyledProperty(view, subviewID, SmallCaps, true)
} }
// IsStrikethrough returns "true" if a text font of the subview is displayed strikethrough, "false" otherwise. // IsStrikethrough returns "true" if a text font of the subview is displayed strikethrough, "false" otherwise.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func IsStrikethrough(view View, subviewID ...string) bool { func IsStrikethrough(view View, subviewID ...string) bool {
return boolStyledProperty(view, subviewID, Strikethrough, true) return boolStyledProperty(view, subviewID, Strikethrough, true)
} }
// IsOverline returns "true" if a text font of the subview is displayed overlined, "false" otherwise. // IsOverline returns "true" if a text font of the subview is displayed overlined, "false" otherwise.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func IsOverline(view View, subviewID ...string) bool { func IsOverline(view View, subviewID ...string) bool {
return boolStyledProperty(view, subviewID, Overline, true) return boolStyledProperty(view, subviewID, Overline, true)
} }
// IsUnderline returns "true" if a text font of the subview is displayed underlined, "false" otherwise. // IsUnderline returns "true" if a text font of the subview is displayed underlined, "false" otherwise.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func IsUnderline(view View, subviewID ...string) bool { func IsUnderline(view View, subviewID ...string) bool {
return boolStyledProperty(view, subviewID, Underline, true) return boolStyledProperty(view, subviewID, Underline, true)
} }
// GetTextLineThickness returns the stroke thickness of the decoration line that // GetTextLineThickness returns the stroke thickness of the decoration line that
// is used on text in an element, such as a line-through, underline, or overline. // is used on text in an element, such as a line-through, underline, or overline.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTextLineThickness(view View, subviewID ...string) SizeUnit { func GetTextLineThickness(view View, subviewID ...string) SizeUnit {
return sizeStyledProperty(view, subviewID, TextLineThickness, true) return sizeStyledProperty(view, subviewID, TextLineThickness, true)
} }
// GetTextLineStyle returns the stroke style of the decoration line that // GetTextLineStyle returns the stroke style of the decoration line that
// is used on text in an element, such as a line-through, underline, or overline. // is used on text in an element, such as a line-through, underline, or overline.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTextLineStyle(view View, subviewID ...string) int { func GetTextLineStyle(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, TextLineStyle, SolidLine, true) return enumStyledProperty(view, subviewID, TextLineStyle, SolidLine, true)
} }
// GetTextLineColor returns the stroke color of the decoration line that // GetTextLineColor returns the stroke color of the decoration line that
// is used on text in an element, such as a line-through, underline, or overline. // is used on text in an element, such as a line-through, underline, or overline.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTextLineColor(view View, subviewID ...string) Color { func GetTextLineColor(view View, subviewID ...string) Color {
return colorStyledProperty(view, subviewID, TextLineColor, true) return colorStyledProperty(view, subviewID, TextLineColor, true)
} }
// GetTextTransform returns a text transform of the subview. Return one of next values: // GetTextTransform returns a text transform of the subview. Return one of next values:
// NoneTextTransform (0), CapitalizeTextTransform (1), LowerCaseTextTransform (2) or UpperCaseTextTransform (3) // NoneTextTransform (0), CapitalizeTextTransform (1), LowerCaseTextTransform (2) or UpperCaseTextTransform (3)
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTextTransform(view View, subviewID ...string) int { func GetTextTransform(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, TextTransform, NoneTextTransform, true) return enumStyledProperty(view, subviewID, TextTransform, NoneTextTransform, true)
} }
@ -500,14 +540,18 @@ func GetTextTransform(view View, subviewID ...string) int {
// GetWritingMode returns whether lines of text are laid out horizontally or vertically, as well as // GetWritingMode returns whether lines of text are laid out horizontally or vertically, as well as
// the direction in which blocks progress. Valid values are HorizontalTopToBottom (0), // the direction in which blocks progress. Valid values are HorizontalTopToBottom (0),
// HorizontalBottomToTop (1), VerticalRightToLeft (2) and VerticalLeftToRight (3) // HorizontalBottomToTop (1), VerticalRightToLeft (2) and VerticalLeftToRight (3)
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetWritingMode(view View, subviewID ...string) int { func GetWritingMode(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, WritingMode, HorizontalTopToBottom, true) return enumStyledProperty(view, subviewID, WritingMode, HorizontalTopToBottom, true)
} }
// GetTextDirection - returns a direction of text, table columns, and horizontal overflow. // GetTextDirection - returns a direction of text, table columns, and horizontal overflow.
// Valid values are SystemTextDirection (0), LeftToRightDirection (1), and RightToLeftDirection (2). // Valid values are SystemTextDirection (0), LeftToRightDirection (1), and RightToLeftDirection (2).
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTextDirection(view View, subviewID ...string) int { func GetTextDirection(view View, subviewID ...string) int {
if view == nil { if view == nil {
return SystemTextDirection return SystemTextDirection
@ -519,7 +563,9 @@ func GetTextDirection(view View, subviewID ...string) int {
// GetVerticalTextOrientation returns a orientation of the text characters in a line. It only affects text // GetVerticalTextOrientation returns a orientation of the text characters in a line. It only affects text
// in vertical mode (when "writing-mode" is "vertical-right-to-left" or "vertical-left-to-right"). // in vertical mode (when "writing-mode" is "vertical-right-to-left" or "vertical-left-to-right").
// Valid values are MixedTextOrientation (0), UprightTextOrientation (1), and SidewaysTextOrientation (2). // Valid values are MixedTextOrientation (0), UprightTextOrientation (1), and SidewaysTextOrientation (2).
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetVerticalTextOrientation(view View, subviewID ...string) int { func GetVerticalTextOrientation(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, VerticalTextOrientation, MixedTextOrientation, true) return enumStyledProperty(view, subviewID, VerticalTextOrientation, MixedTextOrientation, true)
} }
@ -761,7 +807,9 @@ func BlurViewByID(viewID string, session Session) {
} }
// GetCurrent returns the index of the selected item (<0 if there is no a selected item) or the current view index (StackLayout, TabsLayout). // GetCurrent returns the index of the selected item (<0 if there is no a selected item) or the current view index (StackLayout, TabsLayout).
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetCurrent(view View, subviewID ...string) int { func GetCurrent(view View, subviewID ...string) int {
defaultValue := -1 defaultValue := -1
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
@ -775,7 +823,9 @@ func GetCurrent(view View, subviewID ...string) int {
} }
// IsUserSelect returns "true" if the user can select text, "false" otherwise. // IsUserSelect returns "true" if the user can select text, "false" otherwise.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func IsUserSelect(view View, subviewID ...string) bool { func IsUserSelect(view View, subviewID ...string) bool {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
value, _ := isUserSelect(view) value, _ := isUserSelect(view)
@ -821,7 +871,8 @@ func isUserSelect(view View) (bool, bool) {
// BlendSoftLight (9), BlendDifference (10), BlendExclusion (11), BlendHue (12), // BlendSoftLight (9), BlendDifference (10), BlendExclusion (11), BlendHue (12),
// BlendSaturation (13), BlendColor (14), BlendLuminosity (15) // BlendSaturation (13), BlendColor (14), BlendLuminosity (15)
// //
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetMixBlendMode(view View, subviewID ...string) int { func GetMixBlendMode(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, MixBlendMode, BlendNormal, true) return enumStyledProperty(view, subviewID, MixBlendMode, BlendNormal, true)
} }
@ -833,13 +884,16 @@ func GetMixBlendMode(view View, subviewID ...string) int {
// BlendSoftLight (9), BlendDifference (10), BlendExclusion (11), BlendHue (12), // BlendSoftLight (9), BlendDifference (10), BlendExclusion (11), BlendHue (12),
// BlendSaturation (13), BlendColor (14), BlendLuminosity (15) // BlendSaturation (13), BlendColor (14), BlendLuminosity (15)
// //
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetBackgroundBlendMode(view View, subviewID ...string) int { func GetBackgroundBlendMode(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, BackgroundBlendMode, BlendNormal, true) return enumStyledProperty(view, subviewID, BackgroundBlendMode, BlendNormal, true)
} }
// GetTooltip returns a tooltip text of the subview. // GetTooltip returns a tooltip text of the subview.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is 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.
func GetTooltip(view View, subviewID ...string) string { func GetTooltip(view View, subviewID ...string) string {
if view = getSubview(view, subviewID); view != nil { if view = getSubview(view, subviewID); view != nil {
if value := view.Get(Tooltip); value != nil { if value := view.Get(Tooltip); value != nil {