icloudtweetdeckhipchattelegramhangoutsslackgmailskypefacebook-workplaceoutlookemailmicrosoft-teamsdiscordmessengercustom-servicesmacoslinuxwindowsinboxwhatsapp
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.
270 lines
8.2 KiB
270 lines
8.2 KiB
9 years ago
|
/**
|
||
|
* 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();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
});
|