2 * @class Ext.grid.Scroller
3 * @extends Ext.Component
5 * Docked in an Ext.grid.Panel, controls virtualized scrolling and synchronization
6 * across different sections.
10 Ext.define('Ext.grid.Scroller', {
11 extend: 'Ext.Component',
12 alias: 'widget.gridscroller',
14 cls: Ext.baseCSSPrefix + 'scroller',
17 renderTpl: ['<div class="' + Ext.baseCSSPrefix + 'stretcher"></div>'],
19 initComponent: function() {
22 cls = Ext.baseCSSPrefix + 'scroller-vertical',
24 // Subtracting 2px would give us a perfect fit of the scroller
25 // however, some browsers wont allow us to scroll content thats not
26 // visible, therefore we use 1px.
27 // Note: This 1px offset matches code in Ext.grid.ColumnLayout when
28 // reserving room for the scrollbar
29 scrollbarWidth = Ext.getScrollBarWidth() + (Ext.isIE ? 1 : -1);
31 me.offsets = {bottom: 0};
33 if (dock === 'top' || dock === 'bottom') {
34 cls = Ext.baseCSSPrefix + 'scroller-horizontal';
37 me[sizeProp] = scrollbarWidth;
39 me.cls += (' ' + cls);
41 Ext.applyIf(me.renderSelectors, {
42 stretchEl: '.' + Ext.baseCSSPrefix + 'stretcher'
48 afterRender: function() {
51 me.ownerCt.on('afterlayout', me.onOwnerAfterLayout, me);
52 me.mon(me.el, 'scroll', me.onElScroll, me);
53 Ext.cache[me.el.id].skipGarbageCollection = true;
56 getSizeCalculation: function() {
57 var owner = this.getPanel(),
64 if (dock === 'top' || dock === 'bottom') {
65 // TODO: Must gravitate to a single region..
66 // Horizontal scrolling only scrolls virtualized region
67 var items = owner.query('tableview'),
68 center = items[1] || items[0];
73 // center is not guaranteed to have content, such as when there
74 // are zero rows in the grid/tree. We read the width from the
76 width = center.headerCt.getFullWidth();
81 // Account for the 1px removed in Scroller.
84 view = owner.down('tableview:not([lockableInjected])');
93 // needs to also account for header and scroller (if still in picture)
94 // should calculate from headerCt.
95 height = tbl.dom.scrollHeight;
109 invalidate: function(firstPass) {
110 if (!this.stretchEl || !this.ownerCt) {
113 var size = this.getSizeCalculation(),
116 this.stretchEl.setSize(size);
119 // This makes the scroller enabled, when initially rendering.
120 elDom.scrollTop = elDom.scrollTop;
124 onOwnerAfterLayout: function(owner, layout) {
129 * Sets the scrollTop and constrains the value between 0 and max.
130 * @param {Number} scrollTop
131 * @return {Number} The resulting scrollTop value after being constrained
133 setScrollTop: function(scrollTop) {
135 var elDom = this.el.dom;
136 return elDom.scrollTop = Ext.Number.constrain(scrollTop, 0, elDom.scrollHeight - elDom.clientHeight);
141 * Sets the scrollLeft and constrains the value between 0 and max.
142 * @param {Number} scrollLeft
143 * @return {Number} The resulting scrollLeft value after being constrained
145 setScrollLeft: function(scrollLeft) {
147 var elDom = this.el.dom;
148 return elDom.scrollLeft = Ext.Number.constrain(scrollLeft, 0, elDom.scrollWidth - elDom.clientWidth);
154 * @param {Number} delta
155 * @return {Number} The resulting scrollTop value
157 scrollByDeltaY: function(delta) {
159 var elDom = this.el.dom;
160 return this.setScrollTop(elDom.scrollTop + delta);
166 * @param {Number} delta
167 * @return {Number} The resulting scrollLeft value
169 scrollByDeltaX: function(delta) {
171 var elDom = this.el.dom;
172 return this.setScrollLeft(elDom.scrollLeft + delta);
180 scrollToTop : function(){
181 this.setScrollTop(0);
184 // synchronize the scroller with the bound gridviews
185 onElScroll: function(event, target) {
186 this.fireEvent('bodyscroll', event, target);
189 getPanel: function() {
192 me.panel = this.up('[scrollerOwner]');