diff --git a/ui (gen4)/features/all.js b/ui (gen4)/features/all.js index 46ab04be..5dc506ac 100755 --- a/ui (gen4)/features/all.js +++ b/ui (gen4)/features/all.js @@ -21,6 +21,7 @@ require('features/ui') require('features/ui-partial-ribbons') require('features/ui-single-image') require('features/ui-chrome') +require('features/ui-progress') require('features/keyboard') require('features/ui-status') require('features/ui-marks') diff --git a/ui (gen4)/features/filesystem.js b/ui (gen4)/features/filesystem.js index de2eec7d..40c4f461 100755 --- a/ui (gen4)/features/filesystem.js +++ b/ui (gen4)/features/filesystem.js @@ -366,6 +366,7 @@ var FileSystemLoaderActions = actions.Actions({ var that = this // XXX get a logger... logger = logger || this.logger + logger = logger && logger.push('Load') if(path == null){ return @@ -570,6 +571,7 @@ var FileSystemLoaderActions = actions.Actions({ // XXX get a logger... logger = logger || this.logger + //logger = logger && logger.push('getImagesInPath') var that = this path = util.normalizePath(path) @@ -641,6 +643,7 @@ var FileSystemLoaderActions = actions.Actions({ return } logger = logger || this.logger + logger = logger && logger.push('Load images') var that = this path = util.normalizePath(path) @@ -692,6 +695,7 @@ var FileSystemLoaderActions = actions.Actions({ var that = this logger = logger || this.logger + logger = logger && logger.push('Load new images') path = util.normalizePath(path) // cache the loaded images... @@ -1105,6 +1109,7 @@ var FileSystemCommentsActions = actions.Actions({ } logger = logger || this.logger + logger = logger && logger.push('saveComments') var path = this.location.path var comments_dir = this.config['index-dir'] +'/comments' @@ -1126,6 +1131,7 @@ var FileSystemCommentsActions = actions.Actions({ } logger = logger || this.logger + logger = logger && logger.push('Load comments') var that = this var loaded = this.location.loaded @@ -1746,6 +1752,7 @@ var FileSystemWriterActions = actions.Actions({ var that = this // XXX get a logger... logger = logger || this.logger + logger = logger && logger.push('Save') path = path || this.location.loaded path = path && path.length == 1 ? path[0] : path @@ -1830,6 +1837,7 @@ var FileSystemWriterActions = actions.Actions({ exportIndex: ['- File/Export/Export index', function(path, max_size, include_orig, logger){ logger = logger || this.logger + logger = logger && logger.push('Export index') max_size = parseInt(max_size || this.config['export-preview-size-limit']) || null // XXX make this dependant on max_size.... @@ -1953,7 +1961,8 @@ var FileSystemWriterActions = actions.Actions({ index_path, index.date, this.config['index-filename-template'], - logger || this.logger) + logger) + //logger || this.logger) // set hidden file attribute on Windows... .then(function(){ typeof(process) != 'undefined' @@ -1996,6 +2005,7 @@ var FileSystemWriterActions = actions.Actions({ exportDirs: ['- File/Export/Export ribbons as directories', function(path, pattern, level_dir, size, logger){ logger = logger || this.logger + logger = logger && logger.push('Export dirs') var that = this var base_dir = this.location.path diff --git a/ui (gen4)/features/meta.js b/ui (gen4)/features/meta.js index 270b8c9e..66d79bc8 100755 --- a/ui (gen4)/features/meta.js +++ b/ui (gen4)/features/meta.js @@ -81,6 +81,7 @@ core.ImageGridFeatures.Feature('viewer-testing', [ 'external-editor', // chrome... + 'ui-progress', 'ui-status-log', 'ui-scale', 'ui-animation', diff --git a/ui (gen4)/features/ui-progress.js b/ui (gen4)/features/ui-progress.js new file mode 100755 index 00000000..2331e907 --- /dev/null +++ b/ui (gen4)/features/ui-progress.js @@ -0,0 +1,162 @@ +/********************************************************************** +* +* +* +**********************************************************************/ +((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define)( +function(require){ var module={} // makes module AMD/node compatible... +/*********************************************************************/ + +var actions = require('lib/actions') +var features = require('lib/features') + +var core = require('features/core') + + + +/*********************************************************************/ + +var ProgressActions = actions.Actions({ + config: { + 'progress-fade-duration': 200, + 'progress-done-delay': 1000, + }, + + // Progress bar widget... + // + // Create progress bar... + // .testProgress('text') + // + // Update progress bar (value, max, msg)... + // .testProgress('text', 0, 10) + // .testProgress('text', 10, 50, 'message') + // + // Update progress bar value (has no effect if max is not set)... + // .testProgress('text', 10) + // + // Close progress bar... + // .testProgress('text', 'close') + // + // Relative progress modification... + // .testProgress('text', '+1') + // .testProgress('text', '+0', '+1') + // + // + // XXX move configuration to .config + // XXX should we report errors and stoppages??? (error state??) + // XXX multiple containers... + // XXX shorten the nested class names... + // XXX revise styles... + showProgress: ['- Interface/Show progress bar...', + function(text, value, max){ + var viewer = this.ribbons.viewer + var that = this + + var msg = text instanceof Array ? text.slice(1).join(': ') : null + text = text instanceof Array ? text[0] : text + + // container... + var container = viewer.find('.progress-container') + container = container.length == 0 ? + $('
') + .addClass('progress-container') + .appendTo(viewer) + : container + + // widget... + var widget = container.find('.progress-bar[name="'+text+'"]') + // close action... + if(value == 'close'){ + widget.trigger('progressClose') + return + } + widget = widget.length == 0 ? + $('') + .addClass('progress-bar') + .attr('name', text) + .text(text) + // close button... + .append($('×') + .on('click', function(){ widget.trigger('progressClose') })) + // state... + .append($('') + .addClass('progress-details')) + // bar... + .append($('')) + // events... + .on('progressClose', function(){ + widget + .fadeOut(that.config['progress-fade-duration'] || 200, function(){ + $(this).remove() + }) + }) + .appendTo(container) + : widget + + // reset closing timeout... + var timeout = widget.attr('close-timeout') + timeout && clearTimeout(JSON.parse(timeout)) + + // get the widget parts we are updating... + var bar = widget.find('progress') + var state = widget.find('.progress-details') + + // XXX stub??? + // normalize max and value... + max = max != null ? + (typeof(max) == typeof('str') && /[+-][0-9]+/.test(max) ? + parseInt(bar.attr('max') || 0) + parseInt(max) + : parseInt(max)) + : bar.attr('max') + value = value != null ? + (typeof(value) == typeof('str') && /[+-][0-9]+/.test(value) ? + parseInt(bar.attr('value') || 0) + parseInt(value) + : parseInt(value)) + : bar.attr('value') + + // format the message... + msg = msg ? ': '+msg : '' + msg = ' '+ msg + //+ (value && value >= (max || 0) ? ' ('+value+' done)' + + (value && value >= (max || 0) ? ' (done)' + : value && max && value != max ? ' ('+ value +' of '+ max +')' + : '...') + + // update widget... + bar.attr({ + value: value || '', + max: max || '', + }) + state.text(msg) + + // auto-close... + // XXX make this optional... + if(value && value >= (max || 0)){ + widget.attr('close-timeout', + JSON.stringify(setTimeout(function(){ + widget.trigger('progressClose') + }, this.config['progress-done-delay'] || 1000))) + } + + // XXX what should we return??? (state, self, controller?) + }], +}) + +var Progress = +module.Progress = core.ImageGridFeatures.Feature({ + title: '', + doc: '', + + tag: 'ui-progress', + depends: [ + 'ui', + ], + + actions: ProgressActions, +}) + + + + +/********************************************************************** +* vim:set ts=4 sw=4 : */ return module }) diff --git a/ui (gen4)/features/ui-widgets.js b/ui (gen4)/features/ui-widgets.js index f85d53e1..255c8a73 100755 --- a/ui (gen4)/features/ui-widgets.js +++ b/ui (gen4)/features/ui-widgets.js @@ -1111,121 +1111,6 @@ var WidgetTestActions = actions.Actions({ })], - // Progress bar widget... - // - // Create progress bar... - // .testProgress('text') - // - // Update progress bar (value, max, msg)... - // .testProgress('text', 0, 10) - // .testProgress('text', 10, 50, 'message') - // - // Update progress bar value (has no effect if max is not set)... - // .testProgress('text', 10) - // - // Close progress bar... - // .testProgress('text', 'close') - // - // Relative progress modification... - // .testProgress('text', '+1') - // .testProgress('text', '+0', '+1') - // - // - // XXX should we report errors and stoppages??? (error state??) - // XXX multiple containers... - // XXX shorten the nested class names... - // XXX revise styles... - showProgress: ['- Interface/Show progress bar...', - function(text, value, max){ - var viewer = this.ribbons.viewer - - var msg = text instanceof Array ? text.slice(1).join(': ') : null - text = text instanceof Array ? text[0] : text - - // container... - var container = viewer.find('.progress-container') - container = container.length == 0 ? - $('') - .addClass('progress-container') - .appendTo(viewer) - : container - - // widget... - var widget = container.find('.progress-bar[name="'+text+'"]') - // close action... - if(value == 'close'){ - widget.trigger('progressClose') - return - } - widget = widget.length == 0 ? - $('') - .addClass('progress-bar') - .attr('name', text) - .text(text) - // close button... - .append($('×') - .on('click', function(){ widget.trigger('progressClose') })) - // state... - .append($('') - .addClass('progress-details')) - // bar... - .append($('')) - // events... - .on('progressClose', function(){ - widget - .fadeOut(200, function(){ - $(this).remove() - }) - }) - .appendTo(container) - : widget - - // reset closing timeout... - var timeout = widget.attr('close-timeout') - timeout && clearTimeout(JSON.parse(timeout)) - - // get the widget parts we are updating... - var bar = widget.find('progress') - var state = widget.find('.progress-details') - - // XXX stub??? - // normalize max and value... - max = max != null ? - (typeof(max) == typeof('str') && /[+-][0-9]+/.test(max) ? - parseInt(bar.attr('max') || 0) + parseInt(max) - : parseInt(max)) - : bar.attr('max') - value = value != null ? - (typeof(value) == typeof('str') && /[+-][0-9]+/.test(value) ? - parseInt(bar.attr('value') || 0) + parseInt(value) - : parseInt(value)) - : bar.attr('value') - - // format the message... - msg = msg ? ': '+msg : '' - msg = ' '+ msg - + (value && value >= (max || 0) ? ' ('+value+' done)' - : value && max && value != max ? ' ('+ value +' of '+ max +')' - : ' (ready)') - - // update widget... - bar.attr({ - value: value || '', - max: max || '', - }) - state.text(msg) - - // auto-close... - // XXX make this optional... - if(value && value >= (max || 0)){ - widget.attr('close-timeout', - JSON.stringify(setTimeout(function(){ - widget.trigger('progressClose') - }, 1000))) - } - - // XXX what should we return??? (state, self, controller?) - }], testProgress: ['Test/Demo progress bar...', function(text){ var done = 0 diff --git a/ui (gen4)/imagegrid/file.js b/ui (gen4)/imagegrid/file.js index 3d797756..3c9e5def 100755 --- a/ui (gen4)/imagegrid/file.js +++ b/ui (gen4)/imagegrid/file.js @@ -40,6 +40,8 @@ var INDEX_DIR = '.ImageGrid' // Skip nested indexes from tree... // var skipNested = function(paths, index_dir, logger){ + logger = logger && logger.push('Skipping nested') + paths = paths .map(function(p){ return p.split(index_dir).shift() }) .sort(function(a, b){ return a.length - b.length }) @@ -107,6 +109,8 @@ function(base, index_dir){ var getIndexes = module.getIndexes = function(base, index_dir, logger){ + logger = logger && logger.push('Searching') + return new Promise(function(resolve, reject){ listIndexes(base, index_dir) .on('error', function(err){ @@ -243,6 +247,8 @@ function(list){ var groupByKeyword = module.groupByKeyword = function(list, from_date, logger){ + logger = logger && logger.push('Grouping by keyword') + var index = {} var queued = 0 @@ -328,6 +334,8 @@ function(list, from_date, logger){ var loadSaveHistoryList = module.loadSaveHistoryList = function(path, index_dir, logger){ + logger = logger && logger.push('Save history') + path = util.normalizePath(path) index_dir = index_dir || INDEX_DIR @@ -467,6 +475,8 @@ function(path, index_dir, logger){ var loadIndex = module.loadIndex = function(path, index_dir, from_date, logger){ + logger = logger && logger.push('Index') + path = util.normalizePath(path) if(index_dir && index_dir.emit != null){ @@ -921,6 +931,8 @@ var FILENAME = '${DATE}-${KEYWORD}.${EXT}' var writeIndex = module.writeIndex = function(json, path, date, filename_tpl, logger){ + logger = logger && logger.push('Index') + path = util.normalizePath(path) filename_tpl = filename_tpl || FILENAME // XXX for some reason this gets the unpatched node.js Date, so we diff --git a/ui (gen4)/ui.js b/ui (gen4)/ui.js index 7945d767..632d3b34 100755 --- a/ui (gen4)/ui.js +++ b/ui (gen4)/ui.js @@ -143,19 +143,44 @@ $(function(){ ig.features.features.length, ig.features.features) - ig.logger = ig.logger || {emit: function(e, v){ - console.log(' ', e, v) - - // XXX HACK -- need meaningful status... - if(e == 'queued' - || e == 'found'){ - ig.showProgress('Progress', '+0', '+1') + // XXX STUB... + ig.logger = ig.logger || { + root: true, + message: null, - } else if(e == 'loaded' || e == 'done' || e == 'written' - || e == 'skipping' || e == 'index'){ - ig.showProgress('Progress', '+1') - } - }} + emit: function(e, v){ + var msg = this.message + + // console... + console.log(' '+ ((msg && msg.concat('')) || []).join(': '), e, v) + + // progress... + // XXX HACK -- need meaningful status... + if(e == 'queued' + || e == 'found'){ + ig.showProgress(msg || ['Progress', e], '+0', '+1') + + } else if(e == 'loaded' || e == 'done' || e == 'written' + || e == 'skipping' || e == 'index'){ + ig.showProgress(msg || ['Progress', e], '+1') + } + }, + + push: function(msg){ + if(msg == null){ + return this + } + + var logger = Object.create(this) + logger.root = false + logger.message = logger.message == null ? [msg] : logger.message.concat([msg]) + + return logger + }, + pop: function(){ + return !this.__proto__.root ? this.__proto__ : this + }, + } // setup the viewer...