123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- import
- sfml, tables, hashes
- type
- TKeyEventKind* = enum down, up
- TInputFinishedProc* = proc()
- TKeyCallback = proc()
- PKeyClient* = ref object
- onKeyDown: Table[int32, TKeyCallback]
- onKeyUp: Table[int32, TKeyCallback]
- name: string
- PTextInput* = ref object
- text*: string
- cursor: int
- onEnter: TInputFinishedProc
- var
- keyState: array[-MouseButtonCount.int32 .. KeyCount.int32, bool]
- mousePos: TVector2f
- activeClient: PKeyClient = nil
- activeInput: PTextInput = nil
- proc setActive*(client: PKeyClient) =
- activeClient = client
- echo("** set active client ", client.name)
- proc newKeyClient*(name: string = "unnamed", setactive = false): PKeyClient =
- new(result)
- result.onKeyDown = initTable[int32, TKeyCallback](16)
- result.onKeyUp = initTable[int32, TKeyCallback](16)
- result.name = name
- if setActive:
- setActive(result)
- proc keyPressed*(key: TKeyCode): bool {.inline.} =
- return keyState[key.int32]
- proc buttonPressed*(btn: TMouseButton): bool {.inline.} =
- return keyState[-btn.int32]
- proc clearKey*(key: TKeyCode) {.inline.} =
- keyState[key.int32] = false
- proc clearButton*(btn: TMouseButton) {.inline.} =
- keyState[-btn.int32] = false
- proc addKeyEvent*(key: TKeyCode, ev: TKeyEventKind) {.inline.} =
- if activeClient.isNil: return
- let k = key.int32
- case ev
- of down:
- keyState[k] = true
- if activeClient.onKeyDown.hasKey(k):
- activeClient.onKeyDown[k]()
- else:
- keyState[k] = false
- if activeClient.onKeyUp.hasKey(k):
- activeClient.onKeyUp[k]()
- proc addButtonEvent*(btn: TMouseButton, ev: TKeyEventKind) {.inline.} =
- if activeClient.isNil: return
- let b = -btn.int32
- case ev
- of down:
- keyState[b] = true
- if activeClient.onKeyDown.hasKey(b):
- activeClient.onKeyDown[b]()
- else:
- keyState[b] = false
- if activeClient.onKeyUp.hasKey(b):
- activeClient.onKeyUp[b]()
- proc registerHandler*(client: PKeyClient; key: TKeyCode;
- ev: TKeyEventKind; fn: TKeyCallback) =
- case ev
- of down: client.onKeyDown[key.int32] = fn
- of up: client.onKeyUp[key.int32] = fn
- proc registerHandler*(client: PKeyClient; btn: TMouseButton;
- ev: TKeyEventKind; fn: TKeyCallback) =
- case ev
- of down: client.onKeyDown[-btn.int32] = fn
- of up: client.onKeyUp[-btn.int32] = fn
- proc newTextInput*(text = "", pos = 0, onEnter: TInputFinishedProc = nil): PTextInput =
- new(result)
- result.text = text
- result.cursor = pos
- result.onEnter = onEnter
- proc setActive*(i: PTextInput) =
- activeInput = i
- proc stopCapturingText*() =
- activeInput = nil
- proc clear*(i: PTextInput) =
- i.text.setLen 0
- i.cursor = 0
- proc recordText*(i: PTextInput; c: cint) =
- if c > 127 or i.isNil: return
- if c in 32..126: ##printable
- if i.cursor == i.text.len: i.text.add(c.int.chr)
- else:
- let rem = i.text.substr(i.cursor)
- i.text.setLen(i.cursor)
- i.text.add(chr(c.int))
- i.text.add(rem)
- inc(i.cursor)
- elif c == 8: ## \b backspace
- if i.text.len > 0 and i.cursor > 0:
- dec(i.cursor)
- let rem = i.text.substr(i.cursor + 1)
- i.text.setLen(i.cursor)
- i.text.add(rem)
- elif c == 10 or c == 13:## \n, \r enter
- if not i.onEnter.isNil: i.onEnter()
- proc recordText*(i: PTextInput; e: TTextEvent) {.inline.} =
- recordText(i, e.unicode)
- proc setMousePos*(x, y: cint) {.inline.} =
- mousePos.x = x.float
- mousePos.y = y.float
- proc getMousePos*(): TVector2f {.inline.} = result = mousePos
- var event: TEvent
- # Handle and filter input-related events
- iterator filterEvents*(window: PRenderWindow): PEvent =
- while window.pollEvent(addr event):
- case event.kind
- of EvtKeyPressed: addKeyEvent(event.key.code, down)
- of EvtKeyReleased: addKeyEvent(event.key.code, up)
- of EvtMouseButtonPressed: addButtonEvent(event.mouseButton.button, down)
- of EvtMouseButtonReleased: addButtonEvent(event.mouseButton.button, up)
- of EvtTextEntered: recordText(activeInput, event.text)
- of EvtMouseMoved: setMousePos(event.mouseMove.x, event.mouseMove.y)
- else: yield(addr event)
- # Handle and return input-related events
- iterator pollEvents*(window: PRenderWindow): PEvent =
- while window.pollEvent(addr event):
- case event.kind
- of EvtKeyPressed: addKeyEvent(event.key.code, down)
- of EvtKeyReleased: addKeyEvent(event.key.code, up)
- of EvtMouseButtonPressed: addButtonEvent(event.mouseButton.button, down)
- of EvtMouseButtonReleased: addButtonEvent(event.mouseButton.button, up)
- of EvtTextEntered: recordText(activeInput, event.text)
- of EvtMouseMoved: setMousePos(event.mouseMove.x, event.mouseMove.y)
- else: discard
- yield(addr event)
|