From 3c4b538b7ab2619248742a421f0b6fb9dfffe8de Mon Sep 17 00:00:00 2001 From: "Alex A. Naanou" Date: Thu, 12 Jan 2017 21:23:16 +0300 Subject: [PATCH] tweaking, refactoring and .keyHandler(..) action/event (experimental)... Signed-off-by: Alex A. Naanou --- ui (gen4)/features/keyboard.js | 110 +++++++++++++++++++-------------- ui (gen4)/lib/keyboard.js | 98 ++++++++++++++++++++++++----- ui (gen4)/lib/widget/browse.js | 8 ++- 3 files changed, 155 insertions(+), 61 deletions(-) diff --git a/ui (gen4)/features/keyboard.js b/ui (gen4)/features/keyboard.js index a09f82c2..811b72f2 100755 --- a/ui (gen4)/features/keyboard.js +++ b/ui (gen4)/features/keyboard.js @@ -69,8 +69,8 @@ module.GLOBAL_KEYBOARD2 = { // handle in next section... - '(': 'NEXT_SECTION', - ')': 'NEXT_SECTION', + '(': 'NEXT', + ')': 'NEXT', // zooming... '#1': 'fitScreen', @@ -388,21 +388,6 @@ module.GLOBAL_KEYBOARD2 = { -//--------------------------------------------------------------------- - -/*/ XXX DEBUG: remove when done... -window.kb = keyboard.Keyboard( - GLOBAL_KEYBOARD, - function checkGlobalMode(mode, keyboard, context){ - var pattern = keyboard[mode].pattern - return !pattern - || pattern == '*' - || $(keyboard[mode].pattern).length > 0 }) -//*/ - - - - /*********************************************************************/ // XXX add loading/storing of kb bindings... @@ -429,6 +414,14 @@ var KeyboardActions = actions.Actions({ // the handler by cycling the toggler off and on... // NOTE: the target element must be focusable... 'keyboard-event-source': 'window', + + // If true enable .keyPressed(..) action calling on keyboard + // activity... + // + // NOTE: if updated the keyboard handler will need to be restarted + // for changes to take effect. + // XXX EXPERIMENTAL + 'keyboard-key-pressed-action': false, }, get keybindings(){ @@ -569,6 +562,8 @@ var KeyboardActions = actions.Actions({ toggleKeyboardHandling: ['- Interface/Keyboard handling', toggler.Toggler(null, function(_, state){ + var that = this + if(state == null){ return this.__keyboard_handler ? 'on' : 'off' } @@ -591,6 +586,24 @@ var KeyboardActions = actions.Actions({ return true }).bind(this) + // pass keys pressed to .keyPressed(..) action... + // XXX EXPERIMENTAL... + var keyPressdCall = function(handler){ + return that.config['keyboard-key-pressed-action'] ? + function(evt){ + var e = that.keyPressed.pre( + that, + [keyboard.joinKey(keyboard.event2key(evt))]) + + var res = handler.apply(that, arguments) + e.result = res + + that.keyPressed.post(that, e) + return res + } + : handler + } + var kb = this.__keyboard_object = this.__keyboard_object || keyboard.KeyboardWithCSSModes( @@ -599,8 +612,6 @@ var KeyboardActions = actions.Actions({ // start/reset keyboard handling... if(state == 'on'){ - var that = this - // NOTE: the target element must be focusable... var target = this.__keyboard_event_source = @@ -611,41 +622,35 @@ var KeyboardActions = actions.Actions({ : $(this.config['keyboard-event-source']) // need to reset... - if(this.__keyboard_handler != null){ - target.off('keydown', this.__keyboard_handler) - } + this.__keyboard_handler + && target.off('keydown', this.__keyboard_handler) + + // make the base handler... + var handler = + keyboard.stoppableKeyboardRepeat( + // XXX EXPERIMENTAL... + keyPressdCall( + keyboard.makeKeyboardHandler( + this.keyboard, + function(k){ window.DEBUG && console.log('KEY:', k) }, + this)), + check) // setup base keyboard for devel, in case something breaks... // This branch does not drop keys... if(this.config['max-key-repeat-rate'] < 0 || this.config['max-key-repeat-rate'] == null){ - //this.ribbons.viewer - var handler = - this.__keyboard_handler = - keyboard.stoppableKeyboardRepeat( - keyboard.makeKeyboardHandler( - this.keyboard, - //function(){ return that.__keyboard_config }, - function(k){ window.DEBUG && console.log('KEY:', k) }, - this), - check) + this.__keyboard_handler = handler // drop keys if repeating too fast... // NOTE: this is done for smoother animations... } else { - var handler = + handler = this.__keyboard_handler = - keyboard.stoppableKeyboardRepeat( - keyboard.dropRepeatingkeys( - keyboard.makeKeyboardHandler( - this.keyboard, - //function(){ return that.__keyboard_config }, - function(k){ window.DEBUG && console.log(k) }, - this), - function(){ - return that.config['max-key-repeat-rate'] - }), - check) + keyboard.dropRepeatingkeys( + handler, + function(){ + return that.config['max-key-repeat-rate'] }) } target.keydown(handler) @@ -663,6 +668,21 @@ var KeyboardActions = actions.Actions({ }, ['on', 'off'])], + // XXX EXPERIMENTAL: event for actions to be able to handle keys... + // ...not working yet... + // XXX not sure if we need this... + // ...the main reason being that this may be a way to bypass the + // .keyboard handler and config and handle keys within an action + // if overdone this can be a mess... + keyPressed: ['- Interface/Key pressed event', + 'This is called by the keyboard handler when a key is pressed, ' + +'the key is passed as argument.', + core.notUserCallable(function(key){ + // This is the keyboard hook protocol root function + // + // Not for direct use. + })], + // interface stuff... @@ -715,7 +735,7 @@ var KeyboardActions = actions.Actions({ { not_filtered_out: true, // XXX should sections be searchable??? - //not_searchable: true, + not_searchable: true, }) .addClass('mode') diff --git a/ui (gen4)/lib/keyboard.js b/ui (gen4)/lib/keyboard.js index 117a0e76..e9501655 100755 --- a/ui (gen4)/lib/keyboard.js +++ b/ui (gen4)/lib/keyboard.js @@ -182,7 +182,12 @@ function event2key(evt){ evt.altKey && key.push('alt') evt.metaKey && key.push('meta') evt.shiftKey && key.push('shift') - key.push(code2key(evt.keyCode)) + + var k = code2key(evt.keyCode) + + // add the key if it's not already in, this can happen if we just + // pressed a modifier key... + key.indexOf(k.toLowerCase()) < 0 && key.push(k) return key } @@ -241,6 +246,12 @@ function splitKey(key){ .concat(sep.indexOf(key.slice(-1)) >= 0 ? key.slice(-1) : []) .filter(function(c){ return c != '' }) } +var joinKey = +module.joinKey = +function joinKey(key){ + return key instanceof Array ? + key.join(KEY_SEPARATORS[0] || '+') + : key } // Normalize key string/array... // @@ -276,7 +287,7 @@ function normalizeKey(key){ return output == 'array' ? key - : key.join(KEY_SEPARATORS[0] || '+') + : joinKey(key) } @@ -305,7 +316,7 @@ function shifted(key){ return s == null ? null : output == 'string' ? - res.join(KEY_SEPARATORS[0] || '+') + joinKey(res) : res } @@ -314,6 +325,63 @@ function shifted(key){ /*********************************************************************/ // Generic keyboard handler... +// +// Key binding format: +// { +// : { +// doc: , +// +// // list of keys to drop after this section is done. +// // +// // Setting this to '*' will drop all keys... +// // +// // NOTE: these keys will be handled in current section. +// // NOTE: these keys will not get propagated to the next +// // matching section... +// // NOTE: it is possible to override this and explicitly pass +// // a key to the next section via 'NEXT' (see below). +// drop: [ , ... ] | '*', +// +// // Key mapped to action... +// // +// // NOTE: the system poses no restrictions on action format, +// // but it is recommended to stick to strings or use the +// // doc(..) wrapper... +// : , +// +// // Key mapped to an alias... +// // +// // An alias is any string that is also a key in bindings, it +// // can be just a string or a key, when matching the string of +// // aliases will be resolved till either an action (non-alias) +// // is found or a loop is detected. +// // +// // NOTE: in case of a loop, nothing will get called... +// : | , +// +// // Alias-action mapping... +// : , +// +// // Explicitly drop key... +// // +// // NOTE: this is similar in effect to .drop +// : 'DROP', +// +// // Explicitly pass key to next section... +// // +// // This can be useful when it is needed to drop all keys +// // except for a small sub-group, this can be dune by setting +// // .drop to '*' (drop all) and explicitly setting the keys to +// // be propagated to 'NEXT'. +// // +// // NOTE: his takes precedence over .drop +// : 'NEXT', +// +// ... +// }, +// ... +// } +// var KeyboardClassPrototype = { service_fields: ['doc', 'drop'], @@ -323,6 +391,7 @@ var KeyboardClassPrototype = { code2key: code2key, isKey: isKey, splitKey: splitKey, + joinKey: joinKey, normalizeKey: normalizeKey, shifted: shifted } @@ -331,7 +400,7 @@ var KeyboardPrototype = { //service_fields: ['doc', 'drop'], special_handlers: { DROP: 'drop key', - NEXT_SECTION: 'handle key in next section', + NEXT: 'handle key in next section', }, // Format: @@ -349,11 +418,11 @@ var KeyboardPrototype = { // } // // Reserved special handlers: - // - DROP - drop checking of key - // NOTE: this will prevent handling next sections - // for this key. - // - NEXT_SECTION - force check next section, this has priority - // over .drop + // - DROP - drop checking of key + // NOTE: this will prevent handling next sections + // for this key. + // - NEXT - force check next section, this has priority + // over .drop // __keyboard: null, get keyboard(){ @@ -372,6 +441,7 @@ var KeyboardPrototype = { code2key: KeyboardClassPrototype.code2key, shifted: KeyboardClassPrototype.shifted, splitKey: KeyboardClassPrototype.splitKey, + joinKey: KeyboardClassPrototype.joinKey, normalizeKey: KeyboardClassPrototype.normalizeKey, isKey: KeyboardClassPrototype.isKey, @@ -435,10 +505,10 @@ var KeyboardPrototype = { mod = mod || [] if(key in rev){ rev[key].forEach(function(k){ - k = that.normalizeKey(mod - .concat(that.splitKey(k)) - .unique() - .join(key_separators[0])) + k = that.normalizeKey( + that.joinKey(mod + .concat(that.splitKey(k)) + .unique())) res.indexOf(k) < 0 && res.push(k) && walkAliases(res, rev, bindings, k, mod) @@ -688,7 +758,7 @@ var KeyboardPrototype = { // if key in .drop then ignore the rest... if(drop // explicit go to next section... - && handler != 'NEXT_SECTION' + && handler != 'NEXT' && (bindings.drop == '*' // XXX should this be more flexible by adding a // specific key combo? diff --git a/ui (gen4)/lib/widget/browse.js b/ui (gen4)/lib/widget/browse.js index f7cd6cd0..2e357592 100755 --- a/ui (gen4)/lib/widget/browse.js +++ b/ui (gen4)/lib/widget/browse.js @@ -380,6 +380,10 @@ var BrowserPrototype = { // keep text editing action from affecting the selection... drop: '*', + // XXX not sure about this... + Up: 'NEXT', + Down: 'NEXT', + Enter: 'push!', Esc: 'update!', }, @@ -400,8 +404,8 @@ var BrowserPrototype = { // keep text editing action from affecting the selection... drop: '*', - Up: 'NEXT_SECTION', - Down: 'NEXT_SECTION', + Up: 'NEXT', + Down: 'NEXT', Enter: 'push!', Esc: 'stopFilter!',