mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-28 18:00:09 +00:00
881 lines
22 KiB
JavaScript
Executable File
881 lines
22 KiB
JavaScript
Executable File
/**********************************************************************
|
|
*
|
|
*
|
|
*
|
|
**********************************************************************/
|
|
|
|
//var DEBUG = DEBUG != null ? DEBUG : true
|
|
|
|
var _STEPS_LEFT_TO_CHANGE_DIRECTION = CONFIG.steps_to_change_direction
|
|
var DIRECTION = 'next'
|
|
|
|
var ACTIONS = {}
|
|
|
|
|
|
/*********************************************************************/
|
|
|
|
function updateDirection(direction){
|
|
if(DIRECTION != direction){
|
|
_STEPS_LEFT_TO_CHANGE_DIRECTION--
|
|
if(_STEPS_LEFT_TO_CHANGE_DIRECTION == 0){
|
|
DIRECTION = direction
|
|
_STEPS_LEFT_TO_CHANGE_DIRECTION = CONFIG.steps_to_change_direction
|
|
}
|
|
} else {
|
|
_STEPS_LEFT_TO_CHANGE_DIRECTION = CONFIG.steps_to_change_direction
|
|
}
|
|
}
|
|
|
|
|
|
function directionImage(reverse){
|
|
if(DIRECTION == (reverse ? 'prev' : 'next')){
|
|
nextImage()
|
|
} else {
|
|
prevImage()
|
|
}
|
|
}
|
|
|
|
|
|
// XXX this is experimental...
|
|
// ...not sure yet how to go about this...
|
|
function Action(text, func){
|
|
var not_action = func === false ? true : false
|
|
func = !func ? function(){return true}: func
|
|
func.doc = text
|
|
|
|
var name = text.split('\n')[0].trim()
|
|
|
|
if(name in ACTIONS){
|
|
console.warn('Action: "'+name+'" is defined more than once.')
|
|
}
|
|
|
|
if(!not_action){
|
|
ACTIONS[name] = func
|
|
}
|
|
|
|
return func
|
|
}
|
|
|
|
|
|
var _doc = doc
|
|
var doc = Action
|
|
|
|
|
|
|
|
/*********************************************************************/
|
|
|
|
var KEYBOARD_CONFIG = {
|
|
'Global bindings': {
|
|
doc: 'NOTE: binding priority is the same as the order of sections '+
|
|
'on this page.',
|
|
pattern: '*',
|
|
|
|
F4: {
|
|
alt: doc('Close viewer',
|
|
function(){
|
|
closeWindow()
|
|
return false
|
|
}),
|
|
},
|
|
F5: doc('Full reload viewer',
|
|
function(){
|
|
reload()
|
|
return false
|
|
}),
|
|
F12: doc('Show devTools',
|
|
function(){
|
|
showDevTools()
|
|
return false
|
|
}),
|
|
// NOTE: these are for systems where F** keys are not available
|
|
// or do other stuff...
|
|
R: {
|
|
'ctrl+alt': doc('Reload viewer',
|
|
function(){
|
|
reloadViewer()
|
|
return false
|
|
}),
|
|
'ctrl+shift': 'F5',
|
|
},
|
|
P: {
|
|
'ctrl+shift': 'F12',
|
|
},
|
|
|
|
// NOTE: this is handled by the wrapper at this point, so we do
|
|
// not have to do anything here...
|
|
F11: doc('Toggle full screen view', function(){
|
|
toggleFullscreenMode()
|
|
return false
|
|
}),
|
|
F: {
|
|
ctrl: 'F11',
|
|
},
|
|
|
|
},
|
|
|
|
// NOTE: this is here to prevent selecting images while trying to
|
|
// select info text...
|
|
'Info overlay': {
|
|
doc: 'Displayed on bottom of the screen if enabled (toggle with '+
|
|
'<b>I</b>) and/or inline, at bottom of an image when cursor '+
|
|
'is over it (only in ribbon view, toggle with <b>alt-I</b>)'+
|
|
|
|
'<p>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.',
|
|
pattern: '.overlay-info:hover',
|
|
|
|
ignore: [ 'A', 'C', 'D' ],
|
|
|
|
// NOTE: these are here only for documentation...
|
|
A: {
|
|
ctrl: doc('Select all', false),
|
|
},
|
|
C: {
|
|
ctrl: doc('Copy selection', false)
|
|
},
|
|
|
|
D: {
|
|
ctrl: doc('Clear selection',
|
|
function(){
|
|
console.log('!!!')
|
|
document.getSelection().empty()
|
|
})
|
|
}
|
|
},
|
|
|
|
|
|
// NOTE: editor effects are not documented, but should be obvious...
|
|
// XXX is this the case?
|
|
'Dialog': {
|
|
doc: 'NOTE: to <i>close</i> a dialog, in addition to the keyaboard '+
|
|
'shortcuts, one can also click anywhere outside the dialog.',
|
|
pattern: '.viewer.overlay .overlay-block.dialog, '
|
|
+'.panel :focus',
|
|
|
|
ignore: '*',
|
|
|
|
'insert-return': doc('Insert return', false),
|
|
|
|
Enter: {
|
|
default: doc('Accept dialog',
|
|
function(){
|
|
var f = $(':focus')
|
|
|
|
// trigger the default button/summary action...
|
|
// NOTE: for some reason checkboxes in dialogs do not work (not a biggie)...
|
|
if(f.length > 0
|
|
&& (/button|summary/i.test(f[0].tagName)
|
|
|| /button|checkbox/i.test(f.attr('type')))){
|
|
f.click()
|
|
// prevent the key from propagating to the viewer...
|
|
return false
|
|
|
|
// accept the input -- e.g. remove focus from it...
|
|
} else if(toggleEditor('?') == 'on'){
|
|
f.blur()
|
|
// prevent the key from propagating to the viewer...
|
|
return false
|
|
|
|
// accept the dialog...
|
|
} else if(isOverlayVisible('.viewer')) {
|
|
getOverlay($('.viewer')).trigger('accept')
|
|
hideOverlay($('.viewer'))
|
|
}
|
|
}),
|
|
shift: 'insert-return',
|
|
//ctrl: 'insert-return',
|
|
},
|
|
Esc: doc('Close dialog',
|
|
function(){
|
|
// hide the overlay...
|
|
if(isOverlayVisible('.viewer')){
|
|
//getOverlay($('.viewer')).trigger('close')
|
|
hideOverlay($('.viewer'))
|
|
return false
|
|
|
|
// blur focused element, if nothing focused close...
|
|
} else if(toggleEditor('?') == 'on'){
|
|
$(':focus').blur()
|
|
return false
|
|
}
|
|
}),
|
|
},
|
|
|
|
|
|
// NOTE: need to keep all info modes before the rest so as to give
|
|
// their bindings priority...
|
|
'Drawer views': {
|
|
doc: 'NOTE: In this view all other key bindings are disabled, '+
|
|
'except app defaults and the ones explicitly defined here.',
|
|
pattern: '.drawer-mode',
|
|
|
|
ignore: '*',
|
|
|
|
Esc: doc('Close drawer',
|
|
function(){
|
|
toggleKeyboardHelp('off')
|
|
return false
|
|
}),
|
|
Q: 'Esc',
|
|
},
|
|
|
|
|
|
'Slideshow view': {
|
|
doc: 'To enter this view press <b>S</b>.',
|
|
pattern: '.slideshow-mode',
|
|
|
|
// XXX think about what else to disable here...
|
|
ignore: [
|
|
'Up', 'Down', 'Enter', 'R', 'L',
|
|
],
|
|
|
|
L: doc('Toggle slideshow looping',
|
|
function(){
|
|
SLIDESHOW_LOOP = SLIDESHOW_LOOP ? false : true
|
|
showStatus('Slideshow: looping', SLIDESHOW_LOOP ? 'enabled...' : 'disabled...')
|
|
return false
|
|
}),
|
|
R: doc('Reverse slideshow direction',
|
|
function(){
|
|
SLIDESHOW_DIRECTION = SLIDESHOW_DIRECTION == 'next' ? 'prev' : 'next'
|
|
showStatus('Slideshow: direction:', SLIDESHOW_DIRECTION + '...')
|
|
return false
|
|
}),
|
|
Esc: doc('Exit/stop slideshow',
|
|
function(){
|
|
toggleSlideShowMode('off')
|
|
return false
|
|
}),
|
|
S: 'Esc',
|
|
Q: 'Esc',
|
|
},
|
|
|
|
|
|
'Single image view': {
|
|
doc: 'To toggle between this and ribbon view press <b>Enter</b>.',
|
|
pattern: '.single-image-mode',
|
|
|
|
Esc: doc('Exit single image view',
|
|
function(){
|
|
toggleSingleImageMode('off')
|
|
return false
|
|
}),
|
|
Q: 'Esc',
|
|
},
|
|
|
|
|
|
'Cropped ribbon views': {
|
|
doc: 'To crop marked images press <b>shift-F2</b> for '+
|
|
'single ribbon crop view press <b>F3</b> and to open the crop '+
|
|
'dialog for more options press <b>C</b>.'+
|
|
'<p>NOTE: toggling crop views is only possible from ribbon view.',
|
|
pattern: '.single-ribbon-mode:not(.single-image-mode), '
|
|
+'.marked-only-view:not(.single-image-mode)',
|
|
|
|
Esc: {
|
|
default: doc('Uncrop to last state',
|
|
function(){
|
|
uncropLastState()
|
|
return false
|
|
}),
|
|
shift: doc('Exit crop view',
|
|
function(){
|
|
toggleMarkedOnlyView('off')
|
|
toggleSingleRibbonMode('off')
|
|
return false
|
|
}),
|
|
},
|
|
Q: 'Esc',
|
|
},
|
|
|
|
|
|
// visible marks...
|
|
//
|
|
/* XXX does this work???
|
|
* ...appears to be overtaken by every Esc definition before,
|
|
* and every single one of them returns false...
|
|
'.marks-visible': {
|
|
title: 'Visible marks',
|
|
|
|
Esc: doc('Hide marks',
|
|
function(){
|
|
toggleMarksView('off')
|
|
return false
|
|
}),
|
|
},
|
|
*/
|
|
|
|
|
|
// NOTE: these bindings apply ONLY to ribbon view...
|
|
// XXX this breaks getKeyHandlers(...) when modes argument is given...
|
|
'Ribbon view': {
|
|
pattern: '.viewer:not(.overlay):not(.single-image-mode)',
|
|
ignore: [ '#1', '#2', '#3', '#4', '#5', '#6', '#7', '#8', '#9', '#0' ],
|
|
|
|
Left: {
|
|
// XXX revise...
|
|
alt: doc('Shift image left',
|
|
function(){
|
|
event.preventDefault()
|
|
shiftImageLeft()
|
|
centerView(null, 'css')
|
|
// XXX for some odd reason centerRibbons does
|
|
// something really odd here -- images get to
|
|
// correct positions but the align is totally
|
|
// wrong...
|
|
// ...race condition???
|
|
//centerRibbons()
|
|
// XXX HACK...
|
|
if(window._center_ribbon_delay != null){
|
|
clearTimeout(_center_ribbon_delay)
|
|
}
|
|
_center_ribbon_delay = setTimeout(
|
|
function(){
|
|
centerRibbons()
|
|
}, 300)
|
|
|
|
return false
|
|
}),
|
|
ctrl: 'prev-screen',
|
|
},
|
|
Right: {
|
|
// XXX revise...
|
|
alt: doc('Shift image right',
|
|
function(){
|
|
event.preventDefault()
|
|
shiftImageRight()
|
|
centerView(null, 'css')
|
|
// XXX for some odd reason centerRibbons does
|
|
// something really odd here -- images get to
|
|
// correct positions but the align is totally
|
|
// wrong...
|
|
// ...race condition???
|
|
//centerRibbons()
|
|
// XXX HACK...
|
|
if(window._center_ribbon_delay != null){
|
|
clearTimeout(_center_ribbon_delay)
|
|
}
|
|
_center_ribbon_delay = setTimeout(
|
|
function(){
|
|
centerRibbons()
|
|
}, 300)
|
|
|
|
return false
|
|
}),
|
|
ctrl: 'next-screen',
|
|
},
|
|
'prev-screen': doc('Previous screen',
|
|
function(){
|
|
event.preventDefault()
|
|
prevScreenImages()
|
|
centerRibbons()
|
|
}),
|
|
'next-screen': doc('Next screen',
|
|
function(){
|
|
event.preventDefault()
|
|
nextScreenImages()
|
|
centerRibbons()
|
|
}),
|
|
Space: {
|
|
// screen-oriented movement...
|
|
ctrl: 'Right',
|
|
'ctrl+shift': 'prev-screen',
|
|
},
|
|
Backspace: {
|
|
// screen-oriented movement...
|
|
ctrl: 'Left',
|
|
'ctrl+shift': 'next-screen',
|
|
},
|
|
|
|
// align to base ribbon...
|
|
// XXX base ribbon concept is not yet fully defined...
|
|
Down: {
|
|
'ctrl+alt': doc('Align sorted section to current ribbon (EXPERIMENTAL)',
|
|
function(){
|
|
alignRibbons()
|
|
}),
|
|
},
|
|
|
|
// zooming...
|
|
'#1': doc('Fit one image', function(){ fitNImages(1) }),
|
|
'#2': doc('Fit two images', function(){ fitNImages(2) }),
|
|
'#3': doc('Fit three images', function(){ fitNImages(3) }),
|
|
'#4': doc('Fit four images', function(){ fitNImages(4) }),
|
|
'#5': doc('Fit five images', function(){ fitNImages(5) }),
|
|
'#6': doc('Fit six images', function(){ fitNImages(6) }),
|
|
'#7': doc('Fit seven images', function(){ fitNImages(7) }),
|
|
'#8': doc('Fit eight images', function(){ fitNImages(8) }),
|
|
'#9': doc('Fit nine images', function(){ fitNImages(9) }),
|
|
'#0': doc('Fit maximum images', function(){ fitNImages(getScreenWidthInImages(CONFIG.min_image_size)) }),
|
|
|
|
// cropping...
|
|
C: doc('Show ribbon crop dialog', cropImagesDialog),
|
|
F: doc('Filter images', filterImagesDialog),
|
|
|
|
// XXX add a non FXX key for macs...
|
|
F2: {
|
|
shift: doc('Crop marked only images',
|
|
function(){
|
|
toggleMarkedOnlyView('on')
|
|
// prevent the default from the main mode from
|
|
// getting called...
|
|
return false
|
|
}),
|
|
},
|
|
|
|
// XXX add a non FXX key for macs...
|
|
F3: doc('Crop single ribbon',
|
|
function(){
|
|
event.preventDefault()
|
|
toggleSingleRibbonMode('on')
|
|
}),
|
|
},
|
|
|
|
|
|
// general bindings...
|
|
//
|
|
'Viewer': {
|
|
doc: 'These key bindings work in most other viewer views.'+
|
|
|
|
'<p>NOTE: shifting all marked 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. ',
|
|
pattern: '.viewer:not(.overlay)',
|
|
|
|
// Basics...
|
|
// XXX STUB: use a real path browser...
|
|
O: doc('Open a directory path',
|
|
function(){
|
|
loadDirectoryDialog()
|
|
}),
|
|
|
|
|
|
// Navigation...
|
|
// XXX need to cancel the animation of the prev action...
|
|
Left: {
|
|
default: doc('Previous image',
|
|
function(){
|
|
event.preventDefault()
|
|
// update direction...
|
|
updateDirection('prev')
|
|
prevImage()
|
|
centerRibbons()
|
|
}),
|
|
|
|
// XXX button not final...
|
|
'ctrl+shift': doc('Previous URL in history', loadURLHistoryPrev ),
|
|
},
|
|
Right: {
|
|
default: doc('Next image',
|
|
function(){
|
|
event.preventDefault()
|
|
// update direction...
|
|
updateDirection('next')
|
|
nextImage()
|
|
centerRibbons()
|
|
}),
|
|
|
|
// XXX button not final...
|
|
'ctrl+shift': doc('Next URL in history', loadURLHistoryNext ),
|
|
},
|
|
Space: {
|
|
default: 'Right',
|
|
shift: 'Left',
|
|
},
|
|
Backspace: {
|
|
default: 'Left',
|
|
shift: 'Right',
|
|
},
|
|
Home: doc('First image',
|
|
function(){
|
|
event.preventDefault()
|
|
firstImage()
|
|
centerRibbons()
|
|
}),
|
|
End: doc('Last image',
|
|
function(){
|
|
event.preventDefault()
|
|
lastImage()
|
|
centerRibbons()
|
|
}),
|
|
|
|
// bookmark navigation...
|
|
'[': doc('Previous bookmarked image',
|
|
function(){ prevBookmark() }),
|
|
']': doc('Next bookmarked image',
|
|
function(){ nextBookmark() }),
|
|
|
|
// marked/unmarked navigation...
|
|
',': {
|
|
default: doc('Previous marked image',
|
|
function(){ prevMark() }),
|
|
shift: doc('Previous unmarked image',
|
|
function(){ prevUnmarked() }),
|
|
},
|
|
'.': {
|
|
default: doc('Next marked image',
|
|
function(){ nextMark() }),
|
|
shift: doc('Next unmarked image',
|
|
function(){ nextUnmarked() }),
|
|
},
|
|
|
|
// sorted section navigation...
|
|
'{': doc('Previous unsorted section edge',
|
|
function(){ prevUnsortedSection() }),
|
|
'}': doc('Next unsorted section edge',
|
|
function(){ nextUnsortedSection() }),
|
|
|
|
|
|
// combined navigation and editor actions...
|
|
Up: {
|
|
default: doc('Go to ribbon above',
|
|
function(){
|
|
event.preventDefault()
|
|
prevRibbon()
|
|
centerRibbons()
|
|
}),
|
|
shift: doc('Shift image up',
|
|
function(){
|
|
event.preventDefault()
|
|
shiftImageUp(null, DIRECTION)
|
|
centerRibbons()
|
|
}),
|
|
'ctrl+shift': doc('Shift image up to new ribbon',
|
|
function(){
|
|
event.preventDefault()
|
|
shiftImageUpNewRibbon(null, DIRECTION)
|
|
centerRibbons()
|
|
}),
|
|
alt: doc('Shift marked images up',
|
|
function(){
|
|
toggleMarksView('on')
|
|
shiftMarkedImagesUp()
|
|
}),
|
|
'alt+shift': doc('Shift marked images up to new ribbon',
|
|
function(){
|
|
// XXX
|
|
}),
|
|
},
|
|
Down: {
|
|
default: doc('Go to ribbon below',
|
|
function(){
|
|
event.preventDefault()
|
|
nextRibbon()
|
|
centerRibbons()
|
|
}),
|
|
shift: doc('Shift image down',
|
|
function(){
|
|
event.preventDefault()
|
|
shiftImageDown(null, DIRECTION)
|
|
centerRibbons()
|
|
}),
|
|
'ctrl+shift': doc('Shift image down to new ribbon',
|
|
function(){
|
|
event.preventDefault()
|
|
shiftImageDownNewRibbon(null, DIRECTION)
|
|
centerRibbons()
|
|
}),
|
|
alt: doc('Shift marked images down',
|
|
function(){
|
|
toggleMarksView('on')
|
|
shiftMarkedImagesDown()
|
|
}),
|
|
'alt+shift': doc('Shift marked images down to new ribbon',
|
|
function(){
|
|
// XXX
|
|
}),
|
|
},
|
|
|
|
L: doc('Rotate image left', function(){ rotateLeft() }),
|
|
R: {
|
|
default: doc('Rotate image right',
|
|
function(){ rotateRight() }),
|
|
ctrl: doc('Reverse image order',
|
|
function(){
|
|
event.preventDefault()
|
|
reverseImageOrder()
|
|
}),
|
|
},
|
|
H: {
|
|
default: doc('Flip image horizontally',
|
|
function(){
|
|
var o = getImage().attr('orientation')
|
|
// need to rotate relative to user, not relative to image...
|
|
if(o == 90 || o == 270){
|
|
flipVertical()
|
|
} else {
|
|
flipHorizontal()
|
|
}
|
|
}),
|
|
ctrl: doc('Show recently opend urls',
|
|
function(){
|
|
recentlyOpenedDialog()
|
|
}),
|
|
},
|
|
V: doc('Flip image vertically',
|
|
function(){
|
|
var o = getImage().attr('orientation')
|
|
// need to rotate relative to user, not relative to image...
|
|
if(o == 90 || o == 270){
|
|
flipHorizontal()
|
|
} else {
|
|
flipVertical()
|
|
}
|
|
}),
|
|
|
|
|
|
// zooming...
|
|
'#1': doc('Fit image to screen', function(){ fitNImages(1) }),
|
|
'#2': doc('Show big image',
|
|
function(){
|
|
fitNImages(CONFIG.single_image_view_scale_2)
|
|
}),
|
|
'#3': doc('Show small image',
|
|
function(){
|
|
fitNImages(CONFIG.single_image_view_scale_3)
|
|
}),
|
|
|
|
'-': doc('Zoom in', function(){ zoomOut() }),
|
|
'=': doc('Zoom out', function(){ zoomIn() }),
|
|
|
|
|
|
Enter: doc('Toggle single image view',
|
|
function(){ toggleSingleImageMode() }),
|
|
|
|
B: {
|
|
default: doc('Toggle theme',
|
|
function(){ toggleTheme() }),
|
|
ctrl: doc('Toggle bookmark',
|
|
function(){ toggleBookmark() }),
|
|
},
|
|
|
|
S: {
|
|
default: doc('Start slideshow',
|
|
function(){ toggleSlideShowMode('on') }),
|
|
shift: doc('Sort images',
|
|
function(){
|
|
sortImagesDialog()
|
|
}),
|
|
ctrl: doc('Save current state',
|
|
function(){
|
|
event.preventDefault()
|
|
|
|
showStatusQ('Saving: localStorage: Settings.')
|
|
saveLocalStorageSettings()
|
|
|
|
saveFileState()
|
|
|
|
showStatusQ('Saving: Done.')
|
|
}),
|
|
'ctrl+shift': doc('Export',
|
|
function(){
|
|
exportPreviewsDialog()
|
|
}),
|
|
// NOTE: this will not delete anything, just merge all the diffs
|
|
// into a single, redundent images.json.
|
|
// this will make loading faster...
|
|
'ctrl+alt': doc('Compact image data.',
|
|
function(){
|
|
showStatusQ('Merging: images diffs.')
|
|
saveFileImages()
|
|
}),
|
|
},
|
|
Z: {
|
|
ctrl: doc('Restore to last saved state',
|
|
function(){
|
|
loadLocalStorage()
|
|
loadLocalStorageMarks()
|
|
})
|
|
},
|
|
|
|
|
|
// marking...
|
|
// XXX not final, think of a better way to do this...
|
|
// XXX need mark navigation...
|
|
// XXX need marked image shift up/down actions...
|
|
// XXX unmarking an image in marked-only mode results in nothing
|
|
// visible focused if we unmark the first or last image in
|
|
// the ribbon...
|
|
M: {
|
|
// NOTE: marking moves in the same direction as the last
|
|
// move...
|
|
// i.e. marking can change direction depending on where
|
|
// we moved last...
|
|
// NOTE: marking does not change move direction...
|
|
// XXX should this toggle or set mark to on?
|
|
default: doc('Mark current image and advance',
|
|
function(){
|
|
toggleMark('on')
|
|
directionImage()
|
|
// XXX do we need this???
|
|
//if(getImage().filter(':visible').length == 0){
|
|
// centerView(focusImage(getImageBefore()))
|
|
//}
|
|
centerRibbons()
|
|
}),
|
|
// same as default but in reverse direction...
|
|
shift: doc('Mark current image and return',
|
|
function(){
|
|
toggleMark('on')
|
|
directionImage(true)
|
|
// XXX do we need this???
|
|
//if(getImage().filter(':visible').length == 0){
|
|
// centerView(focusImage(getImageBefore()))
|
|
//}
|
|
centerRibbons()
|
|
}),
|
|
ctrl: doc('Show mark dialog', function(){ markImagesDialog() }),
|
|
},
|
|
Ins: doc('Toggle mark on current image', function(){ toggleMark() }),
|
|
'invert-marks': doc('Invert image marks',
|
|
function(){ invertImageMarks() }),
|
|
A: {
|
|
// XXX does not yet work with DATA (???)
|
|
//shift: doc('Toggle marks in current contagious block',
|
|
// function(){ toggleMarkBlock() }),
|
|
|
|
ctrl: doc('Mark current ribbon',
|
|
function(){
|
|
toggleMarksView('on')
|
|
markAll('ribbon')
|
|
}),
|
|
'ctrl+shift': doc('Mark all images',
|
|
function(){
|
|
toggleMarksView('on')
|
|
markAll('all')
|
|
}),
|
|
},
|
|
|
|
'unmark-ribbon': doc('Unmark current ribbon',
|
|
function(){
|
|
event.preventDefault()
|
|
unmarkAll('ribbon')
|
|
}),
|
|
'unmark-all': doc('Unmark all images',
|
|
function(){ unmarkAll('all') }),
|
|
|
|
D: {
|
|
ctrl: 'unmark-ribbon',
|
|
'ctrl+shift': 'unmark-all',
|
|
|
|
},
|
|
U: {
|
|
default: doc('Unmark current image',
|
|
function(){ toggleMark('off') }),
|
|
ctrl: 'unmark-ribbon',
|
|
shift: 'unmark-all',
|
|
},
|
|
|
|
|
|
// XXX add a non FXX key for macs...
|
|
F2: doc('Toggle mark visibility',
|
|
function(){ toggleMarksView() }),
|
|
// XXX should we be able to toggle crop modes from single image mode???
|
|
// ...if yes, then remove the F2 & F3 definitions form ribbon
|
|
// mode...
|
|
// one way to go is to exit single-image-mode on s-f2 or f3...
|
|
/*
|
|
F2: {
|
|
default: doc('Toggle mark visibility',
|
|
function(){ toggleMarksView() }),
|
|
shift: doc('Crop marked only images',
|
|
function(){
|
|
toggleMarkedOnlyView('on')
|
|
}),
|
|
},
|
|
|
|
F3: doc('Crop single ribbon',
|
|
function(){
|
|
event.preventDefault()
|
|
toggleSingleRibbonMode('on')
|
|
}),
|
|
*/
|
|
|
|
E: {
|
|
default: doc('Open image in external software', openImage),
|
|
// XXX Experimental
|
|
ctrl: doc('Open preview editor panel (Experimental)',
|
|
function(){ toggleEditor() }),
|
|
},
|
|
// XXX make F4 a default editor and E a default viewer...
|
|
F4: 'E',
|
|
|
|
// info...
|
|
I: {
|
|
default: doc('Show current image info',
|
|
function(){
|
|
showImageInfo()
|
|
//toggleImageInfoDrawer()
|
|
}),
|
|
shift: doc('Toggle image info display',
|
|
function(){ toggleImageInfo() }),
|
|
alt: doc('Toggle inline image info display',
|
|
function(){
|
|
toggleInlineImageInfo()
|
|
}),
|
|
|
|
// marking...
|
|
ctrl: 'invert-marks',
|
|
},
|
|
P: {
|
|
default: doc('Show panel list',
|
|
function(){
|
|
panelListDialog()
|
|
}),
|
|
shift: doc('Show options',
|
|
function(){
|
|
toggleOptionsUI()
|
|
}),
|
|
ctrl: doc('Print keyboard help',
|
|
function(){
|
|
toggleKeyboardHelp('on')
|
|
// NOTE: on chrome this is blocking...
|
|
print()
|
|
toggleKeyboardHelp('off')
|
|
}),
|
|
},
|
|
|
|
// Help and info...
|
|
'?': doc('Show keyboard bindings',
|
|
function(){ toggleKeyboardHelp() }),
|
|
|
|
// XXX add a non FXX key for macs...
|
|
F1: doc('Show help',
|
|
function(){ toggleHelp() }),
|
|
|
|
|
|
// XXX DEBUG MODE...
|
|
// ...remove these in production...
|
|
//F12: doc('Show devTools', function(){ showDevTools() }),
|
|
//F5: doc('Reload app', function(){ reload() }),
|
|
|
|
/* testing the shift-key feature...
|
|
'~': {
|
|
default: function(){ alert('~') },
|
|
// this is inaccessible...
|
|
shift: function(){ alert('shift-~') },
|
|
ctrl: function(){ alert('ctrl-~') },
|
|
'ctrl+alt': function(){ alert('ctrl-alt-~') },
|
|
},
|
|
'`': {
|
|
default: function(){ alert('`') },
|
|
// this is also not accessible as it is shadowed by '''...
|
|
shift: function(){ alert('shift-`') },
|
|
ctrl: function(){ alert('ctrl-`') },
|
|
'ctrl+alt': function(){ alert('ctrl-alt-`') },
|
|
},
|
|
*/
|
|
},
|
|
|
|
'.image': {
|
|
'#1': doc('mooo!')
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
* vim:set ts=4 sw=4 : */
|