mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 18:30:09 +00:00
194 lines
4.1 KiB
JavaScript
194 lines
4.1 KiB
JavaScript
|
|
/**********************************************************************
|
||
|
|
*
|
||
|
|
* Ribbon Crop API
|
||
|
|
*
|
||
|
|
*
|
||
|
|
**********************************************************************/
|
||
|
|
|
||
|
|
var CROP_STACK = []
|
||
|
|
|
||
|
|
var CROP_MODES = []
|
||
|
|
|
||
|
|
|
||
|
|
/******************************************************* Crop Data ***/
|
||
|
|
|
||
|
|
function isViewCropped(){
|
||
|
|
return CROP_STACK.length != 0
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
function getAllData(){
|
||
|
|
if(!isViewCropped()){
|
||
|
|
return DATA
|
||
|
|
} else {
|
||
|
|
return CROP_STACK[0]
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// NOTE: this will not update .current state...
|
||
|
|
// NOTE: when keep_ribbons is set, this may generate empty ribbons...
|
||
|
|
//
|
||
|
|
// XXX should this set the .current to anything but null or the first elem???
|
||
|
|
function makeCroppedData(gids, keep_ribbons){
|
||
|
|
var res = {
|
||
|
|
varsion: '2.0',
|
||
|
|
current: null,
|
||
|
|
ribbons: [],
|
||
|
|
order: DATA.order.slice(),
|
||
|
|
}
|
||
|
|
|
||
|
|
// flat single ribbon crop...
|
||
|
|
if(!keep_ribbons){
|
||
|
|
res.ribbons[0] = gids
|
||
|
|
|
||
|
|
// keep the ribbon structure...
|
||
|
|
} else {
|
||
|
|
$.each(DATA.ribbons, function(_, e){
|
||
|
|
e = e.filter(function(ee){ return gids.indexOf(ee) >= 0 })
|
||
|
|
// skip empty ribbons...
|
||
|
|
if(e.length != 0){
|
||
|
|
res.ribbons.push(e)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
return res
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// NOTE: if keep_ribbons is not set this will ALWAYS build a single ribbon
|
||
|
|
// data-set...
|
||
|
|
function cropDataTo(gids, keep_ribbons){
|
||
|
|
var prev_state = DATA
|
||
|
|
var cur = DATA.current
|
||
|
|
var r = getRibbonIndex()
|
||
|
|
|
||
|
|
var new_data = makeCroppedData(gids, keep_ribbons)
|
||
|
|
|
||
|
|
// do nothing if there is no change...
|
||
|
|
// XXX is there a better way to compare states???
|
||
|
|
if(JSON.stringify(DATA.ribbons) == JSON.stringify(new_data.ribbons)){
|
||
|
|
return DATA
|
||
|
|
}
|
||
|
|
|
||
|
|
CROP_STACK.push(prev_state)
|
||
|
|
DATA = new_data
|
||
|
|
|
||
|
|
cur = getGIDBefore(cur, keep_ribbons ? r : 0)
|
||
|
|
cur = cur == null ? gids[0] : cur
|
||
|
|
DATA.current = cur
|
||
|
|
|
||
|
|
reloadViewer()
|
||
|
|
updateImages()
|
||
|
|
|
||
|
|
return prev_state
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
function uncropData(){
|
||
|
|
if(!isViewCropped()){
|
||
|
|
return DATA
|
||
|
|
}
|
||
|
|
var prev_state = DATA
|
||
|
|
var cur = DATA.current
|
||
|
|
|
||
|
|
DATA = CROP_STACK.pop()
|
||
|
|
|
||
|
|
// check if cur exists in data being loaded...
|
||
|
|
if($.map(DATA.ribbons,
|
||
|
|
function(e, i){ return e.indexOf(cur) >= 0 }).indexOf(true) >= 0){
|
||
|
|
// keep the current position...
|
||
|
|
DATA.current = cur
|
||
|
|
}
|
||
|
|
|
||
|
|
reloadViewer()
|
||
|
|
updateImages()
|
||
|
|
|
||
|
|
return prev_state
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
function showAllData(){
|
||
|
|
var prev_state = DATA
|
||
|
|
var cur = DATA.current
|
||
|
|
|
||
|
|
if(CROP_STACK.length != 0){
|
||
|
|
DATA = getAllData()
|
||
|
|
CROP_STACK = []
|
||
|
|
|
||
|
|
// XXX do we need to check if this exists???
|
||
|
|
// ...in theory, as long as there are no global destructive
|
||
|
|
// operations, no.
|
||
|
|
// keep the current position...
|
||
|
|
DATA.current = cur
|
||
|
|
|
||
|
|
reloadViewer()
|
||
|
|
updateImages()
|
||
|
|
}
|
||
|
|
|
||
|
|
return prev_state
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// Helpers for making crop modes and using crop...
|
||
|
|
|
||
|
|
// Make a generic crop mode toggler
|
||
|
|
//
|
||
|
|
// NOTE: This will add the toggler to CROP_MODES, for use by
|
||
|
|
// uncropLastState(...)
|
||
|
|
// NOTE: crop modes are exclusive -- it is not possible to enter one crop
|
||
|
|
// mode from a different crop mode
|
||
|
|
function makeCropModeToggler(cls, crop){
|
||
|
|
var res = createCSSClassToggler(
|
||
|
|
'.viewer',
|
||
|
|
//cls + ' cropped-mode',
|
||
|
|
cls,
|
||
|
|
function(action){
|
||
|
|
// prevent mixing marked-only and single-ribbon modes...
|
||
|
|
if(action == 'on'
|
||
|
|
&& isViewCropped()
|
||
|
|
&& res('?') != 'on'){
|
||
|
|
return false
|
||
|
|
}
|
||
|
|
},
|
||
|
|
function(action){
|
||
|
|
if(action == 'on'){
|
||
|
|
showStatusQ('Cropping current ribbon...')
|
||
|
|
crop()
|
||
|
|
} else {
|
||
|
|
showStatusQ('Uncropping to all data...')
|
||
|
|
showAllData()
|
||
|
|
}
|
||
|
|
})
|
||
|
|
CROP_MODES.push(res)
|
||
|
|
return res
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// Uncrop to last state and there is no states to uncrop then exit
|
||
|
|
// cropped mode.
|
||
|
|
//
|
||
|
|
// NOTE: this will exit all crop modes when uncropping the last step.
|
||
|
|
function uncropLastState(){
|
||
|
|
// do nothing if we aren't in a crop mode...
|
||
|
|
if(!isViewCropped()){
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
// exit cropped all modes...
|
||
|
|
if(CROP_STACK.length == 1){
|
||
|
|
$.each(CROP_MODES, function(_, e){ e('off') })
|
||
|
|
|
||
|
|
// ucrop one state...
|
||
|
|
} else {
|
||
|
|
showStatusQ('Uncropping...')
|
||
|
|
uncropData()
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
/**********************************************************************
|
||
|
|
* vim:set ts=4 sw=4 : */
|