mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-12-16 16:21:40 +00:00
added several new image sorting algorithms...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
a5d64b031c
commit
0bdc98b3e1
145
ui/data.js
145
ui/data.js
@ -262,24 +262,23 @@ function cmp(a, b, get){
|
|||||||
// NOTE: this expects gids...
|
// NOTE: this expects gids...
|
||||||
function imageDateCmp(a, b, get, data){
|
function imageDateCmp(a, b, get, data){
|
||||||
data = data == null ? IMAGES : data
|
data = data == null ? IMAGES : data
|
||||||
if(get == null){
|
if(get != null){
|
||||||
return data[b].ctime - data[a].ctime
|
a = get(a)
|
||||||
} else {
|
b = get(b)
|
||||||
return data[get(b)].ctime - data[get(a)].ctime
|
|
||||||
}
|
}
|
||||||
|
return data[b].ctime - data[a].ctime
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// NOTE: this expects gids...
|
// NOTE: this expects gids...
|
||||||
function imageNameCmp(a, b, get, data){
|
function imageNameCmp(a, b, get, data){
|
||||||
data = data == null ? IMAGES : data
|
data = data == null ? IMAGES : data
|
||||||
if(get == null){
|
if(get != null){
|
||||||
a = data[a].path.split('/').pop()
|
a = get(a)
|
||||||
b = data[b].path.split('/').pop()
|
b = get(b)
|
||||||
} else {
|
|
||||||
a = data[get(a)].path.split('/').pop()
|
|
||||||
b = data[get(b)].path.split('/').pop()
|
|
||||||
}
|
}
|
||||||
|
a = data[a].path.split('/').pop()
|
||||||
|
b = data[b].path.split('/').pop()
|
||||||
if(a == b){
|
if(a == b){
|
||||||
return 0
|
return 0
|
||||||
} else if(a < b){
|
} else if(a < b){
|
||||||
@ -290,14 +289,87 @@ function imageNameCmp(a, b, get, data){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Get the first sequence of numbers in the file name...
|
||||||
|
function getImageNameSeq(gid, data){
|
||||||
|
data = data == null ? IMAGES : data
|
||||||
|
var n = data[gid].path.split('/').pop()
|
||||||
|
var r = /([0-9]+)/m.exec(n)
|
||||||
|
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){
|
||||||
|
data = data == null ? IMAGES : data
|
||||||
|
var n = data[gid].path.split('/').pop()
|
||||||
|
var r = /^([0-9]+)/g.exec(n)
|
||||||
|
return r == null ? n : parseInt(r[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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort images 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// NOTE: this expects gids...
|
// NOTE: this expects gids...
|
||||||
function imageOrderCmp(a, b, get, data){
|
function imageOrderCmp(a, b, get, data){
|
||||||
data = data == null ? DATA : data
|
data = data == null ? DATA : data
|
||||||
if(get == null){
|
if(get != null){
|
||||||
return data.order.indexOf(a) - data.order.indexOf(b)
|
a = get(a)
|
||||||
} else {
|
b = get(b)
|
||||||
return data.order.indexOf(get(a)) - data.order.indexOf(get(b))
|
|
||||||
}
|
}
|
||||||
|
return data.order.indexOf(a) - data.order.indexOf(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1785,6 +1857,12 @@ function sortImagesByDate(reverse){
|
|||||||
function sortImagesByFileName(reverse){
|
function sortImagesByFileName(reverse){
|
||||||
return sortImages(imageNameCmp, reverse)
|
return sortImages(imageNameCmp, reverse)
|
||||||
}
|
}
|
||||||
|
function sortImagesByFileSeqOrName(reverse){
|
||||||
|
return sortImages(imageSeqOrNameCmp, reverse)
|
||||||
|
}
|
||||||
|
function sortImagesByFileNameXPStyle(reverse){
|
||||||
|
return sortImages(imageXPStyleFileNameCmp, reverse)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Sort images by name while taking into account sequence overflows
|
// Sort images by name while taking into account sequence overflows
|
||||||
@ -1793,7 +1871,9 @@ function sortImagesByFileName(reverse){
|
|||||||
// *9999 and then resets to *0001...
|
// *9999 and then resets to *0001...
|
||||||
//
|
//
|
||||||
// For this to be applicable:
|
// For this to be applicable:
|
||||||
// - filenames must comply with /....[0-9]{4}/
|
// - ALL filenames must contain a sequence number
|
||||||
|
// XXX do we need to make this more strict?
|
||||||
|
// ...for example make name.split(<seq>) equal for all files
|
||||||
// - the total number of files in sequence is < 10K
|
// - the total number of files in sequence is < 10K
|
||||||
// XXX a simplification...
|
// XXX a simplification...
|
||||||
// there could be more than 10K images but then we will need to
|
// there could be more than 10K images but then we will need to
|
||||||
@ -1805,10 +1885,12 @@ function sortImagesByFileName(reverse){
|
|||||||
// number of files in set
|
// number of files in set
|
||||||
// XXX a simplification...
|
// XXX a simplification...
|
||||||
//
|
//
|
||||||
|
// NOTE: at this pint the gap size must be above proximity*10
|
||||||
// NOTE: if any of the above conditions is not applicable this will
|
// NOTE: if any of the above conditions is not applicable this will
|
||||||
// essentially revert to sortImagesByFileName(...)
|
// essentially revert to sortImagesByFileSeqOrName(...)
|
||||||
// NOTE: this will cut at the largest gap between sequence numbers.
|
// NOTE: this will cut at the largest gap between sequence numbers.
|
||||||
//
|
//
|
||||||
|
// XXX it would be a good idea to account for folder name sequencing...
|
||||||
// XXX it's also a good idea to write an image serial number sort...
|
// XXX it's also a good idea to write an image serial number sort...
|
||||||
// XXX is this overcomplicated???
|
// XXX is this overcomplicated???
|
||||||
//
|
//
|
||||||
@ -1816,54 +1898,50 @@ function sortImagesByFileName(reverse){
|
|||||||
// ever know it's here, if we replace it with the thee line dumb
|
// ever know it's here, if we replace it with the thee line dumb
|
||||||
// sortImagesByFileName(...) then things get "annoying" every 10K
|
// sortImagesByFileName(...) then things get "annoying" every 10K
|
||||||
// images :)
|
// images :)
|
||||||
function sortImagesByNameWithSeqOverflow(reverse, proximity){
|
function sortImagesByFileNameSeqWithOverflow(reverse, proximity){
|
||||||
proximity = proximity == null ? 10 : proximity
|
proximity = proximity == null ? 10 : proximity
|
||||||
|
|
||||||
// prepare to sort and check names...
|
// prepare to sort and check names...
|
||||||
// NOTE: we do not usually have a filename seq 0000...
|
// NOTE: we do not usually have a filename seq 0000...
|
||||||
if(DATA.order.length < 9999){
|
if(DATA.order.length < 9999){
|
||||||
var pattern = /....[0-9]{4}[a-z]?(\....[.])?/
|
|
||||||
var need_to_fix = true
|
var need_to_fix = true
|
||||||
|
|
||||||
function cmp(a, b){
|
function cmp(a, b){
|
||||||
if(need_to_fix){
|
if(need_to_fix){
|
||||||
// check filename compliance...
|
if(typeof(getImageNameSeq(a)) == typeof('str')
|
||||||
var aa = pattern.test(IMAGES[a].path.split('/').pop())
|
|| typeof(getImageNameSeq(b)) == typeof('str')){
|
||||||
var bb = pattern.test(IMAGES[b].path.split('/').pop())
|
|
||||||
if(!aa && !bb){
|
|
||||||
need_to_fix = false
|
need_to_fix = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return imageNameCmp(a, b)
|
return imageSeqOrNameCmp(a, b)
|
||||||
}
|
|
||||||
function getSeq(gid){
|
|
||||||
return parseInt(IMAGES[gid].path.split('/').pop().slice(4))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// revert to normal sort my name...
|
// revert to normal sort my name...
|
||||||
// XXX this is not needed but will make things faster...
|
|
||||||
} else {
|
} else {
|
||||||
|
// XXX make this more cleaver -- split the set into 10K chunks and
|
||||||
|
// sort the chunks too...
|
||||||
return sortImagesByFileName(reverse)
|
return sortImagesByFileName(reverse)
|
||||||
}
|
}
|
||||||
|
|
||||||
DATA.order.sort(cmp)
|
DATA.order.sort(cmp)
|
||||||
|
|
||||||
|
// find and fix the gap...
|
||||||
if(need_to_fix
|
if(need_to_fix
|
||||||
// check if first and last are close to 0001 and 9999 resp.
|
// check if first and last are close to 0001 and 9999 resp.
|
||||||
&& getSeq(DATA.order[0]) <= proximity
|
&& getImageNameSeq(DATA.order[0]) <= proximity
|
||||||
&& getSeq(DATA.order[DATA.order.length-1]) >= 9999-proximity){
|
&& getImageNameSeq(DATA.order[DATA.order.length-1]) >= 9999-proximity){
|
||||||
// find the largest gap position...
|
// find the largest gap position...
|
||||||
var pos = null
|
var pos = null
|
||||||
var gap = 0
|
var gap = 0
|
||||||
for(var i=1; i<DATA.order.length; i++){
|
for(var i=1; i<DATA.order.length; i++){
|
||||||
var n_gap = Math.max(getSeq(DATA.order[i])-getSeq(DATA.order[i-1]), gap)
|
var n_gap = Math.max(getImageNameSeq(DATA.order[i])-getImageNameSeq(DATA.order[i-1]), gap)
|
||||||
if(n_gap != gap){
|
if(n_gap != gap){
|
||||||
pos = i
|
pos = i
|
||||||
gap = n_gap
|
gap = n_gap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// split and rearrange the order chunks...
|
// split and rearrange the order chunks...
|
||||||
if(gap > proximity){
|
if(gap > proximity*10){
|
||||||
DATA.order = DATA.order.splice(pos).concat(DATA.order)
|
DATA.order = DATA.order.splice(pos).concat(DATA.order)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1875,11 +1953,6 @@ function sortImagesByNameWithSeqOverflow(reverse, proximity){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Set the default filename sort...
|
|
||||||
// XXX is this the correct way to do this???
|
|
||||||
var sortImagesByName = sortImagesByNameWithSeqOverflow
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************** Manual sorting ***/
|
/************************************************** Manual sorting ***/
|
||||||
|
|
||||||
|
|||||||
@ -1173,6 +1173,9 @@ button:hover {
|
|||||||
.overlay-block .dialog table tr td:last-child {
|
.overlay-block .dialog table tr td:last-child {
|
||||||
color: silver;
|
color: silver;
|
||||||
}
|
}
|
||||||
|
.overlay-block .dialog .choice .item {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
/************************************************************ Help ***/
|
/************************************************************ Help ***/
|
||||||
/* XXX make this more generic, and not just for the keyboard... */
|
/* XXX make this more generic, and not just for the keyboard... */
|
||||||
/* this is for sliding stuff */
|
/* this is for sliding stuff */
|
||||||
|
|||||||
@ -1217,6 +1217,10 @@ button:hover {
|
|||||||
color: silver;
|
color: silver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.overlay-block .dialog .choice .item {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************************ Help ***/
|
/************************************************************ Help ***/
|
||||||
|
|||||||
27
ui/ui.js
27
ui/ui.js
@ -978,9 +978,16 @@ function sortImagesDialog(message){
|
|||||||
cfg = {}
|
cfg = {}
|
||||||
cfg[message] = [
|
cfg[message] = [
|
||||||
'Date (ascending)',
|
'Date (ascending)',
|
||||||
'Name (ascending)',
|
'Date (descending)',
|
||||||
'Date (decending)',
|
|
||||||
'Name (decending)'
|
'Sequence number (ascending)',
|
||||||
|
'Sequence number (descending)',
|
||||||
|
|
||||||
|
'Sequence number with overflow (ascending)',
|
||||||
|
'Sequence number with overflow (descending)',
|
||||||
|
|
||||||
|
'File name (ascending)',
|
||||||
|
'File name (descending)'
|
||||||
]
|
]
|
||||||
|
|
||||||
formDialog(null, '',
|
formDialog(null, '',
|
||||||
@ -990,10 +997,20 @@ function sortImagesDialog(message){
|
|||||||
.done(function(res){
|
.done(function(res){
|
||||||
res = res[message]
|
res = res[message]
|
||||||
|
|
||||||
if(/Date/.test(res)){
|
if(/Date/i.test(res)){
|
||||||
var method = sortImagesByDate
|
var method = sortImagesByDate
|
||||||
|
|
||||||
|
} else if(/File name/i.test(res)){
|
||||||
|
var method = sortImagesByFileNameXPStyle
|
||||||
|
|
||||||
|
} else if(/Sequence/i.test(res) && !/with overflow/.test(res)){
|
||||||
|
var method = sortImagesByFileSeqOrName
|
||||||
|
|
||||||
|
} else if(/Sequence/i.test(res) && /with overflow/.test(res)){
|
||||||
|
var method = sortImagesByFileNameSeqWithOverflow
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
var method = sortImagesByName
|
var method = sortImagesByFileName
|
||||||
}
|
}
|
||||||
if(/\(ascending\)/.test(res)){
|
if(/\(ascending\)/.test(res)){
|
||||||
var reverse = null
|
var reverse = null
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user