moved keyboard and demo data to features, some refactoring and cleanup...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2016-04-02 17:34:25 +03:00
parent 2738b470ec
commit af7a8cf51f
10 changed files with 436 additions and 285 deletions

48
ui (gen4)/features/_feature.js Executable file
View File

@ -0,0 +1,48 @@
/**********************************************************************
*
*
*
**********************************************************************/
define(function(require){ var module = {}
//var DEBUG = DEBUG != null ? DEBUG : true
var actions = require('lib/actions')
var features = require('lib/features')
var core = require('features/core')
/*********************************************************************/
var FeatureActions = actions.Actions({
emptyAction: ['- Demo/Empty action',
function(){
// XXX
}],
})
var Feature =
module.Feature = core.ImageGridFeatures.Feature({
title: '',
doc: '',
// XXX
tag: 'feature-tag',
depends: [
// XXX
],
actions: FeatureActions,
handlers: [],
})
/**********************************************************************
* vim:set ts=4 sw=4 : */
return module })

View File

@ -15,6 +15,7 @@ var location = require('features/location')
var history = require('features/history') var history = require('features/history')
var app = require('features/app') var app = require('features/app')
var ui = require('features/ui') var ui = require('features/ui')
var keyboard = require('features/keyboard')
var status = require('features/ui-status') var status = require('features/ui-status')
var marks = require('features/ui-marks') var marks = require('features/ui-marks')
var widgets = require('features/ui-widgets') var widgets = require('features/ui-widgets')

View File

@ -10,7 +10,6 @@ define(function(require){ var module = {}
var actions = require('lib/actions') var actions = require('lib/actions')
var features = require('lib/features') var features = require('lib/features')
var toggler = require('lib/toggler')
var data = require('data') var data = require('data')
var images = require('images') var images = require('images')

345
ui (gen4)/features/keyboard.js Executable file
View File

@ -0,0 +1,345 @@
/**********************************************************************
*
*
*
**********************************************************************/
define(function(require){ var module = {}
//var DEBUG = DEBUG != null ? DEBUG : true
var actions = require('lib/actions')
var features = require('lib/features')
var toggler = require('lib/toggler')
var keyboard = require('lib/keyboard')
var core = require('features/core')
/*********************************************************************/
// XXX add this to the global doc...
var GLOBAL_KEYBOARD =
module.GLOBAL_KEYBOARD = {
'Slideshow': {
pattern: '.slideshow-running',
ignore: [
'Up', 'Down', 'Enter',
'R', 'L',
],
Esc: 'toggleSlideshow: "off"',
Enter: 'slideshowDialog',
Left: 'resetSlideshowTimer',
Right: 'resetSlideshowTimer',
Home: 'resetSlideshowTimer',
End: 'resetSlideshowTimer',
R: 'toggleSlideshowDirection',
L: 'toggleSlideshowLooping',
},
'Global': {
doc: 'NOTE: binding priority is the same as the order of sections '+
'on this page.',
pattern: '*',
F4: {
alt: 'close',
},
Q: {
meta: 'close',
},
F5: keyboard.doc('Full reload viewer',
function(){
//a.stop()
/*
killAllWorkers()
.done(function(){
reload()
})
*/
location.reload()
return false
}),
F12: 'showDevTools',
// NOTE: these are for systems where F** keys are not available
// or do other stuff...
R: {
default: 'rotateCW',
shift: 'reverseImages',
ctrl: 'reload!',
'ctrl+shift': 'F5',
},
L: 'rotateCCW',
H: {
default: 'flipHorizontal',
ctrl: 'listURLHistory',
alt: 'browseActions: "/History/"',
},
V: 'flipVertical',
P: {
'ctrl+shift': 'F12',
},
// NOTE: this is handled by the wrapper at this point, so we do
// not have to do anything here...
F11: 'toggleFullScreen',
F: {
ctrl: 'F11',
meta: 'F11',
},
// XXX testing...
Enter: 'toggleSingleImage',
Home: {
default: 'firstImage',
ctrl: 'firstGlobalImage',
shift: 'firstRibbon',
},
End: {
default: 'lastImage',
ctrl: 'lastGlobalImage',
shift: 'lastRibbon',
},
Left: {
default: 'prevImage',
alt: 'shiftImageLeft!',
ctrl: 'prevScreen',
// XXX need to prevent default on mac + browser...
meta: 'prevScreen',
},
PgUp: 'prevScreen',
PgDown: 'nextScreen',
Right: {
default: 'nextImage',
alt: 'shiftImageRight!',
ctrl: 'nextScreen',
// XXX need to prevent default on mac + browser...
meta: 'nextScreen',
},
'(': 'prevImageInOrder',
')': 'nextImageInOrder',
',': 'prevMarked',
'.': 'nextMarked',
'[': 'prevBookmarked',
']': 'nextBookmarked',
Up: {
default: 'prevRibbon',
shift: 'shiftImageUp',
'alt+shift': 'travelImageUp',
'ctrl+shift': 'shiftImageUpNewRibbon',
},
Down: {
default: 'nextRibbon',
shift: 'shiftImageDown',
'alt+shift': 'travelImageDown',
'ctrl+shift': 'shiftImageDownNewRibbon',
},
'#0': 'fitMax',
'#1': {
default: 'fitImage',
shift: 'fitRibbon',
ctrl: 'fitOrig!',
},
'#2': 'fitImage: 2',
'#3': {
default: 'fitImage: 3',
shift: 'fitRibbon: 3.5',
},
'#4': 'fitImage: 4',
'#5': {
default: 'fitImage: 5',
shift: 'fitRibbon: 5.5',
},
'#6': 'fitImage: 6',
'#7': 'fitImage: 7',
'#8':'fitImage: 8',
'#9': 'fitImage: 9',
'+': 'zoomIn',
'=': '+',
'-': 'zoomOut',
F2: {
default: 'cropRibbon',
shift: 'cropRibbonAndAbove',
ctrl: 'cropMarked',
alt: 'cropBookmarked',
},
Esc: {
default: 'uncrop',
ctrl: 'uncropAll',
},
// marking...
M: {
default: 'toggleMark',
alt: 'browseActions: "/Mark/"',
},
A: {
alt: 'browseActions',
'alt+shift': 'listActions',
ctrl: 'toggleMark!: "ribbon" "on"',
},
D: {
ctrl: 'toggleMark!: "ribbon" "off"',
},
I: {
default: 'showMetadata',
shift: 'toggleStatusBar',
ctrl: 'toggleMark!: "ribbon"',
'ctrl+shift': 'showMetadata: "current" "full"',
'meta+alt': 'showDevTools',
},
B: {
default: 'toggleBookmark',
ctrl: 'toggleTheme!',
alt: 'browseActions: "/Bookmark/"',
},
E: {
default: 'openInExtenalEditor',
shift: 'openInExtenalEditor: 1',
alt: 'listExtenalEditors',
},
C: 'browseActions: "/Crop/"',
O: 'browsePath',
S: {
//default: 'browseActions: "/Slideshow/"',
default: 'slideshowDialog',
// XXX need to make this save to base_path if it exists and
// ask the user if it does not... now it always asks.
ctrl: 'saveIndexHere',
'ctrl+shift': 'browseSaveIndex',
},
// XXX still experimental...
U: {
default: 'undoLast',
shift: 'redoLast',
},
Z: {
ctrl: 'undoLast',
'ctrl+shift': 'redoLast',
},
G: {
default: 'editStatusBarIndex!',
shift: 'toggleStatusBarIndexMode!',
// XXX for debug...
ctrl: function(){ $('.viewer').toggleClass('visible-gid') },
},
},
}
/*********************************************************************/
var KeyboardActions = actions.Actions({
config: {
// limit key repeat to one per N milliseconds.
//
// Set this to -1 or null to run keys without any limitations.
'max-key-repeat-rate': 0,
},
get keyboard(){
return this.__keyboard_config
},
toggleKeyboardHandling: ['- Interface/Toggle keyboard handling',
toggler.Toggler(null, function(_, state){
if(state == null){
return this.__keyboard_handler ? 'on' : 'off'
}
// XXX this does not work yet...
//var target = this.ribbons.viewer
var target = $(document)
// start/reset keyboard handling...
if(state == 'on'){
var that = this
// need to reset...
if(this.__keyboard_handler != null){
target.off('keydown', this.__keyboard_handler)
}
// setup base keyboard for devel, in case something breaks...
// This branch does not drop keys...
if(this.config['max-key-repeat-rate'] < 0
|| this.config['max-key-repeat-rate'] == null){
//this.ribbons.viewer
var handler =
this.__keyboard_handler =
keyboard.makeKeyboardHandler(
function(){ return that.__keyboard_config },
function(k){ window.DEBUG && console.log(k) },
this)
// drop keys if repeating too fast...
// NOTE: this is done for smoother animations...
} else {
var handler =
this.__keyboard_handler =
keyboard.dropRepeatingkeys(
keyboard.makeKeyboardHandler(
function(){ return that.__keyboard_config },
function(k){ window.DEBUG && console.log(k) },
this),
function(){
return that.config['max-key-repeat-rate']
})
}
target.keydown(handler)
// stop keyboard handling...
} else {
target.off('keydown', this.__keyboard_handler)
delete this.__keyboard_handler
}
},
['on', 'off'])]
})
var Keyboard =
module.Keyboard = core.ImageGridFeatures.Feature({
title: '',
doc: '',
tag: 'keyboard',
depends: [
'ui'
],
actions: KeyboardActions,
handlers: [
['start',
function(){
var that = this
this.__keyboard_config = this.keyboard || GLOBAL_KEYBOARD
this.toggleKeyboardHandling('on')
}]
],
})
/**********************************************************************
* vim:set ts=4 sw=4 : */
return module })

View File

@ -52,6 +52,7 @@ core.ImageGridFeatures.Feature('viewer-testing', [
'workspace', 'workspace',
'ui', 'ui',
'keyboard',
'ui-ribbons-placement', 'ui-ribbons-placement',

View File

@ -180,16 +180,16 @@ var StatusBarActions = actions.Actions({
// global index... // global index...
if(cls == 'global'){ if(cls == 'global'){
item.find('.position:not(:focus)') item.find('.position:not(:focus)')
.text(this.data.getImageOrder(gid)+1) .text(this.data ? this.data.getImageOrder(gid)+1 : 0)
item.find('.length') item.find('.length')
.text('/'+ this.data.length) .text('/'+ (this.data ? this.data.length : 0))
// ribbon index... // ribbon index...
} else { } else {
item.find('.position:not(:focus)') item.find('.position:not(:focus)')
.text(this.data.getImageOrder('ribbon', gid)+1) .text(this.data ? this.data.getImageOrder('ribbon', gid)+1 : 0)
item.find('.length') item.find('.length')
.text('/'+ this.data.getImages(gid).len) .text('/'+ (this.data ? this.data.getImages(gid).len : 0))
} }
return item return item
@ -272,7 +272,7 @@ var StatusBarActions = actions.Actions({
// them here... // them here...
// ...this also simpler than handling '?' and other // ...this also simpler than handling '?' and other
// special toggler args in the handler... // special toggler args in the handler...
var tags = this.data.getTags(gid) var tags = this.data ? this.data.getTags(gid) : []
var tag = type == 'mark' ? 'selected' : 'bookmark' var tag = type == 'mark' ? 'selected' : 'bookmark'
item[tags.indexOf(tag) < 0 ? item[tags.indexOf(tag) < 0 ?
'removeClass' 'removeClass'
@ -287,8 +287,14 @@ var StatusBarActions = actions.Actions({
// reconstruct all the items. // reconstruct all the items.
toggleStatusBar: ['Interface/Toggle status bar modes', toggleStatusBar: ['Interface/Toggle status bar modes',
toggler.CSSClassToggler( toggler.CSSClassToggler(
// get/construct status bar...
// XXX change class... // XXX change class...
function(){ function(){
// no viewer yet...
if(!this.ribbons || !this.ribbons.viewer){
return $()
}
var bar = this.ribbons.viewer.find('.state-indicator-container.global-info') var bar = this.ribbons.viewer.find('.state-indicator-container.global-info')
if(bar.length == 0){ if(bar.length == 0){
bar = makeStateIndicator('global-info overlay-info') bar = makeStateIndicator('global-info overlay-info')
@ -466,7 +472,7 @@ module.StatusBar = core.ImageGridFeatures.Feature({
function(){ function(){
this.toggleStatusBar(this.config['status-bar-mode']) this.toggleStatusBar(this.config['status-bar-mode'])
}], }],
['focusImage', ['focusImage clear',
function(){ function(){
this.updateStatusBar() this.updateStatusBar()
}], }],

View File

@ -135,13 +135,6 @@ module.ViewerActions = actions.Actions({
'fit-overflow': 0.2, 'fit-overflow': 0.2,
// limit key repeat to one per N milliseconds.
//
// Set this to -1 or null to run keys without any limitations.
// XXX at this point the keyboard is setup in ui.js, need to
// move to a more logical spot...
'max-key-repeat-rate': 0,
// Theme to set on startup... // Theme to set on startup...
'theme': null, 'theme': null,

20
ui (gen4)/lib/_module.js Executable file
View File

@ -0,0 +1,20 @@
/**********************************************************************
*
*
*
**********************************************************************/
define(function(require){ var module = {}
console.log('>>> viewer')
//var DEBUG = DEBUG != null ? DEBUG : true
/*********************************************************************/
/**********************************************************************
* vim:set ts=4 sw=4 : */
return module })

View File

@ -669,6 +669,10 @@ function makeKeyboardHandler(keybindings, unhandled, actions){
var did_handling = false var did_handling = false
var res = null var res = null
var _keybindings = typeof(keybindings) == typeof(function(){}) ?
keybindings.call(this)
: keybindings
// key data... // key data...
var key = evt.keyCode var key = evt.keyCode
@ -677,7 +681,7 @@ function makeKeyboardHandler(keybindings, unhandled, actions){
//window.DEBUG && console.log('KEY:', key, chr, modifiers) //window.DEBUG && console.log('KEY:', key, chr, modifiers)
var handlers = getKeyHandlers(key, modifiers, keybindings, null, null, actions) var handlers = getKeyHandlers(key, modifiers, _keybindings, null, null, actions)
for(var mode in handlers){ for(var mode in handlers){
var handler = handlers[mode] var handler = handlers[mode]
@ -691,7 +695,7 @@ function makeKeyboardHandler(keybindings, unhandled, actions){
did_handling = true did_handling = true
//res = handler(evt) //res = handler(evt)
res = handler.call(keybindings) res = handler.call(_keybindings)
if(res === false){ if(res === false){
break break

View File

@ -48,243 +48,6 @@ var viewer = require('viewer')
/*********************************************************************/
// XXX move this to config...
// NOTE: setting this here (and only here) to -1 or null will desable
// key dropping...
// NOTE: keeping this disabled is recommended for development...
// NOTE: setting this to 0 will only allow a single keypress per
// execution frame...
// XXX yes there should be only one execution frame per event
// triggered but this actually improves things, thus the issue
// needs more investigation...
module.MAX_KEY_REPEAT_RATE = 0
// XXX add this to the global doc...
module.GLOBAL_KEYBOARD = {
'Slideshow': {
pattern: '.slideshow-running',
ignore: [
'Up', 'Down', 'Enter',
'R', 'L',
],
Esc: 'toggleSlideshow: "off"',
Enter: 'slideshowDialog',
Left: 'resetSlideshowTimer',
Right: 'resetSlideshowTimer',
Home: 'resetSlideshowTimer',
End: 'resetSlideshowTimer',
R: 'toggleSlideshowDirection',
L: 'toggleSlideshowLooping',
},
'Global': {
doc: 'NOTE: binding priority is the same as the order of sections '+
'on this page.',
pattern: '*',
F4: {
alt: 'close',
},
Q: {
meta: 'close',
},
F5: doc('Full reload viewer',
function(){
//a.stop()
/*
killAllWorkers()
.done(function(){
reload()
})
*/
location.reload()
return false
}),
F12: 'showDevTools',
// NOTE: these are for systems where F** keys are not available
// or do other stuff...
R: {
default: 'rotateCW',
shift: 'reverseImages',
ctrl: 'reload!',
'ctrl+shift': 'F5',
},
L: 'rotateCCW',
H: {
default: 'flipHorizontal',
ctrl: 'listURLHistory',
alt: 'browseActions: "/History/"',
},
V: 'flipVertical',
P: {
'ctrl+shift': 'F12',
},
// NOTE: this is handled by the wrapper at this point, so we do
// not have to do anything here...
F11: 'toggleFullScreen',
F: {
ctrl: 'F11',
meta: 'F11',
},
// XXX testing...
Enter: 'toggleSingleImage',
Home: {
default: 'firstImage',
ctrl: 'firstGlobalImage',
shift: 'firstRibbon',
},
End: {
default: 'lastImage',
ctrl: 'lastGlobalImage',
shift: 'lastRibbon',
},
Left: {
default: 'prevImage',
alt: 'shiftImageLeft!',
ctrl: 'prevScreen',
// XXX need to prevent default on mac + browser...
meta: 'prevScreen',
},
PgUp: 'prevScreen',
PgDown: 'nextScreen',
Right: {
default: 'nextImage',
alt: 'shiftImageRight!',
ctrl: 'nextScreen',
// XXX need to prevent default on mac + browser...
meta: 'nextScreen',
},
'(': 'prevImageInOrder',
')': 'nextImageInOrder',
',': 'prevMarked',
'.': 'nextMarked',
'[': 'prevBookmarked',
']': 'nextBookmarked',
Up: {
default: 'prevRibbon',
shift: 'shiftImageUp',
'alt+shift': 'travelImageUp',
'ctrl+shift': 'shiftImageUpNewRibbon',
},
Down: {
default: 'nextRibbon',
shift: 'shiftImageDown',
'alt+shift': 'travelImageDown',
'ctrl+shift': 'shiftImageDownNewRibbon',
},
'#0': 'fitMax',
'#1': {
default: 'fitImage',
shift: 'fitRibbon',
ctrl: 'fitOrig!',
},
'#2': 'fitImage: 2',
'#3': {
default: 'fitImage: 3',
shift: 'fitRibbon: 3.5',
},
'#4': 'fitImage: 4',
'#5': {
default: 'fitImage: 5',
shift: 'fitRibbon: 5.5',
},
'#6': 'fitImage: 6',
'#7': 'fitImage: 7',
'#8':'fitImage: 8',
'#9': 'fitImage: 9',
'+': 'zoomIn',
'=': '+',
'-': 'zoomOut',
F2: {
default: 'cropRibbon',
shift: 'cropRibbonAndAbove',
ctrl: 'cropMarked',
alt: 'cropBookmarked',
},
Esc: {
default: 'uncrop',
ctrl: 'uncropAll',
},
// marking...
M: {
default: 'toggleMark',
alt: 'browseActions: "/Mark/"',
},
A: {
alt: 'browseActions',
'alt+shift': 'listActions',
ctrl: 'toggleMark!: "ribbon" "on"',
},
D: {
ctrl: 'toggleMark!: "ribbon" "off"',
},
I: {
default: 'showMetadata',
shift: 'toggleStatusBar',
ctrl: 'toggleMark!: "ribbon"',
'ctrl+shift': 'showMetadata: "current" "full"',
'meta+alt': 'showDevTools',
},
B: {
default: 'toggleBookmark',
ctrl: 'toggleTheme!',
alt: 'browseActions: "/Bookmark/"',
},
E: {
default: 'openInExtenalEditor',
shift: 'openInExtenalEditor: 1',
alt: 'listExtenalEditors',
},
C: 'browseActions: "/Crop/"',
O: 'browsePath',
S: {
//default: 'browseActions: "/Slideshow/"',
default: 'slideshowDialog',
// XXX need to make this save to base_path if it exists and
// ask the user if it does not... now it always asks.
ctrl: 'saveIndexHere',
'ctrl+shift': 'browseSaveIndex',
},
// XXX still experimental...
U: {
default: 'undoLast',
shift: 'redoLast',
},
Z: {
ctrl: 'undoLast',
'ctrl+shift': 'redoLast',
},
G: {
default: 'editStatusBarIndex!',
shift: 'toggleStatusBarIndexMode!',
// XXX for debug...
ctrl: function(){ $('.viewer').toggleClass('visible-gid') },
},
},
}
/*********************************************************************/ /*********************************************************************/
$(function(){ $(function(){
@ -300,13 +63,14 @@ $(function(){
.setup([ .setup([
'viewer-testing', 'viewer-testing',
'demo',
// XXX this is not for production... // XXX this is not for production...
'experiments', 'experiments',
'demo',
]) ])
// used switch experimental actions on (set to true) or off (unset or false)... // used to switch experimental actions on (set to true) or off (unset or false)...
//a.experimental = true //a.experimental = true
@ -350,36 +114,6 @@ $(function(){
'Nothing loaded...', 'Nothing loaded...',
'Press \'O\' to load, \'F1\' for help or \'?\' for keyboard mappings.') 'Press \'O\' to load, \'F1\' for help or \'?\' for keyboard mappings.')
// setup base keyboard for devel, in case something breaks...
// This branch does not drop keys...
if(a.config['max-key-repeat-rate'] < 0 || a.config['max-key-repeat-rate'] == null){
$(document)
.keydown(
keyboard.makeKeyboardHandler(
module.GLOBAL_KEYBOARD,
function(k){
window.DEBUG && console.log(k)
},
a))
// drop keys if repeating too fast...
// NOTE: this is done for smoother animations...
} else {
$(document)
.keydown(
keyboard.dropRepeatingkeys(
keyboard.makeKeyboardHandler(
module.GLOBAL_KEYBOARD,
function(k){
window.DEBUG && console.log(k)
},
a),
function(){
return a.config['max-key-repeat-rate']
}))
}
}) })