--- /dev/null
+<!DOCTYPE html><html><head><title>Sencha Documentation Project</title><link rel="stylesheet" href="../reset.css" type="text/css"><link rel="stylesheet" href="../prettify.css" type="text/css"><link rel="stylesheet" href="../prettify_sa.css" type="text/css"><script type="text/javascript" src="../prettify.js"></script></head><body onload="prettyPrint()"><pre class="prettyprint"><pre><span id='Ext-grid.plugin.HeaderResizer'>/**
+</span> * @class Ext.grid.plugin.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.plugin.HeaderResizer', {
+ extend: 'Ext.util.Observable',
+ requires: ['Ext.dd.DragTracker', 'Ext.util.Region'],
+ alias: 'plugin.gridheaderresizer',
+
+ disabled: false,
+
+<span id='Ext-grid.plugin.HeaderResizer-cfg-dynamic'> /**
+</span> * @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',
+
+ 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, {single: true});
+ },
+
+<span id='Ext-grid.plugin.HeaderResizer-method-destroy'> /**
+</span> * @private
+ * AbstractComponent calls destroy on all its plugins at destroy time.
+ */
+ destroy: function() {
+ if (this.tracker) {
+ this.tracker.destroy();
+ }
+ },
+
+ afterHeaderRender: function() {
+ var headerCt = this.headerCt,
+ el = headerCt.el;
+
+ headerCt.mon(el, 'mousemove', this.onHeaderCtMouseMove, this);
+
+ this.tracker = Ext.create('Ext.dd.DragTracker', {
+ disabled: this.disabled,
+ 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, and cache the resize target header for use
+ // if/when they mousedown.
+ onHeaderCtMouseMove: function(e, t) {
+ if (this.headerCt.dragging) {
+ if (this.activeHd) {
+ this.activeHd.el.dom.style.cursor = '';
+ delete this.activeHd;
+ }
+ } else {
+ var headerEl = e.getTarget('.' + this.colHeaderCls, 3, true),
+ overHeader, resizeHeader;
+
+ if (headerEl){
+ overHeader = Ext.getCmp(headerEl.id);
+
+ // On left edge, we are resizing the previous non-hidden, base level column.
+ if (overHeader.isOnLeftEdge(e)) {
+ resizeHeader = overHeader.previousNode('gridcolumn:not([hidden]):not([isGroupHeader])');
+ }
+ // Else, if on the right edge, we're resizing the column we are over
+ else if (overHeader.isOnRightEdge(e)) {
+ resizeHeader = overHeader;
+ }
+ // Between the edges: we are not resizing
+ else {
+ resizeHeader = null;
+ }
+
+ // We *are* resizing
+ if (resizeHeader) {
+ // If we're attempting to resize a group header, that cannot be resized,
+ // so find its last base level column header; Group headers are sized
+ // by the size of their child headers.
+ if (resizeHeader.isGroupHeader) {
+ resizeHeader = resizeHeader.getVisibleGridColumns();
+ resizeHeader = resizeHeader[resizeHeader.length - 1];
+ }
+
+ if (resizeHeader && !resizeHeader.fixed) {
+ this.activeHd = resizeHeader;
+ overHeader.el.dom.style.cursor = this.eResizeCursor;
+ }
+ // reset
+ } else {
+ overHeader.el.dom.style.cursor = '';
+ 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) {
+ //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 me = this,
+ dragHd = me.dragHd,
+ dragHdEl = dragHd.el,
+ width = dragHdEl.getWidth(),
+ headerCt = me.headerCt,
+ t = e.getTarget();
+
+ if (me.dragHd && !Ext.fly(t).hasCls('x-column-header-trigger')) {
+ headerCt.dragging = true;
+ }
+
+ me.origWidth = width;
+
+ // setup marker proxies
+ if (!me.dynamic) {
+ var xy = dragHdEl.getXY(),
+ gridSection = headerCt.up('[scrollerOwner]'),
+ dragHct = me.dragHd.up(':not([isGroupHeader])'),
+ firstSection = dragHct.up(),
+ lhsMarker = gridSection.getLhsMarker(),
+ rhsMarker = gridSection.getRhsMarker(),
+ el = rhsMarker.parent(),
+ offsetLeft = el.getLeft(true),
+ offsetTop = el.getTop(true),
+ topLeft = el.translatePoints(xy),
+ markerHeight = firstSection.body.getHeight() + headerCt.getHeight(),
+ top = topLeft.top - offsetTop;
+
+ lhsMarker.setTop(top);
+ rhsMarker.setTop(top);
+ lhsMarker.setHeight(markerHeight);
+ rhsMarker.setHeight(markerHeight);
+ lhsMarker.setLeft(topLeft.left - offsetLeft);
+ rhsMarker.setLeft(topLeft.left + width - offsetLeft);
+ }
+ },
+
+ // synchronize the rhsMarker with the mouse movement
+ onDrag: function(e){
+ if (!this.dynamic) {
+ var xy = this.tracker.getXY('point'),
+ gridSection = this.headerCt.up('[scrollerOwner]'),
+ rhsMarker = gridSection.getRhsMarker(),
+ el = rhsMarker.parent(),
+ topLeft = el.translatePoints(xy),
+ offsetLeft = el.getLeft(true);
+
+ rhsMarker.setLeft(topLeft.left - offsetLeft);
+ // 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('[scrollerOwner]'),
+ 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,
+ nextHd,
+ offset = this.tracker.getOffset('point');
+
+ // resize the dragHd
+ if (dragHd.flex) {
+ delete dragHd.flex;
+ }
+
+ // If HeaderContainer is configured forceFit, inhibit upstream layout notification, so that
+ // we can also shrink the following Header by an equal amount, and *then* inform the upstream layout.
+ if (this.headerCt.forceFit) {
+ nextHd = dragHd.nextNode('gridcolumn:not([hidden]):not([isGroupHeader])');
+ if (nextHd) {
+ this.headerCt.componentLayout.layoutBusy = true;
+ }
+ }
+
+ // Non-flexed Headers may never be squeezed in the event of a shortfall so
+ // always set the minWidth to their current width.
+ dragHd.minWidth = this.origWidth + offset[0];
+ dragHd.setWidth(dragHd.minWidth);
+
+ // In the case of forceFit, change the following Header width.
+ // Then apply the two width changes by laying out the owning HeaderContainer
+ if (nextHd) {
+ delete nextHd.flex;
+ nextHd.setWidth(nextHd.getWidth() - offset[0]);
+ this.headerCt.componentLayout.layoutBusy = false;
+ this.headerCt.doComponentLayout();
+ }
+ }
+ },
+
+ disable: function() {
+ this.disabled = true;
+ if (this.tracker) {
+ this.tracker.disable();
+ }
+ },
+
+ enable: function() {
+ this.disabled = false;
+ if (this.tracker) {
+ this.tracker.enable();
+ }
+ }
+});</pre></pre></body></html>
\ No newline at end of file