2013-05-17 06:57:35 +04:00
|
|
|
/**********************************************************************
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
**********************************************************************/
|
|
|
|
|
|
|
|
|
|
//var DEBUG = DEBUG != null ? DEBUG : true
|
|
|
|
|
|
2013-12-20 06:37:08 +04:00
|
|
|
// NOTE: this must be sorted in the same order as DATA.order
|
2013-12-15 18:56:21 +04:00
|
|
|
var MARKED = []
|
|
|
|
|
|
2013-12-13 03:39:23 +04:00
|
|
|
var MARKED_FILE_DEFAULT = 'marked.json'
|
|
|
|
|
var MARKED_FILE_PATTERN = /^[0-9]*-marked.json$/
|
|
|
|
|
|
2013-05-17 06:57:35 +04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************************
|
2013-05-18 01:16:56 +04:00
|
|
|
* helpers...
|
2013-05-17 06:57:35 +04:00
|
|
|
*/
|
|
|
|
|
|
2013-12-04 23:18:23 +04:00
|
|
|
function _addMark(cls, gid, image){
|
|
|
|
|
gid = gid == null ? getImageGID() : gid
|
|
|
|
|
image = image == null ? getImage() : $(image)
|
|
|
|
|
|
2013-12-13 06:36:40 +04:00
|
|
|
// no image is loaded...
|
|
|
|
|
if(image.length == 0){
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-04 23:18:23 +04:00
|
|
|
var mark = $('.mark.'+cls+'.'+gid)
|
|
|
|
|
|
|
|
|
|
if(mark.length == 0){
|
2013-12-13 03:39:23 +04:00
|
|
|
mark = $('<div class="mark"/>')
|
2013-12-04 23:18:23 +04:00
|
|
|
.addClass(gid)
|
2013-12-13 03:39:23 +04:00
|
|
|
.addClass(cls)
|
2013-12-04 23:18:23 +04:00
|
|
|
.insertAfter(image)
|
|
|
|
|
}
|
|
|
|
|
return mark
|
|
|
|
|
}
|
|
|
|
|
function _removeMark(cls, gid, image){
|
|
|
|
|
gid = gid == null ? getImageGID() : gid
|
|
|
|
|
image = image == null ? getImage() : $(image)
|
|
|
|
|
|
2013-12-13 06:36:40 +04:00
|
|
|
// no image is loaded...
|
|
|
|
|
if(image.length == 0){
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-04 23:18:23 +04:00
|
|
|
var mark = $('.mark.'+cls+'.'+gid)
|
|
|
|
|
|
|
|
|
|
if(mark.length != 0){
|
|
|
|
|
mark.detach()
|
|
|
|
|
}
|
|
|
|
|
return mark
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2013-12-16 01:49:47 +04:00
|
|
|
var getMarkedGIDBefore = makeGIDBeforeGetterFromList(
|
|
|
|
|
function(){
|
|
|
|
|
return MARKED
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
2013-12-12 19:35:13 +04:00
|
|
|
// Make a mark toggler
|
|
|
|
|
//
|
|
|
|
|
// The toggler will:
|
|
|
|
|
// - toggle img_class on the target image
|
|
|
|
|
// - add/remove a mark element after the image
|
|
|
|
|
// - toggle mark_class on the mark element
|
2013-12-17 21:26:57 +04:00
|
|
|
// - call the callback, if defined, passing it:
|
|
|
|
|
// - gid
|
2013-12-18 05:09:47 +04:00
|
|
|
// - action ('on' or 'off')
|
2013-12-12 19:35:13 +04:00
|
|
|
// - trigger the evt_name on the viewer passing it:
|
2013-12-17 21:26:57 +04:00
|
|
|
// - gid
|
2013-12-18 05:09:47 +04:00
|
|
|
// - action ('on' or 'off')
|
2013-12-12 19:35:13 +04:00
|
|
|
//
|
|
|
|
|
// The actual toggler is built with createCSSClassToggler(..), see its
|
|
|
|
|
// docs for protocol descrittion.
|
|
|
|
|
//
|
2013-12-18 05:09:47 +04:00
|
|
|
// The resulting toggler, by default, marks the current image
|
2013-12-12 19:35:13 +04:00
|
|
|
// (.current.image), but can be passed a different image as first
|
|
|
|
|
// argument.
|
|
|
|
|
//
|
|
|
|
|
// NOTE: when passing an alternative image as an argument, the second
|
|
|
|
|
// argument MUST also be passed. it can be one of:
|
|
|
|
|
// - 'on' : force create mark
|
|
|
|
|
// - 'off' : force remove mark
|
|
|
|
|
// - 'next' : toggle next state (default)
|
2013-12-13 06:36:40 +04:00
|
|
|
// NOTE: when passing this a gid, the 'next' action is not supported
|
2013-12-17 21:26:57 +04:00
|
|
|
//
|
|
|
|
|
// XXX do we need a pre-callback here???
|
2013-12-17 21:16:10 +04:00
|
|
|
function makeMarkToggler(img_class, mark_class, evt_name, callback){
|
2013-12-11 02:47:44 +04:00
|
|
|
return createCSSClassToggler(
|
|
|
|
|
'.current.image',
|
|
|
|
|
img_class,
|
|
|
|
|
function(action, elem){
|
|
|
|
|
toggleMarkesView('on')
|
2013-12-13 06:36:40 +04:00
|
|
|
|
|
|
|
|
// we got a gid...
|
|
|
|
|
if(elem.length == 0 && elem.selector in IMAGES){
|
|
|
|
|
var gid = elem.selector
|
|
|
|
|
elem = getImage(gid)
|
|
|
|
|
elem = elem.length == 0 ? null : elem
|
|
|
|
|
|
|
|
|
|
// we are given an image...
|
2013-12-11 02:47:44 +04:00
|
|
|
} else {
|
2013-12-13 06:36:40 +04:00
|
|
|
var gid = getImageGID(elem)
|
2013-12-11 02:47:44 +04:00
|
|
|
}
|
2013-12-13 06:36:40 +04:00
|
|
|
|
|
|
|
|
// do this only of the image is loaded...
|
|
|
|
|
if(elem != null){
|
|
|
|
|
if(action == 'on'){
|
|
|
|
|
_addMark(mark_class, gid, elem)
|
|
|
|
|
} else {
|
|
|
|
|
_removeMark(mark_class, gid, elem)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-17 21:26:57 +04:00
|
|
|
if(callback != null){
|
|
|
|
|
callback(gid, action)
|
|
|
|
|
}
|
2013-12-17 21:16:10 +04:00
|
|
|
|
2013-12-13 06:36:40 +04:00
|
|
|
$('.viewer').trigger(evt_name, [gid, action])
|
2013-12-11 02:47:44 +04:00
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2013-12-14 04:29:51 +04:00
|
|
|
// generate an image updater function...
|
|
|
|
|
//
|
|
|
|
|
// the resulting function will update image mark state by adding or
|
|
|
|
|
// removing the mark the specific mark object.
|
2013-12-13 03:39:23 +04:00
|
|
|
function makeMarkUpdater(img_class, mark_class, test){
|
2013-12-14 06:58:13 +04:00
|
|
|
var _updater = function(gid, image){
|
2013-12-13 03:39:23 +04:00
|
|
|
// marks...
|
|
|
|
|
if(test(gid)){
|
|
|
|
|
image.addClass(img_class)
|
|
|
|
|
_addMark(mark_class, gid, image)
|
|
|
|
|
} else {
|
|
|
|
|
image.removeClass(img_class)
|
|
|
|
|
_removeMark(mark_class, gid, image)
|
|
|
|
|
}
|
|
|
|
|
return image
|
|
|
|
|
}
|
2013-12-14 06:58:13 +04:00
|
|
|
IMAGE_UPDATERS.push(_updater)
|
|
|
|
|
return _updater
|
2013-12-13 03:39:23 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2013-12-17 21:26:57 +04:00
|
|
|
|
2013-12-13 03:39:23 +04:00
|
|
|
/**********************************************************************
|
2013-12-18 05:09:47 +04:00
|
|
|
*
|
2013-12-13 03:39:23 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
var updateSelectedImageMark = makeMarkUpdater(
|
|
|
|
|
'marked',
|
|
|
|
|
'selected',
|
|
|
|
|
function(gid){
|
|
|
|
|
return MARKED.indexOf(gid) > -1
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
2013-05-24 19:35:03 +04:00
|
|
|
// NOTE: to disable MARKED cleanout set no_cleanout_marks to true.
|
|
|
|
|
// NOTE: MARKED may contain both gids that are not loaded and that do
|
|
|
|
|
// not exist, as there is no way to distinguish between the two
|
|
|
|
|
// situations the cleanup is optional...
|
2013-12-20 06:10:45 +04:00
|
|
|
function cropMarkedImages(keep_ribbons, keep_unloaded_gids){
|
2013-12-21 09:49:15 +04:00
|
|
|
var marked = MARKED.slice()
|
2013-08-08 23:19:28 +04:00
|
|
|
|
2013-12-15 03:38:15 +04:00
|
|
|
cropDataTo(marked, keep_ribbons, keep_unloaded_gids)
|
2013-06-16 02:42:29 +04:00
|
|
|
|
2013-05-17 06:57:35 +04:00
|
|
|
return DATA
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2013-05-18 01:16:56 +04:00
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
|
|
|
* Modes
|
|
|
|
|
*/
|
|
|
|
|
|
2013-08-08 23:19:28 +04:00
|
|
|
// XXX is this a mode???
|
2013-09-21 05:47:54 +04:00
|
|
|
var toggleMarkedOnlyView = makeCropModeToggler(
|
|
|
|
|
'marked-only-view',
|
|
|
|
|
cropMarkedImages)
|
2013-05-17 06:57:35 +04:00
|
|
|
|
|
|
|
|
|
2013-11-16 02:21:07 +04:00
|
|
|
var toggleMarkedOnlyWithRibbonsView = makeCropModeToggler(
|
|
|
|
|
'marked-only-view',
|
|
|
|
|
function(){
|
2013-12-20 06:10:45 +04:00
|
|
|
cropMarkedImages(true)
|
2013-11-16 02:21:07 +04:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
2013-05-17 06:57:35 +04:00
|
|
|
// XXX shifting images and unmarking in this mode do not work correctly...
|
2013-06-03 21:10:42 +04:00
|
|
|
var toggleMarkesView = createCSSClassToggler(
|
|
|
|
|
'.viewer',
|
|
|
|
|
'marks-visible',
|
2013-05-17 06:57:35 +04:00
|
|
|
function(){
|
2013-05-28 21:59:38 +04:00
|
|
|
var cur = getImage()
|
2013-05-17 06:57:35 +04:00
|
|
|
// current is marked...
|
|
|
|
|
if(cur.hasClass('marked')){
|
|
|
|
|
centerView(null, 'css')
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
// there is a marked image in this ribbon...
|
|
|
|
|
var target = getImageBefore(cur, null)
|
|
|
|
|
if(target.length > 0){
|
|
|
|
|
centerView(focusImage(target), 'css')
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
// get marked image from other ribbons...
|
|
|
|
|
prevRibbon()
|
2013-05-28 21:59:38 +04:00
|
|
|
if(getImage().hasClass('marked')){
|
2013-05-17 06:57:35 +04:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
nextRibbon()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
2013-05-17 06:59:04 +04:00
|
|
|
|
2013-05-17 06:57:35 +04:00
|
|
|
/**********************************************************************
|
|
|
|
|
* Actions
|
|
|
|
|
*/
|
|
|
|
|
|
2013-12-17 21:16:10 +04:00
|
|
|
var toggleMark = makeMarkToggler(
|
|
|
|
|
'marked',
|
|
|
|
|
'selected',
|
|
|
|
|
'togglingMark',
|
|
|
|
|
function(gid, action){
|
|
|
|
|
// add marked image to list...
|
|
|
|
|
if(action == 'on'){
|
|
|
|
|
if(MARKED.indexOf(gid) == -1){
|
2013-12-18 06:06:34 +04:00
|
|
|
insertGIDToPosition(gid, MARKED)
|
2013-12-17 21:16:10 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// remove marked image from list...
|
|
|
|
|
} else {
|
|
|
|
|
MARKED.splice(MARKED.indexOf(gid), 1)
|
|
|
|
|
}
|
2013-12-24 05:23:51 +04:00
|
|
|
|
|
|
|
|
marksUpdated()
|
2013-12-17 21:16:10 +04:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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){
|
2013-12-21 09:49:15 +04:00
|
|
|
//insertGIDToPosition(e, MARKED)
|
|
|
|
|
MARKED.push(e)
|
2013-12-17 21:16:10 +04:00
|
|
|
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)
|
|
|
|
|
|
2013-12-21 09:49:15 +04:00
|
|
|
MARKED = fastSortGIDsByOrder(MARKED)
|
|
|
|
|
|
2013-12-17 21:16:10 +04:00
|
|
|
updateImages(updated)
|
2013-05-17 06:57:35 +04:00
|
|
|
|
2013-12-17 21:16:10 +04:00
|
|
|
$('.viewer').trigger('togglingMarks', [updated, action])
|
|
|
|
|
|
2013-12-24 05:23:51 +04:00
|
|
|
marksUpdated()
|
|
|
|
|
|
2013-12-17 21:16:10 +04:00
|
|
|
return res
|
|
|
|
|
}
|
2013-05-17 06:57:35 +04:00
|
|
|
|
|
|
|
|
// mode can be:
|
|
|
|
|
// - 'ribbon'
|
|
|
|
|
// - 'all'
|
|
|
|
|
function removeImageMarks(mode){
|
2013-12-17 21:16:10 +04:00
|
|
|
mode = mode == null ? 'ribbon' : mode
|
|
|
|
|
var res = toggleAllMarks('off', mode)
|
|
|
|
|
$('.viewer').trigger('removingMarks', [res, mode])
|
2013-05-31 20:10:23 +04:00
|
|
|
return res
|
2013-05-17 06:57:35 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function markAll(mode){
|
2013-12-17 21:16:10 +04:00
|
|
|
mode = mode == null ? 'ribbon' : mode
|
|
|
|
|
var res = toggleAllMarks('on', mode)
|
|
|
|
|
$('.viewer').trigger('addingMarks', [res, mode])
|
2013-05-31 20:10:23 +04:00
|
|
|
return res
|
2013-05-17 06:57:35 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// NOTE: this only does it's work in the current ribbon...
|
|
|
|
|
function invertImageMarks(){
|
2013-12-17 21:16:10 +04:00
|
|
|
var ribbon = getRibbonGIDs()
|
|
|
|
|
var on = []
|
|
|
|
|
var off = []
|
|
|
|
|
|
|
|
|
|
$.each(ribbon, function(_, e){
|
|
|
|
|
var i = MARKED.indexOf(e)
|
|
|
|
|
if(i == -1){
|
|
|
|
|
on.push(e)
|
2013-12-21 09:49:15 +04:00
|
|
|
MARKED.push(e)
|
|
|
|
|
//insertGIDToPosition(e, MARKED)
|
2013-12-17 21:16:10 +04:00
|
|
|
} else {
|
|
|
|
|
off.push(e)
|
|
|
|
|
MARKED.splice(i, 1)
|
|
|
|
|
}
|
|
|
|
|
})
|
2013-12-21 09:49:15 +04:00
|
|
|
MARKED = fastSortGIDsByOrder(MARKED)
|
2013-12-17 21:16:10 +04:00
|
|
|
updateImages(ribbon)
|
|
|
|
|
|
|
|
|
|
$('.viewer')
|
|
|
|
|
.trigger('invertingMarks', [ribbon])
|
|
|
|
|
.trigger('togglingMarks', [on, 'on'])
|
|
|
|
|
.trigger('togglingMarks', [off, 'off'])
|
|
|
|
|
|
2013-12-24 05:23:51 +04:00
|
|
|
marksUpdated()
|
|
|
|
|
|
2013-12-17 21:16:10 +04:00
|
|
|
return on.concat(off)
|
2013-05-17 06:57:35 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Toggle marks in the current continuous section of marked or unmarked
|
|
|
|
|
// images...
|
2013-12-14 06:29:22 +04:00
|
|
|
function toggleMarkBlock(image){
|
2013-12-17 21:16:10 +04:00
|
|
|
image = image == null ? getImage() : image
|
|
|
|
|
var gid = typeof(image) == typeof('str') ? image : getImageGID(image)
|
|
|
|
|
image = typeof(image) == typeof('str') ? getImage(gid) : image
|
|
|
|
|
|
|
|
|
|
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){
|
2013-12-21 09:49:15 +04:00
|
|
|
//insertGIDToPosition(e, MARKED)
|
|
|
|
|
MARKED.push(e)
|
2013-12-17 21:16:10 +04:00
|
|
|
} else {
|
|
|
|
|
MARKED.splice(MARKED.indexOf(e), 1)
|
2013-05-17 06:57:35 +04:00
|
|
|
}
|
2013-12-17 21:16:10 +04:00
|
|
|
updated.push(e)
|
2013-05-17 06:57:35 +04:00
|
|
|
}
|
2013-12-13 06:36:40 +04:00
|
|
|
|
2013-12-17 21:16:10 +04:00
|
|
|
// go left...
|
|
|
|
|
var left = ribbon.slice(0, i)
|
|
|
|
|
left.reverse()
|
|
|
|
|
$.each(left, _convert)
|
|
|
|
|
|
|
|
|
|
// go right...
|
|
|
|
|
var right = ribbon.slice(i+1)
|
|
|
|
|
$.each(right, _convert)
|
|
|
|
|
|
2013-12-21 09:49:15 +04:00
|
|
|
MARKED = fastSortGIDsByOrder(MARKED)
|
|
|
|
|
|
2013-12-17 21:16:10 +04:00
|
|
|
updateImages(updated)
|
|
|
|
|
|
|
|
|
|
$('.viewer')
|
|
|
|
|
.trigger('togglingImageBlockMarks', [image, updated, state])
|
|
|
|
|
.trigger('togglingMarks', [updated, state ? 'on' : 'off'])
|
2013-12-13 06:36:40 +04:00
|
|
|
|
2013-12-24 05:23:51 +04:00
|
|
|
marksUpdated()
|
|
|
|
|
|
2013-05-17 06:57:35 +04:00
|
|
|
return state
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2013-06-03 00:01:49 +04:00
|
|
|
// XXX need to account for empty ribbons...
|
|
|
|
|
function shiftMarkedImages(direction, mode, new_ribbon){
|
|
|
|
|
mode = mode == null ? 'ribbon' : mode
|
|
|
|
|
var cur = getRibbonIndex()
|
2013-12-17 04:55:02 +04:00
|
|
|
var orig_ribbon = cur
|
2013-06-03 00:01:49 +04:00
|
|
|
|
|
|
|
|
// ribbon only...
|
|
|
|
|
if(mode == 'ribbon'){
|
|
|
|
|
var ribbon = DATA.ribbons[cur]
|
2013-12-28 06:17:05 +04:00
|
|
|
// remove all the marked images form the current ribbon...
|
|
|
|
|
// NOTE: this builds a list of marked images ONLY in current
|
|
|
|
|
// ribbon...
|
2013-06-03 00:01:49 +04:00
|
|
|
var marked = $.map(MARKED, function(e){
|
|
|
|
|
var i = ribbon.indexOf(e)
|
|
|
|
|
if(i >= 0){
|
|
|
|
|
ribbon.splice(i, 1)
|
|
|
|
|
return e
|
|
|
|
|
}
|
|
|
|
|
return null
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// shift all marked images...
|
|
|
|
|
} else {
|
|
|
|
|
var marked = MARKED.slice()
|
2013-12-21 09:49:15 +04:00
|
|
|
// remove all the marked images form all other ribbons...
|
2013-06-03 00:01:49 +04:00
|
|
|
$.each(DATA.ribbons, function(ribbon){
|
|
|
|
|
$.each(marked, function(e){
|
|
|
|
|
var i = ribbon.indexOf(e)
|
|
|
|
|
i >= 0 ? ribbon.splice(i, 1) : null
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if we are at the top or bottom ribbons we need to create a new
|
|
|
|
|
// ribbon regardless...
|
|
|
|
|
if((cur == 0 && direction == 'prev')
|
|
|
|
|
|| (cur == DATA.ribbons.length-1 && direction == 'next')){
|
|
|
|
|
new_ribbon = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// add marked to new ribbon...
|
|
|
|
|
if(new_ribbon){
|
|
|
|
|
cur += direction == 'next' ? 1 : 0
|
|
|
|
|
DATA.ribbons.splice(cur, 0, marked)
|
|
|
|
|
|
|
|
|
|
// add marked to existing ribbon...
|
|
|
|
|
} else {
|
|
|
|
|
cur += direction == 'next' ? 1 : -1
|
2013-12-21 09:49:15 +04:00
|
|
|
DATA.ribbons[cur] = fastSortGIDsByOrder(DATA.ribbons[cur].concat(marked))
|
2013-06-03 00:01:49 +04:00
|
|
|
}
|
|
|
|
|
|
2013-12-28 06:17:05 +04:00
|
|
|
// remove empty ribbons and reload...
|
|
|
|
|
dropEmptyRibbons()
|
|
|
|
|
reloadViewer()
|
2013-12-17 04:55:02 +04:00
|
|
|
|
|
|
|
|
$('.viewer').trigger('shiftedImages', [marked, orig_ribbon, cur])
|
2013-06-03 00:01:49 +04:00
|
|
|
}
|
|
|
|
|
function shiftMarkedImagesUp(mode, new_ribbon){
|
|
|
|
|
return shiftMarkedImages('prev', mode, new_ribbon)
|
|
|
|
|
}
|
|
|
|
|
function shiftMarkedImagesDown(mode, new_ribbon){
|
|
|
|
|
return shiftMarkedImages('next', mode, new_ribbon)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// XXX these are ribbon wise only (???)
|
|
|
|
|
// XXX this on first step this must pack all marked images
|
|
|
|
|
function horizontalShiftMarkedImages(direction){
|
2013-06-03 04:09:32 +04:00
|
|
|
// XXX
|
2013-06-03 00:01:49 +04:00
|
|
|
}
|
|
|
|
|
function shiftMarkedImagesLeft(){
|
2013-12-17 04:37:20 +04:00
|
|
|
return horizontalShiftMarkedImages('prev')
|
2013-06-03 00:01:49 +04:00
|
|
|
}
|
|
|
|
|
function shiftMarkedImagesRight(){
|
2013-12-17 04:37:20 +04:00
|
|
|
return horizontalShiftMarkedImages('next')
|
2013-06-03 00:01:49 +04:00
|
|
|
}
|
|
|
|
|
|
2013-05-17 06:57:35 +04:00
|
|
|
|
2013-12-16 01:49:47 +04:00
|
|
|
// focus next/prev mark...
|
|
|
|
|
//
|
|
|
|
|
// NOTE: these will not jump to marks on other ribbons... to prevent this
|
|
|
|
|
// add true as the final argument (see restrict_to_ribbon argument
|
|
|
|
|
// of makeNextFromListAction(..) for more info)
|
|
|
|
|
var nextMark = makeNextFromListAction(
|
|
|
|
|
getMarkedGIDBefore,
|
|
|
|
|
function(){ return MARKED })
|
|
|
|
|
var prevMark = makePrevFromListAction(
|
|
|
|
|
getMarkedGIDBefore,
|
|
|
|
|
function(){ return MARKED })
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-05-17 06:57:35 +04:00
|
|
|
|
2013-12-05 03:58:13 +04:00
|
|
|
/**********************************************************************
|
|
|
|
|
* Dialogs...
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
function markImagesDialog(){
|
|
|
|
|
|
|
|
|
|
updateStatus('Mark...').show()
|
|
|
|
|
|
2013-12-05 05:55:14 +04:00
|
|
|
var alg = 'Mark images:'
|
2013-12-05 03:58:13 +04:00
|
|
|
|
2013-12-14 06:29:22 +04:00
|
|
|
var cur = toggleMark('?') == 'on' ? 'Unmark' : 'Mark'
|
2013-12-05 03:58:13 +04:00
|
|
|
|
|
|
|
|
cfg = {}
|
|
|
|
|
cfg[alg] = [
|
|
|
|
|
cur + ' current image',
|
|
|
|
|
cur + ' current block | '+
|
|
|
|
|
'A block is a set of similarly marked images\n'+
|
|
|
|
|
'to the left and right of the current image,\n'+
|
|
|
|
|
'up until the closest images marked differently',
|
|
|
|
|
'Invert marks in current ribbon',
|
|
|
|
|
'Mark all in current ribbon',
|
|
|
|
|
'Unmark all in current ribbon',
|
2013-12-17 21:16:10 +04:00
|
|
|
'Mark all images',
|
2013-12-05 03:58:13 +04:00
|
|
|
'Unmark all images'
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
formDialog(null, '',
|
|
|
|
|
cfg,
|
|
|
|
|
'OK',
|
|
|
|
|
'markImagesDialog')
|
|
|
|
|
.done(function(res){
|
|
|
|
|
res = res[alg]
|
|
|
|
|
|
|
|
|
|
// NOTE: these must be in order of least-specific last...
|
|
|
|
|
if(/current image/.test(res)){
|
2013-12-14 06:29:22 +04:00
|
|
|
toggleMark()
|
2013-12-05 03:58:13 +04:00
|
|
|
var msg = (cur + ' image').toLowerCase()
|
|
|
|
|
|
|
|
|
|
} else if(/current block/.test(res)){
|
2013-12-14 06:29:22 +04:00
|
|
|
toggleMarkBlock()
|
2013-12-05 03:58:13 +04:00
|
|
|
var msg = 'toggled block marks'
|
|
|
|
|
|
|
|
|
|
} else if(/Invert/.test(res)){
|
|
|
|
|
invertImageMarks()
|
|
|
|
|
var msg = 'inverted ribbon marks'
|
|
|
|
|
|
2013-12-17 21:16:10 +04:00
|
|
|
} else if(/Mark all.*current ribbon/.test(res)){
|
|
|
|
|
markAll()
|
|
|
|
|
var msg = 'marked ribbon'
|
|
|
|
|
|
2013-12-05 03:58:13 +04:00
|
|
|
} else if(/Mark all/.test(res)){
|
|
|
|
|
markAll()
|
|
|
|
|
var msg = 'marked ribbon'
|
|
|
|
|
|
|
|
|
|
} else if(/Unmark all in/.test(res)){
|
|
|
|
|
removeImageMarks('ribbon')
|
|
|
|
|
var msg = 'unmarked ribbon'
|
|
|
|
|
|
|
|
|
|
} else if(/Unmark all images/.test(res)){
|
|
|
|
|
removeImageMarks('all')
|
|
|
|
|
var msg = 'unmarked all'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
showStatusQ('Mark: '+msg+'...')
|
|
|
|
|
})
|
|
|
|
|
.fail(function(){
|
|
|
|
|
showStatusQ('Marking: canceled.')
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2013-12-14 05:07:57 +04:00
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
|
|
|
* Files...
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// Load image marks form file
|
|
|
|
|
//
|
|
|
|
|
// NOTE: if no marks are found then set them to []
|
|
|
|
|
var loadFileMarks = makeFileLoader(
|
|
|
|
|
'Marks',
|
|
|
|
|
MARKED_FILE_DEFAULT,
|
|
|
|
|
MARKED_FILE_PATTERN,
|
|
|
|
|
function(data){
|
2013-12-20 06:17:21 +04:00
|
|
|
// set the MARKED...
|
|
|
|
|
MARKED = data
|
|
|
|
|
|
2013-12-20 06:10:45 +04:00
|
|
|
// for version below 2.1, sort MARKED and update to 2.1...
|
|
|
|
|
if(DATA.version == '2.0'){
|
|
|
|
|
setTimeout(function(){
|
|
|
|
|
var t0 = Date.now()
|
2013-12-21 09:49:15 +04:00
|
|
|
MARKED = fastSortGIDsByOrder(MARKED)
|
2013-12-20 06:10:45 +04:00
|
|
|
var t1 = Date.now()
|
|
|
|
|
|
|
|
|
|
// XXX is this the correct way to do this???
|
|
|
|
|
DATA.version = DATA_VERSION
|
|
|
|
|
|
2013-12-20 06:37:08 +04:00
|
|
|
console.warn('Marks: sort: done ('+( t1 - t0 )+'ms) -- re-save the data.')
|
2013-12-20 06:10:45 +04:00
|
|
|
}, 0)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
'marksLoaded')
|
2013-12-14 05:07:57 +04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
// Save image marks to file
|
|
|
|
|
var saveFileMarks = makeFileSaver(
|
2013-12-24 05:23:51 +04:00
|
|
|
'Marks',
|
2013-12-14 05:07:57 +04:00
|
|
|
MARKED_FILE_DEFAULT,
|
|
|
|
|
function(){
|
|
|
|
|
return MARKED
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
2013-12-24 05:23:51 +04:00
|
|
|
function marksUpdated(){
|
|
|
|
|
fileUpdated('Marks')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2013-12-14 05:07:57 +04:00
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
|
|
|
* Setup...
|
|
|
|
|
*/
|
|
|
|
|
|
2013-12-12 19:35:13 +04:00
|
|
|
|
|
|
|
|
function setupMarks(viewer){
|
|
|
|
|
console.log('Marks: setup...')
|
2013-12-14 06:58:13 +04:00
|
|
|
|
|
|
|
|
// XXX make this viewer specific...
|
|
|
|
|
makeContextIndicatorUpdater('marked')
|
|
|
|
|
|
|
|
|
|
// XXX make these viewer specific...
|
|
|
|
|
showGlobalIndicator(
|
|
|
|
|
'marks-visible',
|
|
|
|
|
'Marks visible (F2)')
|
|
|
|
|
.click(function(){ toggleMarkesView() })
|
|
|
|
|
showGlobalIndicator(
|
|
|
|
|
'marked-only-visible',
|
|
|
|
|
'Marked only images visible (shift-F2)')
|
|
|
|
|
.click(function(){ toggleMarkedOnlyView() })
|
|
|
|
|
showContextIndicator(
|
|
|
|
|
'current-image-marked',
|
2013-12-15 02:55:05 +04:00
|
|
|
'Marked (Ins)')
|
2013-12-14 06:58:13 +04:00
|
|
|
.click(function(){ toggleMark() })
|
|
|
|
|
|
2013-12-12 19:35:13 +04:00
|
|
|
return viewer
|
2013-12-17 21:16:10 +04:00
|
|
|
// XXX do we actually need this???
|
|
|
|
|
.on('togglingMarks', function(evt, lst, action){
|
|
|
|
|
lst.forEach(function(gid){
|
|
|
|
|
viewer.trigger('togglingMark', [gid, action])
|
2013-12-12 19:35:13 +04:00
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
SETUP_BINDINGS.push(setupMarks)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-05-17 06:57:35 +04:00
|
|
|
/**********************************************************************
|
|
|
|
|
* vim:set ts=4 sw=4 : */
|