summary refs log tree commit diff stats
path: root/tests/manyloc/keineschweine/lib/input_helpers.nim
diff options
context:
space:
mode:
Diffstat (limited to 'tests/manyloc/keineschweine/lib/input_helpers.nim')
-rw-r--r--tests/manyloc/keineschweine/lib/input_helpers.nim138
1 files changed, 138 insertions, 0 deletions
diff --git a/tests/manyloc/keineschweine/lib/input_helpers.nim b/tests/manyloc/keineschweine/lib/input_helpers.nim
new file mode 100644
index 000000000..ff1286c8d
--- /dev/null
+++ b/tests/manyloc/keineschweine/lib/input_helpers.nim
@@ -0,0 +1,138 @@
+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)