/** * This is a simple container that is used to compile content and a {@link Ext.scroll.View} instance. It also * provides scroll indicators. * * 99% of the time all you need to use in this class is {@link #getScroller}. * * This should never be extended. */ Ext.define('Ext.scroll.View', { extend: 'Ext.Evented', alternateClassName: 'Ext.util.ScrollView', requires: [ 'Ext.scroll.Scroller', 'Ext.scroll.Indicator' ], config: { /** * @cfg {String} indicatorsUi * The style of the indicators of this view. Available options are `dark` or `light`. */ indicatorsUi: 'dark', element: null, scroller: {}, indicators: { x: { axis: 'x' }, y: { axis: 'y' } }, indicatorsHidingDelay: 100, cls: Ext.baseCSSPrefix + 'scroll-view' }, /** * @method getScroller * Returns the scroller instance in this view. Checkout the documentation of {@link Ext.scroll.Scroller} and * {@link Ext.Container#getScrollable} for more information. * @return {Ext.scroll.View} The scroller */ /** * @private */ processConfig: function(config) { if (!config) { return null; } if (typeof config == 'string') { config = { direction: config }; } config = Ext.merge({}, config); var scrollerConfig = config.scroller, name; if (!scrollerConfig) { config.scroller = scrollerConfig = {}; } for (name in config) { if (config.hasOwnProperty(name)) { if (!this.hasConfig(name)) { scrollerConfig[name] = config[name]; delete config[name]; } } } return config; }, constructor: function(config) { config = this.processConfig(config); this.useIndicators = { x: true, y: true }; this.doHideIndicators = Ext.Function.bind(this.doHideIndicators, this); this.initConfig(config); }, setConfig: function(config) { return this.callParent([this.processConfig(config)]); }, updateIndicatorsUi: function(newUi) { var indicators = this.getIndicators(); indicators.x.setUi(newUi); indicators.y.setUi(newUi); }, applyScroller: function(config, currentScroller) { return Ext.factory(config, Ext.scroll.Scroller, currentScroller); }, applyIndicators: function(config, indicators) { var defaultClass = Ext.scroll.Indicator, useIndicators = this.useIndicators; if (!config) { config = {}; } if (!config.x) { useIndicators.x = false; config.x = {}; } if (!config.y) { useIndicators.y = false; config.y = {}; } return { x: Ext.factory(config.x, defaultClass, indicators && indicators.x), y: Ext.factory(config.y, defaultClass, indicators && indicators.y) }; }, updateIndicators: function(indicators) { this.indicatorsGrid = Ext.Element.create({ className: 'x-scroll-bar-grid-wrapper', children: [{ className: 'x-scroll-bar-grid', children: [ { children: [{}, { children: [indicators.y.barElement] }] }, { children: [{ children: [indicators.x.barElement] }, {}] } ] }] }); }, updateScroller: function(scroller) { scroller.on({ scope: this, scrollstart: 'onScrollStart', scroll: 'onScroll', scrollend: 'onScrollEnd', refresh: 'refreshIndicators' }); }, isAxisEnabled: function(axis) { return this.getScroller().isAxisEnabled(axis) && this.useIndicators[axis]; }, applyElement: function(element) { if (element) { return Ext.get(element); } }, updateElement: function(element) { var scroller = this.getScroller(), scrollerElement; scrollerElement = element.getFirstChild().getFirstChild(); if (this.FixedHBoxStretching) { scrollerElement = scrollerElement.getFirstChild(); } element.addCls(this.getCls()); element.insertFirst(this.indicatorsGrid); scroller.setElement(scrollerElement); this.refreshIndicators(); return this; }, showIndicators: function() { var indicators = this.getIndicators(); if (this.hasOwnProperty('indicatorsHidingTimer')) { clearTimeout(this.indicatorsHidingTimer); delete this.indicatorsHidingTimer; } if (this.isAxisEnabled('x')) { indicators.x.show(); } if (this.isAxisEnabled('y')) { indicators.y.show(); } }, hideIndicators: function() { var delay = this.getIndicatorsHidingDelay(); if (delay > 0) { this.indicatorsHidingTimer = setTimeout(this.doHideIndicators, delay); } else { this.doHideIndicators(); } }, doHideIndicators: function() { var indicators = this.getIndicators(); if (this.isAxisEnabled('x')) { indicators.x.hide(); } if (this.isAxisEnabled('y')) { indicators.y.hide(); } }, onScrollStart: function() { this.onScroll.apply(this, arguments); this.showIndicators(); }, onScrollEnd: function() { this.hideIndicators(); }, onScroll: function(scroller, x, y) { this.setIndicatorValue('x', x); this.setIndicatorValue('y', y); //<debug> if (this.isBenchmarking) { this.framesCount++; } //</debug> }, //<debug> isBenchmarking: false, framesCount: 0, getCurrentFps: function() { var now = Date.now(), fps; if (!this.isBenchmarking) { this.isBenchmarking = true; fps = 0; } else { fps = Math.round(this.framesCount * 1000 / (now - this.framesCountStartTime)); } this.framesCountStartTime = now; this.framesCount = 0; return fps; }, //</debug> setIndicatorValue: function(axis, scrollerPosition) { if (!this.isAxisEnabled(axis)) { return this; } var scroller = this.getScroller(), scrollerMaxPosition = scroller.getMaxPosition()[axis], scrollerContainerSize = scroller.getContainerSize()[axis], value; if (scrollerMaxPosition === 0) { value = scrollerPosition / scrollerContainerSize; if (scrollerPosition >= 0) { value += 1; } } else { if (scrollerPosition > scrollerMaxPosition) { value = 1 + ((scrollerPosition - scrollerMaxPosition) / scrollerContainerSize); } else if (scrollerPosition < 0) { value = scrollerPosition / scrollerContainerSize; } else { value = scrollerPosition / scrollerMaxPosition; } } this.getIndicators()[axis].setValue(value); }, refreshIndicator: function(axis) { if (!this.isAxisEnabled(axis)) { return this; } var scroller = this.getScroller(), indicator = this.getIndicators()[axis], scrollerContainerSize = scroller.getContainerSize()[axis], scrollerSize = scroller.getSize()[axis], ratio = scrollerContainerSize / scrollerSize; indicator.setRatio(ratio); indicator.refresh(); }, refresh: function() { return this.getScroller().refresh(); }, refreshIndicators: function() { var indicators = this.getIndicators(); indicators.x.setActive(this.isAxisEnabled('x')); indicators.y.setActive(this.isAxisEnabled('y')); this.refreshIndicator('x'); this.refreshIndicator('y'); }, destroy: function() { var element = this.getElement(), indicators = this.getIndicators(); Ext.destroy(this.getScroller(), this.indicatorsGrid); if (this.hasOwnProperty('indicatorsHidingTimer')) { clearTimeout(this.indicatorsHidingTimer); delete this.indicatorsHidingTimer; } if (element && !element.isDestroyed) { element.removeCls(this.getCls()); } indicators.x.destroy(); indicators.y.destroy(); delete this.indicatorsGrid; this.callParent(arguments); } });