diff --git a/ui (gen4)/css/experimenting.css b/ui (gen4)/css/experimenting.css index 905b1027..02c261af 100755 --- a/ui (gen4)/css/experimenting.css +++ b/ui (gen4)/css/experimenting.css @@ -136,6 +136,34 @@ body { /*********************************************************************/ +/* scrollbar setup... */ +.browse-widget ::-webkit-scrollbar { + width: 10px; + height: 10px; +} +.browse-widget ::-webkit-scrollbar-button { + display: none; +} +.browse-widget ::-webkit-scrollbar-track { +} +.browse-widget ::-webkit-scrollbar-track-piece { + background: transparent; +} +.browse-widget ::-webkit-scrollbar-track-piece { + background: rgba(0, 0, 0, 0.05); +} +.browse-widget ::-webkit-scrollbar-thumb { + background: rgba(0, 0, 0, 0.15); +} +.browse-widget ::-webkit-scrollbar-thumb:hover { + background: rgba(0, 0, 0, 0.3); +} +.browse-widget ::-webkit-scrollbar-corner { +} +.browse-widget ::-webkit-resizer { +} + + .browse-widget.cloud-view .list>div { font-size: small; } @@ -214,34 +242,6 @@ body { } -/* scrollbar setup... */ -.browse-widget ::-webkit-scrollbar { - width: 10px; - height: 10px; -} -.browse-widget ::-webkit-scrollbar-button { - display: none; -} -.browse-widget ::-webkit-scrollbar-track { -} -.browse-widget ::-webkit-scrollbar-track-piece { - background: transparent; -} -.browse-widget ::-webkit-scrollbar-track-piece { - background: rgba(0, 0, 0, 0.05); -} -.browse-widget ::-webkit-scrollbar-thumb { - background: rgba(0, 0, 0, 0.15); -} -.browse-widget ::-webkit-scrollbar-thumb:hover { - background: rgba(0, 0, 0, 0.3); -} -.browse-widget ::-webkit-scrollbar-corner { -} -.browse-widget ::-webkit-resizer { -} - - /* Dialog highlight experiment... */ .browse-widget { @@ -300,6 +300,13 @@ body { /* key binding editor... */ +.browse-widget.key-bindings .list>div:not(.selected):not(.mode):nth-child(even) { + background: rgba(0, 0, 0, 0.03); +} +.browse-widget.key-bindings .list>div .button { + background-color: rgba(0, 0, 0, 0.1); +} + .browse-widget.key-bindings .list>.mode { color: white; font-weight: bold; @@ -352,12 +359,6 @@ body { margin-right: 0em; } -.browse-widget.key-bindings .list>div:not(.selected):not(.mode):nth-child(even) { - background: rgba(0, 0, 0, 0.03); -} -.browse-widget.key-bindings .list>.key .button { - background-color: rgba(0, 0, 0, 0.1); -} .browse-widget.key-bindings .list>.new { font-style: italic; diff --git a/ui (gen4)/features/keyboard.js b/ui (gen4)/features/keyboard.js index bd7b9546..bc8dee0b 100755 --- a/ui (gen4)/features/keyboard.js +++ b/ui (gen4)/features/keyboard.js @@ -42,7 +42,6 @@ module.GLOBAL_KEYBOARD = { doc: 'Global bindings that take priority over other sections.', pattern: '*', - // XXX }, 'Slideshow': { @@ -398,6 +397,185 @@ module.GLOBAL_KEYBOARD = { +/*********************************************************************/ + +var KeyboardHandlerProto = { + // object/function + keyboard: null, + context: null, + + // helpers... + shifted: function(key){ + }, + + // get keys for handler... + // + keys: function(handler){ + }, + + // get/set handler for key... + // + handler: function(mode, key, action){ + var that = this + + // XXX normalize key... + var full_key = key + var modifiers = key.split('+') + key = modifiers.pop() + + var code = keyboard.toKeyCode(key) + var args = [].slice.call(arguments).slice(3) + + // set handler... + if(action){ + modes = modes instanceof Array ? modes : [modes] + // ignore all but the first mode... + modes = modes.slice(0, 1) + + // get handler... + } else { + var shift_key = (modifiers.indexOf('shift') >= 0 ? + keyboard._SHIFT_KEYS[key] + : keyboard._UNSHIFT_KEYS[key]) + || '' + var shift_modifiers = shift_key != '' + && (((modifiers.indexOf('shift') >= 0 ? + modifiers.filter(function(k){ return k != 'shift' }) + : modifiers.concat(['shift']))) + || modifiers).join('+') + var full_shift_key = shift_modifiers == '' ? + shift_key + : shift_modifiers +'+'+ shift_key + + var any = modes == 'any' + modes = any ? this.getKeyboardModes() + : modes == '*' ? Object.keys(this.keyboard) + : modes + modes = modes instanceof Array ? modes : [modes] + + // filter modes... + var ignore = false + modes = any ? + modes + .filter(function(mode){ + if(ignore){ + return false + } + + var i = that.keyboard[mode].ignore || [] + + ignore = i.indexOf(full_key) >= 0 + || i.indexOf(key) >= 0 + || i.indexOf(shift_key) >= 0 + || i.indexOf(full_shift_key) >= 0 + || i.indexOf(code) >= 0 + + return true + }) + : modes + } + + modifiers = modifiers.join('+') + + + // search modes... + var res = {} + ignore = false + modes + .forEach(function(mode){ + if(ignore){ + return false + } + + var bindings = that.keyboard[mode] + + if(action){ + var match = 'direct' + var alias = code in bindings ? code : key + + } else { + // direct match... + var match = 'direct' + var alias = full_key in bindings ? full_key + : key in bindings ? key + : null + // shift key match... + match = alias == null ? 'shifted' : match + alias = alias == null ? + (full_shift_key in bindings ? full_shift_key + : shift_key in bindings ? shift_key + : null) + : alias + // code match... + match = alias == null ? 'code' : match + alias = alias == null ? + (code in bindings ? code : null) + : alias + } + + var mod = (match == 'code' || match == 'direct') ? + modifiers + : shift_modifiers + mod = mod == '' ? 'default' : mod + + var handler = alias + + // spin through aliases... + // XXX do we look for aliases in this mode only or in all modes? + var seen = [] + while(handler in bindings){ + // handler loop... + if(seen.indexOf(handler) >= 0){ + return null + } + + alias = handler + handler = bindings[alias] + seen.push(alias) + + // go into the map structure... + if(!action && typeof(handler) != typeof('str')){ + handler = handler[mod] + } + } + + // set the action... + if(action){ + if(handler == null || typeof(handler) == typeof('str')){ + bindings[alias] = modifiers.length == 0 ? + action + : { modifiers : action } + + } else if(modifiers.length == 0){ + handler['default'] = action + + } else { + handler[modifiers] = action + } + + // get the action... + } else { + if(handler){ + res[mode] = handler + } + + ignore = any && handler == 'IGNORE' + } + }) + + return !action ? + (modes.length == 1 ? res[modes[0]] : res) || null + : undefined + }, + + // get applicable modes... + // + modes: function(context){ + }, +} + + + /*********************************************************************/ // XXX add a key binding list UI... // XXX add loading/storing of kb bindings... @@ -618,6 +796,13 @@ var KeyboardActions = actions.Actions({ // new // XXX add view mode (read only)... // XXX BUG sections with doc do not show up in title... + // XXX BUG: + // ig.bindKey('Global', 'X', 'editKeyboardBindings') + // ig.editKeyboardBindings() + // -> shows alt-X instead of X + // ig.bindKey('Global', 'X', 'editKeyboardBindings') + // ig.editKeyboardBindings() + // -> shows two keys ctrl-Z and ctrl-shift-Z instead of Z browseKeyboardBindings: ['Interface/Keyboard bindings...', widgets.makeUIDialog(function(path, edit){ var actions = this @@ -787,7 +972,55 @@ var KeyboardActions = actions.Actions({ // XXX resetKeyBindings: ['Interface/Restore default key bindings', function(){ - this.__keyboard_config = GLOBAL_KEYBOARD }] + this.__keyboard_config = GLOBAL_KEYBOARD }], + + // XXX do we look for aliases in this mode only or in all modes? + getKeyHandler: ['- Interface/', + function(modes, key, action){ + }], + // XXX move this to lib/keyboard.js + // XXX not done yet... + bindKey: ['- Interface/', + function(mode, key, action){ + var modifiers = key.split('+') + key = modifiers.pop() + modifiers = modifiers.join('+') + var code = keyboard.toKeyCode(key) + var args = [].slice.call(arguments).slice(3) + action = action + + (args.length > 0 ? + ': '+ args.map(JSON.stringify).join(' ') + : '') + var bindings = this.keyboard[mode] + + var alias = code in bindings ? code : key + var handler = bindings[key] || bindings[code] + + // spin through aliases... + var seen = [] + while(handler in bindings){ + // handler loop... + if(seen.indexOf(handler) >= 0){ + return null + } + + alias = handler + handler = bindings[alias] + seen.push(alias) + } + + if(handler == null || typeof(handler) == typeof('str')){ + bindings[alias] = modifiers.length == 0 ? + action + : { modifiers : action } + + } else if(modifiers.length == 0){ + handler['default'] = action + + } else { + handler[modifiers] = action + } + }], }) var Keyboard = diff --git a/ui (gen4)/lib/keyboard.js b/ui (gen4)/lib/keyboard.js index 1f3f876a..896ab6c2 100755 --- a/ui (gen4)/lib/keyboard.js +++ b/ui (gen4)/lib/keyboard.js @@ -90,6 +90,13 @@ module._SHIFT_KEYS = { } +var _UNSHIFT_KEYS = +module._UNSHIFT_KEYS = {} +for(var k in _SHIFT_KEYS){ + _UNSHIFT_KEYS[_SHIFT_KEYS[k]] = k +} + + // build a reverse map of _SPECIAL_KEYS var _KEY_CODES = module._KEY_CODES = {} @@ -143,6 +150,8 @@ function doc(text, func){ var getApplicableModes = module.getApplicableModes = function getApplicableModes(keybindings, modes, elem){ + modes = modes || 'any' + return Object.keys(keybindings) .filter(function(title){ @@ -155,13 +164,13 @@ function getApplicableModes(keybindings, modes, elem){ // check if we need to skip this mode... return modes == 'all' // explicit mode match... - || modes == mode + || modes == mode || modes == title // 'any' means we need to check the mode... || (modes == 'any' // '*' always matches... && mode == '*' // match the mode... - // XXX is this too global??? + // XXX is this too global??? -- use elem... || $(mode).length != 0) }) } @@ -423,6 +432,10 @@ function getKeyHandlers(key, modifiers, keybindings, modes, shifted_keys, action continue } + // older version compatibility... + //var mode = keybindings[title].pattern || title + var mode = title + // If a key is ignored then look no further... if(did_ignore){ if(modes != 'all'){ @@ -435,9 +448,6 @@ function getKeyHandlers(key, modifiers, keybindings, modes, shifted_keys, action } } - // older version compatibility... - var mode = keybindings[title].pattern || title - // check if we need to skip this mode... if(applicable_modes.indexOf(title) < 0){ continue @@ -818,32 +828,23 @@ function buildKeybindingsHelp(keybindings, shifted_keys, actions, doc_getter){ for(var title in keybindings){ mode = keybindings[title] - // older version compatibility... - if(keybindings[title].pattern != null){ - var pattern = keybindings[title].pattern - } else { - var pattern = title - // titles and docs... - var title = mode.title == null ? pattern : mode.title - } - - res[title] = { - doc: mode.doc == null ? '' : mode.doc - } - section = res[title] + var section = + res[title] = { + doc: mode.doc == null ? '' : mode.doc + } // handlers... for(var key in mode){ if(KEYBOARD_SYSTEM_ATTRS.indexOf(key) >= 0){ continue } - var modifiers = getKeyHandlers(key, '?', keybindings, 'all', null, actions)[pattern] + var modifiers = getKeyHandlers(key, '?', keybindings, 'all', null, actions)[title] modifiers = modifiers == 'none' || modifiers == undefined ? [''] : modifiers for(var i=0; i < modifiers.length; i++){ var mod = modifiers[i] - var handler = getKeyHandlers(key, mod, keybindings, 'all', null, actions)[pattern] + var handler = getKeyHandlers(key, mod, keybindings, 'all', null, actions)[title] // no handler...