Skip to content

Commit

Permalink
Merge pull request #14 from guzba/master
Browse files Browse the repository at this point in the history
mouse move, scroll
  • Loading branch information
treeform authored Oct 21, 2021
2 parents 1c91d59 + 1b815ae commit fd11430
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 12 deletions.
8 changes: 8 additions & 0 deletions examples/callbacks.nim
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ window.onResize = proc() =
window.onFocusChange = proc() =
echo "onFocusChange ", window.focused

window.onMouseMove = proc() =
echo "onMouseMove from ",
window.mousePrevPos, " to ", window.mousePos,
" (delta ", window.mouseDelta, ")"

window.onScroll = proc(delta: Vec2) =
echo "onScroll ", delta

window.visible = true

while running:
Expand Down
6 changes: 6 additions & 0 deletions src/windy/common.nim
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import vmath

type
WindyError* = object of ValueError

MSAA* = enum
msaaDisabled = 0, msaa2x = 2, msaa4x = 4, msaa8x = 8

Callback* = proc()
ScrollCallback* = proc(delta: Vec2)

Mouse* = object
pos*, prevPos*, delta*: IVec2
70 changes: 58 additions & 12 deletions src/windy/platforms/win32/platform.nim
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import ../../common, utils, vmath, windefs
const
windowClassName = "WINDY0"
defaultScreenDpi = 96
wheelDelta = 120
decoratedWindowStyle = WS_OVERLAPPEDWINDOW
undecoratedWindowStyle = WS_POPUP

Expand Down Expand Up @@ -33,6 +34,11 @@ type
onMove*: Callback
onResize*: Callback
onFocusChange*: Callback
onMouseMove*: Callback
onScroll*: ScrollCallback

mouse: Mouse
trackMouseEventRegistered: bool

hWnd: HWND
hdc: HDC
Expand Down Expand Up @@ -266,14 +272,6 @@ proc loadLibraries() =
GetProcAddress(user32, "AdjustWindowRectExForDpi")
)

proc callCallback(name: string, callback: Callback) {.raises: [].} =
if callback == nil:
return
try:
callback()
except:
quit("Exception during " & name & " callback: " & getCurrentExceptionMsg())

proc wndProc(
hWnd: HWND,
uMsg: UINT,
Expand All @@ -294,16 +292,20 @@ proc wndProc(

case uMsg:
of WM_CLOSE:
callCallback("onCloseRequest", window.onCloseRequest)
if window.onCloseRequest != nil:
window.onCloseRequest()
return 0
of WM_MOVE:
callCallback("onMove", window.onMove)
if window.onMove != nil:
window.onMove()
return 0
of WM_SIZE:
callCallback("onResize", window.onResize)
if window.onResize != nil:
window.onResize()
return 0
of WM_SETFOCUS, WM_KILLFOCUS:
callCallback("onFocusChange", window.onFocusChange)
if window.onFocusChange != nil:
window.onFocusChange()
return 0
of WM_DPICHANGED:
# Resize to the suggested size (this triggers WM_SIZE)
Expand All @@ -318,6 +320,41 @@ proc wndProc(
SWP_NOACTIVATE or SWP_NOZORDER
)
return 0
of WM_MOUSEMOVE:
if not window.trackMouseEventRegistered:
var tme: TRACKMOUSEEVENTSTRUCT
tme.cbSize = sizeof(TRACKMOUSEEVENTSTRUCT).DWORD
tme.dwFlags = TME_LEAVE
tme.hWndTrack = window.hWnd
discard TrackMouseEvent(tme.addr)
window.trackMouseEventRegistered = true

window.mouse.prevPos = window.mouse.pos
var pos: POINT
discard GetCursorPos(pos.addr)
discard ScreenToClient(window.hWnd, pos.addr)
window.mouse.pos = ivec2(pos.x, pos.y)
window.mouse.delta = window.mouse.pos - window.mouse.prevPos
if window.onMouseMove != nil:
window.onMouseMove()
return 0
of WM_MOUSELEAVE:
window.trackMouseEventRegistered = false
return 0
of WM_MOUSEWHEEL:
let
hiword = cast[int16]((wParam shr 16))
delta = vec2(0, hiword.float32 / wheelDelta)
if window.onScroll != nil:
window.onScroll(delta)
return 0
of WM_MOUSEHWHEEL:
let
hiword = cast[int16]((wParam shr 16))
delta = vec2(hiword.float32 / wheelDelta, 0)
if window.onScroll != nil:
window.onScroll(delta)
return 0
else:
discard

Expand Down Expand Up @@ -493,6 +530,15 @@ proc contentScale*(window: Window): float32 =
proc focused*(window: Window): bool =
window.hWnd == GetActiveWindow()

proc mousePos*(window: Window): IVec2 =
window.mouse.pos

proc mousePrevPos*(window: Window): IVec2 =
window.mouse.prevPos

proc mouseDelta*(window: Window): IVec2 =
window.mouse.delta

proc `decorated=`*(window: Window, decorated: bool) =
var style: LONG
if decorated:
Expand Down
8 changes: 8 additions & 0 deletions src/windy/platforms/win32/utils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -85,5 +85,13 @@ proc wmEventName*(wm: int | UINT): string =
"WM_DPICHANGED"
of WM_NULL:
"WM_NULL"
of WM_MOUSEMOVE:
"WM_MOUSEMOVE"
of WM_MOUSEWHEEL:
"WM_MOUSEWHEEL"
of WM_MOUSEHWHEEL:
"WM_MOUSEHWHEEL"
of WM_MOUSELEAVE:
"WM_MOUSELEAVE"
else:
"WM " & $wm & " " & $toHex(wm)
28 changes: 28 additions & 0 deletions src/windy/platforms/win32/windefs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ type
ptMinPosition*: POINT
ptMaxPosition*: POINT
rcNormalPosition*: RECT
TRACKMOUSEEVENTSTRUCT* {.pure.} = object
cbSize*: DWORD
dwFlags*: DWORD
hWndTrack*: HWND
dwHoverTime*: DWORD
LPTRACKMOUSEEVENTSTRUCT* = ptr TRACKMOUSEEVENTSTRUCT

type
wglCreateContext* = proc(hdc: HDC): HGLRC {.stdcall, raises: [].}
Expand Down Expand Up @@ -209,6 +215,9 @@ const
WM_NCCALCSIZE* = 0x0083
WM_NCPAINT* = 0x0085
WM_NCACTIVATE* = 0x0086
WM_MOUSEMOVE* = 0x0200
WM_MOUSEWHEEL* = 0x020A
WM_MOUSEHWHEEL* = 0x020E
WM_IME_SETCONTEXT* = 0x0281
WM_IME_NOTIFY* = 0x0282
WM_IME_CONTROL* = 0x0283
Expand All @@ -218,6 +227,7 @@ const
WM_IME_REQUEST* = 0x0288
WM_IME_KEYDOWN* = 0x0290
WM_IME_KEYUP* = 0x0291
WM_MOUSELEAVE* = 0x02A3
WM_DPICHANGED* = 0x02E0
WM_DWMCOMPOSITIONCHANGED* = 0x031e
WM_DWMNCRENDERINGCHANGED* = 0x031f
Expand Down Expand Up @@ -280,6 +290,11 @@ const
MONITOR_DEFAULTTONULL* = 0x00000000
MONITOR_DEFAULTTOPRIMARY* = 0x00000001
MONITOR_DEFAULTTONEAREST* = 0x00000002
TME_HOVER* = 0x00000001
TME_LEAVE* = 0x00000002
TME_NONCLIENT* = 0x00000010
TME_QUERY* = 0x40000000
TME_CANCEL* = 0x80000000'i32

proc GetLastError*(): DWORD {.importc, stdcall, dynlib: "Kernel32".}

Expand Down Expand Up @@ -446,6 +461,11 @@ proc ClientToScreen*(
lpPoint: LPPOINT
): BOOL {.importc, stdcall, dynlib: "User32".}

proc ScreenToClient*(
hWnd: HWND,
lpPoint: LPPOINT
): BOOL {.importc, stdcall, dynlib: "User32".}

proc SetPropW*(
hWnd: HWND,
lpString: LPCWSTR,
Expand All @@ -466,6 +486,14 @@ proc IsIconic*(hWnd: HWND): BOOL {.importc, stdcall, dynlib: "User32".}

proc IsZoomed*(hWnd: HWND): BOOL {.importc, stdcall, dynlib: "User32".}

proc GetCursorPos*(
lpPoint: LPPOINT
): BOOL {.importc, stdcall, dynlib: "User32".}

proc TrackMouseEvent*(
lpEventTrack: LPTRACKMOUSEEVENTSTRUCT
): BOOL {.importc, stdcall, dynlib: "User32".}

proc ChoosePixelFormat*(
hdc: HDC,
ppfd: ptr PIXELFORMATDESCRIPTOR
Expand Down

0 comments on commit fd11430

Please sign in to comment.