<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>The source code</title>
- <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
- <script type="text/javascript" src="../prettify/prettify.js"></script>
+ <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
+ <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
<style type="text/css">
.highlight { display: block; background-color: #ddd; }
</style>
</head>
<body onload="prettyPrint(); highlight();">
<pre class="prettyprint lang-js"><span id='Ext-grid-Scroller'>/**
-</span> * @class Ext.grid.Scroller
- * @extends Ext.Component
- *
- * Docked in an Ext.grid.Panel, controls virtualized scrolling and synchronization
+</span> * Docked in an Ext.grid.Panel, controls virtualized scrolling and synchronization
* across different sections.
- *
- * @private
*/
Ext.define('Ext.grid.Scroller', {
extend: 'Ext.Component',
alias: 'widget.gridscroller',
weight: 110,
- cls: Ext.baseCSSPrefix + 'scroller',
+ baseCls: Ext.baseCSSPrefix + 'scroller',
focusable: false,
-
- renderTpl: ['<div class="' + Ext.baseCSSPrefix + 'stretcher"></div>'],
-
+ reservedSpace: 0,
+
+ renderTpl: [
+ '<div class="' + Ext.baseCSSPrefix + 'scroller-ct" id="{baseId}_ct">',
+ '<div class="' + Ext.baseCSSPrefix + 'stretcher" id="{baseId}_stretch"></div>',
+ '</div>'
+ ],
+
initComponent: function() {
var me = this,
dock = me.dock,
- cls = Ext.baseCSSPrefix + 'scroller-vertical',
- sizeProp = 'width',
- // Subtracting 2px would give us a perfect fit of the scroller
- // however, some browsers wont allow us to scroll content thats not
- // visible, therefore we use 1px.
- // Note: This 1px offset matches code in Ext.grid.ColumnLayout when
- // reserving room for the scrollbar
- scrollbarWidth = Ext.getScrollBarWidth() + (Ext.isIE ? 1 : -1);
+ cls = Ext.baseCSSPrefix + 'scroller-vertical';
me.offsets = {bottom: 0};
+ me.scrollProp = 'scrollTop';
+ me.vertical = true;
+ me.sizeProp = 'width';
if (dock === 'top' || dock === 'bottom') {
cls = Ext.baseCSSPrefix + 'scroller-horizontal';
- sizeProp = 'height';
+ me.sizeProp = 'height';
+ me.scrollProp = 'scrollLeft';
+ me.vertical = false;
+ me.weight += 5;
}
- me[sizeProp] = scrollbarWidth;
-
+
me.cls += (' ' + cls);
-
+
Ext.applyIf(me.renderSelectors, {
- stretchEl: '.' + Ext.baseCSSPrefix + 'stretcher'
+ stretchEl: '.' + Ext.baseCSSPrefix + 'stretcher',
+ scrollEl: '.' + Ext.baseCSSPrefix + 'scroller-ct'
});
me.callParent();
},
-
+ ensureDimension: function(){
+ var me = this,
+ sizeProp = me.sizeProp;
+
+ me[sizeProp] = me.scrollerSize = Ext.getScrollbarSize()[sizeProp];
+ },
+
+ initRenderData: function () {
+ var me = this,
+ ret = me.callParent(arguments) || {};
+
+ ret.baseId = me.id;
+
+ return ret;
+ },
+
afterRender: function() {
var me = this;
me.callParent();
- me.ownerCt.on('afterlayout', me.onOwnerAfterLayout, me);
- me.mon(me.el, 'scroll', me.onElScroll, me);
+
+ me.mon(me.scrollEl, 'scroll', me.onElScroll, me);
Ext.cache[me.el.id].skipGarbageCollection = true;
},
-
+
+ onAdded: function(container) {
+ // Capture the controlling grid Panel so that we can use it even when we are undocked, and don't have an ownerCt
+ this.ownerGrid = container;
+ this.callParent(arguments);
+ },
+
getSizeCalculation: function() {
- var owner = this.getPanel(),
- dock = this.dock,
- elDom = this.el.dom,
+ var me = this,
+ owner = me.getPanel(),
width = 1,
height = 1,
view, tbl;
-
- if (dock === 'top' || dock === 'bottom') {
+
+ if (!me.vertical) {
// TODO: Must gravitate to a single region..
// Horizontal scrolling only scrolls virtualized region
var items = owner.query('tableview'),
center = items[1] || items[0];
-
+
if (!center) {
return false;
}
// are zero rows in the grid/tree. We read the width from the
// headerCt instead.
width = center.headerCt.getFullWidth();
-
+
if (Ext.isIEQuirks) {
width--;
}
- // Account for the 1px removed in Scroller.
- width--;
- } else {
+ } else {
view = owner.down('tableview:not([lockableInjected])');
- if (!view) {
+ if (!view || !view.el) {
return false;
}
- tbl = view.el;
+ tbl = view.el.child('table', true);
if (!tbl) {
return false;
}
-
+
// needs to also account for header and scroller (if still in picture)
// should calculate from headerCt.
- height = tbl.dom.scrollHeight;
+ height = tbl.offsetHeight;
}
if (isNaN(width)) {
width = 1;
height: height
};
},
-
+
invalidate: function(firstPass) {
- if (!this.stretchEl || !this.ownerCt) {
+ var me = this,
+ stretchEl = me.stretchEl;
+
+ if (!stretchEl || !me.ownerCt) {
return;
}
- var size = this.getSizeCalculation(),
- elDom = this.el.dom;
+
+ var size = me.getSizeCalculation(),
+ scrollEl = me.scrollEl,
+ elDom = scrollEl.dom,
+ reservedSpace = me.reservedSpace,
+ pos,
+ extra = 5;
+
if (size) {
- this.stretchEl.setSize(size);
-
+ stretchEl.setSize(size);
+
+ size = me.el.getSize(true);
+
+ if (me.vertical) {
+ size.width += extra;
+ size.height -= reservedSpace;
+ pos = 'left';
+ } else {
+ size.width -= reservedSpace;
+ size.height += extra;
+ pos = 'top';
+ }
+
+ scrollEl.setSize(size);
+ elDom.style[pos] = (-extra) + 'px';
+
// BrowserBug: IE7
// This makes the scroller enabled, when initially rendering.
elDom.scrollTop = elDom.scrollTop;
}
},
- onOwnerAfterLayout: function(owner, layout) {
+ afterComponentLayout: function() {
+ this.callParent(arguments);
this.invalidate();
},
+ restoreScrollPos: function () {
+ var me = this,
+ el = this.scrollEl,
+ elDom = el && el.dom;
+
+ if (me._scrollPos !== null && elDom) {
+ elDom[me.scrollProp] = me._scrollPos;
+ me._scrollPos = null;
+ }
+ },
+
+ setReservedSpace: function (reservedSpace) {
+ var me = this;
+ if (me.reservedSpace !== reservedSpace) {
+ me.reservedSpace = reservedSpace;
+ me.invalidate();
+ }
+ },
+
+ saveScrollPos: function () {
+ var me = this,
+ el = this.scrollEl,
+ elDom = el && el.dom;
+
+ me._scrollPos = elDom ? elDom[me.scrollProp] : null;
+ },
+
<span id='Ext-grid-Scroller-method-setScrollTop'> /**
</span> * Sets the scrollTop and constrains the value between 0 and max.
* @param {Number} scrollTop
* @return {Number} The resulting scrollTop value after being constrained
*/
setScrollTop: function(scrollTop) {
- if (this.el) {
- var elDom = this.el.dom;
+ var el = this.scrollEl,
+ elDom = el && el.dom;
+
+ if (elDom) {
return elDom.scrollTop = Ext.Number.constrain(scrollTop, 0, elDom.scrollHeight - elDom.clientHeight);
}
},
* @return {Number} The resulting scrollLeft value after being constrained
*/
setScrollLeft: function(scrollLeft) {
- if (this.el) {
- var elDom = this.el.dom;
+ var el = this.scrollEl,
+ elDom = el && el.dom;
+
+ if (elDom) {
return elDom.scrollLeft = Ext.Number.constrain(scrollLeft, 0, elDom.scrollWidth - elDom.clientWidth);
}
},
* @return {Number} The resulting scrollTop value
*/
scrollByDeltaY: function(delta) {
- if (this.el) {
- var elDom = this.el.dom;
+ var el = this.scrollEl,
+ elDom = el && el.dom;
+
+ if (elDom) {
return this.setScrollTop(elDom.scrollTop + delta);
}
},
* @return {Number} The resulting scrollLeft value
*/
scrollByDeltaX: function(delta) {
- if (this.el) {
- var elDom = this.el.dom;
+ var el = this.scrollEl,
+ elDom = el && el.dom;
+
+ if (elDom) {
return this.setScrollLeft(elDom.scrollLeft + delta);
}
},
-
-
+
+
<span id='Ext-grid-Scroller-method-scrollToTop'> /**
</span> * Scroll to the top.
*/
scrollToTop : function(){
this.setScrollTop(0);
},
-
+
// synchronize the scroller with the bound gridviews
onElScroll: function(event, target) {
this.fireEvent('bodyscroll', event, target);