3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
16 * Docked in an Ext.grid.Panel, controls virtualized scrolling and synchronization
17 * across different sections.
19 Ext.define('Ext.grid.Scroller', {
20 extend: 'Ext.Component',
21 alias: 'widget.gridscroller',
23 baseCls: Ext.baseCSSPrefix + 'scroller',
28 '<div class="' + Ext.baseCSSPrefix + 'scroller-ct" id="{baseId}_ct">',
29 '<div class="' + Ext.baseCSSPrefix + 'stretcher" id="{baseId}_stretch"></div>',
33 initComponent: function() {
36 cls = Ext.baseCSSPrefix + 'scroller-vertical';
38 me.offsets = {bottom: 0};
39 me.scrollProp = 'scrollTop';
41 me.sizeProp = 'width';
43 if (dock === 'top' || dock === 'bottom') {
44 cls = Ext.baseCSSPrefix + 'scroller-horizontal';
45 me.sizeProp = 'height';
46 me.scrollProp = 'scrollLeft';
51 me.cls += (' ' + cls);
53 Ext.applyIf(me.renderSelectors, {
54 stretchEl: '.' + Ext.baseCSSPrefix + 'stretcher',
55 scrollEl: '.' + Ext.baseCSSPrefix + 'scroller-ct'
60 ensureDimension: function(){
62 sizeProp = me.sizeProp;
64 me[sizeProp] = me.scrollerSize = Ext.getScrollbarSize()[sizeProp];
67 initRenderData: function () {
69 ret = me.callParent(arguments) || {};
76 afterRender: function() {
80 me.mon(me.scrollEl, 'scroll', me.onElScroll, me);
81 Ext.cache[me.el.id].skipGarbageCollection = true;
84 onAdded: function(container) {
85 // Capture the controlling grid Panel so that we can use it even when we are undocked, and don't have an ownerCt
86 this.ownerGrid = container;
87 this.callParent(arguments);
90 getSizeCalculation: function() {
92 owner = me.getPanel(),
98 // TODO: Must gravitate to a single region..
99 // Horizontal scrolling only scrolls virtualized region
100 var items = owner.query('tableview'),
101 center = items[1] || items[0];
106 // center is not guaranteed to have content, such as when there
107 // are zero rows in the grid/tree. We read the width from the
109 width = center.headerCt.getFullWidth();
111 if (Ext.isIEQuirks) {
115 view = owner.down('tableview:not([lockableInjected])');
116 if (!view || !view.el) {
119 tbl = view.el.child('table', true);
124 // needs to also account for header and scroller (if still in picture)
125 // should calculate from headerCt.
126 height = tbl.offsetHeight;
140 invalidate: function(firstPass) {
142 stretchEl = me.stretchEl;
144 if (!stretchEl || !me.ownerCt) {
148 var size = me.getSizeCalculation(),
149 scrollEl = me.scrollEl,
150 elDom = scrollEl.dom,
151 reservedSpace = me.reservedSpace,
156 stretchEl.setSize(size);
158 size = me.el.getSize(true);
162 size.height -= reservedSpace;
165 size.width -= reservedSpace;
166 size.height += extra;
170 scrollEl.setSize(size);
171 elDom.style[pos] = (-extra) + 'px';
174 // This makes the scroller enabled, when initially rendering.
175 elDom.scrollTop = elDom.scrollTop;
179 afterComponentLayout: function() {
180 this.callParent(arguments);
184 restoreScrollPos: function () {
187 elDom = el && el.dom;
189 if (me._scrollPos !== null && elDom) {
190 elDom[me.scrollProp] = me._scrollPos;
191 me._scrollPos = null;
195 setReservedSpace: function (reservedSpace) {
197 if (me.reservedSpace !== reservedSpace) {
198 me.reservedSpace = reservedSpace;
203 saveScrollPos: function () {
206 elDom = el && el.dom;
208 me._scrollPos = elDom ? elDom[me.scrollProp] : null;
212 * Sets the scrollTop and constrains the value between 0 and max.
213 * @param {Number} scrollTop
214 * @return {Number} The resulting scrollTop value after being constrained
216 setScrollTop: function(scrollTop) {
217 var el = this.scrollEl,
218 elDom = el && el.dom;
221 return elDom.scrollTop = Ext.Number.constrain(scrollTop, 0, elDom.scrollHeight - elDom.clientHeight);
226 * Sets the scrollLeft and constrains the value between 0 and max.
227 * @param {Number} scrollLeft
228 * @return {Number} The resulting scrollLeft value after being constrained
230 setScrollLeft: function(scrollLeft) {
231 var el = this.scrollEl,
232 elDom = el && el.dom;
235 return elDom.scrollLeft = Ext.Number.constrain(scrollLeft, 0, elDom.scrollWidth - elDom.clientWidth);
241 * @param {Number} delta
242 * @return {Number} The resulting scrollTop value
244 scrollByDeltaY: function(delta) {
245 var el = this.scrollEl,
246 elDom = el && el.dom;
249 return this.setScrollTop(elDom.scrollTop + delta);
255 * @param {Number} delta
256 * @return {Number} The resulting scrollLeft value
258 scrollByDeltaX: function(delta) {
259 var el = this.scrollEl,
260 elDom = el && el.dom;
263 return this.setScrollLeft(elDom.scrollLeft + delta);
271 scrollToTop : function(){
272 this.setScrollTop(0);
275 // synchronize the scroller with the bound gridviews
276 onElScroll: function(event, target) {
277 this.fireEvent('bodyscroll', event, target);
280 getPanel: function() {
283 me.panel = this.up('[scrollerOwner]');