mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 10:20:08 +00:00
more refactoring, rearanged sort-related functions and re-written image/gid distance related code...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
d2a065b09a
commit
1bc2fb64f8
463
ui/data.js
463
ui/data.js
@ -172,119 +172,6 @@ function concatZip(){
|
||||
}
|
||||
|
||||
|
||||
function makeDistanceCmp(start, get){
|
||||
if(get == null){
|
||||
return function(a, b){
|
||||
return Math.abs(start - a) - Math.abs(start - b)
|
||||
}
|
||||
} else {
|
||||
start = get(start)
|
||||
return function(a, b){
|
||||
return Math.abs(start - get(a)) - Math.abs(start - get(b))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Make a cmp function to compare two gids by distance from gid.
|
||||
function makeImageGIDDistanceCmp(gid, get, order){
|
||||
order = order == null ? DATA.order : order
|
||||
return makeDistanceCmp(gid, get == null ?
|
||||
function(a){
|
||||
return order.indexOf(a)
|
||||
}
|
||||
: function(a){
|
||||
return order.indexOf(get(a))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// NOTE: essentially this is a 2D distance comparison from gid...
|
||||
//
|
||||
// XXX make this faster...
|
||||
// XXX this is fun, but do we actually need this?
|
||||
function makeImageRibbonDistanceCmp(gid, get, data, images){
|
||||
data = data == null ? DATA : data
|
||||
images = images == null ? IMAGES : images
|
||||
|
||||
// make a cmp index...
|
||||
var ribbons = $.map(DATA.ribbons, function(r, i){
|
||||
// sort each ribbon by distance from closest gid...
|
||||
//return [r.slice().sort(makeImageGIDDistanceCmp(getGIDBefore(gid, i)))]
|
||||
return [r.slice().sort(makeImageGIDDistanceCmp(gid))]
|
||||
})
|
||||
var gids = $.map(ribbons, function(e){ return [e[0]] })
|
||||
var ri = gids.indexOf(gid)
|
||||
|
||||
function _getRibbon(gid){
|
||||
for(var i=0; i < ribbons.length; i++){
|
||||
if(ribbons[i].indexOf(gid) >= 0){
|
||||
return ribbons[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _getDistance(a){
|
||||
var r = _getRibbon(a)
|
||||
var x = r.indexOf(a)
|
||||
var y = Math.abs(gids.indexOf(r[0]) - ri)
|
||||
|
||||
// NOTE: this is cheating...
|
||||
//return x + y
|
||||
// calculate real distance...
|
||||
return Math.sqrt(x*x + y*y)
|
||||
}
|
||||
|
||||
if(get == null){
|
||||
return function(a, b){
|
||||
return _getDistance(a) - _getDistance(b)
|
||||
}
|
||||
} else {
|
||||
return function(a, b){
|
||||
return _getDistance(get(a)) - _getDistance(get(b))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function cmp(a, b, get){
|
||||
if(get == null){
|
||||
return a - b
|
||||
}
|
||||
return get(a) - get(b)
|
||||
}
|
||||
|
||||
|
||||
// NOTE: this expects gids...
|
||||
function imageDateCmp(a, b, get, data){
|
||||
data = data == null ? IMAGES : data
|
||||
if(get != null){
|
||||
a = get(a)
|
||||
b = get(b)
|
||||
}
|
||||
return data[b].ctime - data[a].ctime
|
||||
}
|
||||
|
||||
|
||||
// NOTE: this expects gids...
|
||||
function imageNameCmp(a, b, get, data){
|
||||
data = data == null ? IMAGES : data
|
||||
if(get != null){
|
||||
a = get(a)
|
||||
b = get(b)
|
||||
}
|
||||
a = data[a].path.split('/').pop()
|
||||
b = data[b].path.split('/').pop()
|
||||
if(a == b){
|
||||
return 0
|
||||
} else if(a < b){
|
||||
return -1
|
||||
} else {
|
||||
return +1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Get the first sequence of numbers in the file name...
|
||||
function getImageNameSeq(gid, data){
|
||||
data = data == null ? IMAGES : data
|
||||
@ -293,6 +180,7 @@ function getImageNameSeq(gid, data){
|
||||
return r == null ? n : parseInt(r[1])
|
||||
}
|
||||
|
||||
|
||||
// Get the first sequence of numbers in the file name but only if it is
|
||||
// at the filename start...
|
||||
function getImageNameLeadingSeq(gid, data){
|
||||
@ -303,62 +191,69 @@ function getImageNameLeadingSeq(gid, data){
|
||||
}
|
||||
|
||||
|
||||
// Compare images by sequence number (in filename) or by filename
|
||||
//
|
||||
// Examples:
|
||||
// "1 file name", "012-file", "file 123 name", "DSC_1234"
|
||||
//
|
||||
// NOTE: if there are more than one sequence numbers in a filename then
|
||||
// only the first is considered.
|
||||
// NOTE: images with sequence number always precede images with plain
|
||||
// filenames...
|
||||
function imageSeqOrNameCmp(a, b, get, data, get_seq){
|
||||
data = data == null ? IMAGES : data
|
||||
get_seq = get_seq == null ? getImageNameSeq : get_seq
|
||||
function getGIDDistance(a, b, get, data){
|
||||
data = data == null ? DATA : data
|
||||
var order = data.order
|
||||
if(get != null){
|
||||
a = get(a)
|
||||
b = get(b)
|
||||
}
|
||||
a = order.indexOf(a)
|
||||
b = order.indexOf(b)
|
||||
return Math.abs(a - b)
|
||||
}
|
||||
|
||||
var aa = get_seq(a, data)
|
||||
var bb = get_seq(b, data)
|
||||
|
||||
// special case: seq, name
|
||||
if(typeof(aa) == typeof(123) && typeof(bb) == typeof('str')){ return -1 }
|
||||
// special case: name, seq
|
||||
if(typeof(aa) == typeof('str') && typeof(bb) == typeof(123)){ return +1 }
|
||||
// NOTE: this is a constructor to cache the generated index as it is
|
||||
// quite slow to construct, but needs to be current...
|
||||
function makeGIDRibbonDistanceGetter(gid, data){
|
||||
data = data == null ? DATA : data
|
||||
|
||||
// get the names if there are no sequence numbers...
|
||||
// NOTE: at this point both a and b are either numbers or NaN's...
|
||||
a = isNaN(aa) ? data[a].path.split('/').pop() : aa
|
||||
b = isNaN(bb) ? data[b].path.split('/').pop() : bb
|
||||
// make a cmp index...
|
||||
var ribbons = $.map(DATA.ribbons, function(r, i){
|
||||
// sort each ribbon by distance from closest gid...
|
||||
//return [r.slice().sort(makeGIDDistanceCmp(getGIDBefore(gid, i)))]
|
||||
return [r.slice().sort(makeGIDDistanceCmp(gid))]
|
||||
})
|
||||
var gids = $.map(ribbons, function(e){ return [e[0]] })
|
||||
var ri = gids.indexOf(gid)
|
||||
|
||||
// do the actual comparison
|
||||
if(a == b){
|
||||
return 0
|
||||
} else if(a < b){
|
||||
return -1
|
||||
} else {
|
||||
return +1
|
||||
// the basic calculator...
|
||||
return function(gid){
|
||||
var r = ribbons[getGIDRibbonIndex(gid, {ribbons: ribbons})]
|
||||
var x = r.indexOf(gid)
|
||||
var y = Math.abs(gids.indexOf(r[0]) - ri)
|
||||
|
||||
// calculate real distance...
|
||||
return Math.sqrt(x*x + y*y)
|
||||
}
|
||||
}
|
||||
|
||||
// Sort images XP-style
|
||||
|
||||
// Get distance between two gids taking into account ribbons...
|
||||
//
|
||||
// This will consider sequence numbers if they are at the start of the
|
||||
// filename.
|
||||
//
|
||||
// Examples:
|
||||
// "1 file name", "012-file"
|
||||
// This is essentially a 2D distance between two gids in data.
|
||||
//
|
||||
// NOTE: images with sequence number always precede images with plain
|
||||
// filenames...
|
||||
function imageXPStyleFileNameCmp(a, b, get, data){
|
||||
return imageSeqOrNameCmp(a, b, get, data, getImageNameLeadingSeq)
|
||||
// NOTE: to get lots of distances from a specific image use
|
||||
// makeGIDDistanceCmp(...) for faster results...
|
||||
function getGIDRibbonDistance(a, b, data){
|
||||
return makeDistanceFromGIDGetter(a, data)(b)
|
||||
}
|
||||
|
||||
|
||||
|
||||
function cmp(a, b, get){
|
||||
if(get == null){
|
||||
return a - b
|
||||
}
|
||||
return get(a) - get(b)
|
||||
}
|
||||
|
||||
|
||||
// Generic ordering via DATA.order
|
||||
//
|
||||
// NOTE: this expects gids...
|
||||
// NOTE: this is not in sort.js because it is a generic base sort method
|
||||
function imageOrderCmp(a, b, get, data){
|
||||
data = data == null ? DATA : data
|
||||
if(get != null){
|
||||
@ -482,128 +377,22 @@ Array.prototype.binSearch = function(target, cmp, get){
|
||||
}
|
||||
|
||||
|
||||
// Orientation translation...
|
||||
function orientationExif2ImageGrid(orientation){
|
||||
return {
|
||||
orientation: {
|
||||
0: 0,
|
||||
1: 0,
|
||||
2: 0,
|
||||
3: 180,
|
||||
4: 0,
|
||||
5: 90,
|
||||
6: 90,
|
||||
7: 90,
|
||||
8: 270,
|
||||
}[orientation],
|
||||
flipped: {
|
||||
0: null,
|
||||
1: null,
|
||||
2: ['horizontal'],
|
||||
3: null,
|
||||
4: ['vertical'],
|
||||
5: ['vertical'],
|
||||
6: null,
|
||||
7: ['horizontal'],
|
||||
8: null,
|
||||
}[orientation]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Base URL interface...
|
||||
//
|
||||
// NOTE: changing a base URL will trigger a baseURLChanged event...
|
||||
function setBaseURL(url){
|
||||
var old_url = BASE_URL
|
||||
url = url.replace(/\/*$/, '/')
|
||||
BASE_URL = url
|
||||
$('.viewer').trigger('baseURLChanged', [old_url, url])
|
||||
return url
|
||||
}
|
||||
function getBaseURL(){
|
||||
return BASE_URL
|
||||
}
|
||||
|
||||
|
||||
// Normalize the path...
|
||||
//
|
||||
// This will:
|
||||
// - convert windows absolute paths 'X:\...' -> 'file:///X:/...'
|
||||
// - if mode is 'absolute':
|
||||
// - return absolute paths as-is
|
||||
// - base relative paths on base/BASE_URL, returning an absolute
|
||||
// path
|
||||
// - if mode is relative:
|
||||
// - if absolute path is based on base/BASE_URL make a relative
|
||||
// to base path out of it buy cutting the base out.
|
||||
// - return absolute paths as-is
|
||||
// - return relative paths as-is
|
||||
//
|
||||
// NOTE: mode can be either 'absolute' (default) or 'relative'...
|
||||
function normalizePath(url, base, mode){
|
||||
base = base == null ? getBaseURL() : base
|
||||
//mode = /^\./.test(base) && mode == null ? 'relative' : null
|
||||
mode = mode == null ? 'absolute' : mode
|
||||
|
||||
res = ''
|
||||
|
||||
// windows path...
|
||||
// - replace all '\\' with '/'...
|
||||
url = url.replace(/\\/g, '/')
|
||||
// - replace 'X:/...' with 'file:///X:/...'
|
||||
if(/^[A-Z]:\//.test(url)){
|
||||
url = 'file:///' + url
|
||||
}
|
||||
|
||||
// we got absolute path...
|
||||
if(/^(file|http|https):\/\/.*$/.test(url)){
|
||||
// check if we start with base, and remove it if so...
|
||||
if(mode == 'relative' && url.substring(0, base.length) == base){
|
||||
url = url.substring(base.length - 1)
|
||||
res = url[0] == '/' ? url.substring(1) : url
|
||||
|
||||
// if it's a different path, return as-is
|
||||
} else if(mode == 'absolute'){
|
||||
res = url
|
||||
}
|
||||
|
||||
// make an absolute path...
|
||||
} else if(mode == 'absolute') {
|
||||
// if base ends and url starts with '.' avoid making it a '..'
|
||||
if(base[base.length-1] == '.' && url[0] == '.'){
|
||||
res = base + url.substring(1)
|
||||
// avoid creating '//'...
|
||||
} else if(base[base.length-1] != '/' && url[0] != '/'){
|
||||
res = base + '/' + url
|
||||
} else {
|
||||
res = base + url
|
||||
}
|
||||
}
|
||||
|
||||
// get the actual path...
|
||||
res = res.replace('${CACHE_DIR}', CACHE_DIR)
|
||||
|
||||
// XXX legacy support...
|
||||
res = res.replace('.ImageGridCache', CACHE_DIR)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
|
||||
// like getRibbonIndex but get the index only via DATA...
|
||||
function getDataRibbonIndex(gid, data){
|
||||
function getGIDRibbonIndex(gid, data){
|
||||
gid = gid == null ? getImageGID() : gid
|
||||
data = data == null ? DATA : data
|
||||
|
||||
for(var i=0; i < data.ribbons.length; i++){
|
||||
if(data.ribbons[i].indexOf(gid) >= 0){
|
||||
var ribbons = data.ribbons
|
||||
|
||||
for(var i=0; i < ribbons.length; i++){
|
||||
if(ribbons[i].indexOf(gid) >= 0){
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
|
||||
// Same as getImageBefore(...), but uses gids and searches in DATA...
|
||||
//
|
||||
// NOTE: this uses it's own predicate...
|
||||
@ -612,7 +401,7 @@ function getGIDBefore(gid, ribbon, search, data){
|
||||
data = data == null ? DATA : data
|
||||
// XXX get a ribbon without getting into DOM...
|
||||
// ...dependency leek...
|
||||
ribbon = ribbon == null ? getDataRibbonIndex(gid, data) : ribbon
|
||||
ribbon = ribbon == null ? getGIDRibbonIndex(gid, data) : ribbon
|
||||
search = search == null ? binSearch : search
|
||||
//search = search == null ? match2(linSearch, binSearch) : search
|
||||
ribbon = data.ribbons[ribbon]
|
||||
@ -698,6 +487,86 @@ function getImageGIDs(from, count, ribbon, inclusive){
|
||||
}
|
||||
|
||||
|
||||
// Base URL interface...
|
||||
//
|
||||
// NOTE: changing a base URL will trigger a baseURLChanged event...
|
||||
function getBaseURL(){
|
||||
return BASE_URL
|
||||
}
|
||||
function setBaseURL(url){
|
||||
var old_url = BASE_URL
|
||||
url = url.replace(/\/*$/, '/')
|
||||
BASE_URL = url
|
||||
$('.viewer').trigger('baseURLChanged', [old_url, url])
|
||||
return url
|
||||
}
|
||||
|
||||
|
||||
// Normalize the path...
|
||||
//
|
||||
// This will:
|
||||
// - convert windows absolute paths 'X:\...' -> 'file:///X:/...'
|
||||
// - if mode is 'absolute':
|
||||
// - return absolute paths as-is
|
||||
// - base relative paths on base/BASE_URL, returning an absolute
|
||||
// path
|
||||
// - if mode is relative:
|
||||
// - if absolute path is based on base/BASE_URL make a relative
|
||||
// to base path out of it buy cutting the base out.
|
||||
// - return absolute paths as-is
|
||||
// - return relative paths as-is
|
||||
//
|
||||
// NOTE: mode can be either 'absolute' (default) or 'relative'...
|
||||
function normalizePath(url, base, mode){
|
||||
base = base == null ? getBaseURL() : base
|
||||
//mode = /^\./.test(base) && mode == null ? 'relative' : null
|
||||
mode = mode == null ? 'absolute' : mode
|
||||
|
||||
res = ''
|
||||
|
||||
// windows path...
|
||||
// - replace all '\\' with '/'...
|
||||
url = url.replace(/\\/g, '/')
|
||||
// - replace 'X:/...' with 'file:///X:/...'
|
||||
if(/^[A-Z]:\//.test(url)){
|
||||
url = 'file:///' + url
|
||||
}
|
||||
|
||||
// we got absolute path...
|
||||
if(/^(file|http|https):\/\/.*$/.test(url)){
|
||||
// check if we start with base, and remove it if so...
|
||||
if(mode == 'relative' && url.substring(0, base.length) == base){
|
||||
url = url.substring(base.length - 1)
|
||||
res = url[0] == '/' ? url.substring(1) : url
|
||||
|
||||
// if it's a different path, return as-is
|
||||
} else if(mode == 'absolute'){
|
||||
res = url
|
||||
}
|
||||
|
||||
// make an absolute path...
|
||||
} else if(mode == 'absolute') {
|
||||
// if base ends and url starts with '.' avoid making it a '..'
|
||||
if(base[base.length-1] == '.' && url[0] == '.'){
|
||||
res = base + url.substring(1)
|
||||
// avoid creating '//'...
|
||||
} else if(base[base.length-1] != '/' && url[0] != '/'){
|
||||
res = base + '/' + url
|
||||
} else {
|
||||
res = base + url
|
||||
}
|
||||
}
|
||||
|
||||
// get the actual path...
|
||||
res = res.replace('${CACHE_DIR}', CACHE_DIR)
|
||||
|
||||
// XXX legacy support...
|
||||
res = res.replace('.ImageGridCache', CACHE_DIR)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
|
||||
// Select best preview by size...
|
||||
//
|
||||
// NOTE: this will use the original if everything else is smaller...
|
||||
@ -725,27 +594,32 @@ function getBestPreview(gid, size){
|
||||
}
|
||||
|
||||
|
||||
// Resort the ribbons by DATA.order and re-render...
|
||||
//
|
||||
// NOTE: due to how the format is structured, to sort the images one
|
||||
// only needs to sort DATA.order and call this.
|
||||
function updateRibbonOrder(no_reload_viewer){
|
||||
for(var i=0; i < DATA.ribbons.length; i++){
|
||||
DATA.ribbons[i].sort(imageOrderCmp)
|
||||
// Orientation translation...
|
||||
function orientationExif2ImageGrid(orientation){
|
||||
return {
|
||||
orientation: {
|
||||
0: 0,
|
||||
1: 0,
|
||||
2: 0,
|
||||
3: 180,
|
||||
4: 0,
|
||||
5: 90,
|
||||
6: 90,
|
||||
7: 90,
|
||||
8: 270,
|
||||
}[orientation],
|
||||
flipped: {
|
||||
0: null,
|
||||
1: null,
|
||||
2: ['horizontal'],
|
||||
3: null,
|
||||
4: ['vertical'],
|
||||
5: ['vertical'],
|
||||
6: null,
|
||||
7: ['horizontal'],
|
||||
8: null,
|
||||
}[orientation]
|
||||
}
|
||||
if(!no_reload_viewer){
|
||||
reloadViewer()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// get list of gids sorted by proximity to current gid
|
||||
//
|
||||
// NOTE: the distance used is the actual 2D distance...
|
||||
function getClosestGIDs(gid){
|
||||
gid = gid == null ? getImageGID() : gid
|
||||
//return DATA.order.slice().sort(makeImageGIDDistanceCmp(gid))
|
||||
return DATA.order.slice().sort(makeImageRibbonDistanceCmp(gid))
|
||||
}
|
||||
|
||||
|
||||
@ -1276,9 +1150,9 @@ function updateImages(size, cmp){
|
||||
// sorted run...
|
||||
if(UPDATE_SORT_ENABLED && cmp != false){
|
||||
cmp = cmp == null ?
|
||||
makeImageGIDDistanceCmp(getImageGID(), getImageGID)
|
||||
makeGIDDistanceCmp(getImageGID(), getImageGID)
|
||||
// XXX this is more correct but is slow...
|
||||
//makeImageRibbonDistanceCmp(getImageGID(), getImageGID)
|
||||
//makeGIDRibbonDistanceCmp(getImageGID(), getImageGID)
|
||||
: cmp
|
||||
deferred.resolve($('.image')
|
||||
// sort images by distance from current, so as to update what
|
||||
@ -1588,6 +1462,21 @@ function getPrevLocation(){
|
||||
* Actions...
|
||||
*/
|
||||
|
||||
// Sort the ribbons by DATA.order and re-render...
|
||||
//
|
||||
// NOTE: due to how the format is structured, to sort the images one
|
||||
// only needs to sort DATA.order and call this.
|
||||
function updateRibbonOrder(no_reload_viewer){
|
||||
for(var i=0; i < DATA.ribbons.length; i++){
|
||||
DATA.ribbons[i].sort(imageOrderCmp)
|
||||
}
|
||||
if(!no_reload_viewer){
|
||||
reloadViewer()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************* Extension ***/
|
||||
|
||||
// Open image in an external editor/viewer
|
||||
|
||||
154
ui/sort.js
154
ui/sort.js
@ -12,7 +12,159 @@ var OVERFLOW_GAP = PROXIMITY * 5
|
||||
|
||||
|
||||
|
||||
/********************************************************* Sorting ***/
|
||||
/**********************************************************************
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
// create a generic distance comparison function
|
||||
//
|
||||
// NOTE: both distances are measured from a fixed point (start)...
|
||||
function makeDistanceCmp(start, get){
|
||||
if(get == null){
|
||||
return function(a, b){
|
||||
return Math.abs(start - a) - Math.abs(start - b)
|
||||
}
|
||||
} else {
|
||||
start = get(start)
|
||||
return function(a, b){
|
||||
return Math.abs(start - get(a)) - Math.abs(start - get(b))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Make a cmp function to compare two gids by distance from gid.
|
||||
//
|
||||
// NOTE: this calculates the distance in a flat sequence...
|
||||
function makeGIDDistanceCmp(gid, get, data){
|
||||
return function(a, b){
|
||||
return getGIDDistance(gid, a, get, data) - getGIDDistance(gid, b, get, data)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 2D distance from a specified gid comparison...
|
||||
//
|
||||
// XXX make this faster...
|
||||
// XXX this is fun, but do we actually need this?
|
||||
function makeGIDRibbonDistanceCmp(gid, get, data){
|
||||
data = data == null ? DATA : data
|
||||
|
||||
var _getDistance = makeGIDRibbonDistanceGetter(gid)
|
||||
|
||||
if(get == null){
|
||||
return function(a, b){
|
||||
return _getDistance(a) - _getDistance(b)
|
||||
}
|
||||
} else {
|
||||
return function(a, b){
|
||||
return _getDistance(get(a)) - _getDistance(get(b))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// NOTE: this expects gids...
|
||||
function imageDateCmp(a, b, get, data){
|
||||
data = data == null ? IMAGES : data
|
||||
if(get != null){
|
||||
a = get(a)
|
||||
b = get(b)
|
||||
}
|
||||
return data[b].ctime - data[a].ctime
|
||||
}
|
||||
|
||||
|
||||
// NOTE: this expects gids...
|
||||
function imageNameCmp(a, b, get, data){
|
||||
data = data == null ? IMAGES : data
|
||||
if(get != null){
|
||||
a = get(a)
|
||||
b = get(b)
|
||||
}
|
||||
a = data[a].path.split('/').pop()
|
||||
b = data[b].path.split('/').pop()
|
||||
if(a == b){
|
||||
return 0
|
||||
} else if(a < b){
|
||||
return -1
|
||||
} else {
|
||||
return +1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Compare images by sequence number (in filename) or by filename
|
||||
//
|
||||
// Examples:
|
||||
// "1 file name", "012-file", "file 123 name", "DSC_1234"
|
||||
//
|
||||
// NOTE: if there are more than one sequence numbers in a filename then
|
||||
// only the first is considered.
|
||||
// NOTE: images with sequence number always precede images with plain
|
||||
// filenames...
|
||||
function imageSeqOrNameCmp(a, b, get, data, get_seq){
|
||||
data = data == null ? IMAGES : data
|
||||
get_seq = get_seq == null ? getImageNameSeq : get_seq
|
||||
if(get != null){
|
||||
a = get(a)
|
||||
b = get(b)
|
||||
}
|
||||
|
||||
var aa = get_seq(a, data)
|
||||
var bb = get_seq(b, data)
|
||||
|
||||
// special case: seq, name
|
||||
if(typeof(aa) == typeof(123) && typeof(bb) == typeof('str')){ return -1 }
|
||||
// special case: name, seq
|
||||
if(typeof(aa) == typeof('str') && typeof(bb) == typeof(123)){ return +1 }
|
||||
|
||||
// get the names if there are no sequence numbers...
|
||||
// NOTE: at this point both a and b are either numbers or NaN's...
|
||||
a = isNaN(aa) ? data[a].path.split('/').pop() : aa
|
||||
b = isNaN(bb) ? data[b].path.split('/').pop() : bb
|
||||
|
||||
// do the actual comparison
|
||||
if(a == b){
|
||||
return 0
|
||||
} else if(a < b){
|
||||
return -1
|
||||
} else {
|
||||
return +1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Compate images by name XP-style
|
||||
//
|
||||
// This will consider sequence numbers if they are at the start of the
|
||||
// filename.
|
||||
//
|
||||
// Examples:
|
||||
// "1 file name", "012-file"
|
||||
//
|
||||
// NOTE: images with sequence number always precede images with plain
|
||||
// filenames...
|
||||
function imageXPStyleFileNameCmp(a, b, get, data){
|
||||
return imageSeqOrNameCmp(a, b, get, data, getImageNameLeadingSeq)
|
||||
}
|
||||
|
||||
|
||||
// Get list of gids sorted by proximity to current gid
|
||||
//
|
||||
// NOTE: the distance used is the actual 2D distance...
|
||||
function getClosestGIDs(gid){
|
||||
gid = gid == null ? getImageGID() : gid
|
||||
//return DATA.order.slice().sort(makeGIDDistanceCmp(gid))
|
||||
return DATA.order.slice().sort(makeGIDRibbonDistanceCmp(gid))
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* Actions
|
||||
*/
|
||||
|
||||
function reverseImageOrder(){
|
||||
DATA.order.reverse()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user