summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortrustable-code <krauter.simon@arcor.de>2018-05-07 21:12:54 +0200
committertrustable-code <krauter.simon@arcor.de>2018-05-07 21:12:54 +0200
commitf8825fa1d708c644997ad01c1a8dfaedc787727b (patch)
tree2bd2c4cf8e5d73c3e55737869c0e7906d796e6e3 /src
parent684cfa5e63123d4bb4b84d3e52e3e4418e66890a (diff)
downloadNiGui-f8825fa1d708c644997ad01c1a8dfaedc787727b.tar.gz
NiGui-f8825fa1d708c644997ad01c1a8dfaedc787727b.zip
Add possibility to check, which keys are pressed togehter
New procs: - isDown(key: Key): bool - downKeys(): seq[Key]
Diffstat (limited to 'src')
-rwxr-xr-xsrc/nigui.nim40
-rwxr-xr-xsrc/nigui/private/gtk3/platform_impl.nim5
-rwxr-xr-xsrc/nigui/private/windows/platform_impl.nim50
3 files changed, 76 insertions, 19 deletions
diff --git a/src/nigui.nim b/src/nigui.nim
index f7b0f36..6667719 100755
--- a/src/nigui.nim
+++ b/src/nigui.nim
@@ -335,8 +335,9 @@ when useGtk(): include "nigui/private/gtk3/platform_types3"
# Global Variables
# ----------------------------------------------------------------------------------------
-var quitOnLastWindowClose* = true
-var clickMaxXYMove* = 20
+var
+ quitOnLastWindowClose* = true
+ clickMaxXYMove* = 20
# dummy type and object, needed to use get/set properties
type App = object
@@ -377,6 +378,10 @@ proc `clipboardText=`*(app: App, text: string)
proc rgb*(red, green, blue: byte, alpha: byte = 255): Color
+proc isDown*(key: Key): bool
+
+proc downKeys*(): seq[Key]
+
# ----------------------------------------------------------------------------------------
# Dialogs
@@ -907,15 +912,17 @@ import unicode
# Global Variables
# ----------------------------------------------------------------------------------------
-var fErrorHandler: ErrorHandlerProc = nil
-var windowList: seq[Window] = @[]
-var fScrollbarSize = -1
+var
+ fErrorHandler: ErrorHandlerProc = nil
+ windowList: seq[Window] = @[]
+ fScrollbarSize = -1
+ fDownKeys: seq[Key] = @[]
-# Default style:
-var fDefaultBackgroundColor: Color # initialized by platform-specific init()
-var fDefaultTextColor: Color # initialized by platform-specific init()
-var fDefaultFontFamily = ""
-var fDefaultFontSize = 15.float
+ # Default style:
+ fDefaultBackgroundColor: Color # initialized by platform-specific init()
+ fDefaultTextColor: Color # initialized by platform-specific init()
+ fDefaultFontFamily = ""
+ fDefaultFontSize = 15.float
# ----------------------------------------------------------------------------------------
@@ -1042,6 +1049,19 @@ proc newSaveFileDialog(): SaveFileDialog =
result.defaultName = ""
result.file = ""
+proc isDown(key: Key): bool = fDownKeys.contains(key)
+
+proc downKeys(): seq[Key] = fDownKeys
+
+proc internalKeyDown(key: Key) =
+ if not fDownKeys.contains(key):
+ fDownKeys.add(key)
+
+proc internalKeyUp(key: Key) =
+ let i = fDownKeys.find(key)
+ if i != -1:
+ fDownKeys.delete(i)
+
# ----------------------------------------------------------------------------------------
# Canvas
diff --git a/src/nigui/private/gtk3/platform_impl.nim b/src/nigui/private/gtk3/platform_impl.nim
index ba4f51a..52315f1 100755
--- a/src/nigui/private/gtk3/platform_impl.nim
+++ b/src/nigui/private/gtk3/platform_impl.nim
@@ -88,6 +88,7 @@ proc pKeyvalToKey(keyval: cint): Key =
proc pWindowKeyPressSignal(widget: pointer, event: var GdkEventKey, data: pointer): bool {.cdecl.} =
let window = cast[WindowImpl](data)
window.fKeyPressed = pKeyvalToKey(event.keyval)
+ internalKeyDown(window.fKeyPressed)
if gtk_im_context_filter_keypress(window.fIMContext, event) and window.fKeyPressed == Key_None:
return
var evt = new KeyboardEvent
@@ -104,6 +105,9 @@ proc pWindowKeyPressSignal(widget: pointer, event: var GdkEventKey, data: pointe
handleException()
result = evt.handled
+proc pWindowKeyReleaseSignal(widget: pointer, event: var GdkEventKey): bool {.cdecl.} =
+ internalKeyUp(pKeyvalToKey(event.keyval))
+
proc pControlKeyPressSignal(widget: pointer, event: var GdkEventKey, data: pointer): bool {.cdecl.} =
let control = cast[ControlImpl](data)
control.fKeyPressed = pKeyvalToKey(event.keyval)
@@ -624,6 +628,7 @@ proc init(window: WindowImpl) =
discard g_signal_connect_data(window.fHandle, "delete-event", pWindowDeleteSignal, cast[pointer](window))
discard g_signal_connect_data(window.fHandle, "configure-event", pWindowConfigureSignal, cast[pointer](window))
discard g_signal_connect_data(window.fHandle, "key-press-event", pWindowKeyPressSignal, cast[pointer](window))
+ discard g_signal_connect_data(window.fHandle, "key-release-event", pWindowKeyReleaseSignal, cast[pointer](window))
discard g_signal_connect_data(window.fHandle, "window-state-event", pWindowStateEventSignal, cast[pointer](window))
# Enable drag and drop of files:
diff --git a/src/nigui/private/windows/platform_impl.nim b/src/nigui/private/windows/platform_impl.nim
index 3251b61..24d5c8c 100755
--- a/src/nigui/private/windows/platform_impl.nim
+++ b/src/nigui/private/windows/platform_impl.nim
@@ -231,7 +231,34 @@ proc pVirtualKeyToKey(keyval, scancode: int32): Key =
of VK_DELETE: result = Key_Delete
else: result = cast[Key](keyval.unicodeToUpper)
+proc pWMParamsToKey(wParam, lParam: pointer): Key =
+ case cast[int32](wParam)
+ of VK_CONTROL, VK_SHIFT, VK_MENU:
+ let scancode = (cast[int32](lParam) and 0x00FF0000) shr 16
+ case MapVirtualKeyW(scancode, MAPVK_VSC_TO_VK_EX)
+ of VK_LCONTROL: result = Key_ControlL
+ of VK_RCONTROL: result = Key_ControlR
+ of VK_LSHIFT: result = Key_ShiftL
+ of VK_RSHIFT: result = Key_ShiftR
+ of VK_LMENU: result = Key_AltL
+ of VK_RMENU: result = Key_AltR
+ else: discard
+ of VK_PRIOR: result = Key_PageUp
+ of VK_NEXT: result = Key_PageDown
+ of VK_END: result = Key_End
+ of VK_HOME: result = Key_Home
+ of VK_LEFT: result = Key_Left
+ of VK_UP: result = Key_Up
+ of VK_RIGHT: result = Key_Right
+ of VK_DOWN: result = Key_Down
+ of VK_INSERT: result = Key_Insert
+ of VK_DELETE: result = Key_Delete
+ of VK_OEM_5: result = Key_Circumflex
+ else: result = cast[Key](cast[int32](wParam).unicodeToUpper)
+
proc pHandleWMKEYDOWNOrWMCHAR(window: Window, control: Control, unicode: int): bool =
+ internalKeyDown(pKeyDownKey)
+
var windowEvent = new KeyboardEvent
windowEvent.window = window
windowEvent.key = pKeyDownKey
@@ -262,17 +289,17 @@ proc pHandleWMKEYDOWNOrWMCHAR(window: Window, control: Control, unicode: int): b
proc pHandleWMKEYDOWN(window: Window, control: Control, wParam, lParam: pointer): bool =
if not GetKeyboardState(pKeyState): pRaiseLastOSError()
+
+ pKeyDownKey = pWMParamsToKey(wParam, lParam)
# 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 = (cast[int32](lParam) and 0x00FF0000) shr 16
- pKeyDownKey = pVirtualKeyToKey(cast[int32](wParam), scancode)
- if cast[int](wParam) == VK_OEM_5:
+
+ if pKeyDownKey != Key_Circumflex:
# When the dead key "^" on German keyboard is pressed, don't call ToUnicode(), because this would destroy the dead key state
- 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
+ let scancode = (cast[int32](lParam) and 0x00FF0000) shr 16
+ var widestring = newString(2)
+ 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)
proc pHandleWMCHAR(window: Window, control: Control, wParam, lParam: pointer): bool =
@@ -324,6 +351,8 @@ proc pWindowWndProc(hWnd: pointer, uMsg: int32, wParam, lParam: pointer): pointe
let window = cast[Window](pGetWindowLongPtr(hWnd, GWLP_USERDATA))
if window != nil and pHandleWMKEYDOWN(window, nil, wParam, lParam):
return
+ of WM_KEYUP:
+ internalKeyUp(pWMParamsToKey(wParam, lParam))
of WM_CHAR:
let window = cast[Window](pGetWindowLongPtr(hWnd, GWLP_USERDATA))
if window != nil and pHandleWMCHAR(window, nil, wParam, lParam):
@@ -1044,6 +1073,9 @@ proc pCommonControlWndProc(hWnd: pointer, uMsg: int32, wParam, lParam: pointer):
if control != nil and pHandleWMKEYDOWN(control.parentWindow, control, wParam, lParam):
return PWndProcResult_False
+ of WM_KEYUP:
+ internalKeyUp(pWMParamsToKey(wParam, lParam))
+
of WM_CHAR:
let control = cast[Control](pGetWindowLongPtr(hWnd, GWLP_USERDATA))
if control != nil and pHandleWMCHAR(control.parentWindow, control, wParam, lParam):