186 lines
5.0 KiB
JavaScript
186 lines
5.0 KiB
JavaScript
/*
|
||
* Ext JS Library 2.0.2
|
||
* Copyright(c) 2006-2008, Ext JS, LLC.
|
||
* licensing@extjs.com
|
||
*
|
||
* extjs.com/license
|
||
*/
|
||
|
||
Ext.ux.Portal = Ext.extend(Ext.Panel, {
|
||
layout: 'column',
|
||
autoScroll: true,
|
||
cls: 'x-portal',
|
||
defaultType: 'portalcolumn',
|
||
|
||
initComponent: function() {
|
||
Ext.ux.Portal.superclass.initComponent.call(this);
|
||
this.addEvents({
|
||
validatedrop: true,
|
||
beforedragover: true,
|
||
dragover: true,
|
||
beforedrop: true,
|
||
drop: true
|
||
});
|
||
},
|
||
|
||
initEvents: function() {
|
||
Ext.ux.Portal.superclass.initEvents.call(this);
|
||
this.dd = new Ext.ux.Portal.DropZone(this, this.dropConfig);
|
||
}
|
||
});
|
||
Ext.reg('portal', Ext.ux.Portal);
|
||
|
||
|
||
Ext.ux.Portal.DropZone = function(portal, cfg) {
|
||
this.portal = portal;
|
||
Ext.dd.ScrollManager.register(portal.body);
|
||
Ext.ux.Portal.DropZone.superclass.constructor.call(this, portal.bwrap.dom, cfg);
|
||
portal.body.ddScrollConfig = this.ddScrollConfig;
|
||
};
|
||
|
||
Ext.extend(Ext.ux.Portal.DropZone, Ext.dd.DropTarget, {
|
||
ddScrollConfig: {
|
||
vthresh: 50,
|
||
hthresh: -1,
|
||
animate: true,
|
||
increment: 200
|
||
},
|
||
|
||
createEvent: function(dd, e, data, col, c, pos) {
|
||
return {
|
||
portal: this.portal,
|
||
panel: data.panel,
|
||
columnIndex: col,
|
||
column: c,
|
||
position: pos,
|
||
data: data,
|
||
source: dd,
|
||
rawEvent: e,
|
||
status: this.dropAllowed
|
||
};
|
||
},
|
||
|
||
notifyOver: function(dd, e, data) {
|
||
var xy = e.getXY(), portal = this.portal, px = dd.proxy;
|
||
|
||
// case column widths
|
||
if (!this.grid) {
|
||
this.grid = this.getGrid();
|
||
}
|
||
|
||
// handle case scroll where scrollbars appear during drag
|
||
var cw = portal.body.dom.clientWidth;
|
||
if (!this.lastCW) {
|
||
this.lastCW = cw;
|
||
} else if (this.lastCW != cw) {
|
||
this.lastCW = cw;
|
||
portal.doLayout();
|
||
this.grid = this.getGrid();
|
||
}
|
||
|
||
// determine column
|
||
var col = 0, xs = this.grid.columnX, cmatch = false;
|
||
for (var len = xs.length; col < len; col++) {
|
||
if (xy[0] < (xs[col].x + xs[col].w)) {
|
||
cmatch = true;
|
||
break;
|
||
}
|
||
}
|
||
// no match, fix last index
|
||
if (!cmatch) {
|
||
col--;
|
||
}
|
||
|
||
// find insert position
|
||
var p, match = false, pos = 0,
|
||
c = portal.items.itemAt(col),
|
||
items = c.items.items;
|
||
|
||
for (var len = items.length; pos < len; pos++) {
|
||
p = items[pos];
|
||
var h = p.el.getHeight();
|
||
if (h !== 0 && (p.el.getY() + (h / 2)) > xy[1]) {
|
||
match = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
var overEvent = this.createEvent(dd, e, data, col, c,
|
||
match && p ? pos : c.items.getCount());
|
||
|
||
if (portal.fireEvent('validatedrop', overEvent) !== false &&
|
||
portal.fireEvent('beforedragover', overEvent) !== false) {
|
||
|
||
// make sure proxy width is fluid
|
||
px.getProxy().setWidth('auto');
|
||
|
||
if (p) {
|
||
px.moveProxy(p.el.dom.parentNode, match ? p.el.dom : null);
|
||
} else {
|
||
px.moveProxy(c.el.dom, null);
|
||
}
|
||
|
||
this.lastPos = { c: c, col: col, p: match && p ? pos : false };
|
||
this.scrollPos = portal.body.getScroll();
|
||
|
||
portal.fireEvent('dragover', overEvent);
|
||
|
||
return overEvent.status; ;
|
||
} else {
|
||
return overEvent.status;
|
||
}
|
||
|
||
},
|
||
|
||
notifyOut: function() {
|
||
delete this.grid;
|
||
},
|
||
|
||
notifyDrop: function(dd, e, data) {
|
||
delete this.grid;
|
||
if (!this.lastPos) {
|
||
return;
|
||
}
|
||
var c = this.lastPos.c, col = this.lastPos.col, pos = this.lastPos.p;
|
||
|
||
var dropEvent = this.createEvent(dd, e, data, col, c,
|
||
pos !== false ? pos : c.items.getCount());
|
||
|
||
if (this.portal.fireEvent('validatedrop', dropEvent) !== false &&
|
||
this.portal.fireEvent('beforedrop', dropEvent) !== false) {
|
||
|
||
dd.proxy.getProxy().remove();
|
||
dd.panel.el.dom.parentNode.removeChild(dd.panel.el.dom);
|
||
if (pos !== false) {
|
||
c.insert(pos, dd.panel);
|
||
} else {
|
||
c.add(dd.panel);
|
||
}
|
||
|
||
c.doLayout();
|
||
|
||
this.portal.fireEvent('drop', dropEvent);
|
||
|
||
// scroll position is lost on drop, fix it
|
||
var st = this.scrollPos.top;
|
||
if (st) {
|
||
var d = this.portal.body.dom;
|
||
setTimeout(function() {
|
||
d.scrollTop = st;
|
||
}, 10);
|
||
}
|
||
|
||
}
|
||
delete this.lastPos;
|
||
},
|
||
|
||
// internal cache of body and column coords
|
||
getGrid: function() {
|
||
var box = this.portal.bwrap.getBox();
|
||
box.columnX = [];
|
||
this.portal.items.each(function(c) {
|
||
box.columnX.push({ x: c.el.getX(), w: c.el.getWidth() });
|
||
});
|
||
return box;
|
||
}
|
||
}); |