added status display API and some work on keyboard.js...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2013-05-30 19:15:38 +04:00
parent f0c1c816e9
commit e3004899f2
5 changed files with 188 additions and 42 deletions

View File

@ -943,7 +943,7 @@ function loadFileImages(path, no_load_diffs, callback){
}).sort().reverse()[0]
path = path == null ? 'images.json' : path
console.log('Loading:', path)
updateStatus('Loading: ' + path)
path = base +'/'+ path
@ -972,7 +972,7 @@ function loadFileImages(path, no_load_diffs, callback){
// whether we have one or more deffereds here...
.done(function(data){
diff_data[i+1] = data
console.log('Loaded:', e)
updateStatus('Loaded:', e)
})
}))
.then(function(){
@ -988,12 +988,12 @@ function loadFileImages(path, no_load_diffs, callback){
$.extend(json, diff_data)
IMAGES = json
console.log('Loaded IMAGES...')
updateStatus('Loaded images...')
callback != null && callback()
})
.fail(function(){
console.error('ERROR LOADING:', path)
updateErrorStatus('Loading: ' + path)
})
}
@ -1009,7 +1009,7 @@ function saveFileImages(name){
name = name == null ? normalizePath(CACHE_DIR +'/'+ Date.timeStamp()) : name
if(window.dumpJSON == null){
console.error('Can\'t save to file.')
updateErrorStatus('Can\'t save to file.')
return
}
@ -1018,7 +1018,7 @@ function saveFileImages(name){
$.each($.map(listDir(normalizePath(CACHE_DIR)), function(e){
return /.*-images-diff.json$/.test(e) ? e : null
}), function(i, e){
console.log('removeing:', e)
updateStatus('removeing:', e)
removeFile(normalizePath(CACHE_DIR +'/'+ e))
})
IMAGES_UPDATED = []
@ -1060,12 +1060,12 @@ function loadFileState(data_path, callback){
// unknown format...
} else {
console.error('unknown format.')
updateStatus('Unknown format.')
return
}
})
.fail(function(){
console.error('ERROR LOADING:', data_path)
updateErrorStatus('Loading:', data_path)
})
return res
@ -1114,10 +1114,12 @@ function loadDir(path, raw_load){
var orig_path = path
var data
updateStatus('Loading...').show()
var files = listDir(path)
if(files == null){
console.error('Path error:', path)
updateErrorStatus('Path: ' + path)
return
}
@ -1143,11 +1145,14 @@ function loadDir(path, raw_load){
// load the found data file...
if(data != null){
console.log('Loading:', data)
updateStatus('Loading: ', data)
data = path + '/' + data
return loadFileState(data)
.always(function(){
showStatus('Done.')
})
// load the dir as-is...
} else {
@ -1157,7 +1162,7 @@ function loadDir(path, raw_load){
})
if(image_paths.length == 0){
console.error('No images in:', orig_path)
updateErrorStatus('No images in:', orig_path)
return
}
@ -1168,6 +1173,7 @@ function loadDir(path, raw_load){
MARKED = []
loadData()
showStatus('Done.')
}
}
@ -1183,7 +1189,7 @@ function updateRibbonsFromFavDirs(){
// NOTE: this will open the default editor/viewer.
function openImage(){
if(window.runSystem == null){
console.error('Can\'t run external programs.')
updateErrorStatus('Can\'t run external programs.')
return
}
// XXX if path is not present try and open the biggest preview...
@ -1193,13 +1199,61 @@ function openImage(){
/**********************************************************************
* Actions
* Info & status...
*/
// NOTE: if message is null, then just return the status element...
function updateStatus(message){
var elem = $('.global-status')
if(elem.length == 0){
elem = $('<div class="global-status"/>')
}
if(message == null){
return elem
}
if(arguments.length > 1){
message = Array.apply(Array, arguments).join(' ')
}
if(typeof(message) == typeof('s') && /^error.*/i.test(message)){
console.error.apply(console, arguments)
} else {
console.log.apply(console, arguments)
}
return updateInfo(elem, message)
}
function showStatus(message){
return updateStatus(message)
.stop()
.show()
.delay(500)
.fadeOut(800)
}
function showErrorStatus(message){
return updateStatus('Error:' + message)
.stop()
.show()
}
// XXX do we need a full rewrite here, or will it be better to just fill
// the slots...
function updateGlobalImageInfo(image){
image = image == null ? getImage() : $(image)
image = image.length == 0 ? getImage() : image
var elem = $('.global-image-info')
if(elem.length == 0){
elem = $('<div class="global-image-info"/>')
}
// no image no update...
if(image.length == 0){
return elem
}
var gid = getImageGID(image)
var r = getRibbonIndex(getRibbon(image))
@ -1222,11 +1276,6 @@ function updateGlobalImageInfo(image){
meta = meta.join(', ')
meta = meta != '' ? '( '+ meta +' )' : ''
var elem = $('.global-image-info')
if(elem.length == 0){
elem = $('<div class="global-image-info"/>')
}
return updateInfo(elem,
// path...
'<span class="expanding-text path">'+
@ -1268,6 +1317,18 @@ function updateGlobalImageInfo(image){
function updateInlineImageInfo(image){
image = image == null ? getImage() : $(image)
image = image.length == 0 ? getImage() : image
var elem = $('.inline-image-info')
if(elem.length == 0){
elem = $('<div class="inline-image-info"/>')
}
// no image no update...
if(image.length == 0){
return elem
}
var gid = getImageGID(image)
var r = getRibbonIndex(getRibbon(image))
@ -1277,11 +1338,6 @@ function updateInlineImageInfo(image){
var orientation = data.orientation
orientation = orientation == null ? 0 : orientation
var elem = $('.inline-image-info')
if(elem.length == 0){
elem = $('<div class="inline-image-info"/>')
}
return updateInfo(elem,
// name...
data.path.split('/').pop() +'<br>'+
@ -1297,6 +1353,16 @@ function updateInlineImageInfo(image){
}
function inlineImageInfoHoverHandler(evt){
var img = $(evt.target).closest('.image')
if(img.length > 0){
if(img.find('.inline-image-info:visible').length == 0){
updateInlineImageInfo(img)
}
}
}
/**********************************************************************
* Setup

View File

@ -254,7 +254,8 @@ body {
width: 100%;
background: black;
opacity: 0.7;
}
.image .inline-image-info:hover {
-moz-user-select: auto;
-webkit-user-select: auto;
-o-user-select: auto;
@ -328,7 +329,8 @@ body {
color: white;
opacity: 0.6;
}
.overlay-info:hover {
-moz-user-select: auto;
-webkit-user-select: auto;
-o-user-select: auto;
@ -526,6 +528,11 @@ body {
display: inline;
}
.global-status {
opacity: 1;
z-index: 1000;
}
</style>
@ -578,18 +585,6 @@ $(function(){
function(k){
window.DEBUG && console.log(k)
}))
.on('mouseover', function(evt){
var img = $(evt.target).closest('.image')
if(img.length > 0){
if(IMAGE_INFO){
if(img.find('.inline-image-info:visible').length == 0){
updateInlineImageInfo(img)
}
} else {
img.find('.inline-image-info').remove()
}
}
})
setupDataBindings()

View File

@ -16,7 +16,32 @@ var DIRECTION = 'next'
/*********************************************************************/
var KEYBOARD_CONFIG = {
// info overlay...
//
// NOTE: this is here to prevent selecting images while trying to
// select info text...
'.overlay-info:hover': {
title: 'Info overlay',
doc: 'NOTE: when the cursor is over the info overlay one can use '+
'Ctrl-A and Ctrl-D for info text selection, without affecting '+
'image selection/marks.',
ignore: [ 'A' ],
A: {
// NOTE: this is here only for documentation...
ctrl: doc('Select all'),
},
D: {
ctrl: doc('Clear selection',
function(){
document.getSelection().empty()
return false
})
}
},
// help mode...
//
// NOTE: need to keep all info modes before the rest so as to give
// their bindings priority...
'.help-mode': {
@ -40,6 +65,7 @@ var KEYBOARD_CONFIG = {
// single image mode only...
//
'.single-image-mode': {
title: 'Single image mode',
@ -59,6 +85,7 @@ var KEYBOARD_CONFIG = {
// single image mode only...
//
'.marked-only-view:not(.single-image-mode)': {
title: 'Marked only view',
@ -72,6 +99,7 @@ var KEYBOARD_CONFIG = {
// general setup...
//
'.viewer:not(.overlay)': {
title: 'Global',
@ -285,7 +313,7 @@ var KEYBOARD_CONFIG = {
},
I: {
// XXX group this with other info stuff into a single on/off toggle...
default: doc('Toggle image info visibility (on hover)',
default: doc('Toggle image info display',
function(){ toggleImageInfo() }),
// XXX STUB -- replace with a real info window...
shift: doc('Show current image info',
@ -307,14 +335,30 @@ var KEYBOARD_CONFIG = {
'Position (global): '+ order +'/'+ DATA.order.length +'\n'+
'')
}),
alt: doc('Toggle inline image info display',
function(){
toggleInlineImageInfo()
}),
// marking...
ctrl: doc('Invert image marks',
function(){ invertImageMarks() }),
},
A: {
shift: doc('Toggle marks in current contagious block',
function(){ toggleImageMarkBlock() }),
// XXX does not yet work with DATA (???)
//shift: doc('Toggle marks in current contagious block',
// function(){ toggleImageMarkBlock() }),
ctrl: doc('Mark current ribbon',
function(){ markAll('ribbon') }),
'ctrl+shift': doc('Mark all images',
function(){ markAll('all') }),
},
D: {
ctrl: doc('Unmark current ribbon',
function(){ removeImageMarks('ribbon') }),
'ctrl+shift': doc('Unmark all images',
function(){ removeImageMarks('all') }),
},
U: {
ctrl: doc('Unmark current ribbon',

View File

@ -62,6 +62,17 @@ var _SPECIAL_KEYS = {
188: ',', 190: '.', 191: '/',
}
var _SHIFT_KEYS = {
'`': '~', '-': '_', '=':'+',
1: '!', 2: '@', 3: '#', 4: '$', 5: '%',
6:'^', 7:'&', 8: '*', 9: '(', 0: ')',
'[': '{', ']': '}i', '\\': '|',
';': ':', '\'': '"',
',': '<', '.': '>', '/': '?'
}
var _KEY_CODES = {}
for(var k in _SPECIAL_KEYS){
_KEY_CODES[_SPECIAL_KEYS[k]] = k
@ -93,6 +104,7 @@ function toKeyCode(c){
// documentation wrapper...
function doc(text, func){
func = func == null ? function(){return true}: func
func.doc = text
return func
}
@ -135,11 +147,12 @@ function doc(text, func){
* XXX BUG explicitly given modes do not yield results if the pattern
* does not match...
*/
function getKeyHandlers(key, modifiers, keybindings, modes){
function getKeyHandlers(key, modifiers, keybindings, modes, shifted_keys){
var chr = null
var did_handling = false
modifiers = modifiers == null ? '' : modifiers
modes = modes == null ? 'any' : modes
shifted_keys = shifted_keys == null ? _SHIFT_KEYS : shifted_keys
if(typeof(key) == typeof(123)){
key = key
@ -149,6 +162,12 @@ function getKeyHandlers(key, modifiers, keybindings, modes){
key = toKeyCode(key)
}
/* XXX this is not done yet...
if(shifted_keys != false && key in shifted_keys){
key = shifted_keys[key]
}
*/
res = {}
for(var mode in keybindings){
@ -400,7 +419,8 @@ function makeKeyboardHandler(keybindings, unhandled){
* <keys-spec> - list of key names.
*
*/
function buildKeybindingsHelp(keybindings){
function buildKeybindingsHelp(keybindings, shifted_keys){
shifted_keys = shifted_keys == null ? _SHIFT_KEYS : shifted_keys
var res = {}
var mode, title
@ -455,6 +475,13 @@ function buildKeybindingsHelp(keybindings){
var keys = []
section[doc] = keys
}
// translate shifted keys...
if(shifted_keys != false && mod == 'shift' && key in shifted_keys){
mod = ''
key = shifted_keys[key]
}
keys.push((mod == '' || mod == 'default') ? key : (mod +'+'+ key))
}

View File

@ -69,6 +69,20 @@ var toggleTheme = createCSSClassToggler('.viewer',
var toggleImageInfo = createCSSClassToggler('.viewer', '.image-info-visible')
var toggleInlineImageInfo = createCSSClassToggler('.viewer',
'.image-info-inline-visible',
function(action){
if(action == 'on'){
$(document)
.on('mouseover', inlineImageInfoHoverHandler)
} else {
$(document)
.off('mouseover', inlineImageInfoHoverHandler)
$('.inline-image-info').remove()
}
})
// NOTE: this confirmsto the css toggler protocol, but is not implemented
// via createCSSClassToggler as we do not need to set any classes,
// al least at this point...