rui_orig/focusEvents.go

165 lines
3.8 KiB
Go
Raw Permalink Normal View History

2021-09-07 17:36:50 +03:00
package rui
import "strings"
const (
2021-11-04 21:13:34 +03:00
// FocusEvent is the constant for "focus-event" property tag.
2021-09-07 17:36:50 +03:00
// The "focus-event" event occurs when the View takes input focus.
2021-11-04 21:13:34 +03:00
// The main listener format:
// func(View).
// The additional listener format:
// func().
2021-09-07 17:36:50 +03:00
FocusEvent = "focus-event"
2021-11-04 21:13:34 +03:00
// LostFocusEvent is the constant for "lost-focus-event" property tag.
2021-09-07 17:36:50 +03:00
// The "lost-focus-event" event occurs when the View lost input focus.
2021-11-04 21:13:34 +03:00
// The main listener format:
// func(View).
// The additional listener format:
// func().
2021-09-07 17:36:50 +03:00
LostFocusEvent = "lost-focus-event"
)
2022-07-31 15:37:26 +03:00
func valueToNoParamListeners[V any](value any) ([]func(V), bool) {
2021-09-07 17:36:50 +03:00
if value == nil {
return nil, true
}
switch value := value.(type) {
2022-07-27 20:31:57 +03:00
case func(V):
return []func(V){value}, true
2021-09-07 17:36:50 +03:00
case func():
2022-07-27 20:31:57 +03:00
fn := func(V) {
2021-09-07 17:36:50 +03:00
value()
}
2022-07-27 20:31:57 +03:00
return []func(V){fn}, true
2021-09-07 17:36:50 +03:00
2022-07-27 20:31:57 +03:00
case []func(V):
2021-09-07 17:36:50 +03:00
if len(value) == 0 {
return nil, true
}
for _, fn := range value {
if fn == nil {
return nil, false
}
}
return value, true
case []func():
count := len(value)
if count == 0 {
return nil, true
}
2022-07-27 20:31:57 +03:00
listeners := make([]func(V), count)
2021-09-07 17:36:50 +03:00
for i, v := range value {
if v == nil {
return nil, false
}
2022-07-27 20:31:57 +03:00
listeners[i] = func(V) {
2021-09-07 17:36:50 +03:00
v()
}
}
return listeners, true
2022-07-26 18:36:00 +03:00
case []any:
2021-09-07 17:36:50 +03:00
count := len(value)
if count == 0 {
return nil, true
}
2022-07-27 20:31:57 +03:00
listeners := make([]func(V), count)
2021-09-07 17:36:50 +03:00
for i, v := range value {
if v == nil {
return nil, false
}
switch v := v.(type) {
2022-07-27 20:31:57 +03:00
case func(V):
2021-09-07 17:36:50 +03:00
listeners[i] = v
case func():
2022-07-27 20:31:57 +03:00
listeners[i] = func(V) {
2021-09-07 17:36:50 +03:00
v()
}
default:
return nil, false
}
}
return listeners, true
}
return nil, false
}
var focusEvents = map[string]struct{ jsEvent, jsFunc string }{
FocusEvent: {jsEvent: "onfocus", jsFunc: "focusEvent"},
LostFocusEvent: {jsEvent: "onblur", jsFunc: "blurEvent"},
}
2022-07-26 18:36:00 +03:00
func (view *viewData) setFocusListener(tag string, value any) bool {
2022-07-27 20:31:57 +03:00
listeners, ok := valueToNoParamListeners[View](value)
2021-09-07 17:36:50 +03:00
if !ok {
notCompatibleType(tag, value)
return false
}
if listeners == nil {
view.removeFocusListener(tag)
} else if js, ok := focusEvents[tag]; ok {
view.properties[tag] = listeners
if view.created {
2022-10-30 17:22:33 +03:00
view.session.updateProperty(view.htmlID(), js.jsEvent, js.jsFunc+"(this, event)")
2021-09-07 17:36:50 +03:00
}
} else {
return false
}
return true
}
func (view *viewData) removeFocusListener(tag string) {
delete(view.properties, tag)
if view.created {
if js, ok := focusEvents[tag]; ok {
2022-10-30 17:22:33 +03:00
view.session.removeProperty(view.htmlID(), js.jsEvent)
2021-09-07 17:36:50 +03:00
}
}
}
func getFocusListeners(view View, subviewID []string, tag string) []func(View) {
if len(subviewID) > 0 && subviewID[0] != "" {
view = ViewByID(view, subviewID[0])
2021-09-07 17:36:50 +03:00
}
2021-09-07 17:36:50 +03:00
if view != nil {
if value := view.Get(tag); value != nil {
if result, ok := value.([]func(View)); ok {
return result
}
}
}
return []func(View){}
}
func focusEventsHtml(view View, buffer *strings.Builder) {
if view.Focusable() {
for _, js := range focusEvents {
2023-05-02 17:20:01 +03:00
buffer.WriteString(js.jsEvent)
buffer.WriteString(`="`)
buffer.WriteString(js.jsFunc)
buffer.WriteString(`(this, event)" `)
2021-09-07 17:36:50 +03:00
}
}
}
// 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.
func GetFocusListeners(view View, subviewID ...string) []func(View) {
2021-09-07 17:36:50 +03:00
return getFocusListeners(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.
func GetLostFocusListeners(view View, subviewID ...string) []func(View) {
2021-09-07 17:36:50 +03:00
return getFocusListeners(view, subviewID, LostFocusEvent)
}