More work on key handling and rename KeyEvent#keyCode -> KeyEvent#key.

This commit is contained in:
Jürg Lehni 2011-05-08 15:16:41 +01:00
parent 9f47942e7a
commit 742c9da822
4 changed files with 64 additions and 32 deletions

View file

@ -287,7 +287,7 @@
var layer = document.activeLayer; var layer = document.activeLayer;
function onKeyDown(event) { function onKeyDown(event) {
if (event.keyCode == 'space') if (event.key == 'space')
layer.selected = !layer.selected; layer.selected = !layer.selected;
} }
</script> </script>

View file

@ -118,6 +118,12 @@ Base.inject({
}); });
}, },
camelize: function(str) {
return str.replace(/-(\w)/g, function(all, chr) {
return chr.toUpperCase();
});
},
formatNumber: function(num) { formatNumber: function(num) {
return (Math.round(num * 100000) / 100000).toString(); return (Math.round(num * 100000) / 100000).toString();
} }

View file

@ -24,10 +24,13 @@ var Key = this.Key = new function() {
13: 'enter', 13: 'enter',
16: 'shift', 16: 'shift',
17: 'control', 17: 'control',
19: 'option', // was alt 18: 'option',
20: 'capsLock', 19: 'pause',
20: 'caps-lock',
27: 'escape', 27: 'escape',
32: 'space', 32: 'space',
35: 'end',
36: 'home',
37: 'left', 37: 'left',
38: 'up', 38: 'up',
39: 'right', 39: 'right',
@ -44,54 +47,69 @@ var Key = this.Key = new function() {
capsLock: false capsLock: false
}, },
keyCodes = {}, // Since only keypress gets proper keyCodes that are actually representing
downCode, // characters, we need to perform a little trickery here to use these codes
downTimer; // in onKeyDown/Up: keydown is used to store the downCode and handle
// modifiers and special keys such as arrows, space, etc, keypress fires the
// actual onKeyDown event and maps the keydown keyCode to the keypress
// charCode so keyup can do the right thing too.
charCodeMap = {}, // keyCode -> charCode mappings for pressed keys
downCode; // The last keyCode from keydown
function handleKey(down, code, event) { function handleKey(down, keyCode, charCode, event) {
var character = String.fromCharCode(code), var character = String.fromCharCode(charCode),
keyCode = keys[code] || character.toLowerCase(), key = keys[keyCode] || character.toLowerCase(),
handler = down ? 'onKeyDown' : 'onKeyUp'; handler = down ? 'onKeyDown' : 'onKeyUp';
console.log(handler, keyCode, character); if (paper.tool && paper.tool[handler]) {
if (modifiers[keyCode] !== undefined) {
modifiers[keyCode] = down;
} else if (paper.tool && paper.tool[handler]) {
// Call the onKeyDown or onKeyUp handler if present // Call the onKeyDown or onKeyUp handler if present
// When the handler function returns false, prevent the // When the handler function returns false, prevent the
// default behaviour of the key event: // default behaviour of the key event:
// PORT: Add to Sg // PORT: Add to Sg
var keyEvent = new KeyEvent(down, keyCode, character, event); var keyEvent = new KeyEvent(down, key, character, event);
if (paper.tool[handler](keyEvent) === false) { if (paper.tool[handler](keyEvent) === false) {
keyEvent.preventDefault(); keyEvent.preventDefault();
} }
} }
} }
// Since only keypress gest proper keyCodes that are actually representing
// characters, we need to add a little timeout to keydown events to see if
// they are follow immediately by a keypress, and if so, map the keyCode
// from the keydown to the one from keypress, so keyup still knows what
// code has now been released.
DomEvent.add(document, { DomEvent.add(document, {
keydown: function(event) { keydown: function(event) {
var code = downCode = event.which || event.keyCode; downCode = event.which || event.keyCode;
downTimer = setTimeout(function() { // If the keyCode is in keys, it needs to be handled by keydown and
keyCodes[code] = code; // won't fire a keypress after.
handleKey(true, code, event); var key = keys[downCode],
}, 1); name;
if (key) {
// Do not fire handleKey for modifiers, but for other keys such
// ass arrows, delete, backspace, etc.
if (modifiers[name = Base.camelize(key)] !== undefined) {
modifiers[name] = true;
} else {
// No char code for special keys, but mark as pressed
charCodeMap[downCode] = 0;
handleKey(true, downCode, null, event);
}
}
}, },
keypress: function(event) { keypress: function(event) {
clearTimeout(downTimer);
var code = event.which || event.keyCode; var code = event.which || event.keyCode;
keyCodes[downCode] = code; // Link the downCode from keydown with the code form keypress, so
handleKey(true, code, event); // keyup can retrieve that code again.
charCodeMap[downCode] = code;
handleKey(true, downCode, code, event);
}, },
keyup: function(event) { keyup: function(event) {
var code = event.which || event.keyCode; var code = event.which || event.keyCode,
handleKey(false, keyCodes[code], event); key = keys[code],
delete keyCodes[code]; name;
if (key && modifiers[name = Base.camelize(key)] !== undefined) {
modifiers[name] = false
} else if (charCodeMap[code] !== undefined) {
handleKey(false, code, charCodeMap[code], event);
delete charCodeMap[code];
}
} }
}); });

View file

@ -16,11 +16,19 @@
var KeyEvent = this.KeyEvent = Event.extend(new function() { var KeyEvent = this.KeyEvent = Event.extend(new function() {
return { return {
initialize: function(down, keyCode, character, event) { initialize: function(down, key, character, event) {
this.base(event); this.base(event);
this.type = down ? 'key-down' : 'key-up'; this.type = down ? 'key-down' : 'key-up';
this.keyCode = keyCode; this.key = key;
this.character = character; this.character = character;
},
toString: function() {
return '{ type: ' + this.type
+ ', key: ' + this.key
+ ', character: ' + this.character
+ ', modifiers: ' + this.modifiers
+ ' }';
} }
}; };
}); });