1 /****************************************************************************
  2  Copyright (c) 2010-2012 cocos2d-x.org
  3 
  4  http://www.cocos2d-x.org
  5 
  6  Permission is hereby granted, free of charge, to any person obtaining a copy
  7  of this software and associated documentation files (the "Software"), to deal
  8  in the Software without restriction, including without limitation the rights
  9  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 10  copies of the Software, and to permit persons to whom the Software is
 11  furnished to do so, subject to the following conditions:
 12 
 13  The above copyright notice and this permission notice shall be included in
 14  all copies or substantial portions of the Software.
 15 
 16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 19  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 21  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 22  THE SOFTWARE.
 23  ****************************************************************************/
 24 
 25 /**
 26  * loadingBar type
 27  * @type {Object}
 28  */
 29 ccs.LoadingBarType = { left: 0, right: 1};
 30 
 31 ccs.BARRENDERERZ = -1;
 32 /**
 33  * Base class for ccs.LoadingBar
 34  * @class
 35  * @extends ccs.Widget
 36  */
 37 ccs.LoadingBar = ccs.Widget.extend(/** @lends ccs.LoadingBar# */{
 38     _barType: null,
 39     _percent: 100,
 40     _totalLength: 0,
 41     _barRenderer: null,
 42     _renderBarTexType: null,
 43     _barRendererTextureSize: null,
 44     _scale9Enabled: false,
 45     _prevIgnoreSize: true,
 46     _capInsets: null,
 47     _textureFile: "",
 48     _isTextureLoaded: false,
 49     ctor: function () {
 50         ccs.Widget.prototype.ctor.call(this);
 51         this._barType = ccs.LoadingBarType.left;
 52         this._percent = 100;
 53         this._totalLength = 0;
 54         this._barRenderer = null;
 55         this._renderBarTexType = ccs.TextureResType.local;
 56         this._barRendererTextureSize = cc.size(0, 0);
 57         this._scale9Enabled = false;
 58         this._prevIgnoreSize = true;
 59         this._capInsets = cc.rect(0, 0, 0, 0);
 60         this._textureFile = "";
 61     },
 62 
 63     initRenderer: function () {
 64         this._barRenderer = cc.Sprite.create();
 65         cc.Node.prototype.addChild.call(this, this._barRenderer, ccs.BARRENDERERZ, -1);
 66         this._barRenderer.setAnchorPoint(0.0, 0.5);
 67     },
 68 
 69     /**
 70      * Changes the progress direction of loadingbar.
 71      * LoadingBarTypeLeft means progress left to right, LoadingBarTypeRight otherwise.
 72      * @param {ccs.LoadingBarType} dir
 73      */
 74     setDirection: function (dir) {
 75         if (this._barType == dir) {
 76             return;
 77         }
 78         this._barType = dir;
 79 
 80         switch (this._barType) {
 81             case ccs.LoadingBarType.left:
 82                 this._barRenderer.setAnchorPoint(0.0, 0.5);
 83                 this._barRenderer.setPosition(-this._totalLength * 0.5, 0.0);
 84                 if (!this._scale9Enabled) {
 85                     this._barRenderer.setFlippedX(false);
 86                 }
 87                 break;
 88             case ccs.LoadingBarType.right:
 89                 this._barRenderer.setAnchorPoint(1.0, 0.5);
 90                 this._barRenderer.setPosition(this._totalLength * 0.5, 0.0);
 91                 if (!this._scale9Enabled) {
 92                     this._barRenderer.setFlippedX(true);
 93                 }
 94                 break;
 95         }
 96     },
 97 
 98     /**
 99      * Gets the progress direction of loadingbar.
100      * LoadingBarTypeLeft means progress left to right, LoadingBarTypeRight otherwise.
101      * @returns {ccs.LoadingBarType}
102      */
103     getDirection: function () {
104         return this._barType;
105     },
106 
107     /**
108      * Load texture for loadingbar.
109      * @param {String} texture
110      * @param {ccs.TextureResType} texType
111      */
112     loadTexture: function (texture, texType) {
113         if (!texture) {
114             return;
115         }
116         texType = texType || ccs.TextureResType.local;
117         this._renderBarTexType = texType;
118         this._textureFile = texture;
119         var barRenderer = this._barRenderer;
120         switch (this._renderBarTexType) {
121             case ccs.TextureResType.local:
122                 barRenderer.initWithFile(texture);
123                 break;
124             case ccs.TextureResType.plist:
125                 barRenderer.initWithSpriteFrameName(texture);
126                 break;
127             default:
128                 break;
129         }
130         if (this._scale9Enabled){
131             barRenderer.setCapInsets(this._capInsets);
132         }
133         
134         this.updateRGBAToRenderer(barRenderer);
135 
136         var textLoaded = barRenderer.textureLoaded();
137         this._isTextureLoaded = textLoaded;
138         if (!textLoaded) {
139             this._barRendererTextureSize.width = this._customSize.width;
140             this._barRendererTextureSize.height = this._customSize.height;
141             barRenderer.addLoadedEventListener(function () {
142                 this._isTextureLoaded = true;
143                 if (barRenderer.setCapInsets) {
144                     barRenderer.setCapInsets(this._capInsets);
145                 }
146                 var locSize = barRenderer.getContentSize();
147                 this._barRendererTextureSize.width = locSize.width;
148                 this._barRendererTextureSize.height = locSize.height;
149                 this.barRendererScaleChangedWithSize();
150                 this.setPercent(this._percent);
151             }, this);
152         } else {
153             var locBarSize = barRenderer.getContentSize();
154             this._barRendererTextureSize.width = locBarSize.width;
155             this._barRendererTextureSize.height = locBarSize.height;
156         }
157 
158         switch (this._barType) {
159             case ccs.LoadingBarType.left:
160                 barRenderer.setAnchorPoint(0.0, 0.5);
161                 if (!this._scale9Enabled) {
162                     barRenderer.setFlippedX(false);
163                 }
164                 break;
165             case ccs.LoadingBarType.right:
166                 barRenderer.setAnchorPoint(1.0, 0.5);
167                 if (!this._scale9Enabled) {
168                     barRenderer.setFlippedX(true);
169                 }
170                 break;
171         }
172         this.barRendererScaleChangedWithSize();
173     },
174 
175     /**
176      * Sets if loadingbar is using scale9 renderer.
177      * @param {Boolean} enabled
178      */
179     setScale9Enabled: function (enabled) {
180         if (this._scale9Enabled == enabled) {
181             return;
182         }
183         this._scale9Enabled = enabled;
184         cc.Node.prototype.removeChild.call(this, this._barRenderer, true);
185         this._barRenderer = null;
186         if (this._scale9Enabled) {
187             this._barRenderer = cc.Scale9Sprite.create();
188         }
189         else {
190             this._barRenderer = cc.Sprite.create();
191         }
192         this.loadTexture(this._textureFile, this._renderBarTexType);
193         cc.Node.prototype.addChild.call(this, this._barRenderer, ccs.BARRENDERERZ, -1);
194         if (this._scale9Enabled) {
195             var ignoreBefore = this._ignoreSize;
196             this.ignoreContentAdaptWithSize(false);
197             this._prevIgnoreSize = ignoreBefore;
198         }
199         else {
200             this.ignoreContentAdaptWithSize(this._prevIgnoreSize);
201         }
202         this.setCapInsets(this._capInsets);
203         this.setPercent(this._percent);
204     },
205 
206     /**
207      * Get  loadingBar is using scale9 renderer or not..
208      * @returns {Boolean}
209      */
210     isScale9Enabled:function(){
211         return this._scale9Enabled;
212     },
213 
214     /**
215      * Sets capinsets for loadingbar, if loadingbar is using scale9 renderer.
216      * @param {cc.Rect} capInsets
217      */
218     setCapInsets: function (capInsets) {
219         this._capInsets = capInsets;
220         if (!this._scale9Enabled) {
221             return;
222         }
223         this._barRenderer.setCapInsets(capInsets);
224     },
225 
226     /**
227      * Get cap insets for loadingBar.
228      * @returns {cc.Rect}
229      */
230     getCapInsets:function(){
231         return this._capInsets;
232     },
233 
234     /**
235      * Changes the progress direction of loadingbar.
236      * @param {number} percent
237      */
238     setPercent: function (percent) {
239         if (percent < 0 || percent > 100) {
240             return;
241         }
242         if (this._totalLength <= 0) {
243             return;
244         }
245         this._percent = percent;
246         if(!this._isTextureLoaded){
247             return;
248         }
249         var res = this._percent / 100.0;
250 
251         var x = 0, y = 0;
252         if(this._renderBarTexType==ccs.TextureResType.plist){
253             var barNode = this._barRenderer;
254             if (barNode) {
255                 var to = barNode.getTextureRect()._origin;
256                 x = to.x;
257                 y = to.y;
258             }
259         }
260         if (this._scale9Enabled)
261             this.setScale9Scale();
262         else
263             this._barRenderer.setTextureRect(cc.rect(x, y, this._barRendererTextureSize.width * res, this._barRendererTextureSize.height));
264     },
265 
266     /**
267      * Gets the progress direction of loadingbar.
268      * @returns {number}
269      */
270     getPercent: function () {
271         return this._percent;
272     },
273 
274     onSizeChanged: function () {
275         ccs.Widget.prototype.onSizeChanged.call(this);
276         this.barRendererScaleChangedWithSize();
277     },
278 
279     /**
280      * override "ignoreContentAdaptWithSize" method of widget.
281      * @param {Boolean}ignore
282      */
283     ignoreContentAdaptWithSize: function (ignore) {
284         if (!this._scale9Enabled || (this._scale9Enabled && !ignore)) {
285             ccs.Widget.prototype.ignoreContentAdaptWithSize.call(this, ignore);
286             this._prevIgnoreSize = ignore;
287         }
288     },
289 
290     /**
291      * override "getContentSize" method of widget.
292      * @returns {cc.Size}
293      */
294     getContentSize: function () {
295         return this._barRendererTextureSize;
296     },
297 
298     /**
299      * override "getContentSize" method of widget.
300      * @returns {cc.Node}
301      */
302     getVirtualRenderer: function () {
303         return this._barRenderer;
304     },
305 
306     barRendererScaleChangedWithSize: function () {
307         if (this._ignoreSize) {
308             if (!this._scale9Enabled) {
309                 this._totalLength = this._barRendererTextureSize.width;
310                 this._barRenderer.setScale(1.0);
311                 this._size.width = this._barRendererTextureSize;
312             }
313         }
314         else {
315             this._totalLength = this._size.width;
316             if (this._scale9Enabled) {
317                 this.setScale9Scale();
318             }
319             else {
320 
321                 var textureSize = this._barRendererTextureSize;
322                 if (textureSize.width <= 0.0 || textureSize.height <= 0.0) {
323                     this._barRenderer.setScale(1.0);
324                     return;
325                 }
326                 var scaleX = this._size.width / textureSize.width;
327                 var scaleY = this._size.height / textureSize.height;
328                 this._barRenderer.setScaleX(scaleX);
329                 this._barRenderer.setScaleY(scaleY);
330             }
331         }
332         switch (this._barType) {
333             case ccs.LoadingBarType.left:
334                 this._barRenderer.setPosition(-this._totalLength * 0.5, 0.0);
335                 break;
336             case ccs.LoadingBarType.right:
337                 this._barRenderer.setPosition(this._totalLength * 0.5, 0.0);
338                 break;
339             default:
340                 break;
341         }
342     },
343 
344     setScale9Scale: function () {
345         var width = (this._percent) / 100 * this._totalLength;
346         this._barRenderer.setPreferredSize(cc.size(width, this._size.height));
347     },
348 
349     updateTextureColor: function () {
350         this.updateColorToRenderer(this._barRenderer);
351     },
352 
353     updateTextureOpacity: function () {
354         this.updateOpacityToRenderer(this._barRenderer);
355     },
356 
357     updateTextureRGBA: function () {
358         this.updateRGBAToRenderer(this._barRenderer);
359     },
360     
361     /**
362      * Returns the "class name" of widget.
363      * @returns {string}
364      */
365     getDescription: function () {
366         return "LoadingBar";
367     },
368 
369     createCloneInstance: function () {
370         return ccs.LoadingBar.create();
371     },
372 
373     copySpecialProperties: function (loadingBar) {
374         this._prevIgnoreSize = loadingBar._prevIgnoreSize;
375         this.setScale9Enabled(loadingBar._scale9Enabled);
376         this.loadTexture(loadingBar._textureFile, loadingBar._renderBarTexType);
377         this.setCapInsets(loadingBar._capInsets);
378         this.setPercent(loadingBar._percent);
379         this.setDirection(loadingBar._barType);
380     }
381 });
382 /**
383  * allocates and initializes a UILoadingBar.
384  * @constructs
385  * @return {ccs.LoadingBar}
386  * @example
387  * // example
388  * var uiLoadingBar = ccs.LoadingBar.create();
389  */
390 ccs.LoadingBar.create = function () {
391     var uiLoadingBar = new ccs.LoadingBar();
392     if (uiLoadingBar && uiLoadingBar.init()) {
393         return uiLoadingBar;
394     }
395     return null;
396 };