mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 18:30:09 +00:00
cleanup and refinement of ribbon pan handler (still not too happy with it)...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
e8c59924e9
commit
856d212aed
@ -500,6 +500,11 @@ module.StatusBar = core.ImageGridFeatures.Feature({
|
|||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
|
|
||||||
|
['ribbonPanning.post',
|
||||||
|
function(_, gid){
|
||||||
|
gid == this.data.getRibbon() && this.updateStatusBar()
|
||||||
|
}],
|
||||||
|
|
||||||
// Workspace...
|
// Workspace...
|
||||||
['saveWorkspace',
|
['saveWorkspace',
|
||||||
core.makeWorkspaceConfigWriter(
|
core.makeWorkspaceConfigWriter(
|
||||||
|
|||||||
@ -1800,8 +1800,25 @@ var ControlActions = actions.Actions({
|
|||||||
'focus-central-image': 'silent',
|
'focus-central-image': 'silent',
|
||||||
|
|
||||||
'ribbon-pan-threshold': 30,
|
'ribbon-pan-threshold': 30,
|
||||||
|
'control-in-progress-timeout': 100,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Ribbon pan "event"...
|
||||||
|
//
|
||||||
|
// Protocol:
|
||||||
|
// - pre phase is called when pan is started.
|
||||||
|
// - post phase is called when pan is finished.
|
||||||
|
//
|
||||||
|
// This is not intended to be called by user, instead it is
|
||||||
|
// internally called by the pan handler.
|
||||||
|
//
|
||||||
|
// NOTE: more than one ribbon can be panned at once.
|
||||||
|
ribbonPanning: ['- Interface/',
|
||||||
|
core.notUserCallable(function(gid){
|
||||||
|
// This is ribbon pan event...
|
||||||
|
//
|
||||||
|
// Not for direct use.
|
||||||
|
})],
|
||||||
|
|
||||||
// XXX this is really slow on IE...
|
// XXX this is really slow on IE...
|
||||||
toggleRibbonPanHandling: ['Interface/Toggle ribbon pan handling',
|
toggleRibbonPanHandling: ['Interface/Toggle ribbon pan handling',
|
||||||
@ -1817,6 +1834,9 @@ var ControlActions = actions.Actions({
|
|||||||
// XXX
|
// XXX
|
||||||
var that = this
|
var that = this
|
||||||
var r = this.ribbons.getRibbon(target)
|
var r = this.ribbons.getRibbon(target)
|
||||||
|
var rgid = this.ribbons.getElemGID(r)
|
||||||
|
var data = false
|
||||||
|
var post_handlers
|
||||||
|
|
||||||
// setup dragging...
|
// setup dragging...
|
||||||
if(r.length > 0 && !r.hasClass('draggable')){
|
if(r.length > 0 && !r.hasClass('draggable')){
|
||||||
@ -1835,17 +1855,16 @@ var ControlActions = actions.Actions({
|
|||||||
//evt.stopPropagation()
|
//evt.stopPropagation()
|
||||||
|
|
||||||
// XXX stop all previous animations...
|
// XXX stop all previous animations...
|
||||||
//r.velocity("stop")
|
r.velocity("stop")
|
||||||
|
|
||||||
var d = that.ribbons.dom
|
var d = that.ribbons.dom
|
||||||
var s = that.scale
|
|
||||||
var g = evt.gesture
|
var g = evt.gesture
|
||||||
|
var s = that.scale
|
||||||
var data = r.data('drag-data')
|
|
||||||
|
|
||||||
// we just started...
|
// we just started...
|
||||||
if(!data){
|
if(!data){
|
||||||
that.__control_in_progress = (that.__control_in_progress || 0) + 1
|
that.__control_in_progress = (that.__control_in_progress || 0) + 1
|
||||||
|
post_handlers = that.ribbonPanning.pre(that, [rgid])
|
||||||
|
|
||||||
// hide and remove current image indicator...
|
// hide and remove current image indicator...
|
||||||
// NOTE: it will be reconstructed on
|
// NOTE: it will be reconstructed on
|
||||||
@ -1860,20 +1879,21 @@ var ControlActions = actions.Actions({
|
|||||||
})
|
})
|
||||||
|
|
||||||
// store initial position...
|
// store initial position...
|
||||||
var data = {
|
data = {
|
||||||
left: d.getOffset(this).left,
|
//left: d.getOffset(this).left,
|
||||||
|
left: $(this).transform('x'),
|
||||||
pointers: g.pointers.length,
|
pointers: g.pointers.length,
|
||||||
}
|
}
|
||||||
r.data('drag-data', data)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// do the actual move...
|
// do the actual move...
|
||||||
d.setOffset(this, data.left + (g.deltaX / s))
|
//d.setOffset(this, data.left + (g.deltaX / s))
|
||||||
|
r.transform({x: data.left + (g.deltaX / s)})
|
||||||
|
|
||||||
/* XXX this seems to offer no speed advantages
|
/* XXX this seems to offer no speed advantages
|
||||||
* vs. .setOffset(..) but does not play
|
* vs. .setOffset(..) but does not play
|
||||||
* well with .updateRibbon(..)
|
* well with .updateRibbon(..)
|
||||||
$(this)
|
r
|
||||||
.velocity('stop')
|
.velocity('stop')
|
||||||
.velocity({
|
.velocity({
|
||||||
translateX: data.left + (g.deltaX / s),
|
translateX: data.left + (g.deltaX / s),
|
||||||
@ -1896,19 +1916,44 @@ var ControlActions = actions.Actions({
|
|||||||
|
|
||||||
// when done...
|
// when done...
|
||||||
if(g.isFinal){
|
if(g.isFinal){
|
||||||
r.removeData('drag-data')
|
|
||||||
|
|
||||||
// XXX this seems to have trouble with off-screen images...
|
|
||||||
var central = that.ribbons.getImageByPosition('center', r)
|
var central = that.ribbons.getImageByPosition('center', r)
|
||||||
|
|
||||||
|
// check if central if off screen, if yes,
|
||||||
|
// nudge it into user-accessible area...
|
||||||
|
//
|
||||||
|
// we are fully off screen -- focus first/last image...
|
||||||
|
if(central == null){
|
||||||
|
var gid = that.data.getImage(
|
||||||
|
r.offset().left < 0 ? -1 : 0, rgid)
|
||||||
|
|
||||||
|
that.centerImage(gid)
|
||||||
|
central = that.ribbons.getImage(gid)
|
||||||
|
|
||||||
|
// partly out the left -- show last image...
|
||||||
|
} else if(central.offset().left < 0){
|
||||||
|
r.transform({
|
||||||
|
x: r.transform('x') - (central.offset().left / s)
|
||||||
|
})
|
||||||
|
|
||||||
|
// partly out the right -- show first image...
|
||||||
|
} else if(central.offset().left + (central.width()*s)
|
||||||
|
> that.ribbons.viewer.width()){
|
||||||
|
r.transform({
|
||||||
|
x: r.transform('x')
|
||||||
|
+ (that.ribbons.viewer.width()
|
||||||
|
- (central.offset().left
|
||||||
|
+ central.width()*s)) / s
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// load stuff if needed...
|
// load stuff if needed...
|
||||||
that.updateRibbon(central)
|
that.updateRibbon(central)
|
||||||
|
|
||||||
|
/*
|
||||||
// XXX add inertia....
|
// XXX add inertia....
|
||||||
/* XXX
|
|
||||||
console.log('!!!!', g.velocityX)
|
|
||||||
r.velocity({
|
r.velocity({
|
||||||
translateX: (data.left + g.deltaX + (g.velocityX * 10)) +'px'
|
translateX: (data.left + ((g.deltaX + (g.velocityX * 10)) / s)) +'px'
|
||||||
}, 'easeInSine')
|
}, 'easeInSine')
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1916,21 +1961,27 @@ var ControlActions = actions.Actions({
|
|||||||
if(that.config['focus-central-image'] == 'silent'){
|
if(that.config['focus-central-image'] == 'silent'){
|
||||||
var gid = that.ribbons.getElemGID(central)
|
var gid = that.ribbons.getElemGID(central)
|
||||||
|
|
||||||
// XXX is this the right way to do this???
|
that.data.focusImage(gid, rgid)
|
||||||
that.data.focusImage(gid)
|
that.ribbons.focusImage(a.current)
|
||||||
that.ribbons.focusImage(gid)
|
|
||||||
|
|
||||||
// focus central image in a normal manner...
|
// focus central image in a normal manner...
|
||||||
} else if(that.config['focus-central-image']){
|
} else if(that.config['focus-central-image']){
|
||||||
that.focusImage(that.ribbons.getElemGID(central))
|
var gid = that.ribbons.getElemGID(central)
|
||||||
|
|
||||||
|
that.data.focusImage(gid, rgid)
|
||||||
|
that.focusImage()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data = false
|
||||||
|
|
||||||
|
that.ribbonPanning.post(that, post_handlers)
|
||||||
|
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
that.__control_in_progress -= 1
|
that.__control_in_progress -= 1
|
||||||
if(that.__control_in_progress <= 0){
|
if(that.__control_in_progress <= 0){
|
||||||
delete that.__control_in_progress
|
delete that.__control_in_progress
|
||||||
}
|
}
|
||||||
}, 50)
|
}, that.config['control-in-progress-timeout'] || 100)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -358,6 +358,9 @@ function Action(name, doc, ldoc, func){
|
|||||||
|
|
||||||
meth.func = func
|
meth.func = func
|
||||||
|
|
||||||
|
// make introspection be a bit better...
|
||||||
|
meth.toString = func.toString.bind(func)
|
||||||
|
|
||||||
return meth
|
return meth
|
||||||
}
|
}
|
||||||
// this will make action instances behave like real functions...
|
// this will make action instances behave like real functions...
|
||||||
@ -370,24 +373,60 @@ Action.prototype.chainApply = function(context, inner, args){
|
|||||||
var res = context
|
var res = context
|
||||||
var outer = this.name
|
var outer = this.name
|
||||||
|
|
||||||
|
var data = this.pre(context, args)
|
||||||
|
|
||||||
|
// call the inner action/function if preset....
|
||||||
|
if(inner){
|
||||||
|
//res = inner instanceof Function ?
|
||||||
|
inner instanceof Function ?
|
||||||
|
inner.call(context, args)
|
||||||
|
: inner instanceof Array && inner.length > 0 ?
|
||||||
|
context[inner.pop()].chainCall(context, inner, args)
|
||||||
|
: typeof(inner) == typeof('str') ?
|
||||||
|
context[inner].chainCall(context, null, args)
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.post(context, data)
|
||||||
|
}
|
||||||
|
Action.prototype.chainCall = function(context, inner){
|
||||||
|
return this.chainApply(context, inner, args2array(arguments).slice(2))
|
||||||
|
}
|
||||||
|
|
||||||
|
// The pre/post stage runners...
|
||||||
|
//
|
||||||
|
// .pre(context, args)
|
||||||
|
// -> data
|
||||||
|
//
|
||||||
|
// .post(context, data)
|
||||||
|
// -> result
|
||||||
|
//
|
||||||
|
Action.prototype.pre = function(context, args){
|
||||||
|
args = args || []
|
||||||
|
|
||||||
|
var res = context
|
||||||
|
var outer = this.name
|
||||||
|
|
||||||
var getHandlers = context.getHandlers || MetaActions.getHandlers
|
var getHandlers = context.getHandlers || MetaActions.getHandlers
|
||||||
var isToggler = context.isToggler || MetaActions.isToggler
|
var isToggler = context.isToggler || MetaActions.isToggler
|
||||||
|
|
||||||
// get .__call__(..) wrapper handler list...
|
|
||||||
var call_wrapper = outer != '__call__' && inner != '__call__' ?
|
|
||||||
getHandlers.call(context, '__call__')
|
|
||||||
: []
|
|
||||||
|
|
||||||
// get the handler list...
|
// get the handler list...
|
||||||
var handlers = getHandlers.call(context, outer)
|
var handlers = getHandlers.call(context, outer)
|
||||||
|
|
||||||
// special case: toggler -- do not handle special args...
|
// special case: toggler -- do not handle special args...
|
||||||
|
// XXX should this be here???
|
||||||
if(isToggler.call(context, outer)
|
if(isToggler.call(context, outer)
|
||||||
&& args.length == 1
|
&& args.length == 1
|
||||||
&& (args[0] == '?' || args[0] == '??')){
|
&& (args[0] == '?' || args[0] == '??')){
|
||||||
return handlers.slice(-1)[0].pre.apply(context, args)
|
return {
|
||||||
|
result: handlers.slice(-1)[0].pre.apply(context, args),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var call_wrapper = outer != '__call__' ?
|
||||||
|
getHandlers.call(context, '__call__')
|
||||||
|
: []
|
||||||
|
|
||||||
// wrapper handlers: pre phase...
|
// wrapper handlers: pre phase...
|
||||||
call_wrapper = call_wrapper
|
call_wrapper = call_wrapper
|
||||||
.map(function(a){
|
.map(function(a){
|
||||||
@ -430,25 +469,29 @@ Action.prototype.chainApply = function(context, inner, args){
|
|||||||
return a
|
return a
|
||||||
})
|
})
|
||||||
|
|
||||||
// call the inner action/function if preset....
|
// return context if nothing specific is returned...
|
||||||
if(inner){
|
|
||||||
//res = inner instanceof Function ?
|
|
||||||
inner instanceof Function ?
|
|
||||||
inner.call(context, args)
|
|
||||||
: inner instanceof Array && inner.length > 0 ?
|
|
||||||
context[inner.pop()].chainCall(context, inner, args)
|
|
||||||
: typeof(inner) == typeof('str') ?
|
|
||||||
context[inner].chainCall(context, null, args)
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
|
|
||||||
// return this if nothing specific is returned...
|
|
||||||
res = res === undefined ? context : res
|
res = res === undefined ? context : res
|
||||||
|
|
||||||
|
return {
|
||||||
|
arguments: args,
|
||||||
|
|
||||||
|
wrapper: call_wrapper,
|
||||||
|
handlers: handlers,
|
||||||
|
|
||||||
|
result: res,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Action.prototype.post = function(context, data){
|
||||||
|
var res = data.result || context
|
||||||
|
|
||||||
|
var args = data.arguments || []
|
||||||
// the post handlers get the result as the first argument...
|
// the post handlers get the result as the first argument...
|
||||||
args.splice(0, 0, res)
|
args.splice(0, 0, res)
|
||||||
|
|
||||||
|
var outer = this.name
|
||||||
|
|
||||||
// handlers: post phase...
|
// handlers: post phase...
|
||||||
handlers
|
data.handlers && data.handlers
|
||||||
// NOTE: post handlers are called LIFO -- last defined last...
|
// NOTE: post handlers are called LIFO -- last defined last...
|
||||||
.reverse()
|
.reverse()
|
||||||
.forEach(function(a){
|
.forEach(function(a){
|
||||||
@ -459,7 +502,7 @@ Action.prototype.chainApply = function(context, inner, args){
|
|||||||
})
|
})
|
||||||
|
|
||||||
// wrapper handlers: post phase...
|
// wrapper handlers: post phase...
|
||||||
call_wrapper
|
data.wrapper && data.wrapper
|
||||||
// NOTE: post handlers are called LIFO -- last defined last...
|
// NOTE: post handlers are called LIFO -- last defined last...
|
||||||
.reverse()
|
.reverse()
|
||||||
.forEach(function(a){
|
.forEach(function(a){
|
||||||
@ -469,13 +512,8 @@ Action.prototype.chainApply = function(context, inner, args){
|
|||||||
: a.post.call(context, res, outer, args.slice(1)))
|
: a.post.call(context, res, outer, args.slice(1)))
|
||||||
})
|
})
|
||||||
|
|
||||||
// action result...
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
Action.prototype.chainCall = function(context, inner){
|
|
||||||
return this.chainApply(context, inner, args2array(arguments).slice(2))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// A base action-set object...
|
// A base action-set object...
|
||||||
//
|
//
|
||||||
|
|||||||
@ -1027,7 +1027,7 @@ var RibbonsPrototype = {
|
|||||||
// sort images by distance...
|
// sort images by distance...
|
||||||
.sort(function(a, b){ return Math.abs(a[0]) - Math.abs(b[0]) })
|
.sort(function(a, b){ return Math.abs(a[0]) - Math.abs(b[0]) })
|
||||||
|
|
||||||
var a = res[0][0]
|
var a = res[0] ? res[0][0] : null
|
||||||
var b = res[1] ? res[1][0] : null
|
var b = res[1] ? res[1][0] : null
|
||||||
|
|
||||||
// we have two images that are about the same distance from
|
// we have two images that are about the same distance from
|
||||||
@ -1041,7 +1041,8 @@ var RibbonsPrototype = {
|
|||||||
|
|
||||||
// a single hit...
|
// a single hit...
|
||||||
} else {
|
} else {
|
||||||
return res[0][1]
|
// NOTE: if no image is on screen this will get nothing...
|
||||||
|
return res[0] ? res[0][1] : null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user