diff --git a/ui/base.js b/ui/base.js index 66912c5d..7d947468 100755 --- a/ui/base.js +++ b/ui/base.js @@ -111,18 +111,20 @@ function getImage(gid){ return res.length == 0 ? $('.image').first() : res } + // order... + if(typeof(gid) == typeof(1)){ + res = $('.image[order="'+ JSON.stringify(gid) +'"]') + if(res.length != null){ + return res + } + } + // gid... - res = $('.image[gid='+ JSON.stringify(gid) +']') + res = $('.image[gid="'+ JSON.stringify(gid) +'"]') if(res.length != null){ return res } - // order... - res = $('.image[order='+ JSON.stringify(gid) +']') - if(res.length != null){ - return res - } - return null } diff --git a/ui/data.js b/ui/data.js index a05dfa97..a2b069f8 100755 --- a/ui/data.js +++ b/ui/data.js @@ -88,6 +88,10 @@ $.each([ }) */ +var UPDATE_SORT_ENABLED = false +// XXX for some reason the sync version appears to work faster... +var UPDATE_SYNC = false + /********************************************************************** @@ -492,11 +496,13 @@ function getBestPreview(gid, size){ // // NOTE: due to how the format is structured, to sort the images one // only needs to sort DATA.order and call this. -function updateRibbonOrder(){ +function updateRibbonOrder(no_reload_viewer){ for(var i=0; i < DATA.ribbons.length; i++){ DATA.ribbons[i].sort(imageOrderCmp) } - reloadViewer() + if(!no_reload_viewer){ + reloadViewer() + } } @@ -505,6 +511,8 @@ function updateRibbonOrder(){ * Constructors */ +// Construct an IMAGES object from list of urls. +// // NOTE: this depends on that the base dir contains ALL the images... function imagesFromUrls(lst){ var res = {} @@ -537,6 +545,9 @@ function imagesFromUrls(lst){ } +// Construct a DATA object from a list of images +// +// NOTE: this will create a single ribbon... function dataFromImages(images){ var gids = Object.keys(images).sort() @@ -552,6 +563,8 @@ function dataFromImages(images){ } +// Construct a ribbons hierarchy from the fav dirs structure +// // NOTE: this depends on listDir(...) // NOTE: this assumes that images contain ALL the images... function ribbonsFromFavDirs(path, images, cmp){ @@ -659,6 +672,7 @@ function convertDataGen1(data, cmp){ * Loaders */ +// Update an image element function updateImage(image, gid, size){ image = $(image) var title = '' @@ -715,10 +729,6 @@ function updateImage(image, gid, size){ } -var UPDATE_SORT_ENABLED = false -// XXX for some reason the sync version appears to work faster... -var UPDATE_SYNC = false - // Same as updateImage(...) but will update all images. // // NOTE: this will prioritize images by distance from current image... @@ -763,6 +773,7 @@ function updateImages(size, cmp){ return deferred } + /* XXX for some very odd reason this is slower that the monster above... function updateImages(size){ size = size == null ? getVisibleImageSize('max') : size @@ -923,6 +934,7 @@ function rollImages(n, ribbon, extend, no_compensate_shift){ } +// Reload the viewer using the current DATA and IMAGES objects function reloadViewer(images_per_screen){ var ribbons_set = $('.ribbon-set') var current = DATA.current @@ -950,6 +962,7 @@ function reloadViewer(images_per_screen){ } +// Apply the current SETTINGS to current viewer function loadSettings(){ toggleTheme(SETTINGS['theme']) @@ -1293,6 +1306,7 @@ function saveFileState(name, no_normalize_path){ // 2) find a cache directory and a data file there // 3) list the images and load them as-is // +// XXX this will not load the marks file... // XXX make sure that save works... function loadDir(path, raw_load){ path = normalizePath(path) @@ -1304,7 +1318,7 @@ function loadDir(path, raw_load){ var files = listDir(path) if(files == null){ - showErrorStatus('Path: ' + path) + showErrorStatus('No files in path: ' + path) return } @@ -1334,6 +1348,10 @@ function loadDir(path, raw_load){ data = path + '/' + data + // marks... + // XXX see if there's a marks file... + MARKED = [] + return loadFileState(data) .always(function(){ showStatus('Done.') @@ -1369,6 +1387,11 @@ function updateRibbonsFromFavDirs(){ } + +/********************************************************************** +* Actions... +*/ + // Open image in an external editor/viewer // // NOTE: this will open the default editor/viewer. @@ -1382,11 +1405,6 @@ function openImage(){ } - -/********************************************************************** -* Actions... -*/ - function reverseImageOrder(){ DATA.order.reverse() updateRibbonOrder() @@ -1406,7 +1424,7 @@ function sortImages(cmp, reverse){ } -// shirt-hands... +// shorthands... function sortImagesByDate(reverse){ return sortImages(reverse) } @@ -1415,6 +1433,54 @@ function sortImagesByName(reverse){ } +// shifting images... +// NOTE: this a bit more complicated than simply shifting an image +// left/right the DATA.order, we have to put it before or after +// the prev/next image... +function horizontalShiftImage(image, direction){ + image = image == null ? getImage() : $(image) + var gid = getImageGID(image) + var r = getRibbonIndex(image) + var ri = DATA.ribbons[r].indexOf(gid) + + // the image we are going to move relative to... + var target = DATA.ribbons[r][ri + (direction == 'next' ? 1 : -1)] + // we can hit the end or start of the ribbon... + if(target == null){ + return image + } + + var order = DATA.order + var i = order.indexOf(gid) + if(i == 0){ + return image + } + var j = order.indexOf(target) + j += (direction == 'next' ? 1 : 0) + + order.splice(i, 1) + order.splice(j, 0, gid) + + + // just update the ribbons, no reloading needed... + updateRibbonOrder(true) + + // shift the images... + getImage(target)[direction == 'prev' ? 'before' : 'after'](image) + + // update stuff that changed, mainly order... + updateImages() + + return image +} +function shiftImageLeft(image){ + return horizontalShiftImage(image, 'prev') +} +function shiftImageRight(image){ + return horizontalShiftImage(image, 'next') +} + + /********************************************************************** * vim:set ts=4 sw=4 spell : */ diff --git a/ui/keybindings.js b/ui/keybindings.js index 6bfe6ff3..ed7d89ab 100755 --- a/ui/keybindings.js +++ b/ui/keybindings.js @@ -163,30 +163,11 @@ var KEYBOARD_CONFIG = { // '.viewer:not(.overlay)': { title: 'Global', - doc: 'These key bindings work in most other modes.', - - // Actions... - 'next-screen': doc('Next screen', - function(){ - event.preventDefault() - nextScreenImages() - centerRibbons() - }), - 'prev-screen': doc('Previous screen', - function(){ - event.preventDefault() - prevScreenImages() - centerRibbons() - }), - - - // Help and info... - '?': doc('Show keyboard bindings', - function(){ toggleKeyboardHelp() }), - - F1: doc('Show help', - function(){ toggleHelp() }), - H: 'F1', + doc: 'These key bindings work in most other modes.'+ + '
NOTE: shifting markid images from different ribbons will '+ + 'perform the operations on ALL marked images but relative '+ + 'the the current ribbon. i.e. some images might get promoted,'+ + 'others demoted while some will not change position.', // Basics... // XXX STUB: use a real path browser... @@ -213,6 +194,25 @@ var KEYBOARD_CONFIG = { centerRibbons() }), ctrl: 'prev-screen', + alt: doc('Shift image left', + function(){ + event.preventDefault() + shiftImageLeft() + centerView(null, 'css') + // XXX for some odd reason centerRibbons does + // something really odd here... + //centerRibbons() + // XXX HACK... + // XXX this still gets misaligned sometimes but this + // is likely due to one of the align bugs + if(window._center_ribbon_delay != null){ + clearTimeout(_center_ribbon_delay) + } + _center_ribbon_delay = setTimeout( + function(){ + centerRibbons() + }, 300) + }), }, Right: { default: doc('Next image', @@ -224,8 +224,39 @@ var KEYBOARD_CONFIG = { centerRibbons() }), ctrl: 'next-screen', + alt: doc('Shift image right', + function(){ + event.preventDefault() + shiftImageRight() + centerView(null, 'css') + // XXX for some odd reason centerRibbons does + // something really odd here... + //centerRibbons() + // XXX HACK... + // XXX this still gets misaligned sometimes but this + // is likely due to one of the align bugs + // (see: TODO.otl) + if(window._center_ribbon_delay != null){ + clearTimeout(_center_ribbon_delay) + } + _center_ribbon_delay = setTimeout( + function(){ + centerRibbons() + }, 300) + }), }, - + 'prev-screen': doc('Previous screen', + function(){ + event.preventDefault() + prevScreenImages() + centerRibbons() + }), + 'next-screen': doc('Next screen', + function(){ + event.preventDefault() + nextScreenImages() + centerRibbons() + }), Space: { default: 'Right', shift: 'Left', @@ -274,6 +305,16 @@ var KEYBOARD_CONFIG = { shiftImageUpNewRibbon(null, DIRECTION) centerRibbons() }), + + // XXX + alt: doc('Shift marked images up', + function(){ + // XXX + }), + 'alt+shift': doc('Shift marked images up to empty ribbon', + function(){ + // XXX + }), }, Down: { default: doc('Go to ribbon below', @@ -294,6 +335,16 @@ var KEYBOARD_CONFIG = { shiftImageDownNewRibbon(null, DIRECTION) centerRibbons() }), + + // XXX + alt: doc('Shift marked images down', + function(){ + // XXX + }), + 'alt+shift': doc('Shift marked images down to empty ribbon', + function(){ + // XXX + }), }, L: doc('Rotate image left', function(){ rotateLeft() }), @@ -439,6 +490,18 @@ var KEYBOARD_CONFIG = { P: doc('Show options', function(){ toggleOptionsUI() }), + // NOTE: this is handled by the wrapper at this point, so we do + // not have to do anything here... + F11: doc('Toggle full screen mode'), + + + // Help and info... + '?': doc('Show keyboard bindings', + function(){ toggleKeyboardHelp() }), + + F1: doc('Show help', + function(){ toggleHelp() }), + H: 'F1', /* testing the shift-key feature... diff --git a/ui/lib/keyboard.js b/ui/lib/keyboard.js index 1541d235..3ac518db 100755 --- a/ui/lib/keyboard.js +++ b/ui/lib/keyboard.js @@ -500,9 +500,7 @@ function buildKeybindingsHelp(keybindings, shifted_keys){ } // skip anything that is not a key... - //if(key.length > 1 && (!(key in _KEY_CODES) || /\..+/.test(key))){ if(key.length > 1 && !(key in _KEY_CODES)){ - console.log('### skipping:', key) continue }