messengercustom-servicesmacoslinuxwindowsinboxwhatsappicloudtweetdeckhipchattelegramhangoutsslackgmailskypefacebook-workplaceoutlookemailmicrosoft-teamsdiscord
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
269 lines
8.2 KiB
269 lines
8.2 KiB
/** |
|
* Provides automatic scrolling of overflow regions in the page during drag operations. |
|
* |
|
* The ScrollManager configs will be used as the defaults for any scroll container registered with it, but you can also |
|
* override most of the configs per scroll container by adding a ddScrollConfig object to the target element that |
|
* contains these properties: {@link #hthresh}, {@link #vthresh}, {@link #increment} and {@link #frequency}. Example |
|
* usage: |
|
* |
|
* var el = Ext.get('scroll-ct'); |
|
* el.ddScrollConfig = { |
|
* vthresh: 50, |
|
* hthresh: -1, |
|
* frequency: 100, |
|
* increment: 200 |
|
* }; |
|
* Ext.dd.ScrollManager.register(el); |
|
* |
|
* Note: This class is designed to be used in "Point Mode |
|
*/ |
|
Ext.define('Ext.dd.ScrollManager', { |
|
singleton: true, |
|
requires: [ |
|
'Ext.dd.DragDropManager' |
|
], |
|
|
|
dirTrans: { |
|
up: -1, |
|
left: -1, |
|
down: 1, |
|
right: 1 |
|
}, |
|
|
|
constructor: function() { |
|
var ddm = Ext.dd.DragDropManager; |
|
ddm.fireEvents = Ext.Function.createSequence(ddm.fireEvents, this.onFire, this); |
|
ddm.stopDrag = Ext.Function.createSequence(ddm.stopDrag, this.onStop, this); |
|
this.doScroll = this.doScroll.bind(this); |
|
this.ddmInstance = ddm; |
|
this.els = {}; |
|
this.dragEl = null; |
|
this.proc = {}; |
|
}, |
|
|
|
onStop: function(e){ |
|
var sm = Ext.dd.ScrollManager; |
|
sm.dragEl = null; |
|
sm.clearProc(); |
|
}, |
|
|
|
triggerRefresh: function() { |
|
if (this.ddmInstance.dragCurrent) { |
|
this.ddmInstance.refreshCache(this.ddmInstance.dragCurrent.groups); |
|
} |
|
}, |
|
|
|
doScroll: function() { |
|
var me = this; |
|
|
|
if (me.ddmInstance.dragCurrent) { |
|
var proc = me.proc, |
|
procEl = proc.el, |
|
scrollComponent = proc.component, |
|
ddScrollConfig = proc.el.ddScrollConfig, |
|
distance = ddScrollConfig && ddScrollConfig.increment ? ddScrollConfig.increment : me.increment, |
|
animate = ddScrollConfig && 'animate' in ddScrollConfig ? ddScrollConfig.animate : me.animate, |
|
afterScroll = function() { |
|
me.triggerRefresh(); |
|
}; |
|
|
|
if (animate) { |
|
if (animate === true) { |
|
animate = { |
|
callback: afterScroll |
|
}; |
|
} else { |
|
animate.callback = animate.callback ? |
|
Ext.Function.createSequence(animate.callback, afterScroll) : |
|
afterScroll; |
|
} |
|
} |
|
|
|
// If the element is the overflow element of a Component, and we are scrolling using CSS transform, |
|
// Then scroll using the correct method! |
|
if (scrollComponent) { |
|
|
|
// Left/right means increment has to be negated |
|
distance = distance * me.dirTrans[proc.dir]; |
|
|
|
// Pass X or Y params depending upon dimension being scrolled |
|
if (proc.dir === 'up' || proc.dir === 'down') { |
|
scrollComponent.scrollBy(0, distance, animate); |
|
} else { |
|
scrollComponent.scrollBy(distance, 0, animate); |
|
} |
|
} |
|
else { |
|
procEl.scroll(proc.dir, distance, animate); |
|
} |
|
|
|
if (!animate) { |
|
afterScroll(); |
|
} |
|
} |
|
}, |
|
|
|
clearProc: function() { |
|
var proc = this.proc; |
|
if (proc.id) { |
|
clearInterval(proc.id); |
|
} |
|
proc.id = 0; |
|
proc.el = null; |
|
proc.dir = ""; |
|
}, |
|
|
|
startProc: function(el, dir) { |
|
var me = this, |
|
proc = me.proc, |
|
group, freq; |
|
|
|
me.clearProc(); |
|
proc.el = el; |
|
proc.dir = dir; |
|
|
|
group = el.ddScrollConfig ? el.ddScrollConfig.ddGroup : undefined; |
|
freq = (el.ddScrollConfig && el.ddScrollConfig.frequency) ? el.ddScrollConfig.frequency |
|
: me.frequency; |
|
|
|
if (group === undefined || me.ddmInstance.dragCurrent.ddGroup === group) { |
|
proc.id = Ext.interval(me.doScroll, freq); |
|
} |
|
}, |
|
|
|
onFire: function(e, isDrop) { |
|
var me = this, |
|
pt, |
|
proc, |
|
els, |
|
id, |
|
el, |
|
elementRegion, |
|
configSource; |
|
|
|
if (isDrop || !me.ddmInstance.dragCurrent) { |
|
return; |
|
} |
|
if (!me.dragEl || me.dragEl !== me.ddmInstance.dragCurrent) { |
|
me.dragEl = me.ddmInstance.dragCurrent; |
|
// refresh regions on drag start |
|
me.refreshCache(); |
|
} |
|
|
|
pt = e.getPoint(); |
|
proc = me.proc; |
|
els = me.els; |
|
|
|
for (id in els) { |
|
el = els[id]; |
|
elementRegion = el._region; |
|
configSource = el.ddScrollConfig || me; |
|
if (elementRegion && elementRegion.contains(pt) && el.isScrollable()) { |
|
if (elementRegion.bottom - pt.y <= configSource.vthresh) { |
|
if(proc.el !== el){ |
|
me.startProc(el, "down"); |
|
} |
|
return; |
|
} else if (elementRegion.right - pt.x <= configSource.hthresh) { |
|
if (proc.el !== el) { |
|
me.startProc(el, "right"); |
|
} |
|
return; |
|
} else if (pt.y - elementRegion.top <= configSource.vthresh) { |
|
if (proc.el !== el) { |
|
me.startProc(el, "up"); |
|
} |
|
return; |
|
} else if (pt.x - elementRegion.left <= configSource.hthresh) { |
|
if (proc.el !== el) { |
|
me.startProc(el, "left"); |
|
} |
|
return; |
|
} |
|
} |
|
} |
|
me.clearProc(); |
|
}, |
|
|
|
/** |
|
* Registers new overflow element(s) to auto scroll |
|
* @param {String/HTMLElement/Ext.dom.Element/String[]/HTMLElement[]/Ext.dom.Element[]} el |
|
* The id of or the element to be scrolled or an array of either |
|
*/ |
|
register : function(el){ |
|
if (Ext.isArray(el)) { |
|
for(var i = 0, len = el.length; i < len; i++) { |
|
this.register(el[i]); |
|
} |
|
} else { |
|
el = Ext.get(el); |
|
this.els[el.id] = el; |
|
} |
|
}, |
|
|
|
/** |
|
* Unregisters overflow element(s) so they are no longer scrolled |
|
* @param {String/HTMLElement/Ext.dom.Element/String[]/HTMLElement[]/Ext.dom.Element[]} el |
|
* The id of or the element to be removed or an array of either |
|
*/ |
|
unregister : function(el){ |
|
if(Ext.isArray(el)){ |
|
for (var i = 0, len = el.length; i < len; i++) { |
|
this.unregister(el[i]); |
|
} |
|
}else{ |
|
el = Ext.get(el); |
|
delete this.els[el.id]; |
|
} |
|
}, |
|
|
|
/** |
|
* The number of pixels from the top or bottom edge of a container the pointer needs to be to trigger scrolling |
|
*/ |
|
vthresh : 25 * (window.devicePixelRatio || 1), |
|
|
|
/** |
|
* The number of pixels from the right or left edge of a container the pointer needs to be to trigger scrolling |
|
*/ |
|
hthresh : 25 * (window.devicePixelRatio || 1), |
|
|
|
/** |
|
* The number of pixels to scroll in each scroll increment |
|
*/ |
|
increment : 100, |
|
|
|
/** |
|
* The frequency of scrolls in milliseconds |
|
*/ |
|
frequency : 500, |
|
|
|
/** |
|
* True to animate the scroll |
|
*/ |
|
animate: true, |
|
|
|
/** |
|
* The animation duration in seconds - MUST BE less than Ext.dd.ScrollManager.frequency! |
|
*/ |
|
animDuration: 0.4, |
|
|
|
/** |
|
* @property {String} ddGroup |
|
* The named drag drop {@link Ext.dd.DragSource#ddGroup group} to which this container belongs. If a ddGroup is |
|
* specified, then container scrolling will only occur when a dragged object is in the same ddGroup. |
|
*/ |
|
ddGroup: undefined, |
|
|
|
/** |
|
* Manually trigger a cache refresh. |
|
*/ |
|
refreshCache : function(){ |
|
var els = this.els, |
|
id; |
|
for (id in els) { |
|
if (typeof els[id] === 'object') { // for people extending the object prototype |
|
els[id]._region = els[id].getRegion(); |
|
} |
|
} |
|
} |
|
});
|
|
|