1 /****************************************************************************
  2  Copyright (c) 2008-2010 Ricardo Quesada
  3  Copyright (c) 2011-2012 cocos2d-x.org
  4  Copyright (c) 2013-2014 Chukong Technologies Inc.
  5  Copyright (c) 2010      Lam Pham
  6 
  7  http://www.cocos2d-x.org
  8 
  9  Permission is hereby granted, free of charge, to any person obtaining a copy
 10  of this software and associated documentation files (the "Software"), to deal
 11  in the Software without restriction, including without limitation the rights
 12  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 13  copies of the Software, and to permit persons to whom the Software is
 14  furnished to do so, subject to the following conditions:
 15 
 16  The above copyright notice and this permission notice shall be included in
 17  all copies or substantial portions of the Software.
 18 
 19  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 20  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 21  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 22  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 23  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 24  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 25  THE SOFTWARE.
 26  ****************************************************************************/
 27 
 28 /**
 29  * cc.Progresstimer is a subclass of cc.Node.   <br/>
 30  * It renders the inner sprite according to the percentage.<br/>
 31  * The progress can be Radial, Horizontal or vertical.
 32  * @class
 33  * @extends cc.Node
 34  *
 35  * @property {cc.Point}     midPoint        <p>- Midpoint is used to modify the progress start position.<br/>
 36  *                                          If you're using radials type then the midpoint changes the center point<br/>
 37  *                                          If you're using bar type the the midpoint changes the bar growth<br/>
 38  *                                              it expands from the center but clamps to the sprites edge so:<br/>
 39  *                                              you want a left to right then set the midpoint all the way to cc.p(0,y)<br/>
 40  *                                              you want a right to left then set the midpoint all the way to cc.p(1,y)<br/>
 41  *                                              you want a bottom to top then set the midpoint all the way to cc.p(x,0)<br/>
 42  *                                              you want a top to bottom then set the midpoint all the way to cc.p(x,1)</p>
 43  * @property {cc.Point}     barChangeRate   - This allows the bar type to move the component at a specific rate.
 44  * @property {enum}         type            - Type of the progress timer: cc.ProgressTimer.TYPE_RADIAL|cc.ProgressTimer.TYPE_BAR.
 45  * @property {Number}       percentage      - Percentage to change progress, from 0 to 100.
 46  * @property {cc.Sprite}    sprite          - The sprite to show the progress percentage.
 47  * @property {Boolean}      reverseDir      - Indicate whether the direction is reversed.
 48  *
 49  */
 50 cc.ProgressTimer = cc.Node.extend(/** @lends cc.ProgressTimer# */{
 51     _type:null,
 52     _percentage:0.0,
 53     _sprite:null,
 54 
 55     _midPoint:null,
 56     _barChangeRate:null,
 57     _reverseDirection:false,
 58     _className:"ProgressTimer",
 59 
 60     /**
 61      * constructor of cc.cc.ProgressTimer
 62      * @function
 63      * @param {cc.Sprite} sprite
 64      */
 65     ctor: function(sprite){
 66         cc.Node.prototype.ctor.call(this);
 67 
 68         this._type = cc.ProgressTimer.TYPE_RADIAL;
 69         this._percentage = 0.0;
 70         this._midPoint = cc.p(0, 0);
 71         this._barChangeRate = cc.p(0, 0);
 72         this._reverseDirection = false;
 73         this._sprite = null;
 74 
 75         sprite && this.initWithSprite(sprite);
 76     },
 77 
 78     /**
 79      *    Midpoint is used to modify the progress start position.
 80      *    If you're using radials type then the midpoint changes the center point
 81      *    If you're using bar type the the midpoint changes the bar growth
 82      *        it expands from the center but clamps to the sprites edge so:
 83      *        you want a left to right then set the midpoint all the way to cc.p(0,y)
 84      *        you want a right to left then set the midpoint all the way to cc.p(1,y)
 85      *        you want a bottom to top then set the midpoint all the way to cc.p(x,0)
 86      *        you want a top to bottom then set the midpoint all the way to cc.p(x,1)
 87      *  @return {cc.Point}
 88      */
 89     getMidpoint:function () {
 90         return cc.p(this._midPoint.x, this._midPoint.y);
 91     },
 92 
 93     /**
 94      * Midpoint setter
 95      * @param {cc.Point} mpoint
 96      */
 97     setMidpoint:function (mpoint) {
 98         this._midPoint = cc.pClamp(mpoint, cc.p(0, 0), cc.p(1, 1));
 99     },
100 
101     /**
102      *    This allows the bar type to move the component at a specific rate
103      *    Set the component to 0 to make sure it stays at 100%.
104      *    For example you want a left to right bar but not have the height stay 100%
105      *    Set the rate to be cc.p(0,1); and set the midpoint to = cc.p(0,.5f);
106      *  @return {cc.Point}
107      */
108     getBarChangeRate:function () {
109         return cc.p(this._barChangeRate.x, this._barChangeRate.y);
110     },
111 
112     /**
113      * @param {cc.Point} barChangeRate
114      */
115     setBarChangeRate:function (barChangeRate) {
116         this._barChangeRate = cc.pClamp(barChangeRate, cc.p(0, 0), cc.p(1, 1));
117     },
118 
119     /**
120      *  Change the percentage to change progress
121      * @return {cc.ProgressTimer.TYPE_RADIAL|cc.ProgressTimer.TYPE_BAR}
122      */
123     getType:function () {
124         return this._type;
125     },
126 
127     /**
128      * Percentages are from 0 to 100
129      * @return {Number}
130      */
131     getPercentage:function () {
132         return this._percentage;
133     },
134 
135     /**
136      * The image to show the progress percentage, retain
137      * @return {cc.Sprite}
138      */
139     getSprite:function () {
140         return this._sprite;
141     },
142 
143     /**
144      * from 0-100
145      * @param {Number} percentage
146      */
147     setPercentage:function (percentage) {
148         if (this._percentage !== percentage) {
149             this._percentage = cc.clampf(percentage, 0, 100);
150             this._renderCmd._updateProgress();
151         }
152     },
153     /**
154      * only use for jsbinding
155      * @param bValue
156      */
157     setOpacityModifyRGB:function (bValue) {
158     },
159     /**
160      * only use for jsbinding
161      * @returns {boolean}
162      */
163     isOpacityModifyRGB:function () {
164         return false;
165     },
166     /**
167      * return if reverse direction
168      * @returns {boolean}
169      */
170     isReverseDirection:function () {
171         return this._reverseDirection;
172     },
173 
174     /**
175      * set color of sprite
176      * @param {cc.Color} color
177      */
178     setColor:function (color) {
179         this._sprite.color = color;
180         this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.colorDirty);
181     },
182 
183     /**
184      *  set opacity of sprite
185      * @param {Number} opacity
186      */
187     setOpacity:function (opacity) {
188         this._sprite.opacity = opacity;
189         //this._renderCmd._updateColor();
190         this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.opacityDirty);
191     },
192 
193     /**
194      * return color of sprite
195      * @return {cc.Color}
196      */
197     getColor:function () {
198         return this._sprite.color;
199     },
200 
201     /**
202      * return Opacity of sprite
203      * @return {Number}
204      */
205     getOpacity:function () {
206         return this._sprite.opacity;
207     },
208 
209     /**
210      * set reverse cc.ProgressTimer
211      * @function
212      * @param {Boolean} reverse
213      */
214     setReverseProgress: function(reverse){
215         if (this._reverseDirection !== reverse){
216             this._reverseDirection = reverse;
217             this._renderCmd.releaseData();
218         }
219     },
220 
221     /**
222      * set sprite for cc.ProgressTimer
223      * @function
224      * @param {cc.Sprite} sprite
225      */
226     setSprite: function(sprite){
227         if (this._sprite !== sprite) {
228             this._sprite = sprite;
229             if(sprite)
230                 this.setContentSize(sprite.width,sprite.height);
231             else
232                 this.setContentSize(0,0);
233             this._renderCmd.releaseData();
234         }
235     },
236 
237     /**
238      * set Progress type of cc.ProgressTimer
239      * @function
240      * @param {cc.ProgressTimer.TYPE_RADIAL|cc.ProgressTimer.TYPE_BAR} type
241      */
242     setType: function(type){
243         if (type !== this._type){
244             this._type = type;
245             this._renderCmd.releaseData();
246         }
247     },
248 
249     /**
250      * Reverse Progress setter
251      * @function
252      * @param {Boolean} reverse
253      */
254     setReverseDirection: function(reverse){
255         if (this._reverseDirection !== reverse){
256             this._reverseDirection = reverse;
257             this._renderCmd.releaseData();
258         }
259     },
260 
261     /**
262      * Initializes a progress timer with the sprite as the shape the timer goes through
263      * @function
264      * @param {cc.Sprite} sprite
265      * @return {Boolean}
266      */
267     initWithSprite: function(sprite){
268         this.percentage = 0;
269         this.setAnchorPoint(0.5,0.5);
270 
271         this._type = cc.ProgressTimer.TYPE_RADIAL;
272         this._reverseDirection = false;
273         this.midPoint = cc.p(0.5, 0.5);
274         this.barChangeRate = cc.p(1, 1);
275         this.setSprite(sprite);
276         this._renderCmd.initCmd();
277         return true;
278     },
279 
280     _createRenderCmd: function(){
281         if(cc._renderType === cc._RENDER_TYPE_CANVAS)
282             return new cc.ProgressTimer.CanvasRenderCmd(this);
283         else
284             return new cc.ProgressTimer.WebGLRenderCmd(this);
285     }
286 });
287 
288 // Extended properties
289 var _p = cc.ProgressTimer.prototype;
290 
291 /** @expose */
292 _p.midPoint;
293 cc.defineGetterSetter(_p, "midPoint", _p.getMidpoint, _p.setMidpoint);
294 /** @expose */
295 _p.barChangeRate;
296 cc.defineGetterSetter(_p, "barChangeRate", _p.getBarChangeRate, _p.setBarChangeRate);
297 /** @expose */
298 _p.type;
299 cc.defineGetterSetter(_p, "type", _p.getType, _p.setType);
300 /** @expose */
301 _p.percentage;
302 cc.defineGetterSetter(_p, "percentage", _p.getPercentage, _p.setPercentage);
303 /** @expose */
304 _p.sprite;
305 cc.defineGetterSetter(_p, "sprite", _p.getSprite, _p.setSprite);
306 /** @expose */
307 _p.reverseDir;
308 cc.defineGetterSetter(_p, "reverseDir", _p.isReverseDirection, _p.setReverseDirection);
309 
310 
311 /**
312  * create a progress timer object with image file name that renders the inner sprite according to the percentage
313  * @deprecated since v3.0,please use new cc.ProgressTimer(sprite) instead.
314  * @param {cc.Sprite} sprite
315  * @return {cc.ProgressTimer}
316  */
317 cc.ProgressTimer.create = function (sprite) {
318     return new cc.ProgressTimer(sprite);
319 };
320 
321 /**
322  * @constant
323  * @type Number
324  */
325 cc.ProgressTimer.TEXTURE_COORDS_COUNT = 4;
326 
327 /**
328  * @constant
329  * @type Number
330  */
331 cc.ProgressTimer.TEXTURE_COORDS = 0x4b;
332 
333 /**
334  * Radial Counter-Clockwise
335  * @type Number
336  * @constant
337  */
338 cc.ProgressTimer.TYPE_RADIAL = 0;
339 
340 /**
341  * Bar
342  * @type Number
343  * @constant
344  */
345 cc.ProgressTimer.TYPE_BAR = 1;
346