mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-12-19 17:51:41 +00:00
major refactoring of ui/lob/keyboard.js, needs more testing...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
81f26c36a4
commit
927184e872
@ -18,6 +18,7 @@ var DIRECTION = 'next'
|
|||||||
var KEYBOARD_CONFIG = {
|
var KEYBOARD_CONFIG = {
|
||||||
// general setup...
|
// general setup...
|
||||||
'.viewer': {
|
'.viewer': {
|
||||||
|
ignore: [ ],
|
||||||
// Navigation...
|
// Navigation...
|
||||||
// XXX need to cancel the animation of the prev action...
|
// XXX need to cancel the animation of the prev action...
|
||||||
Left: {
|
Left: {
|
||||||
|
|||||||
@ -91,9 +91,12 @@ function toKeyCode(c){
|
|||||||
return c.charCodeAt(0)
|
return c.charCodeAt(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// documentation wrapper...
|
||||||
|
function doc(text, func){
|
||||||
|
func.doc = text
|
||||||
|
return func
|
||||||
|
}
|
||||||
|
|
||||||
// if set to false the event handlers will always return false...
|
|
||||||
var KEYBOARD_HANDLER_PROPAGATE = true
|
|
||||||
|
|
||||||
/* Basic key binding format:
|
/* Basic key binding format:
|
||||||
*
|
*
|
||||||
@ -106,6 +109,8 @@ var KEYBOARD_HANDLER_PROPAGATE = true
|
|||||||
* // this defines the list of keys to ignore by the handler.
|
* // this defines the list of keys to ignore by the handler.
|
||||||
* // NOTE: use "*" to ignore all keys other than explicitly
|
* // NOTE: use "*" to ignore all keys other than explicitly
|
||||||
* // defined in the current section.
|
* // defined in the current section.
|
||||||
|
* // NOTE: ignoring a key will stop processing it in other
|
||||||
|
* // compatible modes.
|
||||||
* ignore: <ignored-keys>
|
* ignore: <ignored-keys>
|
||||||
*
|
*
|
||||||
* // NOTE: a callback can have a .doc attr containing
|
* // NOTE: a callback can have a .doc attr containing
|
||||||
@ -129,7 +134,7 @@ var KEYBOARD_HANDLER_PROPAGATE = true
|
|||||||
* default: <callback> | <key-def-x>,
|
* default: <callback> | <key-def-x>,
|
||||||
*
|
*
|
||||||
* // a modifier can be any single modifier, like shift or a
|
* // a modifier can be any single modifier, like shift or a
|
||||||
* // combination of modifers like 'ctrl+shift', given in order
|
* // combination of modifiers like 'ctrl+shift', given in order
|
||||||
* // of priority.
|
* // of priority.
|
||||||
* // supported modifiers are (in order of priority):
|
* // supported modifiers are (in order of priority):
|
||||||
* // - ctrl
|
* // - ctrl
|
||||||
@ -166,30 +171,57 @@ var KEYBOARD_HANDLER_PROPAGATE = true
|
|||||||
* NOTE: the number keys are named with a leading hash '#' (e.g. '#8')
|
* NOTE: the number keys are named with a leading hash '#' (e.g. '#8')
|
||||||
* to avoid conflicsts with keys that have the code with the same
|
* to avoid conflicsts with keys that have the code with the same
|
||||||
* value (e.g. 'backspace' (8)).
|
* value (e.g. 'backspace' (8)).
|
||||||
|
* NOTE: one can use a doc(<doc-string>, <callback>) as a shorthand to assign
|
||||||
|
* a docstring to a handler.
|
||||||
|
* it will only assign .doc attr and return the original function.
|
||||||
|
*
|
||||||
|
* XXX use getKeyHandler(...)
|
||||||
|
* XXX need an explicit way to prioritize modes...
|
||||||
*/
|
*/
|
||||||
function makeKeyboardHandler(keybindings, unhandled){
|
function makeKeyboardHandler(keybindings, unhandled){
|
||||||
if(unhandled == null){
|
if(unhandled == null){
|
||||||
//unhandled = function(){return false}
|
unhandled = function(){}
|
||||||
unhandled = function(){return KEYBOARD_HANDLER_PROPAGATE}
|
|
||||||
}
|
}
|
||||||
return function(evt){
|
return function(evt){
|
||||||
var did_handling = false
|
var did_handling = false
|
||||||
var res = null
|
var res = null
|
||||||
|
|
||||||
|
// key data...
|
||||||
var key = evt.keyCode
|
var key = evt.keyCode
|
||||||
var chr = toKeyName(key)
|
|
||||||
|
|
||||||
window.DEBUG && console.log('KEY:', key, chr)
|
// normalize the modifiers...
|
||||||
|
var modifiers = evt.ctrlKey ? 'ctrl' : ''
|
||||||
|
modifiers += evt.altKey ? (modifiers != '' ? '+alt' : 'alt') : ''
|
||||||
|
modifiers += evt.shiftKey ? (modifiers != '' ? '+shift' : 'shift') : ''
|
||||||
|
|
||||||
|
//window.DEBUG && console.log('KEY:', key, chr, modifiers)
|
||||||
|
|
||||||
|
var handlers = getKeyHandlers(key, modifiers, keybindings)
|
||||||
|
|
||||||
|
for(var mode in handlers){
|
||||||
|
var handler = handlers[mode]
|
||||||
|
if(handler != null){
|
||||||
|
|
||||||
|
did_handling = true
|
||||||
|
res = handler(evt)
|
||||||
|
|
||||||
|
if(res === false){
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!did_handling){
|
||||||
|
return unhandled(key)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
|
||||||
|
/* XXX remove this after through testing...
|
||||||
|
var chr = toKeyName(key)
|
||||||
|
|
||||||
for(var mode in keybindings){
|
for(var mode in keybindings){
|
||||||
if($(mode).length > 0){
|
if($(mode).length > 0){
|
||||||
var bindings = keybindings[mode]
|
var bindings = keybindings[mode]
|
||||||
|
|
||||||
// normalize the modifiers...
|
|
||||||
var modifers = evt.ctrlKey ? 'ctrl' : ''
|
|
||||||
modifers += evt.altKey ? (modifers != '' ? '+alt' : 'alt') : ''
|
|
||||||
modifers += evt.shiftKey ? (modifers != '' ? '+shift' : 'shift') : ''
|
|
||||||
|
|
||||||
if(chr in bindings){
|
if(chr in bindings){
|
||||||
var handler = bindings[chr]
|
var handler = bindings[chr]
|
||||||
} else {
|
} else {
|
||||||
@ -205,8 +237,8 @@ function makeKeyboardHandler(keybindings, unhandled){
|
|||||||
|
|
||||||
// do the complex handler aliases...
|
// do the complex handler aliases...
|
||||||
if(typeof(handler) == typeof({}) && handler.constructor.name == 'Object'){
|
if(typeof(handler) == typeof({}) && handler.constructor.name == 'Object'){
|
||||||
if(typeof(handler[modifers]) == typeof('str')){
|
if(typeof(handler[modifiers]) == typeof('str')){
|
||||||
handler = handler[modifers]
|
handler = handler[modifiers]
|
||||||
} else if(typeof(handler['default']) == typeof('str')){
|
} else if(typeof(handler['default']) == typeof('str')){
|
||||||
handler = handler['default']
|
handler = handler['default']
|
||||||
} else {
|
} else {
|
||||||
@ -216,7 +248,6 @@ function makeKeyboardHandler(keybindings, unhandled){
|
|||||||
|
|
||||||
// simple handlers...
|
// simple handlers...
|
||||||
if(handler in bindings){
|
if(handler in bindings){
|
||||||
// XXX need to take care of that we can always be a number or a string...
|
|
||||||
handler = bindings[handler]
|
handler = bindings[handler]
|
||||||
} else if(typeof(handler) == typeof(1)) {
|
} else if(typeof(handler) == typeof(1)) {
|
||||||
handler = bindings[toKeyName(handler)]
|
handler = bindings[toKeyName(handler)]
|
||||||
@ -228,7 +259,9 @@ function makeKeyboardHandler(keybindings, unhandled){
|
|||||||
if(handler == null){
|
if(handler == null){
|
||||||
// if something is ignored then just breakout and stop handling...
|
// if something is ignored then just breakout and stop handling...
|
||||||
if(bindings.ignore == '*'
|
if(bindings.ignore == '*'
|
||||||
|| bindings.ignore != null && bindings.ignore.indexOf(key) != -1){
|
|| bindings.ignore != null
|
||||||
|
&& (bindings.ignore.indexOf(key) != -1
|
||||||
|
|| bindings.ignore.indexOf(chr) != -1)){
|
||||||
res = res == null ? true : res
|
res = res == null ? true : res
|
||||||
did_handling = true
|
did_handling = true
|
||||||
// ignoring a key will stop processing it...
|
// ignoring a key will stop processing it...
|
||||||
@ -244,24 +277,25 @@ function makeKeyboardHandler(keybindings, unhandled){
|
|||||||
}
|
}
|
||||||
// complex handler...
|
// complex handler...
|
||||||
if(typeof(handler) == typeof({}) && handler.constructor.name == 'Object'){
|
if(typeof(handler) == typeof({}) && handler.constructor.name == 'Object'){
|
||||||
var callback = handler[modifers]
|
var callback = handler[modifiers]
|
||||||
if(callback == null){
|
if(callback == null){
|
||||||
callback = handler['default']
|
callback = handler['default']
|
||||||
}
|
}
|
||||||
|
|
||||||
if(callback != null){
|
if(callback != null){
|
||||||
res = callback()
|
res = callback(evt)
|
||||||
did_handling = true
|
did_handling = true
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// simple callback...
|
// simple callback...
|
||||||
//res = handler(evt)
|
//res = handler(evt)
|
||||||
res = handler()
|
res = handler(evt)
|
||||||
// if the handler explicitly returned false break out...
|
// if the handler explicitly returned false break out...
|
||||||
if(res === false){
|
if(res === false){
|
||||||
// XXX is this corrent???
|
// XXX is this corrent???
|
||||||
// XXX should we just break here instead of return...
|
// XXX should we just break here instead of return...
|
||||||
return KEYBOARD_HANDLER_PROPAGATE ? res : null
|
return res
|
||||||
}
|
}
|
||||||
did_handling = true
|
did_handling = true
|
||||||
continue
|
continue
|
||||||
@ -273,18 +307,132 @@ function makeKeyboardHandler(keybindings, unhandled){
|
|||||||
return unhandled(key)
|
return unhandled(key)
|
||||||
} else {
|
} else {
|
||||||
// XXX should we handle multiple hits???
|
// XXX should we handle multiple hits???
|
||||||
return KEYBOARD_HANDLER_PROPAGATE&&res?true:false
|
return res
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// helper...
|
// NOTE: if modifiers are null then this will not resolve aliases that
|
||||||
function doc(text, func){
|
// depend on modifiers and return a complex ahndler as-is.
|
||||||
func.doc = text
|
// NOTE: this will test modes and return only compatible handlers by
|
||||||
return func
|
// default, to return all modes, set all_modes to true.
|
||||||
|
// XXX need an explicit way to prioritize modes...
|
||||||
|
// XXX check do we need did_handling here...
|
||||||
|
function getKeyHandlers(key, modifiers, keybindings, all_modes){
|
||||||
|
var chr = null
|
||||||
|
var did_handling = false
|
||||||
|
modifiers = modifiers == null ? '' : modifiers
|
||||||
|
|
||||||
|
if(typeof(key) == typeof(123)){
|
||||||
|
key = key
|
||||||
|
chr = toKeyName(key)
|
||||||
|
} else {
|
||||||
|
chr = key
|
||||||
|
key = toKeyCode(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
res = {}
|
||||||
|
|
||||||
|
for(var mode in keybindings){
|
||||||
|
|
||||||
|
// test for mode compatibility...
|
||||||
|
if(!all_modes && $(mode).length == 0){
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var bindings = keybindings[mode]
|
||||||
|
|
||||||
|
if(chr in bindings){
|
||||||
|
var handler = bindings[chr]
|
||||||
|
} else {
|
||||||
|
var handler = bindings[key]
|
||||||
|
}
|
||||||
|
|
||||||
|
// alias...
|
||||||
|
while( handler != null
|
||||||
|
&& (typeof(handler) == typeof(123)
|
||||||
|
|| typeof(handler) == typeof('str')
|
||||||
|
|| typeof(handler) == typeof({})
|
||||||
|
&& handler.constructor.name == 'Object') ){
|
||||||
|
|
||||||
|
// do the complex handler aliases...
|
||||||
|
if(typeof(handler) == typeof({}) && handler.constructor.name == 'Object'){
|
||||||
|
if(typeof(handler[modifiers]) == typeof('str')){
|
||||||
|
handler = handler[modifiers]
|
||||||
|
} else if(typeof(handler['default']) == typeof('str')){
|
||||||
|
handler = handler['default']
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// simple handlers...
|
||||||
|
if(handler in bindings){
|
||||||
|
// XXX need to take care of that we can always be a number or a string...
|
||||||
|
handler = bindings[handler]
|
||||||
|
} else if(typeof(handler) == typeof(1)) {
|
||||||
|
handler = bindings[toKeyName(handler)]
|
||||||
|
} else {
|
||||||
|
handler = bindings[toKeyCode(handler)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no handler...
|
||||||
|
if(handler == null){
|
||||||
|
// if something is ignored then just breakout and stop handling...
|
||||||
|
if(bindings.ignore == '*'
|
||||||
|
|| bindings.ignore != null
|
||||||
|
&& (bindings.ignore.indexOf(key) != -1
|
||||||
|
|| bindings.ignore.indexOf(chr) != -1)){
|
||||||
|
did_handling = true
|
||||||
|
// ignoring a key will stop processing it...
|
||||||
|
if(all_modes){
|
||||||
|
res[mode] = 'IGNORE'
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Array, lisp style with docs...
|
||||||
|
if(typeof(handler) == typeof([]) && handler.constructor.name == 'Array'){
|
||||||
|
// we do not care about docs here, so just get the handler...
|
||||||
|
handler = handler[0]
|
||||||
|
}
|
||||||
|
// complex handler...
|
||||||
|
if(typeof(handler) == typeof({}) && handler.constructor.name == 'Object'){
|
||||||
|
var callback = handler[modifiers]
|
||||||
|
if(callback == null){
|
||||||
|
callback = handler['default']
|
||||||
|
}
|
||||||
|
|
||||||
|
if(callback != null){
|
||||||
|
res[mode] = callback
|
||||||
|
|
||||||
|
did_handling = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// simple callback...
|
||||||
|
res[mode] = handler
|
||||||
|
|
||||||
|
did_handling = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if(did_handling){
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Build structure ready for conversion to HTML help.
|
/* Build structure ready for conversion to HTML help.
|
||||||
* Structure:
|
* Structure:
|
||||||
* {
|
* {
|
||||||
@ -299,67 +447,10 @@ function doc(text, func){
|
|||||||
* <keys-spec> - list of key names.
|
* <keys-spec> - list of key names.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function getKeyHandler(key, keybindings){
|
function buildKeybindingsHelp(keybindings){
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function buildKeyindingsHelp(keybindings){
|
|
||||||
var res = {}
|
var res = {}
|
||||||
|
|
||||||
for(var selector in keybindings){
|
// XXX
|
||||||
var section = keybindings[selector]
|
|
||||||
var title = section.title == null ? selector : section.title
|
|
||||||
var res_sec = {
|
|
||||||
doc: section.doc,
|
|
||||||
}
|
|
||||||
res.title = res_sec
|
|
||||||
|
|
||||||
for(var k in section){
|
|
||||||
// handler...
|
|
||||||
var h = section[k]
|
|
||||||
var doc
|
|
||||||
var key = typeof(k) == typeof(1) ? toKeyName(k) : k
|
|
||||||
|
|
||||||
// an alias...
|
|
||||||
while(typeof(h) == typeof(1) || typeof(h) == typeof('s')){
|
|
||||||
if(h in section){
|
|
||||||
// XXX need to take care of that we can always be a number or a string...
|
|
||||||
h = section[h]
|
|
||||||
} else if(typeof(h) == typeof(1)) {
|
|
||||||
h = section[toKeyName(h)]
|
|
||||||
} else {
|
|
||||||
h = section[toKeyCode(h)]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// no handler...
|
|
||||||
if(h == null){
|
|
||||||
doc = 'Nothing'
|
|
||||||
|
|
||||||
// a handler with doc (array)...
|
|
||||||
} else if(typeof(h) == typeof([]) && handler.constructor.name == 'Array'){
|
|
||||||
doc = h[1]
|
|
||||||
|
|
||||||
// complex handler (object)...
|
|
||||||
} else if(typeof(h) == typeof({})){
|
|
||||||
// XXX
|
|
||||||
|
|
||||||
|
|
||||||
// simple handler (function)...
|
|
||||||
} else {
|
|
||||||
doc = h.doc != null ? h.doc : h
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// push the actual data...
|
|
||||||
if(doc in res_sec){
|
|
||||||
res_sec[doc].push(key)
|
|
||||||
} else {
|
|
||||||
res_sec[doc] = [key]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user