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.NodeRGBA.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         this.updateDisplayedColor(this.getColor());
134         this.updateDisplayedOpacity(this.getOpacity());
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.NodeRGBA.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.NodeRGBA.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     },
204 
205     /**
206      * Sets capinsets for loadingbar, if loadingbar is using scale9 renderer.
207      * @param {cc.Rect} capInsets
208      */
209     setCapInsets: function (capInsets) {
210         this._capInsets = capInsets;
211         if (!this._scale9Enabled) {
212             return;
213         }
214         this._barRenderer.setCapInsets(capInsets);
215     },
216 
217     /**
218      * Changes the progress direction of loadingbar.
219      * @param {number} percent
220      */
221     setPercent: function (percent) {
222         if (percent < 0 || percent > 100) {
223             return;
224         }
225         if (this._totalLength <= 0) {
226             return;
227         }
228         this._percent = percent;
229         if(!this._isTextureLoaded){
230             return;
231         }
232         var res = this._percent / 100.0;
233 
234         var x = 0, y = 0;
235         if(this._renderBarTexType==ccs.TextureResType.plist){
236             var barNode = this._barRenderer;
237             if (barNode) {
238                 var to = barNode.getTextureRect()._origin;
239                 x = to.x;
240                 y = to.y;
241             }
242         }
243         if (this._scale9Enabled)
244             this.setScale9Scale();
245         else
246             this._barRenderer.setTextureRect(cc.rect(x, y, this._barRendererTextureSize.width * res, this._barRendererTextureSize.height));
247     },
248 
249     /**
250      * Gets the progress direction of loadingbar.
251      * @returns {number}
252      */
253     getPercent: function () {
254         return this._percent;
255     },
256 
257     onSizeChanged: function () {
258         ccs.Widget.prototype.onSizeChanged.call(this);
259         this.barRendererScaleChangedWithSize();
260     },
261 
262     /**
263      * override "ignoreContentAdaptWithSize" method of widget.
264      * @param {Boolean}ignore
265      */
266     ignoreContentAdaptWithSize: function (ignore) {
267         if (!this._scale9Enabled || (this._scale9Enabled && !ignore)) {
268             ccs.Widget.prototype.ignoreContentAdaptWithSize.call(this, ignore);
269             this._prevIgnoreSize = ignore;
270         }
271     },
272 
273     /**
274      * override "getContentSize" method of widget.
275      * @returns {cc.Size}
276      */
277     getContentSize: function () {
278         return this._barRendererTextureSize;
279     },
280 
281     /**
282      * override "getContentSize" method of widget.
283      * @returns {cc.Node}
284      */
285     getVirtualRenderer: function () {
286         return this._barRenderer;
287     },
288 
289     barRendererScaleChangedWithSize: function () {
290         if (this._ignoreSize) {
291             if (!this._scale9Enabled) {
292                 this._totalLength = this._barRendererTextureSize.width;
293                 this._barRenderer.setScale(1.0);
294                 this._size.width = this._barRendererTextureSize;
295             }
296         }
297         else {
298             this._totalLength = this._size.width;
299             if (this._scale9Enabled) {
300                 this.setScale9Scale();
301             }
302             else {
303 
304                 var textureSize = this._barRendererTextureSize;
305                 if (textureSize.width <= 0.0 || textureSize.height <= 0.0) {
306                     this._barRenderer.setScale(1.0);
307                     return;
308                 }
309                 var scaleX = this._size.width / textureSize.width;
310                 var scaleY = this._size.height / textureSize.height;
311                 this._barRenderer.setScaleX(scaleX);
312                 this._barRenderer.setScaleY(scaleY);
313             }
314         }
315         switch (this._barType) {
316             case ccs.LoadingBarType.left:
317                 this._barRenderer.setPosition(-this._totalLength * 0.5, 0.0);
318                 break;
319             case ccs.LoadingBarType.right:
320                 this._barRenderer.setPosition(this._totalLength * 0.5, 0.0);
321                 break;
322             default:
323                 break;
324         }
325     },
326 
327     setScale9Scale: function () {
328         var width = (this._percent) / 100 * this._totalLength;
329         this._barRenderer.setPreferredSize(cc.size(width, this._size.height));
330     },
331 
332     /**
333      * Returns the "class name" of widget.
334      * @returns {string}
335      */
336     getDescription: function () {
337         return "LoadingBar";
338     },
339 
340     createCloneInstance: function () {
341         return ccs.LoadingBar.create();
342     },
343 
344     copySpecialProperties: function (loadingBar) {
345         this._prevIgnoreSize = loadingBar._prevIgnoreSize;
346         this.setScale9Enabled(loadingBar._scale9Enabled);
347         this.loadTexture(loadingBar._textureFile, loadingBar._renderBarTexType);
348         this.setCapInsets(loadingBar._capInsets);
349         this.setPercent(loadingBar._percent);
350     }
351 });
352 /**
353  * allocates and initializes a UILoadingBar.
354  * @constructs
355  * @return {ccs.LoadingBar}
356  * @example
357  * // example
358  * var uiLoadingBar = ccs.LoadingBar.create();
359  */
360 ccs.LoadingBar.create = function () {
361     var uiLoadingBar = new ccs.LoadingBar();
362     if (uiLoadingBar && uiLoadingBar.init()) {
363         return uiLoadingBar;
364     }
365     return null;
366 };