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