From 63ad1dec90fdcccfe0990389a0407d909342d2d0 Mon Sep 17 00:00:00 2001 From: "Alex A. Naanou" Date: Wed, 11 Jan 2017 20:03:33 +0300 Subject: [PATCH] reworked how cursor autohiding works... Signed-off-by: Alex A. Naanou --- ui (gen4)/features/filesystem.js | 2 +- ui (gen4)/features/keyboard.js | 8 +- ui (gen4)/features/ui-single-image.js | 31 ++---- ui (gen4)/features/ui.js | 152 +++++++++++++++++++++----- ui (gen4)/lib/keyboard2.js | 14 ++- ui (gen4)/lib/toggler.js | 6 +- ui (gen4)/lib/widget/browse.js | 3 + 7 files changed, 154 insertions(+), 62 deletions(-) diff --git a/ui (gen4)/features/filesystem.js b/ui (gen4)/features/filesystem.js index bdb12131..a2ac9be5 100755 --- a/ui (gen4)/features/filesystem.js +++ b/ui (gen4)/features/filesystem.js @@ -1413,7 +1413,7 @@ var FileSystemSaveHistoryUIActions = actions.Actions({ // XXX add comment editing... // XXX might be a good idea to show a diff of some kind or at least // what .changed when writing a save... - listSaveHistory: ['File/History...', + listSaveHistory: ['File/Edit history...', widgets.makeUIDialog(function(){ var that = this diff --git a/ui (gen4)/features/keyboard.js b/ui (gen4)/features/keyboard.js index 4f3cf232..863ac0ea 100755 --- a/ui (gen4)/features/keyboard.js +++ b/ui (gen4)/features/keyboard.js @@ -50,8 +50,8 @@ module.GLOBAL_KEYBOARD2 = { End: 'resetSlideshowTimer', T: 'slideshowIntervalDialog', - R: 'toggleSlideshowDirection', - L: 'toggleSlideshowLooping', + R: 'toggleSlideshowDirection -- Reverse slideshow direction', + L: 'toggleSlideshowLooping -- Toggle slideshow looping', }, // 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... var target = this.__keyboard_event_source = - this.config['keyboard-event-source'] == null - || this.config['keyboard-event-source'] == 'viewer' ? this.ribbons.viewer + this.config['keyboard-event-source'] ? $(window) + : this.config['keyboard-event-source'] == 'viewer' ? this.ribbons.viewer : this.config['keyboard-event-source'] == 'window' ? $(window) : this.config['keyboard-event-source'] == 'document' ? $(document) : $(this.config['keyboard-event-source']) diff --git a/ui (gen4)/features/ui-single-image.js b/ui (gen4)/features/ui-single-image.js index 3acfe0d7..2203e292 100755 --- a/ui (gen4)/features/ui-single-image.js +++ b/ui (gen4)/features/ui-single-image.js @@ -521,8 +521,6 @@ module.SingleImageAutoHideCursor = core.ImageGridFeatures.Feature({ config: { 'cursor-autohide-single-image-view': 'on', 'cursor-autohide-ribbon-view': 'off', - - //'cursor-autohide-on-navigate': true, }, handlers: [ @@ -533,43 +531,30 @@ module.SingleImageAutoHideCursor = core.ImageGridFeatures.Feature({ 'cursor-autohide-single-image-view' : 'cursor-autohide-ribbon-view' - this.toggleAutoHideCursor(this.config[mode] || 'off') + this.toggleAutoHideCursorTimeout(this.config[mode] || 'off') }], // store state for each mode... - ['toggleAutoHideCursor', + ['toggleAutoHideCursorTimeout', function(){ var mode = this.toggleSingleImage('?') == 'on' ? 'cursor-autohide-single-image-view' : 'cursor-autohide-ribbon-view' - this.config[mode] = this.toggleAutoHideCursor('?') + this.config[mode] = this.toggleAutoHideCursorTimeout('?') }], // restore state per mode... ['toggleSingleImage', function(){ if(this.toggleSingleImage('?') == 'on'){ - this.toggleAutoHideCursor(this.config['cursor-autohide-single-image-view']) + this.toggleAutoHideCursorTimeout(this.config['cursor-autohide-single-image-view']) } 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') - } - }], - */ ] }) diff --git a/ui (gen4)/features/ui.js b/ui (gen4)/features/ui.js index fed13c60..adb198a8 100755 --- a/ui (gen4)/features/ui.js +++ b/ui (gen4)/features/ui.js @@ -418,13 +418,13 @@ module.ViewerActions = actions.Actions({ function(){ return this.ribbons.viewer }, function(){ return this.config.themes }, function(state){ this.config.theme = state }) ], - lighterTheme: ['Interface/Theme/Lighter', + lighterTheme: ['Interface/Theme/Lighter theme', function(){ var themes = this.config.themes var i = themes.indexOf(this.toggleTheme('?')) this.toggleTheme(Math.min(i+1, themes.length-1)) }], - darkerTheme: ['Interface/Theme/Darker', + darkerTheme: ['Interface/Theme/Darker theme', function(){ var themes = this.config.themes var i = themes.indexOf(this.toggleTheme('?')) @@ -1604,12 +1604,15 @@ module.AutoHideCursor = core.ImageGridFeatures.Feature({ ], config: { + 'cursor-autohide': 'on', + 'cursor-autohide-on-timeout': 'on', + 'cursor-autohide-timeout': 1000, - 'cursor-autohide-threshold': 10, + 'cursor-show-threshold': 10, }, actions: actions.Actions({ - toggleAutoHideCursor: ['Interface/Cursor auto hiding', + toggleHiddenCursor: ['Interface/Cursor hidden', toggler.CSSClassToggler( function(){ return this.ribbons.viewer }, 'cursor-hidden', @@ -1617,19 +1620,15 @@ module.AutoHideCursor = core.ImageGridFeatures.Feature({ var that = this var viewer = this.ribbons.viewer - // setup... if(state == 'on'){ var x, y - var timer - var timeout = this.config['cursor-autohide-timeout'] || 1000 + // auto-show -- on mouse move greater than threshold... var handler - = this.__cursor_autohide_handler - = (this.__cursor_autohide_handler + = this.__cursor_show_handler + = (this.__cursor_show_handler || function(){ - timer && clearTimeout(timer) - - var threshold = that.config['cursor-autohide-threshold'] || 0 + var threshold = that.config['cursor-show-threshold'] || 0 x = x || event.clientX y = y || event.clientY @@ -1638,50 +1637,141 @@ module.AutoHideCursor = core.ImageGridFeatures.Feature({ if(Math.max(Math.abs(x - event.clientX), Math.abs(y - event.clientY)) > threshold){ x = y = null - that.ribbons.viewer - .removeClass('cursor-hidden') + that.toggleHiddenCursor('off') } // show right away -- no threshold... } else { - that.ribbons.viewer - .removeClass('cursor-hidden') + that.toggleHiddenCursor('off') } + }) - 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){ timer = setTimeout(function(){ var viewer = that.ribbons.viewer - if(!viewer.prop('cursor-autohide')){ - viewer.removeClass('cursor-hidden') + // auto-hide is off -- restore... + if(!viewer.hasClass('cursor-autohide')){ + that.toggleHiddenCursor('off') return } - timer && viewer.addClass('cursor-hidden') + timer && that.toggleHiddenCursor('on') }, 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... !viewer.prop('cursor-autohide') && viewer - .prop('cursor-autohide', true) - .addClass('cursor-hidden') // prevent multiple handlers... - .off('mousemove', this.__cursor_autohide_handler) - .mousemove(handler) + .off('mousemove', this.__cursor_autohide_mouse_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... } else { - viewer - .off('mousemove', this.__cursor_autohide_handler) - .prop('cursor-autohide', false) - .removeClass('cursor-hidden') - delete this.__cursor_autohide_handler + this.__cursor_autohide_mouse_handler + && viewer + .off('mousemove', this.__cursor_autohide_mouse_handler) + delete this.__cursor_autohide_mouse_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 && this.ribbons.viewer //&& 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', function(state){ var that = this diff --git a/ui (gen4)/lib/keyboard2.js b/ui (gen4)/lib/keyboard2.js index b5d8186c..cd05ebd2 100755 --- a/ui (gen4)/lib/keyboard2.js +++ b/ui (gen4)/lib/keyboard2.js @@ -14,7 +14,7 @@ var object = require('lib/object') /*********************************************************************/ var MODIFIERS = -module.MODIFIERS = [ 'ctrl', 'alt', 'meta', 'shift' ] +module.MODIFIERS = [ 'ctrl', 'meta', 'alt', 'shift' ] var KEY_SEPARATORS = @@ -166,6 +166,12 @@ function parseActionCall(txt){ // Helpers... // Form standard key string from keyboard event... +// +// Format: +// "[ctrl+][meta+][alt+][shift+]" +// +// - string returned by code2key(..) +// var event2key = module.event2key = function event2key(evt){ @@ -365,6 +371,12 @@ var KeyboardHandlerPrototype = { isKey: KeyboardHandlerClassPrototype.isKey, //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... // diff --git a/ui (gen4)/lib/toggler.js b/ui (gen4)/lib/toggler.js index fdfc004c..fabdf65a 100755 --- a/ui (gen4)/lib/toggler.js +++ b/ui (gen4)/lib/toggler.js @@ -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... var states = state_set - if(typeof(states_getter) == typeof(function(){})){ + if(states_getter instanceof Function){ // get the states... var states = states_getter.call(this) 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... // ...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', { get: function(){ return states_getter.apply(this) }, }) @@ -287,7 +287,7 @@ function(elem, state_accessor, states, callback_a, callback_b){ if(func.__doc != null){ return func.__doc } - var states = typeof(states_getter) == typeof(function(){}) ? + var states = states_getter instanceof Function ? states_getter.apply(this) : state_set diff --git a/ui (gen4)/lib/widget/browse.js b/ui (gen4)/lib/widget/browse.js index fc2b87c2..cbd64c8c 100755 --- a/ui (gen4)/lib/widget/browse.js +++ b/ui (gen4)/lib/widget/browse.js @@ -393,6 +393,7 @@ var BrowserPrototype = { 'P', 'O', 'T', 'D', + 'H', // let the system handle copy paste... 'C', 'V', 'X', @@ -425,6 +426,7 @@ var BrowserPrototype = { 'P', 'O', 'T', 'D', + 'H', // let the system handle copy paste... 'C', 'V', 'X', @@ -454,6 +456,7 @@ var BrowserPrototype = { 'P', 'O', 'T', 'D', + 'H', // let the system handle copy paste... 'C', 'V', 'X',