2013-06-02 20:14:39 +04:00
|
|
|
/**********************************************************************
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
**********************************************************************/
|
|
|
|
|
|
2013-06-08 21:32:22 +04:00
|
|
|
// A threshold after which the image block ratio will be changed to
|
|
|
|
|
// 'fit-viewer' in single image mode...
|
|
|
|
|
//
|
|
|
|
|
// NOTE: if null this feature will be disabled.
|
|
|
|
|
var PROPORTIONS_RATIO_THRESHOLD = 1.5
|
|
|
|
|
|
2013-12-14 06:58:13 +04:00
|
|
|
var CONTEXT_INDICATOR_UPDATERS = []
|
2013-06-08 21:32:22 +04:00
|
|
|
|
2013-06-02 20:14:39 +04:00
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
|
|
|
* Setup
|
|
|
|
|
*/
|
|
|
|
|
|
2013-06-04 09:00:59 +04:00
|
|
|
function setupIndicators(){
|
2013-06-16 02:42:29 +04:00
|
|
|
showGlobalIndicator(
|
|
|
|
|
'single-ribbon-mode',
|
|
|
|
|
'Single ribbon mode (F3)')
|
|
|
|
|
.css('cursor', 'hand')
|
|
|
|
|
.click(function(){ toggleSingleRibbonMode() })
|
2013-12-14 06:58:13 +04:00
|
|
|
}
|
2013-06-04 09:00:59 +04:00
|
|
|
|
2013-12-14 06:29:22 +04:00
|
|
|
|
2013-12-14 06:58:13 +04:00
|
|
|
function makeContextIndicatorUpdater(image_class){
|
|
|
|
|
var _updater = function(image){
|
|
|
|
|
var indicator = $('.context-mode-indicators .current-image-'+image_class)
|
|
|
|
|
if(image.hasClass(image_class)){
|
|
|
|
|
indicator.addClass('shown')
|
|
|
|
|
} else {
|
|
|
|
|
indicator.removeClass('shown')
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
CONTEXT_INDICATOR_UPDATERS.push(_updater)
|
|
|
|
|
return _updater
|
2013-06-04 09:00:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2013-07-05 18:03:44 +04:00
|
|
|
function updateContextIndicators(image){
|
|
|
|
|
image = image == null ? getImage() : $(image)
|
2013-12-14 06:07:22 +04:00
|
|
|
|
2013-07-05 18:03:44 +04:00
|
|
|
// marked...
|
2013-12-14 06:58:13 +04:00
|
|
|
CONTEXT_INDICATOR_UPDATERS.map(function(update){
|
|
|
|
|
update(image)
|
|
|
|
|
})
|
2013-07-05 18:03:44 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2013-07-05 19:23:31 +04:00
|
|
|
|
2013-06-02 20:14:39 +04:00
|
|
|
// Setup event handlers for data bindings...
|
|
|
|
|
//
|
|
|
|
|
// This does two jobs:
|
|
|
|
|
// - maintain DATA state
|
|
|
|
|
// - editor actions
|
|
|
|
|
// - focus
|
|
|
|
|
// - marking
|
|
|
|
|
// - maintain view consistency
|
|
|
|
|
// - centering/moving (roll)
|
|
|
|
|
// - shifting (expand/contract)
|
|
|
|
|
// - zooming (expand/contract)
|
|
|
|
|
//
|
|
|
|
|
function setupDataBindings(viewer){
|
|
|
|
|
viewer = viewer == null ? $('.viewer') : viewer
|
2013-12-12 19:35:13 +04:00
|
|
|
|
|
|
|
|
SETUP_BINDINGS.forEach(function(setup){
|
|
|
|
|
setup(viewer)
|
|
|
|
|
})
|
|
|
|
|
|
2013-06-02 20:14:39 +04:00
|
|
|
viewer
|
2013-06-13 17:51:28 +04:00
|
|
|
.click(function(){
|
|
|
|
|
if($('.ribbon').length == 0){
|
2013-07-04 21:15:02 +04:00
|
|
|
loadDirectoryDialog()
|
2013-06-13 17:51:28 +04:00
|
|
|
}
|
|
|
|
|
})
|
2013-12-02 08:50:43 +04:00
|
|
|
|
|
|
|
|
.on([
|
|
|
|
|
'focusingImage',
|
|
|
|
|
'fittingImages'
|
|
|
|
|
].join(' '),
|
|
|
|
|
function(){
|
|
|
|
|
updateCurrentMarker()
|
|
|
|
|
})
|
|
|
|
|
|
2013-12-02 17:45:54 +04:00
|
|
|
// NOTE: we do not need to worry about explicit centering the ribbon
|
|
|
|
|
// here, just ball-park-load the correct batch...
|
2013-12-07 05:05:43 +04:00
|
|
|
// NOTE: if we decide to hide ribbons, uncomment the visibility
|
|
|
|
|
// test down in the code...
|
2013-06-02 20:14:39 +04:00
|
|
|
.on('preCenteringRibbon', function(evt, ribbon, image){
|
2013-12-02 17:45:54 +04:00
|
|
|
var r = getRibbonIndex(ribbon)
|
|
|
|
|
|
|
|
|
|
// skip all but the curent ribbon in single image view...
|
|
|
|
|
if(toggleSingleImageMode('?') == 'on' && r != getRibbonIndex()){
|
|
|
|
|
return
|
|
|
|
|
}
|
2013-06-02 20:14:39 +04:00
|
|
|
|
2013-12-06 17:09:02 +04:00
|
|
|
// prepare for loading...
|
|
|
|
|
var gid = getImageGID(image)
|
|
|
|
|
var gr = DATA.ribbons[r]
|
2013-12-06 19:12:24 +04:00
|
|
|
|
2013-12-07 05:05:43 +04:00
|
|
|
// NOTE: this can return null in certain cases (see docs)
|
2013-12-06 17:09:02 +04:00
|
|
|
var gid_before = getGIDBefore(gid, r)
|
2013-12-07 05:05:43 +04:00
|
|
|
// we'll set the image to the first if the align target is
|
2013-12-10 05:37:00 +04:00
|
|
|
// before it (i.e. gid_before is null)...
|
2013-12-06 19:12:24 +04:00
|
|
|
var img_before = gid_before == null
|
|
|
|
|
? ribbon.find('.image').first()
|
|
|
|
|
: getImageBefore(image, ribbon)
|
|
|
|
|
gid_before = gid_before == null ? gr[0] : gid_before
|
2013-12-06 17:18:34 +04:00
|
|
|
|
2013-12-06 17:09:02 +04:00
|
|
|
var screen_size = getScreenWidthInImages()
|
|
|
|
|
screen_size = screen_size < 1 ? 1 : screen_size
|
|
|
|
|
var load_frame_size = Math.round(screen_size * LOAD_SCREENS)
|
2013-12-06 17:18:34 +04:00
|
|
|
|
2013-12-07 05:05:43 +04:00
|
|
|
// target image is loaded...
|
2013-12-06 19:12:24 +04:00
|
|
|
if(gid_before == getImageGID(img_before)){
|
2013-12-07 05:05:43 +04:00
|
|
|
var roll_frame_size = Math.ceil(load_frame_size * ROLL_FRAME)
|
|
|
|
|
var threshold = Math.floor(load_frame_size * LOAD_THRESHOLD)
|
2013-12-06 19:12:24 +04:00
|
|
|
threshold = threshold < 1 ? 1 : threshold
|
|
|
|
|
|
2013-12-06 17:09:02 +04:00
|
|
|
var head = img_before.prevAll('.image').length
|
|
|
|
|
var tail = img_before.nextAll('.image').length
|
|
|
|
|
var l = ribbon.find('.image').length
|
2013-12-06 19:12:24 +04:00
|
|
|
var index = gr.indexOf(gid_before)
|
2013-12-06 17:18:34 +04:00
|
|
|
var at_start = index < threshold
|
|
|
|
|
var at_end = (gr.length-1 - index) < threshold
|
|
|
|
|
|
2013-12-06 17:09:02 +04:00
|
|
|
// less images than expected - extend ribbon...
|
|
|
|
|
if(l < load_frame_size){
|
|
|
|
|
// NOTE: we are forcing the count of images...
|
|
|
|
|
loadImagesAround(load_frame_size, gid, ribbon, null, true)
|
|
|
|
|
|
|
|
|
|
// tail at threshold - roll ->
|
|
|
|
|
} else if(!at_end && tail < threshold){
|
|
|
|
|
var rolled = rollImages(roll_frame_size, ribbon)
|
|
|
|
|
|
|
|
|
|
// head at threshold - roll <-
|
|
|
|
|
} else if(!at_start && head < threshold){
|
|
|
|
|
var rolled = rollImages(-roll_frame_size, ribbon)
|
2013-12-06 19:23:03 +04:00
|
|
|
|
2013-12-07 14:25:53 +04:00
|
|
|
//} else {
|
|
|
|
|
// console.log('>>> skipping:', r)
|
2013-11-25 04:12:40 +04:00
|
|
|
}
|
2013-12-06 17:09:02 +04:00
|
|
|
|
|
|
|
|
// we jumped, load new set...
|
|
|
|
|
} else {
|
|
|
|
|
// NOTE: we are forcing the count of images...
|
|
|
|
|
loadImagesAround(load_frame_size, gid, ribbon, null, true)
|
2013-06-02 20:14:39 +04:00
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.on('shiftedImage', function(evt, image, from, to){
|
|
|
|
|
from = getRibbonIndex(from)
|
2013-06-05 00:42:41 +04:00
|
|
|
//var ribbon = to
|
2013-06-02 20:14:39 +04:00
|
|
|
to = getRibbonIndex(to)
|
|
|
|
|
|
|
|
|
|
var gid = getImageGID(image)
|
|
|
|
|
var after = getGIDBefore(gid, to)
|
|
|
|
|
|
|
|
|
|
// remove the elem from the from ribbon...
|
|
|
|
|
var index = DATA.ribbons[from].indexOf(gid)
|
|
|
|
|
var img = DATA.ribbons[from].splice(index, 1)
|
|
|
|
|
|
|
|
|
|
// put the elem in the to ribbon...
|
|
|
|
|
index = after == null ? 0 : DATA.ribbons[to].indexOf(after) + 1
|
|
|
|
|
DATA.ribbons[to].splice(index, 0, gid)
|
|
|
|
|
|
|
|
|
|
// indicators...
|
|
|
|
|
flashIndicator(from < to ? 'next' : 'prev')
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.on('createdRibbon', function(evt, index){
|
|
|
|
|
index = getRibbonIndex(index)
|
|
|
|
|
DATA.ribbons.splice(index, 0, [])
|
|
|
|
|
})
|
|
|
|
|
.on('removedRibbon', function(evt, index){
|
|
|
|
|
DATA.ribbons.splice(index, 1)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.on('requestedFirstImage', function(evt, ribbon){
|
|
|
|
|
var r = getRibbonIndex(ribbon)
|
|
|
|
|
var gr = DATA.ribbons[r]
|
|
|
|
|
rollImages(-gr.length, ribbon)
|
|
|
|
|
})
|
|
|
|
|
.on('requestedLastImage', function(evt, ribbon){
|
|
|
|
|
var r = getRibbonIndex(ribbon)
|
|
|
|
|
var gr = DATA.ribbons[r]
|
|
|
|
|
rollImages(gr.length, ribbon)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
.on('fittingImages', function(evt, n){
|
2013-12-07 14:25:53 +04:00
|
|
|
//console.log('!!!! fittingImages')
|
2013-06-02 20:14:39 +04:00
|
|
|
// load correct amount of images in each ribbon!!!
|
|
|
|
|
var screen_size = getScreenWidthInImages()
|
|
|
|
|
var gid = getImageGID()
|
2013-12-02 17:45:54 +04:00
|
|
|
|
|
|
|
|
/* XXX used to skip ribbons that are not visible... (see bellow)
|
|
|
|
|
var viewer = $('.viewer')
|
|
|
|
|
var H = viewer.height()
|
|
|
|
|
var h = getImage().height()
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// update and align ribbons...
|
2013-06-02 20:14:39 +04:00
|
|
|
$('.ribbon').each(function(){
|
|
|
|
|
var r = $(this)
|
2013-12-02 17:45:54 +04:00
|
|
|
/* XXX skip ribbons that are not visible...
|
|
|
|
|
* causes misaligns and misloads on zoom-in...
|
|
|
|
|
// NOTE: we factor in the scale difference to predict
|
|
|
|
|
// ribbon position in the new view...
|
|
|
|
|
var t = getRelativeVisualPosition(viewer, r).top * (n/screen_size)
|
|
|
|
|
if( t+h <= 0 || t >= H ){
|
|
|
|
|
console.log('#### skipping align of ribbon:', getRibbonIndex(r))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
*/
|
2013-12-06 17:09:02 +04:00
|
|
|
loadImagesAround(Math.round(screen_size * LOAD_SCREENS), gid, r, null, true)
|
2013-06-02 20:14:39 +04:00
|
|
|
})
|
2013-12-02 17:45:54 +04:00
|
|
|
|
2013-06-02 20:14:39 +04:00
|
|
|
centerView(null, 'css')
|
|
|
|
|
|
|
|
|
|
// update settings...
|
|
|
|
|
if(toggleSingleImageMode('?') == 'on'){
|
2013-07-03 20:18:00 +04:00
|
|
|
SETTINGS['single-image-mode-screen-images'] = n
|
2013-06-02 20:14:39 +04:00
|
|
|
} else {
|
2013-07-03 20:18:00 +04:00
|
|
|
SETTINGS['ribbon-mode-screen-images'] = n
|
2013-06-02 20:14:39 +04:00
|
|
|
}
|
|
|
|
|
|
2013-06-08 21:32:22 +04:00
|
|
|
// update proportions...
|
|
|
|
|
if(window.PROPORTIONS_RATIO_THRESHOLD != null
|
|
|
|
|
&& toggleSingleImageMode('?') == 'on'){
|
2013-06-09 02:26:22 +04:00
|
|
|
|
2013-06-08 21:32:22 +04:00
|
|
|
var h = getVisibleImageSize('height')
|
2013-06-09 02:26:22 +04:00
|
|
|
var w = getVisibleImageSize('width')
|
|
|
|
|
var H = $('.viewer').innerHeight()
|
|
|
|
|
var W = $('.viewer').innerWidth()
|
2013-06-08 21:32:22 +04:00
|
|
|
|
2013-06-09 02:26:22 +04:00
|
|
|
var m = Math.min(W/w, H/h)
|
2013-06-08 21:32:22 +04:00
|
|
|
|
|
|
|
|
if(m < PROPORTIONS_RATIO_THRESHOLD){
|
|
|
|
|
toggleImageProportions('fit-viewer')
|
|
|
|
|
} else {
|
|
|
|
|
toggleImageProportions('none')
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-09 17:34:24 +04:00
|
|
|
// update size classes...
|
|
|
|
|
// XXX make thresholds global...
|
|
|
|
|
if(n <= 2.5){
|
|
|
|
|
$('.viewer')
|
|
|
|
|
.removeClass('small')
|
|
|
|
|
.addClass('large')
|
|
|
|
|
} else if (n >= 6) {
|
|
|
|
|
$('.viewer')
|
|
|
|
|
.addClass('small')
|
|
|
|
|
.removeClass('large')
|
|
|
|
|
} else {
|
|
|
|
|
$('.viewer')
|
|
|
|
|
.removeClass('small')
|
|
|
|
|
.removeClass('large')
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-02 20:14:39 +04:00
|
|
|
// update previews...
|
|
|
|
|
updateImages()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.on('focusingImage', function(evt, image){
|
|
|
|
|
image = $(image)
|
|
|
|
|
DATA.current = getImageGID(image)
|
2013-06-11 17:12:50 +04:00
|
|
|
|
|
|
|
|
if(window.setWindowTitle != null){
|
2013-06-11 17:16:18 +04:00
|
|
|
// XXX do we need to hide the extension...
|
2013-10-18 05:03:11 +04:00
|
|
|
setWindowTitle(getImageFileName())
|
2013-06-11 17:16:18 +04:00
|
|
|
//.split(/\.(jpg|jpeg|png|gif)$/)[0])
|
2013-06-11 17:12:50 +04:00
|
|
|
}
|
2013-06-02 20:14:39 +04:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// basic image manipulation...
|
|
|
|
|
.on('rotatingLeft rotatingRight', function(evt, image){
|
|
|
|
|
$(image).each(function(i, e){
|
|
|
|
|
var img = $(this)
|
|
|
|
|
var gid = getImageGID(img)
|
|
|
|
|
var orientation = img.attr('orientation')
|
|
|
|
|
|
|
|
|
|
// change the image orientation status and add to
|
|
|
|
|
// updated list...
|
|
|
|
|
IMAGES[gid].orientation = orientation
|
2013-12-15 03:38:15 +04:00
|
|
|
imageUpdated(gid)
|
2013-06-02 20:14:39 +04:00
|
|
|
})
|
|
|
|
|
})
|
2013-06-04 22:01:41 +04:00
|
|
|
.on('flippingVertical flippingHorizontal', function(evt, image){
|
|
|
|
|
$(image).each(function(i, e){
|
|
|
|
|
var img = $(this)
|
|
|
|
|
var gid = getImageGID(img)
|
|
|
|
|
var flip = getImageFlipState(img)
|
|
|
|
|
|
|
|
|
|
IMAGES[gid].flipped = flip
|
2013-12-15 03:38:15 +04:00
|
|
|
imageUpdated(gid)
|
2013-06-04 22:01:41 +04:00
|
|
|
})
|
|
|
|
|
})
|
2013-06-04 23:29:44 +04:00
|
|
|
.on('resetToOriginalImage', function(evt, image){
|
|
|
|
|
$(image).each(function(i, e){
|
|
|
|
|
var img = $(this)
|
|
|
|
|
var gid = getImageGID(img)
|
|
|
|
|
|
|
|
|
|
IMAGES[gid].flipped = null
|
|
|
|
|
IMAGES[gid].orientation = 0
|
|
|
|
|
|
2013-12-15 03:38:15 +04:00
|
|
|
imageUpdated(gid)
|
2013-06-04 23:29:44 +04:00
|
|
|
})
|
|
|
|
|
})
|
2013-06-02 20:14:39 +04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
// caching...
|
2013-12-15 07:41:01 +04:00
|
|
|
/* XXX this appears to actually make things slower...
|
2013-06-02 20:14:39 +04:00
|
|
|
.on('reloadedRibbon updatedRibbon', function(evt, ribbon){
|
|
|
|
|
|
|
|
|
|
window.DEBUG && console.log('>>> (ribbon:', getRibbonIndex(ribbon), ') Updating cache...')
|
|
|
|
|
|
|
|
|
|
preCacheRibbonImages(ribbon)
|
|
|
|
|
})
|
2013-12-15 07:41:01 +04:00
|
|
|
*/
|
2013-06-02 20:14:39 +04:00
|
|
|
|
|
|
|
|
// info...
|
2013-09-13 21:51:58 +04:00
|
|
|
.on('focusingImage',
|
|
|
|
|
function(){
|
|
|
|
|
showRibbonIndicator()
|
|
|
|
|
})
|
|
|
|
|
.on([
|
|
|
|
|
'focusedNextRibbon',
|
|
|
|
|
'focusedPrevRibbon'
|
|
|
|
|
].join(' '),
|
|
|
|
|
function(){
|
|
|
|
|
if(toggleSingleImageMode('?') == 'on'){
|
|
|
|
|
flashRibbonIndicator()
|
|
|
|
|
}
|
|
|
|
|
})
|
2013-07-05 18:03:44 +04:00
|
|
|
.on([
|
2013-06-02 20:14:39 +04:00
|
|
|
'rotatingLeft',
|
|
|
|
|
'rotateingRight',
|
2013-06-04 22:01:41 +04:00
|
|
|
'flippingVertical',
|
2013-07-05 18:03:44 +04:00
|
|
|
'flippingHorizontal'
|
2013-06-02 20:14:39 +04:00
|
|
|
].join(' '),
|
|
|
|
|
function(evt, image){
|
|
|
|
|
updateGlobalImageInfo($(image))
|
|
|
|
|
})
|
|
|
|
|
.on([
|
2013-12-14 06:07:22 +04:00
|
|
|
'focusingImage',
|
|
|
|
|
'togglingMark',
|
2013-12-14 06:29:22 +04:00
|
|
|
'togglingBookmark',
|
2013-06-02 20:14:39 +04:00
|
|
|
'removeingAllMarks',
|
|
|
|
|
'removeingRibbonMarks',
|
|
|
|
|
'markingAll',
|
|
|
|
|
'markingRibbon',
|
|
|
|
|
'invertingMarks'
|
|
|
|
|
].join(' '),
|
|
|
|
|
function(){
|
|
|
|
|
updateGlobalImageInfo()
|
2013-07-05 18:03:44 +04:00
|
|
|
updateContextIndicators()
|
2013-06-02 20:14:39 +04:00
|
|
|
})
|
2013-06-04 09:00:59 +04:00
|
|
|
|
2013-06-08 18:28:10 +04:00
|
|
|
|
|
|
|
|
.on('baseURLChanged', function(evt, url){
|
|
|
|
|
saveLocalStorageBaseURL()
|
|
|
|
|
saveLocalStorageBaseURLHistory()
|
|
|
|
|
})
|
2013-06-02 20:14:39 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
|
|
|
* vim:set ts=4 sw=4 : */
|