mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-10-31 03:10:07 +00:00 
			
		
		
		
	more refactoring -- unbloating features/ui.js
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									af7a8cf51f
								
							
						
					
					
						commit
						9e4e5eced5
					
				| @ -10,26 +10,29 @@ define(function(require){ var module = {} | ||||
| 
 | ||||
| // import features...
 | ||||
| var core = require('features/core') | ||||
| var base = require('features/base') | ||||
| var location = require('features/location') | ||||
| var history = require('features/history') | ||||
| var app = require('features/app') | ||||
| var ui = require('features/ui') | ||||
| var keyboard = require('features/keyboard') | ||||
| var status = require('features/ui-status') | ||||
| var marks = require('features/ui-marks') | ||||
| var widgets = require('features/ui-widgets') | ||||
| var slideshow = require('features/ui-slideshow') | ||||
| var exteditor = require('features/external-editor') | ||||
| var metadata = require('features/metadata') | ||||
| var meta = require('features/meta') | ||||
| 
 | ||||
| var experimental = require('features/experimental') | ||||
| var demo = require('features/demo') | ||||
| require('features/base') | ||||
| require('features/location') | ||||
| require('features/history') | ||||
| require('features/app') | ||||
| require('features/ui') | ||||
| require('features/ui-single-image') | ||||
| require('features/ui-chrome') | ||||
| require('features/keyboard') | ||||
| require('features/ui-status') | ||||
| require('features/ui-marks') | ||||
| require('features/ui-widgets') | ||||
| require('features/ui-slideshow') | ||||
| require('features/external-editor') | ||||
| require('features/metadata') | ||||
| require('features/meta') | ||||
| 
 | ||||
| require('features/experimental') | ||||
| require('features/demo') | ||||
| 
 | ||||
| if(window.nodejs != null){ | ||||
| 	var filesystem = require('features/filesystem') | ||||
| 	var cli = require('features/cli') | ||||
| 	require('features/filesystem') | ||||
| 	require('features/cli') | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -928,6 +928,269 @@ core.ImageGridFeatures.Feature('base-full', [ | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| //---------------------------------------------------------------------
 | ||||
| // Journal...
 | ||||
| 
 | ||||
| function logImageShift(action){ | ||||
| 	return [action.slice(-4) != '.pre' ?  | ||||
| 			action + '.pre'  | ||||
| 			: action, | ||||
| 		function(target){ | ||||
| 			target = this.data.getImage(target) | ||||
| 			var args = args2array(arguments) | ||||
| 
 | ||||
| 			var o = this.data.getImageOrder(target) | ||||
| 			var r = this.data.getRibbon(target) | ||||
| 			var current = this.current | ||||
| 
 | ||||
| 			return function(){ | ||||
| 				var on = this.data.getImageOrder(target) | ||||
| 				var rn = this.data.getRibbon(target) | ||||
| 
 | ||||
| 				if(o == on || r == rn){  | ||||
| 					/* | ||||
| 					this.journalPush( | ||||
| 						this.current,  | ||||
| 						action,  | ||||
| 						args, | ||||
| 						{ | ||||
| 							before: [r, o], | ||||
| 							after: [rn, on], | ||||
| 						}) | ||||
| 					*/ | ||||
| 					this.journalPush({ | ||||
| 						type: 'shift', | ||||
| 						current: current,  | ||||
| 						target: target, | ||||
| 						action: action,  | ||||
| 						args: args, | ||||
| 						undo: journalActions[action], | ||||
| 						diff: { | ||||
| 							before: [r, o], | ||||
| 							after: [rn, on], | ||||
| 						}, | ||||
| 					}) | ||||
| 				} | ||||
| 				 | ||||
| 			} | ||||
| 		}] | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // Format:
 | ||||
| // 	{
 | ||||
| // 		<action>: <undo-action> | <undo-function> | null,
 | ||||
| // 		...
 | ||||
| // 	}
 | ||||
| var journalActions = { | ||||
| 	clear: null, | ||||
| 	load: null, | ||||
| 
 | ||||
| 	setBaseRibbon: null, | ||||
| 
 | ||||
| 	// XXX need to account for position change, i.e. if action had no 
 | ||||
| 	// 		effect then do nothing...
 | ||||
| 	// 		...take target position before and after...
 | ||||
| 	shiftImageTo: null, | ||||
| 
 | ||||
| 	shiftImageUp: 'shiftImageDown', | ||||
| 	shiftImageDown: 'shiftImageUp', | ||||
| 	shiftImageLeft: 'shiftImageRight', | ||||
| 	shiftImageRight: 'shiftImageLeft', | ||||
| 	shiftRibbonUp: 'shiftRibbonDown', | ||||
| 	shiftRibbonDown: 'shiftRibbonUp', | ||||
| 
 | ||||
| 	rotateCW: 'rotateCCW', | ||||
| 	rotateCCW: 'rotateCW', | ||||
| 	flipHorizontal: 'flipHorizontal', | ||||
| 	flipVertical: 'flipVertical', | ||||
| 
 | ||||
| 	sortImages: null, | ||||
| 	reverseImages: 'reverseImages', | ||||
| 	reverseRibbons: 'reverseRibbons', | ||||
| 
 | ||||
| 	crop: null, | ||||
| 	uncrop: null, | ||||
| 
 | ||||
| 	tag: null,  | ||||
| 	untag: null, | ||||
| 
 | ||||
| 	group: null, | ||||
| 	ungroup: null, | ||||
| 	expandGroup: null, | ||||
| 	collapseGroup: null, | ||||
| 
 | ||||
| 	runJournal: null, | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // XXX is this the right level for this???
 | ||||
| // 		...data seems to be a better candidate...
 | ||||
| // XXX would be great to add a mechanism define how to reverse actions...
 | ||||
| // 		...one way to do this at this point is to revert to last state
 | ||||
| // 		and re-run the journal until the desired event...
 | ||||
| // XXX need to define a clear journaling strategy in the lines of:
 | ||||
| // 		- save state clears journal and adds a state load action
 | ||||
| // 		- .load(..) clears journal
 | ||||
| // XXX needs careful testing...
 | ||||
| var Journal =  | ||||
| module.Journal = core.ImageGridFeatures.Feature({ | ||||
| 	title: 'Action Journal', | ||||
| 
 | ||||
| 	tag: 'system-journal', | ||||
| 
 | ||||
| 	depends: ['base'], | ||||
| 
 | ||||
| 	actions: actions.Actions({ | ||||
| 
 | ||||
| 		journal: null, | ||||
| 		rjournal: null, | ||||
| 
 | ||||
| 		clone: [function(full){ | ||||
| 				return function(res){ | ||||
| 					res.rjournal = null | ||||
| 					res.journal = null | ||||
| 					if(full && this.hasOwnProperty('journal') && this.journal){ | ||||
| 						res.journal = JSON.parse(JSON.stringify(this.journal)) | ||||
| 					} | ||||
| 				} | ||||
| 			}], | ||||
| 
 | ||||
| 		// XXX might be good to add some kind of metadata to journal...
 | ||||
| 		journalPush: ['- Journal/Add an item to journal', | ||||
| 			function(data){ | ||||
| 				this.journal = (this.hasOwnProperty('journal')  | ||||
| 						|| this.journal) ?  | ||||
| 					this.journal  | ||||
| 					: [] | ||||
| 				this.journal.push(data) | ||||
| 			}], | ||||
| 		clearJournal: ['Journal/Clear the action journal', | ||||
| 			function(){ | ||||
| 				if(this.journal){ | ||||
| 					// NOTE: overwriting here is better as it will keep
 | ||||
| 					// 		shadowing the parent's .journal in case we 
 | ||||
| 					// 		are cloned.
 | ||||
| 					// NOTE: either way this will have no effect as we 
 | ||||
| 					// 		only use the local .journal but the user may
 | ||||
| 					// 		get confused...
 | ||||
| 					//delete this.journal
 | ||||
| 					this.journal = null | ||||
| 				} | ||||
| 			}], | ||||
| 		runJournal: ['- Journal/Run journal', | ||||
| 			function(journal){ | ||||
| 				var that = this | ||||
| 				journal.forEach(function(e){ | ||||
| 					// load state...
 | ||||
| 					that | ||||
| 						.focusImage(e.current) | ||||
| 						// run action...
 | ||||
| 						[e.action].apply(that, e.args) | ||||
| 				}) | ||||
| 			}], | ||||
| 
 | ||||
| 		// XXX need to clear the rjournal as soon as we do something...
 | ||||
| 		// 		...at this point it is really easy to mess things up by
 | ||||
| 		// 		undoing something, and after some actions doing a 
 | ||||
| 		// 		.redoLast(..)
 | ||||
| 		// XXX this is not ready for production...
 | ||||
| 		undoLast: ['Journal/Undo last', | ||||
| 			function(){ | ||||
| 				var journal = this.journal | ||||
| 				this.rjournal = (this.hasOwnProperty('rjournal')  | ||||
| 						|| this.rjournal) ?  | ||||
| 					this.rjournal  | ||||
| 					: [] | ||||
| 
 | ||||
| 				for(var i = journal.length-1; i >= 0; i--){ | ||||
| 					var a = journal[i] | ||||
| 
 | ||||
| 					// we undo only a very specific set of actions...
 | ||||
| 					if(a.undo && a.type == 'shift' && a.args.length == 0){ | ||||
| 						this | ||||
| 							.focusImage(a.current) | ||||
| 							[a.undo].call(this, a.target) | ||||
| 
 | ||||
| 						// pop the undo command...
 | ||||
| 						this.journal.pop() | ||||
| 						this.rjournal.push(journal.splice(i, 1)[0]) | ||||
| 						break | ||||
| 					} | ||||
| 				} | ||||
| 			}], | ||||
| 		_redoLast: ['Journal/Redo last', | ||||
| 			function(){ | ||||
| 				if(!this.rjournal || this.rjournal.length == 0){ | ||||
| 					return | ||||
| 				} | ||||
| 
 | ||||
| 				this.runJournal([this.rjournal.pop()]) | ||||
| 			}], | ||||
| 	}), | ||||
| 
 | ||||
| 	// log state, action and its args... 
 | ||||
| 	// XXX need to drop journal on save...
 | ||||
| 	// XXX rotate/truncate journal???
 | ||||
| 	// XXX need to check that all the listed actions are clean -- i.e.
 | ||||
| 	// 		running the journal will produce the same results as user 
 | ||||
| 	// 		actions that generated the journal.
 | ||||
| 	// XXX would be good if we could know the name of the action in the 
 | ||||
| 	// 		handler, thus enabling us to define a single handler rather
 | ||||
| 	// 		than generating a custom handler per action...
 | ||||
| 	handlers: [ | ||||
| 		logImageShift('shiftImageTo'), | ||||
| 		logImageShift('shiftImageUp'), | ||||
| 		logImageShift('shiftImageDown'), | ||||
| 		logImageShift('shiftImageLeft'), | ||||
| 		logImageShift('shiftImageRight'), | ||||
| 		logImageShift('shiftRibbonUp'), | ||||
| 		logImageShift('shiftRibbonDown'), | ||||
| 
 | ||||
| 	].concat([ | ||||
| 			'clear', | ||||
| 			'load', | ||||
| 
 | ||||
| 			'setBaseRibbon', | ||||
| 
 | ||||
| 			'rotateCW', | ||||
| 			'rotateCCW', | ||||
| 			'flipHorizontal', | ||||
| 			'flipVertical', | ||||
| 
 | ||||
| 			'sortImages', | ||||
| 			'reverseImages', | ||||
| 			'reverseRibbons', | ||||
| 
 | ||||
| 			'crop', | ||||
| 			'uncrop', | ||||
| 
 | ||||
| 			'tag',  | ||||
| 			'untag', | ||||
| 
 | ||||
| 			'group', | ||||
| 			'ungroup', | ||||
| 			'expandGroup', | ||||
| 			'collapseGroup', | ||||
| 
 | ||||
| 			//'runJournal',
 | ||||
| 		].map(function(action){ | ||||
| 			return [ | ||||
| 				action+'.pre',  | ||||
| 				function(){ | ||||
| 					this.journalPush({ | ||||
| 						type: 'basic', | ||||
| 						current: this.current,  | ||||
| 						action: action,  | ||||
| 						args: args2array(arguments), | ||||
| 					}) | ||||
| 				}] | ||||
| 		})),  | ||||
| }) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /********************************************************************** | ||||
| * vim:set ts=4 sw=4 :                                                */ | ||||
| return module }) | ||||
|  | ||||
| @ -95,6 +95,9 @@ module.ExternalEditor = core.ImageGridFeatures.Feature({ | ||||
| 	depends: [ | ||||
| 		'base', | ||||
| 	], | ||||
| 	suggested: [ | ||||
| 		'ui-external-editor', | ||||
| 	], | ||||
| 
 | ||||
| 	isApplicable: function(){  | ||||
| 		return this.runtime == 'nw' || this.runtime == 'node' }, | ||||
|  | ||||
| @ -320,6 +320,10 @@ module.FileSystemLoader = core.ImageGridFeatures.Feature({ | ||||
| 	depends: [ | ||||
| 		'location', | ||||
| 	], | ||||
| 	suggested: [ | ||||
| 		'ui-fs-loader', | ||||
| 		'fs-url-history', | ||||
| 	], | ||||
| 
 | ||||
| 	actions: FileSystemLoaderActions, | ||||
| 
 | ||||
| @ -505,6 +509,9 @@ module.FileSystemLoaderURLHistory = core.ImageGridFeatures.Feature({ | ||||
| 		'fs-loader', | ||||
| 		'url-history', | ||||
| 	], | ||||
| 	suggested: [ | ||||
| 		'ui-fs-url-history', | ||||
| 	], | ||||
| 
 | ||||
| 	handlers: [ | ||||
| 		pushToHistory('loadImages'),  | ||||
| @ -841,7 +848,12 @@ module.FileSystemWriter = core.ImageGridFeatures.Feature({ | ||||
| 
 | ||||
| 	tag: 'fs-writer', | ||||
| 	// NOTE: this is mostly because of the base path handling...
 | ||||
| 	depends: ['fs-loader'], | ||||
| 	depends: [ | ||||
| 		'fs-loader' | ||||
| 	], | ||||
| 	suggested: [ | ||||
| 		'ui-fs-writer', | ||||
| 	], | ||||
| 
 | ||||
| 	actions: FileSystemWriterActions, | ||||
| 
 | ||||
| @ -998,6 +1010,13 @@ module.FileSystemWriterUI = core.ImageGridFeatures.Feature({ | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| //---------------------------------------------------------------------
 | ||||
| 
 | ||||
| core.ImageGridFeatures.Feature('fs', [ | ||||
| 	'fs-loader', | ||||
| 	'fs-writer', | ||||
| ]) | ||||
| 
 | ||||
| 
 | ||||
| /********************************************************************** | ||||
| * vim:set ts=4 sw=4 :                                                */ | ||||
|  | ||||
| @ -182,6 +182,11 @@ module.URLHistory = core.ImageGridFeatures.Feature({ | ||||
| 	depends: [ | ||||
| 		'location', | ||||
| 	], | ||||
| 	suggested: [ | ||||
| 		'ui-url-history', | ||||
| 		'url-history-local-storage', | ||||
| 		'url-history-fs-writer', | ||||
| 	], | ||||
| 
 | ||||
| 	actions: URLHistoryActions, | ||||
| }) | ||||
|  | ||||
| @ -38,11 +38,9 @@ core.ImageGridFeatures.Feature('viewer-minimal', [ | ||||
| 	'image-marks', | ||||
| 	'image-bookmarks', | ||||
| 
 | ||||
| 	'fs-loader', | ||||
| 	'fs-writer', | ||||
| 	'fs', | ||||
| 
 | ||||
| 	'metadata', | ||||
| 	'fs-metadata', | ||||
| ]) | ||||
| 
 | ||||
| 
 | ||||
| @ -62,7 +60,7 @@ core.ImageGridFeatures.Feature('viewer-testing', [ | ||||
| 	//'ui-ribbon-align-to-first',
 | ||||
| 	//'ui-ribbon-manual-align',
 | ||||
| 	 | ||||
| 	'ui-single-image-view', | ||||
| 	'ui-single-image', | ||||
| 	'ui-partial-ribbons', | ||||
| 
 | ||||
| 	// XXX
 | ||||
| @ -70,30 +68,16 @@ core.ImageGridFeatures.Feature('viewer-testing', [ | ||||
| 	//'ui-direct-control',
 | ||||
| 	//'ui-indirect-control',
 | ||||
| 
 | ||||
| 	'image-marks', | ||||
| 	'image-bookmarks', | ||||
| 
 | ||||
| 	'marks', | ||||
| 
 | ||||
| 	// local storage + url...
 | ||||
| 	'config-local-storage', | ||||
| 	'ui-url-hash', | ||||
| 	'url-history-local-storage', | ||||
| 	'url-history-fs-writer', | ||||
| 	'url-history', | ||||
| 	'ui-single-image-view-local-storage', | ||||
| 
 | ||||
| 
 | ||||
| 	// fs...
 | ||||
| 	'ui-fs-loader', | ||||
| 	'fs-url-history', | ||||
| 	'ui-fs-url-history', | ||||
| 	'ui-fs-writer', | ||||
| 
 | ||||
| 	'metadata', | ||||
| 	'fs-metadata', | ||||
| 	'ui-metadata', | ||||
| 
 | ||||
| 	'external-editor', | ||||
| 	'ui-external-editor', | ||||
| 
 | ||||
| 	// chrome...
 | ||||
| 	'ui-status-log', | ||||
| @ -118,8 +102,6 @@ core.ImageGridFeatures.Feature('viewer-testing', [ | ||||
| 
 | ||||
| 	// ui control...
 | ||||
| 	'ui-clickable', | ||||
| 	//'ui-autohide-cursor',
 | ||||
| 	'ui-autohide-cursor-single-image-view', | ||||
| 	//'ui-direct-control-jquery',
 | ||||
| 	// XXX BUG: on touch down and first move this gets offset by a distance
 | ||||
| 	// 		not sure why...
 | ||||
|  | ||||
| @ -75,6 +75,10 @@ module.Metadata = core.ImageGridFeatures.Feature({ | ||||
| 	depends: [ | ||||
| 		'base', | ||||
| 	], | ||||
| 	suggested: [ | ||||
| 		'fs-metadata', | ||||
| 		'ui-metadata', | ||||
| 	], | ||||
| 
 | ||||
| 	actions: MetadataActions, | ||||
| }) | ||||
|  | ||||
							
								
								
									
										619
									
								
								ui (gen4)/features/ui-chrome.js
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										619
									
								
								ui (gen4)/features/ui-chrome.js
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,619 @@ | ||||
| /********************************************************************** | ||||
| *  | ||||
| * | ||||
| * | ||||
| **********************************************************************/ | ||||
| 
 | ||||
| define(function(require){ var module = {} | ||||
| 
 | ||||
| //var DEBUG = DEBUG != null ? DEBUG : true
 | ||||
| 
 | ||||
| var actions = require('lib/actions') | ||||
| var features = require('lib/features') | ||||
| var toggler = require('lib/toggler') | ||||
| 
 | ||||
| var core = require('features/core') | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /*********************************************************************/ | ||||
| 
 | ||||
| // helper...
 | ||||
| function didAdvance(indicator){ | ||||
| 	return function(){ | ||||
| 		var img = this.data.current | ||||
| 		return function(){ | ||||
| 			if(img == this.data.current){ | ||||
| 				this.flashIndicator(indicator) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| var BoundsIndicatorsActions = actions.Actions({ | ||||
| 	flashIndicator: ['- Interface/Flash an indicator', | ||||
| 		function(direction){ | ||||
| 			if(this.ribbons.getRibbonSet().length == 0){ | ||||
| 				return | ||||
| 			} | ||||
| 			var cls = { | ||||
| 				// shift up/down...
 | ||||
| 				up: '.up-indicator', | ||||
| 				down: '.down-indicator', | ||||
| 				// hit start/end/top/bottom of view...
 | ||||
| 				start: '.start-indicator', | ||||
| 				end: '.end-indicator', | ||||
| 				top: '.top-indicator', | ||||
| 				bottom: '.bottom-indicator', | ||||
| 			}[direction] | ||||
| 
 | ||||
| 			var indicator = this.ribbons.viewer.find(cls) | ||||
| 
 | ||||
| 			if(indicator.length == 0){ | ||||
| 				indicator = $('<div>') | ||||
| 					.addClass(cls.replace('.', '') +' '+ this.tag) | ||||
| 					.appendTo(this.ribbons.viewer) | ||||
| 			} | ||||
| 
 | ||||
| 			return indicator | ||||
| 				// NOTE: this needs to be visible in all cases and key press 
 | ||||
| 				// 		rhythms... 
 | ||||
| 				.show() | ||||
| 				.delay(100) | ||||
| 				.fadeOut(300) | ||||
| 		}], | ||||
| }) | ||||
| 
 | ||||
| var BoundsIndicators =  | ||||
| module.BoundsIndicators = core.ImageGridFeatures.Feature({ | ||||
| 	title: '', | ||||
| 	doc: '', | ||||
| 
 | ||||
| 	tag: 'ui-bounds-indicators', | ||||
| 	depends: ['ui'], | ||||
| 
 | ||||
| 	actions: BoundsIndicatorsActions, | ||||
| 
 | ||||
| 	handlers: [ | ||||
| 		// basic navigation...
 | ||||
| 		['nextImage.pre lastImage.pre', didAdvance('end')], | ||||
| 		['prevImage.pre firstImage.pre', didAdvance('start')], | ||||
| 		['nextRibbon.pre lastRibbon.pre', didAdvance('bottom')], | ||||
| 		['prevRibbon.pre firstRibbon.pre', didAdvance('top')], | ||||
| 
 | ||||
| 		// vertical shifting...
 | ||||
| 		['shiftImageUp.pre', | ||||
| 			function(target){  | ||||
| 				target = target || this.current | ||||
| 				var r = this.data.getRibbonOrder(target) | ||||
| 
 | ||||
| 				var l = this.data.getImages(r).length | ||||
| 				var l0 = this.data.getImages(0).length | ||||
| 
 | ||||
| 				return function(){ | ||||
| 					// when shifting last image of top ribbon (i.e. length == 1)
 | ||||
| 					// up the state essentially will not change...
 | ||||
| 					if((r == 0 && l == 1)  | ||||
| 							// we are shifting to a new empty ribbon...
 | ||||
| 							|| (r == 1 && l == 1 && l0 == 0)){ | ||||
| 						this.flashIndicator('top') | ||||
| 					} else {	 | ||||
| 						this.flashIndicator('up') | ||||
| 					} | ||||
| 				} | ||||
| 			}], | ||||
| 		['shiftImageDown.pre', | ||||
| 			function(target){  | ||||
| 				target = target || this.current | ||||
| 				var r0 = this.data.getRibbonOrder(target) | ||||
| 				var l = this.data.getImages(r0).length | ||||
| 
 | ||||
| 				return function(){ | ||||
| 					var r1 = this.data.getRibbonOrder(target) | ||||
| 					if(r0 == r1 && r0 == this.data.ribbon_order.length-1 && l == 1){ | ||||
| 						this.flashIndicator('bottom') | ||||
| 					} else { | ||||
| 						this.flashIndicator('down')  | ||||
| 					} | ||||
| 				} | ||||
| 			}], | ||||
| 
 | ||||
| 		// horizontal shifting...
 | ||||
| 		['shiftImageLeft.pre', | ||||
| 			function(target){  | ||||
| 				if(target == null  | ||||
| 						//&& actions.data.getImageOrder('ribbon') == 0){
 | ||||
| 						&& this.data.getImage('prev') == null){ | ||||
| 					this.flashIndicator('start') | ||||
| 				} | ||||
| 			}], | ||||
| 		['shiftImageRight.pre', | ||||
| 			function(target){  | ||||
| 				if(target == null  | ||||
| 						&& this.data.getImage('next') == null){ | ||||
| 					this.flashIndicator('end') | ||||
| 				} | ||||
| 			}], | ||||
| 	], | ||||
| }) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| //---------------------------------------------------------------------
 | ||||
| 
 | ||||
| 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() | ||||
| 
 | ||||
| 			if(ribbon_set.length == 0){ | ||||
| 				return | ||||
| 			} | ||||
| 
 | ||||
| 			var scale = this.ribbons.scale() | ||||
| 			var cur = this.ribbons.getImage(target) | ||||
| 			// NOTE: cur may be unloaded...
 | ||||
| 			var ribbon = this.ribbons.getRibbon(cur.length > 0 ? target : this.currentRibbon) | ||||
| 
 | ||||
| 			var marker = ribbon.find('.current-marker') | ||||
| 
 | ||||
| 			// remove marker if current image is not loaded...
 | ||||
| 			if(cur.length == 0){ | ||||
| 				marker.remove() | ||||
| 				return | ||||
| 			} | ||||
| 
 | ||||
| 			// get config...
 | ||||
| 			var border = this.config['current-image-border'] | ||||
| 			var min_border = this.config['current-image-min-border'] | ||||
| 			var border_timeout = this.config['current-image-border-timeout'] | ||||
| 			var fadein = this.config['current-image-indicator-fadein'] | ||||
| 
 | ||||
| 			// no marker found -- either in different ribbon or not created yet...
 | ||||
| 			if(marker.length == 0){ | ||||
| 				// get marker globally...
 | ||||
| 				marker = this.ribbons.viewer.find('.current-marker') | ||||
| 
 | ||||
| 				// no marker exists -- create a marker...
 | ||||
| 				if(marker.length == 0){ | ||||
| 					var marker = $('<div/>') | ||||
| 						.addClass('current-marker ui-current-image-indicator') | ||||
| 						.css({ | ||||
| 							opacity: '0', | ||||
| 							// NOTE: these are not used for positioning
 | ||||
| 							// 		but are needed for correct absolute
 | ||||
| 							// 		placement...
 | ||||
| 							top: '0px', | ||||
| 							left: '0px', | ||||
| 						}) | ||||
| 						.appendTo(ribbon) | ||||
| 						.animate({ | ||||
| 							'opacity': 1 | ||||
| 						}, fadein) | ||||
| 					this.ribbons.dom.setOffset(marker, 0, 0) | ||||
| 
 | ||||
| 				// add marker to current ribbon...
 | ||||
| 				} else { | ||||
| 					marker.appendTo(ribbon) | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			// NOTE: we will update only the attrs that need to be updated...
 | ||||
| 			var css = {} | ||||
| 
 | ||||
| 			var w = cur.outerWidth(true) | ||||
| 			var h = cur.outerHeight(true) | ||||
| 
 | ||||
| 			// keep size same as the image...
 | ||||
| 			if(marker.outerWidth() != w || marker.outerHeight() != h){ | ||||
| 				css.width = w | ||||
| 				css.height = h | ||||
| 			} | ||||
| 
 | ||||
| 			// update border...
 | ||||
| 			if(update_border !== false){ | ||||
| 				var border = Math.max(min_border, border / scale) | ||||
| 
 | ||||
| 				// set border right away...
 | ||||
| 				if(update_border == 'before'){ | ||||
| 					css.borderWidth = border | ||||
| 
 | ||||
| 				// set border with a delay...
 | ||||
| 				// NOTE: this is to prevent the ugly border resize before
 | ||||
| 				// 		the scale on scale down animation starts...
 | ||||
| 				} else { | ||||
| 					setTimeout(function(){  | ||||
| 						marker.css({ borderWidth: border })  | ||||
| 					}, border_timeout) | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			//css.left = cur[0].offsetLeft
 | ||||
| 			this.ribbons.dom.setOffset(marker, cur[0].offsetLeft, 0) | ||||
| 
 | ||||
| 			marker.css(css) | ||||
| 		}], | ||||
| }) | ||||
| 
 | ||||
| var CurrentImageIndicator =  | ||||
| module.CurrentImageIndicator = core.ImageGridFeatures.Feature({ | ||||
| 	title: '', | ||||
| 	doc: '', | ||||
| 
 | ||||
| 	tag: 'ui-current-image-indicator', | ||||
| 	depends: ['ui'], | ||||
| 
 | ||||
| 	actions: CurrentImageIndicatorActions, | ||||
| 
 | ||||
| 	handlers: [ | ||||
| 		// move marker to current image...
 | ||||
| 		['focusImage.post', | ||||
| 			function(){ this.updateCurrentImageIndicator() }], | ||||
| 		// prevent animations when focusing ribbons...
 | ||||
| 		['focusRibbon.pre', | ||||
| 			function(){ | ||||
| 				var m = this.ribbons.viewer.find('.current-marker') | ||||
| 				this.ribbons.preventTransitions(m) | ||||
| 				return function(){ | ||||
| 					this.ribbons.restoreTransitions(m) | ||||
| 				} | ||||
| 			}], | ||||
| 		// this is here to compensate for position change on ribbon 
 | ||||
| 		// resize...
 | ||||
| 		// NOTE: hide/show of indicator on resize appears to have solved
 | ||||
| 		// 		the jumpy animation issue.
 | ||||
| 		// 		this might cause some blinking on slow resizes (visible 
 | ||||
| 		// 		only on next/prev screen)... 
 | ||||
| 		// 		...still not sure why .preventTransitions(m) did not
 | ||||
| 		// 		do the job.
 | ||||
| 		['resizeRibbon.pre', | ||||
| 			function(target, s){ | ||||
| 				var m = this.ribbons.viewer.find('.current-marker') | ||||
| 				// only update if marker exists and we are in current ribbon...
 | ||||
| 				if(m.length != 0 && this.currentRibbon == this.data.getRibbon(target)){ | ||||
| 					//this.ribbons.preventTransitions(m)
 | ||||
| 					m.hide() | ||||
| 
 | ||||
| 					return function(){ | ||||
| 						this.updateCurrentImageIndicator(target, false) | ||||
| 						//this.ribbons.restoreTransitions(m, true)
 | ||||
| 						m | ||||
| 							.show() | ||||
| 							// NOTE: keeping display in inline style will
 | ||||
| 							// 		prevent the element from being hidden
 | ||||
| 							// 		by css...
 | ||||
| 							.css({display: ''}) | ||||
| 					} | ||||
| 				} | ||||
| 			}], | ||||
| 		// Change border size in the appropriate spot in the animation:
 | ||||
| 		// 	- before animation when scaling up
 | ||||
| 		// 	- after when scaling down
 | ||||
| 		// This is done to make the visuals consistent...
 | ||||
| 		['fitImage.pre fitRibbon.pre', | ||||
| 			function(w1){  | ||||
| 				var w0 = this.screenwidth | ||||
| 				w1 = w1 || 1 | ||||
| 				return function(){ | ||||
| 					this.updateCurrentImageIndicator(null, w0 > w1 ? 'before' : 'after')  | ||||
| 				} | ||||
| 			}], | ||||
| 		['shiftImageLeft.pre shiftImageRight.pre', | ||||
| 			function(){ | ||||
| 				this.ribbons.viewer.find('.current-marker').hide() | ||||
| 				if(this._current_image_indicator_timeout != null){ | ||||
| 					clearTimeout(this._current_image_indicator_timeout) | ||||
| 					delete this._current_image_indicator_timeout | ||||
| 				} | ||||
| 				return function(){ | ||||
| 					var ribbons = this.ribbons | ||||
| 					var fadein = this.config['current-image-indicator-fadein'] | ||||
| 					this._current_image_indicator_timeout = setTimeout(function(){  | ||||
| 						ribbons.viewer.find('.current-marker').fadeIn(fadein) | ||||
| 					}, this.config['current-image-shift-timeout']) | ||||
| 				} | ||||
| 			}], | ||||
| 	], | ||||
| }) | ||||
| 
 | ||||
| 
 | ||||
| var CurrentImageIndicatorHideOnFastScreenNav =  | ||||
| module.CurrentImageIndicatorHideOnFastScreenNav = core.ImageGridFeatures.Feature({ | ||||
| 	title: '', | ||||
| 	doc: '', | ||||
| 
 | ||||
| 	tag: 'ui-current-image-indicator-hide-on-fast-screen-nav', | ||||
| 
 | ||||
| 
 | ||||
| 	depends: [ | ||||
| 		'ui', | ||||
| 		'ui-current-image-indicator' | ||||
| 	], | ||||
| 	exclusive: ['ui-current-image-indicator-hide'], | ||||
| 
 | ||||
| 
 | ||||
| 	handlers: [ | ||||
| 		// hide indicator on screen next/prev...
 | ||||
| 		//
 | ||||
| 		// XXX experimental -- not sure if we need this...
 | ||||
| 		// XXX need to think about the trigger mechanics here and make 
 | ||||
| 		// 		them more natural...
 | ||||
| 		['prevScreen.pre nextScreen.pre', | ||||
| 			function(){  | ||||
| 				var m = this.ribbons.viewer.find('.current-marker') | ||||
| 				var t = this.config['current-image-indicator-hide-timeout'] | ||||
| 
 | ||||
| 				var cur = this.current | ||||
| 
 | ||||
| 				return function(){ | ||||
| 					var that = this | ||||
| 
 | ||||
| 					// delay fadeout...
 | ||||
| 					if(cur != this.current  | ||||
| 							&& m.css('opacity') == 1 | ||||
| 							&& this.__current_indicator_t0 == null){ | ||||
| 						this.__current_indicator_t0 = setTimeout(function(){ | ||||
| 							delete that.__current_indicator_t0 | ||||
| 
 | ||||
| 							m.css({ opacity: 0 }) | ||||
| 						}, t) | ||||
| 					} | ||||
| 
 | ||||
| 					// cancel/delay previous fadein...
 | ||||
| 					if(this.__current_indicator_t1 != null){ | ||||
| 						clearTimeout(this.__current_indicator_t1) | ||||
| 					} | ||||
| 
 | ||||
| 					// cancel fadeout and do fadein...
 | ||||
| 					this.__current_indicator_t1 = setTimeout(function(){ | ||||
| 						delete that.__current_indicator_t1 | ||||
| 
 | ||||
| 						// cancel fadeout...
 | ||||
| 						if(that.__current_indicator_t0 != null){ | ||||
| 							clearTimeout(that.__current_indicator_t0) | ||||
| 							delete that.__current_indicator_t0 | ||||
| 						}  | ||||
| 
 | ||||
| 						// show...
 | ||||
| 						m.animate({ opacity: '1' }) | ||||
| 					}, t-50) | ||||
| 				} | ||||
| 			}], | ||||
| 	], | ||||
| }) | ||||
| 
 | ||||
| var CurrentImageIndicatorHideOnScreenNav =  | ||||
| module.CurrentImageIndicatorHideOnScreenNav = core.ImageGridFeatures.Feature({ | ||||
| 	title: '', | ||||
| 	doc: '', | ||||
| 
 | ||||
| 	tag: 'ui-current-image-indicator-hide-on-screen-nav', | ||||
| 
 | ||||
| 
 | ||||
| 	depends: [ | ||||
| 		'ui', | ||||
| 		'ui-current-image-indicator' | ||||
| 	], | ||||
| 	exclusive: ['ui-current-image-indicator-hide'], | ||||
| 
 | ||||
| 
 | ||||
| 	handlers: [ | ||||
| 		// 	this does the following:
 | ||||
| 		// 		- hide on screen jump
 | ||||
| 		// 		- show on any other action
 | ||||
| 		//
 | ||||
| 		// NOTE: we use .pre events here to see if we have moved...
 | ||||
| 		['prevScreen.post nextScreen.post', | ||||
| 			function(){  | ||||
| 				var m = this.ribbons.viewer.find('.current-marker') | ||||
| 
 | ||||
| 				m.css({ opacity: 0 }) | ||||
| 			}], | ||||
| 		['focusImage.post', | ||||
| 			function(){  | ||||
| 				var m = this.ribbons.viewer.find('.current-marker') | ||||
| 
 | ||||
| 				m.css({ opacity: '' }) | ||||
| 			}], | ||||
| 	], | ||||
| }) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| //---------------------------------------------------------------------
 | ||||
| // XXX this should:
 | ||||
| // 	- float to the left of a ribbon if image #1 is fully visible (working)
 | ||||
| // 	- float at left of viewer if image #1 is off screen...
 | ||||
| // 	- float on the same level as the base ribbon...
 | ||||
| 
 | ||||
| // XXX make this an action...
 | ||||
| var updateBaseRibbonIndicator = function(img){ | ||||
| 	var scale = this.ribbons.scale() | ||||
| 	var base = this.ribbons.getRibbon('base') | ||||
| 	img = this.ribbons.getImage(img) | ||||
| 	var m = base.find('.base-ribbon-marker') | ||||
| 
 | ||||
| 	if(base.length == 0){ | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if(m.length == 0){ | ||||
| 		m = this.ribbons.viewer.find('.base-ribbon-marker') | ||||
| 
 | ||||
| 		// make the indicator...
 | ||||
| 		if(m.length == 0){ | ||||
| 			m = $('<div>') | ||||
| 				.addClass('base-ribbon-marker') | ||||
| 				.text('base ribbon') | ||||
| 		} | ||||
| 
 | ||||
| 		m.prependTo(base) | ||||
| 	} | ||||
| 
 | ||||
| 	// XXX this is wrong -- need to calculate the offset after the move and not now...
 | ||||
| 	if(base.offset().left < 0){ | ||||
| 		m.css('left', (img.position().left + img.width()/2 - this.ribbons.viewer.width()/2) / scale) | ||||
| 
 | ||||
| 	} else { | ||||
| 		m.css('left', '') | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| var BaseRibbonIndicator =  | ||||
| module.BaseRibbonIndicator = core.ImageGridFeatures.Feature({ | ||||
| 	title: '', | ||||
| 	doc: '', | ||||
| 
 | ||||
| 	tag: 'ui-base-ribbon-indicator', | ||||
| 	depends: ['ui'], | ||||
| 
 | ||||
| 	handlers: [ | ||||
| 		// move marker to current image...
 | ||||
| 		['focusImage.pre', | ||||
| 			function(target){  | ||||
| 				updateBaseRibbonIndicator.call(this, target) | ||||
| 			}], | ||||
| 		// prevent animations when focusing ribbons...
 | ||||
| 		['focusRibbon.pre setBaseRibbon', | ||||
| 			function(){ | ||||
| 				updateBaseRibbonIndicator.call(this) | ||||
| 
 | ||||
| 				/* | ||||
| 				this.ribbons.preventTransitions(m) | ||||
| 				return function(){ | ||||
| 					this.ribbons.restoreTransitions(m) | ||||
| 				} | ||||
| 				*/ | ||||
| 			}], | ||||
| 	] | ||||
| }) | ||||
| 
 | ||||
| 
 | ||||
| var PassiveBaseRibbonIndicator =  | ||||
| module.PassiveBaseRibbonIndicator = core.ImageGridFeatures.Feature({ | ||||
| 	title: '', | ||||
| 	doc: '', | ||||
| 
 | ||||
| 	tag: 'ui-passive-base-ribbon-indicator', | ||||
| 	depends: ['ui'], | ||||
| 
 | ||||
| 	config: { | ||||
| 		'ui-show-passive-base-ribbon-indicator': true, | ||||
| 	}, | ||||
| 
 | ||||
| 	actions: actions.Actions({ | ||||
| 		togglePassiveBaseRibbonIndicator: ['Interface/Toggle passive base ribbon indicator', | ||||
| 			toggler.CSSClassToggler( | ||||
| 				function(){ return this.ribbons.viewer },  | ||||
| 				'show-passive-base-ribbon-indicator', | ||||
| 				function(state){  | ||||
| 					this.config['ui-show-passive-base-ribbon-indicator'] = state == 'on' }) ], | ||||
| 	}), | ||||
| 
 | ||||
| 	handlers: [ | ||||
| 		['start', | ||||
| 			function(){ | ||||
| 				this.togglePassiveBaseRibbonIndicator( | ||||
| 					this.config['ui-show-passive-base-ribbon-indicator'] ? | ||||
| 						'on' : 'off') | ||||
| 			}] | ||||
| 	], | ||||
| }) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| //---------------------------------------------------------------------
 | ||||
| 
 | ||||
| // XXX make this work in browser
 | ||||
| var UIScaleActions = actions.Actions({ | ||||
| 	config: { | ||||
| 		// XXX
 | ||||
| 		'ui-scale-modes': { | ||||
| 			desktop: 0, | ||||
| 			touch: 3, | ||||
| 		}, | ||||
| 	}, | ||||
| 
 | ||||
| 	// XXX need to account for scale in PartialRibbons
 | ||||
| 	// XXX should this be browser API???
 | ||||
| 	// XXX this does not re-scale the ribbons correctly in nw0.13
 | ||||
| 	toggleInterfaceScale: ['Interface/Toggle interface modes', | ||||
| 		core.makeConfigToggler('ui-scale-mode',  | ||||
| 			function(){ return Object.keys(this.config['ui-scale-modes']) }, | ||||
| 			function(state){  | ||||
| 				var gui = requirejs('nw.gui') | ||||
| 				var win = gui.Window.get() | ||||
| 
 | ||||
| 
 | ||||
| 				this.ribbons.preventTransitions() | ||||
| 
 | ||||
| 				var w = this.screenwidth | ||||
| 
 | ||||
| 				// NOTE: scale = Math.pow(1.2, zoomLevel)
 | ||||
| 				// XXX in nw0.13 this appears to be async...
 | ||||
| 				win.zoomLevel = this.config['ui-scale-modes'][state] || 0 | ||||
| 
 | ||||
| 				this.screenwidth = w | ||||
| 				this.centerViewer() | ||||
| 
 | ||||
| 				this.ribbons.restoreTransitions() | ||||
| 			})], | ||||
| }) | ||||
| 
 | ||||
| 
 | ||||
| // XXX enable scale loading...
 | ||||
| // 		...need to make this play nice with restoring scale on startup...
 | ||||
| var UIScale =  | ||||
| module.UIScale = core.ImageGridFeatures.Feature({ | ||||
| 	title: '', | ||||
| 	doc: '', | ||||
| 
 | ||||
| 	tag: 'ui-scale', | ||||
| 	depends: [ | ||||
| 		'ui', | ||||
| 	], | ||||
| 
 | ||||
| 	actions: UIScaleActions, | ||||
| 
 | ||||
| 	// XXX test if in:
 | ||||
| 	// 	- chrome app
 | ||||
| 	// 	- nw
 | ||||
| 	// 	- mobile
 | ||||
| 	isApplicable: function(){ return this.runtime == 'nw' }, | ||||
| 
 | ||||
| 	// XXX show main window...
 | ||||
| 	handlers: [ | ||||
| 		['start', | ||||
| 			function(){  | ||||
| 				// XXX this messes up ribbon scale...
 | ||||
| 				// 		...too close/fast?
 | ||||
| 				//this.toggleInterfaceScale('!')
 | ||||
| 			}], | ||||
| 	], | ||||
| }) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /********************************************************************** | ||||
| * vim:set ts=4 sw=4 :                                                */ | ||||
| return module }) | ||||
| @ -292,6 +292,15 @@ module.ImageBookmarks = core.ImageGridFeatures.Feature({ | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| //---------------------------------------------------------------------
 | ||||
| 
 | ||||
| core.ImageGridFeatures.Feature('marks', [ | ||||
| 	'image-marks', | ||||
| 	'image-bookmarks', | ||||
| ]) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /********************************************************************** | ||||
| * vim:set ts=4 sw=4 :                                                */ | ||||
| return module }) | ||||
|  | ||||
							
								
								
									
										299
									
								
								ui (gen4)/features/ui-single-image.js
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										299
									
								
								ui (gen4)/features/ui-single-image.js
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,299 @@ | ||||
| /********************************************************************** | ||||
| *  | ||||
| * | ||||
| * | ||||
| **********************************************************************/ | ||||
| 
 | ||||
| define(function(require){ var module = {} | ||||
| 
 | ||||
| //var DEBUG = DEBUG != null ? DEBUG : true
 | ||||
| 
 | ||||
| var actions = require('lib/actions') | ||||
| var features = require('lib/features') | ||||
| var toggler = require('lib/toggler') | ||||
| 
 | ||||
| var core = require('features/core') | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /*********************************************************************/ | ||||
| // helper...
 | ||||
| // XXX should this be an action???
 | ||||
| function updateImageProportions(){ | ||||
| 	// XXX
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| //---------------------------------------------------------------------
 | ||||
| 
 | ||||
| var SingleImageActions = actions.Actions({ | ||||
| 	config: { | ||||
| 		// NOTE: these will get overwritten if/when the user changes the scale...
 | ||||
| 		'single-image-scale': null, | ||||
| 		'ribbon-scale': null, | ||||
| 	}, | ||||
| 
 | ||||
| 	toggleSingleImage: ['Interface/Toggle single image view',  | ||||
| 		toggler.CSSClassToggler( | ||||
| 			function(){ return this.ribbons.viewer },  | ||||
| 			'single-image-mode') ], | ||||
| }) | ||||
| 
 | ||||
| 
 | ||||
| // XXX an ideal case would be:
 | ||||
| //
 | ||||
| // A)
 | ||||
| //       viewer
 | ||||
| //      +---------------+
 | ||||
| //      |     image     |   - small image
 | ||||
| //      |     +---+     |   - square image block
 | ||||
| //      |     |   |     |   - smaller than this the block is always square
 | ||||
| //      |     +---+     |   - we just change scale
 | ||||
| //      |               |
 | ||||
| //      +---------------+
 | ||||
| //
 | ||||
| //
 | ||||
| // B)
 | ||||
| //       viewer
 | ||||
| //      +---------------+
 | ||||
| //      | +-----------+ |   - bigger image
 | ||||
| //      | | image     | |   - block close to viewer proportion
 | ||||
| //      | |    <-->   | |   - image block growing parallel to viewer
 | ||||
| //      | |           | |     longer side
 | ||||
| //      | +-----------+ |   - this stage is not affected specific by image
 | ||||
| //      +---------------+     proportions and can be done in bulk
 | ||||
| //
 | ||||
| //
 | ||||
| // C)
 | ||||
| //       viewer
 | ||||
| //      +---------------+
 | ||||
| //      | image         |   - image block same size as viewer
 | ||||
| //      |               |   - need to account for chrome
 | ||||
| //      |               |
 | ||||
| //      |               |
 | ||||
| //      |               |
 | ||||
| //      +---------------+
 | ||||
| //
 | ||||
| //
 | ||||
| // D)
 | ||||
| //       image
 | ||||
| //      + - - - - - - - +
 | ||||
| //      .               .
 | ||||
| //      +---------------+
 | ||||
| //      | viewer        |   - image bigger than viewer in one dimension
 | ||||
| //      |       ^       |   - block grows to fit image proportions
 | ||||
| //      |       |       |   - need to account for individual image 
 | ||||
| //      |       v       |     proportions
 | ||||
| //      |               |   - drag enabled
 | ||||
| //      +---------------+
 | ||||
| //      .               .
 | ||||
| //      + - - - - - - - +
 | ||||
| //
 | ||||
| //
 | ||||
| // E) 
 | ||||
| //     image
 | ||||
| //    + - - - - - - - - - +
 | ||||
| //    .                   .
 | ||||
| //    . +---------------+ .
 | ||||
| //    . | viewer        | . - image bigger than viewer 
 | ||||
| //    . |               | . - image block same proportion as image
 | ||||
| //    . |               | . - we just change scale
 | ||||
| //    . |               | . - drag enabled
 | ||||
| //    . |               | .
 | ||||
| //    . +---------------+ .
 | ||||
| //    .                   .
 | ||||
| //    + - - - - - - - - - +
 | ||||
| //
 | ||||
| //
 | ||||
| var SingleImageView = | ||||
| module.SingleImageView = core.ImageGridFeatures.Feature({ | ||||
| 	title: '', | ||||
| 	doc: '', | ||||
| 
 | ||||
| 	tag: 'ui-single-image-view', | ||||
| 	depends: [ | ||||
| 		'ui' | ||||
| 	], | ||||
| 
 | ||||
| 	actions: SingleImageActions, | ||||
| 
 | ||||
| 	handlers:[ | ||||
| 		['fitImage.post', | ||||
| 			function(){  | ||||
| 
 | ||||
| 				// singe image mode -- set image proportions...
 | ||||
| 				if(this.toggleSingleImage('?') == 'on'){ | ||||
| 					updateImageProportions.call(this) | ||||
| 
 | ||||
| 					this.config['single-image-scale'] = this.screenwidth | ||||
| 
 | ||||
| 				} else { | ||||
| 					this.config['ribbon-scale'] = this.screenwidth | ||||
| 				} | ||||
| 			}], | ||||
| 		// NOTE: this is not part of the actual action above because we 
 | ||||
| 		// 		need to see if the state has changed and doing this with 
 | ||||
| 		// 		two separate pre/post callbacks (toggler callbacks) is 
 | ||||
| 		// 		harder than with two nested callbacks (action callbacks)
 | ||||
| 		// XXX this uses .screenwidth for scale, is this the right way to go?
 | ||||
| 		['toggleSingleImage.pre',  | ||||
| 			function(){  | ||||
| 				var pre_state = this.toggleSingleImage('?') | ||||
| 
 | ||||
| 				return function(){ | ||||
| 					var state = this.toggleSingleImage('?') | ||||
| 
 | ||||
| 					// singe image mode -- set image proportions...
 | ||||
| 					if(state == 'on'){ | ||||
| 						updateImageProportions.call(this) | ||||
| 
 | ||||
| 						// update scale...
 | ||||
| 						if(state != pre_state){ | ||||
| 							var w = this.screenwidth | ||||
| 							this.config['ribbon-scale'] = w | ||||
| 							this.screenwidth = this.config['single-image-scale'] || w | ||||
| 						} | ||||
| 
 | ||||
| 					// ribbon mode -- restore original image size...
 | ||||
| 					} else { | ||||
| 						this.ribbons.viewer.find('.image:not(.clone)').css({ | ||||
| 							width: '', | ||||
| 							height: '' | ||||
| 						}) | ||||
| 
 | ||||
| 						// update scale...
 | ||||
| 						if(state != pre_state){ | ||||
| 							var w = this.screenwidth | ||||
| 							this.config['single-image-scale'] = w | ||||
| 							this.screenwidth = this.config['ribbon-scale'] || w | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 			}], | ||||
| 	], | ||||
| }) | ||||
| 
 | ||||
| 
 | ||||
| var SingleImageViewLocalStorage = | ||||
| module.SingleImageViewLocalStorage = core.ImageGridFeatures.Feature({ | ||||
| 	title: '', | ||||
| 	doc: '', | ||||
| 
 | ||||
| 	tag: 'ui-single-image-view-local-storage', | ||||
| 	depends: [ | ||||
| 		'ui-single-image-view', | ||||
| 		'config-local-storage', | ||||
| 	], | ||||
| 
 | ||||
| 	handlers:[ | ||||
| 		// set scale...
 | ||||
| 		['load', | ||||
| 			function(){ | ||||
| 				// prevent this from doing anything while no viewer...
 | ||||
| 				if(!this.ribbons || !this.ribbons.viewer || this.ribbons.viewer.length == 0){ | ||||
| 					return | ||||
| 				} | ||||
| 
 | ||||
| 				if(this.toggleSingleImage('?') == 'on'){ | ||||
| 					this.screenwidth = this.config['single-image-scale'] || this.screenwidth | ||||
| 
 | ||||
| 				} else { | ||||
| 					this.screenwidth = this.config['ribbon-scale'] || this.screenwidth | ||||
| 				} | ||||
| 			}], | ||||
| 	], | ||||
| }) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| //---------------------------------------------------------------------
 | ||||
| 
 | ||||
| // This will store/restore autohide state for single-image and ribbon 
 | ||||
| // views...
 | ||||
| //
 | ||||
| // NOTE: chrome 49 + devtools open appears to prevent the cursor from being hidden...
 | ||||
| //
 | ||||
| // XXX hiding cursor on navigation for some reason does not work...
 | ||||
| var SingleImageAutoHideCursor =  | ||||
| module.SingleImageAutoHideCursor = core.ImageGridFeatures.Feature({ | ||||
| 	title: '', | ||||
| 	doc: '', | ||||
| 
 | ||||
| 	tag: 'ui-single-image-view-autohide-cursor', | ||||
| 	depends: [ | ||||
| 		'ui-autohide-cursor', | ||||
| 		'ui-single-image-view', | ||||
| 	], | ||||
| 
 | ||||
| 	config: { | ||||
| 		'cursor-autohide-single-image-view': 'on', | ||||
| 		'cursor-autohide-ribbon-view': 'off', | ||||
| 
 | ||||
| 		//'cursor-autohide-on-navigate': true, 
 | ||||
| 	}, | ||||
| 
 | ||||
| 	handlers: [ | ||||
| 		// setup...
 | ||||
| 		['load', | ||||
| 			function(){ | ||||
| 				var mode = this.toggleSingleImage('?') == 'on' ?  | ||||
| 					'cursor-autohide-single-image-view' | ||||
| 					: 'cursor-autohide-ribbon-view' | ||||
| 
 | ||||
| 				this.toggleAutoHideCursor(this.config[mode] || 'off') | ||||
| 			}], | ||||
| 		// store state for each mode...
 | ||||
| 		['toggleAutoHideCursor', | ||||
| 			function(){ | ||||
| 				var mode = this.toggleSingleImage('?') == 'on' ?  | ||||
| 					'cursor-autohide-single-image-view' | ||||
| 					: 'cursor-autohide-ribbon-view' | ||||
| 
 | ||||
| 				this.config[mode] = this.toggleAutoHideCursor('?') | ||||
| 			}], | ||||
| 		// restore state per mode...
 | ||||
| 		['toggleSingleImage',  | ||||
| 			function(){ | ||||
| 				if(this.toggleSingleImage('?') == 'on'){ | ||||
| 					this.toggleAutoHideCursor(this.config['cursor-autohide-single-image-view']) | ||||
| 
 | ||||
| 				} else { | ||||
| 					this.toggleAutoHideCursor(this.config['cursor-autohide-ribbon-view']) | ||||
| 				} | ||||
| 			}], | ||||
| 		/* XXX for some reason this does not work... | ||||
| 		// autohide on navigation...
 | ||||
| 		['focusImage',  | ||||
| 			function(){ | ||||
| 				//if(this.config['cursor-autohide-on-navigate'] 
 | ||||
| 				//		&& this.toggleAutoHideCursor('?') == 'on'){
 | ||||
| 				//	this.toggleAutoHideCursor('on')
 | ||||
| 				//}
 | ||||
| 				if(this.config['cursor-autohide-on-navigate']  | ||||
| 						&& this.toggleAutoHideCursor('?') == 'on' | ||||
| 						&& this.ribbons.viewer.prop('cursor-autohide')){ | ||||
| 					this.ribbons.viewer | ||||
| 						.addClass('cursor-hidden') | ||||
| 				} | ||||
| 			}], | ||||
| 		*/ | ||||
| 	] | ||||
| }) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| //---------------------------------------------------------------------
 | ||||
| 
 | ||||
| core.ImageGridFeatures.Feature('ui-single-image', [ | ||||
| 	'ui-single-image-view', | ||||
| 	'ui-single-image-view-local-storage', | ||||
| 
 | ||||
| 	'ui-single-image-view-autohide-cursor', | ||||
| ]) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /********************************************************************** | ||||
| * vim:set ts=4 sw=4 :                                                */ | ||||
| return module }) | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user