/*
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
if(!dojo._hasResource["dojox.drawing.manager.keys"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojox.drawing.manager.keys"] = true;
dojo.provide("dojox.drawing.manager.keys");
(function(){
// Ref: isEdit allows events to happen in Drawing, like TextBlocks
var isEdit = false;
// Ref: enabled = false allows inputs outside of drawing to function
var enabled = true;
var alphabet = "abcdefghijklmnopqrstuvwxyz";
dojox.drawing.manager.keys = {
// summary:
// A singleton, master object that detects
// keyboard keys and events
// Connect to it like:
// dojo.connect(this.keys, "onEnter", ....);
//
// arrowIncrement:Number
// The amount, in pixels, a selected Stencil will
// move on an arrow key event
arrowIncrement:1,
//
// arrowShiftIncrement: Number
// The amount, in pixels, a selected Stencil will
// move on an arrow key + SHIFT event
arrowShiftIncrement:10,
//
// shift: [readonly] Boolean
// Indicates whether the Shift key is currently pressed
shift:false,
//
// ctrl: [readonly] Boolean
// Indicates whether the Control key is currently pressed
ctrl:false,
//
// alt: [readonly] Boolean
// Indicates whether the Alt or Option key is currently pressed
alt:false,
//
// cmmd: [readonly] Boolean
// Indicates whether the Apple Command key is currently pressed
cmmd:false, // apple key
//
// meta: [readonly] Boolean
// Indicates whether any 'meta' key is currently pressed:
// shift || ctrl || cmmd || alt
meta:false, // any meta key
onDelete: function(/* Event */evt){
// summary:
// Event fires when Delete key is released
},
onEsc: function(/* Event */evt){
// summary:
// Event fires when ESC key is released
},
onEnter: function(/* Event */evt){
// summary:
// Event fires when Enter key is released
},
onArrow: function(/* Event */evt){
// summary:
// Event fires when an Arrow key is released
// You will have to further check if evt.keyCode
// is 37,38,39, or 40
},
onKeyDown: function(/* Event */evt){
// summary:
// Event fires when any key is pressed
},
onKeyUp: function(/* Event */evt){
// summary:
// Event fires when any key is released
},
listeners:[],
register: function(options){
// summary:
// Register an object and callback to be notified
// of events.
// NOTE: Not really used in code, but should work.
// See manager.mouse for similar usage
//
var _handle = dojox.drawing.util.uid("listener");
this.listeners.push({
handle:_handle,
scope: options.scope || window,
callback:options.callback,
keyCode:options.keyCode
});
},
_getLetter: function(evt){
if(!evt.meta && evt.keyCode>=65 && evt.keyCode<=90){
return alphabet.charAt(evt.keyCode-65);
}
return null;
},
_mixin: function(evt){
// summary:
// Internal. Mixes in key events.
evt.meta = this.meta;
evt.shift = this.shift;
evt.alt = this.alt;
evt.cmmd = this.cmmd;
evt.letter = this._getLetter(evt);
return evt;
},
editMode: function(_isedit){
// summary:
// Relinquishes control of events to another portion
// of Drawing; namely the TextBlock.
isEdit = _isedit;
},
enable: function(_enabled){
// summary:
// Enables or disables key events, to relinquish
// control to something outside of Drawing; input
// fields for example.
// You may need to call this directly if you are
// using textareas or contenteditables.
// NOTE: See scanForFields
enabled = _enabled;
},
scanForFields: function(){
// summary:
// Scans the document for inputs
// and calls this automatically. However you may need
// to call this if you create inputs after the fact.
//
if(this._fieldCons){
dojo.forEach(this._fieldCons, dojo.disconnect, dojo);
}
this._fieldCons = [];
dojo.query("input").forEach(function(n){
var a = dojo.connect(n, "focus", this, function(evt){
this.enable(false);
});
var b = dojo.connect(n, "blur", this, function(evt){
this.enable(true);
});
this._fieldCons.push(a);
this._fieldCons.push(b);
}, this);
},
init: function(){
// summary:
// Initialize the keys object
//
// a little extra time is needed in some browsers
setTimeout(dojo.hitch(this, "scanForFields"), 500);
dojo.connect(document, "blur", this, function(evt){
// when command tabbing to another application, the key "sticks"
// this clears any key used for such activity
this.meta = this.shift = this.ctrl = this.cmmd = this.alt = false;
});
dojo.connect(document, "keydown", this, function(evt){
if(!enabled){ return; }
if(evt.keyCode==16){
this.shift = true;
}
if(evt.keyCode==17){
this.ctrl = true;
}
if(evt.keyCode==18){
this.alt = true;
}
if(evt.keyCode==224){
this.cmmd = true;
}
this.meta = this.shift || this.ctrl || this.cmmd || this.alt;
if(!isEdit){
this.onKeyDown(this._mixin(evt));
if(evt.keyCode==8 || evt.keyCode==46){
dojo.stopEvent(evt);
}
}
});
dojo.connect(document, "keyup", this, function(evt){
if(!enabled){ return; }
//console.log("KEY UP:", evt.keyCode);
var _stop = false;
if(evt.keyCode==16){
this.shift = false;
}
if(evt.keyCode==17){
this.ctrl = false;
}
if(evt.keyCode==18){
this.alt = false;
}
if(evt.keyCode==224){
this.cmmd = false;
}
this.meta = this.shift || this.ctrl || this.cmmd || this.alt;
!isEdit && this.onKeyUp(this._mixin(evt));
if(evt.keyCode==13){
console.warn("KEY ENTER");
this.onEnter(evt);
_stop = true;
}
if(evt.keyCode==27){
this.onEsc(evt);
_stop = true;
}
if(evt.keyCode==8 || evt.keyCode==46){
this.onDelete(evt);
_stop = true;
}
if(_stop && !isEdit){
dojo.stopEvent(evt);
}
});
dojo.connect(document, "keypress", this, function(evt){
if(!enabled){ return; }
var inc = this.shift ? this.arrowIncrement*this.arrowShiftIncrement : this.arrowIncrement;
var x =0, y =0;
if(evt.keyCode==32 && !isEdit){ //space
dojo.stopEvent(evt);
}
if(evt.keyCode==37){ //left
x = -inc;
}
if(evt.keyCode==38){ //up
y = -inc;
}
if(evt.keyCode==39){ //right
x = inc;
}
if(evt.keyCode==40){ //down
y = inc;
}
if(x || y){
evt.x = x;
evt.y = y;
evt.shift = this.shift;
if(!isEdit){
this.onArrow(evt);
dojo.stopEvent(evt);
}
}
});
}
};
dojo.addOnLoad(dojox.drawing.manager.keys, "init");
})();
}