diff --git a/ui (gen4)/lib/actions.js b/ui (gen4)/lib/actions.js index d632372e..6e5e22e2 100755 --- a/ui (gen4)/lib/actions.js +++ b/ui (gen4)/lib/actions.js @@ -215,8 +215,8 @@ function Action(name, doc, ldoc, func){ var args = args2array(arguments) var that = this - var getHandlers = this.getHandlers - getHandlers = getHandlers == null ? MetaActions.getHandlers : getHandlers + var getHandlers = this.getHandlers || MetaActions.getHandlers + var isToggler = this.isToggler || MetaActions.isToggler // get handlers... // @@ -232,7 +232,7 @@ function Action(name, doc, ldoc, func){ // special case: if the root handler is a toggler and we call // it with '?'/'??' then do not call the handlers... // XXX might be good to make this modular/configurable... - if(handlers.slice(-1)[0] instanceof Toggler + if(isToggler.call(this, name)//handlers.slice(-1)[0] instanceof Toggler && args.length == 1 && (args[0] == '?' || args[0] == '??')){ return handlers.slice(-1)[0].apply(this, args) @@ -289,6 +289,7 @@ function Action(name, doc, ldoc, func){ Action.prototype.__proto__ = Function + // A base action-set object... // // This will define a set of action-set specific methods and helpers. @@ -405,6 +406,26 @@ module.MetaActions = { }, + // Test if the action is a Toggler... + // + // NOTE: an action is considered a toggler only if it's base action + // is a toggler (instance of Toggler), thus, the same "top" + // action can be or not be a toggler in different contexts. + // + // For more info on togglers see: lib/toggler.js + isToggler: function(name){ + var handlers = (this.getHandlers + || MetaActions.getHandlers) + .call(this, name) + + if(handlers.slice(-1)[0] instanceof Toggler){ + return true + } + + return false + }, + + // Register an action callback... // // Register a post action callback diff --git a/ui (gen4)/lib/widget/browse.js b/ui (gen4)/lib/widget/browse.js index ac01721d..300aea2c 100755 --- a/ui (gen4)/lib/widget/browse.js +++ b/ui (gen4)/lib/widget/browse.js @@ -770,7 +770,7 @@ var BrowserPrototype = { .click(function(){ if(!$(this).hasClass('disabled')){ //that.push(quoteWS($(this).find('.text').text())) - that.push($(this).find('.text').text()) + that.push('"'+ $(this).find('.text').text() +'"') } }) //.text(p) @@ -795,7 +795,7 @@ var BrowserPrototype = { : that.options.actionButton) .click(function(evt){ evt.stopPropagation() - that.select(p) + that.select('"'+ p +'"') that.action() })) } @@ -808,7 +808,7 @@ var BrowserPrototype = { : that.options.pushButton) .click(function(evt){ evt.stopPropagation() - that.push(p) + that.push('"'+ p +'"') })) } @@ -1650,7 +1650,7 @@ var BrowserPrototype = { var path = this.path //var txt = quoteWS(elem.find('.text').text()) - var txt = elem.find('.text').text() + var txt = '"'+ elem.find('.text').text() +'"' path.push(elem.find('.text').text()) // XXX should this be before or after the actual path update??? @@ -1709,7 +1709,7 @@ var BrowserPrototype = { var path = this.path //path.push(quoteWS(elem.find('.text').text())) - path.push(elem.find('.text').text()) + path.push('"'+ elem.find('.text').text() +'"') var res = this.open(path) @@ -1824,7 +1824,7 @@ var BrowserPrototype = { // load the current path + selection... path = this.path - path.push(elem.find('.text').text()) + path.push('"'+ elem.find('.text').text() +'"') // normalize and load path... //} else { @@ -1845,7 +1845,7 @@ var BrowserPrototype = { path = this.path //path.push(quoteWS(elem.find('.text').text())) - path.push(elem.find('.text').text()) + path.push('"'+ elem.find('.text').text() +'"') } // get the options method and call it if it exists... @@ -2248,7 +2248,8 @@ PathListPrototype.options = { // get the '*' listers... var lister = keys - .filter(function(k){ return k.trim().slice(-1) == '*' }) + .filter(function(k){ + return k.trim().split(/[\\\/]+/g).pop() == '*' }) .filter(function(k){ k = k.split(/[\\\/]+/) // remove the trailing '*'... diff --git a/ui (gen4)/viewer.js b/ui (gen4)/viewer.js index f2c07d8f..e8658555 100755 --- a/ui (gen4)/viewer.js +++ b/ui (gen4)/viewer.js @@ -140,6 +140,25 @@ function makeTagWalker(direction, dfl_tag){ } +// NOTE: if not state is set this assumes that the first state is the +// default... +var makeConfigToggler = function(attr, states){ + return Toggler(null, + function(_, action){ + var lst = states.constructor === Array ? states : states.call(this) + + if(action == null){ + return this.config[attr] || lst[0] + + } else { + this.config[attr] = action + this.focusImage() + } + }, + states) +} + + /*********************************************************************/ @@ -276,14 +295,16 @@ actions.Actions({ // see .direction for details... 'steps-to-change-direction': 3, - // determines the image selection mode when focusing ribbons... + // Determines the image selection mode when focusing or moving + // between ribbons... // // supported modes: - // 'order' - select image closest to current in order - // 'first' - select first image - // 'last' - select last image - // 'visual' - select image closest visually - //'ribbon-focus-mode': 'order', + 'ribbon-focus-modes': [ + 'visual', // select image closest visually + 'order', // select image closest to current in order + 'first', // select first image + 'last', // select last image + ], 'ribbon-focus-mode': 'visual', }, @@ -363,6 +384,11 @@ actions.Actions({ } }, + toggleRibbonFocusMode : ['Interface/Toggle ribbon focus mode', + makeConfigToggler('ribbon-focus-mode', + function(){ return this.config['ribbon-focus-modes'] })], + + // basic life-cycle actions... // // XXX do we need to call .syncTags(..) here??? @@ -1600,9 +1626,34 @@ module.Viewer = ImageGridFeatures.Feature({ handlers: [ ['start', function(){ + var that = this + if(this.config.theme){ this.toggleTheme(this.config.theme) } + + if(!this.__viewer_resize){ + this.__viewer_resize = function(){ + if(that.__centering_on_resize){ + return + } + // this will prevent centering calls from overlapping... + that.__centering_on_resize = true + + that.centerViewer() + + delete that.__centering_on_resize + } + + $(window).resize(this.__viewer_resize) + } + }], + ['stop', + function(){ + if(that.__viewer_resize){ + $(window).off('resize', that.__viewer_resize) + delete that.__viewer_resize + } }], ], }) @@ -2604,6 +2655,7 @@ module.SingleImageViewLocalStorage = ImageGridFeatures.Feature({ //--------------------------------------------------------------------- // These feature glue traverse and ribbon alignment... + // XXX manual align needs more work... var AutoAlignRibbons = module.AutoAlignRibbons = ImageGridFeatures.Feature({ @@ -2615,25 +2667,27 @@ module.AutoAlignRibbons = ImageGridFeatures.Feature({ exclusive: ['ui-ribbon-align'], config: { - // Control image selection and optionally ribbon alignment... - // - // NOTE: this only supports the following modes: - // - 'visual' - // - 'order' - // - 'fisrt' - // - 'manual' - // NOTE: if 'ribbon-align-mode' is not null this can be set to - // any mode without restriction. - //'ribbon-focus-mode': 'order', - 'ribbon-focus-mode': 'visual', - // control ribbon alignment... // // NOTE: when this is null then 'ribbon-focus-mode' will be used... // NOTE: this supports the same modes as 'ribbon-focus-mode'... + 'ribbon-align-modes': [ + 'none', // use .config['ribbon-focus-mode']'s value + 'visual', + 'order', + 'first', + //'last', + 'manual', + ], 'ribbon-align-mode': null, }, + actions: actions.Actions({ + toggleRibbonAlignMode : ['Interface/Toggle ribbon align mode', + makeConfigToggler('ribbon-align-mode', + function(){ return this.config['ribbon-align-modes'] })], + }), + handlers: [ ['focusImage.post', function(){ @@ -3334,6 +3388,24 @@ var makeActionLister = function(list, filter, pre_order){ return res } } + + // toggler -- add state list... + if(that.isToggler && that.isToggler(n)){ + var states = that[n]('??') + var cur = that[n]('?') + + // bool toggler... + if(cur == 'on' || cur == 'off'){ + states = ['off', 'on'] + } + + states.forEach(function(state){ + actions[k +'/'+ state + (cur == state ? ' *': '')] = + function(){ + that[n](state) + } + }) + } }) var config = Object.create(that.config['browse-actions-settings'] || {}) @@ -3400,13 +3472,13 @@ var ActionTreeActions = actions.Actions({ })], // XXX this is just a test... - embededListerTest: ['Interface|Test/Lister test (embeded)/*', + embededListerTest: ['Test/Lister test (embeded)/*', function(path, make){ make('a/') make('b/') make('c/') }], - floatingListerTest: ['Interface|Test/Lister test (floating)...', + floatingListerTest: ['Test/Lister test (floating)...', function(path){ var parent = this.preventClosing ? this.preventClosing() : null @@ -3448,7 +3520,7 @@ var ActionTreeActions = actions.Actions({ }) }], // XXX use this.ribbons.viewer as base... - drawerTest: ['Interface|Test/Drawer widget test', + drawerTest: ['Test/Drawer widget test', function(){ // XXX use this.ribbons.viewer as base... drawer.Drawer($('body'), @@ -3472,7 +3544,7 @@ var ActionTreeActions = actions.Actions({ // XXX use this.ribbons.viewer as base... // XXX BUG: when using this.ribbons.viewer as base some actions leak // between the two viewers... - showTaggedInDrawer: ['Interface|Test/Show tagged in drawer', + showTaggedInDrawer: ['- Test/Show tagged in drawer', function(tag){ tag = tag || 'bookmark' var that = this @@ -3584,9 +3656,9 @@ var ActionTreeActions = actions.Actions({ return b }], - showBookmarkedInDrawer: ['Interface|Test/Show bookmarked in drawer', + showBookmarkedInDrawer: ['Test/Show bookmarked in drawer', function(){ this.showTaggedInDrawer('bookmark') }], - showSelectedInDrawer: ['Interface|Test/Show selected in drawer', + showSelectedInDrawer: ['Test/Show selected in drawer', function(){ this.showTaggedInDrawer('selected') }], }) @@ -3886,6 +3958,8 @@ var AppControlActions = actions.Actions({ function(){ // XXX where should toggleFullscreenMode(..) be defined... toggleFullscreenMode() + + this.centerViewer() }], showDevTools: ['Interface|Development/Show Dev Tools', function(){ @@ -3933,20 +4007,6 @@ module.AppControl = ImageGridFeatures.Feature({ // XXX win.show() - - // XXX not sure if this should be here... - var that = this - $(window).resize(function(){ - if(that.__centering_on_resize){ - return - } - // this will prevent centering calls from overlapping... - that.__centering_on_resize = true - - that.centerViewer() - - delete that.__centering_on_resize - }) }], ['focusImage', function(){