-
Notifications
You must be signed in to change notification settings - Fork 0
/
glfwinput.nim
107 lines (98 loc) · 2.77 KB
/
glfwinput.nim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
from input import nil
import glfw/glfw
import glfw/wrapper
import tables
import logging
import hashes
var winDat = initTable[PWin, ptr input.TInputMapping]()
proc hash(wnd: PWin): THash =
#the handle member is not exported
#and we need a unique identifier for
#each window, we are just extracting
#that handle pointer here, in the most
#insane way possible
hash(cast[ptr pointer](wnd)[])
proc `$`(wnd: PWin): string =
result = $cast[int](cast[ptr pointer](wnd)[])
proc getKey(k: glfw.TKey): input.TKey =
case k
of glfw.keyUnknown: return input.keyUnknown
of glfw.keyA..glfw.KeyZ:
var intVal = cast[int](k)
const keyAVal = glfw.keyA.int
const inputKeyAVal = input.keyA.int
return cast[input.TKey]((intVal - keyAVal) + inputKeyAVal)
of glfw.keyLeftShift:
return input.keyLeftShift
else:
return input.keyUnknown
proc keyCb(o: PWin; key: glfw.TKey; scanCode: int; action: TKeyAction;
modKeys: TModifierKeySet) =
#this line is batshit, since PWin.handle
#is not exported and we need the user pointer
#we exploit the fact that the first member
#of PWin is a GLFWwindow* and use this
#to cast. OOP bitches
if not winDat.hasKey(o):
return
var winData = winDat[o]
if winData == nil:
return
var inputkey = getKey(key)
if inputkey != input.keyUnknown:
if action == kaDown: input.ActivateKey(winData[], inputKey)
if action == kaUp: input.DeactivateKey(winData[], inputKey)
else:
info("Unknown key: " & $key)
var lastX: float64
var lastY: float64
var justEntered: bool = false
proc handleMouse*(wnd: PWin) =
if not winDat.hasKey(wnd):
return
var winData = winDat[wnd]
if winData == nil:
return
var pos = wnd.cursorPos()
var size = wnd.size()
var dx = pos.x - lastX
var dy = pos.y - lastY
lastX = pos.x
lastY = pos.y
proc cursorEnterCb(self: PWin, entered: bool) =
if entered:
var (x,y) = self.cursorPos
lastX = x
lastY = y
justEntered = true
proc closeCb(wnd: PWin) =
winDat.del(wnd)
proc AttachInput*(wnd: PWin) =
wnd.cursorEnterCb = cursorEnterCb
proc pollKeyboard*(self: PWin): input.TKeyCombination =
for elm in glfw.TKey:
if self.isKeyDown(elm):
result.incl(getKey(elm))
else:
result.excl(getKey(elm))
proc pollMouse*(self: PWin): input.TMouse =
var (x,y) = self.cursorPos
result.x = x
result.y = y
if self.mouseBtnDown(glfw.mbLeft):
result.buttons.incl(input.mbLeft)
if self.mouseBtnDown(glfw.mbRight):
result.buttons.incl(input.mbRight)
var dx = result.x - lastx
var dy = result.y - lasty
if justEntered:
justEntered = false
dx = 0
dy = 0
lastx = result.x
lasty = result.y
result.dx = dx
result.dy = dy
proc pollInput*(self: PWin): input.TInput =
result.keyboard = pollKeyboard(self)
result.mouse = pollMouse(self)