X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/0494b8d9b9bb03ab6c22b34dae81261e3cd7e3e6..7a654f8d43fdb43d78b63d90528bed6e86b608cc:/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..c0a1da4c --- /dev/null +++ b/examples/portal/classes/PortalDropZone.js @@ -0,0 +1,190 @@ +/** + * @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); + } +});