4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <title>The source code</title>
6 <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
7 <script type="text/javascript" src="../prettify/prettify.js"></script>
8 <style type="text/css">
9 .highlight { display: block; background-color: #ddd; }
11 <script type="text/javascript">
12 function highlight() {
13 document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
17 <body onload="prettyPrint(); highlight();">
18 <pre class="prettyprint lang-js"><span id='Ext-grid-plugin-HeaderResizer'>/**
19 </span> * @class Ext.grid.plugin.HeaderResizer
20 * @extends Ext.util.Observable
22 * Plugin to add header resizing functionality to a HeaderContainer.
23 * Always resizing header to the left of the splitter you are resizing.
25 * Todo: Consider RTL support, columns would always calculate to the right of
26 * the splitter instead of to the left.
28 Ext.define('Ext.grid.plugin.HeaderResizer', {
29 extend: 'Ext.util.Observable',
30 requires: ['Ext.dd.DragTracker', 'Ext.util.Region'],
31 alias: 'plugin.gridheaderresizer',
35 <span id='Ext-grid-plugin-HeaderResizer-cfg-dynamic'> /**
36 </span> * @cfg {Boolean} dynamic
37 * Set to true to resize on the fly rather than using a proxy marker. Defaults to false.
43 colHeaderCls: Ext.baseCSSPrefix + 'column-header',
47 wResizeCursor: 'col-resize',
48 eResizeCursor: 'col-resize',
49 // not using w and e resize bc we are only ever resizing one
51 //wResizeCursor: Ext.isWebKit ? 'w-resize' : 'col-resize',
52 //eResizeCursor: Ext.isWebKit ? 'e-resize' : 'col-resize',
54 init: function(headerCt) {
55 this.headerCt = headerCt;
56 headerCt.on('render', this.afterHeaderRender, this, {single: true});
59 <span id='Ext-grid-plugin-HeaderResizer-method-destroy'> /**
61 * AbstractComponent calls destroy on all its plugins at destroy time.
65 this.tracker.destroy();
69 afterHeaderRender: function() {
70 var headerCt = this.headerCt,
73 headerCt.mon(el, 'mousemove', this.onHeaderCtMouseMove, this);
75 this.tracker = Ext.create('Ext.dd.DragTracker', {
76 disabled: this.disabled,
77 onBeforeStart: Ext.Function.bind(this.onBeforeStart, this),
78 onStart: Ext.Function.bind(this.onStart, this),
79 onDrag: Ext.Function.bind(this.onDrag, this),
80 onEnd: Ext.Function.bind(this.onEnd, this),
87 // As we mouse over individual headers, change the cursor to indicate
88 // that resizing is available, and cache the resize target header for use
89 // if/when they mousedown.
90 onHeaderCtMouseMove: function(e, t) {
91 if (this.headerCt.dragging) {
93 this.activeHd.el.dom.style.cursor = '';
97 var headerEl = e.getTarget('.' + this.colHeaderCls, 3, true),
98 overHeader, resizeHeader;
101 overHeader = Ext.getCmp(headerEl.id);
103 // On left edge, we are resizing the previous non-hidden, base level column.
104 if (overHeader.isOnLeftEdge(e)) {
105 resizeHeader = overHeader.previousNode('gridcolumn:not([hidden]):not([isGroupHeader])');
107 // Else, if on the right edge, we're resizing the column we are over
108 else if (overHeader.isOnRightEdge(e)) {
109 resizeHeader = overHeader;
111 // Between the edges: we are not resizing
118 // If we're attempting to resize a group header, that cannot be resized,
119 // so find its last base level column header; Group headers are sized
120 // by the size of their child headers.
121 if (resizeHeader.isGroupHeader) {
122 resizeHeader = resizeHeader.getVisibleGridColumns();
123 resizeHeader = resizeHeader[resizeHeader.length - 1];
126 if (resizeHeader && !(resizeHeader.fixed || this.disabled)) {
127 this.activeHd = resizeHeader;
128 overHeader.el.dom.style.cursor = this.eResizeCursor;
132 overHeader.el.dom.style.cursor = '';
133 delete this.activeHd;
139 // only start when there is an activeHd
140 onBeforeStart : function(e){
141 var t = e.getTarget();
142 // cache the activeHd because it will be cleared.
143 this.dragHd = this.activeHd;
145 if (!!this.dragHd && !Ext.fly(t).hasCls('x-column-header-trigger') && !this.headerCt.dragging) {
146 //this.headerCt.dragging = true;
147 this.tracker.constrainTo = this.getConstrainRegion();
150 this.headerCt.dragging = false;
155 // get the region to constrain to, takes into account max and min col widths
156 getConstrainRegion: function() {
157 var dragHdEl = this.dragHd.el,
158 region = Ext.util.Region.getRegion(dragHdEl);
160 return region.adjust(
162 this.maxColWidth - dragHdEl.getWidth(),
168 // initialize the left and right hand side markers around
169 // the header that we are resizing
170 onStart: function(e){
173 dragHdEl = dragHd.el,
174 width = dragHdEl.getWidth(),
175 headerCt = me.headerCt,
178 if (me.dragHd && !Ext.fly(t).hasCls('x-column-header-trigger')) {
179 headerCt.dragging = true;
182 me.origWidth = width;
184 // setup marker proxies
186 var xy = dragHdEl.getXY(),
187 gridSection = headerCt.up('[scrollerOwner]'),
188 dragHct = me.dragHd.up(':not([isGroupHeader])'),
189 firstSection = dragHct.up(),
190 lhsMarker = gridSection.getLhsMarker(),
191 rhsMarker = gridSection.getRhsMarker(),
192 el = rhsMarker.parent(),
193 offsetLeft = el.getLeft(true),
194 offsetTop = el.getTop(true),
195 topLeft = el.translatePoints(xy),
196 markerHeight = firstSection.body.getHeight() + headerCt.getHeight(),
197 top = topLeft.top - offsetTop;
199 lhsMarker.setTop(top);
200 rhsMarker.setTop(top);
201 lhsMarker.setHeight(markerHeight);
202 rhsMarker.setHeight(markerHeight);
203 lhsMarker.setLeft(topLeft.left - offsetLeft);
204 rhsMarker.setLeft(topLeft.left + width - offsetLeft);
208 // synchronize the rhsMarker with the mouse movement
211 var xy = this.tracker.getXY('point'),
212 gridSection = this.headerCt.up('[scrollerOwner]'),
213 rhsMarker = gridSection.getRhsMarker(),
214 el = rhsMarker.parent(),
215 topLeft = el.translatePoints(xy),
216 offsetLeft = el.getLeft(true);
218 rhsMarker.setLeft(topLeft.left - offsetLeft);
219 // Resize as user interacts
226 this.headerCt.dragging = false;
229 var dragHd = this.dragHd,
230 gridSection = this.headerCt.up('[scrollerOwner]'),
231 lhsMarker = gridSection.getLhsMarker(),
232 rhsMarker = gridSection.getRhsMarker(),
233 currWidth = dragHd.getWidth(),
234 offset = this.tracker.getOffset('point'),
238 lhsMarker.setLeft(offscreen);
239 rhsMarker.setLeft(offscreen);
245 doResize: function() {
247 var dragHd = this.dragHd,
249 offset = this.tracker.getOffset('point');
256 // If HeaderContainer is configured forceFit, inhibit upstream layout notification, so that
257 // we can also shrink the following Header by an equal amount, and *then* inform the upstream layout.
258 if (this.headerCt.forceFit) {
259 nextHd = dragHd.nextNode('gridcolumn:not([hidden]):not([isGroupHeader])');
261 this.headerCt.componentLayout.layoutBusy = true;
265 // Non-flexed Headers may never be squeezed in the event of a shortfall so
266 // always set the minWidth to their current width.
267 dragHd.minWidth = this.origWidth + offset[0];
268 dragHd.setWidth(dragHd.minWidth);
270 // In the case of forceFit, change the following Header width.
271 // Then apply the two width changes by laying out the owning HeaderContainer
274 nextHd.setWidth(nextHd.getWidth() - offset[0]);
275 this.headerCt.componentLayout.layoutBusy = false;
276 this.headerCt.doComponentLayout();
281 disable: function() {
282 this.disabled = true;
284 this.tracker.disable();
289 this.disabled = false;
291 this.tracker.enable();