@@ -0,0 +1,123 @@
2+Elm.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])];
12+ while (xs[0] !== "Nil") {
13+ if (xs[1] === x) return true;
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]);
22+ this.removeEventListener('keydown',arguments.callee,false);
24+ Value.addListener(document, 'keyup', function(e) {
25+ var codes = remove(e.keyCode, keysDown.value);
26+ var hasListener = Dispatcher.notify(keysDown.id, codes);
28+ this.removeEventListener('keyup',arguments.callee,false);
30+ Value.addListener(window, 'blur', function(e) {
31+ var hasListener = Dispatcher.notify(keysDown.id, ["Nil"]);
33+ this.removeEventListener('blur',arguments.callee,false);
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"]);
39+ this.removeEventListener('keypress',arguments.callee,false);
41+ return {keysDown:keysDown,
42+ charPressed:charPressed};
47+These are nicely curated inputs from the keyboard. See the
48+[Keyboard.Raw library](/docs/Signal/KeyboardRaw.elm) for a
49+lower-level interface that will let you define more complicated behavior.
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;
60+ function dir(left,right,up,down) {
63+ while (ks[0] == "Cons") {
65+ case left : --x; break;
66+ case right: ++x; break;
67+ case up : ++y; break;
68+ case down : --y; break;
72+ return { _:[true], x:[x], y:[y] };
79+ while (ks[0] == "Cons") {
80+ if (key == ks[1]) return true;
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.
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.
104+ Elm.Keyboard.wasd = dir(65,68,87,83);
108+ /** shift : Signal Bool
109+ Whether the shift key is pressed.
111+ Elm.Keyboard.shift = is(16);
113+ /** ctrl : Signal Bool
114+ Whether the control key is pressed.
116+ Elm.Keyboard.ctrl = is(17);
118+ /** space : Signal Bool
119+ Whether the space key is pressed.
121+ Elm.Keyboard.space = is(32);