mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-28 18:00: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...
|
||||
['saveWorkspace',
|
||||
core.makeWorkspaceConfigWriter(
|
||||
|
||||
@ -1800,8 +1800,25 @@ var ControlActions = actions.Actions({
|
||||
'focus-central-image': 'silent',
|
||||
|
||||
'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...
|
||||
toggleRibbonPanHandling: ['Interface/Toggle ribbon pan handling',
|
||||
@ -1817,6 +1834,9 @@ var ControlActions = actions.Actions({
|
||||
// XXX
|
||||
var that = this
|
||||
var r = this.ribbons.getRibbon(target)
|
||||
var rgid = this.ribbons.getElemGID(r)
|
||||
var data = false
|
||||
var post_handlers
|
||||
|
||||
// setup dragging...
|
||||
if(r.length > 0 && !r.hasClass('draggable')){
|
||||
@ -1835,17 +1855,16 @@ var ControlActions = actions.Actions({
|
||||
//evt.stopPropagation()
|
||||
|
||||
// XXX stop all previous animations...
|
||||
//r.velocity("stop")
|
||||
r.velocity("stop")
|
||||
|
||||
var d = that.ribbons.dom
|
||||
var s = that.scale
|
||||
var g = evt.gesture
|
||||
|
||||
var data = r.data('drag-data')
|
||||
var s = that.scale
|
||||
|
||||
// we just started...
|
||||
if(!data){
|
||||
that.__control_in_progress = (that.__control_in_progress || 0) + 1
|
||||
post_handlers = that.ribbonPanning.pre(that, [rgid])
|
||||
|
||||
// hide and remove current image indicator...
|
||||
// NOTE: it will be reconstructed on
|
||||
@ -1860,20 +1879,21 @@ var ControlActions = actions.Actions({
|
||||
})
|
||||
|
||||
// store initial position...
|
||||
var data = {
|
||||
left: d.getOffset(this).left,
|
||||
data = {
|
||||
//left: d.getOffset(this).left,
|
||||
left: $(this).transform('x'),
|
||||
pointers: g.pointers.length,
|
||||
}
|
||||
r.data('drag-data', data)
|
||||
}
|
||||
|
||||
// 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
|
||||
* vs. .setOffset(..) but does not play
|
||||
* well with .updateRibbon(..)
|
||||
$(this)
|
||||
r
|
||||
.velocity('stop')
|
||||
.velocity({
|
||||
translateX: data.left + (g.deltaX / s),
|
||||
@ -1896,19 +1916,44 @@ var ControlActions = actions.Actions({
|
||||
|
||||
// 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)
|
||||
|
||||
// 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...
|
||||
that.updateRibbon(central)
|
||||
|
||||
/*
|
||||
// XXX add inertia....
|
||||
/* XXX
|
||||
console.log('!!!!', g.velocityX)
|
||||
r.velocity({
|
||||
translateX: (data.left + g.deltaX + (g.velocityX * 10)) +'px'
|
||||
translateX: (data.left + ((g.deltaX + (g.velocityX * 10)) / s)) +'px'
|
||||
}, 'easeInSine')
|
||||
*/
|
||||
|
||||
@ -1916,21 +1961,27 @@ var ControlActions = actions.Actions({
|
||||
if(that.config['focus-central-image'] == 'silent'){
|
||||
var gid = that.ribbons.getElemGID(central)
|
||||
|
||||
// XXX is this the right way to do this???
|
||||
that.data.focusImage(gid)
|
||||
that.ribbons.focusImage(gid)
|
||||
that.data.focusImage(gid, rgid)
|
||||
that.ribbons.focusImage(a.current)
|
||||
|
||||
// focus central image in a normal manner...
|
||||
} 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(){
|
||||
that.__control_in_progress -= 1
|
||||
if(that.__control_in_progress <= 0){
|
||||
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
|
||||
|
||||
// make introspection be a bit better...
|
||||
meth.toString = func.toString.bind(func)
|
||||
|
||||
return meth
|
||||
}
|
||||
// this will make action instances behave like real functions...
|
||||
@ -370,24 +373,60 @@ Action.prototype.chainApply = function(context, inner, args){
|
||||
var res = context
|
||||
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 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...
|
||||
var handlers = getHandlers.call(context, outer)
|
||||
|
||||
// special case: toggler -- do not handle special args...
|
||||
// XXX should this be here???
|
||||
if(isToggler.call(context, outer)
|
||||
&& args.length == 1
|
||||
&& (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...
|
||||
call_wrapper = call_wrapper
|
||||
.map(function(a){
|
||||
@ -430,25 +469,29 @@ Action.prototype.chainApply = function(context, inner, args){
|
||||
return a
|
||||
})
|
||||
|
||||
// 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 if nothing specific is returned...
|
||||
// return context if nothing specific is returned...
|
||||
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...
|
||||
args.splice(0, 0, res)
|
||||
|
||||
var outer = this.name
|
||||
|
||||
// handlers: post phase...
|
||||
handlers
|
||||
data.handlers && data.handlers
|
||||
// NOTE: post handlers are called LIFO -- last defined last...
|
||||
.reverse()
|
||||
.forEach(function(a){
|
||||
@ -459,7 +502,7 @@ Action.prototype.chainApply = function(context, inner, args){
|
||||
})
|
||||
|
||||
// wrapper handlers: post phase...
|
||||
call_wrapper
|
||||
data.wrapper && data.wrapper
|
||||
// NOTE: post handlers are called LIFO -- last defined last...
|
||||
.reverse()
|
||||
.forEach(function(a){
|
||||
@ -469,13 +512,8 @@ Action.prototype.chainApply = function(context, inner, args){
|
||||
: a.post.call(context, res, outer, args.slice(1)))
|
||||
})
|
||||
|
||||
// action result...
|
||||
return res
|
||||
}
|
||||
Action.prototype.chainCall = function(context, inner){
|
||||
return this.chainApply(context, inner, args2array(arguments).slice(2))
|
||||
}
|
||||
|
||||
|
||||
// A base action-set object...
|
||||
//
|
||||
|
||||
@ -1027,7 +1027,7 @@ var RibbonsPrototype = {
|
||||
// sort images by distance...
|
||||
.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
|
||||
|
||||
// we have two images that are about the same distance from
|
||||
@ -1041,7 +1041,8 @@ var RibbonsPrototype = {
|
||||
|
||||
// a single hit...
|
||||
} 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