refactored and simplified marks.js...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2013-12-17 21:16:10 +04:00
parent c67c84aeeb
commit b0651a3f7a
3 changed files with 193 additions and 182 deletions

View File

@ -73,7 +73,24 @@ var toggleBookmarkedOnlyWithRibbonsView = makeCropModeToggler(
var toggleBookmark = makeMarkToggler(
'bookmarked',
'bookmark',
'togglingBookmark')
'togglingBookmark',
function(gid, action){
// add a bookmark...
if(action == 'on'){
if(BOOKMARKS.indexOf(gid) == -1){
BOOKMARKS.push(gid)
// XXX is this too expensive???
// ...a way to avoid sorting is to:
// BOOKMARKS.splice(
// getGIDBefore(gid, BOOKMARKS)+1, 0, gid)
BOOKMARKS.sort(imageOrderCmp)
}
// remove a bookmark...
} else {
BOOKMARKS.splice(BOOKMARKS.indexOf(gid), 1)
}
})
// focus next bookmark...
@ -132,23 +149,6 @@ function setupBookmarks(viewer){
.click(function(){ toggleBookmark() })
return viewer
.on('togglingBookmark', function(evt, gid, action){
// add a bookmark...
if(action == 'on'){
if(BOOKMARKS.indexOf(gid) == -1){
BOOKMARKS.push(gid)
// XXX is this too expensive???
// ...a way to avoid sorting is to:
// BOOKMARKS.splice(
// getGIDBefore(gid, BOOKMARKS)+1, 0, gid)
BOOKMARKS.sort(imageOrderCmp)
}
// remove a bookmark...
} else {
BOOKMARKS.splice(BOOKMARKS.indexOf(gid), 1)
}
})
.on('sortedImages', function(){
BOOKMARKS.sort(imageOrderCmp)
})

View File

@ -570,6 +570,18 @@ function getRibbonGIDs(a, data){
}
// get all the currently loaded gids...
//
function getLoadedGIDs(data){
data = data == null ? DATA : data
var res = []
data.ribbons.forEach(function(r){
res = res.concat(r)
})
return res
}
// like getImageOrder(..) but use DATA...
//
function getGIDOrder(gid){
@ -1604,36 +1616,44 @@ function updateImage(image, gid, size, sync){
// Same as updateImage(...) but will update all loaded images.
//
// If list is passed this will update only the images in the list. The
// list can contain either gids or image elements.
//
// NOTE: this will prioritize images by distance from current image...
//
// XXX need to run this in the background...
function updateImages(size, cmp){
function updateImages(list, size, cmp){
var deferred = $.Deferred()
function _worker(){
list = list == null ? $('.image') : $(list)
size = size == null ? getVisibleImageSize('max') : size
function _update(_, e){
var img = typeof(e) == typeof('str') ? getImage(e) : $(e)
if(img.length > 0){
updateImage(img, null, size)
}
}
// sorted run...
if(CONFIG.update_sort_enabled && cmp != false){
cmp = cmp == null ?
makeGIDDistanceCmp(getImageGID(), getImageGID)
makeGIDDistanceCmp(getImageGID(), function(e){
return typeof(e) == typeof('str') ? e : getImageGID(e)
})
// XXX this is more correct but is slow...
//makeGIDRibbonDistanceCmp(getImageGID(), getImageGID)
: cmp
deferred.resolve($('.image')
deferred.resolve(list
// sort images by distance from current, so as to update what
// the user is looking at first...
.sort(cmp)
.each(function(){
updateImage($(this), null, size)
}))
.map(_update))
// do a fast run w.o. sorting images...
} else {
deferred.resolve($('.image')
.each(function(){
updateImage($(this), null, size)
}))
deferred.resolve(list.map(_update))
}
}

View File

@ -83,7 +83,7 @@ var getMarkedGIDBefore = makeGIDBeforeGetterFromList(
// - 'off' : force remove mark
// - 'next' : toggle next state (default)
// NOTE: when passing this a gid, the 'next' action is not supported
function makeMarkToggler(img_class, mark_class, evt_name){
function makeMarkToggler(img_class, mark_class, evt_name, callback){
return createCSSClassToggler(
'.current.image',
img_class,
@ -110,6 +110,8 @@ function makeMarkToggler(img_class, mark_class, evt_name){
}
}
callback(gid, action)
$('.viewer').trigger(evt_name, [gid, action])
})
}
@ -212,68 +214,115 @@ var toggleMarkesView = createCSSClassToggler(
*/
var toggleMark = makeMarkToggler('marked', 'selected', 'togglingMark')
var toggleMark = makeMarkToggler(
'marked',
'selected',
'togglingMark',
function(gid, action){
// add marked image to list...
if(action == 'on'){
if(MARKED.indexOf(gid) == -1){
MARKED.push(gid)
MARKED.sort(imageOrderCmp)
}
// remove marked image from list...
} else {
MARKED.splice(MARKED.indexOf(gid), 1)
}
})
function toggleAllMarks(action, mode){
action = action == null ? toggleMark('?') : action
mode = mode == null ? 'ribbon' : mode
var updated = []
if(action == 'on'){
var _update = function(e){
if(MARKED.indexOf(e) < 0){
MARKED.push(e)
updated.push(e)
}
}
} else {
var _update = function(e){
var i = MARKED.indexOf(e)
if(i >= 0){
MARKED.splice(i, 1)
updated.push(e)
}
}
}
// marks from current ribbon (default)...
if(mode == 'ribbon'){
var res = getRibbonGIDs()
// all marks...
} else if(mode == 'all'){
var res = getLoadedGIDs()
}
res.forEach(_update)
if(action == 'on'){
MARKED.sort(imageOrderCmp)
}
updateImages(updated)
$('.viewer').trigger('togglingMarks', [updated, action])
return res
}
// mode can be:
// - 'ribbon'
// - 'all'
function removeImageMarks(mode){
// remove marks from current ribbon (default)...
if(mode == 'ribbon' || mode == null){
var ribbon = getRibbon()
var res = ribbon
.find('.marked')
.each(function(){
toggleMark(this, 'off')
})
$('.viewer').trigger('removeingRibbonMarks', [ribbon])
// remove all marks...
} else if(mode == 'all'){
var res = $('.marked')
.each(function(){
toggleMark(this, 'off')
})
$('.viewer').trigger('removeingAllMarks')
}
mode = mode == null ? 'ribbon' : mode
var res = toggleAllMarks('off', mode)
$('.viewer').trigger('removingMarks', [res, mode])
return res
}
function markAll(mode){
// current ribbon (default)...
if(mode == 'ribbon' || mode == null){
var ribbon = getRibbon()
var res = ribbon
.find('.image:not(.marked)')
.each(function(){
toggleMark(this, 'on')
})
$('.viewer').trigger('markingRibbon', [ribbon])
// mark everything...
} else if(mode == 'all'){
var res = $('.image:not(.marked)')
.each(function(){
toggleMark(this, 'on')
})
$('.viewer').trigger('markingAll')
}
mode = mode == null ? 'ribbon' : mode
var res = toggleAllMarks('on', mode)
$('.viewer').trigger('addingMarks', [res, mode])
return res
}
// NOTE: this only does it's work in the current ribbon...
function invertImageMarks(){
var ribbon = getRibbon()
var res = ribbon
.find('.image')
.each(function(){
toggleMark(this, 'next')
})
$('.viewer').trigger('invertingMarks', [ribbon])
return res
var ribbon = getRibbonGIDs()
var on = []
var off = []
$.each(ribbon, function(_, e){
var i = MARKED.indexOf(e)
if(i == -1){
on.push(e)
MARKED.push(e)
MARKED.sort(imageOrderCmp)
} else {
off.push(e)
MARKED.splice(i, 1)
}
})
updateImages(ribbon)
$('.viewer')
.trigger('invertingMarks', [ribbon])
.trigger('togglingMarks', [on, 'on'])
.trigger('togglingMarks', [off, 'off'])
return on.concat(off)
}
@ -282,29 +331,48 @@ function invertImageMarks(){
// XXX need to make this dynamic data compatible...
// XXX this will mark the block ONLY IF it is loaded!!!
function toggleMarkBlock(image){
if(image == null){
image = getImage()
}
var found = [false, false]
// we need to invert this...
var state = toggleMark()
var _convert = function(i){
return function(){
if(toggleMark(this, '?') == state){
// we found the end...
// NOTE: this will not be set if we reached the end of
// the ribbon or the end of the loaded images...
found[i] = true
// stop the iteration...
return false
}
toggleMark(this, state)
}
}
image.nextAll('.image').each(_convert(1))
image.prevAll('.image').each(_convert(0))
image = image == null ? getImage() : image
var gid = typeof(image) == typeof('str') ? image : getImageGID(image)
image = typeof(image) == typeof('str') ? getImage(gid) : image
$('.viewer').trigger('togglingImageBlockMarks', [image, state, found])
var state = toggleMark(image, 'next') == 'off' ? false : true
var ribbon = DATA.ribbons[getRibbonIndex(image)]
var i = ribbon.indexOf(gid)
var updated = [gid]
var _convert = function(_, e){
// break if state differs from current...
if((MARKED.indexOf(e) >= 0) == state){
return false
}
// do the toggle...
if(state){
MARKED.push(e)
} else {
MARKED.splice(MARKED.indexOf(e), 1)
}
updated.push(e)
}
// go left...
var left = ribbon.slice(0, i)
left.reverse()
$.each(left, _convert)
// go right...
var right = ribbon.slice(i+1)
$.each(right, _convert)
updateImages(updated)
if(state){
MARKED.sort(imageOrderCmp)
}
$('.viewer')
.trigger('togglingImageBlockMarks', [image, updated, state])
.trigger('togglingMarks', [updated, state ? 'on' : 'off'])
return state
}
@ -424,6 +492,7 @@ function markImagesDialog(){
'Invert marks in current ribbon',
'Mark all in current ribbon',
'Unmark all in current ribbon',
'Mark all images',
'Unmark all images'
]
@ -447,6 +516,10 @@ function markImagesDialog(){
invertImageMarks()
var msg = 'inverted ribbon marks'
} else if(/Mark all.*current ribbon/.test(res)){
markAll()
var msg = 'marked ribbon'
} else if(/Mark all/.test(res)){
markAll()
var msg = 'marked ribbon'
@ -520,92 +593,10 @@ function setupMarks(viewer){
.click(function(){ toggleMark() })
return viewer
// marks...
.on('togglingMark', function(evt, gid, action){
// add marked image to list...
if(action == 'on'){
if(MARKED.indexOf(gid) == -1){
MARKED.push(gid)
MARKED.sort(imageOrderCmp)
}
// remove marked image from list...
} else {
MARKED.splice(MARKED.indexOf(gid), 1)
}
})
.on('togglingImageBlockMarks', function(evt, img, state, found){
var gid = getImageGID(img)
var ribbon = DATA.ribbons[getRibbonIndex(img)]
var i = ribbon.indexOf(gid)
state = state == 'off' ? false : true
var _convert = function(_, e){
if(skipping && (MARKED.indexOf(e) >= 0) == state){
return
}
skipping = false
if((MARKED.indexOf(e) >= 0) == state){
return false
}
// do the toggle...
if(state){
MARKED.push(e)
MARKED.sort(imageOrderCmp)
} else {
MARKED.splice(MARKED.indexOf(e), 1)
}
}
// go left...
if(!found[0]){
var skipping = true
var left = ribbon.slice(0, i)
left.reverse()
$.each(left, _convert)
}
// go right...
if(!found[1]){
var skipping = true
var right = ribbon.slice(i)
$.each(right, _convert)
}
})
.on('removeingRibbonMarks', function(evt, ribbon){
$.each(DATA.ribbons[getRibbonIndex(ribbon)], function(_, e){
var i = MARKED.indexOf(e)
if(i != -1){
MARKED.splice(i, 1)
}
})
})
.on('removeingAllMarks', function(evt){
MARKED.splice(0, MARKED.length)
})
.on('markingRibbon', function(evt, ribbon){
$.each(DATA.ribbons[getRibbonIndex(ribbon)], function(_, e){
var i = MARKED.indexOf(e)
if(i == -1){
MARKED.push(e)
MARKED.sort(imageOrderCmp)
}
})
})
.on('markingAll', function(evt){
MARKED.splice(0, MARKED.length)
MARKED.concat(DATA.order)
})
.on('invertingMarks', function(evt, ribbon){
$.each(DATA.ribbons[getRibbonIndex(ribbon)], function(_, e){
var i = MARKED.indexOf(e)
if(i == -1){
MARKED.push(e)
MARKED.sort(imageOrderCmp)
} else {
MARKED.splice(i, 1)
}
// XXX do we actually need this???
.on('togglingMarks', function(evt, lst, action){
lst.forEach(function(gid){
viewer.trigger('togglingMark', [gid, action])
})
})
}