mirror of https://github.com/anoshenko/rui.git
Changed the main DropDownList and EditView listener
This commit is contained in:
parent
eac3379fb1
commit
2a480cc6ac
28
README-ru.md
28
README-ru.md
|
@ -3107,13 +3107,21 @@ string свойство "edit-view-pattern" (константа EditViewPattern)
|
|||
Для отслеживания изменения текста используется событие "edit-text-changed" (константа
|
||||
EditTextChangedEvent). Основной слушатель события имеет следующий формат:
|
||||
|
||||
func(EditView, string)
|
||||
func(EditView, string, string)
|
||||
|
||||
где второй аргумент это новое значение текста
|
||||
где второй аргумент это новое значение текста, третий аргумент - предыдущее значение текста.
|
||||
|
||||
Дополнительные слушатели события могут иметь следующий формат
|
||||
|
||||
func(EditView, newText string)
|
||||
func(newText, oldText string)
|
||||
func(newText string)
|
||||
func(EditView)
|
||||
func()
|
||||
|
||||
Получить текущий список слушателей изменения текста можно с помощью функции
|
||||
|
||||
func GetTextChangedListeners(view View, subviewID ...string) []func(EditView, string)
|
||||
func GetTextChangedListeners(view View, subviewID ...string) []func(EditView, string, string)
|
||||
|
||||
## NumberPicker
|
||||
|
||||
|
@ -3425,13 +3433,21 @@ float32, float64, int, int8…int64, uint, uint8…uint64.
|
|||
Для отслеживания изменения свойства "current" используется событие "drop-down-event" (константа
|
||||
DropDownEvent). Основной слушатель события имеет следующий формат:
|
||||
|
||||
func(list DropDownList, newCurrent int)
|
||||
func(list DropDownList, newCurrent, oldCurrent int)
|
||||
|
||||
где второй аргумент это индекс выбранного элемента
|
||||
где второй аргумент это индекс выбранного элемента, третий аргумент - предыдущее значение индекса.
|
||||
|
||||
Дополнительные слушатели события могут иметь следующий формат
|
||||
|
||||
func(list DropDownList, newCurrent int)
|
||||
func(newCurrent, oldCurrent int)
|
||||
func(newCurrent int)
|
||||
func(list DropDownList)
|
||||
func()
|
||||
|
||||
Получить текущий список слушателей изменения даты можно с помощью функции
|
||||
|
||||
func GetDropDownListeners(view View, subviewID ...string) []func(DropDownList, int)
|
||||
func GetDropDownListeners(view View, subviewID ...string) []func(DropDownList, int, int)
|
||||
|
||||
## ProgressBar
|
||||
|
||||
|
|
26
README.md
26
README.md
|
@ -3071,13 +3071,21 @@ The following functions can be used to get the values of the properties of an Ed
|
|||
The "edit-text-changed" event (EditTextChangedEvent constant) is used to track changes to the text.
|
||||
The main event listener has the following format:
|
||||
|
||||
func(EditView, string)
|
||||
func(EditView, string, string)
|
||||
|
||||
where the second argument is the new text value
|
||||
where the second argument is the new text value the third argument is the previous text value.
|
||||
|
||||
Additional event listeners can have the following format
|
||||
|
||||
func(EditView, newText string)
|
||||
func(newText, oldText string)
|
||||
func(newText string)
|
||||
func(EditView)
|
||||
func()
|
||||
|
||||
You can get the current list of text change listeners using the function
|
||||
|
||||
func GetTextChangedListeners(view View, subviewID ...string) []func(EditView, string)
|
||||
func GetTextChangedListeners(view View, subviewID ...string) []func(EditView, string, string)
|
||||
|
||||
## NumberPicker
|
||||
|
||||
|
@ -3393,11 +3401,19 @@ The main event listener has the following format:
|
|||
|
||||
func(list DropDownList, newCurrent int)
|
||||
|
||||
where the second argument is the index of the selected item
|
||||
where the second argument is the index of the selected item, the third argument is the previous index value.
|
||||
|
||||
Additional event listeners can have the following format
|
||||
|
||||
func(list DropDownList, newCurrent int)
|
||||
func(newCurrent, oldCurrent int)
|
||||
func(newCurrent int)
|
||||
func(list DropDownList)
|
||||
func()
|
||||
|
||||
You can get the current list of date change listeners using the function
|
||||
|
||||
func GetDropDownListeners(view View, subviewID ...string) []func(DropDownList, int)
|
||||
func GetDropDownListeners(view View, subviewID ...string) []func(DropDownList, int, int)
|
||||
|
||||
## ProgressBar
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ type dropDownListData struct {
|
|||
viewData
|
||||
items []string
|
||||
disabledItems []any
|
||||
dropDownListener []func(DropDownList, int)
|
||||
dropDownListener []func(DropDownList, int, int)
|
||||
}
|
||||
|
||||
// NewDropDownList create new DropDownList object and return it
|
||||
|
@ -41,7 +41,7 @@ func (list *dropDownListData) init(session Session) {
|
|||
list.tag = "DropDownList"
|
||||
list.items = []string{}
|
||||
list.disabledItems = []any{}
|
||||
list.dropDownListener = []func(DropDownList, int){}
|
||||
list.dropDownListener = []func(DropDownList, int, int){}
|
||||
}
|
||||
|
||||
func (list *dropDownListData) String() string {
|
||||
|
@ -78,7 +78,7 @@ func (list *dropDownListData) remove(tag string) {
|
|||
|
||||
case DropDownEvent:
|
||||
if len(list.dropDownListener) > 0 {
|
||||
list.dropDownListener = []func(DropDownList, int){}
|
||||
list.dropDownListener = []func(DropDownList, int, int){}
|
||||
list.propertyChangedEvent(tag)
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ func (list *dropDownListData) remove(tag string) {
|
|||
if list.created {
|
||||
list.session.callFunc("selectDropDownListItem", list.htmlID(), 0)
|
||||
}
|
||||
list.onSelectedItemChanged(0)
|
||||
list.onSelectedItemChanged(0, oldCurrent)
|
||||
}
|
||||
|
||||
default:
|
||||
|
@ -116,12 +116,12 @@ func (list *dropDownListData) set(tag string, value any) bool {
|
|||
return list.setDisabledItems(value)
|
||||
|
||||
case DropDownEvent:
|
||||
listeners, ok := valueToEventListeners[DropDownList, int](value)
|
||||
listeners, ok := valueToEventWithOldListeners[DropDownList, int](value)
|
||||
if !ok {
|
||||
notCompatibleType(tag, value)
|
||||
return false
|
||||
} else if listeners == nil {
|
||||
listeners = []func(DropDownList, int){}
|
||||
listeners = []func(DropDownList, int, int){}
|
||||
}
|
||||
list.dropDownListener = listeners
|
||||
list.propertyChangedEvent(tag)
|
||||
|
@ -137,7 +137,7 @@ func (list *dropDownListData) set(tag string, value any) bool {
|
|||
if list.created {
|
||||
list.session.callFunc("selectDropDownListItem", list.htmlID(), current)
|
||||
}
|
||||
list.onSelectedItemChanged(current)
|
||||
list.onSelectedItemChanged(current, oldCurrent)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -377,9 +377,9 @@ func (list *dropDownListData) htmlDisabledProperties(self View, buffer *strings.
|
|||
}
|
||||
}
|
||||
|
||||
func (list *dropDownListData) onSelectedItemChanged(number int) {
|
||||
func (list *dropDownListData) onSelectedItemChanged(number, old int) {
|
||||
for _, listener := range list.dropDownListener {
|
||||
listener(list, number)
|
||||
listener(list, number, old)
|
||||
}
|
||||
list.propertyChangedEvent(Current)
|
||||
}
|
||||
|
@ -390,8 +390,9 @@ func (list *dropDownListData) handleCommand(self View, command string, data Data
|
|||
if text, ok := data.PropertyValue("number"); ok {
|
||||
if number, err := strconv.Atoi(text); err == nil {
|
||||
if GetCurrent(list) != number && number >= 0 && number < len(list.items) {
|
||||
old := GetCurrent(list)
|
||||
list.properties[Current] = number
|
||||
list.onSelectedItemChanged(number)
|
||||
list.onSelectedItemChanged(number, old)
|
||||
}
|
||||
} else {
|
||||
ErrorLog(err.Error())
|
||||
|
@ -406,8 +407,8 @@ func (list *dropDownListData) handleCommand(self View, command string, data Data
|
|||
|
||||
// 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.
|
||||
func GetDropDownListeners(view View, subviewID ...string) []func(DropDownList, int) {
|
||||
return getEventListeners[DropDownList, int](view, subviewID, DropDownEvent)
|
||||
func GetDropDownListeners(view View, subviewID ...string) []func(DropDownList, int, int) {
|
||||
return getEventWithOldListeners[DropDownList, int](view, subviewID, DropDownEvent)
|
||||
}
|
||||
|
||||
// GetDropDownItems return the DropDownList items list.
|
||||
|
|
27
editView.go
27
editView.go
|
@ -41,7 +41,7 @@ type EditView interface {
|
|||
|
||||
type editViewData struct {
|
||||
viewData
|
||||
textChangeListeners []func(EditView, string)
|
||||
textChangeListeners []func(EditView, string, string)
|
||||
}
|
||||
|
||||
// NewEditView create new EditView object and return it
|
||||
|
@ -58,7 +58,7 @@ func newEditView(session Session) View {
|
|||
|
||||
func (edit *editViewData) init(session Session) {
|
||||
edit.viewData.init(session)
|
||||
edit.textChangeListeners = []func(EditView, string){}
|
||||
edit.textChangeListeners = []func(EditView, string, string){}
|
||||
edit.tag = "EditView"
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,7 @@ func (edit *editViewData) remove(tag string) {
|
|||
|
||||
case EditTextChangedEvent:
|
||||
if len(edit.textChangeListeners) > 0 {
|
||||
edit.textChangeListeners = []func(EditView, string){}
|
||||
edit.textChangeListeners = []func(EditView, string, string){}
|
||||
edit.propertyChangedEvent(tag)
|
||||
}
|
||||
|
||||
|
@ -134,7 +134,7 @@ func (edit *editViewData) remove(tag string) {
|
|||
oldText := GetText(edit)
|
||||
delete(edit.properties, tag)
|
||||
if oldText != "" {
|
||||
edit.textChanged("")
|
||||
edit.textChanged("", oldText)
|
||||
if edit.created {
|
||||
edit.session.callFunc("setInputValue", edit.htmlID(), "")
|
||||
}
|
||||
|
@ -205,7 +205,7 @@ func (edit *editViewData) set(tag string, value any) bool {
|
|||
if text, ok := value.(string); ok {
|
||||
edit.properties[Text] = text
|
||||
if text = GetText(edit); oldText != text {
|
||||
edit.textChanged(text)
|
||||
edit.textChanged(text, oldText)
|
||||
if edit.created {
|
||||
if GetEditViewType(edit) == MultiLineText {
|
||||
updateInnerHTML(edit.htmlID(), edit.Session())
|
||||
|
@ -328,12 +328,12 @@ func (edit *editViewData) set(tag string, value any) bool {
|
|||
return false
|
||||
|
||||
case EditTextChangedEvent:
|
||||
listeners, ok := valueToEventListeners[EditView, string](value)
|
||||
listeners, ok := valueToEventWithOldListeners[EditView, string](value)
|
||||
if !ok {
|
||||
notCompatibleType(tag, value)
|
||||
return false
|
||||
} else if listeners == nil {
|
||||
listeners = []func(EditView, string){}
|
||||
listeners = []func(EditView, string, string){}
|
||||
}
|
||||
edit.textChangeListeners = listeners
|
||||
edit.propertyChangedEvent(tag)
|
||||
|
@ -358,10 +358,11 @@ func (edit *editViewData) AppendText(text string) {
|
|||
if GetEditViewType(edit) == MultiLineText {
|
||||
if value := edit.getRaw(Text); value != nil {
|
||||
if textValue, ok := value.(string); ok {
|
||||
oldText := textValue
|
||||
textValue += text
|
||||
edit.properties[Text] = textValue
|
||||
edit.session.callFunc("appendToInnerHTML", edit.htmlID(), text)
|
||||
edit.textChanged(textValue)
|
||||
edit.textChanged(textValue, oldText)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -371,9 +372,9 @@ func (edit *editViewData) AppendText(text string) {
|
|||
}
|
||||
}
|
||||
|
||||
func (edit *editViewData) textChanged(newText string) {
|
||||
func (edit *editViewData) textChanged(newText, oldText string) {
|
||||
for _, listener := range edit.textChangeListeners {
|
||||
listener(edit, newText)
|
||||
listener(edit, newText, oldText)
|
||||
}
|
||||
edit.propertyChangedEvent(Text)
|
||||
}
|
||||
|
@ -485,7 +486,7 @@ func (edit *editViewData) handleCommand(self View, command string, data DataObje
|
|||
if text, ok := data.PropertyValue("text"); ok {
|
||||
edit.properties[Text] = text
|
||||
if text := GetText(edit); text != oldText {
|
||||
edit.textChanged(text)
|
||||
edit.textChanged(text, oldText)
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
@ -552,8 +553,8 @@ func IsSpellcheck(view View, subviewID ...string) bool {
|
|||
// 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.
|
||||
func GetTextChangedListeners(view View, subviewID ...string) []func(EditView, string) {
|
||||
return getEventListeners[EditView, string](view, subviewID, EditTextChangedEvent)
|
||||
func GetTextChangedListeners(view View, subviewID ...string) []func(EditView, string, string) {
|
||||
return getEventWithOldListeners[EditView, string](view, subviewID, EditTextChangedEvent)
|
||||
}
|
||||
|
||||
// GetEditViewType returns a value of the Type property of EditView.
|
||||
|
|
192
keyEvents.go
192
keyEvents.go
|
@ -193,6 +193,185 @@ func valueToEventListeners[V View, E any](value any) ([]func(V, E), bool) {
|
|||
return nil, false
|
||||
}
|
||||
|
||||
func valueToEventWithOldListeners[V View, E any](value any) ([]func(V, E, E), bool) {
|
||||
if value == nil {
|
||||
return nil, true
|
||||
}
|
||||
|
||||
switch value := value.(type) {
|
||||
case func(V, E, E):
|
||||
return []func(V, E, E){value}, true
|
||||
|
||||
case func(V, E):
|
||||
fn := func(v V, val, _ E) {
|
||||
value(v, val)
|
||||
}
|
||||
return []func(V, E, E){fn}, true
|
||||
|
||||
case func(E, E):
|
||||
fn := func(_ V, val, old E) {
|
||||
value(val, old)
|
||||
}
|
||||
return []func(V, E, E){fn}, true
|
||||
|
||||
case func(E):
|
||||
fn := func(_ V, val, _ E) {
|
||||
value(val)
|
||||
}
|
||||
return []func(V, E, E){fn}, true
|
||||
|
||||
case func(V):
|
||||
fn := func(v V, _, _ E) {
|
||||
value(v)
|
||||
}
|
||||
return []func(V, E, E){fn}, true
|
||||
|
||||
case func():
|
||||
fn := func(V, E, E) {
|
||||
value()
|
||||
}
|
||||
return []func(V, E, E){fn}, true
|
||||
|
||||
case []func(V, E, E):
|
||||
if len(value) == 0 {
|
||||
return nil, true
|
||||
}
|
||||
for _, fn := range value {
|
||||
if fn == nil {
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
return value, true
|
||||
|
||||
case []func(V, E):
|
||||
count := len(value)
|
||||
if count == 0 {
|
||||
return nil, true
|
||||
}
|
||||
listeners := make([]func(V, E, E), count)
|
||||
for i, fn := range value {
|
||||
if fn == nil {
|
||||
return nil, false
|
||||
}
|
||||
listeners[i] = func(view V, val, _ E) {
|
||||
fn(view, val)
|
||||
}
|
||||
}
|
||||
return listeners, true
|
||||
|
||||
case []func(E):
|
||||
count := len(value)
|
||||
if count == 0 {
|
||||
return nil, true
|
||||
}
|
||||
listeners := make([]func(V, E, E), count)
|
||||
for i, fn := range value {
|
||||
if fn == nil {
|
||||
return nil, false
|
||||
}
|
||||
listeners[i] = func(_ V, val, _ E) {
|
||||
fn(val)
|
||||
}
|
||||
}
|
||||
return listeners, true
|
||||
|
||||
case []func(E, E):
|
||||
count := len(value)
|
||||
if count == 0 {
|
||||
return nil, true
|
||||
}
|
||||
listeners := make([]func(V, E, E), count)
|
||||
for i, fn := range value {
|
||||
if fn == nil {
|
||||
return nil, false
|
||||
}
|
||||
listeners[i] = func(_ V, val, old E) {
|
||||
fn(val, old)
|
||||
}
|
||||
}
|
||||
return listeners, true
|
||||
|
||||
case []func(V):
|
||||
count := len(value)
|
||||
if count == 0 {
|
||||
return nil, true
|
||||
}
|
||||
listeners := make([]func(V, E, E), count)
|
||||
for i, fn := range value {
|
||||
if fn == nil {
|
||||
return nil, false
|
||||
}
|
||||
listeners[i] = func(view V, _, _ E) {
|
||||
fn(view)
|
||||
}
|
||||
}
|
||||
return listeners, true
|
||||
|
||||
case []func():
|
||||
count := len(value)
|
||||
if count == 0 {
|
||||
return nil, true
|
||||
}
|
||||
listeners := make([]func(V, E, E), count)
|
||||
for i, fn := range value {
|
||||
if fn == nil {
|
||||
return nil, false
|
||||
}
|
||||
listeners[i] = func(V, E, E) {
|
||||
fn()
|
||||
}
|
||||
}
|
||||
return listeners, true
|
||||
|
||||
case []any:
|
||||
count := len(value)
|
||||
if count == 0 {
|
||||
return nil, true
|
||||
}
|
||||
listeners := make([]func(V, E, E), count)
|
||||
for i, v := range value {
|
||||
if v == nil {
|
||||
return nil, false
|
||||
}
|
||||
switch fn := v.(type) {
|
||||
case func(V, E, E):
|
||||
listeners[i] = fn
|
||||
|
||||
case func(V, E):
|
||||
listeners[i] = func(view V, val, _ E) {
|
||||
fn(view, val)
|
||||
}
|
||||
|
||||
case func(E, E):
|
||||
listeners[i] = func(_ V, val, old E) {
|
||||
fn(val, old)
|
||||
}
|
||||
|
||||
case func(E):
|
||||
listeners[i] = func(_ V, val, _ E) {
|
||||
fn(val)
|
||||
}
|
||||
|
||||
case func(V):
|
||||
listeners[i] = func(view V, _, _ E) {
|
||||
fn(view)
|
||||
}
|
||||
|
||||
case func():
|
||||
listeners[i] = func(V, E, E) {
|
||||
fn()
|
||||
}
|
||||
|
||||
default:
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
return listeners, true
|
||||
}
|
||||
|
||||
return nil, false
|
||||
}
|
||||
|
||||
var keyEvents = map[string]struct{ jsEvent, jsFunc string }{
|
||||
KeyDownEvent: {jsEvent: "onkeydown", jsFunc: "keyDownEvent"},
|
||||
KeyUpEvent: {jsEvent: "onkeyup", jsFunc: "keyUpEvent"},
|
||||
|
@ -227,6 +406,19 @@ func (view *viewData) removeKeyListener(tag string) {
|
|||
}
|
||||
}
|
||||
|
||||
func getEventWithOldListeners[V View, E any](view View, subviewID []string, tag string) []func(V, E, E) {
|
||||
if len(subviewID) > 0 && subviewID[0] != "" {
|
||||
view = ViewByID(view, subviewID[0])
|
||||
}
|
||||
if view != nil {
|
||||
if value := view.Get(tag); value != nil {
|
||||
if result, ok := value.([]func(V, E, E)); ok {
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
return []func(V, E, E){}
|
||||
}
|
||||
func getEventListeners[V View, E any](view View, subviewID []string, tag string) []func(V, E) {
|
||||
if len(subviewID) > 0 && subviewID[0] != "" {
|
||||
view = ViewByID(view, subviewID[0])
|
||||
|
|
Loading…
Reference in New Issue