mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-10-31 11:20:09 +00:00 
			
		
		
		
	simplified the custom dialog constructing -- still not too happy with it + some preliminary work on exporting...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									de0136c614
								
							
						
					
					
						commit
						4063cc4898
					
				| @ -33,6 +33,15 @@ var browseWalk = require('lib/widget/browse-walk') | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /*********************************************************************/ | ||||
| 
 | ||||
| if(typeof(process) != 'undefined'){ | ||||
| 	var copy = file.denodeify(fse.copy) | ||||
| 	var ensureDir = file.denodeify(fse.ensureDir) | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /*********************************************************************/ | ||||
| // fs reader/loader...
 | ||||
| 
 | ||||
| @ -758,17 +767,21 @@ var FileSystemWriterActions = actions.Actions({ | ||||
| 	exportView: ['File/Export current view', | ||||
| 		function(){ | ||||
| 		}], | ||||
| 	// XXX not done yet...
 | ||||
| 	// 		needs:
 | ||||
| 	// 			ensureDir(..)
 | ||||
| 	// 			copy(..)
 | ||||
| 	// 		...both denodeify(..)'ed
 | ||||
| 	// XXX export current state as a full loadable index
 | ||||
| 
 | ||||
| 	// Export current state as a full loadable index
 | ||||
| 	//
 | ||||
| 	// XXX might be interesting to unify this and .exportView(..)
 | ||||
| 	// XXX should this return a promise??? ...a clean promise???
 | ||||
| 	// XXX add preview selection...
 | ||||
| 	// XXX handle .image.path and other stack files...
 | ||||
| 	// XXX local collections???
 | ||||
| 	// XXX add a ui...
 | ||||
| 	// 		- select path
 | ||||
| 	// 		- select preview size
 | ||||
| 	exportCollection: ['File/Export as collection', | ||||
| 		function(path, logger){ | ||||
| 			logger = logger || this.logger | ||||
| 
 | ||||
| 			var json = this.json() | ||||
| 
 | ||||
| 			// get all loaded gids...
 | ||||
| @ -785,6 +798,7 @@ var FileSystemWriterActions = actions.Actions({ | ||||
| 				var img = json.images[gid] | ||||
| 				if(img){ | ||||
| 					images[gid] = json.images[gid] | ||||
| 
 | ||||
| 					// remove un-needed previews...
 | ||||
| 					// XXX
 | ||||
| 				} | ||||
| @ -794,26 +808,27 @@ var FileSystemWriterActions = actions.Actions({ | ||||
| 			json.data.order = gids | ||||
| 			json.images = images | ||||
| 			// XXX should we check if index dir is present in path???
 | ||||
| 			path = path +'/'+ this.config['index-dir'] | ||||
| 
 | ||||
| 			// NOTE: if we are to use .saveIndex(..) here, do not forget
 | ||||
| 			// 		to reset .changes
 | ||||
| 			file.writeIndex( | ||||
| 				this.prepareIndexForWrite(json).prepared,  | ||||
| 				path,  | ||||
| 				this.config['index-filename-template'],  | ||||
| 				logger || this.logger) | ||||
| 			var index_path = path +'/'+ this.config['index-dir'] | ||||
| 
 | ||||
| 			// copy previews for the loaded images...
 | ||||
| 			// XXX should also optionally populate the base dir and nested favs...
 | ||||
| 			var base_dir = this.base_dir | ||||
| 			var base_dir = this.location.path | ||||
| 
 | ||||
| 			gids.forEach(function(gid){ | ||||
| 				var img = json.images[gid] | ||||
| 				var img_base = img.base_path | ||||
| 				img.base_path = path | ||||
| 				var previews = img.preview | ||||
| 
 | ||||
| 				for(var res in previews){ | ||||
| 				// NOTE: we are copying everything to one place so no 
 | ||||
| 				// 		need for a base path...
 | ||||
| 				delete img.base_path | ||||
| 
 | ||||
| 				// XXX copy img.path -- the main image, especially when no previews present....
 | ||||
| 				// XXX
 | ||||
| 
 | ||||
| 				Object.keys(previews).forEach(function(res){ | ||||
| 					var preview_path = decodeURI(previews[res])  | ||||
| 
 | ||||
| 					var from = (img_base || base_dir) +'/'+ preview_path | ||||
| 					var to = path +'/'+ preview_path | ||||
| 
 | ||||
| @ -823,7 +838,7 @@ var FileSystemWriterActions = actions.Actions({ | ||||
| 					// XXX
 | ||||
| 					ensureDir(pathlib.dirname(to)) | ||||
| 						.catch(function(err){ | ||||
| 							// XXX
 | ||||
| 							logger && logger.emit('error', err) | ||||
| 						}) | ||||
| 						.then(function(){ | ||||
| 							return copy(from, to) | ||||
| @ -832,12 +847,99 @@ var FileSystemWriterActions = actions.Actions({ | ||||
| 								// 		we just use the one above (after
 | ||||
| 								// 		.then(..))
 | ||||
| 								.catch(function(err){ | ||||
| 									// XXX
 | ||||
| 									logger && logger.emit('error', err) | ||||
| 								}) | ||||
| 								.then(function(){ | ||||
| 									logger && logger.emit('done', to) | ||||
| 								}) | ||||
| 						}) | ||||
| 				} | ||||
| 				}) | ||||
| 			}) | ||||
| 
 | ||||
| 			// NOTE: if we are to use .saveIndex(..) here, do not forget
 | ||||
| 			// 		to reset .changes
 | ||||
| 			file.writeIndex( | ||||
| 				this.prepareIndexForWrite(json, true).prepared,  | ||||
| 				index_path,  | ||||
| 				this.config['index-filename-template'],  | ||||
| 				logger || this.logger) | ||||
| 			 | ||||
| 		}], | ||||
| 	 | ||||
| 	// XXX use options:
 | ||||
| 	// 		- level dir name
 | ||||
| 	// 		- size
 | ||||
| 	// 		- filename pattern
 | ||||
| 	// XXX might also be good to save/load the export state to .ImageGrid-export.json
 | ||||
| 	// XXX make custom previews...
 | ||||
| 	// 		...should this be a function of .images.getBestPreview(..)???
 | ||||
| 	exportDirs: ['File/Export as nested directories', | ||||
| 		function(path, pattern, level_dir, size, logger){ | ||||
| 			logger = logger || this.logger | ||||
| 			var that = this | ||||
| 			var base_dir = this.location.path | ||||
| 			var to_dir = path | ||||
| 
 | ||||
| 			// get/set the config data...
 | ||||
| 			// XXX should this store the last set???
 | ||||
| 			level_dir = level_dir || this.config['export-level-directory-name'] || 'fav' | ||||
| 			size = size || this.config['export-preview-size'] || 1000 | ||||
| 			pattern = pattern || this.config['export-preview-name-pattern'] || '%f' | ||||
| 
 | ||||
| 			this.data.ribbon_order | ||||
| 				.slice() | ||||
| 				.reverse() | ||||
| 				.forEach(function(ribbon){ | ||||
| 					// NOTE: this is here to keep the specific path local to 
 | ||||
| 					// 		this scope...
 | ||||
| 					var img_dir = to_dir | ||||
| 
 | ||||
| 					ensureDir(pathlib.dirname(img_dir)) | ||||
| 						.catch(function(err){ | ||||
| 							logger && logger.emit('error', err) | ||||
| 						}) | ||||
| 						.then(function(){ | ||||
| 							that.data.ribbons[ribbon].forEach(function(gid){ | ||||
| 								var img = that.images[gid] | ||||
| 
 | ||||
| 
 | ||||
| 								// get best preview...
 | ||||
| 								var from = (img.base_path || base_dir) +'/'+ that.images.getBestPreview(gid, size).url | ||||
| 
 | ||||
| 								// XXX see if we need to make a preview (sharp)
 | ||||
| 								// XXX
 | ||||
| 
 | ||||
| 								// XXX get/form image name... 
 | ||||
| 								// XXX might be a good idea to connect this to the info framework...
 | ||||
| 								var ext = pathlib.extname(img.name) | ||||
| 								var name = pattern | ||||
| 									.replace(/%f/, img.name) | ||||
| 									.replace(/%n/, img.name.replace(ext, '')) | ||||
| 									.replace(/%e/, ext) | ||||
| 									.replace(/%gid/, gid) | ||||
| 									// XXX get the correct length...
 | ||||
| 									.replace(/%g/, gid.slice(-7, -1)) | ||||
| 									// XXX %()m marked...
 | ||||
| 									// XXX
 | ||||
| 									// XXX %()b bookmarked...
 | ||||
| 									// XXX
 | ||||
| 									// XXX EXIF...
 | ||||
| 
 | ||||
| 								var to = img_dir +'/'+ name | ||||
| 
 | ||||
| 								copy(from, to) | ||||
| 									.catch(function(err){ | ||||
| 										logger && logger.emit('error', err) | ||||
| 									}) | ||||
| 									.then(function(){ | ||||
| 										logger && logger.emit('done', to) | ||||
| 									}) | ||||
| 							}) | ||||
| 						}) | ||||
| 
 | ||||
| 					to_dir += '/'+level_dir | ||||
| 				}) | ||||
| 		}] | ||||
| }) | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -57,33 +57,25 @@ var SlideshowActions = actions.Actions({ | ||||
| 
 | ||||
| 			this.suspendSlideshowTimer() | ||||
| 
 | ||||
| 			// XXX might be a good idea to make this generic...
 | ||||
| 			var _makeTogglHandler = function(toggler){ | ||||
| 				return function(){ | ||||
| 					var txt = $(this).find('.text').first().text() | ||||
| 					that[toggler]() | ||||
| 					o.client.update() | ||||
| 						.then(function(){ o.client.select(txt) }) | ||||
| 					that.toggleSlideshow('?') == 'on'  | ||||
| 						&& o.close() | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			var o = overlay.Overlay(this.ribbons.viewer,  | ||||
| 				browse.makeList( | ||||
| 					null, | ||||
| 					[ | ||||
| 						// XXX make this editable...
 | ||||
| 						['Interval: ',  | ||||
| 							function(){ return that.config['slideshow-interval'] }], | ||||
| 						['Direction: ',  | ||||
| 							function(){ return that.config['slideshow-direction'] }], | ||||
| 						['Looping: ',  | ||||
| 							function(){ return that.config['slideshow-looping'] }], | ||||
| 				browse.makeLister(null, function(path, make){ | ||||
| 					make(['Interval: ',  | ||||
| 							function(){ return that.config['slideshow-interval'] }]) | ||||
| 						.on('open', function(){ | ||||
| 							var txt = $(this).find('.text').first().text() | ||||
| 
 | ||||
| 						//'---',
 | ||||
| 						[function(){  | ||||
| 							return that.toggleSlideshow('?') == 'on' ? 'Stop' : 'Start' }], | ||||
| 					]) | ||||
| 					.open(function(evt, path){ | ||||
| 						// start/stop...
 | ||||
| 						if(path == 'Start' || path == 'Stop'){ | ||||
| 							that.toggleSlideshow() | ||||
| 							o.close() | ||||
| 							return | ||||
| 						} | ||||
| 
 | ||||
| 						// interval...
 | ||||
| 						if(/interval/i.test(path)){ | ||||
| 							var to_remove = [] | ||||
| 							var oo = widgets.makeConfigListEditor(that, 'slideshow-intervals', { | ||||
| 									new_button: 'New...', | ||||
| 									length_limit: that.config['slideshow-interval-max-count'], | ||||
| @ -107,9 +99,8 @@ var SlideshowActions = actions.Actions({ | ||||
| 									// XXX this is ugly...
 | ||||
| 									o.focus() | ||||
| 
 | ||||
| 									if(that.toggleSlideshow('?') == 'on'){ | ||||
| 										o.close() | ||||
| 									} | ||||
| 									that.toggleSlideshow('?') == 'on' | ||||
| 										&& o.close() | ||||
| 								}) | ||||
| 
 | ||||
| 							oo.client | ||||
| @ -122,42 +113,36 @@ var SlideshowActions = actions.Actions({ | ||||
| 
 | ||||
| 										// XXX this is ugly...
 | ||||
| 										oo.close() | ||||
| 
 | ||||
| 										o.client.update() | ||||
| 										o.client.select(path.split(':')[0]) | ||||
| 										o.client.select(txt) | ||||
| 									} | ||||
| 								}) | ||||
| 
 | ||||
| 							oo.client.dom.addClass('tail-action') | ||||
| 							oo.client.select(that.config['slideshow-interval']) | ||||
| 						}) | ||||
| 
 | ||||
| 							return | ||||
| 						} | ||||
| 					make(['Direction: ',  | ||||
| 							function(){ return that.config['slideshow-direction'] }]) | ||||
| 						.on('open', _makeTogglHandler('toggleSlideshowDirection')) | ||||
| 					make(['Looping: ',  | ||||
| 							function(){ return that.config['slideshow-looping'] }]) | ||||
| 						.on('open', _makeTogglHandler('toggleSlideshowLooping')) | ||||
| 
 | ||||
| 						// direction...
 | ||||
| 						if(/direction/i.test(path)){ | ||||
| 							that.toggleSlideshowDirection() | ||||
| 							o.client.update() | ||||
| 
 | ||||
| 						// Looping...
 | ||||
| 						} else if(/looping/i.test(path)){ | ||||
| 							that.toggleSlideshowLooping() | ||||
| 							o.client.update() | ||||
| 						} | ||||
| 
 | ||||
| 						// XXX this is ugly...
 | ||||
| 						o.client.select(path.split(':')[0]) | ||||
| 
 | ||||
| 						// do not keep the dialog open during the slideshow...
 | ||||
| 						if(that.toggleSlideshow('?') == 'on'){ | ||||
| 					// Start/stop...
 | ||||
| 					make([function(){  | ||||
| 							return that.toggleSlideshow('?') == 'on' ? 'Stop' : 'Start' }]) | ||||
| 						.on('open', function(){ | ||||
| 							that.toggleSlideshow() | ||||
| 							o.close() | ||||
| 						} | ||||
| 					})) | ||||
| 						}) | ||||
| 				})) | ||||
| 				.close(function(){ | ||||
| 					that.resetSlideshowTimer() | ||||
| 				}) | ||||
| 
 | ||||
| 			o.client.dom.addClass('metadata-view tail-action') | ||||
| 
 | ||||
| 			o.client.select(-1) | ||||
| 
 | ||||
| 			return o | ||||
|  | ||||
| @ -94,8 +94,15 @@ function listJSON(path, pattern){ | ||||
| 	return gGlob(path +'/'+ pattern +'.json') | ||||
| } | ||||
| 
 | ||||
| // wrap a node style callback function into a Promise...
 | ||||
| //
 | ||||
| // NOTE: this is inspired by the promise module for node this stopped 
 | ||||
| // 		working, and porting one method was simpler that trying to get
 | ||||
| // 		to the bottom of the issue, especially with native promises...
 | ||||
| // XXX move to someplace generic...
 | ||||
| var denodeify = function(func){ | ||||
| var denodeify =  | ||||
| module.denodeify = | ||||
| function(func){ | ||||
| 	return function(){ | ||||
| 		// XXX for some reason this does not see args2array...
 | ||||
| 		// XXX and for some reason the error is not reported...
 | ||||
|  | ||||
| @ -2189,6 +2189,48 @@ Browser.prototype.__proto__ = widget.Widget.prototype | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /*********************************************************************/ | ||||
| 
 | ||||
| var ListerPrototype = Object.create(BrowserPrototype) | ||||
| ListerPrototype.options = { | ||||
| 	pathPrefix: '',  | ||||
| 	fullPathEdit: false, | ||||
| 	traversable: false, | ||||
| 	flat: true, | ||||
| 
 | ||||
| 	// XXX not sure if we need these...
 | ||||
| 	skipDisabledItems: false, | ||||
| 	// NOTE: to disable this set it to false or null
 | ||||
| 	disableItemPattern: '^- ', | ||||
| 
 | ||||
| 	elementSeparatorText: '---', | ||||
| } | ||||
| // XXX should we inherit or copy options???
 | ||||
| // 		...inheriting might pose problems with deleting values reverting
 | ||||
| // 		them to default instead of nulling them and mutable options might
 | ||||
| // 		get overwritten...
 | ||||
| ListerPrototype.options.__proto__ = BrowserPrototype.options | ||||
| 
 | ||||
| var Lister =  | ||||
| module.Lister =  | ||||
| object.makeConstructor('Lister',  | ||||
| 		BrowserClassPrototype,  | ||||
| 		ListerPrototype) | ||||
| 
 | ||||
| 
 | ||||
| // This is a shorthand for: new List(<elem>, { data: <list> })
 | ||||
| var makeLister =  | ||||
| module.makeLister = function(elem, lister, options){ | ||||
| 	var opts = {} | ||||
| 	for(var k in options){ | ||||
| 		opts[k] = rest[k] | ||||
| 	} | ||||
| 	opts.list = lister | ||||
| 	return Lister(elem, opts) | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /*********************************************************************/ | ||||
| 
 | ||||
| // Flat list...
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user