diff --git a/example/simpleDemo/main.go b/example/simpleDemo/main.go index 3fd45f03..b286bef1 100644 --- a/example/simpleDemo/main.go +++ b/example/simpleDemo/main.go @@ -39,6 +39,9 @@ func main() { gutter.OptionPixelRatio(1.2), gutter.OptionVMArguments([]string{"--dart-non-checked-mode", "--observatory-port=50300"}), gutter.OptionAddPluginReceiver(ownPlugin, "plugin_demo"), + // Default keyboard is Qwerty, if you want to change it, you can check keyboard.go in gutter package. + // Otherwise you can create your own by usinng `KeyboardShortcuts` struct. + //gutter.OptionKeyboardLayout(gutter.KeyboardAzertyLayout), } if err = gutter.Run(options...); err != nil { diff --git a/gutter.go b/gutter.go index 8e7b9a59..ff74d1ad 100644 --- a/gutter.go +++ b/gutter.go @@ -93,73 +93,74 @@ func glfwMouseButtonCallback(window *glfw.Window, key glfw.MouseButton, action g var state = textModel{} -func glfwKeyCallback(w *glfw.Window, key glfw.Key, scancode int, action glfw.Action, mods glfw.ModifierKey) { +func glfwKey(keyboardLayout KeyboardShortcuts) func(w *glfw.Window, key glfw.Key, scancode int, action glfw.Action, mods glfw.ModifierKey) { - if key == glfw.KeyEscape && action == glfw.Press { - w.SetShouldClose(true) - } + return func(w *glfw.Window, key glfw.Key, scancode int, action glfw.Action, mods glfw.ModifierKey) { + if key == glfw.KeyEscape && action == glfw.Press { + w.SetShouldClose(true) + } - if action == glfw.Repeat || action == glfw.Press { - if state.clientID != 0 { + if action == glfw.Repeat || action == glfw.Press { + if state.clientID != 0 { - switch key { - case glfw.KeyEnter: - if mods == glfw.ModControl { - performAction(w, "done") - } else { - state.addChar([]rune{'\n'}) - performAction(w, "newline") - } + switch key { + case glfw.KeyEnter: + if mods == glfw.ModControl { + performAction(w, "done") + } else { + state.addChar([]rune{'\n'}) + performAction(w, "newline") + } - case glfw.KeyHome: - state.MoveCursorHome(int(mods)) + case glfw.KeyHome: + state.MoveCursorHome(int(mods)) - case glfw.KeyEnd: - state.MoveCursorEnd(int(mods)) + case glfw.KeyEnd: + state.MoveCursorEnd(int(mods)) - case glfw.KeyLeft: - state.MoveCursorLeft(int(mods)) + case glfw.KeyLeft: + state.MoveCursorLeft(int(mods)) - case glfw.KeyRight: - state.MoveCursorRight(int(mods)) + case glfw.KeyRight: + state.MoveCursorRight(int(mods)) - case glfw.KeyDelete: - state.Delete(int(mods)) + case glfw.KeyDelete: + state.Delete(int(mods)) - case glfw.KeyBackspace: - state.Backspace(int(mods)) + case glfw.KeyBackspace: + state.Backspace(int(mods)) - case glfw.KeyA: - if mods == glfw.ModControl { - state.SelectAll() - } + case keyboardLayout.SelectAll: + if mods == glfw.ModControl { + state.SelectAll() + } - case glfw.KeyC: - if mods == glfw.ModControl && state.isSelected() { - _, _, selectedContent := state.GetSelectedText() - w.SetClipboardString(selectedContent) - } + case keyboardLayout.Copy: + if mods == glfw.ModControl && state.isSelected() { + _, _, selectedContent := state.GetSelectedText() + w.SetClipboardString(selectedContent) + } - case glfw.KeyX: - if mods == glfw.ModControl && state.isSelected() { - _, _, selectedContent := state.GetSelectedText() - w.SetClipboardString(selectedContent) - state.RemoveSelectedText() - } + case keyboardLayout.Cut: + if mods == glfw.ModControl && state.isSelected() { + _, _, selectedContent := state.GetSelectedText() + w.SetClipboardString(selectedContent) + state.RemoveSelectedText() + } - case glfw.KeyV: - if mods == glfw.ModControl { - var clpString, err = w.GetClipboardString() - if err != nil { - log.Printf("unable to get the clipboard content: %v\n", err) - } else { - state.addChar([]rune(clpString)) + case keyboardLayout.Paste: + if mods == glfw.ModControl { + var clpString, err = w.GetClipboardString() + if err != nil { + log.Printf("unable to get the clipboard content: %v\n", err) + } else { + state.addChar([]rune(clpString)) + } } } } } } - } func glfwWindowSizeCallback(window *glfw.Window, width int, height int) { @@ -242,6 +243,13 @@ func runFlutter(window *glfw.Window, c config) *flutter.EngineOpenGL { width, height := window.GetFramebufferSize() glfwWindowSizeCallback(window, width, height) + var glfwKeyCallback func(w *glfw.Window, key glfw.Key, scancode int, action glfw.Action, mods glfw.ModifierKey) + + if c.KeyboardLayout != nil { + glfwKeyCallback = glfwKey(*c.KeyboardLayout) + } else { + glfwKeyCallback = glfwKey(KeyboardQwertyLayout) + } window.SetKeyCallback(glfwKeyCallback) window.SetFramebufferSizeCallback(glfwWindowSizeCallback) @@ -286,11 +294,11 @@ func performAction(window *glfw.Window, action string) { "TextInputAction." + action, }) message := flutter.Message{ - Args: actionArgs, - Method:"TextInputClient.performAction", + Args: actionArgs, + Method: "TextInputClient.performAction", } var mess = &flutter.PlatformMessage{ - Channel:textInputChannel, + Channel: textInputChannel, Message: message, } flutterOGL := flutter.SelectEngine(0) diff --git a/keyboard.go b/keyboard.go new file mode 100644 index 00000000..6d81b167 --- /dev/null +++ b/keyboard.go @@ -0,0 +1,19 @@ +package gutter + +import "github.com/go-gl/glfw/v3.2/glfw" + +// KeyboardQwertyLayout is the default key for shortcuts (US-layout) +var KeyboardQwertyLayout = KeyboardShortcuts{ + Cut: glfw.KeyX, + Copy: glfw.KeyC, + Paste: glfw.KeyV, + SelectAll: glfw.KeyA, +} + +// KeyboardAzertyLayout gives an Azerty layout (french) +var KeyboardAzertyLayout = KeyboardShortcuts{ + Cut: glfw.KeyX, + Copy: glfw.KeyC, + Paste: glfw.KeyV, + SelectAll: glfw.KeyQ, +} diff --git a/option.go b/option.go index 9a518c8a..17deb31d 100644 --- a/option.go +++ b/option.go @@ -86,6 +86,14 @@ func OptionAddPluginReceiver(handler PluginReceivers, channelName string) Option } } +// OptionKeyboardLayout allow application to support keyboard that have a different layout +// when the FlutterEngine send a PlatformMessage to the Embedder +func OptionKeyboardLayout(keyboardLayout KeyboardShortcuts) Option { + return func(c *config) { + c.KeyboardLayout = &keyboardLayout + } +} + type config struct { WindowDimension struct { x int @@ -97,6 +105,16 @@ type config struct { PixelRatio float64 VMArguments []string PlatformMessageReceivers map[string][]PluginReceivers // The Key is the Channel name. + KeyboardLayout *KeyboardShortcuts +} + +// KeyboardShortcuts Struct where user can define his own keyboard shortcut. +// This will allow application to support keyboard layout different from US layout +type KeyboardShortcuts struct { + Cut glfw.Key + Copy glfw.Key + Paste glfw.Key + SelectAll glfw.Key } func (t config) merge(options ...Option) config {