keys.js 6.9 KB

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