mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-28 18:00:09 +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...
|
||||
//Enter: 'toggleSingleImage',
|
||||
Enter: 'debounce: 500 "toggleSingleImage" -- Toggle single image mode (debounced)',
|
||||
Enter: '@500 toggleSingleImage',
|
||||
S: 'slideshowDialog',
|
||||
|
||||
|
||||
@ -513,6 +512,120 @@ var KeyboardActions = actions.Actions({
|
||||
function(){ return that.dom })
|
||||
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/',
|
||||
core.doc`Self-test action keyboard configuration.`,
|
||||
{self_test: true},
|
||||
@ -529,7 +642,8 @@ var KeyboardActions = actions.Actions({
|
||||
|
||||
// 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...
|
||||
if(a.action == ''){
|
||||
return
|
||||
@ -691,7 +805,8 @@ var KeyboardActions = actions.Actions({
|
||||
// - .no_default
|
||||
// - .stop_propagation
|
||||
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 ?
|
||||
a.action
|
||||
+(a.arguments.length > 0 ?
|
||||
@ -838,56 +953,6 @@ var KeyboardActions = actions.Actions({
|
||||
this.config['keyboard-repeat-pause-check'] > 0
|
||||
&& 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 =
|
||||
@ -913,7 +978,8 @@ module.Keyboard = core.ImageGridFeatures.Feature({
|
||||
this.__keyboard_config = this.keybindings || GLOBAL_KEYBOARD
|
||||
|
||||
// string action call parser...
|
||||
this.parseStringHandler = this.parseStringAction
|
||||
//this.parseStringHandler = this.parseStringAction
|
||||
//this.parseStringHandler = this.parseStringActionWithDebounce
|
||||
|
||||
this.toggleKeyboardHandling('on')
|
||||
}],
|
||||
@ -1069,7 +1135,8 @@ var KeyboardUIActions = actions.Actions({
|
||||
var c = 0
|
||||
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){
|
||||
var doc = ''
|
||||
@ -1419,7 +1486,8 @@ var KeyboardUIActions = actions.Actions({
|
||||
['⋯', function(evt, elem){
|
||||
code = code || ''
|
||||
// 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 ?
|
||||
that.getDocPath(a.action)
|
||||
: ''
|
||||
@ -1444,6 +1512,9 @@ var KeyboardUIActions = actions.Actions({
|
||||
.on('edit-commit',
|
||||
function(evt, text){ code = text })
|
||||
|
||||
// XXX should we edit/view this separately???
|
||||
//make(['Debounce:', that.parseStringHandler(code).debounce || ''])
|
||||
|
||||
make('---')
|
||||
|
||||
make.EditableList(keys, {
|
||||
|
||||
@ -536,6 +536,18 @@ var KeyboardPrototype = {
|
||||
// XXX revise name...
|
||||
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...
|
||||
event2key: KeyboardClassPrototype.event2key,
|
||||
@ -1193,7 +1205,9 @@ function makeKeyboardHandler(keyboard, unhandled, actions){
|
||||
// action call syntax...
|
||||
// XXX should this be a Keyboard thing or a context thing???
|
||||
} 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('.') : []
|
||||
|
||||
if(path.length > 0 && path[0] in actions){
|
||||
@ -1204,13 +1218,9 @@ function makeKeyboardHandler(keyboard, unhandled, actions){
|
||||
&& evt.preventDefault()
|
||||
|
||||
// call the handler...
|
||||
var context = actions
|
||||
res = path
|
||||
.reduce(function(res, k){
|
||||
context = res
|
||||
return res[k]
|
||||
}, actions)
|
||||
.apply(context, h.arguments)
|
||||
res = actions.callKeyboardHandler ?
|
||||
actions.callKeyboardHandler(h, actions)
|
||||
: kb.callKeyboardHandler(h, actions)
|
||||
|
||||
evt
|
||||
&& 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",
|
||||
"version": "4.0.0a",
|
||||
"version": "4.0.0-a",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@ -1141,11 +1141,11 @@
|
||||
"integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
|
||||
},
|
||||
"ig-actions": {
|
||||
"version": "3.19.3",
|
||||
"resolved": "https://registry.npmjs.org/ig-actions/-/ig-actions-3.19.3.tgz",
|
||||
"integrity": "sha512-UPhN/RVUGNJ9PSV/zrgZNDDm5ySPYvcrRTheHZ5QW/UtdKtEI0CGTbmTVGuEAXH/Ag23KexJnUUlnSrtU5Jsjw==",
|
||||
"version": "3.20.0",
|
||||
"resolved": "https://registry.npmjs.org/ig-actions/-/ig-actions-3.20.0.tgz",
|
||||
"integrity": "sha512-TcKAJg3ZtbZC7IiaNW/cMgwDkEt5xrr8hsTsoH0UTA9gQSIlnp6TACxcTW/gOS9lQiK82yDYHMrmH12Yn6+SFg==",
|
||||
"requires": {
|
||||
"ig-object": "^1.0.0"
|
||||
"ig-object": "^1.0.7"
|
||||
}
|
||||
},
|
||||
"ig-features": {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user