on 54ffaab help sign in
elk/core/Native/Keyboard.js
123 lines 3.4 kB history raw
2Elm.Keyboard = { Raw : function() {
3 var keysDown = Elm.Signal.constant(["Nil"]);
4 var charPressed = Elm.Signal.constant(["Nothing"]);
6 function remove(x,xs) {
7 if (xs[0] === "Nil") return xs;
8 if (xs[1] === x) return xs[2];
9 return ["Cons", xs[1], remove(x,xs[2])];
10 }
11 function has(x,xs) {
12 while (xs[0] !== "Nil") {
13 if (xs[1] === x) return true;
14 xs = xs[2];
15 }
16 return false;
17 }
18 Value.addListener(document, 'keydown', function(e) {
19 if (has(e.keyCode, keysDown.value)) return;
20 var hasListener = Dispatcher.notify(keysDown.id, ["Cons", e.keyCode, keysDown.value]);
21 if (!hasListener)
22 this.removeEventListener('keydown',arguments.callee,false);
23 });
24 Value.addListener(document, 'keyup', function(e) {
25 var codes = remove(e.keyCode, keysDown.value);
26 var hasListener = Dispatcher.notify(keysDown.id, codes);
27 if (!hasListener)
28 this.removeEventListener('keyup',arguments.callee,false);
29 });
30 Value.addListener(window, 'blur', function(e) {
31 var hasListener = Dispatcher.notify(keysDown.id, ["Nil"]);
32 if (!hasListener)
33 this.removeEventListener('blur',arguments.callee,false);
34 });
35 Value.addListener(document, 'keypress', function(e) {
36 var hasListener = Dispatcher.notify(charPressed.id, ["Just",e.charCode || e.keyCode]);
37 Dispatcher.notify(charPressed.id, ["Nothing"]);
38 if (!hasListener)
39 this.removeEventListener('keypress',arguments.callee,false);
40 });
41 return {keysDown:keysDown,
42 charPressed:charPressed};
43 }()
44};
46/*! Keyboard
47These are nicely curated inputs from the keyboard. See the
48[Keyboard.Raw library](/docs/Signal/KeyboardRaw.elm) for a
49lower-level interface that will let you define more complicated behavior.
50!*/
52(function() {
53 function keySignal(f) {
54 var signal = Elm.Signal.lift(f)(Elm.Keyboard.Raw.keysDown);
55 Elm.Keyboard.Raw.keysDown.defaultNumberOfKids += 1;
56 signal.defaultNumberOfKids = 0;
57 return signal;
58 }
60 function dir(left,right,up,down) {
61 function f(ks) {
62 var x = 0, y = 0;
63 while (ks[0] == "Cons") {
64 switch (ks[1]) {
65 case left : --x; break;
66 case right: ++x; break;
67 case up : ++y; break;
68 case down : --y; break;
69 }
70 ks = ks[2];
71 }
72 return { _:[true], x:[x], y:[y] };
73 }
74 return keySignal(f);
75 }
77 function is(key) {
78 function f(ks) {
79 while (ks[0] == "Cons") {
80 if (key == ks[1]) return true;
81 ks = ks[2];
82 }
83 return false;
84 }
85 return keySignal(f);
86 }
88 /*[Directions]*/
90 /** arrows : Signal { x:Int, y:Int }
91 A signal of records indicating which arrow keys are pressed.
93 `{ x = 0, y = 0 }` when pressing no arrows.
94 `{ x =-1, y = 0 }` when pressing the left arrow.
95 `{ x = 1, y = 1 }` when pressing the up and right arrows.
96 `{ x = 0, y =-1 }` when pressing the down, left, and right arrows.
97 **/
98 Elm.Keyboard.arrows = dir(37,39,38,40);
100 /** wasd : Signal { x:Int, y:Int }
101 Just like the arrows signal, but this uses keys w, a, s, and d,
102 which are common controls for many computer games.
103 **/
104 Elm.Keyboard.wasd = dir(65,68,87,83);
106 /*[Modifiers]*/
108 /** shift : Signal Bool
109 Whether the shift key is pressed.
110 **/
111 Elm.Keyboard.shift = is(16);
113 /** ctrl : Signal Bool
114 Whether the control key is pressed.
115 **/
116 Elm.Keyboard.ctrl = is(17);
118 /** space : Signal Bool
119 Whether the space key is pressed.
120 **/
121 Elm.Keyboard.space = is(32);
123}());