[483] | 1 | define(["dojo", "../util/common"], |
---|
| 2 | function(dojo, utilCommon){ |
---|
| 3 | |
---|
| 4 | // Ref: isEdit allows events to happen in Drawing, like TextBlocks |
---|
| 5 | var isEdit = false; |
---|
| 6 | |
---|
| 7 | // Ref: enabled = false allows inputs outside of drawing to function |
---|
| 8 | var enabled = true; |
---|
| 9 | |
---|
| 10 | var alphabet = "abcdefghijklmnopqrstuvwxyz"; |
---|
| 11 | |
---|
| 12 | //dojox.drawing.manager.keys = |
---|
| 13 | var keys = { |
---|
| 14 | // summary: |
---|
| 15 | // A singleton, master object that detects |
---|
| 16 | // keyboard keys and events |
---|
| 17 | // Connect to it like: |
---|
| 18 | // | dojo.connect(this.keys, "onEnter", ....); |
---|
| 19 | |
---|
| 20 | // arrowIncrement: Number |
---|
| 21 | // The amount, in pixels, a selected Stencil will |
---|
| 22 | // move on an arrow key event |
---|
| 23 | arrowIncrement:1, |
---|
| 24 | |
---|
| 25 | // arrowShiftIncrement: Number |
---|
| 26 | // The amount, in pixels, a selected Stencil will |
---|
| 27 | // move on an arrow key + SHIFT event |
---|
| 28 | arrowShiftIncrement:10, |
---|
| 29 | |
---|
| 30 | // shift: [readonly] Boolean |
---|
| 31 | // Indicates whether the Shift key is currently pressed |
---|
| 32 | shift:false, |
---|
| 33 | |
---|
| 34 | // ctrl: [readonly] Boolean |
---|
| 35 | // Indicates whether the Control key is currently pressed |
---|
| 36 | ctrl:false, |
---|
| 37 | |
---|
| 38 | // alt: [readonly] Boolean |
---|
| 39 | // Indicates whether the Alt or Option key is currently pressed |
---|
| 40 | alt:false, |
---|
| 41 | |
---|
| 42 | // cmmd: [readonly] Boolean |
---|
| 43 | // Indicates whether the Apple Command key is currently pressed |
---|
| 44 | cmmd:false, // apple key |
---|
| 45 | |
---|
| 46 | // meta: [readonly] Boolean |
---|
| 47 | // Indicates whether any 'meta' key is currently pressed: |
---|
| 48 | // shift || ctrl || cmd || alt |
---|
| 49 | meta:false, // any meta key |
---|
| 50 | |
---|
| 51 | onDelete: function(/* Event */evt){ |
---|
| 52 | // summary: |
---|
| 53 | // Event fires when Delete key is released |
---|
| 54 | }, |
---|
| 55 | onEsc: function(/* Event */evt){ |
---|
| 56 | // summary: |
---|
| 57 | // Event fires when ESC key is released |
---|
| 58 | }, |
---|
| 59 | onEnter: function(/* Event */evt){ |
---|
| 60 | // summary: |
---|
| 61 | // Event fires when Enter key is released |
---|
| 62 | }, |
---|
| 63 | onArrow: function(/* Event */evt){ |
---|
| 64 | // summary: |
---|
| 65 | // Event fires when an Arrow key is released |
---|
| 66 | // You will have to further check if evt.keyCode |
---|
| 67 | // is 37,38,39, or 40 |
---|
| 68 | }, |
---|
| 69 | onKeyDown: function(/* Event */evt){ |
---|
| 70 | // summary: |
---|
| 71 | // Event fires when any key is pressed |
---|
| 72 | }, |
---|
| 73 | onKeyUp: function(/* Event */evt){ |
---|
| 74 | // summary: |
---|
| 75 | // Event fires when any key is released |
---|
| 76 | }, |
---|
| 77 | |
---|
| 78 | listeners:[], |
---|
| 79 | register: function(options){ |
---|
| 80 | // summary: |
---|
| 81 | // Register an object and callback to be notified |
---|
| 82 | // of events. |
---|
| 83 | // NOTE: Not really used in code, but should work. |
---|
| 84 | // See manager.mouse for similar usage |
---|
| 85 | |
---|
| 86 | var _handle = utilCommon.uid("listener"); |
---|
| 87 | this.listeners.push({ |
---|
| 88 | handle:_handle, |
---|
| 89 | scope: options.scope || window, |
---|
| 90 | callback:options.callback, |
---|
| 91 | keyCode:options.keyCode |
---|
| 92 | }); |
---|
| 93 | }, |
---|
| 94 | |
---|
| 95 | _getLetter: function(evt){ |
---|
| 96 | if(!evt.meta && evt.keyCode>=65 && evt.keyCode<=90){ |
---|
| 97 | return alphabet.charAt(evt.keyCode-65); |
---|
| 98 | } |
---|
| 99 | return null; |
---|
| 100 | }, |
---|
| 101 | |
---|
| 102 | _mixin: function(evt){ |
---|
| 103 | // summary: |
---|
| 104 | // Internal. Mixes in key events. |
---|
| 105 | evt.meta = this.meta; |
---|
| 106 | evt.shift = this.shift; |
---|
| 107 | evt.alt = this.alt; |
---|
| 108 | evt.cmmd = this.cmmd; |
---|
| 109 | evt.ctrl = this.ctrl; |
---|
| 110 | evt.letter = this._getLetter(evt); |
---|
| 111 | return evt; |
---|
| 112 | }, |
---|
| 113 | |
---|
| 114 | editMode: function(_isedit){ |
---|
| 115 | // summary: |
---|
| 116 | // Relinquishes control of events to another portion |
---|
| 117 | // of Drawing; namely the TextBlock. |
---|
| 118 | isEdit = _isedit; |
---|
| 119 | }, |
---|
| 120 | |
---|
| 121 | enable: function(_enabled){ |
---|
| 122 | // summary: |
---|
| 123 | // Enables or disables key events, to relinquish |
---|
| 124 | // control to something outside of Drawing; input |
---|
| 125 | // fields for example. |
---|
| 126 | // You may need to call this directly if you are |
---|
| 127 | // using textareas or contenteditables. |
---|
| 128 | // NOTE: See scanForFields |
---|
| 129 | enabled = _enabled; |
---|
| 130 | }, |
---|
| 131 | |
---|
| 132 | scanForFields: function(){ |
---|
| 133 | // summary: |
---|
| 134 | // Scans the document for inputs |
---|
| 135 | // and calls this automatically. However you may need |
---|
| 136 | // to call this if you create inputs after the fact. |
---|
| 137 | |
---|
| 138 | if(this._fieldCons){ |
---|
| 139 | dojo.forEach(this._fieldCons, dojo.disconnect, dojo); |
---|
| 140 | } |
---|
| 141 | this._fieldCons = []; |
---|
| 142 | dojo.query("input").forEach(function(n){ |
---|
| 143 | var a = dojo.connect(n, "focus", this, function(evt){ |
---|
| 144 | this.enable(false); |
---|
| 145 | }); |
---|
| 146 | var b = dojo.connect(n, "blur", this, function(evt){ |
---|
| 147 | this.enable(true); |
---|
| 148 | }); |
---|
| 149 | this._fieldCons.push(a); |
---|
| 150 | this._fieldCons.push(b); |
---|
| 151 | }, this); |
---|
| 152 | |
---|
| 153 | }, |
---|
| 154 | |
---|
| 155 | init: function(){ |
---|
| 156 | // summary: |
---|
| 157 | // Initialize the keys object |
---|
| 158 | |
---|
| 159 | // a little extra time is needed in some browsers |
---|
| 160 | setTimeout(dojo.hitch(this, "scanForFields"), 500); |
---|
| 161 | |
---|
| 162 | dojo.connect(document, "blur", this, function(evt){ |
---|
| 163 | // when command tabbing to another application, the key "sticks" |
---|
| 164 | // this clears any key used for such activity |
---|
| 165 | this.meta = this.shift = this.ctrl = this.cmmd = this.alt = false; |
---|
| 166 | }); |
---|
| 167 | |
---|
| 168 | dojo.connect(document, "keydown", this, function(evt){ |
---|
| 169 | if(!enabled){ return; } |
---|
| 170 | if(evt.keyCode==16){ |
---|
| 171 | this.shift = true; |
---|
| 172 | } |
---|
| 173 | if(evt.keyCode==17){ |
---|
| 174 | this.ctrl = true; |
---|
| 175 | } |
---|
| 176 | if(evt.keyCode==18){ |
---|
| 177 | this.alt = true; |
---|
| 178 | } |
---|
| 179 | if(evt.keyCode==224){ |
---|
| 180 | this.cmmd = true; |
---|
| 181 | } |
---|
| 182 | |
---|
| 183 | this.meta = this.shift || this.ctrl || this.cmmd || this.alt; |
---|
| 184 | |
---|
| 185 | if(!isEdit){ |
---|
| 186 | this.onKeyDown(this._mixin(evt)); |
---|
| 187 | if(evt.keyCode==8 || evt.keyCode==46){ |
---|
| 188 | dojo.stopEvent(evt); |
---|
| 189 | } |
---|
| 190 | } |
---|
| 191 | }); |
---|
| 192 | dojo.connect(document, "keyup", this, function(evt){ |
---|
| 193 | if(!enabled){ return; } |
---|
| 194 | //console.log("KEY UP:", evt.keyCode); |
---|
| 195 | var _stop = false; |
---|
| 196 | if(evt.keyCode==16){ |
---|
| 197 | this.shift = false; |
---|
| 198 | } |
---|
| 199 | if(evt.keyCode==17){ |
---|
| 200 | this.ctrl = false; |
---|
| 201 | } |
---|
| 202 | if(evt.keyCode==18){ |
---|
| 203 | this.alt = false; |
---|
| 204 | } |
---|
| 205 | if(evt.keyCode==224){ |
---|
| 206 | this.cmmd = false; |
---|
| 207 | } |
---|
| 208 | |
---|
| 209 | this.meta = this.shift || this.ctrl || this.cmmd || this.alt; |
---|
| 210 | |
---|
| 211 | !isEdit && this.onKeyUp(this._mixin(evt)); |
---|
| 212 | |
---|
| 213 | if(evt.keyCode==13){ |
---|
| 214 | console.warn("KEY ENTER"); |
---|
| 215 | this.onEnter(evt); |
---|
| 216 | _stop = true; |
---|
| 217 | } |
---|
| 218 | if(evt.keyCode==27){ |
---|
| 219 | this.onEsc(evt); |
---|
| 220 | _stop = true; |
---|
| 221 | } |
---|
| 222 | if(evt.keyCode==8 || evt.keyCode==46){ |
---|
| 223 | this.onDelete(evt); |
---|
| 224 | _stop = true; |
---|
| 225 | } |
---|
| 226 | |
---|
| 227 | if(_stop && !isEdit){ |
---|
| 228 | dojo.stopEvent(evt); |
---|
| 229 | } |
---|
| 230 | }); |
---|
| 231 | |
---|
| 232 | dojo.connect(document, "keypress", this, function(evt){ |
---|
| 233 | if(!enabled){ return; } |
---|
| 234 | var inc = this.shift ? this.arrowIncrement*this.arrowShiftIncrement : this.arrowIncrement, |
---|
| 235 | altOrOption = evt.alt || this.cmmd; |
---|
| 236 | |
---|
| 237 | var x =0, y =0; |
---|
| 238 | if(evt.keyCode==32 && !isEdit){ //space |
---|
| 239 | dojo.stopEvent(evt); |
---|
| 240 | } |
---|
| 241 | if(evt.keyCode==37 && !altOrOption){ //left |
---|
| 242 | x = -inc; |
---|
| 243 | } |
---|
| 244 | if(evt.keyCode==38 && !altOrOption){ //up |
---|
| 245 | y = -inc; |
---|
| 246 | } |
---|
| 247 | if(evt.keyCode==39 && !altOrOption){ //right |
---|
| 248 | x = inc; |
---|
| 249 | } |
---|
| 250 | if(evt.keyCode==40 && !altOrOption){ //down |
---|
| 251 | y = inc; |
---|
| 252 | } |
---|
| 253 | if(x || y){ |
---|
| 254 | evt.x = x; |
---|
| 255 | evt.y = y; |
---|
| 256 | evt.shift = this.shift; |
---|
| 257 | if(!isEdit){ |
---|
| 258 | this.onArrow(evt); |
---|
| 259 | dojo.stopEvent(evt); |
---|
| 260 | } |
---|
| 261 | } |
---|
| 262 | }); |
---|
| 263 | } |
---|
| 264 | }; |
---|
| 265 | dojo.addOnLoad(keys, "init"); |
---|
| 266 | return keys; |
---|
| 267 | }); |
---|