From b0651a3f7ab5d28bbdc97e0b88d2ab8f006659b9 Mon Sep 17 00:00:00 2001 From: "Alex A. Naanou" Date: Tue, 17 Dec 2013 21:16:10 +0400 Subject: [PATCH] refactored and simplified marks.js... Signed-off-by: Alex A. Naanou --- ui/bookmarks.js | 36 +++--- ui/data.js | 40 +++++-- ui/marks.js | 299 +++++++++++++++++++++++------------------------- 3 files changed, 193 insertions(+), 182 deletions(-) diff --git a/ui/bookmarks.js b/ui/bookmarks.js index c26dde02..45551f1b 100755 --- a/ui/bookmarks.js +++ b/ui/bookmarks.js @@ -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) }) diff --git a/ui/data.js b/ui/data.js index dc6730d5..182a87ad 100755 --- a/ui/data.js +++ b/ui/data.js @@ -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)) } } diff --git a/ui/marks.js b/ui/marks.js index eb992c57..e8ecfb55 100755 --- a/ui/marks.js +++ b/ui/marks.js @@ -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]) }) }) }