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( var toggleBookmark = makeMarkToggler(
'bookmarked', 'bookmarked',
'bookmark', '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... // focus next bookmark...
@ -132,23 +149,6 @@ function setupBookmarks(viewer){
.click(function(){ toggleBookmark() }) .click(function(){ toggleBookmark() })
return viewer 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(){ .on('sortedImages', function(){
BOOKMARKS.sort(imageOrderCmp) 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... // like getImageOrder(..) but use DATA...
// //
function getGIDOrder(gid){ function getGIDOrder(gid){
@ -1604,36 +1616,44 @@ function updateImage(image, gid, size, sync){
// Same as updateImage(...) but will update all loaded images. // 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... // NOTE: this will prioritize images by distance from current image...
// //
// XXX need to run this in the background... // XXX need to run this in the background...
function updateImages(size, cmp){ function updateImages(list, size, cmp){
var deferred = $.Deferred() var deferred = $.Deferred()
function _worker(){ function _worker(){
list = list == null ? $('.image') : $(list)
size = size == null ? getVisibleImageSize('max') : size 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... // sorted run...
if(CONFIG.update_sort_enabled && cmp != false){ if(CONFIG.update_sort_enabled && cmp != false){
cmp = cmp == null ? 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... // XXX this is more correct but is slow...
//makeGIDRibbonDistanceCmp(getImageGID(), getImageGID) //makeGIDRibbonDistanceCmp(getImageGID(), getImageGID)
: cmp : cmp
deferred.resolve($('.image') deferred.resolve(list
// sort images by distance from current, so as to update what // sort images by distance from current, so as to update what
// the user is looking at first... // the user is looking at first...
.sort(cmp) .sort(cmp)
.each(function(){ .map(_update))
updateImage($(this), null, size)
}))
// do a fast run w.o. sorting images... // do a fast run w.o. sorting images...
} else { } else {
deferred.resolve($('.image') deferred.resolve(list.map(_update))
.each(function(){
updateImage($(this), null, size)
}))
} }
} }

View File

@ -83,7 +83,7 @@ var getMarkedGIDBefore = makeGIDBeforeGetterFromList(
// - 'off' : force remove mark // - 'off' : force remove mark
// - 'next' : toggle next state (default) // - 'next' : toggle next state (default)
// NOTE: when passing this a gid, the 'next' action is not supported // 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( return createCSSClassToggler(
'.current.image', '.current.image',
img_class, img_class,
@ -110,6 +110,8 @@ function makeMarkToggler(img_class, mark_class, evt_name){
} }
} }
callback(gid, action)
$('.viewer').trigger(evt_name, [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: // mode can be:
// - 'ribbon' // - 'ribbon'
// - 'all' // - 'all'
function removeImageMarks(mode){ function removeImageMarks(mode){
// remove marks from current ribbon (default)... mode = mode == null ? 'ribbon' : mode
if(mode == 'ribbon' || mode == null){ var res = toggleAllMarks('off', mode)
var ribbon = getRibbon() $('.viewer').trigger('removingMarks', [res, mode])
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')
}
return res return res
} }
function markAll(mode){ function markAll(mode){
// current ribbon (default)... mode = mode == null ? 'ribbon' : mode
if(mode == 'ribbon' || mode == null){ var res = toggleAllMarks('on', mode)
var ribbon = getRibbon() $('.viewer').trigger('addingMarks', [res, mode])
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')
}
return res return res
} }
// NOTE: this only does it's work in the current ribbon... // NOTE: this only does it's work in the current ribbon...
function invertImageMarks(){ function invertImageMarks(){
var ribbon = getRibbon() var ribbon = getRibbonGIDs()
var res = ribbon var on = []
.find('.image') var off = []
.each(function(){
toggleMark(this, 'next') $.each(ribbon, function(_, e){
}) var i = MARKED.indexOf(e)
$('.viewer').trigger('invertingMarks', [ribbon]) if(i == -1){
return res 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 need to make this dynamic data compatible...
// XXX this will mark the block ONLY IF it is loaded!!! // XXX this will mark the block ONLY IF it is loaded!!!
function toggleMarkBlock(image){ function toggleMarkBlock(image){
if(image == null){ image = image == null ? getImage() : image
image = getImage() var gid = typeof(image) == typeof('str') ? image : getImageGID(image)
} image = typeof(image) == typeof('str') ? getImage(gid) : image
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))
$('.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 return state
} }
@ -424,6 +492,7 @@ function markImagesDialog(){
'Invert marks in current ribbon', 'Invert marks in current ribbon',
'Mark all in current ribbon', 'Mark all in current ribbon',
'Unmark all in current ribbon', 'Unmark all in current ribbon',
'Mark all images',
'Unmark all images' 'Unmark all images'
] ]
@ -447,6 +516,10 @@ function markImagesDialog(){
invertImageMarks() invertImageMarks()
var msg = 'inverted ribbon marks' var msg = 'inverted ribbon marks'
} else if(/Mark all.*current ribbon/.test(res)){
markAll()
var msg = 'marked ribbon'
} else if(/Mark all/.test(res)){ } else if(/Mark all/.test(res)){
markAll() markAll()
var msg = 'marked ribbon' var msg = 'marked ribbon'
@ -520,92 +593,10 @@ function setupMarks(viewer){
.click(function(){ toggleMark() }) .click(function(){ toggleMark() })
return viewer return viewer
// marks... // XXX do we actually need this???
.on('togglingMark', function(evt, gid, action){ .on('togglingMarks', function(evt, lst, action){
// add marked image to list... lst.forEach(function(gid){
if(action == 'on'){ viewer.trigger('togglingMark', [gid, action])
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)
}
}) })
}) })
} }