mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 18:30:09 +00:00
sort now mostly working...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
e1390b2747
commit
dd0fe62ad7
@ -79,6 +79,8 @@ actions.Actions({
|
||||
'last', // select last image
|
||||
],
|
||||
'ribbon-focus-mode': 'order',
|
||||
|
||||
'defeault-sort': 'birthtime ctime',
|
||||
},
|
||||
|
||||
|
||||
@ -512,15 +514,90 @@ actions.Actions({
|
||||
|
||||
// XXX align to ribbon...
|
||||
|
||||
// Custom sort modes...
|
||||
//
|
||||
// Format:
|
||||
// {
|
||||
// <mode-name>: function(a, b){ ... },
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// NOTE: the cmp function is called in the actions context.
|
||||
__sort_modes__: {
|
||||
},
|
||||
// XXX this also requires images...
|
||||
// XXX cache order???
|
||||
sortImages: ['Sort/',
|
||||
function(method){
|
||||
if(this.images){
|
||||
// select method...
|
||||
this.data.order = this.images.sortImages().reverse()
|
||||
sortImages: ['- Edit|Sort/Sort images',
|
||||
function(method, reverse){
|
||||
var that = this
|
||||
|
||||
if(method == 'reverse'){
|
||||
method = null
|
||||
reverse = true
|
||||
}
|
||||
|
||||
reverse = reverse == null
|
||||
|| reverse == 'reverse'
|
||||
|| reverse
|
||||
|
||||
method = method
|
||||
|| this.config['defeault-sort']
|
||||
|| 'birthtime'
|
||||
// handle multiple methods....
|
||||
method = typeof(method) == typeof('str') ? method.split(/ +/g) : method
|
||||
method = method instanceof Array ? method : [method]
|
||||
method = method.map(function(m){
|
||||
return BaseActions.__sort_modes__[m]
|
||||
|| (that.__sort_modes__ && that.__sort_modes__[m])
|
||||
// sort by attr path...
|
||||
|| (function(){
|
||||
var p = m.split(/\./g)
|
||||
var _get = function(obj){
|
||||
for(var i=0; i<p.length; i++){
|
||||
obj = obj[p[i]]
|
||||
if(obj === undefined){
|
||||
return null
|
||||
}
|
||||
}
|
||||
return obj
|
||||
}
|
||||
return function(a, b){
|
||||
a = _get(this.images[a])
|
||||
b = _get(this.images[b])
|
||||
|
||||
if(a == b){
|
||||
return 0
|
||||
} else if(a < b){
|
||||
return -1
|
||||
} else {
|
||||
return +1
|
||||
}
|
||||
}})()
|
||||
})
|
||||
|
||||
// prepare the cmp function...
|
||||
var cmp = method.length == 1 ?
|
||||
method[0]
|
||||
// chain compare -- return first non equal (0) result...
|
||||
: function(a, b){
|
||||
var res = 0
|
||||
for(var i=0; i < method.length; i++){
|
||||
res = method[i].call(that, a, b)
|
||||
if(res != 0){
|
||||
return res
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// do the sort (in place)...
|
||||
if(method && this.images){
|
||||
this.data.order = this.data.order.slice()
|
||||
reverse ?
|
||||
this.data.order.sort(cmp.bind(this)).reverse()
|
||||
: this.data.order.sort(cmp.bind(this))
|
||||
this.data.updateImagePositions()
|
||||
}
|
||||
this.data.updateImagePositions()
|
||||
}],
|
||||
|
||||
// basic image editing...
|
||||
|
||||
@ -250,6 +250,9 @@ var FileSystemLoaderActions = actions.Actions({
|
||||
img.atime = stat.atime
|
||||
img.mtime = stat.mtime
|
||||
img.ctime = stat.ctime
|
||||
img.birthtime = stat.birthtime
|
||||
|
||||
img.size = stat.size
|
||||
|
||||
// XXX do we need anything else???
|
||||
})
|
||||
|
||||
@ -263,6 +263,8 @@ module.GLOBAL_KEYBOARD = {
|
||||
O: 'browsePath',
|
||||
S: {
|
||||
default: 'slideshowDialog',
|
||||
shift: 'sortImages: "birthtime ctime" -- Sort images by date',
|
||||
alt: 'browseActions: "/Sort/"',
|
||||
// XXX need to make this save to base_path if it exists and
|
||||
// ask the user if it does not... now it always asks.
|
||||
ctrl: 'saveIndexHere',
|
||||
|
||||
@ -239,7 +239,7 @@ var StatusBarActions = actions.Actions({
|
||||
text = (img && ((img.base_path || '') +'/'+ img.path) || '---')
|
||||
// remove /./
|
||||
.replace(/[\\\/]\.[\\\/]/, '/')
|
||||
txt = text.split(/[\\\/]/).pop()
|
||||
txt = img && (img.name + img.ext) || text.split(/[\\\/]/).pop()
|
||||
}
|
||||
|
||||
item.find('.shown').text(txt)
|
||||
|
||||
@ -166,6 +166,11 @@ module.ViewerActions = actions.Actions({
|
||||
'last', // select last image
|
||||
],
|
||||
'ribbon-focus-mode': 'visual',
|
||||
|
||||
'sort-modes': {
|
||||
'Sort by date': 'metadata.createDate birthtime',
|
||||
'Sort by name': 'name path',
|
||||
},
|
||||
},
|
||||
|
||||
// Images...
|
||||
@ -625,7 +630,15 @@ module.ViewerActions = actions.Actions({
|
||||
|
||||
reverseImages: [ reloadAfter() ],
|
||||
reverseRibbons: [ reloadAfter() ],
|
||||
sortImages: [ reloadAfter() ],
|
||||
sortImages: [ reloadAfter(true) ],
|
||||
|
||||
// XXX should this be a dialog with ability to edit modes???
|
||||
// XXX should this store state???
|
||||
toggleImageSort: ['Edit|Sort/Sort images by',
|
||||
core.makeConfigToggler(
|
||||
function(){ return Object.keys(this.config['sort-modes'])[0]},
|
||||
function(){ return Object.keys(this.config['sort-modes']) },
|
||||
function(mode){ this.sortImages(this.config['sort-modes'][mode]) })],
|
||||
|
||||
|
||||
// basic image editing...
|
||||
|
||||
@ -317,10 +317,20 @@ module.ImagesClassPrototype = {
|
||||
// XXXX
|
||||
var gid = hash('I'+i+':'+p)
|
||||
|
||||
var name = (p
|
||||
// basename...
|
||||
.split(/[\\\/]/g).pop() || '')
|
||||
// ext...
|
||||
.split(/(\.[^\.]*$)/)
|
||||
|
||||
// XXX populate the image doc better...
|
||||
images[gid] = {
|
||||
id: gid,
|
||||
path: p,
|
||||
// basename...
|
||||
name: name[0],
|
||||
// ext with leading '.'
|
||||
ext: name[1],
|
||||
}
|
||||
|
||||
// remove only of base path is given and in path...
|
||||
|
||||
@ -26,6 +26,8 @@ module.QueueActions = actions.Actions({
|
||||
// XXX at this point these is ignored...
|
||||
'retry-limit': 5,
|
||||
'default-queue-mode': 'resumable',
|
||||
|
||||
'clear-on-done': true,
|
||||
},
|
||||
|
||||
// NOTE: these are sparse...
|
||||
@ -211,7 +213,9 @@ module.QueueActions = actions.Actions({
|
||||
// the pool.
|
||||
//
|
||||
// NOTE: there can be no more than one instance running at a time.
|
||||
// NOTE: if .state is not 'running' this will silently exit.
|
||||
// NOTE: if .state is not 'running' or 'ready' this will silently exit.
|
||||
// NOTE: if .state is 'ready' this will set it to 'running' and when
|
||||
// queue is depleted the .state will get set back to 'ready'
|
||||
//
|
||||
// XXX need to handle retries correctly, at this point all errors just
|
||||
// drop to failed and retry counter is incremented, there is no
|
||||
@ -283,6 +287,9 @@ module.QueueActions = actions.Actions({
|
||||
&& that.__running && that.__running.len == 0){
|
||||
that._state = 'ready'
|
||||
that.done()
|
||||
|
||||
that.config['clear-on-done']
|
||||
&& that.clear()
|
||||
}
|
||||
})
|
||||
// push to done and ._run some more...
|
||||
@ -304,6 +311,9 @@ module.QueueActions = actions.Actions({
|
||||
&& that.__running && that.__running.len == 0){
|
||||
that._state = 'ready'
|
||||
that.done()
|
||||
|
||||
that.config['clear-on-done']
|
||||
&& that.clear()
|
||||
}
|
||||
})
|
||||
|
||||
@ -323,6 +333,9 @@ module.QueueActions = actions.Actions({
|
||||
&& that.__running && that.__running.len == 0){
|
||||
that._state = 'ready'
|
||||
that.done()
|
||||
|
||||
that.config['clear-on-done']
|
||||
&& that.clear()
|
||||
}
|
||||
}
|
||||
})() }
|
||||
@ -344,6 +357,7 @@ module.QueueActions = actions.Actions({
|
||||
}],
|
||||
clear: ['',
|
||||
function(){
|
||||
// XXX should this stop???
|
||||
this.stop()
|
||||
delete this.__ready
|
||||
delete this.__running
|
||||
|
||||
@ -83,6 +83,19 @@ Array.prototype.setCmp = function(other){
|
||||
}
|
||||
|
||||
|
||||
module.chainCmp = function(cmp_chain){
|
||||
return function(a, b, get, data){
|
||||
var res
|
||||
for(var i=0; i < cmp_chain.length; i++){
|
||||
res = cmp_chain[i](a, b, get, data)
|
||||
if(res != 0){
|
||||
return res
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// like .length but for sparse arrays will return the element count...
|
||||
// XXX make this a prop...
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user