/** * @class Ext.grid.HeaderResizer * @extends Ext.util.Observable * * Plugin to add header resizing functionality to a HeaderContainer. * Always resizing header to the left of the splitter you are resizing. * * Todo: Consider RTL support, columns would always calculate to the right of * the splitter instead of to the left. */ Ext.define('Ext.grid.HeaderResizer', { extend: 'Ext.util.Observable', requires: ['Ext.dd.DragTracker', 'Ext.util.Region'], alias: 'plugin.gridheaderresizer',
/** * @cfg {Boolean} dynamic * Set to true to resize on the fly rather than using a proxy marker. Defaults to false. */ configs: { dynamic: true }, colHeaderCls: Ext.baseCSSPrefix + 'column-header', handleWidth: 10, minColWidth: 40, maxColWidth: 1000, wResizeCursor: 'col-resize', eResizeCursor: 'col-resize', // not using w and e resize bc we are only ever resizing one // column //wResizeCursor: Ext.isWebKit ? 'w-resize' : 'col-resize', //eResizeCursor: Ext.isWebKit ? 'e-resize' : 'col-resize', init: function(headerCt) { this.headerCt = headerCt; headerCt.on('render', this.afterHeaderRender, this); }, afterHeaderRender: function() { var headerCt = this.headerCt, el = headerCt.el; headerCt.mon(el, 'mousemove', this.onHeaderCtMouseMove, this); this.tracker = new Ext.dd.DragTracker({ onBeforeStart: Ext.Function.bind(this.onBeforeStart, this), onStart: Ext.Function.bind(this.onStart, this), onDrag: Ext.Function.bind(this.onDrag, this), onEnd: Ext.Function.bind(this.onEnd, this), tolerance: 3, autoStart: 300, el: el }); }, // As we mouse over individual headers, change the cursor to indicate // that resizing is available. onHeaderCtMouseMove: function(e, t) { if (!this.headerCt.dragging) { var handleWidth = this.handleWidth, headerEl = e.getTarget('.'+this.colHeaderCls, 3, true), x = e.getPageX(), header, headerIdx, region, style, parentNode; if (headerEl){ header = Ext.getCmp(headerEl.id); headerIdx = this.headerCt.items.indexOf(header); region = headerEl.getRegion(); style = headerEl.dom.style; // left hand edge of the header // want to resize the previous column that is NOT hidden if (x - region.left <= handleWidth && headerIdx !== 0) { // TODO: need to also check that the header is NOT hidden. this.activeHd = Ext.getCmp(headerEl.id).previousSibling('gridheader:not(gridheader[hidden])'); if (this.activeHd && !this.activeHd.fixed) { style.cursor = this.eResizeCursor; } // right hand edge of the header // want to resize this column } else if (region.right - x <= handleWidth) { this.activeHd = Ext.getCmp(headerEl.id); if (!this.activeHd.fixed) { style.cursor = this.wResizeCursor; } // reset } else { delete this.activeHd; style.cursor = ''; } if (this.activeHd && this.activeHd.fixed) { delete this.activeHd; } } } else { delete this.activeHd; } }, // only start when there is an activeHd onBeforeStart : function(e){ var t = e.getTarget(); // cache the activeHd because it will be cleared. this.dragHd = this.activeHd; if (this.dragHd && !Ext.fly(t).hasCls('x-column-header-trigger')) { this.headerCt.dragging = true; this.tracker.constrainTo = this.getConstrainRegion(); return true; } else { this.headerCt.dragging = false; return false; } }, // get the region to constrain to, takes into account max and min col widths getConstrainRegion: function() { var dragHdEl = this.dragHd.el, region = Ext.util.Region.getRegion(dragHdEl); return region.adjust( 0, this.maxColWidth - dragHdEl.getWidth(), 0, this.minColWidth ); }, // initialize the left and right hand side markers around // the header that we are resizing onStart: function(e){ var dragHd = this.dragHd, dragHdEl = dragHd.el, width = dragHdEl.getWidth(); this.origWidth = width; // setup marker proxies if (!this.dynamic) { var xy = dragHdEl.getXY(), gridSection = this.headerCt.up('gridsection'), lhsMarker = gridSection.getLhsMarker(), rhsMarker = gridSection.getRhsMarker(), el = rhsMarker.parent(), topLeft = el.translatePoints(xy), markerHeight = gridSection.getHeight(); if (gridSection.horizontalScroller.ownerCt === gridSection) { markerHeight -= (Ext.getScrollBarWidth() - 2); } lhsMarker.setHeight(markerHeight); rhsMarker.setHeight(markerHeight); lhsMarker.setLeft(topLeft.left); rhsMarker.setLeft(topLeft.left + width); } }, // synchronize the rhsMarker with the mouse movement onDrag: function(e){ if (!this.dynamic) { var xy = this.tracker.getXY('point'), gridSection = this.headerCt.up('gridsection'), rhsMarker = gridSection.getRhsMarker(), el = rhsMarker.parent(), topLeft = el.translatePoints(xy); rhsMarker.setLeft(topLeft.left); // Resize as user interacts } else { this.doResize(); } }, onEnd: function(e){ this.headerCt.dragging = false; if (this.dragHd) { if (!this.dynamic) { var dragHd = this.dragHd, gridSection = this.headerCt.up('gridsection'), lhsMarker = gridSection.getLhsMarker(), rhsMarker = gridSection.getRhsMarker(), currWidth = dragHd.getWidth(), offset = this.tracker.getOffset('point'), offscreen = -9999; // hide markers lhsMarker.setLeft(offscreen); rhsMarker.setLeft(offscreen); } this.doResize(); } }, doResize: function() { if (this.dragHd) { var dragHd = this.dragHd, offset = this.tracker.getOffset('point'); // resize the dragHd if (dragHd.flex) { delete dragHd.flex; } dragHd.setWidth(this.origWidth + offset[0]); } } });