Upgrade to ExtJS 3.3.1 - Released 11/30/2010
[extjs.git] / docs / source / ScrollerOverflow.html
1 <html>
2 <head>
3   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    
4   <title>The source code</title>
5     <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
6     <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
7 </head>
8 <body  onload="prettyPrint();">
9     <pre class="prettyprint lang-js">/*!
10  * Ext JS Library 3.3.1
11  * Copyright(c) 2006-2010 Sencha Inc.
12  * licensing@sencha.com
13  * http://www.sencha.com/license
14  */
15 <div id="cls-Ext.layout.boxOverflow.Scroller"></div>/**
16  * @class Ext.layout.boxOverflow.Scroller
17  * @extends Ext.layout.boxOverflow.None
18  * Description
19  */
20 Ext.layout.boxOverflow.Scroller = Ext.extend(Ext.layout.boxOverflow.None, {
21     <div id="cfg-Ext.layout.boxOverflow.Scroller-null"></div>/**
22      * @cfg animateScroll
23      * @type Boolean
24      * True to animate the scrolling of items within the layout (defaults to true, ignored if enableScroll is false)
25      */
26     animateScroll: true,
27     
28     <div id="cfg-Ext.layout.boxOverflow.Scroller-null"></div>/**
29      * @cfg scrollIncrement
30      * @type Number
31      * The number of pixels to scroll by on scroller click (defaults to 100)
32      */
33     scrollIncrement: 100,
34     
35     <div id="cfg-Ext.layout.boxOverflow.Scroller-null"></div>/**
36      * @cfg wheelIncrement
37      * @type Number
38      * The number of pixels to increment on mouse wheel scrolling (defaults to <tt>3</tt>).
39      */
40     wheelIncrement: 3,
41     
42     <div id="cfg-Ext.layout.boxOverflow.Scroller-null"></div>/**
43      * @cfg scrollRepeatInterval
44      * @type Number
45      * Number of milliseconds between each scroll while a scroller button is held down (defaults to 400)
46      */
47     scrollRepeatInterval: 400,
48     
49     <div id="cfg-Ext.layout.boxOverflow.Scroller-null"></div>/**
50      * @cfg scrollDuration
51      * @type Number
52      * Number of seconds that each scroll animation lasts (defaults to 0.4)
53      */
54     scrollDuration: 0.4,
55     
56     <div id="cfg-Ext.layout.boxOverflow.Scroller-null"></div>/**
57      * @cfg beforeCls
58      * @type String
59      * CSS class added to the beforeCt element. This is the element that holds any special items such as scrollers,
60      * which must always be present at the leftmost edge of the Container
61      */
62     beforeCls: 'x-strip-left',
63     
64     <div id="cfg-Ext.layout.boxOverflow.Scroller-null"></div>/**
65      * @cfg afterCls
66      * @type String
67      * CSS class added to the afterCt element. This is the element that holds any special items such as scrollers,
68      * which must always be present at the rightmost edge of the Container
69      */
70     afterCls: 'x-strip-right',
71     
72     <div id="cfg-Ext.layout.boxOverflow.Scroller-null"></div>/**
73      * @cfg scrollerCls
74      * @type String
75      * CSS class added to both scroller elements if enableScroll is used
76      */
77     scrollerCls: 'x-strip-scroller',
78     
79     <div id="cfg-Ext.layout.boxOverflow.Scroller-null"></div>/**
80      * @cfg beforeScrollerCls
81      * @type String
82      * CSS class added to the left scroller element if enableScroll is used
83      */
84     beforeScrollerCls: 'x-strip-scroller-left',
85     
86     <div id="cfg-Ext.layout.boxOverflow.Scroller-null"></div>/**
87      * @cfg afterScrollerCls
88      * @type String
89      * CSS class added to the right scroller element if enableScroll is used
90      */
91     afterScrollerCls: 'x-strip-scroller-right',
92     
93     /**
94      * @private
95      * Sets up an listener to scroll on the layout's innerCt mousewheel event
96      */
97     createWheelListener: function() {
98         this.layout.innerCt.on({
99             scope     : this,
100             mousewheel: function(e) {
101                 e.stopEvent();
102
103                 this.scrollBy(e.getWheelDelta() * this.wheelIncrement * -1, false);
104             }
105         });
106     },
107     
108     /**
109      * @private
110      * Most of the heavy lifting is done in the subclasses
111      */
112     handleOverflow: function(calculations, targetSize) {
113         this.createInnerElements();
114         this.showScrollers();
115     },
116     
117     /**
118      * @private
119      */
120     clearOverflow: function() {
121         this.hideScrollers();
122     },
123     
124     /**
125      * @private
126      * Shows the scroller elements in the beforeCt and afterCt. Creates the scrollers first if they are not already
127      * present. 
128      */
129     showScrollers: function() {
130         this.createScrollers();
131         
132         this.beforeScroller.show();
133         this.afterScroller.show();
134         
135         this.updateScrollButtons();
136     },
137     
138     /**
139      * @private
140      * Hides the scroller elements in the beforeCt and afterCt
141      */
142     hideScrollers: function() {
143         if (this.beforeScroller != undefined) {
144             this.beforeScroller.hide();
145             this.afterScroller.hide();          
146         }
147     },
148     
149     /**
150      * @private
151      * Creates the clickable scroller elements and places them into the beforeCt and afterCt
152      */
153     createScrollers: function() {
154         if (!this.beforeScroller && !this.afterScroller) {
155             var before = this.beforeCt.createChild({
156                 cls: String.format("{0} {1} ", this.scrollerCls, this.beforeScrollerCls)
157             });
158             
159             var after = this.afterCt.createChild({
160                 cls: String.format("{0} {1}", this.scrollerCls, this.afterScrollerCls)
161             });
162             
163             before.addClassOnOver(this.beforeScrollerCls + '-hover');
164             after.addClassOnOver(this.afterScrollerCls + '-hover');
165             
166             before.setVisibilityMode(Ext.Element.DISPLAY);
167             after.setVisibilityMode(Ext.Element.DISPLAY);
168             
169             this.beforeRepeater = new Ext.util.ClickRepeater(before, {
170                 interval: this.scrollRepeatInterval,
171                 handler : this.scrollLeft,
172                 scope   : this
173             });
174             
175             this.afterRepeater = new Ext.util.ClickRepeater(after, {
176                 interval: this.scrollRepeatInterval,
177                 handler : this.scrollRight,
178                 scope   : this
179             });
180             
181             <div id="prop-Ext.layout.boxOverflow.Scroller-beforeScroller"></div>/**
182              * @property beforeScroller
183              * @type Ext.Element
184              * The left scroller element. Only created when needed.
185              */
186             this.beforeScroller = before;
187             
188             <div id="prop-Ext.layout.boxOverflow.Scroller-afterScroller"></div>/**
189              * @property afterScroller
190              * @type Ext.Element
191              * The left scroller element. Only created when needed.
192              */
193             this.afterScroller = after;
194         }
195     },
196     
197     /**
198      * @private
199      */
200     destroy: function() {
201         Ext.destroy(this.beforeScroller, this.afterScroller, this.beforeRepeater, this.afterRepeater, this.beforeCt, this.afterCt);
202     },
203     
204     /**
205      * @private
206      * Scrolls left or right by the number of pixels specified
207      * @param {Number} delta Number of pixels to scroll to the right by. Use a negative number to scroll left
208      */
209     scrollBy: function(delta, animate) {
210         this.scrollTo(this.getScrollPosition() + delta, animate);
211     },
212     
213     /**
214      * @private
215      * Normalizes an item reference, string id or numerical index into a reference to the item
216      * @param {Ext.Component|String|Number} item The item reference, id or index
217      * @return {Ext.Component} The item
218      */
219     getItem: function(item) {
220         if (Ext.isString(item)) {
221             item = Ext.getCmp(item);
222         } else if (Ext.isNumber(item)) {
223             item = this.items[item];
224         }
225         
226         return item;
227     },
228     
229     /**
230      * @private
231      * @return {Object} Object passed to scrollTo when scrolling
232      */
233     getScrollAnim: function() {
234         return {
235             duration: this.scrollDuration, 
236             callback: this.updateScrollButtons, 
237             scope   : this
238         };
239     },
240     
241     /**
242      * @private
243      * Enables or disables each scroller button based on the current scroll position
244      */
245     updateScrollButtons: function() {
246         if (this.beforeScroller == undefined || this.afterScroller == undefined) {
247             return;
248         }
249         
250         var beforeMeth = this.atExtremeBefore()  ? 'addClass' : 'removeClass',
251             afterMeth  = this.atExtremeAfter() ? 'addClass' : 'removeClass',
252             beforeCls  = this.beforeScrollerCls + '-disabled',
253             afterCls   = this.afterScrollerCls  + '-disabled';
254         
255         this.beforeScroller[beforeMeth](beforeCls);
256         this.afterScroller[afterMeth](afterCls);
257         this.scrolling = false;
258     },
259     
260     /**
261      * @private
262      * Returns true if the innerCt scroll is already at its left-most point
263      * @return {Boolean} True if already at furthest left point
264      */
265     atExtremeBefore: function() {
266         return this.getScrollPosition() === 0;
267     },
268     
269     /**
270      * @private
271      * Scrolls to the left by the configured amount
272      */
273     scrollLeft: function(animate) {
274         this.scrollBy(-this.scrollIncrement, animate);
275     },
276     
277     /**
278      * @private
279      * Scrolls to the right by the configured amount
280      */
281     scrollRight: function(animate) {
282         this.scrollBy(this.scrollIncrement, animate);
283     },
284     
285     <div id="method-Ext.layout.boxOverflow.Scroller-scrollToItem"></div>/**
286      * Scrolls to the given component.
287      * @param {String|Number|Ext.Component} item The item to scroll to. Can be a numerical index, component id 
288      * or a reference to the component itself.
289      * @param {Boolean} animate True to animate the scrolling
290      */
291     scrollToItem: function(item, animate) {
292         item = this.getItem(item);
293         
294         if (item != undefined) {
295             var visibility = this.getItemVisibility(item);
296             
297             if (!visibility.fullyVisible) {
298                 var box  = item.getBox(true, true),
299                     newX = box.x;
300                     
301                 if (visibility.hiddenRight) {
302                     newX -= (this.layout.innerCt.getWidth() - box.width);
303                 }
304                 
305                 this.scrollTo(newX, animate);
306             }
307         }
308     },
309     
310     /**
311      * @private
312      * For a given item in the container, return an object with information on whether the item is visible
313      * with the current innerCt scroll value.
314      * @param {Ext.Component} item The item
315      * @return {Object} Values for fullyVisible, hiddenLeft and hiddenRight
316      */
317     getItemVisibility: function(item) {
318         var box         = this.getItem(item).getBox(true, true),
319             itemLeft    = box.x,
320             itemRight   = box.x + box.width,
321             scrollLeft  = this.getScrollPosition(),
322             scrollRight = this.layout.innerCt.getWidth() + scrollLeft;
323         
324         return {
325             hiddenLeft  : itemLeft < scrollLeft,
326             hiddenRight : itemRight > scrollRight,
327             fullyVisible: itemLeft > scrollLeft && itemRight < scrollRight
328         };
329     }
330 });
331
332 Ext.layout.boxOverflow.scroller = Ext.layout.boxOverflow.Scroller;
333
334
335 <div id="cls-Ext.layout.boxOverflow.VerticalScroller"></div>/**\r
336  * @class Ext.layout.boxOverflow.VerticalScroller\r
337  * @extends Ext.layout.boxOverflow.Scroller\r
338  * Description\r
339  */\r
340 Ext.layout.boxOverflow.VerticalScroller = Ext.extend(Ext.layout.boxOverflow.Scroller, {
341     scrollIncrement: 75,
342     wheelIncrement : 2,
343     
344     handleOverflow: function(calculations, targetSize) {
345         Ext.layout.boxOverflow.VerticalScroller.superclass.handleOverflow.apply(this, arguments);
346         
347         return {
348             targetSize: {
349                 height: targetSize.height - (this.beforeCt.getHeight() + this.afterCt.getHeight()),
350                 width : targetSize.width
351             }
352         };
353     },
354     
355     /**
356      * @private
357      * Creates the beforeCt and afterCt elements if they have not already been created
358      */
359     createInnerElements: function() {
360         var target = this.layout.innerCt;
361         
362         //normal items will be rendered to the innerCt. beforeCt and afterCt allow for fixed positioning of
363         //special items such as scrollers or dropdown menu triggers
364         if (!this.beforeCt) {
365             this.beforeCt = target.insertSibling({cls: this.beforeCls}, 'before');
366             this.afterCt  = target.insertSibling({cls: this.afterCls},  'after');
367
368             this.createWheelListener();
369         }
370     },
371     
372     /**
373      * @private
374      * Scrolls to the given position. Performs bounds checking.
375      * @param {Number} position The position to scroll to. This is constrained.
376      * @param {Boolean} animate True to animate. If undefined, falls back to value of this.animateScroll
377      */
378     scrollTo: function(position, animate) {
379         var oldPosition = this.getScrollPosition(),
380             newPosition = position.constrain(0, this.getMaxScrollBottom());
381         
382         if (newPosition != oldPosition && !this.scrolling) {
383             if (animate == undefined) {
384                 animate = this.animateScroll;
385             }
386             
387             this.layout.innerCt.scrollTo('top', newPosition, animate ? this.getScrollAnim() : false);
388             
389             if (animate) {
390                 this.scrolling = true;
391             } else {
392                 this.scrolling = false;
393                 this.updateScrollButtons();
394             }
395         }
396     },
397     
398     <div id="method-Ext.layout.boxOverflow.VerticalScroller-getScrollPosition"></div>/**
399      * Returns the current scroll position of the innerCt element
400      * @return {Number} The current scroll position
401      */
402     getScrollPosition: function(){
403         return parseInt(this.layout.innerCt.dom.scrollTop, 10) || 0;
404     },
405     
406     /**
407      * @private
408      * Returns the maximum value we can scrollTo
409      * @return {Number} The max scroll value
410      */
411     getMaxScrollBottom: function() {
412         return this.layout.innerCt.dom.scrollHeight - this.layout.innerCt.getHeight();
413     },
414     
415     /**
416      * @private
417      * Returns true if the innerCt scroll is already at its right-most point
418      * @return {Boolean} True if already at furthest right point
419      */
420     atExtremeAfter: function() {
421         return this.getScrollPosition() >= this.getMaxScrollBottom();
422     }
423 });
424
425 Ext.layout.boxOverflow.scroller.vbox = Ext.layout.boxOverflow.VerticalScroller;
426
427
428 <div id="cls-Ext.layout.boxOverflow.HorizontalScroller"></div>/**
429  * @class Ext.layout.boxOverflow.HorizontalScroller
430  * @extends Ext.layout.boxOverflow.Scroller
431  * Description
432  */
433 Ext.layout.boxOverflow.HorizontalScroller = Ext.extend(Ext.layout.boxOverflow.Scroller, {
434     handleOverflow: function(calculations, targetSize) {
435         Ext.layout.boxOverflow.HorizontalScroller.superclass.handleOverflow.apply(this, arguments);
436         
437         return {
438             targetSize: {
439                 height: targetSize.height,
440                 width : targetSize.width - (this.beforeCt.getWidth() + this.afterCt.getWidth())
441             }
442         };
443     },
444     
445     /**
446      * @private
447      * Creates the beforeCt and afterCt elements if they have not already been created
448      */
449     createInnerElements: function() {
450         var target = this.layout.innerCt;
451         
452         //normal items will be rendered to the innerCt. beforeCt and afterCt allow for fixed positioning of
453         //special items such as scrollers or dropdown menu triggers
454         if (!this.beforeCt) {
455             this.afterCt  = target.insertSibling({cls: this.afterCls},  'before');
456             this.beforeCt = target.insertSibling({cls: this.beforeCls}, 'before');
457             
458             this.createWheelListener();
459         }
460     },
461     
462     /**
463      * @private
464      * Scrolls to the given position. Performs bounds checking.
465      * @param {Number} position The position to scroll to. This is constrained.
466      * @param {Boolean} animate True to animate. If undefined, falls back to value of this.animateScroll
467      */
468     scrollTo: function(position, animate) {
469         var oldPosition = this.getScrollPosition(),
470             newPosition = position.constrain(0, this.getMaxScrollRight());
471         
472         if (newPosition != oldPosition && !this.scrolling) {
473             if (animate == undefined) {
474                 animate = this.animateScroll;
475             }
476             
477             this.layout.innerCt.scrollTo('left', newPosition, animate ? this.getScrollAnim() : false);
478             
479             if (animate) {
480                 this.scrolling = true;
481             } else {
482                 this.scrolling = false;
483                 this.updateScrollButtons();
484             }
485         }
486     },
487     
488     <div id="method-Ext.layout.boxOverflow.HorizontalScroller-getScrollPosition"></div>/**
489      * Returns the current scroll position of the innerCt element
490      * @return {Number} The current scroll position
491      */
492     getScrollPosition: function(){
493         return parseInt(this.layout.innerCt.dom.scrollLeft, 10) || 0;
494     },
495     
496     /**
497      * @private
498      * Returns the maximum value we can scrollTo
499      * @return {Number} The max scroll value
500      */
501     getMaxScrollRight: function() {
502         return this.layout.innerCt.dom.scrollWidth - this.layout.innerCt.getWidth();
503     },
504     
505     /**
506      * @private
507      * Returns true if the innerCt scroll is already at its right-most point
508      * @return {Boolean} True if already at furthest right point
509      */
510     atExtremeAfter: function() {
511         return this.getScrollPosition() >= this.getMaxScrollRight();
512     }
513 });
514
515 Ext.layout.boxOverflow.scroller.hbox = Ext.layout.boxOverflow.HorizontalScroller;</pre>    
516 </body>
517 </html>