/** * @private */Ext.define('Ext.grid.HeaderDropZone', { extend: 'Ext.grid.GridDropZone', dropMarkerCls: Ext.baseCSSPrefix + 'header-drop-indicator', autoDestroy: false, isValidDrag: function(targetCmp, sourceCmp) { var info = this.info, regionChange = targetCmp.getLocked() !== sourceCmp.getLocked(), grid = sourceCmp.getGrid && sourceCmp.getGrid(), cursor, prevSibling, nextSibling, box, diff; // Avoid parent column to be dragged on child column or column container if (!!targetCmp.up(sourceCmp)) { return false; } cursor = info.cursor.current; prevSibling = sourceCmp.previousSibling(); nextSibling = sourceCmp.nextSibling(); // Only a valid drop for siblings if dragged more than // half way through a sibling if (grid && grid.isCssLockedGrid && sourceCmp.getAlwaysLocked() && regionChange) { return false; } if (targetCmp === prevSibling && !regionChange) { box = prevSibling.element.getBox(); diff = (cursor.x - box.left) / box.width; if (diff > 0.50) { return false; } } else if (targetCmp === nextSibling && !regionChange) { box = nextSibling.element.getBox(); diff = (cursor.x - box.left) / box.width; if (diff <= 0.50) { return false; } } return true; }, onDragMove: function(info) { var me = this, ddManager = Ext.dd.Manager, targetCmp = ddManager.getTargetComp(info), isDragTarget = targetCmp.isDragColumn, sourceCmp = ddManager.getSourceComp(info), notHeader = !targetCmp.isHeaderContainer || !sourceCmp.isHeaderContainer, highlight, positionCls; // Return on same column, not a column, on drag indicator column // or on header end if space is available if (notHeader || targetCmp === sourceCmp || isDragTarget || targetCmp.getParent() === me.view) { if (this.ddEl) { this.removeDropMarker(); } return; } highlight = ddManager.getPosition(info, targetCmp, 'x'); positionCls = me.dropMarkerCls + '-' + highlight; if (targetCmp.hasCls(positionCls)) { return; } if (this.ddEl) { this.removeDropMarker(); } if (me.isValidDrag(targetCmp, sourceCmp)) { me.ddEl = targetCmp; me.addDropMarker(targetCmp, [me.dropIndicator, positionCls]); } }, /** * Remove the parent header if all its child headers are removed * And is not grid header container */ trackHeaderMove: function(header, headerCt) { var parentCt; if (!header || header === headerCt || header.innerItems.length) { return; } parentCt = header.getParent(); headerCt.fireEvent('columngroupremove', parentCt, header); parentCt.remove(header); this.trackHeaderMove(parentCt, headerCt); }, onDrop: function(info) { var me = this, dropMethod = 'insertBefore', ddManager, targetCmp, headerCt, sourceCmp, dropAt, position, targetRegion, sourceRegion, relativeToItem, fromCtRoot, fromIdx, sourceCmpParent, grid, isLastUnlockedColumn, isCssLockedGrid, scroller; if (!me.ddEl) { return; } ddManager = Ext.dd.Manager; targetCmp = ddManager.getTargetComp(info); targetRegion = targetCmp.getRegion(); headerCt = targetCmp.getParent() || targetCmp.getRootHeaderCt(); sourceCmp = ddManager.getSourceComp(info); sourceRegion = sourceCmp.getRegion(); fromCtRoot = sourceCmp.getRootHeaderCt(); fromIdx = fromCtRoot.indexOf(sourceCmp); dropAt = headerCt.indexOf(targetCmp); position = ddManager.getPosition(info, targetCmp, 'x'); sourceCmpParent = sourceCmp.getParent(); grid = me.view; isCssLockedGrid = grid && grid.isCssLockedGrid; isLastUnlockedColumn = isCssLockedGrid && grid.getLockedColumns().length === grid.getVisibleColumns().length - 1; me.removeDropMarker(); if (dropAt === -1 || (isLastUnlockedColumn && sourceRegion === "center" && targetRegion !== sourceRegion)) { return; } if (position === 'after') { relativeToItem = headerCt.getAt(dropAt + 1); if (!relativeToItem) { dropMethod = 'insertAfter'; relativeToItem = targetCmp; } } else { relativeToItem = headerCt.getAt(dropAt); } headerCt[dropMethod](sourceCmp, (relativeToItem || null)); me.trackHeaderMove(sourceCmpParent, fromCtRoot); fromCtRoot.fireEvent('move', fromCtRoot, sourceCmp, dropAt, fromIdx); // Update dropped column 'locked' property to be same as dropped region if (isCssLockedGrid) { scroller = sourceCmp.getGrid().getScrollable(); // Work around for visual artifact where, when the center region is scrolled to the // far right, a drop anywhere in the grid will cause the column headers to be // misaligned. Unable to determine the reason for // this but this seems to resolve the visual artifact. scroller.scrollBy(-1); scroller.scrollBy(1); fromCtRoot.fireEvent('columnlockedchange', sourceCmp, targetRegion, sourceRegion); } }});