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;
|
||||
}
|
||||
|
||||
/* 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 ***/
|
||||
|
||||
@ -271,16 +271,20 @@ module.GLOBAL_KEYBOARD = {
|
||||
shift_End: 'lastRibbon',
|
||||
|
||||
Up: 'prevRibbon',
|
||||
caps_shift_Up: 'prevRibbon',
|
||||
Down: 'nextRibbon',
|
||||
caps_shift_Down: 'nextRibbon',
|
||||
|
||||
|
||||
// shifting...
|
||||
shift_Up: 'shiftImageUp',
|
||||
caps_Up: 'shiftImageUp',
|
||||
alt_shift_Up: 'travelImageUp',
|
||||
ctrl_shift_Up: 'shiftImageUpNewRibbon',
|
||||
ctrl_Up: 'shiftMarkedUp',
|
||||
|
||||
shift_Down: 'shiftImageDown',
|
||||
caps_Down: 'shiftImageDown',
|
||||
alt_shift_Down: 'travelImageDown',
|
||||
ctrl_shift_Down: 'shiftImageDownNewRibbon',
|
||||
ctrl_Down: 'shiftMarkedDown',
|
||||
|
||||
@ -64,7 +64,6 @@ core.ImageGridFeatures.Feature('viewer-testing', [
|
||||
|
||||
'ui-single-image',
|
||||
//'ui-partial-ribbons',
|
||||
// XXX this is still experimental but seems to already work faster...
|
||||
'ui-partial-ribbons-2',
|
||||
|
||||
'marks',
|
||||
|
||||
@ -62,6 +62,7 @@ var StatusBarActions = actions.Actions({
|
||||
// separates left/right aligned elements...
|
||||
'---',
|
||||
|
||||
'edit-mode',
|
||||
'mark',
|
||||
'bookmark',
|
||||
],
|
||||
@ -90,7 +91,39 @@ var StatusBarActions = actions.Actions({
|
||||
},
|
||||
|
||||
__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){
|
||||
// cleanup...
|
||||
if(item == null){
|
||||
return
|
||||
}
|
||||
|
||||
var that = this
|
||||
gid = gid || this.current
|
||||
|
||||
@ -188,6 +221,11 @@ var StatusBarActions = actions.Actions({
|
||||
return item
|
||||
},
|
||||
ribbon: function(item, gid, img){
|
||||
// cleanup...
|
||||
if(item == null){
|
||||
return
|
||||
}
|
||||
|
||||
var that = this
|
||||
|
||||
// get ribbon number...
|
||||
@ -248,6 +286,11 @@ var StatusBarActions = actions.Actions({
|
||||
return item
|
||||
},
|
||||
changes: function(item, gid, img){
|
||||
// cleanup...
|
||||
if(item == null){
|
||||
return
|
||||
}
|
||||
|
||||
if(typeof(item) == typeof('str')){
|
||||
item = $('<span>')
|
||||
.addClass('changes')
|
||||
@ -260,6 +303,11 @@ var StatusBarActions = actions.Actions({
|
||||
},
|
||||
// XXX handle path correctly...
|
||||
gid: function(item, gid, img){
|
||||
// cleanup...
|
||||
if(item == null){
|
||||
return
|
||||
}
|
||||
|
||||
var that = this
|
||||
gid = gid || this.current
|
||||
img = img || (this.images && gid in this.images && this.images[gid])
|
||||
@ -309,8 +357,54 @@ var StatusBarActions = actions.Actions({
|
||||
return item
|
||||
},
|
||||
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...
|
||||
mark: function(item, gid, img){
|
||||
// cleanup...
|
||||
if(item == null){
|
||||
return
|
||||
}
|
||||
|
||||
gid = gid || this.current
|
||||
var that = this
|
||||
|
||||
@ -398,15 +492,6 @@ var StatusBarActions = actions.Actions({
|
||||
var that = this
|
||||
this.config['status-bar-mode'] = state
|
||||
|
||||
// destroy...
|
||||
if(state == 'none'){
|
||||
bar.empty()
|
||||
|
||||
// build/update...
|
||||
} else {
|
||||
gid = gid || this.current
|
||||
var img = this.images && this.images[gid]
|
||||
|
||||
var _getHandler = function(key){
|
||||
var elems = that.__statusbar_elements__ || {}
|
||||
var base_elems = StatusBarActions.__statusbar_elements__ || {}
|
||||
@ -433,6 +518,31 @@ var StatusBarActions = actions.Actions({
|
||||
return handler
|
||||
}
|
||||
|
||||
// destroy...
|
||||
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()
|
||||
|
||||
// build/update...
|
||||
} else {
|
||||
gid = gid || this.current
|
||||
var img = this.images && this.images[gid]
|
||||
|
||||
// build...
|
||||
if(bar.children().length <= 0){
|
||||
var items = this.config['status-bar-items'].slice()
|
||||
|
||||
@ -14,7 +14,8 @@ var object = require('lib/object')
|
||||
/*********************************************************************/
|
||||
|
||||
var MODIFIERS =
|
||||
module.MODIFIERS = [ 'ctrl', 'meta', 'alt', 'shift' ]
|
||||
//module.MODIFIERS = [ 'ctrl', 'meta', 'alt', 'shift' ]
|
||||
module.MODIFIERS = [ 'caps', 'ctrl', 'meta', 'alt', 'shift' ]
|
||||
|
||||
|
||||
var KEY_SEPARATORS =
|
||||
@ -204,12 +205,17 @@ var event2key =
|
||||
module.event2key =
|
||||
function event2key(evt){
|
||||
evt = evt || event
|
||||
// NOTE: we do not care about the jQuery wrapper here...
|
||||
evt = evt.originalEvent || evt
|
||||
|
||||
var key = []
|
||||
evt.ctrlKey && key.push('ctrl')
|
||||
evt.altKey && key.push('alt')
|
||||
evt.metaKey && key.push('meta')
|
||||
evt.shiftKey && key.push('shift')
|
||||
evt.getModifierState
|
||||
&& evt.getModifierState('CapsLock')
|
||||
&& key.push('caps')
|
||||
|
||||
var k = code2key(evt.keyCode)
|
||||
|
||||
@ -760,8 +766,7 @@ var KeyboardPrototype = {
|
||||
mode = '*'
|
||||
}
|
||||
|
||||
|
||||
var genKeys = function(key, shift_key){
|
||||
var joinKeys = function(key, shift_key){
|
||||
// match candidates...
|
||||
return key_separators
|
||||
// full key...
|
||||
@ -772,6 +777,40 @@ var KeyboardPrototype = {
|
||||
.map(function(s){ return shift_key.join(s) })
|
||||
: [])
|
||||
.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 seen = []
|
||||
var modifiers = modifiers || []
|
||||
@ -803,7 +842,8 @@ var KeyboardPrototype = {
|
||||
var shift_key = this.shifted(key)
|
||||
|
||||
// match candidates...
|
||||
var keys = genKeys(key, shift_key).unique()
|
||||
//var keys = joinKeys(key, shift_key).unique()
|
||||
var keys = keyCombinations(key, shift_key)
|
||||
|
||||
// get modes...
|
||||
var modes = mode == '*' ? Object.keys(keyboard)
|
||||
@ -817,7 +857,8 @@ var KeyboardPrototype = {
|
||||
var k = key.slice(-1)[0]
|
||||
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 == '?'
|
||||
for(var i=0; i < modes.length; i++){
|
||||
@ -983,6 +1024,11 @@ KeyboardWithCSSModes.prototype.__proto__ = Keyboard.prototype
|
||||
// // used directly...
|
||||
// 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 =
|
||||
module.makeKeyboardHandler =
|
||||
function makeKeyboardHandler(keyboard, unhandled, actions){
|
||||
@ -991,6 +1037,7 @@ function makeKeyboardHandler(keyboard, unhandled, actions){
|
||||
keyboard
|
||||
//: Keyboard(keyboard, checkGlobalMode)
|
||||
: Keyboard(keyboard)
|
||||
kb.capslock = undefined
|
||||
|
||||
return function(key, no_match){
|
||||
no_match = no_match || unhandled
|
||||
@ -1002,6 +1049,8 @@ function makeKeyboardHandler(keyboard, unhandled, actions){
|
||||
if(typeof(key) != typeof('str')){
|
||||
evt = key
|
||||
key = kb.event2key(evt)
|
||||
|
||||
kb.capslock = key.indexOf('caps') >= 0
|
||||
}
|
||||
|
||||
var handlers = kb.handler('test', key)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user