From dc2ea14cac0a395f7da7b13204474bb2caefd318 Mon Sep 17 00:00:00 2001 From: anoshenko Date: Mon, 15 May 2023 16:19:33 +0300 Subject: [PATCH] Added SetHotKey function to Session interface --- CHANGELOG.md | 1 + README-ru.md | 2 + README.md | 3 + keyEvents.go | 215 ++++++++++++++++++++++++++------------------------- session.go | 61 ++++++++++++++- 5 files changed, 176 insertions(+), 106 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d3c98b..dcd61c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # v0.13.0 +* Added SetHotKey function to Session interface * Added ViewIndex function to ViewsContainer interface * Added ReloadCell function to TableView interface * Added ReloadTableViewCell function diff --git a/README-ru.md b/README-ru.md index 8b8fe05..9219a5d 100644 --- a/README-ru.md +++ b/README-ru.md @@ -5217,6 +5217,8 @@ Safari и Firefox. * DownloadFileData(filename string, data []byte) - загружает (сохраняет) на стороне клиента файл с заданным именем и заданным содержимым. Обычно используется для передачи файла сгенерированного в памяти сервера. +* SetHotKey(keyCode KeyCode, controlKeys ControlKeyMask, fn func(Session)) - устанавливает функцию которая будет вызываться при нажатии заданной горячей клавиши. + ## Формат описания ресурсов Ресурсы приложения (темы, View, переводы) могут быть описаны в виде текста (utf-8). Данный текст помещается diff --git a/README.md b/README.md index 9b26347..33e3d55 100644 --- a/README.md +++ b/README.md @@ -5171,6 +5171,9 @@ It is used when the client needs to transfer a file from the server. * DownloadFileData(filename string, data [] byte) downloads (saves) on the client side a file with a specified name and specified content. Typically used to transfer a file generated in server memory. +* SetHotKey(keyCode KeyCode, controlKeys ControlKeyMask, fn func(Session)) - sets the function that will be called +when the given hotkey is pressed. + ## Resource description format Application resources (themes, views, translations) can be described as text (utf-8). diff --git a/keyEvents.go b/keyEvents.go index bf2522b..886f455 100644 --- a/keyEvents.go +++ b/keyEvents.go @@ -18,117 +18,122 @@ const ( // The additional listener formats: // func(KeyEvent), func(View), and func(). KeyUpEvent = "key-up-event" +) +type ControlKeyMask int +type KeyCode string + +const ( // AltKey is the mask of the "alt" key - AltKey = 1 + AltKey ControlKeyMask = 1 // CtrlKey is the mask of the "ctrl" key - CtrlKey = 2 + CtrlKey ControlKeyMask = 2 // ShiftKey is the mask of the "shift" key - ShiftKey = 4 + ShiftKey ControlKeyMask = 4 // MetaKey is the mask of the "meta" key - MetaKey = 8 + MetaKey ControlKeyMask = 8 - KeyA = "KeyA" - KeyB = "KeyB" - KeyC = "KeyC" - KeyD = "KeyD" - KeyE = "KeyE" - KeyF = "KeyF" - KeyG = "KeyG" - KeyH = "KeyH" - KeyI = "KeyI" - KeyJ = "KeyJ" - KeyK = "KeyK" - KeyL = "KeyL" - KeyM = "KeyM" - KeyN = "KeyN" - KeyO = "KeyO" - KeyP = "KeyP" - KeyQ = "KeyQ" - KeyR = "KeyR" - KeyS = "KeyS" - KeyT = "KeyT" - KeyU = "KeyU" - KeyV = "KeyV" - KeyW = "KeyW" - KeyX = "KeyX" - KeyY = "KeyY" - KeyZ = "KeyZ" - Digit0Key = "Digit0" - Digit1Key = "Digit1" - Digit2Key = "Digit2" - Digit3Key = "Digit3" - Digit4Key = "Digit4" - Digit5Key = "Digit5" - Digit6Key = "Digit6" - Digit7Key = "Digit7" - Digit8Key = "Digit8" - Digit9Key = "Digit9" - SpaceKey = "Space" - MinusKey = "Minus" - EqualKey = "Equal" - IntlBackslashKey = "IntlBackslash" - BracketLeftKey = "BracketLeft" - BracketRightKey = "BracketRight" - SemicolonKey = "Semicolon" - CommaKey = "Comma" - PeriodKey = "Period" - QuoteKey = "Quote" - BackquoteKey = "Backquote" - SlashKey = "Slash" - EscapeKey = "Escape" - EnterKey = "Enter" - TabKey = "Tab" - CapsLockKey = "CapsLock" - DeleteKey = "Delete" - HelpKey = "Help" - BackspaceKey = "Backspace" - ArrowLeftKey = "ArrowLeft" - ArrowRightKey = "ArrowRight" - ArrowUpKey = "ArrowUp" - ArrowDownKey = "ArrowDown" - HomeKey = "Home" - EndKey = "End" - PageUpKey = "PageUp" - PageDownKey = "PageDown" - F1Key = "F1" - F2Key = "F2" - F3Key = "F3" - F4Key = "F4" - F5Key = "F5" - F6Key = "F6" - F7Key = "F7" - F8Key = "F8" - F9Key = "F9" - F10Key = "F10" - F11Key = "F11" - F12Key = "F12" - F13Key = "F13" - NumLockKey = "NumLock" - NumpadKey0 = "Numpad0" - NumpadKey1 = "Numpad1" - NumpadKey2 = "Numpad2" - NumpadKey3 = "Numpad3" - NumpadKey4 = "Numpad4" - NumpadKey5 = "Numpad5" - NumpadKey6 = "Numpad6" - NumpadKey7 = "Numpad7" - NumpadKey8 = "Numpad8" - NumpadKey9 = "Numpad9" - NumpadDecimalKey = "NumpadDecimal" - NumpadEnterKey = "NumpadEnter" - NumpadAddKey = "NumpadAdd" - NumpadSubtractKey = "NumpadSubtract" - NumpadMultiplyKey = "NumpadMultiply" - NumpadDivideKey = "NumpadDivide" - ShiftLeftKey = "ShiftLeft" - ShiftRightKey = "ShiftRight" - ControlLeftKey = "ControlLeft" - ControlRightKey = "ControlRight" - AltLeftKey = "AltLeft" - AltRightKey = "AltRight" - MetaLeftKey = "MetaLeft" - MetaRightKey = "MetaRight" + KeyA KeyCode = "KeyA" + KeyB KeyCode = "KeyB" + KeyC KeyCode = "KeyC" + KeyD KeyCode = "KeyD" + KeyE KeyCode = "KeyE" + KeyF KeyCode = "KeyF" + KeyG KeyCode = "KeyG" + KeyH KeyCode = "KeyH" + KeyI KeyCode = "KeyI" + KeyJ KeyCode = "KeyJ" + KeyK KeyCode = "KeyK" + KeyL KeyCode = "KeyL" + KeyM KeyCode = "KeyM" + KeyN KeyCode = "KeyN" + KeyO KeyCode = "KeyO" + KeyP KeyCode = "KeyP" + KeyQ KeyCode = "KeyQ" + KeyR KeyCode = "KeyR" + KeyS KeyCode = "KeyS" + KeyT KeyCode = "KeyT" + KeyU KeyCode = "KeyU" + KeyV KeyCode = "KeyV" + KeyW KeyCode = "KeyW" + KeyX KeyCode = "KeyX" + KeyY KeyCode = "KeyY" + KeyZ KeyCode = "KeyZ" + Digit0Key KeyCode = "Digit0" + Digit1Key KeyCode = "Digit1" + Digit2Key KeyCode = "Digit2" + Digit3Key KeyCode = "Digit3" + Digit4Key KeyCode = "Digit4" + Digit5Key KeyCode = "Digit5" + Digit6Key KeyCode = "Digit6" + Digit7Key KeyCode = "Digit7" + Digit8Key KeyCode = "Digit8" + Digit9Key KeyCode = "Digit9" + SpaceKey KeyCode = "Space" + MinusKey KeyCode = "Minus" + EqualKey KeyCode = "Equal" + IntlBackslashKey KeyCode = "IntlBackslash" + BracketLeftKey KeyCode = "BracketLeft" + BracketRightKey KeyCode = "BracketRight" + SemicolonKey KeyCode = "Semicolon" + CommaKey KeyCode = "Comma" + PeriodKey KeyCode = "Period" + QuoteKey KeyCode = "Quote" + BackquoteKey KeyCode = "Backquote" + SlashKey KeyCode = "Slash" + EscapeKey KeyCode = "Escape" + EnterKey KeyCode = "Enter" + TabKey KeyCode = "Tab" + CapsLockKey KeyCode = "CapsLock" + DeleteKey KeyCode = "Delete" + HelpKey KeyCode = "Help" + BackspaceKey KeyCode = "Backspace" + ArrowLeftKey KeyCode = "ArrowLeft" + ArrowRightKey KeyCode = "ArrowRight" + ArrowUpKey KeyCode = "ArrowUp" + ArrowDownKey KeyCode = "ArrowDown" + HomeKey KeyCode = "Home" + EndKey KeyCode = "End" + PageUpKey KeyCode = "PageUp" + PageDownKey KeyCode = "PageDown" + F1Key KeyCode = "F1" + F2Key KeyCode = "F2" + F3Key KeyCode = "F3" + F4Key KeyCode = "F4" + F5Key KeyCode = "F5" + F6Key KeyCode = "F6" + F7Key KeyCode = "F7" + F8Key KeyCode = "F8" + F9Key KeyCode = "F9" + F10Key KeyCode = "F10" + F11Key KeyCode = "F11" + F12Key KeyCode = "F12" + F13Key KeyCode = "F13" + NumLockKey KeyCode = "NumLock" + NumpadKey0 KeyCode = "Numpad0" + NumpadKey1 KeyCode = "Numpad1" + NumpadKey2 KeyCode = "Numpad2" + NumpadKey3 KeyCode = "Numpad3" + NumpadKey4 KeyCode = "Numpad4" + NumpadKey5 KeyCode = "Numpad5" + NumpadKey6 KeyCode = "Numpad6" + NumpadKey7 KeyCode = "Numpad7" + NumpadKey8 KeyCode = "Numpad8" + NumpadKey9 KeyCode = "Numpad9" + NumpadDecimalKey KeyCode = "NumpadDecimal" + NumpadEnterKey KeyCode = "NumpadEnter" + NumpadAddKey KeyCode = "NumpadAdd" + NumpadSubtractKey KeyCode = "NumpadSubtract" + NumpadMultiplyKey KeyCode = "NumpadMultiply" + NumpadDivideKey KeyCode = "NumpadDivide" + ShiftLeftKey KeyCode = "ShiftLeft" + ShiftRightKey KeyCode = "ShiftRight" + ControlLeftKey KeyCode = "ControlLeft" + ControlRightKey KeyCode = "ControlRight" + AltLeftKey KeyCode = "AltLeft" + AltRightKey KeyCode = "AltRight" + MetaLeftKey KeyCode = "MetaLeft" + MetaRightKey KeyCode = "MetaRight" ) type KeyEvent struct { diff --git a/session.go b/session.go index f1d8924..08dd300 100644 --- a/session.go +++ b/session.go @@ -100,10 +100,17 @@ type Session interface { // OpenURL opens the url in the new browser tab OpenURL(url string) + // ClientItem reads value by key from the client-side storage ClientItem(key string) (string, bool) + // SetClientItem stores a key-value pair in the client-side storage SetClientItem(key, value string) + // RemoveAllClientItems removes all key-value pair from the client-side storage RemoveAllClientItems() + // SetHotKey sets the function that will be called when the given hotkey is pressed. + // Invoke SetHotKey(..., ..., nil) for remove hotkey function. + SetHotKey(keyCode KeyCode, controlKeys ControlKeyMask, fn func(Session)) + getCurrentTheme() Theme registerAnimation(props []AnimatedProperty) string @@ -188,6 +195,7 @@ type sessionData struct { animationCSS string updateScripts map[string]*strings.Builder clientStorage map[string]string + hotkeys map[string]func(Session) } func newSession(app Application, id int, customTheme string, params DataObject) Session { @@ -205,6 +213,7 @@ func newSession(app Application, id int, customTheme string, params DataObject) session.animationCSS = "" session.updateScripts = map[string]*strings.Builder{} session.clientStorage = map[string]string{} + session.hotkeys = map[string]func(Session){} if customTheme != "" { if theme, ok := CreateThemeFromText(customTheme); ok { @@ -672,7 +681,57 @@ func (session *sessionData) hotKey(event KeyEvent) { return } } - // TODO + + var controlKeys ControlKeyMask = 0 + if event.AltKey { + controlKeys |= AltKey + } + if event.CtrlKey { + controlKeys |= CtrlKey + } + if event.MetaKey { + controlKeys |= MetaKey + } + if event.ShiftKey { + controlKeys |= ShiftKey + } + + key := hotkeyCode(KeyCode(event.Code), controlKeys) + if fn, ok := session.hotkeys[key]; ok && fn != nil { + fn(session) + } +} + +func hotkeyCode(keyCode KeyCode, controlKeys ControlKeyMask) string { + buffer := allocStringBuilder() + defer freeStringBuilder(buffer) + + buffer.WriteString(strings.ToLower(string(keyCode))) + if controlKeys != 0 { + buffer.WriteRune('-') + if controlKeys&AltKey != 0 { + buffer.WriteRune('a') + } + if controlKeys&CtrlKey != 0 { + buffer.WriteRune('c') + } + if controlKeys&MetaKey != 0 { + buffer.WriteRune('m') + } + if controlKeys&ShiftKey != 0 { + buffer.WriteRune('s') + } + } + return buffer.String() +} + +func (session *sessionData) SetHotKey(keyCode KeyCode, controlKeys ControlKeyMask, fn func(Session)) { + hotkey := hotkeyCode(keyCode, controlKeys) + if fn == nil { + delete(session.hotkeys, hotkey) + } else { + session.hotkeys[hotkey] = fn + } } func (session *sessionData) SetTitle(title string) {