From 6b8b4d2801cadfe17252969f3aebf75d7e675183 Mon Sep 17 00:00:00 2001 From: "Alex A. Naanou" Date: Sun, 29 Nov 2015 20:46:15 +0300 Subject: [PATCH] added loader selection sub-list + moved feature config to feature actions (closer to where they are used)... Signed-off-by: Alex A. Naanou --- ui (gen4)/lib/features.js | 2 +- ui (gen4)/lib/widget/browse.js | 14 +- ui (gen4)/viewer.js | 266 ++++++++++++++++++++------------- 3 files changed, 177 insertions(+), 105 deletions(-) diff --git a/ui (gen4)/lib/features.js b/ui (gen4)/lib/features.js index 8a80b951..2bd39548 100755 --- a/ui (gen4)/lib/features.js +++ b/ui (gen4)/lib/features.js @@ -105,7 +105,7 @@ module.FeatureProto = { if(this.config != null || (this.actions != null && this.actions.config != null)){ - var config = this.config || this.actions.config + var config = this.config = this.config || this.actions.config if(actions.config == null){ actions.config = {} diff --git a/ui (gen4)/lib/widget/browse.js b/ui (gen4)/lib/widget/browse.js index afe87327..297c928a 100755 --- a/ui (gen4)/lib/widget/browse.js +++ b/ui (gen4)/lib/widget/browse.js @@ -599,6 +599,18 @@ var BrowserPrototype = { // path due to an error, we need to be able to render the new // path both in the path and list sections... // NOTE: current behaviour is not wrong, it just not too flexible... + // + // XXX one use-case here would be to pass this a custom lister or a full + // browser, need to make this work correctly for full set of + // events... + // - custom lister -- handle all sub-paths in some way... + // - full browser -- handle all sub-paths by the nested + // browser... + // one way to handle nested browsers is to implement a browser + // stack which if not empty the top browser handles all the + // sub-paths + // ...this will also need to indicate a way to split the path + // and when to 'pop' the sub browser... update: function(path, list){ path = path || this.path var browser = this.dom @@ -743,7 +755,7 @@ var BrowserPrototype = { that.action() })) } - // push action... + // push... if(traversable && that.options.pushButton){ res.append($('
') .addClass('button') diff --git a/ui (gen4)/viewer.js b/ui (gen4)/viewer.js index 247a250a..89ba060b 100755 --- a/ui (gen4)/viewer.js +++ b/ui (gen4)/viewer.js @@ -794,11 +794,6 @@ module.Base = ImageGridFeatures.Feature({ tag: 'base', - config: { - // see .direction for details... - 'steps-to-change-direction': 3, - }, - actions: BaseActions, }) @@ -809,6 +804,28 @@ module.Base = ImageGridFeatures.Feature({ var ViewerActions = module.ViewerActions = actions.Actions({ + config: { + // The maximum screen width allowed when zooming... + 'max-screen-images': 30, + + // A step (multiplier) used by .zoomIn()/.zoomOut() actions. + // NOTE: this is rounded to the nearest whole screen width in images + // and current fit-overflow added. + 'zoom-step': 1.2, + + // added to odd number of images to fit to indicate scroll ability... + // ...this effectively sets the closest distance an image can be from + // the viewer edge... + 'fit-overflow': 0.2, + + + // limit key repeat to one per N milliseconds. + // + // Set this to -1 or null to run keys without any limitations. + // XXX at this point the keyboard is setup in ui.js, need to + // move to a more logical spot... + 'max-key-repeat-rate': 0, + }, // Images... // XXX this seems like a hack... @@ -1316,29 +1333,6 @@ module.Viewer = ImageGridFeatures.Feature({ depends: ['base'], - config: { - // The maximum screen width allowed when zooming... - 'max-screen-images': 30, - - // A step (multiplier) used by .zoomIn()/.zoomOut() actions. - // NOTE: this is rounded to the nearest whole screen width in images - // and current fit-overflow added. - 'zoom-step': 1.2, - - // added to odd number of images to fit to indicate scroll ability... - // ...this effectively sets the closest distance an image can be from - // the viewer edge... - 'fit-overflow': 0.2, - - - // limit key repeat to one per N milliseconds. - // - // Set this to -1 or null to run keys without any limitations. - // XXX at this point the keyboard is setup in ui.js, need to - // move to a more logical spot... - 'max-key-repeat-rate': 0, - }, - actions: ViewerActions, // check if we are running in a UI context... @@ -1465,6 +1459,25 @@ module.Journal = ImageGridFeatures.Feature({ // XXX try a strategy: load more in the direction of movement by an offset... // XXX updateRibbon(..) is not signature compatible with data.updateRibbon(..) var PartialRibbonsActions = actions.Actions({ + config: { + // number of screen widths to load... + 'ribbon-size-screens': 7, + + // number of screen widths to edge to trigger reload... + 'ribbon-resize-threshold': 1.5, + + // timeout before a non-forced ribbon size update happens after + // the action... + // NOTE: if set to null, the update will be sync... + 'ribbon-update-timeout': 120, + + // how many non-adjacent images to preload... + 'preload-radius': 5, + + // sources to preload... + 'preload-sources': ['bookmark', 'selected'], + }, + // NOTE: this will not work from chrome when loading from a local fs... // XXX experimental... startCacheWorker: ['Interface/', @@ -1794,25 +1807,6 @@ module.PartialRibbons = ImageGridFeatures.Feature({ actions: PartialRibbonsActions, - config: { - // number of screen widths to load... - 'ribbon-size-screens': 7, - - // number of screen widths to edge to trigger reload... - 'ribbon-resize-threshold': 1.5, - - // timeout before a non-forced ribbon size update happens after - // the action... - // NOTE: if set to null, the update will be sync... - 'ribbon-update-timeout': 120, - - // how many non-adjacent images to preload... - 'preload-radius': 5, - - // sources to preload... - 'preload-sources': ['bookmark', 'selected'], - }, - handlers: [ ['focusImage.pre centerImage.pre', function(target, list){ @@ -1857,6 +1851,11 @@ module.PartialRibbons = ImageGridFeatures.Feature({ //--------------------------------------------------------------------- var SingleImageActions = actions.Actions({ + config: { + 'single-image-scale': null, + 'ribbon-scale': null, + }, + toggleSingleImage: ['Interface/Toggle single image view', // XXX this is wrong!!! CSSClassToggler( @@ -1944,11 +1943,6 @@ module.SingleImageView = ImageGridFeatures.Feature({ tag: 'ui-single-image-view', depends: ['ui'], - config: { - 'single-image-scale': null, - 'ribbon-scale': null, - }, - actions: SingleImageActions, handlers:[ @@ -2193,6 +2187,25 @@ module.BoundsIndicators = ImageGridFeatures.Feature({ //--------------------------------------------------------------------- var CurrentImageIndicatorActions = actions.Actions({ + config: { + 'current-image-border': 3, + 'current-image-min-border': 2, + + 'current-image-border-timeout': 200, + 'current-image-shift-timeout': 200, + + 'current-image-indicator-fadein': 500, + + 'current-image-indicator-hide-timeout': 250, + + // this can be: + // 'hide' - simply hide on next/prev screen action + // and show on focus image. + // 'hide-show' - hide on fast scroll through screens and + // show when slowing down. + 'current-image-indicator-screen-nav-mode': 'hide', + }, + updateCurrentImageIndicator: ['Interface/Update current image indicator', function(target, update_border){ var ribbon_set = this.ribbons.getRibbonSet() @@ -2282,25 +2295,6 @@ module.CurrentImageIndicator = ImageGridFeatures.Feature({ tag: 'ui-current-image-indicator', depends: ['ui'], - config: { - 'current-image-border': 3, - 'current-image-min-border': 2, - - 'current-image-border-timeout': 200, - 'current-image-shift-timeout': 200, - - 'current-image-indicator-fadein': 500, - - 'current-image-indicator-hide-timeout': 250, - - // this can be: - // 'hide' - simply hide on next/prev screen action - // and show on focus image. - // 'hide-show' - hide on fast scroll through screens and - // show when slowing down. - 'current-image-indicator-screen-nav-mode': 'hide', - }, - actions: CurrentImageIndicatorActions, handlers: [ @@ -2651,6 +2645,14 @@ var makeActionLister = function(list, filter, pre_order){ } var ActionTreeActions = actions.Actions({ + config: { + 'action-category-order': [ + 'File', + 'Edit', + 'Navigate', + ], + }, + // XXX move this to a generic modal overlay feature... getOverlay: ['Interface/Get overlay object', function(o){ @@ -2869,14 +2871,6 @@ module.ActionTree = ImageGridFeatures.Feature({ tag: 'ui-action-tree', depends: ['ui'], - config: { - 'action-category-order': [ - 'File', - 'Edit', - 'Navigate', - ], - }, - actions: ActionTreeActions, }) @@ -3193,6 +3187,7 @@ module.AppControl = ImageGridFeatures.Feature({ // XXX at this point this is a stub... if(window.nodejs != null){ var file = requirejs('./file') + var glob = requirejs('glob') } @@ -3202,7 +3197,7 @@ var FileSystemLoaderActions = actions.Actions({ // ...and how should this be handled when merging indexes or // viewing multiple/clustered indexes??? // XXX look inside... - loadPath: ['File/Load path', + loadIndex: ['File/Load index', function(path, logger){ var that = this @@ -3290,6 +3285,27 @@ var FileSystemLoaderActions = actions.Actions({ that.load(index) }) }], + // XXX use the logger... + // XXX add a recursive option... + // ...might also be nice to add sub-dirs to ribbons... + loadImages: ['File/Load images', + function(path, logger){ + if(path == null){ + return + } + + var that = this + + return glob(path + '/*+(jpg|png)') + .on('end', function(lst){ + that.loadURLs(lst) + }) + }], + + // XXX auto-detect format or let the user chose... + loadPath: ['File/Load path', + function(){ + }], }) @@ -3312,28 +3328,44 @@ module.FileSystemLoader = ImageGridFeatures.Feature({ //--------------------------------------------------------------------- +var makeProwseProxy = function(action){ + return function(path, logger){ + var that = this + if(path == null){ + // XXX should we set a start path here to current??? + return this.browsePath(path, + function(path){ + return that[action](path, logger) + }) + } + } +} + + var FileSystemLoaderUIActions = actions.Actions({ - // NOTE: if no path is passed (null) this behaves just like .browsePath(..) - // otherwise it will just load the given path (no UI) while - // .browsePath(..) will load the UI in all cases but will treat - // the given path as a base path to start from. + config: { + 'path-loaders': [ + 'loadIndex', + 'loadImages', + ], + }, + + // NOTE: if no path is passed (null) these behave just like .browsePath(..) + // with the appropriate callback otherwise it will just load + // the given path (no UI) while .browsePath(..) will load the + // UI in all cases but will treat the given path as a base path + // to start from. // XXX should passing no path to this start browsing from the current // path or from the root? - loadPath: ['File/Load path...', - function(path, logger){ - var that = this - if(path == null){ - // XXX should we set a start path here to current??? - return this.browsePath(path, - function(path){ - return that.loadPath(path, logger) - }) - } - }], + loadIndex: ['File/Load index...', + makeProwseProxy('loadIndex')], + loadImages: ['File/Load images...', + makeProwseProxy('loadImages')], // XXX BUG: for some reason this when run from .browseActions(..) or // any other Browse, loads incorrectly while when called // directly is OK... + // XXX should the loader list be nested or open in overlay (as-is now)??? browsePath: ['File/Browse file system...', function(base, callback){ var that = this @@ -3344,18 +3376,46 @@ var FileSystemLoaderUIActions = actions.Actions({ require('./lib/widget/browse-walk').makeWalk(null, base, false, false) // path selected... .open(function(evt, path){ - // close self and parent... - o.close() - parent - && parent.close - && parent.close() - // pass the selected path on... - if(callback){ + // single loader... + if(callback && callback.constructor === Function){ + // close self and parent... + o.close() + parent + && parent.close + && parent.close() + callback(path) + // list of loaders... } else { - that.loadPath(path) + // user-provided list... + if(callback){ + var loaders = callback + + // build the loaders list from .config... + } else { + var loaders = {} + that.config['path-loaders'].forEach(function(m){ + loaders[that[m].doc.split('/').pop()] = function(){ + return that[m](path) + } + }) + } + + // show user the list... + var so = overlay.Overlay(that.ribbons.viewer, + browse.makeList(null, loaders) + // close self and parent... + .open(function(){ + so.close() + o.close() + })) + // closed menu... + .close(function(){ + o.focus() + }) + so.client.select(0) } })) // we closed the browser...