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
view View
listener func(view View, animation AnimationProperty, event PropertyName)
oldListeners map[PropertyName][]func(View, PropertyName)
oldListeners map[PropertyName][]oneArgListener[View, PropertyName]
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.
// 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 {
return boolStyledProperty(view, subviewID, AnimationPaused, false)
}

View File

@ -156,45 +156,6 @@ const (
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) {
if propertyName, ok := data.PropertyValue("property"); ok {
property := PropertyName(propertyName)
@ -208,50 +169,11 @@ func (view *viewData) handleTransitionEvents(tag PropertyName, data DataObject)
}
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) {
if listeners := getOneArgEventListeners[View, string](view, nil, tag); len(listeners) > 0 {
id := ""
@ -263,63 +185,135 @@ func (view *viewData) handleAnimationEvents(tag PropertyName, data DataObject) {
}
}
for _, listener := range listeners {
listener(view, id)
listener.Run(view, id)
}
}
}
// GetTransitionRunListeners returns the "transition-run-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 GetTransitionRunListeners(view View, subviewID ...string) []func(View, string) {
return getOneArgEventListeners[View, string](view, subviewID, TransitionRunEvent)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, string](view, subviewID, TransitionStartEvent)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, string](view, subviewID, TransitionEndEvent)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, string](view, subviewID, TransitionCancelEvent)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, string](view, subviewID, AnimationStartEvent)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, string](view, subviewID, AnimationEndEvent)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, string](view, subviewID, AnimationCancelEvent)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, string](view, subviewID, AnimationIterationEvent)
//
// Result elements can be of the following types:
// - 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
import "slices"
func (animation *animationData) Start(view View, listener func(view View, animation AnimationProperty, event PropertyName)) bool {
if view == nil {
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.oldAnimation = nil
//if getOneArgEventListeners[View, PropertyName](view, nil, Animation)
if value := view.Get(Animation); value != nil {
if oldAnimation, ok := value.([]AnimationProperty); ok && len(oldAnimation) > 0 {
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)) {
var listeners []func(View, PropertyName) = nil
if value := view.Get(event); value != nil {
if oldListeners, ok := value.([]func(View, PropertyName)); ok && len(oldListeners) > 0 {
listeners = oldListeners
}
}
if listeners == nil {
view.Set(event, listener)
} else {
animation.oldListeners[event] = listeners
view.Set(event, append(listeners, listener))
listeners := getOneArgEventListeners[View, PropertyName](view, nil, event)
if len(listeners) > 0 {
animation.oldListeners[event] = slices.Clone(listeners)
}
view.Set(event, append(listeners, newOneArgListenerVE(listener)))
}
setListeners(AnimationStartEvent, animation.onAnimationStart)
@ -49,7 +45,7 @@ func (animation *animationData) Start(view View, listener func(view View, animat
func (animation *animationData) finish() {
if animation.view != nil {
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)
} else {
animation.view.Remove(event)
@ -63,7 +59,7 @@ func (animation *animationData) finish() {
animation.view.Set(Animation, "")
}
animation.oldListeners = map[PropertyName][]func(View, PropertyName){}
animation.oldListeners = map[PropertyName][]oneArgListener[View, PropertyName]{}
animation.view = nil
animation.listener = nil

View File

@ -268,14 +268,16 @@ func backgroundStyledPropery(view View, subviewID []string, tag PropertyName) []
// 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 {
return backgroundStyledPropery(view, subviewID, Background)
}
// 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 {
return backgroundStyledPropery(view, subviewID, Mask)
}
@ -284,7 +286,8 @@ func GetMask(view View, subviewID ...string) []BackgroundElement {
//
// 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 {
return enumStyledProperty(view, subviewID, BackgroundClip, 0, false)
}
@ -293,7 +296,8 @@ func GetBackgroundClip(view View, subviewID ...string) int {
//
// 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 {
return enumStyledProperty(view, subviewID, BackgroundOrigin, 0, false)
}
@ -302,7 +306,8 @@ func GetBackgroundOrigin(view View, subviewID ...string) int {
//
// 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 {
return enumStyledProperty(view, subviewID, MaskClip, 0, false)
}
@ -311,7 +316,8 @@ func GetMaskClip(view View, subviewID ...string) int {
//
// 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 {
return enumStyledProperty(view, subviewID, MaskOrigin, 0, false)
}

View File

@ -53,8 +53,8 @@ func (button *checkboxData) init(session Session) {
button.remove = button.removeFunc
button.changed = button.propertyChanged
button.setRaw(ClickEvent, []func(View, MouseEvent){checkboxClickListener})
button.setRaw(KeyDownEvent, []func(View, KeyEvent){checkboxKeyListener})
button.setRaw(ClickEvent, []oneArgListener[View, MouseEvent]{newOneArgListenerVE(checkboxClickListener)})
button.setRaw(KeyDownEvent, []oneArgListener[View, KeyEvent]{newOneArgListenerVE(checkboxKeyListener)})
}
func (button *checkboxData) Focusable() bool {
@ -67,9 +67,9 @@ func (button *checkboxData) propertyChanged(tag PropertyName) {
case Checked:
session := button.Session()
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 {
listener(button, checked)
listener.Run(button, checked)
}
}
@ -103,7 +103,7 @@ func (button *checkboxData) setFunc(tag PropertyName, value any) []PropertyName
switch tag {
case ClickEvent:
if listeners, ok := valueToOneArgEventListeners[View, MouseEvent](value); ok && listeners != nil {
listeners = append(listeners, checkboxClickListener)
listeners = append(listeners, newOneArgListenerVE(checkboxClickListener))
button.setRaw(tag, listeners)
return []PropertyName{tag}
}
@ -111,7 +111,7 @@ func (button *checkboxData) setFunc(tag PropertyName, value any) []PropertyName
case KeyDownEvent:
if listeners, ok := valueToOneArgEventListeners[View, KeyEvent](value); ok && listeners != nil {
listeners = append(listeners, checkboxKeyListener)
listeners = append(listeners, newOneArgListenerVE(checkboxKeyListener))
button.setRaw(tag, listeners)
return []PropertyName{tag}
}
@ -134,31 +134,17 @@ func (button *checkboxData) setFunc(tag PropertyName, value any) []PropertyName
func (button *checkboxData) removeFunc(tag PropertyName) []PropertyName {
switch tag {
case ClickEvent:
button.setRaw(ClickEvent, []func(View, MouseEvent){checkboxClickListener})
button.setRaw(ClickEvent, []oneArgListener[View, MouseEvent]{newOneArgListenerVE(checkboxClickListener)})
return []PropertyName{ClickEvent}
case KeyDownEvent:
button.setRaw(KeyDownEvent, []func(View, KeyEvent){checkboxKeyListener})
button.setRaw(KeyDownEvent, []oneArgListener[View, KeyEvent]{newOneArgListenerVE(checkboxKeyListener)})
return []PropertyName{ClickEvent}
}
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) {
view.Set(Checked, !IsCheckboxChecked(view))
BlurView(view)
@ -302,26 +288,41 @@ func checkboxVerticalAlignCSS(view View) string {
}
// 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 {
return boolStyledProperty(view, subviewID, Checked, false)
}
// 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 {
return enumStyledProperty(view, subviewID, CheckboxVerticalAlign, LeftAlign, false)
}
// 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 {
return enumStyledProperty(view, subviewID, CheckboxHorizontalAlign, TopAlign, false)
}
// GetCheckboxChangedListeners returns the CheckboxChangedListener list of an Checkbox subview.
// 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) {
return getOneArgEventListeners[Checkbox, bool](view, subviewID, CheckboxChangedEvent)
// If there are no listeners then the empty list is returned.
//
// Result elements can be of the following types:
// - 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.
// 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 {
if view = getSubview(view, subviewID); view != nil {
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.
// 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) {
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.
// 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 {
return enumStyledProperty(view, subviewID, ColumnFill, ColumnFillBalance, true)
}
// 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 {
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)
}
}
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.
// 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 {
if view = getSubview(view, subviewID); view != nil {
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,
// "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) {
if view = getSubview(view, subviewID); view != nil {
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,
// "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) {
if view = getSubview(view, subviewID); view != nil {
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.
// 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 {
return intStyledProperty(view, subviewID, DatePickerStep, 0)
}
// 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 {
if view = getSubview(view, subviewID); view == nil {
return time.Now()
@ -436,7 +444,9 @@ func GetDatePickerValue(view View, subviewID ...string) time.Time {
// GetDateChangedListeners returns the DateChangedListener list of an DatePicker subview.
// 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) {
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.
// 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 {
if view = getSubview(view, subviewID); view != 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.
// 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 {
return boolStyledProperty(view, subviewID, Expanded, false)
}
// 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 {
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)
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.
// 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) {
return getOneArgEventListeners[View, DragAndDropEvent](view, subviewID, DragStartEvent)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, DragAndDropEvent](view, subviewID, DragEndEvent)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, DragAndDropEvent](view, subviewID, DragEnterEvent)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, DragAndDropEvent](view, subviewID, DragLeaveEvent)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, DragAndDropEvent](view, subviewID, DragOverEvent)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, DragAndDropEvent](view, subviewID, DropEvent)
//
// Result elements can be of the following types:
// - 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 {
result := map[string]string{}
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.
// 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 {
if view = getSubview(view, subviewID); view != nil {
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.
// 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 {
return floatStyledProperty(view, subviewID, DragImageXOffset, 0)
}
// 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 {
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.
// - 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 {
if view = getSubview(view, subviewID); view != nil {
value := view.getRaw(DropEffect)
@ -573,7 +638,8 @@ func GetDropEffect(view View, subviewID ...string) int {
// - 6 (DropEffectLinkMove) - A link or move operation is 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 {
if view = getSubview(view, subviewID); view != nil {
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.
// 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) {
return getTwoArgEventListeners[DropDownList, int](view, subviewID, DropDownEvent)
}
// 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 {
if view = getSubview(view, subviewID); view != 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.
// 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 {
view = getSubview(view, subviewID)
return getIndicesArray(view, DisabledItems)
}
// 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 {
view = getSubview(view, subviewID)
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.
// 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 {
return boolStyledProperty(view, subviewID, Spellcheck, false)
}
// GetTextChangedListeners returns the TextChangedListener list of an EditView or MultiLineEditView subview.
// 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) {
return getTwoArgEventListeners[EditView, string](view, subviewID, EditTextChangedEvent)
}
// 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 {
return enumStyledProperty(view, subviewID, EditViewType, SingleLineText, false)
}
// 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 {
if view = getSubview(view, subviewID); view != nil {
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.
// 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 {
return boolStyledProperty(view, subviewID, EditWrap, false)
}
// 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) {
if subviewID != "" {
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.
// 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 {
return colorStyledProperty(view, subviewID, CaretColor, false)
}

442
events.go
View File

@ -1,6 +1,9 @@
package rui
import "strings"
import (
"reflect"
"strings"
)
var eventJsFunc = map[PropertyName]struct{ jsEvent, jsFunc string }{
FocusEvent: {jsEvent: "onfocus", jsFunc: "focusEvent"},
@ -38,12 +41,203 @@ var eventJsFunc = map[PropertyName]struct{ jsEvent, jsFunc string }{
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 {
return nil, true
}
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):
return []func(V){value}, true
@ -109,137 +303,153 @@ func valueToNoArgEventListeners[V any](value any) ([]func(V), bool) {
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 {
return nil, true
}
switch value := value.(type) {
case func(V, E):
return []func(V, E){value}, true
case string:
return []oneArgListener[V, E]{newOneArgListenerBinding[V, E](value)}, true
case func(E):
fn := func(_ V, event E) {
value(event)
}
return []func(V, E){fn}, true
case func(V, E):
return []oneArgListener[V, E]{newOneArgListenerVE[V, E](value)}, true
case func(V):
fn := func(view V, _ E) {
value(view)
}
return []func(V, E){fn}, true
return []oneArgListener[V, E]{newOneArgListenerV[V, E](value)}, true
case func(E):
return []oneArgListener[V, E]{newOneArgListenerE[V, E](value)}, true
case func():
fn := func(V, E) {
value()
}
return []func(V, E){fn}, true
return []oneArgListener[V, E]{newOneArgListener0[V, E](value)}, true
case []func(V, E):
if len(value) == 0 {
return nil, true
}
result := make([]oneArgListener[V, E], 0, len(value))
for _, fn := range value {
if fn == nil {
return nil, false
if fn != nil {
result = append(result, newOneArgListenerVE[V, E](fn))
}
}
return value, true
return result, len(result) > 0
case []func(E):
count := len(value)
if count == 0 {
return nil, true
}
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)
result := make([]oneArgListener[V, E], 0, len(value))
for _, fn := range value {
if fn != nil {
result = append(result, newOneArgListenerE[V, E](fn))
}
}
return listeners, true
return result, len(result) > 0
case []func(V):
count := len(value)
if count == 0 {
return nil, true
}
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)
result := make([]oneArgListener[V, E], 0, len(value))
for _, fn := range value {
if fn != nil {
result = append(result, newOneArgListenerV[V, E](fn))
}
}
return listeners, true
return result, len(result) > 0
case []func():
count := len(value)
if count == 0 {
return nil, true
}
listeners := make([]func(V, E), count)
for i, v := range value {
if v == nil {
return nil, false
}
listeners[i] = func(V, E) {
v()
result := make([]oneArgListener[V, E], 0, len(value))
for _, fn := range value {
if fn != nil {
result = append(result, newOneArgListener0[V, E](fn))
}
}
return listeners, true
return result, len(result) > 0
case []any:
count := len(value)
if count == 0 {
return nil, true
}
listeners := make([]func(V, E), count)
for i, v := range value {
if v == nil {
return nil, false
}
result := make([]oneArgListener[V, E], 0, len(value))
for _, v := range value {
if v != nil {
switch v := v.(type) {
case func(V, E):
listeners[i] = v
result = append(result, newOneArgListenerVE[V, E](v))
case func(E):
listeners[i] = func(_ V, event E) {
v(event)
}
result = append(result, newOneArgListenerE[V, E](v))
case func(V):
listeners[i] = func(view V, _ E) {
v(view)
}
result = append(result, newOneArgListenerV[V, E](v))
case func():
listeners[i] = func(V, E) {
v()
}
result = append(result, newOneArgListener0[V, E](v))
case string:
result = append(result, newOneArgListenerBinding[V, E](v))
default:
return nil, false
}
}
return listeners, true
}
return result, len(result) > 0
}
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 {
return nil, true
}
switch value := value.(type) {
case string:
fn := func(view V, val1 E, val2 E) {
bind := view.binding()
if bind == nil {
ErrorLogF(`There is no a binding object for call "%s"`, value)
return
}
val := reflect.ValueOf(bind)
method := val.MethodByName(value)
if !method.IsValid() {
ErrorLogF(`The "%s" method is not valid`, value)
return
}
methodType := method.Type()
var args []reflect.Value = nil
switch methodType.NumIn() {
case 0:
args = []reflect.Value{}
case 1:
inType := methodType.In(0)
if inType == reflect.TypeOf(view) {
args = []reflect.Value{reflect.ValueOf(view)}
} else if inType == reflect.TypeOf(val1) {
args = []reflect.Value{reflect.ValueOf(val1)}
}
case 2:
valType := reflect.TypeOf(val1)
if methodType.In(0) == reflect.TypeOf(view) && methodType.In(1) == valType {
args = []reflect.Value{reflect.ValueOf(view), reflect.ValueOf(val1)}
} else if methodType.In(0) == valType && methodType.In(1) == valType {
args = []reflect.Value{reflect.ValueOf(val1), reflect.ValueOf(val2)}
}
case 3:
valType := reflect.TypeOf(val1)
if methodType.In(0) == reflect.TypeOf(view) && methodType.In(1) == valType && methodType.In(2) == valType {
args = []reflect.Value{reflect.ValueOf(view), reflect.ValueOf(val1), reflect.ValueOf(val2)}
}
}
if args != nil {
method.Call(args)
} else {
ErrorLogF(`Unsupported prototype of "%s" method`, value)
}
}
return []func(V, E, E){fn}, true
case func(V, E, E):
return []func(V, E, E){value}, true
@ -424,17 +634,27 @@ func getNoArgEventListeners[V View](view View, subviewID []string, tag PropertyN
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 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 []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) {
if view = getSubview(view, subviewID); view != 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){}
}
func setNoArgEventListener[V View](properties Properties, tag PropertyName, value any) []PropertyName {
if listeners, ok := valueToNoArgEventListeners[V](value); ok {
func setNoArgEventListener[V View](view View, tag PropertyName, value any) []PropertyName {
if listeners, ok := valueToNoArgEventListeners[V](view, value); ok {
if len(listeners) > 0 {
properties.setRaw(tag, listeners)
} else if properties.getRaw(tag) != nil {
properties.setRaw(tag, nil)
view.setRaw(tag, listeners)
} else if view.getRaw(tag) != nil {
view.setRaw(tag, nil)
} else {
return []PropertyName{}
}
@ -461,12 +681,13 @@ func setNoArgEventListener[V View](properties Properties, tag PropertyName, valu
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 {
properties.setRaw(tag, listeners)
} else if properties.getRaw(tag) != nil {
properties.setRaw(tag, nil)
view.setRaw(tag, listeners)
} else if view.getRaw(tag) != nil {
view.setRaw(tag, nil)
} else {
return []PropertyName{}
}
@ -475,16 +696,18 @@ func setOneArgEventListener[V View, T any](properties Properties, tag PropertyNa
notCompatibleType(tag, value)
return nil
}
*/
func setTwoArgEventListener[V View, T any](properties Properties, tag PropertyName, value any) []PropertyName {
listeners, ok := valueToTwoArgEventListeners[V, T](value)
func setTwoArgEventListener[V View, T any](view View, tag PropertyName, value any) []PropertyName {
listeners, ok := valueToTwoArgEventListeners[V, T](view, value)
if !ok {
notCompatibleType(tag, value)
return nil
} else if len(listeners) > 0 {
properties.setRaw(tag, listeners)
} else if properties.getRaw(tag) != nil {
properties.setRaw(tag, nil)
}
if len(listeners) > 0 {
view.setRaw(tag, listeners)
} else if view.getRaw(tag) != nil {
view.setRaw(tag, nil)
} else {
return []PropertyName{}
}
@ -493,9 +716,17 @@ func setTwoArgEventListener[V View, T any](properties Properties, tag PropertyNa
func viewEventsHtml[T any](view View, events []PropertyName, buffer *strings.Builder) {
for _, tag := range events {
if value := view.getRaw(tag); value != nil {
if js, ok := eventJsFunc[tag]; ok {
if listeners, ok := value.([]func(View, T)); ok && len(listeners) > 0 {
if value := getOneArgEventListeners[View, T](view, nil, tag); len(value) > 0 {
buffer.WriteString(js.jsEvent)
buffer.WriteString(`="`)
buffer.WriteString(js.jsFunc)
buffer.WriteString(`(this, event)" `)
}
}
/*if value := view.getRaw(tag); value != nil {
if js, ok := eventJsFunc[tag]; ok {
if listeners, ok := value.([] func(View, T)); ok && len(listeners) > 0 {
buffer.WriteString(js.jsEvent)
buffer.WriteString(`="`)
buffer.WriteString(js.jsFunc)
@ -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":
if files := parseFilesTag(data); files != nil {
picker.files = files
for _, listener := range GetFileSelectedListeners(picker) {
listener(picker, files)
for _, listener := range getOneArgEventListeners[FilePicker, []FileInfo](picker, nil, FileSelectedEvent) {
listener.Run(picker, files)
}
}
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.
// 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 {
return boolStyledProperty(view, subviewID, Multiple, false)
}
// 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 {
if view = getSubview(view, subviewID); view != nil {
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.
// 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) {
return getOneArgEventListeners[FilePicker, []FileInfo](view, subviewID, FileSelectedEvent)
//
// Result elements can be of the following types:
// - 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
// 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) {
return getNoArgEventListeners[View](view, subviewID, FocusEvent)
}
// 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) {
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)
// 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 {
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)
// 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 {
return enumStyledProperty(view, subviewID, CellHorizontalAlign, StretchAlign, false)
}
// 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 {
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.
// 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 {
if view = getSubview(view, subviewID); view != nil {
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.
// 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 {
if view = getSubview(view, subviewID); view != nil {
return gridCellSizes(view, CellHeight, view.Session())
@ -544,13 +554,17 @@ func GetCellHeight(view View, subviewID ...string) []SizeUnit {
}
// 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 {
return sizeStyledProperty(view, subviewID, GridRowGap, false)
}
// 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 {
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) {
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)" `)
} 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)" `)
}
}
@ -454,7 +452,7 @@ func handleKeyEvents(view View, tag PropertyName, data DataObject) {
if len(listeners) > 0 {
for _, listener := range listeners {
listener(view, event)
listener.Run(view, event)
}
return
}
@ -477,20 +475,38 @@ func handleKeyEvents(view View, tag PropertyName, data DataObject) {
ScreenY: view.Frame().Top + view.Frame().Height/2,
}
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.
// 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) {
return getOneArgEventListeners[View, KeyEvent](view, subviewID, KeyDownEvent)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, KeyEvent](view, subviewID, KeyUpEvent)
//
// Result elements can be of the following types:
// - 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:
// 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 {
return enumStyledProperty(view, subviewID, VerticalAlign, TopAlign, false)
}
// GetListHorizontalAlign returns the vertical align of a ListLayout or ListView subview:
// 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 {
return enumStyledProperty(view, subviewID, HorizontalAlign, LeftAlign, false)
}
// GetListOrientation returns the orientation of a ListLayout or ListView subview:
// 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 {
if view = getSubview(view, subviewID); view != nil {
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:
// 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 {
return enumStyledProperty(view, subviewID, ListWrap, ListWrapOff, false)
}
// 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 {
return sizeStyledProperty(view, subviewID, ListRowGap, false)
}
// 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 {
return sizeStyledProperty(view, subviewID, ListColumnGap, false)
}

View File

@ -122,19 +122,13 @@ type ListView interface {
// ReloadListViewData updates ListView content
ReloadListViewData()
//getCheckedItems() []int
getItemFrames() []Frame
}
type listViewData struct {
viewData
//adapter ListAdapter
//clickedListeners []func(ListView, int)
//selectedListeners []func(ListView, int)
//checkedListeners []func(ListView, []int)
items []View
itemFrame []Frame
//checkedItem []int
}
// 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 {
current := GetCurrent(listView)
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 {
checked := GetListViewCheckedItems(listView)
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) {
listView.properties[Current] = number
for _, listener := range getOneArgEventListeners[ListView, int](listView, nil, ListItemSelectedEvent) {
listener(listView, number)
listener.Run(listView, number)
}
if listener, ok := listView.changeListener[Current]; ok {
listener(listView, Current)
@ -1032,12 +1026,12 @@ func (listView *listViewData) onItemClick(number int) {
}
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) {
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)
// 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 {
return enumStyledProperty(view, subviewID, VerticalAlign, TopAlign, false)
}
// 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 {
return enumStyledProperty(view, subviewID, HorizontalAlign, LeftAlign, false)
}
// GetListItemClickedListeners returns a ListItemClickedListener of the ListView.
// 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) {
return getOneArgEventListeners[ListView, int](view, subviewID, ListItemClickedEvent)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[ListView, int](view, subviewID, ListItemSelectedEvent)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[ListView, []int](view, subviewID, ListItemCheckedEvent)
//
// Result elements can be of the following types:
// - 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.
// 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 {
return sizeStyledProperty(view, subviewID, ItemWidth, false)
}
// 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 {
return sizeStyledProperty(view, subviewID, ItemHeight, false)
}
// 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 {
return enumStyledProperty(view, subviewID, ItemCheckbox, 0, false)
}
// 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 {
if view = getSubview(view, subviewID); view != 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:
// 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 {
return enumStyledProperty(view, subviewID, CheckboxVerticalAlign, TopAlign, false)
}
// GetListViewCheckboxHorizontalAlign returns the horizontal align of the ListView checkbox:
// 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 {
return enumStyledProperty(view, subviewID, CheckboxHorizontalAlign, LeftAlign, false)
}
// GetListItemVerticalAlign returns the vertical align of the ListView item content:
// 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 {
return enumStyledProperty(view, subviewID, ItemVerticalAlign, TopAlign, false)
}
// ItemHorizontalAlign returns the horizontal align of the ListView item 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 GetListItemHorizontalAlign(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, ItemHorizontalAlign, LeftAlign, false)
}
// 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 {
if subviewID != "" {
view = ViewByID(view, subviewID)
@ -1182,7 +1225,9 @@ func GetListItemFrame(view View, subviewID string, index int) Frame {
}
// 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 {
if view = getSubview(view, subviewID); view != 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)
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.
// 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) {
return getOneArgEventListeners[View, MouseEvent](view, subviewID, ClickEvent)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, MouseEvent](view, subviewID, DoubleClickEvent)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, MouseEvent](view, subviewID, ContextMenuEvent)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, MouseEvent](view, subviewID, MouseDown)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, MouseEvent](view, subviewID, MouseUp)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, MouseEvent](view, subviewID, MouseMove)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, MouseEvent](view, subviewID, MouseOver)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, MouseEvent](view, subviewID, MouseOut)
//
// Result elements can be of the following types:
// - 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:
// NumberEditor (0) - NumberPicker is presented by editor (default type);
// 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 {
return enumStyledProperty(view, subviewID, NumberPickerType, NumberEditor, false)
}
// 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) {
view = getSubview(view, subviewID)
pickerType := GetNumberPickerType(view)
@ -328,7 +332,9 @@ func GetNumberPickerMinMax(view View, subviewID ...string) (float64, float64) {
}
// 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 {
view = getSubview(view, subviewID)
_, max := GetNumberPickerMinMax(view)
@ -341,7 +347,9 @@ func GetNumberPickerStep(view View, subviewID ...string) float64 {
}
// 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 {
view = getSubview(view, subviewID)
min, _ := GetNumberPickerMinMax(view)
@ -350,13 +358,17 @@ func GetNumberPickerValue(view View, subviewID ...string) float64 {
// GetNumberChangedListeners returns the NumberChangedListener list of an NumberPicker subview.
// 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) {
return getTwoArgEventListeners[NumberPicker, float64](view, subviewID, NumberChangedEvent)
}
// 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 {
return intStyledProperty(view, subviewID, NumberPickerPrecision, 0)
}

View File

@ -192,42 +192,96 @@ func handlePointerEvents(view View, tag PropertyName, data DataObject) {
event.init(data)
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.
// 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) {
return getOneArgEventListeners[View, PointerEvent](view, subviewID, PointerDown)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, PointerEvent](view, subviewID, PointerUp)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, PointerEvent](view, subviewID, PointerMove)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, PointerEvent](view, subviewID, PointerCancel)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, PointerEvent](view, subviewID, PointerOver)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, PointerEvent](view, subviewID, PointerOut)
//
// Result elements can be of the following types:
// - 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:
if listeners, ok := valueToNoArgEventListeners[Popup](value); ok {
if listeners, ok := valueToNoArgEventListeners[Popup](popup.contentView, value); ok {
if listeners != nil {
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.
// 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 {
return floatStyledProperty(view, subviewID, ProgressBarMax, 1)
}
// 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 {
return floatStyledProperty(view, subviewID, ProgressBarValue, 0)
}

View File

@ -2723,4 +2723,6 @@ const (
//
// Supported types: string.
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.Width = width
view.frame.Height = height
for _, listener := range GetResizeListeners(view) {
listener(self, view.frame)
for _, listener := range getOneArgEventListeners[View, Frame](view, nil, ResizeEvent) {
listener.Run(self, view.frame)
}
}
@ -73,7 +73,9 @@ func (view *viewData) Frame() Frame {
}
// 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 {
view = getSubview(view, subviewID)
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
// 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) {
return getOneArgEventListeners[View, Frame](view, subviewID, ResizeEvent)
//
// Result elements can be of the following types:
// - 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.Width = width
view.scroll.Height = height
for _, listener := range GetScrollListeners(view) {
listener(self, view.scroll)
for _, listener := range getOneArgEventListeners[View, Frame](view, nil, ScrollEvent) {
listener.Run(self, view.scroll)
}
}
@ -42,7 +42,9 @@ func (view *viewData) setScroll(x, y, width, height float64) {
}
// 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 {
view = getSubview(view, subviewID)
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
// 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) {
return getOneArgEventListeners[View, Frame](view, subviewID, ResizeEvent)
//
// Result elements can be of the following types:
// - 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.
// 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) {
if 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.
// 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) {
if view = getSubview(view, subviewID); view != nil {
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.
// 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) {
if view = getSubview(view, subviewID); view != nil {
view.Session().callFunc("scrollToEnd", view.htmlID())

View File

@ -334,7 +334,9 @@ func (layout *stackLayoutData) init(session Session) {
layout.remove = layout.removeFunc
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 {
layout.setRaw(PushTransform, NewTransformProperty(Params{TranslateX: Percent(-100)}))
} else {
@ -434,7 +436,7 @@ func (layout *stackLayoutData) setFunc(tag PropertyName, value any) []PropertyNa
// TODO
listeners, ok := valueToOneArgEventListeners[View, PropertyName](value)
if ok && listeners != nil {
listeners = append(listeners, layout.transitionFinished)
listeners = append(listeners, newOneArgListenerVE(layout.transitionFinished))
layout.setRaw(TransitionEndEvent, listeners)
return []PropertyName{tag}
}
@ -464,7 +466,9 @@ func (layout *stackLayoutData) propertyChanged(tag PropertyName) {
func (layout *stackLayoutData) removeFunc(tag PropertyName) []PropertyName {
switch tag {
case TransitionEndEvent:
layout.setRaw(TransitionEndEvent, []func(View, PropertyName){layout.transitionFinished})
layout.setRaw(TransitionEndEvent, []oneArgListener[View, PropertyName]{
newOneArgListenerVE(layout.transitionFinished),
})
return []PropertyName{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.
// 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 {
if view = getSubview(view, subviewID); view != nil {
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)
// for an animated pushing of a child view.
// 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 {
return transformStyledProperty(view, subviewID, PushTransform)
}

View File

@ -592,14 +592,6 @@ func (table *tableViewData) init(session Session) {
table.tag = "TableView"
table.cellViews = []View{}
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.set = table.setFunc
table.changed = table.propertyChanged
@ -955,63 +947,6 @@ func tableViewCurrentInactiveStyle(view View) string {
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 {
return "table"
}
@ -1735,8 +1670,8 @@ func (table *tableViewData) handleCommand(self View, command PropertyName, data
listener(table, Current)
}
for _, listener := range GetTableRowSelectedListeners(table) {
listener(table, row)
for _, listener := range getOneArgEventListeners[TableView, int](table, nil, TableRowSelectedEvent) {
listener.Run(table, row)
}
}
@ -1761,8 +1696,8 @@ func (table *tableViewData) handleCommand(self View, command PropertyName, data
case "rowClick":
if row, ok := dataIntProperty(data, "row"); ok {
for _, listener := range GetTableRowClickedListeners(table) {
listener(table, row)
for _, listener := range getOneArgEventListeners[TableView, int](table, nil, TableRowClickedEvent) {
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.
// 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 {
if view = getSubview(view, subviewID); view != 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.
// 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 {
if view = getSubview(view, subviewID); view != nil {
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.
// 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 {
if view = getSubview(view, subviewID); view != nil {
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.
// 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 {
if view = getSubview(view, subviewID); view != nil {
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.
// 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 {
return enumStyledProperty(view, subviewID, SelectionMode, NoneSelection, false)
}
// GetTableVerticalAlign returns a vertical align in a TableView cell. Returns one of next values:
// 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 {
return enumStyledProperty(view, subviewID, TableVerticalAlign, TopAlign, false)
}
// 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 {
return intStyledProperty(view, subviewID, HeadHeight, 0)
}
// 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 {
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),
// 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 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 {
if view = getSubview(view, subviewID); view != nil {
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.
// 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) {
return getTwoArgEventListeners[TableView, int](view, subviewID, TableCellClickedEvent)
}
// 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 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) {
return getTwoArgEventListeners[TableView, int](view, subviewID, TableCellSelectedEvent)
}
// 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 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) {
return getOneArgEventListeners[TableView, int](view, subviewID, TableRowClickedEvent)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[TableView, int](view, subviewID, TableRowSelectedEvent)
//
// Result elements can be of the following types:
// - 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

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 {
tabs, _ := enumProperty(tabsLayout, Tabs, tabsLayout.session, 0)
return tabs
@ -504,7 +355,7 @@ func (tabsLayout *tabsLayoutData) ListItem(index int, session Session) View {
Content: "✕",
ClickEvent: func() {
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 number, err := strconv.Atoi(numberText); err == nil {
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)
}
// 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:
// 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 {
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,
// "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) {
if view = getSubview(view, subviewID); view != nil {
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,
// "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) {
if view = getSubview(view, subviewID); view != nil {
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.
// 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 {
return intStyledProperty(view, subviewID, TimePickerStep, 60)
}
// 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 {
if view = getSubview(view, subviewID); view == nil {
return time.Now()
@ -409,7 +417,9 @@ func GetTimePickerValue(view View, subviewID ...string) time.Time {
// GetTimeChangedListeners returns the TimeChangedListener list of an TimePicker subview.
// 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) {
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)
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.
// 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) {
return getOneArgEventListeners[View, TouchEvent](view, subviewID, TouchStart)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, TouchEvent](view, subviewID, TouchEnd)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, TouchEvent](view, subviewID, TouchMove)
//
// Result elements can be of the following types:
// - 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.
// 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) {
return getOneArgEventListeners[View, TouchEvent](view, subviewID, TouchCancel)
//
// Result elements can be of the following types:
// - 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.
// 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 {
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
// 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).
// 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 {
return sizeStyledProperty(view, subviewID, Perspective, false)
}
// 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%).
// 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) {
view = getSubview(view, subviewID)
if view == nil {
@ -675,14 +681,18 @@ func GetPerspectiveOrigin(view View, subviewID ...string) (SizeUnit, SizeUnit) {
// visible when turned towards the user. Values:
// 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.
// 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 {
return boolStyledProperty(view, subviewID, BackfaceVisible, false)
}
// 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%).
// 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) {
view = getSubview(view, subviewID)
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
// 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) {
if transform := GetTransform(view, subviewID...); transform != nil {
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)
// 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) {
if transform := GetTransform(view, subviewID...); transform != nil {
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.
// 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) {
if transform := GetTransform(view, subviewID...); transform != nil {
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
// 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) {
if transform := GetTransform(view, subviewID...); transform != nil {
session := view.Session()

42
view.go
View File

@ -92,6 +92,7 @@ type View interface {
addToCSSStyle(addCSS map[string]string)
exscludeTags() []PropertyName
htmlDisabledProperty() bool
binding() any
onResize(self View, 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
}
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 {
if id == view.ID() {
if v := view.session.viewByHTMLID(view.htmlID()); v != nil {
@ -304,6 +317,14 @@ func (view *viewData) removeFunc(tag PropertyName) []PropertyName {
changedTags = []PropertyName{}
}
case Binding:
if view.getRaw(Binding) != nil {
view.setRaw(Binding, nil)
changedTags = []PropertyName{Binding}
} else {
changedTags = []PropertyName{}
}
case Animation:
if val := view.getRaw(Animation); val != nil {
if animations, ok := val.([]AnimationProperty); ok {
@ -336,6 +357,10 @@ func (view *viewData) setFunc(tag PropertyName, value any) []PropertyName {
notCompatibleType(ID, value)
return nil
case Binding:
view.setRaw(Binding, value)
return []PropertyName{Binding}
case Animation:
oldAnimations := []AnimationProperty{}
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:
result := setOneArgEventListener[View, PropertyName](view, tag, value)
if result == nil {
result = setOneArgEventListener[View, string](view, tag, value)
if result != nil {
if listeners, ok := view.getRaw(tag).([]func(View, string)); ok {
newListeners := make([]func(View, PropertyName), len(listeners))
if listeners, ok := valueToOneArgEventListeners[View, string](view); ok && len(listeners) > 0 {
newListeners := make([]oneArgListener[View, PropertyName], len(listeners))
for i, listener := range listeners {
newListeners[i] = func(view View, name PropertyName) {
listener(view, string(name))
}
newListeners[i] = newOneArgListenerVE(func(view View, name PropertyName) {
listener.Run(view, string(name))
})
}
view.setRaw(tag, newListeners)
return result
}
view.setRaw(tag, nil)
return nil
result = []PropertyName{tag}
}
}
return result

View File

@ -355,31 +355,41 @@ func GetTextShadows(view View, subviewID ...string) []ShadowProperty {
}
// 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 {
return colorStyledProperty(view, subviewID, BackgroundColor, false)
}
// 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 {
return colorStyledProperty(view, subviewID, AccentColor, false)
}
// 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 {
return stringStyledProperty(view, nil, FontName, true)
}
// 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 {
return colorStyledProperty(view, subviewID, TextColor, true)
}
// 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 {
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:
// 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 {
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
//
// 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 {
return enumStyledProperty(view, subviewID, TextAlign, LeftAlign, true)
}
@ -410,89 +423,116 @@ func GetTextAlign(view View, subviewID ...string) int {
//
// 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 {
return enumStyledProperty(view, subviewID, TextWrap, TextWrapOn, true)
}
// 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 {
return sizeStyledProperty(view, subviewID, TextIndent, true)
}
// 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 {
return sizeStyledProperty(view, subviewID, LetterSpacing, true)
}
// 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 {
return sizeStyledProperty(view, subviewID, WordSpacing, true)
}
// 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 {
return sizeStyledProperty(view, subviewID, LineHeight, true)
}
// 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 {
return boolStyledProperty(view, subviewID, Italic, true)
}
// 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 {
return boolStyledProperty(view, subviewID, SmallCaps, true)
}
// 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 {
return boolStyledProperty(view, subviewID, Strikethrough, true)
}
// 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 {
return boolStyledProperty(view, subviewID, Overline, true)
}
// 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 {
return boolStyledProperty(view, subviewID, Underline, true)
}
// 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.
// 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 {
return sizeStyledProperty(view, subviewID, TextLineThickness, true)
}
// 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.
// 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 {
return enumStyledProperty(view, subviewID, TextLineStyle, SolidLine, true)
}
// 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.
// 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 {
return colorStyledProperty(view, subviewID, TextLineColor, true)
}
// GetTextTransform returns a text transform of the subview. Return one of next values:
// 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 {
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
// the direction in which blocks progress. Valid values are HorizontalTopToBottom (0),
// 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 {
return enumStyledProperty(view, subviewID, WritingMode, HorizontalTopToBottom, true)
}
// GetTextDirection - returns a direction of text, table columns, and horizontal overflow.
// 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 {
if view == nil {
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
// 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).
// 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 {
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).
// 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 {
defaultValue := -1
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.
// 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 {
if view = getSubview(view, subviewID); view != nil {
value, _ := isUserSelect(view)
@ -821,7 +871,8 @@ func isUserSelect(view View) (bool, bool) {
// BlendSoftLight (9), BlendDifference (10), BlendExclusion (11), BlendHue (12),
// 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 {
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),
// 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 {
return enumStyledProperty(view, subviewID, BackgroundBlendMode, BlendNormal, true)
}
// 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 {
if view = getSubview(view, subviewID); view != nil {
if value := view.Get(Tooltip); value != nil {