Mercurial > laserkard
comparison onlypaths/js/ext/keymap.js @ 46:26c2b3ad21c7 laserkard
[svn r47] saving progresswww.cinemassacre.com/new/?page_id=30
author | rlm |
---|---|
date | Sun, 31 Jan 2010 12:33:33 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
45:bff96abdddfa | 46:26c2b3ad21c7 |
---|---|
1 /** | |
2 * @class Ext.KeyMap | |
3 * Handles mapping keys to actions for an element. One key map can be used for multiple actions. | |
4 * The constructor accepts the same config object as defined by {@link #addBinding}. | |
5 * If you bind a callback function to a KeyMap, anytime the KeyMap handles an expected key | |
6 * combination it will call the function with this signature (if the match is a multi-key | |
7 * combination the callback will still be called only once): (String key, Ext.EventObject e) | |
8 * A KeyMap can also handle a string representation of keys.<br /> | |
9 * Usage: | |
10 <pre><code> | |
11 // map one key by key code | |
12 var map = new Ext.KeyMap("my-element", { | |
13 key: 13, // or Ext.EventObject.ENTER | |
14 fn: myHandler, | |
15 scope: myObject | |
16 }); | |
17 | |
18 // map multiple keys to one action by string | |
19 var map = new Ext.KeyMap("my-element", { | |
20 key: "a\r\n\t", | |
21 fn: myHandler, | |
22 scope: myObject | |
23 }); | |
24 | |
25 // map multiple keys to multiple actions by strings and array of codes | |
26 var map = new Ext.KeyMap("my-element", [ | |
27 { | |
28 key: [10,13], | |
29 fn: function(){ alert("Return was pressed"); } | |
30 }, { | |
31 key: "abc", | |
32 fn: function(){ alert('a, b or c was pressed'); } | |
33 }, { | |
34 key: "\t", | |
35 ctrl:true, | |
36 shift:true, | |
37 fn: function(){ alert('Control + shift + tab was pressed.'); } | |
38 } | |
39 ]); | |
40 </code></pre> | |
41 * <b>Note: A KeyMap starts enabled</b> | |
42 * @constructor | |
43 * @param {String/HTMLElement/Ext.Element} el The element to bind to | |
44 * @param {Object} config The config (see {@link #addBinding}) | |
45 * @param {String} eventName (optional) The event to bind to (defaults to "keydown") | |
46 */ | |
47 Ext.KeyMap = function(el, config, eventName){ | |
48 this.el = Ext.get(el); | |
49 this.eventName = eventName || "keydown"; | |
50 this.bindings = []; | |
51 if(config){ | |
52 this.addBinding(config); | |
53 } | |
54 this.enable(); | |
55 }; | |
56 | |
57 Ext.KeyMap.prototype = { | |
58 /** | |
59 * True to stop the event from bubbling and prevent the default browser action if the | |
60 * key was handled by the KeyMap (defaults to false) | |
61 * @type Boolean | |
62 */ | |
63 stopEvent : false, | |
64 | |
65 /** | |
66 * Add a new binding to this KeyMap. The following config object properties are supported: | |
67 * <pre> | |
68 Property Type Description | |
69 ---------- --------------- ---------------------------------------------------------------------- | |
70 key String/Array A single keycode or an array of keycodes to handle | |
71 shift Boolean True to handle key only when shift is pressed (defaults to false) | |
72 ctrl Boolean True to handle key only when ctrl is pressed (defaults to false) | |
73 alt Boolean True to handle key only when alt is pressed (defaults to false) | |
74 fn Function The function to call when KeyMap finds the expected key combination | |
75 scope Object The scope of the callback function | |
76 </pre> | |
77 * | |
78 * Usage: | |
79 * <pre><code> | |
80 // Create a KeyMap | |
81 var map = new Ext.KeyMap(document, { | |
82 key: Ext.EventObject.ENTER, | |
83 fn: handleKey, | |
84 scope: this | |
85 }); | |
86 | |
87 //Add a new binding to the existing KeyMap later | |
88 map.addBinding({ | |
89 key: 'abc', | |
90 shift: true, | |
91 fn: handleKey, | |
92 scope: this | |
93 }); | |
94 </code></pre> | |
95 * @param {Object/Array} config A single KeyMap config or an array of configs | |
96 */ | |
97 addBinding : function(config){ | |
98 if(config instanceof Array){ | |
99 for(var i = 0, len = config.length; i < len; i++){ | |
100 this.addBinding(config[i]); | |
101 } | |
102 return; | |
103 } | |
104 var keyCode = config.key, | |
105 shift = config.shift, | |
106 ctrl = config.ctrl, | |
107 alt = config.alt, | |
108 fn = config.fn, | |
109 scope = config.scope; | |
110 if(typeof keyCode == "string"){ | |
111 var ks = []; | |
112 var keyString = keyCode.toUpperCase(); | |
113 for(var j = 0, len = keyString.length; j < len; j++){ | |
114 ks.push(keyString.charCodeAt(j)); | |
115 } | |
116 keyCode = ks; | |
117 } | |
118 var keyArray = keyCode instanceof Array; | |
119 var handler = function(e){ | |
120 if((!shift || e.shiftKey) && (!ctrl || e.ctrlKey) && (!alt || e.altKey)){ | |
121 var k = e.getKey(); | |
122 if(keyArray){ | |
123 for(var i = 0, len = keyCode.length; i < len; i++){ | |
124 if(keyCode[i] == k){ | |
125 if(this.stopEvent){ | |
126 e.stopEvent(); | |
127 } | |
128 fn.call(scope || window, k, e); | |
129 return; | |
130 } | |
131 } | |
132 }else{ | |
133 if(k == keyCode){ | |
134 if(this.stopEvent){ | |
135 e.stopEvent(); | |
136 } | |
137 fn.call(scope || window, k, e); | |
138 } | |
139 } | |
140 } | |
141 }; | |
142 this.bindings.push(handler); | |
143 }, | |
144 | |
145 /** | |
146 * Shorthand for adding a single key listener | |
147 * @param {Number/Array/Object} key Either the numeric key code, array of key codes or an object with the | |
148 * following options: | |
149 * {key: (number or array), shift: (true/false), ctrl: (true/false), alt: (true/false)} | |
150 * @param {Function} fn The function to call | |
151 * @param {Object} scope (optional) The scope of the function | |
152 */ | |
153 on : function(key, fn, scope){ | |
154 var keyCode, shift, ctrl, alt; | |
155 if(typeof key == "object" && !(key instanceof Array)){ | |
156 keyCode = key.key; | |
157 shift = key.shift; | |
158 ctrl = key.ctrl; | |
159 alt = key.alt; | |
160 }else{ | |
161 keyCode = key; | |
162 } | |
163 this.addBinding({ | |
164 key: keyCode, | |
165 shift: shift, | |
166 ctrl: ctrl, | |
167 alt: alt, | |
168 fn: fn, | |
169 scope: scope | |
170 }) | |
171 }, | |
172 | |
173 // private | |
174 handleKeyDown : function(e){ | |
175 if(this.enabled){ //just in case | |
176 var b = this.bindings; | |
177 for(var i = 0, len = b.length; i < len; i++){ | |
178 b[i].call(this, e); | |
179 } | |
180 } | |
181 }, | |
182 | |
183 /** | |
184 * Returns true if this KeyMap is enabled | |
185 * @return {Boolean} | |
186 */ | |
187 isEnabled : function(){ | |
188 return this.enabled; | |
189 }, | |
190 | |
191 /** | |
192 * Enables this KeyMap | |
193 */ | |
194 enable: function(){ | |
195 if(!this.enabled){ | |
196 this.el.on(this.eventName, this.handleKeyDown, this); | |
197 this.enabled = true; | |
198 } | |
199 }, | |
200 | |
201 /** | |
202 * Disable this KeyMap | |
203 */ | |
204 disable: function(){ | |
205 if(this.enabled){ | |
206 this.el.removeListener(this.eventName, this.handleKeyDown, this); | |
207 this.enabled = false; | |
208 } | |
209 } | |
210 }; |