X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/c930e9176a5a85509c5b0230e2bff5c22a591432..f562e4c6e5fac7bcb445985b99acbea4d706e6f0:/examples/portal/classes/PortalDropZone.js diff --git a/examples/portal/classes/PortalDropZone.js b/examples/portal/classes/PortalDropZone.js new file mode 100644 index 00000000..6f5e3ec7 --- /dev/null +++ b/examples/portal/classes/PortalDropZone.js @@ -0,0 +1,205 @@ +/* + +This file is part of Ext JS 4 + +Copyright (c) 2011 Sencha Inc + +Contact: http://www.sencha.com/contact + +GNU General Public License Usage +This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html. + +If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact. + +*/ +/** + * @class Ext.app.PortalDropZone + * @extends Ext.dd.DropTarget + * Internal class that manages drag/drop for {@link Ext.app.PortalPanel}. + */ +Ext.define('Ext.app.PortalDropZone', { + extend: 'Ext.dd.DropTarget', + + constructor: function(portal, cfg) { + this.portal = portal; + Ext.dd.ScrollManager.register(portal.body); + Ext.app.PortalDropZone.superclass.constructor.call(this, portal.body, cfg); + portal.body.ddScrollConfig = this.ddScrollConfig; + }, + + 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, + proxy = 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) { + // set initial client width + this.lastCW = cw; + } else if (this.lastCW != cw) { + // client width has changed, so refresh layout & grid calcs + this.lastCW = cw; + //portal.doLayout(); + this.grid = this.getGrid(); + } + + // determine column + var colIndex = 0, + colRight = 0, + cols = this.grid.columnX, + len = cols.length, + cmatch = false; + + for (len; colIndex < len; colIndex++) { + colRight = cols[colIndex].x + cols[colIndex].w; + if (xy[0] < colRight) { + cmatch = true; + break; + } + } + // no match, fix last index + if (!cmatch) { + colIndex--; + } + + // find insert position + var overPortlet, pos = 0, + h = 0, + match = false, + overColumn = portal.items.getAt(colIndex), + portlets = overColumn.items.items, + overSelf = false; + + len = portlets.length; + + for (len; pos < len; pos++) { + overPortlet = portlets[pos]; + h = overPortlet.el.getHeight(); + if (h === 0) { + overSelf = true; + } else if ((overPortlet.el.getY() + (h / 2)) > xy[1]) { + match = true; + break; + } + } + + pos = (match && overPortlet ? pos : overColumn.items.getCount()) + (overSelf ? -1 : 0); + var overEvent = this.createEvent(dd, e, data, colIndex, overColumn, pos); + + if (portal.fireEvent('validatedrop', overEvent) !== false && portal.fireEvent('beforedragover', overEvent) !== false) { + + // make sure proxy width is fluid in different width columns + proxy.getProxy().setWidth('auto'); + + if (overPortlet) { + proxy.moveProxy(overPortlet.el.dom.parentNode, match ? overPortlet.el.dom : null); + } else { + proxy.moveProxy(overColumn.el.dom, null); + } + + this.lastPos = { + c: overColumn, + col: colIndex, + p: overSelf || (match && overPortlet) ? 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, + panel = dd.panel, + 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) { + + // make sure panel is visible prior to inserting so that the layout doesn't ignore it + panel.el.dom.style.display = ''; + + if (pos !== false) { + c.insert(pos, panel); + } else { + c.add(panel); + } + + dd.proxy.hide(); + 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; + return true; + }, + + // internal cache of body and column coords + getGrid: function() { + var box = this.portal.body.getBox(); + box.columnX = []; + this.portal.items.each(function(c) { + box.columnX.push({ + x: c.el.getX(), + w: c.el.getWidth() + }); + }); + return box; + }, + + // unregister the dropzone from ScrollManager + unreg: function() { + Ext.dd.ScrollManager.unregister(this.portal.body); + Ext.app.PortalDropZone.superclass.unreg.call(this); + } +}); +