/** * @class Ext.grid.Scroller * @extends Ext.Component * * Docked in GridPanels, controls virtualized scrolling across GridSections. */ Ext.define('Ext.grid.Scroller', { extend: 'Ext.Component', alias: 'widget.gridscroller', cls: Ext.baseCSSPrefix + 'scroller',
/** * @cfg {Number} scrollDelta * Number of pixels to scroll when scrolling with mousewheel. * Defaults to 40. */ scrollDelta: 40, renderTpl: ['
'], initComponent: function() { var dock = this.dock, cls = Ext.baseCSSPrefix + 'scroller-vertical', sizeProp = 'width', // TODO: Determine why +2 in getScrollBarWidth // BrowserBug: IE8 dictates that there must be at least 1px of viewable // area before it will allow you to scroll when clicking on the open // area. This adds a 1px visual artificat in IE8. scrollbarWidth = Ext.getScrollBarWidth() - (Ext.isIE ? 1 : 2); this.offsets = {bottom: 0}; if (dock === 'top' || dock === 'bottom') { cls = Ext.baseCSSPrefix + 'scroller-horizontal'; sizeProp = 'height'; } else { this.offsets.bottom = scrollbarWidth; } this[sizeProp] = scrollbarWidth; this.cls += (' ' + cls); Ext.applyIf(this.renderSelectors, { stretchEl: '.' + Ext.baseCSSPrefix + 'stretcher' }); Ext.grid.Scroller.superclass.initComponent.call(this); }, afterRender: function() { Ext.grid.Scroller.superclass.afterRender.call(this); var dockOwner = this.ownerCt, dock = this.dock; dockOwner.on('afterlayout', this.onOwnerAfterLayout, this); this.el.on('scroll', this.onElScroll, this); }, invalidate: function() { if (!this.el) { return; } var owner = this.ownerCt, dock = this.dock, elDom = this.el.dom, width = 1, height = 1; if (dock === 'top' || dock === 'bottom') { // TODO: Must gravitate to a single region.. // Horizontal scrolling only scrolls virtualized region var items = owner.query('gridview'), center = items[1] || items[0]; if (!center) { return; } var centerEl = center.el.dom, centerScrollWidth = centerEl.scrollWidth, // clientWidth often returns 0 in IE resulting in an // infinity result, here we use offsetWidth bc there are // no possible scrollbars and we dont care about margins centerClientWidth = centerEl.offsetWidth, scrollerWidth = this.getWidth(), threshold = Ext.getScrollBarWidth() - 2; width = Math.round(centerScrollWidth * scrollerWidth / centerClientWidth); // because the scroller is completely virtualized, it is easy to get into a couple // pixel rounding error. This makes no overflow occur if the user is +/- the threshold if (scrollerWidth > (width - threshold) /*&& scrollerWidth < (width + threshold)*/) { width = scrollerWidth; } } else { var tbl = owner.el.down('.' + Ext.baseCSSPrefix + 'grid-view'); if (!tbl) { return; } // needs to also account for header and scroller (if still in picture) // should calculate from headerCt. height = tbl.dom.scrollHeight; } if (isNaN(width)) { width = 1; } if (isNaN(height)) { height = 1; } this.stretchEl.setSize(width, height); // BrowserBug: IE7 // This makes the scroller enabled, when initially rendering. elDom.scrollTop = elDom.scrollTop; }, onOwnerAfterLayout: function(owner, layout) { if (Ext.isIE) { Ext.Function.defer(this.invalidate, 1, this); } else { this.invalidate(); } },
/** * Sets the scrollTop and constrains the value between 0 and max. * @param {Number} scrollTop */ setScrollTop: function(scrollTop) { var elDom = this.el.dom; elDom.scrollTop = Ext.Number.constrain(scrollTop, 0, elDom.scrollHeight - elDom.clientHeight); },
/** * Sets the scrollLeft and constrains the value between 0 and max. * @param {Number} scrollTop */ setScrollLeft: function(scrollLeft) { var elDom = this.el.dom; elDom.scrollLeft = Ext.Number.constrain(scrollLeft, 0, elDom.scrollWidth - elDom.clientWidth); },
/** * Scroll by delta * @param {Number} delta */ scrollByDeltaY: function(delta) { var elDom = this.el.dom; this.setScrollTop(elDom.scrollTop + delta); }, scrollByDeltaX: function(delta) { var elDom = this.el.dom; this.setScrollLeft(elDom.scrollLeft + delta); }, scrollToTop : function(){ this.setScrollTop(0); }, // synchronize the scroller with the bound gridviews onElScroll: function(e, t) { var dock = this.dock, owner = this.ownerCt, items = owner.query('gridview'); if (dock === 'top' || dock === 'bottom') { var center = items[1] || items[0], centerEl = center.el.dom, centerScrollWidth = centerEl.scrollWidth, centerClientWidth = centerEl.offsetWidth, width = this.getWidth(); centerEl.scrollLeft = Math.ceil(t.scrollLeft/width * centerClientWidth); } else { for (var i = 0, ln = items.length; i < ln; i++) { items[i].el.dom.scrollTop = t.scrollTop; } } } });