diff options
| -rwxr-xr-x | src/nigui.nim | 105 | ||||
| -rwxr-xr-x | src/nigui/private/gtk3/gtk3.nim | 3 | ||||
| -rwxr-xr-x | src/nigui/private/gtk3/platform_impl.nim | 72 | ||||
| -rwxr-xr-x | src/nigui/private/gtk3/platform_types1.nim | 4 | ||||
| -rwxr-xr-x | src/nigui/private/windows/platform_impl.nim | 14 |
5 files changed, 113 insertions, 85 deletions
diff --git a/src/nigui.nim b/src/nigui.nim index d0281b6..fef6fcc 100755 --- a/src/nigui.nim +++ b/src/nigui.nim @@ -68,59 +68,60 @@ type Key* = enum # Keys with same value than Unicode: - Key_None = 0 - Key_Backspace = 8 - Key_Tab = 9 - Key_Return = 13 - Key_Escape = 27 - Key_Space = 32 - Key_Asterisk = 42 - Key_Plus = 43 - Key_Comma = 44 - Key_Minus = 45 - Key_Point = 46 - Key_Number0 = 48 - Key_Number1 = 49 - Key_Number2 = 50 - Key_Number3 = 51 - Key_Number4 = 52 - Key_Number5 = 53 - Key_Number6 = 54 - Key_Number7 = 55 - Key_Number8 = 56 - Key_Number9 = 57 - Key_A = 65 - Key_B = 66 - Key_C = 67 - Key_D = 68 - Key_E = 69 - Key_F = 70 - Key_G = 71 - Key_H = 72 - Key_I = 73 - Key_J = 74 - Key_K = 75 - Key_L = 76 - Key_M = 77 - Key_N = 78 - Key_O = 79 - Key_P = 80 - Key_Q = 81 - Key_R = 82 - Key_S = 83 - Key_T = 84 - Key_U = 85 - Key_V = 86 - Key_W = 87 - Key_X = 88 - Key_Y = 89 - Key_Z = 90 - Key_AE = 196 - Key_OE = 214 - Key_UE = 220 - Key_SharpS = 223 + Key_None = 0 + Key_Backspace = 8 + Key_Tab = 9 + Key_Return = 13 + Key_Escape = 27 + Key_Space = 32 + Key_Asterisk = 42 + Key_Plus = 43 + Key_Comma = 44 + Key_Minus = 45 + Key_Point = 46 + Key_Number0 = 48 + Key_Number1 = 49 + Key_Number2 = 50 + Key_Number3 = 51 + Key_Number4 = 52 + Key_Number5 = 53 + Key_Number6 = 54 + Key_Number7 = 55 + Key_Number8 = 56 + Key_Number9 = 57 + Key_A = 65 + Key_B = 66 + Key_C = 67 + Key_D = 68 + Key_E = 69 + Key_F = 70 + Key_G = 71 + Key_H = 72 + Key_I = 73 + Key_J = 74 + Key_K = 75 + Key_L = 76 + Key_M = 77 + Key_N = 78 + Key_O = 79 + Key_P = 80 + Key_Q = 81 + Key_R = 82 + Key_S = 83 + Key_T = 84 + Key_U = 85 + Key_V = 86 + Key_W = 87 + Key_X = 88 + Key_Y = 89 + Key_Z = 90 + Key_Circumflex = 94 + Key_AE = 196 + Key_OE = 214 + Key_UE = 220 + Key_SharpS = 223 # Not part of Unicode: - Key_Insert = 1000 + Key_Insert = 1000 Key_Delete Key_Left Key_Right diff --git a/src/nigui/private/gtk3/gtk3.nim b/src/nigui/private/gtk3/gtk3.nim index b1e218f..1edf03c 100755 --- a/src/nigui/private/gtk3/gtk3.nim +++ b/src/nigui/private/gtk3/gtk3.nim @@ -421,6 +421,9 @@ proc gtk_clipboard_store*(clipboard: pointer) {.importc: "gtk_clipboard_store", proc gtk_accelerator_get_default_mod_mask*(): cint {.importc: "gtk_accelerator_get_default_mod_mask", libgtk3.} +proc gtk_im_multicontext_new*(): pointer {.importc: "gtk_im_multicontext_new", libgtk3.} +proc gtk_im_context_filter_keypress*(context: pointer, event: var GdkEventKey): bool {.importc: "gtk_im_context_filter_keypress", libgtk3.} + # ---------------------------------------------------------------------------------------- # Drawing Related Procs diff --git a/src/nigui/private/gtk3/platform_impl.nim b/src/nigui/private/gtk3/platform_impl.nim index 6bf791a..e0635c1 100755 --- a/src/nigui/private/gtk3/platform_impl.nim +++ b/src/nigui/private/gtk3/platform_impl.nim @@ -62,6 +62,7 @@ proc pWindowConfigureSignal(windowHandle, event, data: pointer): bool {.cdecl.} proc pKeyvalToKey(keyval: cint): Key = result = case keyval + of 65106: Key_Circumflex of 65289: Key_Tab of 65293: Key_Return of 65307: Key_Escape @@ -79,59 +80,68 @@ proc pKeyvalToKey(keyval: cint): Key = else: cast[Key](keyval.unicodeToUpper) proc pWindowKeyPressSignal(widget: pointer, event: var GdkEventKey, data: pointer): bool {.cdecl.} = - # echo "window keyPressCallback" - - # echo event.keyval - # echo event.hardware_keycode - - # echo $gdk_keyval_to_unicode(event.keyval) - var unicode = gdk_keyval_to_unicode(event.keyval) - # if unicode == 0: - # unicode = event.keyval - let window = cast[WindowImpl](data) + window.fKeyPressed = pKeyvalToKey(event.keyval) + if gtk_im_context_filter_keypress(window.fIMContext, event) and window.fKeyPressed == Key_None: + return var evt = new WindowKeyEvent evt.window = window - evt.key = pKeyvalToKey(event.keyval) + evt.key = window.fKeyPressed if evt.key == Key_None: echo "Unkown key value: ", event.keyval return - evt.character = $event.`string` - evt.unicode = unicode - + evt.unicode = gdk_keyval_to_unicode(event.keyval) try: window.handleKeyDownEvent(evt) - result = evt.cancel except: handleException() + result = evt.cancel proc pControlKeyPressSignal(widget: pointer, event: var GdkEventKey, data: pointer): bool {.cdecl.} = - - # echo "control keyPressCallback" - - # echo $gdk_keyval_to_unicode(event.keyval) - var unicode = gdk_keyval_to_unicode(event.keyval) - - # if unicode == 0: - # unicode = event.keyval - let control = cast[ControlImpl](data) + control.fKeyPressed = pKeyvalToKey(event.keyval) + if gtk_im_context_filter_keypress(control.fIMContext, event) and control.fKeyPressed == Key_None: + return var evt = new ControlKeyEvent evt.control = control - evt.key = pKeyvalToKey(event.keyval) + evt.key = control.fKeyPressed if evt.key == Key_None: echo "Unkown key value: ", event.keyval return evt.character = $event.`string` - evt.unicode = unicode - + evt.unicode = gdk_keyval_to_unicode(event.keyval) try: control.handleKeyDownEvent(evt) except: handleException() + result = evt.cancel - return evt.cancel +proc pWindowIMContextCommitSignal(context: pointer, str: cstring, data: pointer) {.cdecl.} = + let window = cast[WindowImpl](data) + var evt = new WindowKeyEvent + evt.window = window + evt.character = $str + evt.unicode = evt.character.runeAt(0).toUpper().int + evt.key = window.fKeyPressed + window.fKeyPressed = Key_None + try: + window.handleKeyDownEvent(evt) + except: + handleException() + +proc pControlIMContextCommitSignal(context: pointer, str: cstring, data: pointer) {.cdecl.} = + let control = cast[ControlImpl](data) + var evt = new ControlKeyEvent + evt.control = control + evt.character = $str + evt.unicode = evt.character.runeAt(0).toUpper().int + evt.key = control.fKeyPressed + control.fKeyPressed = Key_None + try: + control.handleKeyDownEvent(evt) + except: + handleException() method focus(control: ControlImpl) = gtk_widget_grab_focus(control.fHandle) @@ -618,6 +628,9 @@ proc init(window: WindowImpl) = gtk_scrolled_window_set_policy(window.fInnerHandle, GTK_POLICY_ALWAYS, GTK_POLICY_ALWAYS) discard g_signal_connect_data(window.fInnerHandle, "draw", pMainScrollbarDraw, nil) + window.fIMContext = gtk_im_multicontext_new() + discard g_signal_connect_data(window.fIMContext, "commit", pWindowIMContextCommitSignal, cast[pointer](window)) + method destroy(window: WindowImpl) = procCall window.Window.destroy() gtk_widget_destroy(window.fHandle) @@ -758,6 +771,9 @@ proc init(control: ControlImpl) = gtk_widget_add_events(control.fHandle, GDK_BUTTON_RELEASE_MASK) discard g_signal_connect_data(control.fHandle, "button-release-event", pControlButtonReleaseSignal, cast[pointer](control)) + control.fIMContext = gtk_im_multicontext_new() + discard g_signal_connect_data(control.fIMContext, "commit", pControlIMContextCommitSignal, cast[pointer](control)) + procCall control.Control.init() method destroy(control: ControlImpl) = diff --git a/src/nigui/private/gtk3/platform_types1.nim b/src/nigui/private/gtk3/platform_types1.nim index 505013b..5266e2f 100755 --- a/src/nigui/private/gtk3/platform_types1.nim +++ b/src/nigui/private/gtk3/platform_types1.nim @@ -6,6 +6,8 @@ type WindowImpl* = ref object of Window fHandle: pointer fInnerHandle: pointer + fIMContext: pointer + fKeyPressed: Key ControlImpl* = ref object of Control fHandle: pointer @@ -14,6 +16,8 @@ type fHAdjust: pointer fVAdjust: pointer fDeadCornerHandle: pointer + fIMContext: pointer + fKeyPressed: Key CanvasImpl* = ref object of Canvas fSurface: pointer diff --git a/src/nigui/private/windows/platform_impl.nim b/src/nigui/private/windows/platform_impl.nim index 78dace3..8e072ff 100755 --- a/src/nigui/private/windows/platform_impl.nim +++ b/src/nigui/private/windows/platform_impl.nim @@ -20,6 +20,7 @@ const pCustomControlWindowClass = "3" var pDefaultParentWindow: pointer var pKeyState: KeyState +var pKeyDownKey: Key # needed to calculate clicks: var pLastMouseButtonDownControl: Control @@ -221,10 +222,10 @@ proc pVirtualKeyToKey(keyval: int): Key = of 46: Key_Delete else: cast[Key](keyval.unicodeToUpper) -proc pHandleWMKEYDOWNOrWMCHAR(window: Window, control: Control, unicode: int, key: Key): bool = +proc pHandleWMKEYDOWNOrWMCHAR(window: Window, control: Control, unicode: int): bool = var windowEvent = new WindowKeyEvent windowEvent.window = window - windowEvent.key = key + windowEvent.key = pKeyDownKey if windowEvent.key == Key_None: echo "WM_CHAR: Unkown key value: ", unicode return @@ -252,19 +253,22 @@ proc pHandleWMKEYDOWNOrWMCHAR(window: Window, control: Control, unicode: int, ke proc pHandleWMKEYDOWN(window: Window, control: Control, wParam, lParam: pointer): bool = if not GetKeyboardState(pKeyState): pRaiseLastOSError() + pKeyDownKey = pVirtualKeyToKey(cast[int](wParam)) + # Save the key for WM_CHAR, because WM_CHAR only gets the key combined with the dead key state var widestring = newString(2) let scancode = int32((cast[int](lParam) shr 8) and 0xFFFFFF00) if scancode == 10496: # When the dead key "^" on German keyboard is pressed, don't call ToUnicode(), because this would destroy the dead key state - return + pKeyDownKey = Key_Circumflex + return pHandleWMKEYDOWNOrWMCHAR(window, control, 0) let ret = ToUnicode(cast[int](wParam).int32, scancode, pKeyState, widestring, 1, 0) if ret == 1: return # Unicode characters are handled by WM_CHAR - result = pHandleWMKEYDOWNOrWMCHAR(window, control, 0, pVirtualKeyToKey(cast[int](wParam))) + result = pHandleWMKEYDOWNOrWMCHAR(window, control, 0) proc pHandleWMCHAR(window: Window, control: Control, wParam, lParam: pointer): bool = let unicode = cast[int](wParam) - result = pHandleWMKEYDOWNOrWMCHAR(window, control, unicode, cast[Key](unicode.unicodeToUpper)) + result = pHandleWMKEYDOWNOrWMCHAR(window, control, unicode) proc pWindowWndProc(hWnd: pointer, uMsg: int32, wParam, lParam: pointer): pointer {.cdecl.} = case uMsg |
