123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495 |
- <!DOCTYPE html>
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>The source code</title>
- <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>
- <script type="text/javascript">
- function highlight() {
- document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
- }
- </script>
- </head>
- <body onload="prettyPrint(); highlight();">
- <pre class="prettyprint lang-js"><span id='Ext-layout-container-boxOverflow-Scroller'>/**
- </span> * @private
- */
- Ext.define('Ext.layout.container.boxOverflow.Scroller', {
- /* Begin Definitions */
- extend: 'Ext.layout.container.boxOverflow.None',
- requires: ['Ext.util.ClickRepeater', 'Ext.Element'],
- alternateClassName: 'Ext.layout.boxOverflow.Scroller',
- mixins: {
- observable: 'Ext.util.Observable'
- },
-
- /* End Definitions */
- <span id='Ext-layout-container-boxOverflow-Scroller-cfg-animateScroll'> /**
- </span> * @cfg {Boolean} animateScroll
- * True to animate the scrolling of items within the layout (ignored if enableScroll is false)
- */
- animateScroll: false,
- <span id='Ext-layout-container-boxOverflow-Scroller-cfg-scrollIncrement'> /**
- </span> * @cfg {Number} scrollIncrement
- * The number of pixels to scroll by on scroller click
- */
- scrollIncrement: 20,
- <span id='Ext-layout-container-boxOverflow-Scroller-cfg-wheelIncrement'> /**
- </span> * @cfg {Number} wheelIncrement
- * The number of pixels to increment on mouse wheel scrolling.
- */
- wheelIncrement: 10,
- <span id='Ext-layout-container-boxOverflow-Scroller-cfg-scrollRepeatInterval'> /**
- </span> * @cfg {Number} scrollRepeatInterval
- * Number of milliseconds between each scroll while a scroller button is held down
- */
- scrollRepeatInterval: 60,
- <span id='Ext-layout-container-boxOverflow-Scroller-cfg-scrollDuration'> /**
- </span> * @cfg {Number} scrollDuration
- * Number of milliseconds that each scroll animation lasts
- */
- scrollDuration: 400,
- <span id='Ext-layout-container-boxOverflow-Scroller-cfg-beforeCtCls'> /**
- </span> * @cfg {String} beforeCtCls
- * CSS class added to the beforeCt element. This is the element that holds any special items such as scrollers,
- * which must always be present at the leftmost edge of the Container
- */
- <span id='Ext-layout-container-boxOverflow-Scroller-cfg-afterCtCls'> /**
- </span> * @cfg {String} afterCtCls
- * CSS class added to the afterCt element. This is the element that holds any special items such as scrollers,
- * which must always be present at the rightmost edge of the Container
- */
- <span id='Ext-layout-container-boxOverflow-Scroller-cfg-scrollerCls'> /**
- </span> * @cfg {String} [scrollerCls='x-box-scroller']
- * CSS class added to both scroller elements if enableScroll is used
- */
- scrollerCls: Ext.baseCSSPrefix + 'box-scroller',
- <span id='Ext-layout-container-boxOverflow-Scroller-cfg-beforeScrollerCls'> /**
- </span> * @cfg {String} beforeScrollerCls
- * CSS class added to the left scroller element if enableScroll is used
- */
- <span id='Ext-layout-container-boxOverflow-Scroller-cfg-afterScrollerCls'> /**
- </span> * @cfg {String} afterScrollerCls
- * CSS class added to the right scroller element if enableScroll is used
- */
- constructor: function(layout, config) {
- var me = this;
- me.layout = layout;
- Ext.apply(me, config || {});
- // Dont pass the config so that it is not applied to 'this' again
- me.mixins.observable.constructor.call(me);
- me.addEvents(
- <span id='Ext-layout-container-boxOverflow-Scroller-event-scroll'> /**
- </span> * @event scroll
- * @param {Ext.layout.container.boxOverflow.Scroller} scroller The layout scroller
- * @param {Number} newPosition The new position of the scroller
- * @param {Boolean/Object} animate If animating or not. If true, it will be a animation configuration, else it will be false
- */
- 'scroll'
- );
- me.scrollPosition = 0;
- me.scrollSize = 0;
- },
- getPrefixConfig: function() {
- var me = this;
- me.initCSSClasses();
- return {
- cls: Ext.layout.container.Box.prototype.innerCls + ' ' + me.beforeCtCls,
- cn : {
- id : me.layout.owner.id + '-before-scroller',
- cls: me.scrollerCls + ' ' + me.beforeScrollerCls,
- style: 'display:none'
- }
- };
- },
- getSuffixConfig: function() {
- var me = this;
- return {
- cls: Ext.layout.container.Box.prototype.innerCls + ' ' + me.afterCtCls,
- cn : {
- id : me.layout.owner.id + '-after-scroller',
- cls: me.scrollerCls + ' ' + me.afterScrollerCls,
- style: 'display:none'
- }
- };
- },
- getOverflowCls: function() {
- return Ext.baseCSSPrefix + this.layout.direction + '-box-overflow-body';
- },
- initCSSClasses: function() {
- var me = this,
- prefix = Ext.baseCSSPrefix,
- layout = me.layout,
- names = layout.getNames(),
- leftName = names.left,
- rightName = names.right,
- type = me.getOwnerType(layout.owner);
- me.beforeCtCls = me.beforeCtCls || prefix + 'box-scroller-' + leftName;
- me.afterCtCls = me.afterCtCls || prefix + 'box-scroller-' + rightName;
-
- me.beforeScrollerCls = me.beforeScrollerCls || prefix + type + '-scroll-' + leftName;
- me.afterScrollerCls = me.afterScrollerCls || prefix + type + '-scroll-' + rightName;
- },
- beginLayout: function (ownerContext) {
- var layout = this.layout,
- names = layout.getNames();
- ownerContext.innerCtScrollPos = layout.innerCt.dom['scroll' + names.leftCap];
- this.callParent(arguments);
- },
- completeLayout: function (ownerContext) {
- // capture this before callParent since it calls handle/clearOverflow:
- this.scrollSize = ownerContext.props['content'+this.layout.getNames().widthCap];
- this.callParent(arguments);
- },
-
- finishedLayout: function(ownerContext) {
- var me = this,
- layout = me.layout,
- names = layout.getNames(),
- scrollPos = Math.min(me.getMaxScrollPosition(), ownerContext.innerCtScrollPos);
- layout.innerCt.dom['scroll' + names.leftCap] = scrollPos;
- },
- handleOverflow: function(ownerContext) {
- var me = this,
- layout = me.layout,
- names = layout.getNames(),
- methodName = 'get' + names.widthCap;
- me.captureChildElements();
- me.showScrollers();
- return {
- reservedSpace: me.beforeCt[methodName]() + me.afterCt[methodName]()
- };
- },
- <span id='Ext-layout-container-boxOverflow-Scroller-method-captureChildElements'> /**
- </span> * @private
- * Gets references to the beforeCt and afterCt elements if they have not already been captured
- * and creates click handlers for them.
- */
- captureChildElements: function() {
- var me = this,
- el = me.layout.owner.el,
- before,
- after;
- // Grab the scroll click receiving elements
- if (!me.beforeCt) {
- before = me.beforeScroller = el.getById(me.layout.owner.id + '-before-scroller');
- after = me.afterScroller = el.getById(me.layout.owner.id + '-after-scroller');
- me.beforeCt = before.up('');
- me.afterCt = after.up('');
- me.createWheelListener();
- before.addClsOnOver(me.beforeScrollerCls + '-hover');
- after.addClsOnOver(me.afterScrollerCls + '-hover');
- before.setVisibilityMode(Ext.Element.DISPLAY);
- after.setVisibilityMode(Ext.Element.DISPLAY);
- me.beforeRepeater = new Ext.util.ClickRepeater(before, {
- interval: me.scrollRepeatInterval,
- handler : me.scrollLeft,
- scope : me
- });
- me.afterRepeater = new Ext.util.ClickRepeater(after, {
- interval: me.scrollRepeatInterval,
- handler : me.scrollRight,
- scope : me
- });
- }
- },
- <span id='Ext-layout-container-boxOverflow-Scroller-method-createWheelListener'> /**
- </span> * @private
- * Sets up an listener to scroll on the layout's innerCt mousewheel event
- */
- createWheelListener: function() {
- this.layout.innerCt.on({
- mousewheel: function(e) {
- this.scrollBy(e.getWheelDelta() * this.wheelIncrement * -1, false);
- },
- stopEvent: true,
- scope: this
- });
- },
- <span id='Ext-layout-container-boxOverflow-Scroller-method-clearOverflow'> /**
- </span> * @private
- */
- clearOverflow: function () {
- var layout = this.layout;
- this.hideScrollers();
- },
- <span id='Ext-layout-container-boxOverflow-Scroller-method-showScrollers'> /**
- </span> * @private
- * Shows the scroller elements in the beforeCt and afterCt. Creates the scrollers first if they are not already
- * present.
- */
- showScrollers: function() {
- var me = this;
- me.captureChildElements();
- me.beforeScroller.show();
- me.afterScroller.show();
- me.updateScrollButtons();
- me.layout.owner.addClsWithUI('scroller');
- // TODO - this may invalidates data in the ContextItem's styleCache
- },
- <span id='Ext-layout-container-boxOverflow-Scroller-method-hideScrollers'> /**
- </span> * @private
- * Hides the scroller elements in the beforeCt and afterCt
- */
- hideScrollers: function() {
- var me = this;
- if (me.beforeScroller !== undefined) {
- me.beforeScroller.hide();
- me.afterScroller.hide();
- me.layout.owner.removeClsWithUI('scroller');
- // TODO - this may invalidates data in the ContextItem's styleCache
- }
- },
- <span id='Ext-layout-container-boxOverflow-Scroller-method-destroy'> /**
- </span> * @private
- */
- destroy: function() {
- var me = this;
- Ext.destroy(me.beforeRepeater, me.afterRepeater, me.beforeScroller, me.afterScroller, me.beforeCt, me.afterCt);
- },
- <span id='Ext-layout-container-boxOverflow-Scroller-method-scrollBy'> /**
- </span> * @private
- * Scrolls left or right by the number of pixels specified
- * @param {Number} delta Number of pixels to scroll to the right by. Use a negative number to scroll left
- */
- scrollBy: function(delta, animate) {
- this.scrollTo(this.getScrollPosition() + delta, animate);
- },
- <span id='Ext-layout-container-boxOverflow-Scroller-method-getScrollAnim'> /**
- </span> * @private
- * @return {Object} Object passed to scrollTo when scrolling
- */
- getScrollAnim: function() {
- return {
- duration: this.scrollDuration,
- callback: this.updateScrollButtons,
- scope : this
- };
- },
- <span id='Ext-layout-container-boxOverflow-Scroller-method-updateScrollButtons'> /**
- </span> * @private
- * Enables or disables each scroller button based on the current scroll position
- */
- updateScrollButtons: function() {
- var me = this,
- beforeMeth,
- afterMeth,
- beforeCls,
- afterCls;
-
- if (me.beforeScroller === undefined || me.afterScroller === undefined) {
- return;
- }
- beforeMeth = me.atExtremeBefore() ? 'addCls' : 'removeCls';
- afterMeth = me.atExtremeAfter() ? 'addCls' : 'removeCls';
- beforeCls = me.beforeScrollerCls + '-disabled';
- afterCls = me.afterScrollerCls + '-disabled';
- me.beforeScroller[beforeMeth](beforeCls);
- me.afterScroller[afterMeth](afterCls);
- me.scrolling = false;
- },
- <span id='Ext-layout-container-boxOverflow-Scroller-method-atExtremeBefore'> /**
- </span> * @private
- * Returns true if the innerCt scroll is already at its left-most point
- * @return {Boolean} True if already at furthest left point
- */
- atExtremeBefore: function() {
- return !this.getScrollPosition();
- },
- <span id='Ext-layout-container-boxOverflow-Scroller-method-scrollLeft'> /**
- </span> * @private
- * Scrolls to the left by the configured amount
- */
- scrollLeft: function() {
- this.scrollBy(-this.scrollIncrement, false);
- },
- <span id='Ext-layout-container-boxOverflow-Scroller-method-scrollRight'> /**
- </span> * @private
- * Scrolls to the right by the configured amount
- */
- scrollRight: function() {
- this.scrollBy(this.scrollIncrement, false);
- },
- <span id='Ext-layout-container-boxOverflow-Scroller-method-getScrollPosition'> /**
- </span> * Returns the current scroll position of the innerCt element
- * @return {Number} The current scroll position
- */
- getScrollPosition: function(){
- var me = this,
- layout = me.layout,
- result;
- // Until we actually scroll, the scroll[Top|Left] is stored as zero to avoid DOM hits.
- if (me.hasOwnProperty('scrollPosition')) {
- result = me.scrollPosition;
- } else {
- result = parseInt(layout.innerCt.dom['scroll' + layout.getNames().leftCap], 10) || 0;
- }
- return result;
- },
- <span id='Ext-layout-container-boxOverflow-Scroller-method-getMaxScrollPosition'> /**
- </span> * @private
- * Returns the maximum value we can scrollTo
- * @return {Number} The max scroll value
- */
- getMaxScrollPosition: function() {
- var me = this,
- layout = me.layout,
- names = layout.getNames(),
- maxScrollPos = me.scrollSize - layout.innerCt['get'+names.widthCap]();
- return (maxScrollPos < 0) ? 0 : maxScrollPos;
- },
- <span id='Ext-layout-container-boxOverflow-Scroller-method-atExtremeAfter'> /**
- </span> * @private
- * Returns true if the innerCt scroll is already at its right-most point
- * @return {Boolean} True if already at furthest right point
- */
- atExtremeAfter: function() {
- return this.getScrollPosition() >= this.getMaxScrollPosition();
- },
- <span id='Ext-layout-container-boxOverflow-Scroller-method-scrollTo'> /**
- </span> * @private
- * Scrolls to the given position. Performs bounds checking.
- * @param {Number} position The position to scroll to. This is constrained.
- * @param {Boolean} animate True to animate. If undefined, falls back to value of this.animateScroll
- */
- scrollTo: function(position, animate) {
- var me = this,
- layout = me.layout,
- names = layout.getNames(),
- oldPosition = me.getScrollPosition(),
- newPosition = Ext.Number.constrain(position, 0, me.getMaxScrollPosition());
- if (newPosition != oldPosition && !me.scrolling) {
- delete me.scrollPosition;
- if (animate === undefined) {
- animate = me.animateScroll;
- }
- layout.innerCt.scrollTo(names.left, newPosition, animate ? me.getScrollAnim() : false);
- if (animate) {
- me.scrolling = true;
- } else {
- me.updateScrollButtons();
- }
- me.fireEvent('scroll', me, newPosition, animate ? me.getScrollAnim() : false);
- }
- },
- <span id='Ext-layout-container-boxOverflow-Scroller-method-scrollToItem'> /**
- </span> * Scrolls to the given component.
- * @param {String/Number/Ext.Component} item The item to scroll to. Can be a numerical index, component id
- * or a reference to the component itself.
- * @param {Boolean} animate True to animate the scrolling
- */
- scrollToItem: function(item, animate) {
- var me = this,
- layout = me.layout,
- names = layout.getNames(),
- visibility,
- box,
- newPos;
- item = me.getItem(item);
- if (item !== undefined) {
- visibility = me.getItemVisibility(item);
- if (!visibility.fullyVisible) {
- box = item.getBox(true, true);
- newPos = box[names.x];
- if (visibility.hiddenEnd) {
- newPos -= (me.layout.innerCt['get' + names.widthCap]() - box[names.width]);
- }
- me.scrollTo(newPos, animate);
- }
- }
- },
- <span id='Ext-layout-container-boxOverflow-Scroller-method-getItemVisibility'> /**
- </span> * @private
- * For a given item in the container, return an object with information on whether the item is visible
- * with the current innerCt scroll value.
- * @param {Ext.Component} item The item
- * @return {Object} Values for fullyVisible, hiddenStart and hiddenEnd
- */
- getItemVisibility: function(item) {
- var me = this,
- box = me.getItem(item).getBox(true, true),
- layout = me.layout,
- names = layout.getNames(),
- itemStart = box[names.x],
- itemEnd = itemStart + box[names.width],
- scrollStart = me.getScrollPosition(),
- scrollEnd = scrollStart + layout.innerCt['get' + names.widthCap]();
- return {
- hiddenStart : itemStart < scrollStart,
- hiddenEnd : itemEnd > scrollEnd,
- fullyVisible: itemStart > scrollStart && itemEnd < scrollEnd
- };
- }
- });
- </pre>
- </body>
- </html>
|