mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-28 18:00:09 +00:00
reworked keyboard to support better searching for keys + added capslock state support...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
c64fe92afe
commit
b2c9a5cb34
@ -1482,6 +1482,23 @@ stretching in width... */
|
|||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Capslock indicator.. */
|
||||||
|
.overlay-info .capslock-state {
|
||||||
|
font-size: small;
|
||||||
|
font-style: italic;
|
||||||
|
margin: 0px 10pt;
|
||||||
|
}
|
||||||
|
.overlay-info .capslock-state:not(.on) {
|
||||||
|
opacity: 0.2;
|
||||||
|
}
|
||||||
|
.overlay-info .capslock-state.on {
|
||||||
|
color: yellow;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
.overlay-info .capslock-state:hover {
|
||||||
|
opacity: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************** Global status ***/
|
/*************************************************** Global status ***/
|
||||||
|
|||||||
@ -271,16 +271,20 @@ module.GLOBAL_KEYBOARD = {
|
|||||||
shift_End: 'lastRibbon',
|
shift_End: 'lastRibbon',
|
||||||
|
|
||||||
Up: 'prevRibbon',
|
Up: 'prevRibbon',
|
||||||
|
caps_shift_Up: 'prevRibbon',
|
||||||
Down: 'nextRibbon',
|
Down: 'nextRibbon',
|
||||||
|
caps_shift_Down: 'nextRibbon',
|
||||||
|
|
||||||
|
|
||||||
// shifting...
|
// shifting...
|
||||||
shift_Up: 'shiftImageUp',
|
shift_Up: 'shiftImageUp',
|
||||||
|
caps_Up: 'shiftImageUp',
|
||||||
alt_shift_Up: 'travelImageUp',
|
alt_shift_Up: 'travelImageUp',
|
||||||
ctrl_shift_Up: 'shiftImageUpNewRibbon',
|
ctrl_shift_Up: 'shiftImageUpNewRibbon',
|
||||||
ctrl_Up: 'shiftMarkedUp',
|
ctrl_Up: 'shiftMarkedUp',
|
||||||
|
|
||||||
shift_Down: 'shiftImageDown',
|
shift_Down: 'shiftImageDown',
|
||||||
|
caps_Down: 'shiftImageDown',
|
||||||
alt_shift_Down: 'travelImageDown',
|
alt_shift_Down: 'travelImageDown',
|
||||||
ctrl_shift_Down: 'shiftImageDownNewRibbon',
|
ctrl_shift_Down: 'shiftImageDownNewRibbon',
|
||||||
ctrl_Down: 'shiftMarkedDown',
|
ctrl_Down: 'shiftMarkedDown',
|
||||||
|
|||||||
@ -64,7 +64,6 @@ core.ImageGridFeatures.Feature('viewer-testing', [
|
|||||||
|
|
||||||
'ui-single-image',
|
'ui-single-image',
|
||||||
//'ui-partial-ribbons',
|
//'ui-partial-ribbons',
|
||||||
// XXX this is still experimental but seems to already work faster...
|
|
||||||
'ui-partial-ribbons-2',
|
'ui-partial-ribbons-2',
|
||||||
|
|
||||||
'marks',
|
'marks',
|
||||||
|
|||||||
@ -62,6 +62,7 @@ var StatusBarActions = actions.Actions({
|
|||||||
// separates left/right aligned elements...
|
// separates left/right aligned elements...
|
||||||
'---',
|
'---',
|
||||||
|
|
||||||
|
'edit-mode',
|
||||||
'mark',
|
'mark',
|
||||||
'bookmark',
|
'bookmark',
|
||||||
],
|
],
|
||||||
@ -90,7 +91,39 @@ var StatusBarActions = actions.Actions({
|
|||||||
},
|
},
|
||||||
|
|
||||||
__statusbar_elements__: {
|
__statusbar_elements__: {
|
||||||
|
/* item template...
|
||||||
|
item: function(item){
|
||||||
|
// cleanup...
|
||||||
|
if(item == null){
|
||||||
|
// XXX
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup the item DOM...
|
||||||
|
if(typeof(item) == typeof('str')){
|
||||||
|
var type = item
|
||||||
|
item = $('<span>')
|
||||||
|
.addClass('item-example')
|
||||||
|
.attr('type', item)
|
||||||
|
.text('example')
|
||||||
|
|
||||||
|
// get stuff from the item...
|
||||||
|
} else {
|
||||||
|
var type = item.attr('type')
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the item...
|
||||||
|
// XXX
|
||||||
|
|
||||||
|
return item
|
||||||
|
},
|
||||||
|
*/
|
||||||
index: function(item, gid, img){
|
index: function(item, gid, img){
|
||||||
|
// cleanup...
|
||||||
|
if(item == null){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var that = this
|
var that = this
|
||||||
gid = gid || this.current
|
gid = gid || this.current
|
||||||
|
|
||||||
@ -188,6 +221,11 @@ var StatusBarActions = actions.Actions({
|
|||||||
return item
|
return item
|
||||||
},
|
},
|
||||||
ribbon: function(item, gid, img){
|
ribbon: function(item, gid, img){
|
||||||
|
// cleanup...
|
||||||
|
if(item == null){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var that = this
|
var that = this
|
||||||
|
|
||||||
// get ribbon number...
|
// get ribbon number...
|
||||||
@ -248,6 +286,11 @@ var StatusBarActions = actions.Actions({
|
|||||||
return item
|
return item
|
||||||
},
|
},
|
||||||
changes: function(item, gid, img){
|
changes: function(item, gid, img){
|
||||||
|
// cleanup...
|
||||||
|
if(item == null){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if(typeof(item) == typeof('str')){
|
if(typeof(item) == typeof('str')){
|
||||||
item = $('<span>')
|
item = $('<span>')
|
||||||
.addClass('changes')
|
.addClass('changes')
|
||||||
@ -260,6 +303,11 @@ var StatusBarActions = actions.Actions({
|
|||||||
},
|
},
|
||||||
// XXX handle path correctly...
|
// XXX handle path correctly...
|
||||||
gid: function(item, gid, img){
|
gid: function(item, gid, img){
|
||||||
|
// cleanup...
|
||||||
|
if(item == null){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var that = this
|
var that = this
|
||||||
gid = gid || this.current
|
gid = gid || this.current
|
||||||
img = img || (this.images && gid in this.images && this.images[gid])
|
img = img || (this.images && gid in this.images && this.images[gid])
|
||||||
@ -309,8 +357,54 @@ var StatusBarActions = actions.Actions({
|
|||||||
return item
|
return item
|
||||||
},
|
},
|
||||||
path: 'gid',
|
path: 'gid',
|
||||||
|
'edit-mode': function(item){
|
||||||
|
// cleanup...
|
||||||
|
if(item == null){
|
||||||
|
this.__edit_mode_indicator_update
|
||||||
|
&& this.off('keyPress', this.__edit_mode_indicator_update)
|
||||||
|
delete this.__edit_mode_indicator_update
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var update = this.__edit_mode_indicator_update = this.__edit_mode_indicator_update
|
||||||
|
|| (function(){
|
||||||
|
var caps = this.keyboard.capslock
|
||||||
|
caps = typeof(event) != 'undefined' && event.getModifierState ?
|
||||||
|
event.getModifierState('CapsLock')
|
||||||
|
: caps
|
||||||
|
item
|
||||||
|
.attr('info', 'Edit mode '
|
||||||
|
+ (caps ? 'on' : 'off')
|
||||||
|
+ ' (Click to update / Press CapsLock to toggle)')
|
||||||
|
[caps ? 'addClass' : 'removeClass']('on')
|
||||||
|
}).bind(this)
|
||||||
|
|
||||||
|
|
||||||
|
if(typeof(item) == typeof('str')){
|
||||||
|
var type = item
|
||||||
|
item = $('<span>')
|
||||||
|
.addClass('capslock-state expanding-text')
|
||||||
|
.append($('<span class="shown">')
|
||||||
|
.text('E'))
|
||||||
|
.append($('<span class="hidden">')
|
||||||
|
.text('Edit mode'))
|
||||||
|
.click(update)
|
||||||
|
|
||||||
|
// XXX need a way to cleanly unhandle this...
|
||||||
|
this.on('keyPress', update)
|
||||||
|
}
|
||||||
|
|
||||||
|
update()
|
||||||
|
|
||||||
|
return item
|
||||||
|
},
|
||||||
// XXX show menu in the appropriate corner...
|
// XXX show menu in the appropriate corner...
|
||||||
mark: function(item, gid, img){
|
mark: function(item, gid, img){
|
||||||
|
// cleanup...
|
||||||
|
if(item == null){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
gid = gid || this.current
|
gid = gid || this.current
|
||||||
var that = this
|
var that = this
|
||||||
|
|
||||||
@ -398,8 +492,50 @@ var StatusBarActions = actions.Actions({
|
|||||||
var that = this
|
var that = this
|
||||||
this.config['status-bar-mode'] = state
|
this.config['status-bar-mode'] = state
|
||||||
|
|
||||||
|
var _getHandler = function(key){
|
||||||
|
var elems = that.__statusbar_elements__ || {}
|
||||||
|
var base_elems = StatusBarActions.__statusbar_elements__ || {}
|
||||||
|
|
||||||
|
var handler = elems[key] || base_elems[key]
|
||||||
|
|
||||||
|
if(handler == null){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle aliases...
|
||||||
|
var seen = []
|
||||||
|
while(typeof(handler) == typeof('str')){
|
||||||
|
seen.push(handler)
|
||||||
|
var handler = elems[handler] || base_elems[handler]
|
||||||
|
// check for loops...
|
||||||
|
if(seen.indexOf(handler) >= 0){
|
||||||
|
console.error('state indicator alias loop detected at:', key)
|
||||||
|
handler = null
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return handler
|
||||||
|
}
|
||||||
|
|
||||||
// destroy...
|
// destroy...
|
||||||
if(state == 'none'){
|
if(state == 'none'){
|
||||||
|
// notify items that they are removed...
|
||||||
|
bar.children()
|
||||||
|
.each(function(i, item){
|
||||||
|
item = $(item)
|
||||||
|
var type = item.attr('type')
|
||||||
|
|
||||||
|
if(type == null){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var handler = _getHandler(type)
|
||||||
|
|
||||||
|
if(handler != null){
|
||||||
|
handler.call(that, null)
|
||||||
|
}
|
||||||
|
})
|
||||||
bar.empty()
|
bar.empty()
|
||||||
|
|
||||||
// build/update...
|
// build/update...
|
||||||
@ -407,32 +543,6 @@ var StatusBarActions = actions.Actions({
|
|||||||
gid = gid || this.current
|
gid = gid || this.current
|
||||||
var img = this.images && this.images[gid]
|
var img = this.images && this.images[gid]
|
||||||
|
|
||||||
var _getHandler = function(key){
|
|
||||||
var elems = that.__statusbar_elements__ || {}
|
|
||||||
var base_elems = StatusBarActions.__statusbar_elements__ || {}
|
|
||||||
|
|
||||||
var handler = elems[key] || base_elems[key]
|
|
||||||
|
|
||||||
if(handler == null){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle aliases...
|
|
||||||
var seen = []
|
|
||||||
while(typeof(handler) == typeof('str')){
|
|
||||||
seen.push(handler)
|
|
||||||
var handler = elems[handler] || base_elems[handler]
|
|
||||||
// check for loops...
|
|
||||||
if(seen.indexOf(handler) >= 0){
|
|
||||||
console.error('state indicator alias loop detected at:', key)
|
|
||||||
handler = null
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return handler
|
|
||||||
}
|
|
||||||
|
|
||||||
// build...
|
// build...
|
||||||
if(bar.children().length <= 0){
|
if(bar.children().length <= 0){
|
||||||
var items = this.config['status-bar-items'].slice()
|
var items = this.config['status-bar-items'].slice()
|
||||||
|
|||||||
@ -14,7 +14,8 @@ var object = require('lib/object')
|
|||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
|
|
||||||
var MODIFIERS =
|
var MODIFIERS =
|
||||||
module.MODIFIERS = [ 'ctrl', 'meta', 'alt', 'shift' ]
|
//module.MODIFIERS = [ 'ctrl', 'meta', 'alt', 'shift' ]
|
||||||
|
module.MODIFIERS = [ 'caps', 'ctrl', 'meta', 'alt', 'shift' ]
|
||||||
|
|
||||||
|
|
||||||
var KEY_SEPARATORS =
|
var KEY_SEPARATORS =
|
||||||
@ -204,12 +205,17 @@ var event2key =
|
|||||||
module.event2key =
|
module.event2key =
|
||||||
function event2key(evt){
|
function event2key(evt){
|
||||||
evt = evt || event
|
evt = evt || event
|
||||||
|
// NOTE: we do not care about the jQuery wrapper here...
|
||||||
|
evt = evt.originalEvent || evt
|
||||||
|
|
||||||
var key = []
|
var key = []
|
||||||
evt.ctrlKey && key.push('ctrl')
|
evt.ctrlKey && key.push('ctrl')
|
||||||
evt.altKey && key.push('alt')
|
evt.altKey && key.push('alt')
|
||||||
evt.metaKey && key.push('meta')
|
evt.metaKey && key.push('meta')
|
||||||
evt.shiftKey && key.push('shift')
|
evt.shiftKey && key.push('shift')
|
||||||
|
evt.getModifierState
|
||||||
|
&& evt.getModifierState('CapsLock')
|
||||||
|
&& key.push('caps')
|
||||||
|
|
||||||
var k = code2key(evt.keyCode)
|
var k = code2key(evt.keyCode)
|
||||||
|
|
||||||
@ -760,8 +766,7 @@ var KeyboardPrototype = {
|
|||||||
mode = '*'
|
mode = '*'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var joinKeys = function(key, shift_key){
|
||||||
var genKeys = function(key, shift_key){
|
|
||||||
// match candidates...
|
// match candidates...
|
||||||
return key_separators
|
return key_separators
|
||||||
// full key...
|
// full key...
|
||||||
@ -772,6 +777,40 @@ var KeyboardPrototype = {
|
|||||||
.map(function(s){ return shift_key.join(s) })
|
.map(function(s){ return shift_key.join(s) })
|
||||||
: [])
|
: [])
|
||||||
.unique() }
|
.unique() }
|
||||||
|
var normalize = this.normalizeKey
|
||||||
|
var keyCombinations = function(key, shift_key){
|
||||||
|
if(key.length <= 1){
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
var _combinations = function(level, res){
|
||||||
|
var next = []
|
||||||
|
level
|
||||||
|
.map(function(elem){
|
||||||
|
var c = normalize(elem)
|
||||||
|
c = typeof(c) == typeof('str') ? c : c.join('+++')
|
||||||
|
res.indexOf(c) < 0
|
||||||
|
&& res.push(c)
|
||||||
|
&& elem
|
||||||
|
//.reverse()
|
||||||
|
.slice(0, -1)
|
||||||
|
.map(function(_, i){
|
||||||
|
var s = elem.slice()
|
||||||
|
s.splice(i, 1)
|
||||||
|
s.length > 0
|
||||||
|
//&& next.push(s.reverse())
|
||||||
|
&& next.push(s)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
next.length > 0
|
||||||
|
&& _combinations(next, res)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
return _combinations(shift_key ? [key, shift_key] : [key], [])
|
||||||
|
// XXX is there a better way???
|
||||||
|
//.map(function(e){ return e.split(/\+\+\+/g).concat(key.slice(-1)) })
|
||||||
|
.map(function(e){ return joinKeys(e.split(/\+\+\+/g)) })
|
||||||
|
.reduce(function(a, b){ return a.concat(b) }, [])
|
||||||
|
}
|
||||||
var walkAliases = function(bindings, handler, modifiers){
|
var walkAliases = function(bindings, handler, modifiers){
|
||||||
var seen = []
|
var seen = []
|
||||||
var modifiers = modifiers || []
|
var modifiers = modifiers || []
|
||||||
@ -803,7 +842,8 @@ var KeyboardPrototype = {
|
|||||||
var shift_key = this.shifted(key)
|
var shift_key = this.shifted(key)
|
||||||
|
|
||||||
// match candidates...
|
// match candidates...
|
||||||
var keys = genKeys(key, shift_key).unique()
|
//var keys = joinKeys(key, shift_key).unique()
|
||||||
|
var keys = keyCombinations(key, shift_key)
|
||||||
|
|
||||||
// get modes...
|
// get modes...
|
||||||
var modes = mode == '*' ? Object.keys(keyboard)
|
var modes = mode == '*' ? Object.keys(keyboard)
|
||||||
@ -817,7 +857,8 @@ var KeyboardPrototype = {
|
|||||||
var k = key.slice(-1)[0]
|
var k = key.slice(-1)[0]
|
||||||
var c = this.key2code(k)
|
var c = this.key2code(k)
|
||||||
|
|
||||||
var mod = genKeys(key.slice(0, -1).concat(''))
|
//var mod = joinKeys(key.slice(0, -1).concat(''))
|
||||||
|
var mod = keyCombinations(key.slice(0, -1).concat(''))
|
||||||
|
|
||||||
var drop = mode == 'test' || mode == '?'
|
var drop = mode == 'test' || mode == '?'
|
||||||
for(var i=0; i < modes.length; i++){
|
for(var i=0; i < modes.length; i++){
|
||||||
@ -983,6 +1024,11 @@ KeyboardWithCSSModes.prototype.__proto__ = Keyboard.prototype
|
|||||||
// // used directly...
|
// // used directly...
|
||||||
// handler('ctrl_C', function(k){ console.log('Not bound:', k) })
|
// handler('ctrl_C', function(k){ console.log('Not bound:', k) })
|
||||||
//
|
//
|
||||||
|
// NOTE: the handler will also set the .capslock attribute on the
|
||||||
|
// keyboard object and update it on each key press...
|
||||||
|
// NOTE: if .capslock is false means that either it is not on or
|
||||||
|
// undetectable...
|
||||||
|
// NOTE: before any key is pressed the .capslock is set to undefined
|
||||||
var makeKeyboardHandler =
|
var makeKeyboardHandler =
|
||||||
module.makeKeyboardHandler =
|
module.makeKeyboardHandler =
|
||||||
function makeKeyboardHandler(keyboard, unhandled, actions){
|
function makeKeyboardHandler(keyboard, unhandled, actions){
|
||||||
@ -991,6 +1037,7 @@ function makeKeyboardHandler(keyboard, unhandled, actions){
|
|||||||
keyboard
|
keyboard
|
||||||
//: Keyboard(keyboard, checkGlobalMode)
|
//: Keyboard(keyboard, checkGlobalMode)
|
||||||
: Keyboard(keyboard)
|
: Keyboard(keyboard)
|
||||||
|
kb.capslock = undefined
|
||||||
|
|
||||||
return function(key, no_match){
|
return function(key, no_match){
|
||||||
no_match = no_match || unhandled
|
no_match = no_match || unhandled
|
||||||
@ -1002,6 +1049,8 @@ function makeKeyboardHandler(keyboard, unhandled, actions){
|
|||||||
if(typeof(key) != typeof('str')){
|
if(typeof(key) != typeof('str')){
|
||||||
evt = key
|
evt = key
|
||||||
key = kb.event2key(evt)
|
key = kb.event2key(evt)
|
||||||
|
|
||||||
|
kb.capslock = key.indexOf('caps') >= 0
|
||||||
}
|
}
|
||||||
|
|
||||||
var handlers = kb.handler('test', key)
|
var handlers = kb.handler('test', key)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user