reworked tag selectors...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2013-12-21 06:20:34 +04:00
parent 0d3f0882d6
commit 4a45ed536f
2 changed files with 128 additions and 33 deletions

View File

@ -647,8 +647,32 @@ function getRibbonGIDs(a, data){
} }
// Test if a gid is loaded...
//
function isGIDLoaded(gid, data){
data = data == null ? DATA : data
var ribbons = data.ribbons
for(var i=0; i<ribbons.length; i++){
if(ribbons[i].indexOf(gid) >= 0){
return true
}
}
return false
}
// Get all the available gids...
//
// NOTE: this will not copy the order...
// NOTE: when this is passed a data object it will return the order...
function getAllGids(data){
return data == null ? DATA.order : data.order
}
// Get all the currently loaded gids... // Get all the currently loaded gids...
// //
// NOTE: this will return an unsorted list of gids...
function getLoadedGIDs(data){ function getLoadedGIDs(data){
data = data == null ? DATA : data data = data == null ? DATA : data
var res = [] var res = []
@ -749,6 +773,27 @@ function getGIDBefore(gid, ribbon, data, search){
} }
// Get a gid directly adjacent to gid...
//
// This will return null if there are no other gids loaded after.
//
// If gid is not in the giver ribbon this will first find the gid before
// and return the gid after that.
//
function getGIDAfter(gid, ribbon, data, search){
gid = gid == null ? getImageGID() : gid
data = data == null ? DATA : data
var cur = getGIDBefore(gid, ribbon, data, search)
ribbon = ribbon == null ? getGIDRibbonIndex(gid, data) : ribbon
ribbon = typeof(ribbon) == typeof(123) ? data.ribbons[ribbon] : ribbon
ribbon = ribbon == null ? data.ribbons[getGIDRibbonIndex(null, data)] : ribbon
return ribbon[ribbon.indexOf(cur)+1]
}
// Construct a function similar to getGIDBefore(..) that will get the // Construct a function similar to getGIDBefore(..) that will get the
// closest gid from a list... // closest gid from a list...
// //

View File

@ -175,21 +175,26 @@ function updateTags(tags, gid, tagset, images){
} }
// this implements the AND selector... /**********************************************************************
* Selectors...
*/
// Select gids tagged by ALL given tags...
// //
// NOTE: do not like this algorithm as it can get O(n^2)-ish function tagSelectAND(tags, from, no_sort, tagset){
// NOTE: unless no_sort is set, this will sort the resulted gids in the
// same order as DATA.order...
function selectByTags(tags, no_sort, tagset){
tags = typeof(tags) == typeof('str') ? [ tags ] : tags tags = typeof(tags) == typeof('str') ? [ tags ] : tags
tagset = tagset == null ? TAGS : tagset tagset = tagset == null ? TAGS : tagset
from = from == null ? getLoadedGIDs() : from
// special case: a single tag... // special case: a single tag...
// NOTE: this is significantly faster.
if(tags.length == 1){ if(tags.length == 1){
var loaded = getLoadedGIDs() var res = tagset[tags[0]]
return tagset[tags[0]].filter(function(gid){ return res == null
// skip unloaded gids... ? []
return loaded.indexOf(gid) >= 0 : res.filter(function(gid){
// skip unloaded from...
return from.indexOf(gid) >= 0
}) })
} }
@ -199,16 +204,21 @@ function selectByTags(tags, no_sort, tagset){
// populate the subtagset... // populate the subtagset...
tags.map(function(tag){ tags.map(function(tag){
if(tagset[tag] == null){ if(tagset[tag] == null){
return subtagset = false
return false
} }
subtagset.push(tagset[tag]) subtagset.push(tagset[tag])
}) })
// sort by length... // if at least one tag is invalid, we'll find nothing...
if(subtagset == false){
return []
}
// sort index by length...
subtagset.sort(function(a, b){ subtagset.sort(function(a, b){
return b.length - a.length return b.length - a.length
}) })
// set the res to the shortest subset... // start with the shortest subset...
var cur = subtagset.pop().slice() var cur = subtagset.pop().slice()
// filter out the result... // filter out the result...
@ -219,7 +229,8 @@ function selectByTags(tags, no_sort, tagset){
break break
} }
} }
if(gid != null){ // populate res...
if(gid != null && from.indexOf(gid) >= 0){
no_sort ? res.push(gid) : insertGIDToPosition(gid, res) no_sort ? res.push(gid) : insertGIDToPosition(gid, res)
} }
}) })
@ -228,6 +239,38 @@ function selectByTags(tags, no_sort, tagset){
} }
// select gids untagged by ALL of the given tags...
//
function tagSelectNOT(tags, from, tagset){
var remove = tagSelectAND(tags, from, false, tagset)
// keep the elements that DO NOT exist in remove...
return from.filter(function(e){
return remove.indexOf(e) < 0
})
}
// Select gids tagged by ANY of the given tags...
//
function tagSelectOR(tags, from, no_sort, tagset){
tags = typeof(tags) == typeof('str') ? [ tags ] : tags
tagset = tagset == null ? TAGS : tagset
from = from == null ? getLoadedGIDs() : from
var all = []
tags.forEach(function(tag){
tag = tagset[tag]
tag = tag == null ? [] : tag
all = all.concat(tag)
})
return from.filter(function(e){
return all.indexOf(e) >= 0
})
}
/* /*
// XXX don't remember the semantics... // XXX don't remember the semantics...
function getRelatedTags(){ function getRelatedTags(){
@ -254,7 +297,8 @@ function untagList(list, tags){
// list... // list...
function tagOnlyList(list, tags, no_sort){ function tagOnlyList(list, tags, no_sort){
no_sort = no_sort == null ? true : false no_sort = no_sort == null ? true : false
selectByTags(tags, no_sort).forEach(function(gid){ tagSelectAND(tags, null, no_sort)
.forEach(function(gid){
if(list.indexOf(gid) < 0){ if(list.indexOf(gid) < 0){
removeTag(tags, gid) removeTag(tags, gid)
} }
@ -285,12 +329,12 @@ function tagOnlyBookmarked(tags){ return tagOnlyList(BOOKMARKED, tags) }
// marking of tagged images... // marking of tagged images...
function markTagged(tags){ function markTagged(tags){
MARKED = selectByTags(tags) MARKED = tagSelectAND(tags)
updateImages() updateImages()
return MARKED return MARKED
} }
function unmarkTagged(tags){ function unmarkTagged(tags){
var set = selectByTags(tags, false) var set = tagSelectAND(tags, null, false)
set.forEach(function(gid){ set.forEach(function(gid){
var i = MARKED.indexOf(gid) var i = MARKED.indexOf(gid)
if(i > -1){ if(i > -1){
@ -304,19 +348,23 @@ function unmarkTagged(tags){
/*********************************************************************/ /*********************************************************************/
// XXX this is a bit brain-dead and slow, but should be good for testing... // Tag image that are not neighbored by an image tagged with the same
function _listTagsAtGaps(tags){ // tags from at least one side.
var order = DATA.order //
var list = selectByTags(tags) // Essentially this will list tag block borders.
//
function listTagsAtGapsFrom(tags, gids){
gids = gids == null ? getLoadedGIDs() : gids
var list = tagSelectAND(tags, gids)
var res = [] var res = []
list.forEach(function(gid){ list.forEach(function(gid){
var i = order.indexOf(gid) var i = gids.indexOf(gid)
// add the current gid to the result iff one or both gids // add the current gid to the result iff one or both gids
// adjacent to it are not in the list... // adjacent to it are not in the list...
if(list.indexOf(order[i-1]) < 0 if(list.indexOf(gids[i-1]) < 0
|| list.indexOf(order[i+1]) < 0){ || list.indexOf(gids[i+1]) < 0){
res.push(gid) res.push(gid)
} }
}) })
@ -332,7 +380,7 @@ function _listTagsAtGaps(tags){
// cropping of tagged images... // cropping of tagged images...
function cropTagged(tags, keep_ribbons, keep_unloaded_gids){ function cropTagged(tags, keep_ribbons, keep_unloaded_gids){
var set = selectByTags(tags) var set = tagSelectAND(tags)
cropDataTo(set, keep_ribbons, keep_unloaded_gids) cropDataTo(set, keep_ribbons, keep_unloaded_gids)
@ -368,23 +416,25 @@ SETUP_BINDINGS.push(setupTags)
// Setup the unsorted image state managers... // Setup the unsorted image state managers...
// //
// Unsorted tags are removed by shifting or by aligning, but only in
// uncropped mode...
function setupUnsortedTagHandler(viewer){ function setupUnsortedTagHandler(viewer){
console.log('Tags: "'+UNSORTED_TAG+'" tag handling: setup...') console.log('Tags: "'+UNSORTED_TAG+'" tag handling: setup...')
return viewer return viewer
// unsorted tag handling... // unsorted tag handling...
.on('shiftedImage', function(evt, img){ .on('shiftedImage', function(evt, img){
if(UNSORTED_TAG != null){ if(UNSORTED_TAG != null && !isViewCropped()){
removeTag(UNSORTED_TAG, getImageGID(img)) removeTag(UNSORTED_TAG, getImageGID(img))
} }
}) })
.on('shiftedImages', function(evt, gids){ .on('shiftedImages', function(evt, gids){
if(UNSORTED_TAG != null){ if(UNSORTED_TAG != null && !isViewCropped()){
untagList(gids, UNSORTED_TAG) untagList(gids, UNSORTED_TAG)
} }
}) })
.on('aligningRibbonsSection', function(evt, base, gids){ .on('aligningRibbonsSection', function(evt, base, gids){
if(UNSORTED_TAG != null){ if(UNSORTED_TAG != null && !isViewCropped()){
untagList(gids, UNSORTED_TAG) untagList(gids, UNSORTED_TAG)
} }
}) })