rui_orig/keyEvents.go

851 lines
21 KiB
Go
Raw Normal View History

2021-09-07 17:36:50 +03:00
package rui
import "strings"
// Constants which represent [View] specific keyboard events properties
2021-09-07 17:36:50 +03:00
const (
// KeyDown is the constant for "key-down-event" property tag.
// The "key-down-event" event is fired when a key is pressed.
2021-11-04 21:13:34 +03:00
// The main listener format:
// func(View, KeyEvent).
// The additional listener formats:
// func(KeyEvent), func(View), and func().
2021-09-07 17:36:50 +03:00
KeyDownEvent = "key-down-event"
2021-11-04 21:13:34 +03:00
// KeyPp is the constant for "key-up-event" property tag.
2021-09-07 17:36:50 +03:00
// The "key-up-event" event is fired when a key is released.
2021-11-04 21:13:34 +03:00
// The main listener format:
// func(View, KeyEvent).
// The additional listener formats:
// func(KeyEvent), func(View), and func().
2021-09-07 17:36:50 +03:00
KeyUpEvent = "key-up-event"
)
// ControlKeyMask represent ORed state of keyboard's control keys like [AltKey], [CtrlKey], [ShiftKey] and [MetaKey]
type ControlKeyMask int
// KeyCode is a string representation the a physical key being pressed.
// The value is not affected by the current keyboard layout or modifier state,
// so a particular key will always have the same value.
type KeyCode string
2023-05-15 15:27:37 +03:00
// Constants for specific keyboard keys.
const (
2023-05-15 15:27:37 +03:00
// AltKey is the mask of the "alt" key
AltKey ControlKeyMask = 1
2023-05-15 15:27:37 +03:00
// CtrlKey is the mask of the "ctrl" key
CtrlKey ControlKeyMask = 2
2023-05-15 15:27:37 +03:00
// ShiftKey is the mask of the "shift" key
ShiftKey ControlKeyMask = 4
2023-05-15 15:27:37 +03:00
// MetaKey is the mask of the "meta" key
MetaKey ControlKeyMask = 8
2023-05-15 15:27:37 +03:00
2024-09-16 14:11:54 +03:00
// KeyA represent "A" key on the keyboard
KeyA KeyCode = "KeyA"
2024-09-16 14:11:54 +03:00
// KeyB represent "B" key on the keyboard
KeyB KeyCode = "KeyB"
2024-09-16 14:11:54 +03:00
// KeyC represent "C" key on the keyboard
KeyC KeyCode = "KeyC"
2024-09-16 14:11:54 +03:00
// KeyD represent "D" key on the keyboard
KeyD KeyCode = "KeyD"
2024-09-16 14:11:54 +03:00
// KeyE represent "E" key on the keyboard
KeyE KeyCode = "KeyE"
2024-09-16 14:11:54 +03:00
// KeyF represent "F" key on the keyboard
KeyF KeyCode = "KeyF"
2024-09-16 14:11:54 +03:00
// KeyG represent "G" key on the keyboard
KeyG KeyCode = "KeyG"
2024-09-16 14:11:54 +03:00
// KeyH represent "H" key on the keyboard
KeyH KeyCode = "KeyH"
2024-09-16 14:11:54 +03:00
// KeyI represent "I" key on the keyboard
KeyI KeyCode = "KeyI"
2024-09-16 14:11:54 +03:00
// KeyJ represent "J" key on the keyboard
KeyJ KeyCode = "KeyJ"
2024-09-16 14:11:54 +03:00
// KeyK represent "K" key on the keyboard
KeyK KeyCode = "KeyK"
2024-09-16 14:11:54 +03:00
// KeyL represent "L" key on the keyboard
KeyL KeyCode = "KeyL"
2024-09-16 14:11:54 +03:00
// KeyM represent "M" key on the keyboard
KeyM KeyCode = "KeyM"
2024-09-16 14:11:54 +03:00
// KeyN represent "N" key on the keyboard
KeyN KeyCode = "KeyN"
2024-09-16 14:11:54 +03:00
// KeyO represent "O" key on the keyboard
KeyO KeyCode = "KeyO"
2024-09-16 14:11:54 +03:00
// KeyP represent "P" key on the keyboard
KeyP KeyCode = "KeyP"
2024-09-16 14:11:54 +03:00
// KeyQ represent "Q" key on the keyboard
KeyQ KeyCode = "KeyQ"
2024-09-16 14:11:54 +03:00
// KeyR represent "R" key on the keyboard
KeyR KeyCode = "KeyR"
2024-09-16 14:11:54 +03:00
// KeyS represent "S" key on the keyboard
KeyS KeyCode = "KeyS"
2024-09-16 14:11:54 +03:00
// KeyT represent "T" key on the keyboard
KeyT KeyCode = "KeyT"
2024-09-16 14:11:54 +03:00
// KeyU represent "U" key on the keyboard
KeyU KeyCode = "KeyU"
2024-09-16 14:11:54 +03:00
// KeyV represent "V" key on the keyboard
KeyV KeyCode = "KeyV"
2024-09-16 14:11:54 +03:00
// KeyW represent "W" key on the keyboard
KeyW KeyCode = "KeyW"
2024-09-16 14:11:54 +03:00
// KeyX represent "X" key on the keyboard
KeyX KeyCode = "KeyX"
2024-09-16 14:11:54 +03:00
// KeyY represent "Y" key on the keyboard
KeyY KeyCode = "KeyY"
2024-09-16 14:11:54 +03:00
// KeyZ represent "Z" key on the keyboard
KeyZ KeyCode = "KeyZ"
2024-09-16 14:11:54 +03:00
// Digit0Key represent "Digit0" key on the keyboard
Digit0Key KeyCode = "Digit0"
2024-09-16 14:11:54 +03:00
// Digit1Key represent "Digit1" key on the keyboard
Digit1Key KeyCode = "Digit1"
2024-09-16 14:11:54 +03:00
// Digit2Key represent "Digit2" key on the keyboard
Digit2Key KeyCode = "Digit2"
2024-09-16 14:11:54 +03:00
// Digit3Key represent "Digit3" key on the keyboard
Digit3Key KeyCode = "Digit3"
2024-09-16 14:11:54 +03:00
// Digit4Key represent "Digit4" key on the keyboard
Digit4Key KeyCode = "Digit4"
2024-09-16 14:11:54 +03:00
// Digit5Key represent "Digit5" key on the keyboard
Digit5Key KeyCode = "Digit5"
2024-09-16 14:11:54 +03:00
// Digit6Key represent "Digit6" key on the keyboard
Digit6Key KeyCode = "Digit6"
2024-09-16 14:11:54 +03:00
// Digit7Key represent "Digit7" key on the keyboard
Digit7Key KeyCode = "Digit7"
2024-09-16 14:11:54 +03:00
// Digit8Key represent "Digit8" key on the keyboard
Digit8Key KeyCode = "Digit8"
2024-09-16 14:11:54 +03:00
// Digit9Key represent "Digit9" key on the keyboard
Digit9Key KeyCode = "Digit9"
2024-09-16 14:11:54 +03:00
// SpaceKey represent "Space" key on the keyboard
SpaceKey KeyCode = "Space"
2024-09-16 14:11:54 +03:00
// MinusKey represent "Minus" key on the keyboard
MinusKey KeyCode = "Minus"
2024-09-16 14:11:54 +03:00
// EqualKey represent "Equal" key on the keyboard
EqualKey KeyCode = "Equal"
2024-09-16 14:11:54 +03:00
// IntlBackslashKey represent "IntlBackslash" key on the keyboard
IntlBackslashKey KeyCode = "IntlBackslash"
2024-09-16 14:11:54 +03:00
// BracketLeftKey represent "BracketLeft" key on the keyboard
BracketLeftKey KeyCode = "BracketLeft"
2024-09-16 14:11:54 +03:00
// BracketRightKey represent "BracketRight" key on the keyboard
BracketRightKey KeyCode = "BracketRight"
2024-09-16 14:11:54 +03:00
// SemicolonKey represent "Semicolon" key on the keyboard
SemicolonKey KeyCode = "Semicolon"
2024-09-16 14:11:54 +03:00
// CommaKey represent "Comma" key on the keyboard
CommaKey KeyCode = "Comma"
2024-09-16 14:11:54 +03:00
// PeriodKey represent "Period" key on the keyboard
PeriodKey KeyCode = "Period"
2024-09-16 14:11:54 +03:00
// QuoteKey represent "Quote" key on the keyboard
QuoteKey KeyCode = "Quote"
2024-09-16 14:11:54 +03:00
// BackquoteKey represent "Backquote" key on the keyboard
BackquoteKey KeyCode = "Backquote"
2024-09-16 14:11:54 +03:00
// SlashKey represent "Slash" key on the keyboard
SlashKey KeyCode = "Slash"
2024-09-16 14:11:54 +03:00
// EscapeKey represent "Escape" key on the keyboard
EscapeKey KeyCode = "Escape"
2024-09-16 14:11:54 +03:00
// EnterKey represent "Enter" key on the keyboard
EnterKey KeyCode = "Enter"
2024-09-16 14:11:54 +03:00
// TabKey represent "Tab" key on the keyboard
TabKey KeyCode = "Tab"
2024-09-16 14:11:54 +03:00
// CapsLockKey represent "CapsLock" key on the keyboard
CapsLockKey KeyCode = "CapsLock"
2024-09-16 14:11:54 +03:00
// DeleteKey represent "Delete" key on the keyboard
DeleteKey KeyCode = "Delete"
2024-09-16 14:11:54 +03:00
// InsertKey represent "Insert" key on the keyboard
InsertKey KeyCode = "Insert"
2024-09-16 14:11:54 +03:00
// HelpKey represent "Help" key on the keyboard
HelpKey KeyCode = "Help"
2024-09-16 14:11:54 +03:00
// BackspaceKey represent "Backspace" key on the keyboard
BackspaceKey KeyCode = "Backspace"
2024-09-16 14:11:54 +03:00
// PrintScreenKey represent "PrintScreen" key on the keyboard
PrintScreenKey KeyCode = "PrintScreen"
2024-09-16 14:11:54 +03:00
// ScrollLockKey represent "ScrollLock" key on the keyboard
ScrollLockKey KeyCode = "ScrollLock"
2024-09-16 14:11:54 +03:00
// PauseKey represent "Pause" key on the keyboard
PauseKey KeyCode = "Pause"
2024-09-16 14:11:54 +03:00
// ContextMenuKey represent "ContextMenu" key on the keyboard
ContextMenuKey KeyCode = "ContextMenu"
2024-09-16 14:11:54 +03:00
// ArrowLeftKey represent "ArrowLeft" key on the keyboard
ArrowLeftKey KeyCode = "ArrowLeft"
2024-09-16 14:11:54 +03:00
// ArrowRightKey represent "ArrowRight" key on the keyboard
ArrowRightKey KeyCode = "ArrowRight"
2024-09-16 14:11:54 +03:00
// ArrowUpKey represent "ArrowUp" key on the keyboard
ArrowUpKey KeyCode = "ArrowUp"
2024-09-16 14:11:54 +03:00
// ArrowDownKey represent "ArrowDown" key on the keyboard
ArrowDownKey KeyCode = "ArrowDown"
2024-09-16 14:11:54 +03:00
// HomeKey represent "Home" key on the keyboard
HomeKey KeyCode = "Home"
2024-09-16 14:11:54 +03:00
// EndKey represent "End" key on the keyboard
EndKey KeyCode = "End"
2024-09-16 14:11:54 +03:00
// PageUpKey represent "PageUp" key on the keyboard
PageUpKey KeyCode = "PageUp"
2024-09-16 14:11:54 +03:00
// PageDownKey represent "PageDown" key on the keyboard
PageDownKey KeyCode = "PageDown"
2024-09-16 14:11:54 +03:00
// F1Key represent "F1" key on the keyboard
F1Key KeyCode = "F1"
2024-09-16 14:11:54 +03:00
// F2Key represent "F2" key on the keyboard
F2Key KeyCode = "F2"
2024-09-16 14:11:54 +03:00
// F3Key represent "F3" key on the keyboard
F3Key KeyCode = "F3"
2024-09-16 14:11:54 +03:00
// F4Key represent "F4" key on the keyboard
F4Key KeyCode = "F4"
2024-09-16 14:11:54 +03:00
// F5Key represent "F5" key on the keyboard
F5Key KeyCode = "F5"
2024-09-16 14:11:54 +03:00
// F6Key represent "F6" key on the keyboard
F6Key KeyCode = "F6"
2024-09-16 14:11:54 +03:00
// F7Key represent "F7" key on the keyboard
F7Key KeyCode = "F7"
2024-09-16 14:11:54 +03:00
// F8Key represent "F8" key on the keyboard
F8Key KeyCode = "F8"
2024-09-16 14:11:54 +03:00
// F9Key represent "F9" key on the keyboard
F9Key KeyCode = "F9"
2024-09-16 14:11:54 +03:00
// F10Key represent "F10" key on the keyboard
F10Key KeyCode = "F10"
2024-09-16 14:11:54 +03:00
// F11Key represent "F11" key on the keyboard
F11Key KeyCode = "F11"
2024-09-16 14:11:54 +03:00
// F12Key represent "F12" key on the keyboard
F12Key KeyCode = "F12"
2024-09-16 14:11:54 +03:00
// F13Key represent "F13" key on the keyboard
F13Key KeyCode = "F13"
2024-09-16 14:11:54 +03:00
// NumLockKey represent "NumLock" key on the keyboard
NumLockKey KeyCode = "NumLock"
2024-09-16 14:11:54 +03:00
// NumpadKey0 represent "Numpad0" key on the keyboard
NumpadKey0 KeyCode = "Numpad0"
2024-09-16 14:11:54 +03:00
// NumpadKey1 represent "Numpad1" key on the keyboard
NumpadKey1 KeyCode = "Numpad1"
2024-09-16 14:11:54 +03:00
// NumpadKey2 represent "Numpad2" key on the keyboard
NumpadKey2 KeyCode = "Numpad2"
2024-09-16 14:11:54 +03:00
// NumpadKey3 represent "Numpad3" key on the keyboard
NumpadKey3 KeyCode = "Numpad3"
2024-09-16 14:11:54 +03:00
// NumpadKey4 represent "Numpad4" key on the keyboard
NumpadKey4 KeyCode = "Numpad4"
2024-09-16 14:11:54 +03:00
// NumpadKey5 represent "Numpad5" key on the keyboard
NumpadKey5 KeyCode = "Numpad5"
2024-09-16 14:11:54 +03:00
// NumpadKey6 represent "Numpad6" key on the keyboard
NumpadKey6 KeyCode = "Numpad6"
2024-09-16 14:11:54 +03:00
// NumpadKey7 represent "Numpad7" key on the keyboard
NumpadKey7 KeyCode = "Numpad7"
2024-09-16 14:11:54 +03:00
// NumpadKey8 represent "Numpad8" key on the keyboard
NumpadKey8 KeyCode = "Numpad8"
2024-09-16 14:11:54 +03:00
// NumpadKey9 represent "Numpad9" key on the keyboard
NumpadKey9 KeyCode = "Numpad9"
2024-09-16 14:11:54 +03:00
// NumpadDecimalKey represent "NumpadDecimal" key on the keyboard
NumpadDecimalKey KeyCode = "NumpadDecimal"
2024-09-16 14:11:54 +03:00
// NumpadEnterKey represent "NumpadEnter" key on the keyboard
NumpadEnterKey KeyCode = "NumpadEnter"
2024-09-16 14:11:54 +03:00
// NumpadAddKey represent "NumpadAdd" key on the keyboard
NumpadAddKey KeyCode = "NumpadAdd"
2024-09-16 14:11:54 +03:00
// NumpadSubtractKey represent "NumpadSubtract" key on the keyboard
NumpadSubtractKey KeyCode = "NumpadSubtract"
2024-09-16 14:11:54 +03:00
// NumpadMultiplyKey represent "NumpadMultiply" key on the keyboard
NumpadMultiplyKey KeyCode = "NumpadMultiply"
2024-09-16 14:11:54 +03:00
// NumpadDivideKey represent "NumpadDivide" key on the keyboard
NumpadDivideKey KeyCode = "NumpadDivide"
2024-09-16 14:11:54 +03:00
// ShiftLeftKey represent "ShiftLeft" key on the keyboard
ShiftLeftKey KeyCode = "ShiftLeft"
2024-09-16 14:11:54 +03:00
// ShiftRightKey represent "ShiftRight" key on the keyboard
ShiftRightKey KeyCode = "ShiftRight"
2024-09-16 14:11:54 +03:00
// ControlLeftKey represent "ControlLeft" key on the keyboard
ControlLeftKey KeyCode = "ControlLeft"
2024-09-16 14:11:54 +03:00
// ControlRightKey represent "ControlRight" key on the keyboard
ControlRightKey KeyCode = "ControlRight"
2024-09-16 14:11:54 +03:00
// AltLeftKey represent "AltLeft" key on the keyboard
AltLeftKey KeyCode = "AltLeft"
2024-09-16 14:11:54 +03:00
// AltRightKey represent "AltRight" key on the keyboard
AltRightKey KeyCode = "AltRight"
2024-09-16 14:11:54 +03:00
// MetaLeftKey represent "MetaLeft" key on the keyboard
MetaLeftKey KeyCode = "MetaLeft"
2024-09-16 14:11:54 +03:00
// MetaRightKey represent "MetaRight" key on the keyboard
MetaRightKey KeyCode = "MetaRight"
2021-09-07 17:36:50 +03:00
)
// KeyEvent represent a keyboard event
2021-09-07 17:36:50 +03:00
type KeyEvent struct {
// TimeStamp is the time at which the event was created (in milliseconds).
// This value is time since epoch—but in reality, browsers' definitions vary.
TimeStamp uint64
// Key is the key value of the key represented by the event. If the value has a printed representation,
// this attribute's value is the same as the char property. Otherwise, it's one of the key value strings
// specified in Key values. If the key can't be identified, its value is the string "Unidentified".
Key string
// Code holds a string that identifies the physical key being pressed. The value is not affected
// by the current keyboard layout or modifier state, so a particular key will always return the same value.
Code KeyCode
2021-09-07 17:36:50 +03:00
// Repeat == true if a key has been depressed long enough to trigger key repetition, otherwise false.
Repeat bool
// CtrlKey == true if the control key was down when the event was fired. false otherwise.
CtrlKey bool
// ShiftKey == true if the shift key was down when the event was fired. false otherwise.
ShiftKey bool
// AltKey == true if the alt key was down when the event was fired. false otherwise.
AltKey bool
// MetaKey == true if the meta key was down when the event was fired. false otherwise.
MetaKey bool
}
2022-07-27 20:31:57 +03:00
func (event *KeyEvent) init(data DataObject) {
getBool := func(tag string) bool {
if value, ok := data.PropertyValue(tag); ok && value == "1" {
return true
}
return false
}
event.Key, _ = data.PropertyValue("key")
code, _ := data.PropertyValue("code")
event.Code = KeyCode(code)
2022-07-27 20:31:57 +03:00
event.TimeStamp = getTimeStamp(data)
event.Repeat = getBool("repeat")
event.CtrlKey = getBool("ctrlKey")
event.ShiftKey = getBool("shiftKey")
event.AltKey = getBool("altKey")
event.MetaKey = getBool("metaKey")
}
func valueToEventListeners[V View, E any](value any) ([]func(V, E), 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, E):
return []func(V, E){value}, true
2021-09-07 17:36:50 +03:00
2022-07-27 20:31:57 +03:00
case func(E):
fn := func(_ V, event E) {
2021-09-07 17:36:50 +03:00
value(event)
}
2022-07-27 20:31:57 +03:00
return []func(V, E){fn}, true
2021-09-07 17:36:50 +03:00
2022-07-27 20:31:57 +03:00
case func(V):
fn := func(view V, _ E) {
2021-09-07 17:36:50 +03:00
value(view)
}
2022-07-27 20:31:57 +03:00
return []func(V, E){fn}, true
2021-09-07 17:36:50 +03:00
case func():
2022-07-27 20:31:57 +03:00
fn := func(V, E) {
2021-09-07 17:36:50 +03:00
value()
}
2022-07-27 20:31:57 +03:00
return []func(V, E){fn}, true
2021-09-07 17:36:50 +03:00
2022-07-27 20:31:57 +03:00
case []func(V, E):
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
2022-07-27 20:31:57 +03:00
case []func(E):
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, E), 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, event E) {
2021-09-07 17:36:50 +03:00
v(event)
}
}
return listeners, true
2022-07-27 20:31:57 +03:00
case []func(V):
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, E), 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(view V, _ E) {
2021-09-07 17:36:50 +03:00
v(view)
}
}
return listeners, true
case []func():
count := len(value)
if count == 0 {
return nil, true
}
2022-07-27 20:31:57 +03:00
listeners := make([]func(V, E), 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, E) {
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, E), 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, E):
2021-09-07 17:36:50 +03:00
listeners[i] = v
2022-07-27 20:31:57 +03:00
case func(E):
listeners[i] = func(_ V, event E) {
2021-09-07 17:36:50 +03:00
v(event)
}
2022-07-27 20:31:57 +03:00
case func(V):
listeners[i] = func(view V, _ E) {
2021-09-07 17:36:50 +03:00
v(view)
}
case func():
2022-07-27 20:31:57 +03:00
listeners[i] = func(V, E) {
2021-09-07 17:36:50 +03:00
v()
}
default:
return nil, false
}
}
return listeners, true
}
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
}
2022-07-26 18:36:00 +03:00
func (view *viewData) setKeyListener(tag string, value any) bool {
2022-07-27 20:31:57 +03:00
listeners, ok := valueToEventListeners[View, KeyEvent](value)
2021-09-07 17:36:50 +03:00
if !ok {
notCompatibleType(tag, value)
return false
}
if listeners == nil {
view.removeKeyListener(tag)
} else {
2023-05-02 17:20:01 +03:00
switch tag {
case KeyDownEvent:
2023-05-15 15:27:37 +03:00
view.properties[tag] = listeners
2023-05-02 17:20:01 +03:00
if view.created {
view.session.updateProperty(view.htmlID(), "onkeydown", "keyDownEvent(this, event)")
}
case KeyUpEvent:
2023-05-15 15:27:37 +03:00
view.properties[tag] = listeners
2023-05-02 17:20:01 +03:00
if view.created {
view.session.updateProperty(view.htmlID(), "onkeyup", "keyUpEvent(this, event)")
}
default:
return false
}
2021-09-07 17:36:50 +03:00
}
2023-05-02 17:20:01 +03:00
2021-09-07 17:36:50 +03:00
return true
}
func (view *viewData) removeKeyListener(tag string) {
delete(view.properties, tag)
if view.created {
2023-05-02 17:20:01 +03:00
switch tag {
case KeyDownEvent:
if !view.Focusable() {
view.session.removeProperty(view.htmlID(), "onkeydown")
}
case KeyUpEvent:
view.session.removeProperty(view.htmlID(), "onkeyup")
2021-09-07 17:36:50 +03:00
}
}
}
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){}
}
2023-05-15 15:27:37 +03:00
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])
2021-09-07 17:36:50 +03:00
}
if view != nil {
if value := view.Get(tag); value != nil {
2022-07-27 20:31:57 +03:00
if result, ok := value.([]func(V, E)); ok {
2021-09-07 17:36:50 +03:00
return result
}
}
}
2022-07-27 20:31:57 +03:00
return []func(V, E){}
2021-09-07 17:36:50 +03:00
}
func keyEventsHtml(view View, buffer *strings.Builder) {
2023-05-02 17:20:01 +03:00
if len(getEventListeners[View, KeyEvent](view, nil, KeyDownEvent)) > 0 {
buffer.WriteString(`onkeydown="keyDownEvent(this, event)" `)
} else if view.Focusable() {
if len(getEventListeners[View, MouseEvent](view, nil, ClickEvent)) > 0 {
buffer.WriteString(`onkeydown="keyDownEvent(this, event)" `)
2021-09-07 17:36:50 +03:00
}
}
2023-05-02 17:20:01 +03:00
if listeners := getEventListeners[View, KeyEvent](view, nil, KeyUpEvent); len(listeners) > 0 {
buffer.WriteString(`onkeyup="keyUpEvent(this, event)" `)
}
2021-09-07 17:36:50 +03:00
}
func handleKeyEvents(view View, tag string, data DataObject) {
2023-05-02 17:20:01 +03:00
var event KeyEvent
event.init(data)
listeners := getEventListeners[View, KeyEvent](view, nil, tag)
2021-09-07 17:36:50 +03:00
2023-05-02 17:20:01 +03:00
if len(listeners) > 0 {
2022-07-27 20:31:57 +03:00
for _, listener := range listeners {
listener(view, event)
2021-09-07 17:36:50 +03:00
}
2023-05-02 17:20:01 +03:00
return
}
if tag == KeyDownEvent && view.Focusable() && (event.Key == " " || event.Key == "Enter") && !IsDisabled(view) {
if listeners := getEventListeners[View, MouseEvent](view, nil, ClickEvent); len(listeners) > 0 {
clickEvent := MouseEvent{
TimeStamp: event.TimeStamp,
Button: PrimaryMouseButton,
Buttons: PrimaryMouseMask,
CtrlKey: event.CtrlKey,
AltKey: event.AltKey,
ShiftKey: event.ShiftKey,
MetaKey: event.MetaKey,
ClientX: view.Frame().Width / 2,
ClientY: view.Frame().Height / 2,
X: view.Frame().Width / 2,
Y: view.Frame().Height / 2,
ScreenX: view.Frame().Left + view.Frame().Width/2,
ScreenY: view.Frame().Top + view.Frame().Height/2,
}
for _, listener := range listeners {
listener(view, clickEvent)
}
}
2021-09-07 17:36:50 +03:00
}
}
// 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) {
2022-07-27 20:31:57 +03:00
return getEventListeners[View, KeyEvent](view, subviewID, KeyDownEvent)
2021-09-07 17:36:50 +03:00
}
// 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) {
2022-07-27 20:31:57 +03:00
return getEventListeners[View, KeyEvent](view, subviewID, KeyUpEvent)
2021-09-07 17:36:50 +03:00
}