1 // ==========================================================================
  2 // Project:   SproutCore - JavaScript Application Framework
  3 // Copyright: ©2006-2011 Strobe Inc. and contributors.
  4 //            Portions ©2008-2011 Apple Inc. All rights reserved.
  5 // License:   Licensed under MIT license (see license.js)
  6 // ==========================================================================
  7 sc_require('views/scroller');
  8 
  9 /** @class
 10 
 11   Implements a complete scroller view for menus.  This class implements the
 12   arrows displayed in a menu to scroll.
 13 
 14   The main difference with SC.ScrollerView is that there is only vertical
 15   scrollers. Value Syncing between SC.MenuScrollView and SC.MenuScrollerView
 16   is done using valueBinding.
 17 
 18   @extends SC.ScrollerView
 19   @since SproutCore 1.0
 20 */
 21 SC.MenuScrollerView = SC.ScrollerView.extend(
 22 /** @scope SC.MenuScrollerView.prototype */ {
 23 
 24   // ---------------------------------------------------------------------------------------------
 25   // Properties
 26   //
 27 
 28   /**
 29     @type Array
 30     @default ['sc-menu-scroller-view']
 31     @see SC.View#classNames
 32   */
 33   classNames: ['sc-menu-scroller-view'],
 34 
 35   /**
 36     Used to set the scrolling direction of the scroller.
 37 
 38     @type Boolean
 39     @default false
 40   */
 41   scrollDown: false,
 42 
 43   /**
 44      Amount to scroll one vertical line.
 45 
 46      @type Number
 47      @default 20
 48   */
 49   verticalLineScroll: 20,
 50 
 51 
 52   // ..........................................................
 53   // INTERNAL SUPPORT
 54   //
 55 
 56   /** @private */
 57   init: function () {
 58     // Set the scrollerThickness based on controlSize
 59     switch (this.get('controlSize')) {
 60     case SC.TINY_CONTROL_SIZE:
 61       this.set('scrollerThickness', SC.MenuScrollerView.TINY_SCROLLER_THICKNESS);
 62       break;
 63     case SC.SMALL_CONTROL_SIZE:
 64       this.set('scrollerThickness', SC.MenuScrollerView.SMALL_SCROLLER_THICKNESS);
 65       break;
 66     case SC.REGULAR_CONTROL_SIZE:
 67       this.set('scrollerThickness', SC.MenuScrollerView.REGULAR_SCROLLER_THICKNESS);
 68       break;
 69     case SC.LARGE_CONTROL_SIZE:
 70       this.set('scrollerThickness', SC.MenuScrollerView.LARGE_SCROLLER_THICKNESS);
 71       break;
 72     case SC.HUGE_CONTROL_SIZE:
 73       this.set('scrollerThickness', SC.MenuScrollerView.HUGE_SCROLLER_THICKNESS);
 74       break;
 75     }
 76 
 77     return sc_super();
 78   },
 79 
 80   /** @private */
 81   render: function (context, firstTime) {
 82     context.addClass('sc-vertical');
 83     context.addClass(this.get('controlSize'));
 84     if (firstTime) {
 85       var direction = this.get('scrollDown') ? 'arrowDown' : 'arrowUp';
 86       context.push('<span class="scrollArrow ' + direction + '"> </span>');
 87     }
 88   },
 89 
 90   /** @private */
 91   mouseEntered: function (evt) {
 92     this.set('isMouseOver', YES);
 93     this._invokeScrollOnMouseOver();
 94   },
 95 
 96   /** @private */
 97   mouseExited: function (evt) {
 98     this.set('isMouseOver', NO);
 99   },
100 
101   /** @private
102     Scroll the menu if it is is an up or down arrow. This is called by
103     the function that simulates mouseOver.
104   */
105   _scrollMenu: function () {
106     var value = this.get('value');
107 
108     if (this.get('scrollDown')) {
109       value = value + this.verticalLineScroll;
110       value = Math.min(value, this.get('maximum'));
111     } else {
112       value = value - this.verticalLineScroll;
113       value = Math.max(value, this.get('minimum'));
114     }
115 
116     this.set('value', value);
117 
118     return YES;
119   },
120 
121   /** @private
122 
123     We use this function to simulate mouseOver. It checks for the flag
124     isMouseOver which is turned on when mouseEntered is called and turned off
125     when mouseExited is called.
126   */
127   _invokeScrollOnMouseOver: function () {
128     this._scrollMenu();
129     if (this.get('isMouseOver')) {
130       this.invokeLater(this._invokeScrollOnMouseOver, 50);
131     }
132   }
133 
134 });
135 
136 
137 /**
138   @static
139   @type Number
140   @default 18
141 */
142 SC.MenuScrollerView.REGULAR_SCROLLER_THICKNESS = 18;
143 
144 /**
145   @static
146   @type Number
147   @default 10
148 */
149 SC.MenuScrollerView.TINY_SCROLLER_THICKNESS    = 10;
150 
151 /**
152   @static
153   @type Number
154   @default 14
155 */
156 SC.MenuScrollerView.SMALL_SCROLLER_THICKNESS   = 14;
157 
158 /**
159   @static
160   @type Number
161   @default 23
162 */
163 SC.MenuScrollerView.LARGE_SCROLLER_THICKNESS   = 23;
164 
165 /**
166   @static
167   @type Number
168   @default 26
169 */
170 SC.MenuScrollerView.HUGE_SCROLLER_THICKNESS    = 26;
171