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  * Base class for ccui.LoadingBar
 27  * @class
 28  * @extends ccui.Widget
 29  *
 30  * @property {ccui.LoadingBar.TYPE_LEFT | ccui.LoadingBar.TYPE_RIGHT}   direction   - The progress direction of loadingbar
 31  * @property {Number}               percent     - The current progress of loadingbar
 32  */
 33 ccui.LoadingBar = ccui.Widget.extend(/** @lends ccui.LoadingBar# */{
 34     _barType: null,
 35     _percent: 100,
 36     _totalLength: 0,
 37     _barRenderer: null,
 38     _renderBarTexType: null,
 39     _barRendererTextureSize: null,
 40     _scale9Enabled: false,
 41     _prevIgnoreSize: true,
 42     _capInsets: null,
 43     _textureFile: "",
 44     _isTextureLoaded: false,
 45     _className:"LoadingBar",
 46     ctor: function () {
 47         ccui.Widget.prototype.ctor.call(this);
 48         this._barType = ccui.LoadingBar.TYPE_LEFT;
 49         this._percent = 100;
 50         this._totalLength = 0;
 51         this._barRenderer = null;
 52         this._renderBarTexType = ccui.Widget.LOCAL_TEXTURE;
 53         this._barRendererTextureSize = cc.size(0, 0);
 54         this._scale9Enabled = false;
 55         this._prevIgnoreSize = true;
 56         this._capInsets = cc.rect(0, 0, 0, 0);
 57         this._textureFile = "";
 58     },
 59 
 60     initRenderer: function () {
 61         this._barRenderer = cc.Sprite.create();
 62         cc.Node.prototype.addChild.call(this, this._barRenderer, ccui.LoadingBar.RENDERER_ZORDER, -1);
 63         this._barRenderer.setAnchorPoint(0.0, 0.5);
 64     },
 65 
 66     /**
 67      * Changes the progress direction of loadingbar.
 68      * LoadingBarTypeLeft means progress left to right, LoadingBarTypeRight otherwise.
 69      * @param {ccui.LoadingBar.TYPE_LEFT | ccui.LoadingBar.TYPE_RIGHT} dir
 70      */
 71     setDirection: function (dir) {
 72         if (this._barType == dir) {
 73             return;
 74         }
 75         this._barType = dir;
 76 
 77         switch (this._barType) {
 78             case ccui.LoadingBar.TYPE_LEFT:
 79                 this._barRenderer.setAnchorPoint(0.0, 0.5);
 80                 this._barRenderer.setPosition(-this._totalLength * 0.5, 0.0);
 81                 if (!this._scale9Enabled) {
 82                     this._barRenderer.setFlippedX(false);
 83                 }
 84                 break;
 85             case ccui.LoadingBar.TYPE_RIGHT:
 86                 this._barRenderer.setAnchorPoint(1.0, 0.5);
 87                 this._barRenderer.setPosition(this._totalLength * 0.5, 0.0);
 88                 if (!this._scale9Enabled) {
 89                     this._barRenderer.setFlippedX(true);
 90                 }
 91                 break;
 92         }
 93     },
 94 
 95     /**
 96      * Gets the progress direction of loadingbar.
 97      * LoadingBarTypeLeft means progress left to right, LoadingBarTypeRight otherwise.
 98      * @returns {ccui.LoadingBar.TYPE_LEFT | ccui.LoadingBar.TYPE_RIGHT}
 99      */
100     getDirection: function () {
101         return this._barType;
102     },
103 
104     /**
105      * Load texture for loadingbar.
106      * @param {String} texture
107      * @param {ccui.Widget.LOCAL_TEXTURE|ccui.Widget.PLIST_TEXTURE} texType
108      */
109     loadTexture: function (texture, texType) {
110         if (!texture) {
111             return;
112         }
113         texType = texType || ccui.Widget.LOCAL_TEXTURE;
114         this._renderBarTexType = texType;
115         this._textureFile = texture;
116         var barRenderer = this._barRenderer;
117         switch (this._renderBarTexType) {
118             case ccui.Widget.LOCAL_TEXTURE:
119                 if(this._scale9Enabled)
120                     barRenderer.initWithFile(texture);
121                 else
122                     barRenderer.init(texture);
123                 break;
124             case ccui.Widget.PLIST_TEXTURE:
125                 barRenderer.initWithSpriteFrameName(texture);
126                 break;
127             default:
128                 break;
129         }
130         if (this._scale9Enabled){
131             barRenderer.setCapInsets(this._capInsets);
132         }
133         this.updateColorToRenderer(barRenderer);
134 
135         var textLoaded = barRenderer.textureLoaded();
136         this._isTextureLoaded = textLoaded;
137         if (!textLoaded) {
138             this._barRendererTextureSize.width = this._customSize.width;
139             this._barRendererTextureSize.height = this._customSize.height;
140             barRenderer.addLoadedEventListener(function () {
141                 this._isTextureLoaded = true;
142                 if (barRenderer.setCapInsets) {
143                     barRenderer.setCapInsets(this._capInsets);
144                 }
145                 var locSize = barRenderer.getContentSize();
146                 this._barRendererTextureSize.width = locSize.width;
147                 this._barRendererTextureSize.height = locSize.height;
148                 this.barRendererScaleChangedWithSize();
149                 this.setPercent(this._percent);
150             }, this);
151         } else {
152             var locBarSize = barRenderer.getContentSize();
153             this._barRendererTextureSize.width = locBarSize.width;
154             this._barRendererTextureSize.height = locBarSize.height;
155         }
156 
157         switch (this._barType) {
158             case ccui.LoadingBar.TYPE_LEFT:
159                 barRenderer.setAnchorPoint(0.0, 0.5);
160                 if (!this._scale9Enabled) {
161                     barRenderer.setFlippedX(false);
162                 }
163                 break;
164             case ccui.LoadingBar.TYPE_RIGHT:
165                 barRenderer.setAnchorPoint(1.0, 0.5);
166                 if (!this._scale9Enabled) {
167                     barRenderer.setFlippedX(true);
168                 }
169                 break;
170         }
171         this.barRendererScaleChangedWithSize();
172     },
173 
174     /**
175      * Sets if loadingbar is using scale9 renderer.
176      * @param {Boolean} enabled
177      */
178     setScale9Enabled: function (enabled) {
179         if (this._scale9Enabled == enabled) {
180             return;
181         }
182         this._scale9Enabled = enabled;
183         cc.Node.prototype.removeChild.call(this, this._barRenderer, true);
184         this._barRenderer = null;
185         if (this._scale9Enabled) {
186             this._barRenderer = cc.Scale9Sprite.create();
187         }
188         else {
189             this._barRenderer = cc.Sprite.create();
190         }
191         this.loadTexture(this._textureFile, this._renderBarTexType);
192         cc.Node.prototype.addChild.call(this, this._barRenderer, ccui.LoadingBar.RENDERER_ZORDER, -1);
193         if (this._scale9Enabled) {
194             var ignoreBefore = this._ignoreSize;
195             this.ignoreContentAdaptWithSize(false);
196             this._prevIgnoreSize = ignoreBefore;
197         }
198         else {
199             this.ignoreContentAdaptWithSize(this._prevIgnoreSize);
200         }
201         this.setCapInsets(this._capInsets);
202         this.setPercent(this._percent);
203     },
204 
205     /**
206      * Get  loadingBar is using scale9 renderer or not..
207      * @returns {Boolean}
208      */
209     isScale9Enabled:function(){
210         return this._scale9Enabled;
211     },
212 
213     /**
214      * Sets capinsets for loadingbar, if loadingbar is using scale9 renderer.
215      * @param {cc.Rect} capInsets
216      */
217     setCapInsets: function (capInsets) {
218         this._capInsets = capInsets;
219         if (!this._scale9Enabled) {
220             return;
221         }
222         this._barRenderer.setCapInsets(capInsets);
223     },
224 
225     /**
226      * Get cap insets for loadingBar.
227      * @returns {cc.Rect}
228      */
229     getCapInsets:function(){
230         return this._capInsets;
231     },
232 
233     /**
234      * The current progress of loadingbar
235      * @param {number} percent
236      */
237     setPercent: function (percent) {
238         if (percent < 0 || percent > 100) {
239             return;
240         }
241         if (this._totalLength <= 0) {
242             return;
243         }
244         this._percent = percent;
245         if(!this._isTextureLoaded){
246             return;
247         }
248         var res = this._percent / 100.0;
249 
250         var x = 0, y = 0;
251         if(this._renderBarTexType==ccui.Widget.PLIST_TEXTURE){
252             var barNode = this._barRenderer;
253             if (barNode) {
254                 var to = barNode.getTextureRect()._origin;
255                 x = to.x;
256                 y = to.y;
257             }
258         }
259         if (this._scale9Enabled)
260             this.setScale9Scale();
261         else
262             this._barRenderer.setTextureRect(cc.rect(x, y, this._barRendererTextureSize.width * res, this._barRendererTextureSize.height));
263     },
264 
265     /**
266      * Gets the progress direction of loadingbar.
267      * @returns {number}
268      */
269     getPercent: function () {
270         return this._percent;
271     },
272 
273     onSizeChanged: function () {
274         ccui.Widget.prototype.onSizeChanged.call(this);
275         this.barRendererScaleChangedWithSize();
276     },
277 
278     /**
279      * override "ignoreContentAdaptWithSize" method of widget.
280      * @param {Boolean}ignore
281      */
282     ignoreContentAdaptWithSize: function (ignore) {
283         if (!this._scale9Enabled || (this._scale9Enabled && !ignore)) {
284             ccui.Widget.prototype.ignoreContentAdaptWithSize.call(this, ignore);
285             this._prevIgnoreSize = ignore;
286         }
287     },
288 
289     /**
290      * override "getContentSize" method of widget.
291      * @returns {cc.Size}
292      */
293     getContentSize: function () {
294         return this._barRendererTextureSize;
295     },
296 	_getWidth: function () {
297 		return this._barRendererTextureSize.width;
298 	},
299 	_getHeight: function () {
300 		return this._barRendererTextureSize.height;
301 	},
302 
303     /**
304      * override "getContentSize" method of widget.
305      * @returns {cc.Node}
306      */
307     getVirtualRenderer: function () {
308         return this._barRenderer;
309     },
310 
311     barRendererScaleChangedWithSize: function () {
312         if (this._ignoreSize) {
313             if (!this._scale9Enabled) {
314                 this._totalLength = this._barRendererTextureSize.width;
315                 this._barRenderer.setScale(1.0);
316                 this._size.width = this._barRendererTextureSize;
317             }
318         }
319         else {
320             this._totalLength = this._size.width;
321             if (this._scale9Enabled) {
322                 this.setScale9Scale();
323             }
324             else {
325 
326                 var textureSize = this._barRendererTextureSize;
327                 if (textureSize.width <= 0.0 || textureSize.height <= 0.0) {
328                     this._barRenderer.setScale(1.0);
329                     return;
330                 }
331                 var scaleX = this._size.width / textureSize.width;
332                 var scaleY = this._size.height / textureSize.height;
333                 this._barRenderer.setScaleX(scaleX);
334                 this._barRenderer.setScaleY(scaleY);
335             }
336         }
337         switch (this._barType) {
338             case ccui.LoadingBar.TYPE_LEFT:
339                 this._barRenderer.setPosition(-this._totalLength * 0.5, 0.0);
340                 break;
341             case ccui.LoadingBar.TYPE_RIGHT:
342                 this._barRenderer.setPosition(this._totalLength * 0.5, 0.0);
343                 break;
344             default:
345                 break;
346         }
347     },
348 
349     setScale9Scale: function () {
350         var width = (this._percent) / 100 * this._totalLength;
351         this._barRenderer.setPreferredSize(cc.size(width, this._size.height));
352     },
353 
354     updateTextureColor: function () {
355         this.updateColorToRenderer(this._barRenderer);
356     },
357 
358     updateTextureOpacity: function () {
359         this.updateOpacityToRenderer(this._barRenderer);
360     },
361 
362     /**
363      * Returns the "class name" of widget.
364      * @returns {string}
365      */
366     getDescription: function () {
367         return "LoadingBar";
368     },
369 
370     createCloneInstance: function () {
371         return ccui.LoadingBar.create();
372     },
373 
374     copySpecialProperties: function (loadingBar) {
375         this._prevIgnoreSize = loadingBar._prevIgnoreSize;
376         this.setScale9Enabled(loadingBar._scale9Enabled);
377         this.loadTexture(loadingBar._textureFile, loadingBar._renderBarTexType);
378         this.setCapInsets(loadingBar._capInsets);
379         this.setPercent(loadingBar._percent);
380         this.setDirection(loadingBar._barType);
381     }
382 });
383 
384 window._p = ccui.LoadingBar.prototype;
385 
386 // Extended properties
387 /** @expose */
388 _p.direction;
389 cc.defineGetterSetter(_p, "direction", _p.getDirection, _p.setDirection);
390 /** @expose */
391 _p.percent;
392 cc.defineGetterSetter(_p, "percent", _p.getPercent, _p.setPercent);
393 
394 delete window._p;
395 
396 /**
397  * allocates and initializes a UILoadingBar.
398  * @constructs
399  * @return {ccui.LoadingBar}
400  * @example
401  * // example
402  * var uiLoadingBar = ccui.LoadingBar.create();
403  */
404 ccui.LoadingBar.create = function () {
405     var uiLoadingBar = new ccui.LoadingBar();
406     if (uiLoadingBar && uiLoadingBar.init()) {
407         return uiLoadingBar;
408     }
409     return null;
410 };
411 
412 // Constants
413 //loadingBar Type
414 ccui.LoadingBar.TYPE_LEFT = 0;
415 ccui.LoadingBar.TYPE_RIGHT = 1;
416 
417 ccui.LoadingBar.RENDERER_ZORDER = -1;