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 8 9 /** 10 @class 11 12 Displays a progress bar. You can display both a defined and an 13 indeterminate progressbar. The progress bar itself is designed to be styled 14 using CSS classes with the following structure: 15 16 <div class="sc-progress-view"><div class="inner"></div></div> 17 18 The outer can form the boundary of the bar while the inner will be adjusted 19 to fit the percentage of the progress. 20 21 Creating a ProgressView accepts a number of properties, for example: 22 23 progressView: SC.ProgressView.design({ 24 value: 50, 25 minimum: 0, 26 maximum: 100, 27 isIndeterminate: NO, 28 isEnabled: YES 29 }) 30 31 @extends SC.View 32 @extends SC.Control 33 @since SproutCore 1.0 34 */ 35 SC.ProgressView = SC.View.extend(SC.Control, 36 /** @scope SC.ProgressView.prototype */{ 37 38 /** 39 @type Array 40 @default ['sc-progress-view'] 41 @see SC.View#classNames 42 */ 43 classNames: ['sc-progress-view'], 44 45 /** 46 @type Array 47 @default ['displayValue', 'ariaValue', 'minimum', 'maximum', 'isIndeterminate', 'isRunning', 'isVisibleInWindow'] 48 @see SC.View#displayProperties 49 */ 50 displayProperties: ['displayValue', 'ariaValue', 'minimum', 'maximum', 'isIndeterminate', 'isRunning', 'isVisibleInWindow'], 51 52 /** 53 @type String 54 @default 'progressRenderDelegate' 55 */ 56 renderDelegateName: 'progressRenderDelegate', 57 58 // ........................................ 59 // PROPERTIES 60 // 61 62 /** 63 Bind this to the current value of the progress bar. Note that by default 64 an empty value will disable the progress bar and a multiple value will make 65 it indeterminate. 66 67 @type Number 68 @default 0.50 69 */ 70 value: 0.50, 71 72 /** @private */ 73 valueBindingDefault: SC.Binding.single().notEmpty(), 74 75 /** 76 @field 77 @type Number 78 @observes value 79 @observes maximum 80 @observes minimum 81 */ 82 displayValue: function(){ 83 var minimum = this.get('minimum') || 0.0, 84 maximum = this.get('maximum') || 1.0, 85 value = this.get('value') || 0.0; 86 87 // Percent value. 88 value = (value - minimum) / (maximum - minimum); 89 90 if (isNaN(value)) value = 0.0; 91 // cannot be smaller then minimum 92 if (value < 0.0) value = 0.0; 93 // cannot be larger then maximum 94 if (value > 1.0) value = 1.0; 95 96 return value; 97 }.property('value', 'maximum', 'minimum').cacheable(), 98 99 /** 100 The WAI-ARIA role for progress view. 101 102 @type String 103 @default 'progressbar' 104 @readOnly 105 */ 106 ariaRole: 'progressbar', 107 108 /** 109 The WAI-ARIA value for the progress view. This value will be passed to any 110 rendering code as-is, not converted into percentages, etc. It is computed 111 based on the original value property. 112 113 @property 114 */ 115 ariaValue: function() { 116 return this.get('value'); 117 }.property('value').cacheable(), 118 119 /** 120 The minimum value of the progress. 121 122 @type Number 123 @default 0 124 */ 125 minimum: 0, 126 127 /** @private */ 128 minimumBindingDefault: SC.Binding.single().notEmpty(), 129 130 /** 131 Optionally specify the key used to extract the minimum progress value 132 from the content object. If this is set to null then the minimum value 133 will not be derived from the content object. 134 135 @type String 136 @default null 137 */ 138 contentMinimumKey: null, 139 140 /** 141 The maximum value of the progress bar. 142 143 @type Number 144 @default 1.0 145 */ 146 maximum: 1.0, 147 148 /** @private */ 149 maximumBindingDefault: SC.Binding.single().notEmpty(), 150 151 /** 152 Optionally specify the key used to extract the maximum progress value 153 from the content object. If this is set to null then the maximum value 154 will not be derived from the content object. 155 156 @type String 157 @default null 158 */ 159 contentMaximumKey: null, 160 161 /** 162 Set to true if the item in progress is indeterminate. This may be 163 overridden by the actual value. 164 165 @type Boolean 166 @default NO 167 */ 168 isIndeterminate: NO, 169 170 /** @private */ 171 isIndeterminateBindingDefault: SC.Binding.bool(), 172 173 /** 174 Set to YES when the process is currently running. This will cause the 175 progress bar to animate, especially if it is indeterminate. 176 177 @type Boolean 178 @default NO 179 */ 180 isRunning: NO, 181 182 /** @private */ 183 isRunningBindingDefault: SC.Binding.bool(), 184 185 /** 186 Optionally specify the key used to extract the isIndeterminate value 187 from the content object. If this is set to null then the isIndeterminate 188 value will not be derived from the content object. 189 190 @type String 191 @default null 192 */ 193 contentIsIndeterminateKey: null, 194 195 // ........................................ 196 // INTERNAL SUPPORT 197 // 198 199 /** @private */ 200 contentPropertyDidChange: function(target, key) { 201 var content = this.get('content'); 202 this.beginPropertyChanges() 203 .updatePropertyFromContent('value', key, 'contentValueKey', content) 204 .updatePropertyFromContent('minimum', key, 'contentMinimumKey', content) 205 .updatePropertyFromContent('maximum', key, 'contentMaximumKey', content) 206 .updatePropertyFromContent('isIndeterminate', key, 'contentIsIndeterminateKey', content) 207 .endPropertyChanges(); 208 }, 209 210 /** @private */ 211 didCreateLayer: function() { 212 // When using the JavaScript animation, we cannot start until the layer is 213 // created. Then if we are indeterminate, running and visible in the 214 // window already, start animating. 215 if (this.get('isIndeterminate') && this.get('isRunning') && this.get('isVisibleInWindow')) { 216 this.displayDidChange(); 217 } 218 } 219 220 }); 221 222