Fix Issue 16: shortcut keys using js-hotkeys
git-svn-id: http://svg-edit.googlecode.com/svn/trunk@134 eee81c28-f429-11dd-99c0-75d572ba1ddd
This commit is contained in:
93
editor/js-hotkeys/README.md
Normal file
93
editor/js-hotkeys/README.md
Normal file
@@ -0,0 +1,93 @@
|
||||
#About
|
||||
**jQuery.hotkeys** is a plug-in that lets you easily add and remove handlers for keyboard events anywhere in your code supporting almost any key combination.
|
||||
|
||||
It is based on a library [Shortcut.js](http://www.openjs.com/scripts/events/keyboard_shortcuts/shortcut.js) written by [Binny V A](http://www.openjs.com/).
|
||||
|
||||
The syntax is as follows:
|
||||
<pre>
|
||||
$(expression).bind(<types>,<options>, <handler>);
|
||||
$(expression).unbind(<types>,<options>, <handler>);
|
||||
|
||||
$(document).bind('keydown', 'Ctrl+a', fn);
|
||||
|
||||
// e.g. replace '$' sign with 'EUR'
|
||||
$('input.foo').bind('keyup', '$', function(){
|
||||
this.value = this.value.replace('$', 'EUR');
|
||||
});
|
||||
|
||||
$('div.foo').unbind('keydown', 'Ctrl+a', fn);
|
||||
</pre>
|
||||
## [Live Demo](http://jshotkeys.googlepages.com/test-static-01.html)
|
||||
|
||||
## Types
|
||||
Supported types are `'keydown'`, `'keyup'` and `'keypress'`
|
||||
|
||||
## Options
|
||||
The options are `'combi'` i.e. the key combination, and `'disableInInput'` which allow your code not to be executed when the cursor is located inside an input ( `$(elem).is('input') || $(elem).is('textarea')` ).
|
||||
|
||||
As you can see, the key combination can be passed as string or as an object. You may pass an object in case you wish to override the default option for `disableInInput` which is set to `false`:
|
||||
<pre>
|
||||
$(document).bind('keydown', {combi:'a', disableinInput: true}, fn);
|
||||
</pre>
|
||||
I.e. when cursor is within an input field, `'a'` will be inserted into the input field without interfering.
|
||||
|
||||
If you want to use more than one modifiers (e.g. alt+ctrl+z) you should define them by an alphabetical order e.g. alt+ctrl+shift
|
||||
|
||||
Modifiers are case insensitive, i.e. 'Ctrl+a' 'ctrl+a'.
|
||||
|
||||
## Handler
|
||||
In previous versions there was an option propagate which is removed now and implemented at the user code level.
|
||||
|
||||
When using jQuery, if an event handler returns false, jQuery will call `stopPropagation()` and `preventDefault()`
|
||||
|
||||
## jQuery Compatibility
|
||||
Tested with *jQuery 1.2.6*
|
||||
|
||||
It known to be working with all the major browsers on all available platforms (Win/Mac/Linux)
|
||||
|
||||
* IE 6/7/8
|
||||
* FF 1.5/2/3
|
||||
* Opera-9
|
||||
* Safari-3
|
||||
* Chrome-0.2
|
||||
|
||||
## Features added in this version (0.7.x)
|
||||
* Implemented as $.fn - let you use `this`.
|
||||
* jQuery selectors are supported.
|
||||
* Extending `$.fn.bind` and `$.fn.unbind` so you get a single interface for binding events to handlers
|
||||
|
||||
## Overriding jQuery
|
||||
The plugin wraps the following jQuery methods:
|
||||
* $.fn.bind
|
||||
* $.fn.unbind
|
||||
* $.find
|
||||
|
||||
Even though the plugin overrides these methods, the original methods will *always* be called.
|
||||
|
||||
The plugin will add functionality only for the `keydown`, `keyup` and `keypress` event types. Any other types are passed untouched to the original `'bind()'` and `'unbind()'` methods.
|
||||
|
||||
Moreover, if you call `bind()` without passing the shortcut key combination e.g. `$(document).bind('keydown', fn)` only the original `'bind()'` method will be executed.
|
||||
|
||||
I also modified the `$.fn.find` method by adding a single line at the top of the function body. here is the code:
|
||||
|
||||
<pre>
|
||||
jQuery.fn.find = function( selector ) {
|
||||
// the line I added
|
||||
this.query=selector;
|
||||
// call jQuery original find
|
||||
return jQuery.fn.__find__.apply(this, arguments);
|
||||
};
|
||||
</pre>
|
||||
|
||||
You can read about this at [jQuery's User Group](http://groups.google.com/group/jquery-en/browse_thread/thread/18f9825e8d22f18d)
|
||||
|
||||
###Notes
|
||||
|
||||
Firefox is the most liberal one in the manner of letting you capture all short-cuts even those that are built-in in the browser such as `Ctrl-t` for new tab, or `Ctrl-a` for selecting all text. You can always bubble them up to the browser by returning `true` in your handler.
|
||||
|
||||
Others, (IE) either let you handle built-in short-cuts, but will add their functionality after your code has executed. Or (Opera/Safari) will *not* pass those events to the DOM at all.
|
||||
|
||||
*So, if you bind `Ctrl-Q` or `Alt-F4` and your Safari/Opera window is closed don't be surprised.*
|
||||
|
||||
|
||||
###Current Version is: beta 0.7
|
||||
19
editor/js-hotkeys/jquery.hotkeys.min.js
vendored
Normal file
19
editor/js-hotkeys/jquery.hotkeys.min.js
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
(function(jQuery){jQuery.fn.__bind__=jQuery.fn.bind;jQuery.fn.__unbind__=jQuery.fn.unbind;jQuery.fn.__find__=jQuery.fn.find;var hotkeys={version:'0.7.9',override:/keypress|keydown|keyup/g,triggersMap:{},specialKeys:{27:'esc',9:'tab',32:'space',13:'return',8:'backspace',145:'scroll',20:'capslock',144:'numlock',19:'pause',45:'insert',36:'home',46:'del',35:'end',33:'pageup',34:'pagedown',37:'left',38:'up',39:'right',40:'down',109:'-',112:'f1',113:'f2',114:'f3',115:'f4',116:'f5',117:'f6',118:'f7',119:'f8',120:'f9',121:'f10',122:'f11',123:'f12',191:'/'},shiftNums:{"`":"~","1":"!","2":"@","3":"#","4":"$","5":"%","6":"^","7":"&","8":"*","9":"(","0":")","-":"_","=":"+",";":":","'":"\"",",":"<",".":">","/":"?","\\":"|"},newTrigger:function(type,combi,callback){var result={};result[type]={};result[type][combi]={cb:callback,disableInInput:false};return result;}};hotkeys.specialKeys=jQuery.extend(hotkeys.specialKeys,{96:'0',97:'1',98:'2',99:'3',100:'4',101:'5',102:'6',103:'7',104:'8',105:'9',106:'*',107:'+',109:'-',110:'.',111:'/'});jQuery.fn.find=function(selector){this.query=selector;return jQuery.fn.__find__.apply(this,arguments);};jQuery.fn.unbind=function(type,combi,fn){if(jQuery.isFunction(combi)){fn=combi;combi=null;}
|
||||
if(combi&&typeof combi==='string'){var selectorId=((this.prevObject&&this.prevObject.query)||(this[0].id&&this[0].id)||this[0]).toString();var hkTypes=type.split(' ');for(var x=0;x<hkTypes.length;x++){delete hotkeys.triggersMap[selectorId][hkTypes[x]][combi];}}
|
||||
return this.__unbind__(type,fn);};jQuery.fn.bind=function(type,data,fn){var handle=type.match(hotkeys.override);if(jQuery.isFunction(data)||!handle){return this.__bind__(type,data,fn);}
|
||||
else{var result=null,pass2jq=jQuery.trim(type.replace(hotkeys.override,''));if(pass2jq){result=this.__bind__(pass2jq,data,fn);}
|
||||
if(typeof data==="string"){data={'combi':data};}
|
||||
if(data.combi){for(var x=0;x<handle.length;x++){var eventType=handle[x];var combi=data.combi.toLowerCase(),trigger=hotkeys.newTrigger(eventType,combi,fn),selectorId=((this.prevObject&&this.prevObject.query)||(this[0].id&&this[0].id)||this[0]).toString();trigger[eventType][combi].disableInInput=data.disableInInput;if(!hotkeys.triggersMap[selectorId]){hotkeys.triggersMap[selectorId]=trigger;}
|
||||
else if(!hotkeys.triggersMap[selectorId][eventType]){hotkeys.triggersMap[selectorId][eventType]=trigger[eventType];}
|
||||
var mapPoint=hotkeys.triggersMap[selectorId][eventType][combi];if(!mapPoint){hotkeys.triggersMap[selectorId][eventType][combi]=[trigger[eventType][combi]];}
|
||||
else if(mapPoint.constructor!==Array){hotkeys.triggersMap[selectorId][eventType][combi]=[mapPoint];}
|
||||
else{hotkeys.triggersMap[selectorId][eventType][combi][mapPoint.length]=trigger[eventType][combi];}
|
||||
this.each(function(){var jqElem=jQuery(this);if(jqElem.attr('hkId')&&jqElem.attr('hkId')!==selectorId){selectorId=jqElem.attr('hkId')+";"+selectorId;}
|
||||
jqElem.attr('hkId',selectorId);});result=this.__bind__(handle.join(' '),data,hotkeys.handler)}}
|
||||
return result;}};hotkeys.findElement=function(elem){if(!jQuery(elem).attr('hkId')){if(jQuery.browser.opera||jQuery.browser.safari){while(!jQuery(elem).attr('hkId')&&elem.parentNode){elem=elem.parentNode;}}}
|
||||
return elem;};hotkeys.handler=function(event){var target=hotkeys.findElement(event.currentTarget),jTarget=jQuery(target),ids=jTarget.attr('hkId');if(ids){ids=ids.split(';');var code=event.which,type=event.type,special=hotkeys.specialKeys[code],character=!special&&String.fromCharCode(code).toLowerCase(),shift=event.shiftKey,ctrl=event.ctrlKey,alt=event.altKey||event.originalEvent.altKey,mapPoint=null;for(var x=0;x<ids.length;x++){if(hotkeys.triggersMap[ids[x]][type]){mapPoint=hotkeys.triggersMap[ids[x]][type];break;}}
|
||||
if(mapPoint){var trigger;if(!shift&&!ctrl&&!alt){trigger=mapPoint[special]||(character&&mapPoint[character]);}
|
||||
else{var modif='';if(alt)modif+='alt+';if(ctrl)modif+='ctrl+';if(shift)modif+='shift+';trigger=mapPoint[modif+special];if(!trigger){if(character){trigger=mapPoint[modif+character]||mapPoint[modif+hotkeys.shiftNums[character]]||(modif==='shift+'&&mapPoint[hotkeys.shiftNums[character]]);}}}
|
||||
if(trigger){var result=false;for(var x=0;x<trigger.length;x++){if(trigger[x].disableInInput){var elem=jQuery(event.target);if(jTarget.is("input")||jTarget.is("textarea")||jTarget.is("select")||elem.is("input")||elem.is("textarea")||elem.is("select")){return true;}}
|
||||
result=result||trigger[x].cb.apply(this,[event]);}
|
||||
return result;}}}};window.hotkeys=hotkeys;return jQuery;})(jQuery);
|
||||
@@ -4,6 +4,7 @@
|
||||
<link rel="stylesheet" href="jpicker/jpicker.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="svg-editor.css" type="text/css"/>
|
||||
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="js-hotkeys/jquery.hotkeys.min.js"></script>
|
||||
<script type="text/javascript" src="jquery.rightClick.js"></script>
|
||||
<script type="text/javascript" src="jpicker/jpicker.js"></script>
|
||||
<script type="text/javascript" src="svgcanvas.js"></script>
|
||||
@@ -93,8 +94,8 @@
|
||||
<img class="tool_button" id="tool_select" src="images/select.png" title="Select Tool [1]" alt="Select"/><br/>
|
||||
<img class="tool_button_current" id="tool_path" src="images/path.png" title="Pencil Tool [2]" alt="Pencil"/><br/>
|
||||
<img class="tool_button" id="tool_line" src="images/line.png" title="Line Tool [3]" alt="Line"/><br/>
|
||||
<img class="tool_button" id="tools_rect_show" src="images/square.png" title="Square/Rect Tool [4/Shift+4]" alt="Square"/><br/>
|
||||
<img class="tool_button" id="tools_ellipse_show" src="images/circle.png" title="Circle/Ellipse Tool [5/Shift+5]" alt="Circle"/><br/>
|
||||
<img class="tool_button" id="tools_rect_show" src="images/square.png" title="Rect/Square Tool [4/Shift+4]" alt="Square"/><br/>
|
||||
<img class="tool_button" id="tools_ellipse_show" src="images/circle.png" title="Ellipse/Circle Tool [5/Shift+5]" alt="Circle"/><br/>
|
||||
<img class="tool_button" id="tool_text" src="images/text.png" title="Text Tool [6]" alt="Text"/>
|
||||
|
||||
<hr/>
|
||||
|
||||
@@ -285,53 +285,19 @@ function svg_edit_setup() {
|
||||
$('#tool_delete').mouseup(function(){$('#tool_delete').removeClass('tool_button_current');});
|
||||
$('#tool_delete').mouseout(function(){$('#tool_delete').removeClass('tool_button_current');});
|
||||
|
||||
$('#workarea').keyup(function(event){
|
||||
if( textBeingEntered ) { return; }
|
||||
switch (event.keyCode) {
|
||||
case 37: // left-arrow
|
||||
break;
|
||||
case 38: // up-arrow
|
||||
break;
|
||||
case 39: // right-arrow
|
||||
break;
|
||||
case 40: // down-arrow
|
||||
break;
|
||||
case 49: // 1
|
||||
clickSelect();
|
||||
break;
|
||||
case 50: // 2
|
||||
clickPath();
|
||||
break;
|
||||
case 51: // 3
|
||||
clickLine();
|
||||
break;
|
||||
case 52: // 4
|
||||
if (event.shiftKey)
|
||||
clickSquare();
|
||||
else
|
||||
clickRect();
|
||||
break;
|
||||
case 53: // 5
|
||||
if (event.shiftKey)
|
||||
clickCircle();
|
||||
else
|
||||
clickEllipse();
|
||||
break;
|
||||
case 54: // 6
|
||||
clickText();
|
||||
break;
|
||||
case 78: // N
|
||||
clickClear();
|
||||
break;
|
||||
case 83: // S
|
||||
clickSave();
|
||||
break;
|
||||
case 88: // X
|
||||
clickDelete();
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
// do keybindings using jquery-hotkeys plugin
|
||||
$(document).bind('keydown', {combi:'1', disableInInput: true}, clickSelect);
|
||||
$(document).bind('keydown', {combi:'2', disableInInput: true}, clickPath);
|
||||
$(document).bind('keydown', {combi:'3', disableInInput: true}, clickLine);
|
||||
$(document).bind('keydown', {combi:'Shift+4', disableInInput: true}, clickSquare);
|
||||
$(document).bind('keydown', {combi:'4', disableInInput: true}, clickRect);
|
||||
$(document).bind('keydown', {combi:'Shift+5', disableInInput: true}, clickCircle);
|
||||
$(document).bind('keydown', {combi:'5', disableInInput: true}, clickEllipse);
|
||||
$(document).bind('keydown', {combi:'6', disableInInput: true}, clickText);
|
||||
$(document).bind('keydown', {combi:'N', disableInInput: true}, clickClear);
|
||||
$(document).bind('keydown', {combi:'S', disableInInput: true}, clickSave);
|
||||
$(document).bind('keydown', {combi:'X', disableInInput: true}, deleteSelected);
|
||||
|
||||
var colorPicker = function(elem) {
|
||||
$('.tools_flyout').hide();
|
||||
var oldbg = elem.css('background');
|
||||
|
||||
Reference in New Issue
Block a user