mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-28 18:00:09 +00:00
added key binding tips to action menu...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
2a04daa811
commit
ef441ff473
@ -261,6 +261,30 @@ body {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* XXX experimental key mappings... */
|
||||||
|
.browse-widget.show-keys .list>div:after {
|
||||||
|
display: inline;
|
||||||
|
position: relative;
|
||||||
|
content: attr(keys);
|
||||||
|
|
||||||
|
float: right;
|
||||||
|
margin-left: 0.5em;
|
||||||
|
margin-right: 0.5em;
|
||||||
|
|
||||||
|
opacity: 0.3;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
.browse-widget.show-keys .list>div.disabled:after {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.browse-widget.show-keys .list>div:hover:after {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
.browse-widget.show-keys .list>div.disabled:hover:after {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* DEBUG stuff... */
|
/* DEBUG stuff... */
|
||||||
.container-center {
|
.container-center {
|
||||||
|
|||||||
@ -210,6 +210,8 @@
|
|||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
/* XXX not sure about this yet... */
|
||||||
|
background-color: rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
.browse-widget .list .button:hover {
|
.browse-widget .list .button:hover {
|
||||||
opacity: 0.9;
|
opacity: 0.9;
|
||||||
|
|||||||
@ -1,5 +1,30 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
<!--
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Experiment: use native scroll for ribbons and view...
|
||||||
|
// Factors:
|
||||||
|
// + the browser will do all the heavy lifting and do it faster
|
||||||
|
// than we can ever hope to do it in JS (assumption)
|
||||||
|
// - will require us to add an extra container per ribbon
|
||||||
|
//
|
||||||
|
// Experiment result:
|
||||||
|
// - more uniform and fast across browsers
|
||||||
|
// (except FF - can't disable scrollbars, need to cheat)
|
||||||
|
// - less controllable (inertia, gestures, ...)
|
||||||
|
// - is affected by scaling in a bad way - paralax...
|
||||||
|
//
|
||||||
|
// Conclusion:
|
||||||
|
// - this again brings us to using code to control the scroll
|
||||||
|
// which in turn defeats the original purpose of avoiding
|
||||||
|
// extra complexity...
|
||||||
|
//
|
||||||
|
// See:
|
||||||
|
// experiments/native-scroll-ribbon.html
|
||||||
|
//
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.mark-center:after {
|
.mark-center:after {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|||||||
@ -468,8 +468,8 @@ var JournalActions = actions.Actions({
|
|||||||
|
|
||||||
this.journalable = this.actions
|
this.journalable = this.actions
|
||||||
.filter(function(action){
|
.filter(function(action){
|
||||||
return !!that.getAttr(action, 'undo')
|
return !!that.getActionAttr(action, 'undo')
|
||||||
|| !!that.getAttr(action, 'journal')
|
|| !!that.getActionAttr(action, 'journal')
|
||||||
})
|
})
|
||||||
// reset the handler
|
// reset the handler
|
||||||
.map(function(action){
|
.map(function(action){
|
||||||
@ -538,7 +538,7 @@ var JournalActions = actions.Actions({
|
|||||||
var a = journal[i]
|
var a = journal[i]
|
||||||
|
|
||||||
// see if the action has an explicit undo attr...
|
// see if the action has an explicit undo attr...
|
||||||
var undo = this.getAttr(a.action, 'undo')
|
var undo = this.getActionAttr(a.action, 'undo')
|
||||||
|
|
||||||
// general undo...
|
// general undo...
|
||||||
if(undo){
|
if(undo){
|
||||||
|
|||||||
@ -868,13 +868,20 @@ var FileSystemLoaderUIActions = actions.Actions({
|
|||||||
browsePath: ['File/Browse file system...',
|
browsePath: ['File/Browse file system...',
|
||||||
widgets.makeUIDialog(function(base, callback){
|
widgets.makeUIDialog(function(base, callback){
|
||||||
var that = this
|
var that = this
|
||||||
|
var cfg = this.config['file-browser-settings']
|
||||||
|
|
||||||
base = base || this.location.path || '/'
|
base = base || this.location.path || '/'
|
||||||
base = util.normalizePath(base)
|
base = util.normalizePath(base)
|
||||||
|
|
||||||
var o = browseWalk.makeWalk(
|
var o = browseWalk.makeWalk(
|
||||||
null, base, this.config['image-file-pattern'],
|
null, base, this.config['image-file-pattern'],
|
||||||
this.config['file-browser-settings'])
|
{
|
||||||
|
cls: 'file-browser',
|
||||||
|
|
||||||
|
disableFiles: cfg.disableFiles,
|
||||||
|
showNonTraversable: cfg.showNonTraversable,
|
||||||
|
showDisabled: cfg.showDisabled,
|
||||||
|
})
|
||||||
// path selected...
|
// path selected...
|
||||||
.open(function(evt, path){
|
.open(function(evt, path){
|
||||||
var item = o.selected
|
var item = o.selected
|
||||||
@ -932,8 +939,6 @@ var FileSystemLoaderUIActions = actions.Actions({
|
|||||||
config.showNonTraversable = o.options.showNonTraversable
|
config.showNonTraversable = o.options.showNonTraversable
|
||||||
})
|
})
|
||||||
|
|
||||||
o.dom.addClass('file-browser')
|
|
||||||
|
|
||||||
return o
|
return o
|
||||||
})],
|
})],
|
||||||
|
|
||||||
|
|||||||
@ -429,8 +429,7 @@ var KeyboardActions = actions.Actions({
|
|||||||
},
|
},
|
||||||
|
|
||||||
get keyboard(){
|
get keyboard(){
|
||||||
return this.__keyboard_config
|
return this.__keyboard_config },
|
||||||
},
|
|
||||||
|
|
||||||
pauseKeyboardRepeat: ['- Interface/',
|
pauseKeyboardRepeat: ['- Interface/',
|
||||||
function(){
|
function(){
|
||||||
@ -523,6 +522,47 @@ var KeyboardActions = actions.Actions({
|
|||||||
},
|
},
|
||||||
['on', 'off'])],
|
['on', 'off'])],
|
||||||
|
|
||||||
|
// Format:
|
||||||
|
// {
|
||||||
|
// <action>: {
|
||||||
|
// <mode>: [
|
||||||
|
// <key>,
|
||||||
|
// ...
|
||||||
|
// ],
|
||||||
|
// ...
|
||||||
|
// },
|
||||||
|
// ...
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
getKeysForAction: ['- Interface/',
|
||||||
|
function(actions){
|
||||||
|
actions = arguments.length == null || actions == '*' ? this.actions
|
||||||
|
: arguments.length > 1 ? [].slice.call(arguments)
|
||||||
|
: actions
|
||||||
|
actions = actions instanceof Array ? actions : [actions]
|
||||||
|
|
||||||
|
var paths = this.getPath(actions)
|
||||||
|
var help = keyboard.buildKeybindingsHelp(this.keyboard, null, this)
|
||||||
|
|
||||||
|
var res = {}
|
||||||
|
|
||||||
|
Object.keys(paths).map(function(k){
|
||||||
|
var action = paths[k][0]
|
||||||
|
var keys = keyboard.getKeysByDoc(k, help)
|
||||||
|
|
||||||
|
if(Object.keys(keys).length > 0){
|
||||||
|
res[action] = keys
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return res
|
||||||
|
}],
|
||||||
|
|
||||||
|
// XXX argument #3 is not yet used (see: lib/keyboard.js)...
|
||||||
|
getKeyboardModes: ['- Interface/',
|
||||||
|
function(){
|
||||||
|
return keyboard.getApplicableModes(this.keyboard, null, this.ribbons.viewer) }],
|
||||||
|
|
||||||
// XXX need to pre-process the docs...
|
// XXX need to pre-process the docs...
|
||||||
// - remove the path component...
|
// - remove the path component...
|
||||||
// - insert the action name where not doc present...
|
// - insert the action name where not doc present...
|
||||||
|
|||||||
@ -788,6 +788,8 @@ var BrowseActionsActions = actions.Actions({
|
|||||||
showHidden: false,
|
showHidden: false,
|
||||||
showEmpty: false,
|
showEmpty: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'browse-actions-keys': true,
|
||||||
},
|
},
|
||||||
|
|
||||||
// Browse actions dialog...
|
// Browse actions dialog...
|
||||||
@ -862,6 +864,21 @@ var BrowseActionsActions = actions.Actions({
|
|||||||
var priority = /^(-?[0-9]+)\s*:\s*/
|
var priority = /^(-?[0-9]+)\s*:\s*/
|
||||||
var dialog
|
var dialog
|
||||||
|
|
||||||
|
// get keys for each action...
|
||||||
|
var keys = this.getKeysForAction ? this.getKeysForAction('*') : {}
|
||||||
|
var modes = this.getKeyboardModes ? this.getKeyboardModes() : []
|
||||||
|
|
||||||
|
// Get keys for action...
|
||||||
|
var getKeys = function(action){
|
||||||
|
var k = keys[action] || {}
|
||||||
|
return Object.keys(k)
|
||||||
|
// keep only the applicable modes...
|
||||||
|
.filter(function(m){ return modes.indexOf(m) >= 0 })
|
||||||
|
.map(function(m){ return k[m] })
|
||||||
|
.reduce(function(a, b){ return a.concat(b) }, [])
|
||||||
|
.join(' / ')
|
||||||
|
}
|
||||||
|
|
||||||
// Get item from tree level taking into account additional
|
// Get item from tree level taking into account additional
|
||||||
// syntax like prioority...
|
// syntax like prioority...
|
||||||
// returns:
|
// returns:
|
||||||
@ -882,13 +899,14 @@ var BrowseActionsActions = actions.Actions({
|
|||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get action browse mode (disabled or hidden)...
|
||||||
var getMode = function(action){
|
var getMode = function(action){
|
||||||
var m = action
|
var m = action
|
||||||
var visited = [m]
|
var visited = [m]
|
||||||
|
|
||||||
// handle aliases...
|
// handle aliases...
|
||||||
do {
|
do {
|
||||||
m = actions.getAttr(m, 'browseMode')
|
m = actions.getActionAttr(m, 'browseMode')
|
||||||
// check for loops...
|
// check for loops...
|
||||||
if(m && visited[m] != null){
|
if(m && visited[m] != null){
|
||||||
m = null
|
m = null
|
||||||
@ -1040,12 +1058,15 @@ var BrowseActionsActions = actions.Actions({
|
|||||||
disabled: mode == 'hidden' || mode == 'disabled',
|
disabled: mode == 'hidden' || mode == 'disabled',
|
||||||
hidden: mode == 'hidden',
|
hidden: mode == 'hidden',
|
||||||
})
|
})
|
||||||
.addClass(state == cur_state ? 'selected highlighted' : '')
|
.attr('keys', getKeys(action))
|
||||||
|
.addClass([
|
||||||
|
state == cur_state ? 'selected highlighted' : '',
|
||||||
|
mode == 'hidden' ? mode : ''
|
||||||
|
].join(' '))
|
||||||
.on('open', function(){
|
.on('open', function(){
|
||||||
actions[action](state)
|
actions[action](state)
|
||||||
that.pop()
|
that.pop()
|
||||||
})
|
})
|
||||||
.addClass(mode == 'hidden' ? mode : '')
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Level: lister -- hand control to lister...
|
// Level: lister -- hand control to lister...
|
||||||
@ -1107,8 +1128,10 @@ var BrowseActionsActions = actions.Actions({
|
|||||||
actions[action]()
|
actions[action]()
|
||||||
that.update()
|
that.update()
|
||||||
that.select('"'+ text +'"')
|
that.select('"'+ text +'"')
|
||||||
}]
|
}],
|
||||||
|
//[getKeys(action)],
|
||||||
]})
|
]})
|
||||||
|
.attr('keys', getKeys(action))
|
||||||
.addClass(mode == 'hidden' ? mode : '')
|
.addClass(mode == 'hidden' ? mode : '')
|
||||||
.on('open', function(){
|
.on('open', function(){
|
||||||
// XXX can this open a dialog???
|
// XXX can this open a dialog???
|
||||||
@ -1127,6 +1150,7 @@ var BrowseActionsActions = actions.Actions({
|
|||||||
disabled: mode == 'hidden' || mode == 'disabled',
|
disabled: mode == 'hidden' || mode == 'disabled',
|
||||||
hidden: mode == 'hidden',
|
hidden: mode == 'hidden',
|
||||||
})
|
})
|
||||||
|
.attr('keys', getKeys(action))
|
||||||
.on('open', function(){
|
.on('open', function(){
|
||||||
waitFor(actions[action]())
|
waitFor(actions[action]())
|
||||||
})
|
})
|
||||||
@ -1145,6 +1169,8 @@ var BrowseActionsActions = actions.Actions({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
|
cls: 'browse-actions',
|
||||||
|
|
||||||
path: path,
|
path: path,
|
||||||
|
|
||||||
flat: false,
|
flat: false,
|
||||||
@ -1163,8 +1189,20 @@ var BrowseActionsActions = actions.Actions({
|
|||||||
config.showHidden = dialog.options.showHidden
|
config.showHidden = dialog.options.showHidden
|
||||||
})
|
})
|
||||||
|
|
||||||
|
this.config['browse-actions-keys']
|
||||||
|
&& dialog.dom.addClass('show-keys')
|
||||||
|
|
||||||
return dialog
|
return dialog
|
||||||
})],
|
})],
|
||||||
|
|
||||||
|
toggleBrowseActionKeys: ['Interface/Show keys in menu',
|
||||||
|
core.makeConfigToggler(
|
||||||
|
'browse-actions-keys',
|
||||||
|
[true, false],
|
||||||
|
function(state){
|
||||||
|
this.modal.client.dom.hasClass('browse-actions')
|
||||||
|
&& this.modal.client.dom[state ? 'addClass' : 'removeClass']('show-keys')
|
||||||
|
})],
|
||||||
})
|
})
|
||||||
|
|
||||||
var BrowseActions =
|
var BrowseActions =
|
||||||
@ -1177,6 +1215,9 @@ module.BrowseActions = core.ImageGridFeatures.Feature({
|
|||||||
'ui',
|
'ui',
|
||||||
'ui-dialogs',
|
'ui-dialogs',
|
||||||
],
|
],
|
||||||
|
suggested: [
|
||||||
|
'keyboard',
|
||||||
|
],
|
||||||
|
|
||||||
actions: BrowseActionsActions,
|
actions: BrowseActionsActions,
|
||||||
})
|
})
|
||||||
|
|||||||
@ -4,13 +4,13 @@
|
|||||||
*
|
*
|
||||||
* Features:
|
* Features:
|
||||||
* - ui
|
* - ui
|
||||||
* maps ribbons to base (data + images)
|
* maps ribbons to base feature (data + images)
|
||||||
* - config-local-storage
|
* - config-local-storage
|
||||||
* maintain configuration state in local storage
|
* maintain configuration state in local storage
|
||||||
* - ui-url-hash
|
* - ui-url-hash
|
||||||
* handle .location.hash
|
* handle .location.hash
|
||||||
* - ui-ribbon-auto-align
|
* - ui-ribbon-auto-align
|
||||||
* handle ribbon alignment...
|
* unify and handle ribbon alignment...
|
||||||
* - ui-ribbon-align-to-order
|
* - ui-ribbon-align-to-order
|
||||||
* - ui-ribbon-align-to-first
|
* - ui-ribbon-align-to-first
|
||||||
* - ui-ribbon-manual-align
|
* - ui-ribbon-manual-align
|
||||||
@ -18,7 +18,7 @@
|
|||||||
* manage UI non-css animations...
|
* manage UI non-css animations...
|
||||||
* - ui-autohide-cursor
|
* - ui-autohide-cursor
|
||||||
* - ui-control
|
* - ui-control
|
||||||
* control mechanics (touch/mouse)
|
* touch/mouse control mechanics
|
||||||
*
|
*
|
||||||
* Dev Features:
|
* Dev Features:
|
||||||
* - fail-safe-devtools
|
* - fail-safe-devtools
|
||||||
@ -31,12 +31,6 @@
|
|||||||
* - auto-single-image
|
* - auto-single-image
|
||||||
* - auto-ribbon
|
* - auto-ribbon
|
||||||
*
|
*
|
||||||
* Legacy:
|
|
||||||
* - ui-clickable
|
|
||||||
* - ui-direct-control-hammer
|
|
||||||
* - ui-indirect-control
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
*
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define)
|
((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define)
|
||||||
@ -1589,74 +1583,8 @@ module.ShiftAnimation = core.ImageGridFeatures.Feature({
|
|||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
// Mouse...
|
// Mouse...
|
||||||
|
//
|
||||||
/*
|
// NOTE: for legacy stuff see: features/ui-legacy.js
|
||||||
// XXX add setup/taredown...
|
|
||||||
var Clickable =
|
|
||||||
module.Clickable = core.ImageGridFeatures.Feature({
|
|
||||||
title: '',
|
|
||||||
doc: '',
|
|
||||||
|
|
||||||
tag: 'ui-clickable',
|
|
||||||
depends: ['ui'],
|
|
||||||
|
|
||||||
config: {
|
|
||||||
'click-threshold': {
|
|
||||||
t: 100,
|
|
||||||
d: 5,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
handlers: [
|
|
||||||
// setup click targets...
|
|
||||||
// XXX click only if we did not drag...
|
|
||||||
['updateImage',
|
|
||||||
function(res, gid){
|
|
||||||
var that = this
|
|
||||||
var img = this.ribbons.getImage(gid)
|
|
||||||
|
|
||||||
// set the clicker only once...
|
|
||||||
if(!img.prop('clickable')){
|
|
||||||
var x, y, t, last, threshold
|
|
||||||
img
|
|
||||||
.prop('clickable', true)
|
|
||||||
.on('mousedown touchstart', function(evt){
|
|
||||||
threshold = that.config['click-threshold']
|
|
||||||
x = evt.clientX
|
|
||||||
y = evt.clientY
|
|
||||||
t = Date.now()
|
|
||||||
})
|
|
||||||
.on('mouseup touchend', function(evt){
|
|
||||||
if(that.__control_in_progress){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// prevent another handler within a timeout...
|
|
||||||
// XXX not too sure about this...
|
|
||||||
if(t - last < threshold.t){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// constrain distance between down and up events...
|
|
||||||
if(x != null
|
|
||||||
&& Math.max(
|
|
||||||
Math.abs(x - evt.clientX),
|
|
||||||
Math.abs(y - evt.clientY)) < threshold.d){
|
|
||||||
// this will prevent double clicks...
|
|
||||||
x = null
|
|
||||||
y = null
|
|
||||||
that.focusImage(that.ribbons.getElemGID($(this)))
|
|
||||||
last = Date.now()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}],
|
|
||||||
],
|
|
||||||
})
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
// Auto-hide cursor...
|
|
||||||
|
|
||||||
// NOTE: removing the prop 'cursor-autohide' will stop hiding the cursor
|
// NOTE: removing the prop 'cursor-autohide' will stop hiding the cursor
|
||||||
// and show it on next timeout/mousemove.
|
// and show it on next timeout/mousemove.
|
||||||
@ -1758,7 +1686,6 @@ module.AutoHideCursor = core.ImageGridFeatures.Feature({
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
// Touch/Control...
|
// Touch/Control...
|
||||||
//
|
//
|
||||||
@ -1768,243 +1695,13 @@ module.AutoHideCursor = core.ImageGridFeatures.Feature({
|
|||||||
// Each new interaction should increment this when starting and
|
// Each new interaction should increment this when starting and
|
||||||
// decrement when done.
|
// decrement when done.
|
||||||
// This should be removed when 0
|
// This should be removed when 0
|
||||||
|
//
|
||||||
// This is to enable other events to handle the situation gracefully
|
// This is to enable other events to handle the situation gracefully
|
||||||
//
|
//
|
||||||
// XXX how should multiple long interactions be handled??
|
// XXX how should multiple long interactions be handled??
|
||||||
|
// XXX revise...
|
||||||
/*
|
|
||||||
// XXX add zoom...
|
|
||||||
// XXX add vertical pan to ribbon-set...
|
|
||||||
var DirectControlHammer =
|
|
||||||
module.DirectControlHammer = core.ImageGridFeatures.Feature({
|
|
||||||
title: '',
|
|
||||||
doc: '',
|
|
||||||
|
|
||||||
tag: 'ui-direct-control-hammer',
|
|
||||||
exclusive: ['ui-control'],
|
|
||||||
depends: [
|
|
||||||
'ui',
|
|
||||||
// this is only used to trigger reoad...
|
|
||||||
//'ui-partial-ribbons',
|
|
||||||
],
|
|
||||||
|
|
||||||
config: {
|
|
||||||
// This can be:
|
|
||||||
// 'silent' - silently focus central image after pan
|
|
||||||
// true - focus central image after pan
|
|
||||||
// null - do nothing.
|
|
||||||
'focus-central-image': 'silent',
|
|
||||||
},
|
|
||||||
|
|
||||||
// XXX add setup/taredown...
|
|
||||||
// XXX add inertia...
|
|
||||||
// XXX hide current image indicator on drag...
|
|
||||||
// XXX add swipe up/down control...
|
|
||||||
// XXX add mode switching....
|
|
||||||
// XXX BUG: after panning and silent focus, marking works correctly
|
|
||||||
// but image is not updated -- mark not drawn...
|
|
||||||
handlers: [
|
|
||||||
// setup ribbon dragging...
|
|
||||||
// XXX it is possible to drag over the loaded ribbon section with
|
|
||||||
// two fingers, need to force update somehow...
|
|
||||||
// ...and need to try and make the update in a single frame...
|
|
||||||
// Ways to go:
|
|
||||||
// - update on touchdown
|
|
||||||
// - update on liftoff
|
|
||||||
// XXX drag in single image mode ONLY if image is larger than screen...
|
|
||||||
['updateRibbon',
|
|
||||||
function(_, target){
|
|
||||||
var that = this
|
|
||||||
var r = this.ribbons.getRibbon(target)
|
|
||||||
|
|
||||||
// setup dragging...
|
|
||||||
if(r.length > 0 && !r.hasClass('draggable')){
|
|
||||||
r
|
|
||||||
.addClass('draggable')
|
|
||||||
.hammer()
|
|
||||||
.on('pan', function(evt){
|
|
||||||
//evt.stopPropagation()
|
|
||||||
|
|
||||||
// XXX stop all previous animations...
|
|
||||||
//r.velocity("stop")
|
|
||||||
|
|
||||||
var d = that.ribbons.dom
|
|
||||||
var s = that.scale
|
|
||||||
var g = evt.gesture
|
|
||||||
|
|
||||||
|
|
||||||
var data = r.data('drag-data')
|
|
||||||
|
|
||||||
// we just started...
|
|
||||||
if(!data){
|
|
||||||
that.__control_in_progress = (that.__control_in_progress || 0) + 1
|
|
||||||
|
|
||||||
// hide and remove current image indicator...
|
|
||||||
// NOTE: it will be reconstructed on
|
|
||||||
// next .focusImage(..)
|
|
||||||
var m = that.ribbons.viewer
|
|
||||||
.find('.current-marker')
|
|
||||||
.velocity({opacity: 0}, {
|
|
||||||
duration: 100,
|
|
||||||
complete: function(){
|
|
||||||
m.remove()
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
// store initial position...
|
|
||||||
var data = {
|
|
||||||
left: d.getOffset(this).left
|
|
||||||
}
|
|
||||||
r.data('drag-data', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// do the actual move...
|
|
||||||
d.setOffset(this, data.left + (g.deltaX / s))
|
|
||||||
|
|
||||||
// when done...
|
|
||||||
if(g.isFinal){
|
|
||||||
r.removeData('drag-data')
|
|
||||||
|
|
||||||
// XXX this seems to have trouble with off-screen images...
|
|
||||||
var central = that.ribbons.getImageByPosition('center', r)
|
|
||||||
|
|
||||||
// load stuff if needed...
|
|
||||||
that.updateRibbon(central)
|
|
||||||
|
|
||||||
// XXX add inertia....
|
|
||||||
//console.log('!!!!', g.velocityX)
|
|
||||||
//r.velocity({
|
|
||||||
// translateX: (data.left + g.deltaX + (g.velocityX * 10)) +'px'
|
|
||||||
//}, 'easeInSine')
|
|
||||||
|
|
||||||
// silently focus central image...
|
|
||||||
if(that.config['focus-central-image'] == 'silent'){
|
|
||||||
that.data.current = that.ribbons.getElemGID(central)
|
|
||||||
|
|
||||||
// focus central image in a normal manner...
|
|
||||||
} else if(that.config['focus-central-image']){
|
|
||||||
that.focusImage(that.ribbons.getElemGID(central))
|
|
||||||
}
|
|
||||||
|
|
||||||
setTimeout(function(){
|
|
||||||
that.__control_in_progress -= 1
|
|
||||||
if(that.__control_in_progress <= 0){
|
|
||||||
delete that.__control_in_progress
|
|
||||||
}
|
|
||||||
}, 50)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}],
|
|
||||||
],
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
// XXX try direct control with hammer.js
|
|
||||||
// XXX load state from config...
|
|
||||||
// XXX sometimes this makes the indicator hang for longer than needed...
|
|
||||||
// XXX BUG: this conflicts a bit whith ui-clickable...
|
|
||||||
// ...use this with hammer.js taps instead...
|
|
||||||
// XXX might be a good idea to make a universal and extensible control
|
|
||||||
// mode toggler...
|
|
||||||
// ...obvious chice would seem to be a meta toggler:
|
|
||||||
// config['control-mode'] = {
|
|
||||||
// <mode-name>: <mode-toggler>
|
|
||||||
// }
|
|
||||||
// and the action will toggle the given mode on and the previous
|
|
||||||
// off...
|
|
||||||
// XXX this seems a bit too complicated...
|
|
||||||
var IndirectControl =
|
|
||||||
module.IndirectControl = core.ImageGridFeatures.Feature({
|
|
||||||
title: '',
|
|
||||||
doc: '',
|
|
||||||
|
|
||||||
tag: 'ui-indirect-control',
|
|
||||||
// XXX is this correct???
|
|
||||||
exclusive: ['ui-control'],
|
|
||||||
depends: ['ui'],
|
|
||||||
|
|
||||||
config: {
|
|
||||||
},
|
|
||||||
|
|
||||||
actions: actions.Actions({
|
|
||||||
toggleSwipeHandling:['Interface/Toggle indirect control swipe handling',
|
|
||||||
toggler.Toggler(null,
|
|
||||||
function(_, state){
|
|
||||||
|
|
||||||
if(state == null){
|
|
||||||
return (this.ribbons
|
|
||||||
&& this.ribbons.viewer
|
|
||||||
&& this.ribbons.viewer.data('hammer'))
|
|
||||||
|| 'none'
|
|
||||||
|
|
||||||
// on...
|
|
||||||
} else if(state == 'handling-swipes'){
|
|
||||||
var that = this
|
|
||||||
var viewer = this.ribbons.viewer
|
|
||||||
|
|
||||||
// prevent multiple handlers...
|
|
||||||
if(viewer.data('hammer') != null){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
viewer.hammer()
|
|
||||||
|
|
||||||
var h = viewer.data('hammer')
|
|
||||||
h.get('swipe').set({direction: Hammer.DIRECTION_ALL})
|
|
||||||
|
|
||||||
viewer
|
|
||||||
.on('swipeleft', function(){ that.nextImage() })
|
|
||||||
.on('swiperight', function(){ that.prevImage() })
|
|
||||||
.on('swipeup', function(){ that.shiftImageUp() })
|
|
||||||
.on('swipedown', function(){ that.shiftImageDown() })
|
|
||||||
|
|
||||||
// off...
|
|
||||||
} else {
|
|
||||||
this.ribbons.viewer
|
|
||||||
.off('swipeleft')
|
|
||||||
.off('swiperight')
|
|
||||||
.off('swipeup')
|
|
||||||
.off('swipedown')
|
|
||||||
.removeData('hammer')
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
'handling-swipes')],
|
|
||||||
}),
|
|
||||||
|
|
||||||
handlers: [
|
|
||||||
['load',
|
|
||||||
function(){ a.toggleSwipeHandling('on') }],
|
|
||||||
['stop',
|
|
||||||
function(){ a.toggleSwipeHandling('off') }],
|
|
||||||
],
|
|
||||||
})
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
// Experiment: use native scroll for ribbons and view...
|
|
||||||
// Factors:
|
|
||||||
// + the browser will do all the heavy lifting and do it faster
|
|
||||||
// than we can ever hope to do it in JS (assumption)
|
|
||||||
// - will require us to add an extra container per ribbon
|
|
||||||
//
|
|
||||||
// Experiment result:
|
|
||||||
// - more uniform and fast across browsers
|
|
||||||
// (except FF -- can't disable scrollbars, need to cheat)
|
|
||||||
// - less controllable (inertia, gestures, ...)
|
|
||||||
// - is affected by scaling in a bad way -- paralax...
|
|
||||||
//
|
|
||||||
// Conclusion:
|
|
||||||
// - this again brings us to using code to control the scroll
|
|
||||||
// which in turn defeats the original purpose of avoiding
|
|
||||||
// extra complexity...
|
|
||||||
//
|
|
||||||
// See:
|
|
||||||
// experiments/native-scroll-ribbon.html
|
|
||||||
//
|
//
|
||||||
|
// NOTE: for legacy stuff see: features/ui-legacy.js
|
||||||
|
|
||||||
// XXX STUB: needs more thought....
|
// XXX STUB: needs more thought....
|
||||||
var ControlActions = actions.Actions({
|
var ControlActions = actions.Actions({
|
||||||
@ -2448,7 +2145,7 @@ var ControlActions = actions.Actions({
|
|||||||
})],
|
})],
|
||||||
|
|
||||||
|
|
||||||
// XXX we are not using this....
|
/*// XXX we are not using this....
|
||||||
__control_mode_handlers__: {
|
__control_mode_handlers__: {
|
||||||
indirect:
|
indirect:
|
||||||
function(state){
|
function(state){
|
||||||
@ -2484,6 +2181,7 @@ var ControlActions = actions.Actions({
|
|||||||
|
|
||||||
this.config['control-mode'] = state
|
this.config['control-mode'] = state
|
||||||
})],
|
})],
|
||||||
|
//*/
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -137,6 +137,36 @@ function doc(text, func){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Get list of applicable modes...
|
||||||
|
//
|
||||||
|
// XXX elem is not used...
|
||||||
|
var getApplicableModes =
|
||||||
|
module.getApplicableModes =
|
||||||
|
function getApplicableModes(keybindings, modes, elem){
|
||||||
|
return Object.keys(keybindings)
|
||||||
|
.filter(function(title){
|
||||||
|
|
||||||
|
if(keybindings[title].pattern != null){
|
||||||
|
var mode = keybindings[title].pattern
|
||||||
|
} else {
|
||||||
|
var mode = title
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if we need to skip this mode...
|
||||||
|
return modes == 'all'
|
||||||
|
// explicit mode match...
|
||||||
|
|| modes == mode
|
||||||
|
// 'any' means we need to check the mode...
|
||||||
|
|| (modes == 'any'
|
||||||
|
// '*' always matches...
|
||||||
|
&& mode == '*'
|
||||||
|
// match the mode...
|
||||||
|
// XXX is this too global???
|
||||||
|
|| $(mode).length != 0)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Build or normalize a modifier string.
|
// Build or normalize a modifier string.
|
||||||
//
|
//
|
||||||
// Acceptable argument sets:
|
// Acceptable argument sets:
|
||||||
@ -369,6 +399,9 @@ function getKeyHandlers(key, modifiers, keybindings, modes, shifted_keys, action
|
|||||||
shifted_keys = shifted_keys || _SHIFT_KEYS
|
shifted_keys = shifted_keys || _SHIFT_KEYS
|
||||||
actions = actions || {}
|
actions = actions || {}
|
||||||
|
|
||||||
|
// XXX too global -- need to pass some context...
|
||||||
|
var applicable_modes = getApplicableModes(keybindings, modes)
|
||||||
|
|
||||||
if(typeof(key) == typeof(123)){
|
if(typeof(key) == typeof(123)){
|
||||||
key = key
|
key = key
|
||||||
chr = toKeyName(key)
|
chr = toKeyName(key)
|
||||||
@ -403,22 +436,10 @@ function getKeyHandlers(key, modifiers, keybindings, modes, shifted_keys, action
|
|||||||
}
|
}
|
||||||
|
|
||||||
// older version compatibility...
|
// older version compatibility...
|
||||||
if(keybindings[title].pattern != null){
|
var mode = keybindings[title].pattern || title
|
||||||
var mode = keybindings[title].pattern
|
|
||||||
} else {
|
|
||||||
var mode = title
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if we need to skip this mode...
|
// check if we need to skip this mode...
|
||||||
if( !(modes == 'all'
|
if(applicable_modes.indexOf(title) < 0){
|
||||||
// explicit mode match...
|
|
||||||
|| modes == mode
|
|
||||||
// 'any' means we need to check the mode...
|
|
||||||
|| (modes == 'any'
|
|
||||||
// '*' always matches...
|
|
||||||
&& mode == '*'
|
|
||||||
// match the mode...
|
|
||||||
|| $(mode).length != 0))){
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -140,6 +140,10 @@ var BrowserClassPrototype = {
|
|||||||
browser.addClass('flat')
|
browser.addClass('flat')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(options.cls){
|
||||||
|
browser.addClass(options.cls)
|
||||||
|
}
|
||||||
|
|
||||||
// path...
|
// path...
|
||||||
var path = $('<div>')
|
var path = $('<div>')
|
||||||
.addClass('v-block path')
|
.addClass('v-block path')
|
||||||
@ -189,6 +193,9 @@ var BrowserPrototype = {
|
|||||||
|
|
||||||
// option defaults and doc...
|
// option defaults and doc...
|
||||||
options: {
|
options: {
|
||||||
|
// CSS classes to add to widget...
|
||||||
|
cls: null,
|
||||||
|
|
||||||
// Initial path...
|
// Initial path...
|
||||||
//path: null,
|
//path: null,
|
||||||
|
|
||||||
|
|||||||
@ -23,11 +23,11 @@
|
|||||||
"glob": "^4.0.6",
|
"glob": "^4.0.6",
|
||||||
"guarantee-events": "^1.0.0",
|
"guarantee-events": "^1.0.0",
|
||||||
"ig-features": "^2.0.0",
|
"ig-features": "^2.0.0",
|
||||||
"ig-actions": "^1.9.0",
|
"ig-actions": "^2.0.0",
|
||||||
"ig-object": "^1.0.1",
|
"ig-object": "^1.0.1",
|
||||||
"openseadragon": "^2.1.0",
|
"openseadragon": "^2.1.0",
|
||||||
"requirejs": "^2.1.23",
|
"requirejs": "^2.1.23",
|
||||||
"sharp": "^0.15.0"
|
"sharp": "^0.17.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"flickrapi": "^0.3.28"
|
"flickrapi": "^0.3.28"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user