1 /**
  2  * The Render Engine
  3  * KeyboardInputComponent
  4  *
  5  * @fileoverview An extension of the input component for dealing with the
  6  *               keyboard.
  7  *
  8  * @author: Brett Fattori (brettf@renderengine.com)
  9  * @author: $Author: bfattori $
 10  * @version: $Revision: 1555 $
 11  *
 12  * Copyright (c) 2011 Brett Fattori (brettf@renderengine.com)
 13  *
 14  * Permission is hereby granted, free of charge, to any person obtaining a copy
 15  * of this software and associated documentation files (the "Software"), to deal
 16  * in the Software without restriction, including without limitation the rights
 17  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 18  * copies of the Software, and to permit persons to whom the Software is
 19  * furnished to do so, subject to the following conditions:
 20  *
 21  * The above copyright notice and this permission notice shall be included in
 22  * all copies or substantial portions of the Software.
 23  *
 24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 25  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 26  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 27  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 28  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 29  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 30  * THE SOFTWARE.
 31  *
 32  */
 33 
 34 // The class this file defines and its required classes
 35 R.Engine.define({
 36     "class":"R.components.input.Keyboard",
 37     "requires":[
 38         "R.components.Input",
 39         "R.engine.Events"
 40     ]
 41 });
 42 
 43 /**
 44  * @class A component which responds to keyboard events and notifies
 45  * its {@link R.engine.GameObject} when one of the events occurs.  The <tt>R.engine.GameObject</tt>
 46  * should add event handlers for any of the following:
 47  * <ul>
 48  * <li><tt>keydown</tt> - A key was pressed down</li>
 49  * <li><tt>keyup</tt> - A key was released</li>
 50  * <li><tt>keypress</tt> - A key was pressed and released</li>
 51  * </ul>
 52  * Each event handler will be passed six arguments.  The first argument is the event object.
 53  * The second argument is the character code, a number which represents the key that was pressed.
 54  * The third argument is the <tt>keyCode</tt>, a number which represents special keys that were
 55  * pressed, such as the arrow keys and function keys.  See {@link R.engine.Events} for key codes of
 56  * the non-alphabetic keys. The fourth, fifth, and sixth arguments are boolean flags indicating if
 57  * the Control, Alt, or Shift keys, respectively, were pressed.
 58  *
 59  * @param name {String} The unique name of the component.
 60  * @param priority {Number} The priority of the component among other input components.
 61  * @extends R.components.Input
 62  * @constructor
 63  * @description Create an instance of a keyboard input component.
 64  */
 65 R.components.input.Keyboard = function () {
 66     "use strict";
 67     return R.components.Input.extend(/** @scope R.components.input.Keyboard.prototype */{
 68 
 69         /**
 70          * @private
 71          */
 72         constructor:function (name, priority) {
 73             this.base(name, priority);
 74 
 75             // Add the event handlers
 76             var ctx = R.Engine.getDefaultContext(), self = this;
 77             ctx.addEvent("keydown", function (evt) {
 78                 return self._keyDownListener(evt);
 79             });
 80 
 81             ctx.addEvent("keyup", function (evt) {
 82                 return self._keyUpListener(evt);
 83             });
 84 
 85             ctx.addEvent("keypress", function (evt) {
 86                 return self._keyPressListener(evt);
 87             });
 88         },
 89 
 90         /**
 91          * Destroy this instance and remove all references.
 92          * @private
 93          */
 94         destroy:function () {
 95             var ctx = R.Engine.getDefaultContext();
 96 
 97             // Clean up event handlers
 98             ctx.removeEvent("keydown");
 99             ctx.removeEvent("keyup");
100             ctx.removeEvent("keypress");
101 
102             this.base();
103         },
104 
105         release:function () {
106             this.base();
107             this.hasInputMethods = null;
108         },
109 
110         /**
111          * Deprecated in favor of {@link #setGameObject}
112          * @deprecated
113          */
114         setHostObject:function (hostObj) {
115             this.setGameObject(hostObj);
116         },
117 
118         /** @private */
119         playEvent:function (e) {
120             var evt = document.createEvent("KeyboardEvent");
121             evt.initKeyEvent(e.type, true, false, null, e.ctrlKey, false, e.shiftKey, false, e.keyCode, 0);
122             R.Engine.getDefaultContext().getSurface().dispatchEvent(evt);
123         },
124 
125         /** @private */
126         _keyDownListener:function (eventObj) {
127             this.record(eventObj, R.components.input.Keyboard.RECORD_PART);
128             return this.getGameObject().triggerEvent("keydown", eventObj, [eventObj.which, eventObj.keyCode, eventObj.ctrlKey, eventObj.altKey, eventObj.shiftKey]);
129         },
130 
131         /** @private */
132         _keyUpListener:function (eventObj) {
133             this.record(eventObj, R.components.input.Keyboard.RECORD_PART);
134             return this.getGameObject().triggerEvent("keyup", eventObj, [eventObj.which, eventObj.keyCode, eventObj.ctrlKey, eventObj.altKey, eventObj.shiftKey]);
135         },
136 
137         /** @private */
138         _keyPressListener:function (eventObj) {
139             this.record(eventObj, R.components.input.Keyboard.RECORD_PART);
140             return this.getGameObject().triggerEvent("keypress", eventObj, [eventObj.which, eventObj.keyCode, eventObj.ctrlKey, eventObj.altKey, eventObj.shiftKey]);
141         }
142 
143     }, /** @scope R.components.input.Keyboard.prototype */{
144         /**
145          * Get the class name of this object
146          *
147          * @return {String} "R.components.input.Keyboard"
148          */
149         getClassName:function () {
150             return "R.components.input.Keyboard";
151         },
152 
153         /** @private */
154         RECORD_PART:["shiftKey", "ctrlKey", "altKey", "keyCode"]
155     });
156 };