reworked how cursor autohiding works...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2017-01-11 20:03:33 +03:00
parent 136601849c
commit 63ad1dec90
7 changed files with 154 additions and 62 deletions

View File

@ -1413,7 +1413,7 @@ var FileSystemSaveHistoryUIActions = actions.Actions({
// XXX add comment editing... // XXX add comment editing...
// XXX might be a good idea to show a diff of some kind or at least // XXX might be a good idea to show a diff of some kind or at least
// what .changed when writing a save... // what .changed when writing a save...
listSaveHistory: ['File/History...', listSaveHistory: ['File/Edit history...',
widgets.makeUIDialog(function(){ widgets.makeUIDialog(function(){
var that = this var that = this

View File

@ -50,8 +50,8 @@ module.GLOBAL_KEYBOARD2 = {
End: 'resetSlideshowTimer', End: 'resetSlideshowTimer',
T: 'slideshowIntervalDialog', T: 'slideshowIntervalDialog',
R: 'toggleSlideshowDirection', R: 'toggleSlideshowDirection -- Reverse slideshow direction',
L: 'toggleSlideshowLooping', L: 'toggleSlideshowLooping -- Toggle slideshow looping',
}, },
// XXX do we need to prevent up/down navigation here, it may get confusing? // XXX do we need to prevent up/down navigation here, it may get confusing?
@ -574,8 +574,8 @@ var KeyboardActions = actions.Actions({
// NOTE: the target element must be focusable... // NOTE: the target element must be focusable...
var target = var target =
this.__keyboard_event_source = this.__keyboard_event_source =
this.config['keyboard-event-source'] == null this.config['keyboard-event-source'] ? $(window)
|| this.config['keyboard-event-source'] == 'viewer' ? this.ribbons.viewer : this.config['keyboard-event-source'] == 'viewer' ? this.ribbons.viewer
: this.config['keyboard-event-source'] == 'window' ? $(window) : this.config['keyboard-event-source'] == 'window' ? $(window)
: this.config['keyboard-event-source'] == 'document' ? $(document) : this.config['keyboard-event-source'] == 'document' ? $(document)
: $(this.config['keyboard-event-source']) : $(this.config['keyboard-event-source'])

View File

@ -521,8 +521,6 @@ module.SingleImageAutoHideCursor = core.ImageGridFeatures.Feature({
config: { config: {
'cursor-autohide-single-image-view': 'on', 'cursor-autohide-single-image-view': 'on',
'cursor-autohide-ribbon-view': 'off', 'cursor-autohide-ribbon-view': 'off',
//'cursor-autohide-on-navigate': true,
}, },
handlers: [ handlers: [
@ -533,43 +531,30 @@ module.SingleImageAutoHideCursor = core.ImageGridFeatures.Feature({
'cursor-autohide-single-image-view' 'cursor-autohide-single-image-view'
: 'cursor-autohide-ribbon-view' : 'cursor-autohide-ribbon-view'
this.toggleAutoHideCursor(this.config[mode] || 'off') this.toggleAutoHideCursorTimeout(this.config[mode] || 'off')
}], }],
// store state for each mode... // store state for each mode...
['toggleAutoHideCursor', ['toggleAutoHideCursorTimeout',
function(){ function(){
var mode = this.toggleSingleImage('?') == 'on' ? var mode = this.toggleSingleImage('?') == 'on' ?
'cursor-autohide-single-image-view' 'cursor-autohide-single-image-view'
: 'cursor-autohide-ribbon-view' : 'cursor-autohide-ribbon-view'
this.config[mode] = this.toggleAutoHideCursor('?') this.config[mode] = this.toggleAutoHideCursorTimeout('?')
}], }],
// restore state per mode... // restore state per mode...
['toggleSingleImage', ['toggleSingleImage',
function(){ function(){
if(this.toggleSingleImage('?') == 'on'){ if(this.toggleSingleImage('?') == 'on'){
this.toggleAutoHideCursor(this.config['cursor-autohide-single-image-view']) this.toggleAutoHideCursorTimeout(this.config['cursor-autohide-single-image-view'])
} else { } else {
this.toggleAutoHideCursor(this.config['cursor-autohide-ribbon-view']) this.toggleAutoHideCursorTimeout(this.config['cursor-autohide-ribbon-view'])
// XXX for some reason this is not working...
this.toggleHiddenCursor(this.config['cursor-autohide-ribbon-view'])
} }
}], }],
/* XXX for some reason this does not work...
// autohide on navigation...
['focusImage',
function(){
//if(this.config['cursor-autohide-on-navigate']
// && this.toggleAutoHideCursor('?') == 'on'){
// this.toggleAutoHideCursor('on')
//}
if(this.config['cursor-autohide-on-navigate']
&& this.toggleAutoHideCursor('?') == 'on'
&& this.ribbons.viewer.prop('cursor-autohide')){
this.ribbons.viewer
.addClass('cursor-hidden')
}
}],
*/
] ]
}) })

View File

@ -418,13 +418,13 @@ module.ViewerActions = actions.Actions({
function(){ return this.ribbons.viewer }, function(){ return this.ribbons.viewer },
function(){ return this.config.themes }, function(){ return this.config.themes },
function(state){ this.config.theme = state }) ], function(state){ this.config.theme = state }) ],
lighterTheme: ['Interface/Theme/Lighter', lighterTheme: ['Interface/Theme/Lighter theme',
function(){ function(){
var themes = this.config.themes var themes = this.config.themes
var i = themes.indexOf(this.toggleTheme('?')) var i = themes.indexOf(this.toggleTheme('?'))
this.toggleTheme(Math.min(i+1, themes.length-1)) this.toggleTheme(Math.min(i+1, themes.length-1))
}], }],
darkerTheme: ['Interface/Theme/Darker', darkerTheme: ['Interface/Theme/Darker theme',
function(){ function(){
var themes = this.config.themes var themes = this.config.themes
var i = themes.indexOf(this.toggleTheme('?')) var i = themes.indexOf(this.toggleTheme('?'))
@ -1604,12 +1604,15 @@ module.AutoHideCursor = core.ImageGridFeatures.Feature({
], ],
config: { config: {
'cursor-autohide': 'on',
'cursor-autohide-on-timeout': 'on',
'cursor-autohide-timeout': 1000, 'cursor-autohide-timeout': 1000,
'cursor-autohide-threshold': 10, 'cursor-show-threshold': 10,
}, },
actions: actions.Actions({ actions: actions.Actions({
toggleAutoHideCursor: ['Interface/Cursor auto hiding', toggleHiddenCursor: ['Interface/Cursor hidden',
toggler.CSSClassToggler( toggler.CSSClassToggler(
function(){ return this.ribbons.viewer }, function(){ return this.ribbons.viewer },
'cursor-hidden', 'cursor-hidden',
@ -1617,19 +1620,15 @@ module.AutoHideCursor = core.ImageGridFeatures.Feature({
var that = this var that = this
var viewer = this.ribbons.viewer var viewer = this.ribbons.viewer
// setup...
if(state == 'on'){ if(state == 'on'){
var x, y var x, y
var timer
var timeout = this.config['cursor-autohide-timeout'] || 1000
// auto-show -- on mouse move greater than threshold...
var handler var handler
= this.__cursor_autohide_handler = this.__cursor_show_handler
= (this.__cursor_autohide_handler = (this.__cursor_show_handler
|| function(){ || function(){
timer && clearTimeout(timer) var threshold = that.config['cursor-show-threshold'] || 0
var threshold = that.config['cursor-autohide-threshold'] || 0
x = x || event.clientX x = x || event.clientX
y = y || event.clientY y = y || event.clientY
@ -1638,50 +1637,141 @@ module.AutoHideCursor = core.ImageGridFeatures.Feature({
if(Math.max(Math.abs(x - event.clientX), if(Math.max(Math.abs(x - event.clientX),
Math.abs(y - event.clientY)) > threshold){ Math.abs(y - event.clientY)) > threshold){
x = y = null x = y = null
that.ribbons.viewer that.toggleHiddenCursor('off')
.removeClass('cursor-hidden')
} }
// show right away -- no threshold... // show right away -- no threshold...
} else { } else {
that.ribbons.viewer that.toggleHiddenCursor('off')
.removeClass('cursor-hidden')
} }
})
var timeout = that.config['cursor-autohide-timeout'] || 1000 viewer
// hide the cursor...
.addClass('cursor-hidden')
// reset handler...
.off('mousemove', handler)
.mousemove(handler)
// show...
} else {
viewer
.removeClass('cursor-hidden')
.off('mousemove', this.__cursor_show_handler)
}
})],
toggleAutoHideCursor: ['Interface/Cursor auto hiding',
toggler.CSSClassToggler(
function(){ return this.ribbons.viewer },
'cursor-autohide',
function(state){
var that = this
console.log('!!!!!', state)
var viewer = this.ribbons.viewer
// NOTE: this is handled by the keyboard feature...
var kb_target = this.__keyboard_event_source || $(window)
this.config['cursor-autohide'] = state
// setup...
if(state == 'on'){
var x, y
var timer
var timeout =
that.config['cursor-autohide-on-timeout'] != 'off' ?
(that.config['cursor-autohide-timeout'] || 1000)
: -1
// hide on timeout...
var mouse_handler
= this.__cursor_autohide_mouse_handler
= (this.__cursor_autohide_mouse_handler
|| function(){
timer && clearTimeout(timer)
// hide on timeout...
var timeout =
that.config['cursor-autohide-on-timeout'] != 'off' ?
(that.config['cursor-autohide-timeout'] || 1000)
: -1
if(timeout && timeout > 0){ if(timeout && timeout > 0){
timer = setTimeout(function(){ timer = setTimeout(function(){
var viewer = that.ribbons.viewer var viewer = that.ribbons.viewer
if(!viewer.prop('cursor-autohide')){ // auto-hide is off -- restore...
viewer.removeClass('cursor-hidden') if(!viewer.hasClass('cursor-autohide')){
that.toggleHiddenCursor('off')
return return
} }
timer && viewer.addClass('cursor-hidden') timer && that.toggleHiddenCursor('on')
}, timeout) }, timeout)
} }
}) })
// hide on key...
// XXX should be usable with mouse, e.g. don't
// hide cursor while moving mous with shift
// pressed...
var key_handler
= this.__cursor_autohide_key_handler
= (this.__cursor_autohide_key_handler
|| function(){
var viewer = that.ribbons.viewer
// auto-hide is off -- restore...
if(!viewer.hasClass('cursor-autohide')){
that.toggleHiddenCursor('off')
return
}
that.toggleHiddenCursor('on')
return true
})
// do the base setup... // do the base setup...
!viewer.prop('cursor-autohide') !viewer.prop('cursor-autohide')
&& viewer && viewer
.prop('cursor-autohide', true)
.addClass('cursor-hidden')
// prevent multiple handlers... // prevent multiple handlers...
.off('mousemove', this.__cursor_autohide_handler) .off('mousemove', this.__cursor_autohide_mouse_handler)
.mousemove(handler) .on('mousemove', mouse_handler)
&& kb_target
.on('keydown', key_handler)
// hide the cursor right away only if timeout is set...
timeout
&& timeout > 0
&& this.toggleHiddenCursor('on')
// teardown... // teardown...
} else { } else {
viewer this.__cursor_autohide_mouse_handler
.off('mousemove', this.__cursor_autohide_handler) && viewer
.prop('cursor-autohide', false) .off('mousemove', this.__cursor_autohide_mouse_handler)
.removeClass('cursor-hidden') delete this.__cursor_autohide_mouse_handler
delete this.__cursor_autohide_handler
this.__cursor_autohide_key_handler
&& kb_target
.off('keydown', this.__cursor_autohide_key_handler)
delete this.__cursor_autohide_key_handler
this.toggleHiddenCursor('off')
} }
})], })],
toggleAutoHideCursorTimeout: ['Interface/Hide cursor on timeout',
core.makeConfigToggler('cursor-autohide-on-timeout',
['on', 'off'],
function(){ this.toggleAutoHideCursor('!') })],
}), }),
handlers: [
['start',
function(){
this.toggleAutoHideCursor(this.config['cursor-autohide'] || 'on') }],
],
}) })
@ -1730,7 +1820,9 @@ var ControlActions = actions.Actions({
return this.ribbons return this.ribbons
&& this.ribbons.viewer && this.ribbons.viewer
//&& this.ribbons.getRibbon().data('hammer') ? 'handling-click' : 'none' }, //&& this.ribbons.getRibbon().data('hammer') ? 'handling-click' : 'none' },
&& this.ribbons.getRibbon().hasClass('clickable') ? 'handling-click' : 'none' }, && this.ribbons.getRibbon().hasClass('clickable') ?
'handling-click'
: 'none' },
'handling-click', 'handling-click',
function(state){ function(state){
var that = this var that = this

View File

@ -14,7 +14,7 @@ var object = require('lib/object')
/*********************************************************************/ /*********************************************************************/
var MODIFIERS = var MODIFIERS =
module.MODIFIERS = [ 'ctrl', 'alt', 'meta', 'shift' ] module.MODIFIERS = [ 'ctrl', 'meta', 'alt', 'shift' ]
var KEY_SEPARATORS = var KEY_SEPARATORS =
@ -166,6 +166,12 @@ function parseActionCall(txt){
// Helpers... // Helpers...
// Form standard key string from keyboard event... // Form standard key string from keyboard event...
//
// Format:
// "[ctrl+][meta+][alt+][shift+]<key>"
//
// <key> - string returned by code2key(..)
//
var event2key = var event2key =
module.event2key = module.event2key =
function event2key(evt){ function event2key(evt){
@ -365,6 +371,12 @@ var KeyboardHandlerPrototype = {
isKey: KeyboardHandlerClassPrototype.isKey, isKey: KeyboardHandlerClassPrototype.isKey,
//isModeApplicable: function(mode, keyboard, context){ return true }, //isModeApplicable: function(mode, keyboard, context){ return true },
// XXX merge configs...
// - need to match and order groups (use 1'st as reference)...
// - need to create new set w/o changing the originals...
merge: function(){
},
// Get keys for handler... // Get keys for handler...
// //

View File

@ -168,7 +168,7 @@ function(elem, state_accessor, states, callback_a, callback_b){
// see if we got an explicit state list or need to use a getter... // see if we got an explicit state list or need to use a getter...
var states = state_set var states = state_set
if(typeof(states_getter) == typeof(function(){})){ if(states_getter instanceof Function){
// get the states... // get the states...
var states = states_getter.call(this) var states = states_getter.call(this)
states = typeof(states) == typeof('str') ? states = typeof(states) == typeof('str') ?
@ -278,7 +278,7 @@ function(elem, state_accessor, states, callback_a, callback_b){
// XXX these are broken -- this is wrong... // XXX these are broken -- this is wrong...
// ...do not see how to fix this now in a good way... // ...do not see how to fix this now in a good way...
if(typeof(states_getter) == typeof(function(){})){ if(states_getter instanceof Function){
Object.defineProperty(func, 'states', { Object.defineProperty(func, 'states', {
get: function(){ return states_getter.apply(this) }, get: function(){ return states_getter.apply(this) },
}) })
@ -287,7 +287,7 @@ function(elem, state_accessor, states, callback_a, callback_b){
if(func.__doc != null){ if(func.__doc != null){
return func.__doc return func.__doc
} }
var states = typeof(states_getter) == typeof(function(){}) ? var states = states_getter instanceof Function ?
states_getter.apply(this) states_getter.apply(this)
: state_set : state_set

View File

@ -393,6 +393,7 @@ var BrowserPrototype = {
'P', 'P',
'O', 'O',
'T', 'D', 'T', 'D',
'H',
// let the system handle copy paste... // let the system handle copy paste...
'C', 'V', 'X', 'C', 'V', 'X',
@ -425,6 +426,7 @@ var BrowserPrototype = {
'P', 'P',
'O', 'O',
'T', 'D', 'T', 'D',
'H',
// let the system handle copy paste... // let the system handle copy paste...
'C', 'V', 'X', 'C', 'V', 'X',
@ -454,6 +456,7 @@ var BrowserPrototype = {
'P', 'P',
'O', 'O',
'T', 'D', 'T', 'D',
'H',
// let the system handle copy paste... // let the system handle copy paste...
'C', 'V', 'X', 'C', 'V', 'X',