mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 10:20:08 +00:00
added key-speciffic debounce support (see: 'Enter' kandling)...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
aa0760fcb9
commit
8ff734bf65
@ -256,8 +256,7 @@ module.GLOBAL_KEYBOARD = {
|
|||||||
|
|
||||||
|
|
||||||
// modes...
|
// modes...
|
||||||
//Enter: 'toggleSingleImage',
|
Enter: '@500 toggleSingleImage',
|
||||||
Enter: 'debounce: 500 "toggleSingleImage" -- Toggle single image mode (debounced)',
|
|
||||||
S: 'slideshowDialog',
|
S: 'slideshowDialog',
|
||||||
|
|
||||||
|
|
||||||
@ -513,6 +512,120 @@ var KeyboardActions = actions.Actions({
|
|||||||
function(){ return that.dom })
|
function(){ return that.dom })
|
||||||
return kb },
|
return kb },
|
||||||
|
|
||||||
|
debounce: ['- Interface/',
|
||||||
|
core.doc`Debounce action call...
|
||||||
|
|
||||||
|
Debounce call an action...
|
||||||
|
.debounce(action, ...)
|
||||||
|
.debounce(timeout, action, ...)
|
||||||
|
.debounce(tag, action, ...)
|
||||||
|
.debounce(timeout, tag, action, ...)
|
||||||
|
|
||||||
|
Debounce call a function...
|
||||||
|
.debounce(tag, func, ...)
|
||||||
|
.debounce(timeout, tag, func, ...)
|
||||||
|
|
||||||
|
NOTE: when using a tag, it must not resolve to and action, i.e.
|
||||||
|
this[tag] must not be callable...
|
||||||
|
NOTE: this ignores action return value and returns this...
|
||||||
|
`,
|
||||||
|
function(...args){
|
||||||
|
// parse the args...
|
||||||
|
var timeout = typeof(args[0]) == typeof(123) ?
|
||||||
|
args.shift()
|
||||||
|
: (this.config['debounce-action-timeout'] || 200)
|
||||||
|
// NOTE: this[tag] must not be callable, otherwise we treat it
|
||||||
|
// as an action...
|
||||||
|
var tag = (args[0] instanceof Function
|
||||||
|
|| this[args[0]] instanceof Function) ?
|
||||||
|
args[0]
|
||||||
|
: args.shift()
|
||||||
|
var action = args.shift()
|
||||||
|
|
||||||
|
// when debouncing a function a tag is required...
|
||||||
|
if(tag instanceof Function){
|
||||||
|
throw new TypeError('debounce: when passing a function a tag is required.')
|
||||||
|
}
|
||||||
|
|
||||||
|
var attr = '__debounce_'+ tag
|
||||||
|
|
||||||
|
// repeated call...
|
||||||
|
if(this[attr]){
|
||||||
|
this[attr +'_retriggered'] = true
|
||||||
|
|
||||||
|
// setup and first call...
|
||||||
|
} else {
|
||||||
|
// NOTE: we are ignoring the return value here so as to
|
||||||
|
// make the first and repeated call uniform...
|
||||||
|
var context = this
|
||||||
|
;(action instanceof Function ?
|
||||||
|
action
|
||||||
|
: action.split('.')
|
||||||
|
.reduce(function(res, e){
|
||||||
|
context = res
|
||||||
|
return res[e]
|
||||||
|
}, this))
|
||||||
|
.call(context, ...args)
|
||||||
|
|
||||||
|
this[attr] = setTimeout(function(){
|
||||||
|
delete this[attr]
|
||||||
|
|
||||||
|
// retrigger...
|
||||||
|
if(this[attr +'_retriggered']){
|
||||||
|
delete this[attr +'_retriggered']
|
||||||
|
|
||||||
|
tag == action ?
|
||||||
|
this.debounce(timeout, action, ...args)
|
||||||
|
: this.debounce(timeout, tag, action, ...args)
|
||||||
|
}
|
||||||
|
}.bind(this), timeout)
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
|
||||||
|
// Add debounce support to keyboard handling...
|
||||||
|
//
|
||||||
|
// NOTE: these are not actions to make the call as light as possible...
|
||||||
|
parseStringHandler: function(txt, ...rest){
|
||||||
|
var debounce = 0
|
||||||
|
var scale = {
|
||||||
|
ms: 1,
|
||||||
|
s: 1000,
|
||||||
|
m: 1000 * 60,
|
||||||
|
h: 1000 * 60 * 60,
|
||||||
|
}
|
||||||
|
txt = txt.replace(/^\s*@([^\s]*)\s*/,
|
||||||
|
function(_, time){
|
||||||
|
var unit = time
|
||||||
|
.replace(/(\d+|\d*\.\d+)(h|m|s|ms)/, '$2')
|
||||||
|
unit = unit == time ? 'ms' : unit
|
||||||
|
debounce = parseFloat(time) * scale[unit]
|
||||||
|
return ''
|
||||||
|
})
|
||||||
|
|
||||||
|
return debounce > 0 ?
|
||||||
|
Object.assign(
|
||||||
|
this.parseStringAction(txt, ...rest),
|
||||||
|
{debounce: debounce})
|
||||||
|
: this.parseStringAction(txt, ...rest)
|
||||||
|
},
|
||||||
|
callKeyboardHandler: function(data, context){
|
||||||
|
context = context || this
|
||||||
|
var meth = data.action
|
||||||
|
.split('.')
|
||||||
|
.reduce(function(res, e){
|
||||||
|
context = res
|
||||||
|
return res[e]
|
||||||
|
}, this)
|
||||||
|
return data.debounce ?
|
||||||
|
// debounce...
|
||||||
|
this.debounce(
|
||||||
|
data.debounce,
|
||||||
|
'tag:'+data.action,
|
||||||
|
meth.bind(context), ...data.arguments)
|
||||||
|
// direct call...
|
||||||
|
: meth.call(context, ...data.arguments) },
|
||||||
|
|
||||||
|
|
||||||
testKeyboardDoc: ['- Interface/',
|
testKeyboardDoc: ['- Interface/',
|
||||||
core.doc`Self-test action keyboard configuration.`,
|
core.doc`Self-test action keyboard configuration.`,
|
||||||
{self_test: true},
|
{self_test: true},
|
||||||
@ -529,7 +642,8 @@ var KeyboardActions = actions.Actions({
|
|||||||
|
|
||||||
// XXX we should also check if code is a key (i.e. alias)...
|
// XXX we should also check if code is a key (i.e. alias)...
|
||||||
|
|
||||||
var a = keyboard.parseActionCall(code, that)
|
//var a = keyboard.parseActionCall(code, that)
|
||||||
|
var a = that.parseStringHandler(code, that)
|
||||||
// skip aliases that look like actions (namely ':') and bad actions...
|
// skip aliases that look like actions (namely ':') and bad actions...
|
||||||
if(a.action == ''){
|
if(a.action == ''){
|
||||||
return
|
return
|
||||||
@ -691,7 +805,8 @@ var KeyboardActions = actions.Actions({
|
|||||||
// - .no_default
|
// - .no_default
|
||||||
// - .stop_propagation
|
// - .stop_propagation
|
||||||
var normalizeHandler = function(action){
|
var normalizeHandler = function(action){
|
||||||
var a = keyboard.parseActionCall(action.doc || action, that)
|
//var a = keyboard.parseActionCall(action.doc || action, that)
|
||||||
|
var a = that.parseStringHandler(action.doc || action, that)
|
||||||
return a.action in that ?
|
return a.action in that ?
|
||||||
a.action
|
a.action
|
||||||
+(a.arguments.length > 0 ?
|
+(a.arguments.length > 0 ?
|
||||||
@ -838,56 +953,6 @@ var KeyboardActions = actions.Actions({
|
|||||||
this.config['keyboard-repeat-pause-check'] > 0
|
this.config['keyboard-repeat-pause-check'] > 0
|
||||||
&& this.keyboard.pauseRepeat
|
&& this.keyboard.pauseRepeat
|
||||||
&& this.keyboard.pauseRepeat() }],
|
&& this.keyboard.pauseRepeat() }],
|
||||||
|
|
||||||
debounce: ['- Interface/',
|
|
||||||
core.doc`Debounce action call...
|
|
||||||
|
|
||||||
.debounce(action, ...)
|
|
||||||
.debounce(timeout, action, ...)
|
|
||||||
.debounce(timeout, tag, action, ...)
|
|
||||||
|
|
||||||
NOTE: when using a tag, it must not resolve to and action, i.e.
|
|
||||||
this[tag] must not be callable...
|
|
||||||
NOTE: this ignores action return value and returns this...
|
|
||||||
`,
|
|
||||||
function(...args){
|
|
||||||
// parse the args...
|
|
||||||
var timeout = typeof(args[0]) == typeof(123) ?
|
|
||||||
args.shift()
|
|
||||||
: (this.config['debounce-action-timeout'] || 200)
|
|
||||||
// NOTE: this[tag] must not be callable, otherwise we treat it
|
|
||||||
// as an action...
|
|
||||||
var tag = this[args[0]] instanceof Function ?
|
|
||||||
args[0]
|
|
||||||
: args.shift()
|
|
||||||
var action = args.shift()
|
|
||||||
|
|
||||||
var attr = '__debounce_'+ tag
|
|
||||||
|
|
||||||
// repeated call...
|
|
||||||
if(this[attr]){
|
|
||||||
this[attr +'_retriggered'] = true
|
|
||||||
|
|
||||||
// setup and first call...
|
|
||||||
} else {
|
|
||||||
// NOTE: we are ignoring the return value here so as to
|
|
||||||
// make the first and repeated call uniform...
|
|
||||||
this[action](...args)
|
|
||||||
|
|
||||||
this[attr] = setTimeout(function(){
|
|
||||||
delete this[attr]
|
|
||||||
|
|
||||||
// retrigger...
|
|
||||||
if(this[attr +'_retriggered']){
|
|
||||||
delete this[attr +'_retriggered']
|
|
||||||
|
|
||||||
tag == action ?
|
|
||||||
this.debounce(timeout, action, ...args)
|
|
||||||
: this.debounce(timeout, tag, action, ...args)
|
|
||||||
}
|
|
||||||
}.bind(this), timeout)
|
|
||||||
}
|
|
||||||
}],
|
|
||||||
})
|
})
|
||||||
|
|
||||||
var Keyboard =
|
var Keyboard =
|
||||||
@ -913,7 +978,8 @@ module.Keyboard = core.ImageGridFeatures.Feature({
|
|||||||
this.__keyboard_config = this.keybindings || GLOBAL_KEYBOARD
|
this.__keyboard_config = this.keybindings || GLOBAL_KEYBOARD
|
||||||
|
|
||||||
// string action call parser...
|
// string action call parser...
|
||||||
this.parseStringHandler = this.parseStringAction
|
//this.parseStringHandler = this.parseStringAction
|
||||||
|
//this.parseStringHandler = this.parseStringActionWithDebounce
|
||||||
|
|
||||||
this.toggleKeyboardHandling('on')
|
this.toggleKeyboardHandling('on')
|
||||||
}],
|
}],
|
||||||
@ -1069,7 +1135,8 @@ var KeyboardUIActions = actions.Actions({
|
|||||||
var c = 0
|
var c = 0
|
||||||
Object.keys(keys[mode] || {}).forEach(function(action){
|
Object.keys(keys[mode] || {}).forEach(function(action){
|
||||||
|
|
||||||
var o = keyboard.parseActionCall(action, that)
|
//var o = keyboard.parseActionCall(action, that)
|
||||||
|
var o = that.parseStringHandler(action, that)
|
||||||
|
|
||||||
if(getKeyText){
|
if(getKeyText){
|
||||||
var doc = ''
|
var doc = ''
|
||||||
@ -1419,7 +1486,8 @@ var KeyboardUIActions = actions.Actions({
|
|||||||
['⋯', function(evt, elem){
|
['⋯', function(evt, elem){
|
||||||
code = code || ''
|
code = code || ''
|
||||||
// highlight the current action...
|
// highlight the current action...
|
||||||
var a = keyboard.parseActionCall(code, that)
|
//var a = keyboard.parseActionCall(code, that)
|
||||||
|
var a = that.parseStringHandler(code, that)
|
||||||
var p = a.action in that ?
|
var p = a.action in that ?
|
||||||
that.getDocPath(a.action)
|
that.getDocPath(a.action)
|
||||||
: ''
|
: ''
|
||||||
@ -1444,6 +1512,9 @@ var KeyboardUIActions = actions.Actions({
|
|||||||
.on('edit-commit',
|
.on('edit-commit',
|
||||||
function(evt, text){ code = text })
|
function(evt, text){ code = text })
|
||||||
|
|
||||||
|
// XXX should we edit/view this separately???
|
||||||
|
//make(['Debounce:', that.parseStringHandler(code).debounce || ''])
|
||||||
|
|
||||||
make('---')
|
make('---')
|
||||||
|
|
||||||
make.EditableList(keys, {
|
make.EditableList(keys, {
|
||||||
|
|||||||
@ -536,6 +536,18 @@ var KeyboardPrototype = {
|
|||||||
// XXX revise name...
|
// XXX revise name...
|
||||||
parseStringHandler: parseActionCall,
|
parseStringHandler: parseActionCall,
|
||||||
|
|
||||||
|
// call keyboard handler...
|
||||||
|
//
|
||||||
|
callKeyboardHandler: function(data, context){
|
||||||
|
// call the handler...
|
||||||
|
return data.action
|
||||||
|
.split('.')
|
||||||
|
.reduce(function(res, k){
|
||||||
|
context = res
|
||||||
|
return res[k]
|
||||||
|
}, context)
|
||||||
|
.apply(context, h.arguments) },
|
||||||
|
|
||||||
|
|
||||||
// utils...
|
// utils...
|
||||||
event2key: KeyboardClassPrototype.event2key,
|
event2key: KeyboardClassPrototype.event2key,
|
||||||
@ -1193,7 +1205,9 @@ function makeKeyboardHandler(keyboard, unhandled, actions){
|
|||||||
// action call syntax...
|
// action call syntax...
|
||||||
// XXX should this be a Keyboard thing or a context thing???
|
// XXX should this be a Keyboard thing or a context thing???
|
||||||
} else if(actions.parseStringHandler || kb.parseStringHandler){
|
} else if(actions.parseStringHandler || kb.parseStringHandler){
|
||||||
var h = (actions.parseStringHandler || kb.parseStringHandler)(handler, actions)
|
var h = actions.parseStringHandler ?
|
||||||
|
actions.parseStringHandler(handler, actions)
|
||||||
|
: kb.parseStringHandler(handler, actions)
|
||||||
var path = h ? h.action.split('.') : []
|
var path = h ? h.action.split('.') : []
|
||||||
|
|
||||||
if(path.length > 0 && path[0] in actions){
|
if(path.length > 0 && path[0] in actions){
|
||||||
@ -1204,13 +1218,9 @@ function makeKeyboardHandler(keyboard, unhandled, actions){
|
|||||||
&& evt.preventDefault()
|
&& evt.preventDefault()
|
||||||
|
|
||||||
// call the handler...
|
// call the handler...
|
||||||
var context = actions
|
res = actions.callKeyboardHandler ?
|
||||||
res = path
|
actions.callKeyboardHandler(h, actions)
|
||||||
.reduce(function(res, k){
|
: kb.callKeyboardHandler(h, actions)
|
||||||
context = res
|
|
||||||
return res[k]
|
|
||||||
}, actions)
|
|
||||||
.apply(context, h.arguments)
|
|
||||||
|
|
||||||
evt
|
evt
|
||||||
&& h.stop_propagation
|
&& h.stop_propagation
|
||||||
|
|||||||
10
ui (gen4)/package-lock.json
generated
10
ui (gen4)/package-lock.json
generated
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ImageGrid.Viewer.g4",
|
"name": "ImageGrid.Viewer.g4",
|
||||||
"version": "4.0.0a",
|
"version": "4.0.0-a",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -1141,11 +1141,11 @@
|
|||||||
"integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
|
"integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
|
||||||
},
|
},
|
||||||
"ig-actions": {
|
"ig-actions": {
|
||||||
"version": "3.19.3",
|
"version": "3.20.0",
|
||||||
"resolved": "https://registry.npmjs.org/ig-actions/-/ig-actions-3.19.3.tgz",
|
"resolved": "https://registry.npmjs.org/ig-actions/-/ig-actions-3.20.0.tgz",
|
||||||
"integrity": "sha512-UPhN/RVUGNJ9PSV/zrgZNDDm5ySPYvcrRTheHZ5QW/UtdKtEI0CGTbmTVGuEAXH/Ag23KexJnUUlnSrtU5Jsjw==",
|
"integrity": "sha512-TcKAJg3ZtbZC7IiaNW/cMgwDkEt5xrr8hsTsoH0UTA9gQSIlnp6TACxcTW/gOS9lQiK82yDYHMrmH12Yn6+SFg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"ig-object": "^1.0.0"
|
"ig-object": "^1.0.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ig-features": {
|
"ig-features": {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user