From 320290861b962d53411c320f7a4229cef6a7a31f Mon Sep 17 00:00:00 2001 From: "Alex A. Naanou" Date: Sat, 28 Jan 2017 01:09:05 +0300 Subject: [PATCH] added full support for browse item sortcut keys + refactoring... Signed-off-by: Alex A. Naanou --- ui (gen4)/features/history.js | 2 - ui (gen4)/features/keyboard.js | 5 -- ui (gen4)/features/ui-slideshow.js | 8 +-- ui (gen4)/features/ui-widgets.js | 38 ++++++++++---- ui (gen4)/lib/widget/browse.js | 83 +++++++++++++++++++----------- 5 files changed, 83 insertions(+), 53 deletions(-) diff --git a/ui (gen4)/features/history.js b/ui (gen4)/features/history.js index 68bb6bb2..ab5fc3d1 100755 --- a/ui (gen4)/features/history.js +++ b/ui (gen4)/features/history.js @@ -632,8 +632,6 @@ var URLHistoryUIActions = actions.Actions({ reason != 'reject' && o.close(reason) }) } - // clone the bindings so as not to mess up the global browser... - o.keybindings = JSON.parse(JSON.stringify(o.keybindings)) o.keyboard.handler('General', 'O', 'browsePath') return o diff --git a/ui (gen4)/features/keyboard.js b/ui (gen4)/features/keyboard.js index c55ac650..6f3011a9 100755 --- a/ui (gen4)/features/keyboard.js +++ b/ui (gen4)/features/keyboard.js @@ -1233,8 +1233,6 @@ var KeyboardUIActions = actions.Actions({ dialog.newMode = function(){ that.editKeyboardMode() } - // clone the bindings so as not to mess up the global browser... - dialog.keybindings = JSON.parse(JSON.stringify(dialog.keybindings)) dialog.keyboard .handler('General', 'N', 'newKey') .handler('General', 'K', 'newKey') @@ -1371,7 +1369,6 @@ var KeyboardUIActions = actions.Actions({ abort = true this.close() } - dialog.keybindings = JSON.parse(JSON.stringify(dialog.keybindings)) dialog.keyboard .handler('General', 'Q', 'abort') @@ -1479,7 +1476,6 @@ var KeyboardUIActions = actions.Actions({ abort = true this.close() } - dialog.keybindings = JSON.parse(JSON.stringify(dialog.keybindings)) dialog.keyboard .handler('General', 'Q', 'abort') @@ -1569,7 +1565,6 @@ var KeyboardUIActions = actions.Actions({ abort = true this.close() } - dialog.keybindings = JSON.parse(JSON.stringify(dialog.keybindings)) dialog.keyboard .handler('General', 'Q', 'abort') diff --git a/ui (gen4)/features/ui-slideshow.js b/ui (gen4)/features/ui-slideshow.js index 3cd612f6..2ab402f6 100755 --- a/ui (gen4)/features/ui-slideshow.js +++ b/ui (gen4)/features/ui-slideshow.js @@ -102,21 +102,21 @@ var SlideshowActions = actions.Actions({ } var o = browse.makeLister(null, function(path, make){ - make(['Interval: ', + make(['$Interval: ', function(){ return that.config['slideshow-interval'] }]) .on('open', function(){ that.slideshowIntervalDialog(make.dialog) }) - make(['Direction: ', + make(['$Direction: ', function(){ return that.config['slideshow-direction'] }]) .on('open', _makeToggleHandler('toggleSlideshowDirection')) - make(['Looping: ', + make(['$Looping: ', function(){ return that.config['slideshow-looping'] }]) .on('open', _makeToggleHandler('toggleSlideshowLooping')) // Start/stop... make([function(){ - return that.toggleSlideshow('?') == 'on' ? 'Stop' : 'Start' }]) + return that.toggleSlideshow('?') == 'on' ? '$Stop' : '$Start' }]) .on('open', function(){ that.toggleSlideshow() o.close() diff --git a/ui (gen4)/features/ui-widgets.js b/ui (gen4)/features/ui-widgets.js index b871a14d..0a0eebac 100755 --- a/ui (gen4)/features/ui-widgets.js +++ b/ui (gen4)/features/ui-widgets.js @@ -721,18 +721,19 @@ module.Dialogs = core.ImageGridFeatures.Feature({ var BrowseActionsActions = actions.Actions({ config: { 'action-category-order': [ - '99:File', + //'99:File', + '99:$File', // NOTE: we can order any sub-tree we want in the same // manner as the root... 'File/-80:Clear viewer', 'File/-90:Close viewer', // NOTE: non existing elements will not get drawn... //'File/-99:moo', - '80:Edit', - '70:Navigate', - '60:Image', - '50:Ribbon', - '40:Crop', + '80:$Edit', + '70:$Navigate', + '60:$Image', + '50:$Ribbon', + '40:$Crop', 'Crop/80:Crop marked images', 'Crop/80:Crop bookmarked images', // NOTE: we can also add separators here... @@ -745,9 +746,9 @@ var BrowseActionsActions = actions.Actions({ 'Crop/-82:Uncrop', '-40:Interface', - '-50:Workspace', + '-50:$Workspace', '-60:System', - '-70:Help', + '-70:$Help', '-80:---', '-90:Development', '-90:Test', @@ -760,6 +761,8 @@ var BrowseActionsActions = actions.Actions({ }, 'browse-actions-keys': true, + + 'browse-actions-shortcut-marker': '\\$(\\w)', }, // Browse actions dialog... @@ -840,6 +843,8 @@ var BrowseActionsActions = actions.Actions({ makeUIDialog(function(path, options){ var actions = this var priority = /^(-?[0-9]+)\s*:\s*/ + var marker = RegExp(this.config['browse-actions-shortcut-marker'], 'g') + marker = marker || RegExp(marker, 'g') var dialog options = options || {} @@ -853,6 +858,8 @@ var BrowseActionsActions = actions.Actions({ traversable: true, pathPrefix: '/', fullPathEdit: true, + + item_shortcut_marker: marker, } cfg.__proto__ = this.config['browse-actions-settings'] @@ -874,7 +881,10 @@ var BrowseActionsActions = actions.Actions({ // check if it's a priority path... } else { for(var e in level){ - if(e.replace(priority, '').trim() == text){ + var n = e.replace(priority, '') + n = (marker ? n.replace(marker, '$1') : n).trim() + + if(n == text){ return [e, level[e]] } } @@ -1163,7 +1173,15 @@ var BrowseActionsActions = actions.Actions({ } else if(actions.config['browse-actions-settings'].showEmpty || (cur[key] != null && Object.keys(cur[key]).length > 0)){ + var p = '/'+ path.concat([text]).join('/') +'/' + p = marker ? p.replace(marker, '$1') : p make(text + '/', { push_on_open: true }) + .attr({ + keys: [ + getKeys('browseActions: "'+ p +'"'), + getKeys('browseActions!: "'+ p +'"'), + ].filter(function(e){ return e.trim() != '' }).join(' / '), + }) // item: line... } else if(text == '---'){ @@ -1190,8 +1208,6 @@ var BrowseActionsActions = actions.Actions({ action && actions.showDoc(action) } - // clone the bindings so as not to mess up the global browser... - dialog.keybindings = JSON.parse(JSON.stringify(dialog.keybindings)) dialog.keyboard.handler('General', '?', 'showDoc') return dialog diff --git a/ui (gen4)/lib/widget/browse.js b/ui (gen4)/lib/widget/browse.js index 7bb766fc..aa48b0bc 100755 --- a/ui (gen4)/lib/widget/browse.js +++ b/ui (gen4)/lib/widget/browse.js @@ -880,7 +880,7 @@ var BrowserClassPrototype = { } path = path - // clear the '..'... + // clear the '..' and markers... // NOTE: we reverse to avoid setting elements with negative // indexes if we have a leading '..' .reverse() @@ -1273,15 +1273,20 @@ var BrowserPrototype = { }, - // Call the constructor's .path2list(..).. + // Call the constructor's .path2list(..) and clear out shortcut markers... // // See: BrowserClassPrototype.path2list(..) for docs... path2list: function(path){ + var marker = this.options.itemShortcutMarker + marker = marker && RegExp(marker, 'g') // if list is flat we do not need to split it, just format... - if(this.options.flat && path && path.constructor !== Array){ - return path == '' || path.length == 0 ? [] : [path] + if(this.options.flat && path && path instanceof Array){ + return (path == '' || path.length == 0) ? [] : [path] } - return this.constructor.path2list.apply(this, arguments) + return this.constructor + .path2list.apply(this, arguments) + .map(function(e){ + return marker ? e.replace(marker, '$1') : e }) }, // Trigger jQuery events on Item then bubble to Browser... @@ -1820,9 +1825,9 @@ var BrowserPrototype = { delete item_shortcuts[k] } }) - var item_shortcut_marker = this.options.itemShortcutMarker || /&(\w)/ + var item_shortcut_marker = this.options.itemShortcutMarker item_shortcut_marker = item_shortcut_marker ? - RegExp(item_shortcut_marker) + RegExp(item_shortcut_marker, 'g') : null // XXX revise signature... @@ -1850,7 +1855,10 @@ var BrowserPrototype = { buttons = buttons || (that.options.itemButtons && that.options.itemButtons.slice()) - // special case: shorthand... + + // NOTE: this is becoming a bit big, so here the code is + // split into more wieldable sections... + //------------------------ special case: shorthand item --- if(p && (p in (that.options.elementShorthand || {}) || (p.hasClass && p in that.options.elementShorthand @@ -1866,6 +1874,7 @@ var BrowserPrototype = { return res } + //------------------------------------------- item text --- // array of str/func/dom... if(p.constructor === Array){ // resolve handlers... @@ -1910,7 +1919,7 @@ var BrowserPrototype = { .text(p.replace(dir, '')) } - // keyboard shortcuts... + //---------------------------------- keyboard shortcuts --- if(item_shortcuts){ // key set in options... opts.shortcut_key && !item_shortcuts[opts.shortcut_key] @@ -1944,7 +1953,9 @@ var BrowserPrototype = { +'' })) }) } } + //--------------------------------------------------------- + // tell the lister that we have started in interactive mode... interactive = true // skip drawing of non-traversable or disabled elements if @@ -1955,31 +1966,31 @@ var BrowserPrototype = { return $() } - // build list item... + //------------------------------------------ build item --- var res = $('
') // handle clicks ONLY when not disabled... .click(function(){ !$(this).hasClass('disabled') && that.push($(this)) }) + .addClass([ + 'item', + // XXX use the same algorithm as .select(..) + selection && res.text() == selection ? 'selected' : '', + + !traversable ? 'not-traversable' : '', + disabled ? 'disabled' : '', + hidden ? 'hidden' : '', + opts.hide_on_search ? 'hide-on-search' : '', + (opts.hide_on_search || opts.not_searchable) ? 'not-searchable' : '', + opts.not_filtered_out ? 'not-filtered-out' : '', + ].join(' ')) // append text elements... .append(p) - res.addClass([ - 'item', - // XXX use the same algorithm as .select(..) - selection && res.text() == selection ? 'selected' : '', + opts.push_on_open + && res.attr('push-on-open', 'on') - !traversable ? 'not-traversable' : '', - disabled ? 'disabled' : '', - hidden ? 'hidden' : '', - opts.hide_on_search ? 'hide-on-search' : '', - (opts.hide_on_search || opts.not_searchable) ? 'not-searchable' : '', - opts.not_filtered_out ? 'not-filtered-out' : '', - ].join(' ')) - - opts.push_on_open && res.attr('push-on-open', 'on') - - // buttons... + //--------------------------------------------- buttons --- // button container... var btn = res.find('.button-container') btn = btn.length == 0 ? @@ -1988,7 +1999,7 @@ var BrowserPrototype = { .appendTo(res) : btn - // action (open)... + // action (open) button... if(traversable && that.options.actionButton){ btn.append($('
') .addClass('button') @@ -2001,7 +2012,8 @@ var BrowserPrototype = { that.action() })) } - // push... + + // push button... if(traversable && that.options.pushButton){ btn.append($('
') .addClass('button') @@ -2045,7 +2057,7 @@ var BrowserPrototype = { })) }) - // place in list... + //--------------------------------------- place in list --- // as-is... if(!sort_traversable || sort_traversable == 'none'){ res.appendTo(l) @@ -2062,6 +2074,7 @@ var BrowserPrototype = { res.appendTo(l) } } + //--------------------------------------------------------- return res } @@ -3564,15 +3577,23 @@ PathListPrototype.options = { // Supported patterns: // A - matches A exactly // A|B - matches either A or B + // shortcut marker + // - see .options.itemShortcutMarker + // + // NOTE: only the second argument is checked for '|' patterns... var match = function(a, path){ + var marker = that.options.itemShortcutMarker + marker = marker && RegExp(marker, 'g') + path = marker ? e.replace(marker, '$1') : path // NOTE: might be good to make this recursive when expanding // pattern support... return a .split('|') + .map(function(e){ + return marker ? e.replace(marker, '$1') : e }) .filter(function(e){ - return e == path - }).length > 0 - } + return e == path }) + .length > 0 } // get the '*' listers... var lister = keys