mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-10-30 10:50:08 +00:00 
			
		
		
		
	reworked ribbon traverse and alignment + minor fix...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									c1c369d3ce
								
							
						
					
					
						commit
						4e31790f95
					
				| @ -297,10 +297,10 @@ var RibbonsPrototype = { | ||||
| 	// XXX try and make image size the product of vmin and scale...
 | ||||
| 	// XXX this might break when no images are loaded and proportions 
 | ||||
| 	// 		are not square...
 | ||||
| 	getVisibleImageSize: function(dim, scale){ | ||||
| 	getVisibleImageSize: function(dim, scale, img){ | ||||
| 		scale = scale || this.getScale() | ||||
| 		dim = dim == null ? 'width' : dim | ||||
| 		var img = this.viewer.find(IMAGE) | ||||
| 		img = img || this.viewer.find(IMAGE) | ||||
| 		var tmp | ||||
| 
 | ||||
| 		// if no images are loaded create one temporarily....
 | ||||
| @ -350,6 +350,117 @@ var RibbonsPrototype = { | ||||
| 		return H/h | ||||
| 	}, | ||||
| 
 | ||||
| 	// Get an image at a relative to viewer position...
 | ||||
| 	//
 | ||||
| 	//	Get central image in current ribbon:
 | ||||
| 	//	.getImageByPosition()
 | ||||
| 	//		-> image
 | ||||
| 	//
 | ||||
| 	//	Get central image closest to current:
 | ||||
| 	//	.getImageByPosition('current'[, <ribbon>])
 | ||||
| 	//		-> image
 | ||||
| 	//
 | ||||
| 	//	Get central image closest to html element:
 | ||||
| 	//	.getImageByPosition(<elem>[, <ribbon>])
 | ||||
| 	//		-> image
 | ||||
| 	//
 | ||||
| 	//	Get image in a specific ribbon:
 | ||||
| 	//	.getImageByPosition('left'[, <ribbon>])
 | ||||
| 	//	.getImageByPosition('center'[, <ribbon>])
 | ||||
| 	//	.getImageByPosition('right'[, <ribbon>])
 | ||||
| 	//		-> image
 | ||||
| 	//
 | ||||
| 	// This can return a pair of images when position is either 'center',
 | ||||
| 	// 'current' or a jquery object, this can happen when the two 
 | ||||
| 	// candidates are closer to the target than delta.
 | ||||
| 	//
 | ||||
| 	//
 | ||||
| 	// NOTE: if no ribbon is given, current ribbon is assumed.
 | ||||
| 	// NOTE: <ribbon> is the same as expected by .getRibbon(..)
 | ||||
| 	// NOTE: position can also be an image...
 | ||||
| 	// NOTE: delta is used ONLY if position is either 'center', 'current'
 | ||||
| 	// 		or an jQuery object...
 | ||||
| 	getImageByPosition: function(position, ribbon, delta){ | ||||
| 		position = position || 'center'	 | ||||
| 		ribbon = this.getRibbon(ribbon)  | ||||
| 
 | ||||
| 		var viewer = this.viewer | ||||
| 
 | ||||
| 		var W = viewer.outerWidth() | ||||
| 		var L = viewer.offset().left | ||||
| 
 | ||||
| 		var target = position == 'current' ? this.getImage() | ||||
| 			: position == 'center' ? viewer | ||||
| 			: position == 'left' ? L | ||||
| 			: position == 'right' ? L + W | ||||
| 			: position | ||||
| 
 | ||||
| 		// unknown keyword...
 | ||||
| 		if(target == null){ | ||||
| 			return $() | ||||
| 
 | ||||
| 		// center of an element...
 | ||||
| 		} else if(typeof(target) != typeof(123)){ | ||||
| 			target = $(target) | ||||
| 			var w = target.hasClass('image') ?  | ||||
| 				this.getVisibleImageSize('width', null, target) :  | ||||
| 				target.outerWidth() | ||||
| 			// NOTE: we will need delta only in this branch, i.e. when
 | ||||
| 			// 		position is either 'current', 'center' or a jQuery 
 | ||||
| 			// 		object...
 | ||||
| 			delta = delta || w / 10 | ||||
| 			target = target.offset().left + w/2 | ||||
| 		} | ||||
| 
 | ||||
| 		var that = this | ||||
| 		var res = ribbon.find(IMAGE) | ||||
| 			.toArray() | ||||
| 			.map(function(img){ | ||||
| 				img = $(img) | ||||
| 				var l = img.offset().left | ||||
| 				var w = that.getVisibleImageSize('width', null, img) | ||||
| 
 | ||||
| 				// skip images not fully shown in viewer...
 | ||||
| 				if(L > l || l+w > L+W){ | ||||
| 					return | ||||
| 				} | ||||
| 
 | ||||
| 				// distance between centers...
 | ||||
| 				if(position == 'center' || position == 'current'){ | ||||
| 					return [target - (l + w/2), img] | ||||
| 
 | ||||
| 				// distance between left edges...
 | ||||
| 				} else if(position == 'left'){ | ||||
| 					return [target - l, img] | ||||
| 
 | ||||
| 				// distance between right edges...
 | ||||
| 				} else { | ||||
| 					return [target - (l + w), img] | ||||
| 				} | ||||
| 			}) | ||||
| 			// drop images outside the viewer...
 | ||||
| 			.filter(function(e){ return e != null }) | ||||
| 			// sort images by distance...
 | ||||
| 			.sort(function(a, b){ return Math.abs(a[0]) - Math.abs(b[0]) }) | ||||
| 
 | ||||
| 		var a = res[0][0] | ||||
| 		var b = res[1] ? res[1][0] : null | ||||
| 
 | ||||
| 		// we have two images that are about the same distance from 
 | ||||
| 		// target...
 | ||||
| 		// NOTE: this is a one-dimentional filter so the can not be more
 | ||||
| 		// 		than two hits...
 | ||||
| 		// NOTE: delta is used ONLY if position is either 'center', 
 | ||||
| 		// 		'current' or an jQuery object...
 | ||||
| 		if(b && (a >= 0) != (b >= 0) && Math.abs(a + b) < delta){ | ||||
| 			return $([res[0][1][0], res[1][1][0]]) | ||||
| 
 | ||||
| 		// a single hit...
 | ||||
| 		} else { | ||||
| 			return res[0][1] | ||||
| 		} | ||||
| 	}, | ||||
| 
 | ||||
| 	// Get ribbon set scale...
 | ||||
| 	//
 | ||||
| 	getScale: function(){ | ||||
|  | ||||
| @ -126,7 +126,7 @@ if(typeof(glob) != 'undefined'){ | ||||
| 
 | ||||
| 
 | ||||
| 	window.loadMBFWR1 = function(logger){ | ||||
| 		a.loadPath('L:/mnt/hdd15 (photo)/NTFS2/media/img/my/work/20151022 - MBFWR (1),/preview (RAW)/', logger) | ||||
| 		a.loadIndex('L:/mnt/hdd15 (photo)/NTFS2/media/img/my/work/20151022 - MBFWR (1),/preview (RAW)/', logger) | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -79,13 +79,6 @@ module.GLOBAL_KEYBOARD = { | ||||
| 
 | ||||
| 		F4: { | ||||
| 			alt: 'close', | ||||
| 			/* | ||||
| 			alt: doc('Close viewer',  | ||||
| 				function(){  | ||||
| 					window.close()  | ||||
| 					return false | ||||
| 				}), | ||||
| 			*/ | ||||
| 		}, | ||||
| 		Q: { | ||||
| 			meta: 'close', | ||||
|  | ||||
| @ -165,6 +165,16 @@ actions.Actions({ | ||||
| 	config: { | ||||
| 		// see .direction for details...
 | ||||
| 		'steps-to-change-direction': 3, | ||||
| 
 | ||||
| 		// determines the image selection mode when focusing 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-mode': 'visual', | ||||
| 	}, | ||||
| 
 | ||||
| 	// basic state...
 | ||||
| @ -283,8 +293,16 @@ actions.Actions({ | ||||
| 		function(img, list){ | ||||
| 			this.data.focusImage(img, list) | ||||
| 		}], | ||||
| 	// Focuses a ribbon by selecting an image in it...
 | ||||
| 	//
 | ||||
| 	// modes supported:
 | ||||
| 	// 	'order'			- focus closest image to current in order
 | ||||
| 	// 	'first'/'last'	- focus first/last image in ribbon
 | ||||
| 	// 	'visual'		- focus visually closest to current image
 | ||||
| 	//
 | ||||
| 	// NOTE: default mode is set in .config.ribbon-focus-mode
 | ||||
| 	focusRibbon: ['Navigate/Focus Ribbon', | ||||
| 		function(target){ | ||||
| 		function(target, mode){ | ||||
| 			var data = this.data | ||||
| 			var r = data.getRibbon(target) | ||||
| 			if(r == null){ | ||||
| @ -293,16 +311,37 @@ actions.Actions({ | ||||
| 			var c = data.getRibbonOrder() | ||||
| 			var i = data.getRibbonOrder(r) | ||||
| 
 | ||||
| 			mode = mode || this.config['ribbon-focus-mode'] || 'order' | ||||
| 
 | ||||
| 			// NOTE: we are not changing the direction here based on 
 | ||||
| 			// 		this.direction as swap will confuse the user...
 | ||||
| 			var direction = c < i ? 'before' : 'after' | ||||
| 
 | ||||
| 			// closest image in order...
 | ||||
| 			if(mode == 'order'){ | ||||
| 				var t = data.getImage(r, direction) | ||||
| 
 | ||||
| 				// if there are no images in the requied direction, try the 
 | ||||
| 				// other way...
 | ||||
| 				t = t == null ? data.getImage(r, direction == 'before' ? 'after' : 'before') : t | ||||
| 
 | ||||
| 			// first/last image...
 | ||||
| 			} else if(mode == 'first' || mode == 'last'){ | ||||
| 				var t = data.getImage(mode, r) | ||||
| 
 | ||||
| 			// visually closest image...
 | ||||
| 			//} else if(mode == 'visual'){
 | ||||
| 			} else { | ||||
| 				var ribbons = this.ribbons | ||||
| 				var t = ribbons.getImageByPosition('current', r) | ||||
| 
 | ||||
| 				if(t.length > 1){ | ||||
| 					t = t.eq(direction == 'before' ? 0 : 1) | ||||
| 				} | ||||
| 
 | ||||
| 				t = ribbons.getElemGID(t) | ||||
| 			} | ||||
| 
 | ||||
| 			this.focusImage(t, r) | ||||
| 		}], | ||||
| 	setBaseRibbon: ['Edit/Set base ribbon', | ||||
| @ -1984,6 +2023,66 @@ module.SingleImageView = ImageGridFeatures.Feature({ | ||||
| 
 | ||||
| 
 | ||||
| //---------------------------------------------------------------------
 | ||||
| // These feature glue traverse and ribbon alignment...
 | ||||
| 
 | ||||
| // XXX manual align needs more work...
 | ||||
| var AutoAlignRibbons =  | ||||
| module.AutoAlignRibbons = ImageGridFeatures.Feature({ | ||||
| 	title: '', | ||||
| 	doc: '', | ||||
| 
 | ||||
| 	tag: 'ui-ribbon-auto-align', | ||||
| 	depends: ['ui'], | ||||
| 	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-mode': null, | ||||
| 	}, | ||||
| 
 | ||||
| 	handlers: [ | ||||
| 		['focusImage.post',  | ||||
| 			function(){  | ||||
| 				var mode = this.config['ribbon-align-mode']  | ||||
| 					|| this.config['ribbon-focus-mode'] | ||||
| 
 | ||||
| 				if(mode == 'visual' || mode == 'order'){ | ||||
| 					this.alignByOrder()  | ||||
| 
 | ||||
| 				} else if(mode == 'first'){ | ||||
| 					this.alignByFirst() | ||||
| 
 | ||||
| 				// manual...
 | ||||
| 				// XXX is this correct???
 | ||||
| 				} else { | ||||
| 					this | ||||
| 						.centerRibbon() | ||||
| 						.centerImage() | ||||
| 				} | ||||
| 			}], | ||||
| 	], | ||||
| }) | ||||
| 
 | ||||
| 
 | ||||
| // XXX add a feature not to align the ribbons and focus the central 
 | ||||
| // 		image on next prev ribbon...
 | ||||
| // XXX in general need a way to control .nextRibbon(..)/.prevRibbon(..)
 | ||||
| // 		image selection...
 | ||||
| 
 | ||||
| // XXX this should also define up/down navigation behavior e.g. what to 
 | ||||
| // 		focus on next/prev ribbon...
 | ||||
| @ -1998,6 +2097,11 @@ module.AlignRibbonsToImageOrder = ImageGridFeatures.Feature({ | ||||
| 	depends: ['ui'], | ||||
| 	exclusive: ['ui-ribbon-align'], | ||||
| 
 | ||||
| 	config: { | ||||
| 		//'ribbon-focus-mode': 'order',
 | ||||
| 		'ribbon-focus-mode': 'visual', | ||||
| 	}, | ||||
| 
 | ||||
| 	handlers: [ | ||||
| 		['focusImage.post', function(){ this.alignByOrder() }] | ||||
| 	], | ||||
| @ -2013,11 +2117,41 @@ module.AlignRibbonsToFirstImage = ImageGridFeatures.Feature({ | ||||
| 	depends: ['ui'], | ||||
| 	exclusive: ['ui-ribbon-align'], | ||||
| 
 | ||||
| 	config: { | ||||
| 		'ribbon-focus-mode': 'first', | ||||
| 	}, | ||||
| 
 | ||||
| 	handlers: [ | ||||
| 		['focusImage.post', function(){ this.alignByFirst() }], | ||||
| 	], | ||||
| }) | ||||
| 
 | ||||
| // XXX needs more work...
 | ||||
| // XXX need to save position in some way, ad on each load the same 
 | ||||
| // 		initial state will get loaded...
 | ||||
| // 		...also would need an initial state...
 | ||||
| var ManualAlignRibbons =  | ||||
| module.ManualAlignRibbons = ImageGridFeatures.Feature({ | ||||
| 	title: '', | ||||
| 	doc: '', | ||||
| 
 | ||||
| 	tag: 'ui-ribbon-manual-align', | ||||
| 	depends: ['ui'], | ||||
| 	exclusive: ['ui-ribbon-align'], | ||||
| 
 | ||||
| 	config: { | ||||
| 		'ribbon-focus-mode': 'visual', | ||||
| 	}, | ||||
| 
 | ||||
| 	handlers: [ | ||||
| 		['focusImage.post', function(){  | ||||
| 			this | ||||
| 				.centerRibbon() | ||||
| 				.centerImage() | ||||
| 		}], | ||||
| 	], | ||||
| }) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| //---------------------------------------------------------------------
 | ||||
| @ -3477,7 +3611,10 @@ ImageGridFeatures.Feature('viewer-testing', [ | ||||
| 	'ui', | ||||
| 
 | ||||
| 	// features...
 | ||||
| 	'ui-ribbon-align-to-order', | ||||
| 	'ui-ribbon-auto-align', | ||||
| 	//'ui-ribbon-align-to-order',
 | ||||
| 	//'ui-ribbon-align-to-first',
 | ||||
| 	//'ui-ribbon-manual-align',
 | ||||
| 	'ui-single-image-view', | ||||
| 	'ui-partial-ribbons', | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user