mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-11-03 12:50:09 +00:00
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:
parent
f0c1c816e9
commit
e3004899f2
112
ui/data.js
112
ui/data.js
@ -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
|
||||
|
||||
@ -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()
|
||||
|
||||
|
||||
@ -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',
|
||||
|
||||
@ -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))
|
||||
}
|
||||
|
||||
|
||||
14
ui/modes.js
14
ui/modes.js
@ -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...
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user