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  * checkBoxEvent type
 27  * @type {Object}
 28  */
 29 ccs.CheckBoxEventType = {
 30     selected: 0,
 31     unselected: 1
 32 };
 33 
 34 ccs.BACKGROUNDBOXRENDERERZ = -1;
 35 ccs.BACKGROUNDBOXSELECTEDRENDERERZ = -1;
 36 ccs.FRONTCROSSRENDERERZ = -1;
 37 ccs.BACKGROUNDBOXDISABLEDRENDERER = -1;
 38 ccs.FRONTCROSSDISABLEDRENDERER = -1;
 39 /**
 40  * Base class for ccs.CheckBox
 41  * @class
 42  * @extends ccs.Widget
 43  */
 44 ccs.CheckBox = ccs.Widget.extend(/** @lends ccs.CheckBox# */{
 45     _backGroundBoxRenderer: null,
 46     _backGroundSelectedBoxRenderer: null,
 47     _frontCrossRenderer: null,
 48     _backGroundBoxDisabledRenderer: null,
 49     _frontCrossDisabledRenderer: null,
 50     _isSelected: true,
 51     _checkBoxEventListener: null,
 52     _checkBoxEventSelector: null,
 53     _backGroundTexType: null,
 54     _backGroundSelectedTexType: null,
 55     _frontCrossTexType: null,
 56     _backGroundDisabledTexType: null,
 57     _frontCrossDisabledTexType: null,
 58     _backGroundFileName: "",
 59     _backGroundSelectedFileName: "",
 60     _frontCrossFileName: "",
 61     _backGroundDisabledFileName: "",
 62     _frontCrossDisabledFileName: "",
 63     ctor: function () {
 64         ccs.Widget.prototype.ctor.call(this);
 65         this._backGroundBoxRenderer = null;
 66         this._backGroundSelectedBoxRenderer = null;
 67         this._frontCrossRenderer = null;
 68         this._backGroundBoxDisabledRenderer = null;
 69         this._frontCrossDisabledRenderer = null;
 70         this._isSelected = true;
 71         this._checkBoxEventListener = null;
 72         this._checkBoxEventSelector = null;
 73         this._backGroundTexType = ccs.TextureResType.local;
 74         this._backGroundSelectedTexType = ccs.TextureResType.local;
 75         this._frontCrossTexType = ccs.TextureResType.local;
 76         this._backGroundDisabledTexType = ccs.TextureResType.local;
 77         this._frontCrossDisabledTexType = ccs.TextureResType.local;
 78         this._backGroundFileName = "";
 79         this._backGroundSelectedFileName = "";
 80         this._frontCrossFileName = "";
 81         this._backGroundDisabledFileName = "";
 82         this._frontCrossDisabledFileName = "";
 83     },
 84     init: function () {
 85         if (ccs.Widget.prototype.init.call(this)) {
 86             this.setTouchEnabled(true);
 87             this.setSelectedState(false);
 88             return true;
 89         }
 90         return false;
 91     },
 92 
 93     initRenderer: function () {
 94         this._backGroundBoxRenderer = cc.Sprite.create();
 95         this._backGroundSelectedBoxRenderer = cc.Sprite.create();
 96         this._frontCrossRenderer = cc.Sprite.create();
 97         this._backGroundBoxDisabledRenderer = cc.Sprite.create();
 98         this._frontCrossDisabledRenderer = cc.Sprite.create();
 99         cc.Node.prototype.addChild.call(this, this._backGroundBoxRenderer, ccs.BACKGROUNDBOXRENDERERZ, -1);
100         cc.Node.prototype.addChild.call(this, this._backGroundSelectedBoxRenderer, ccs.BACKGROUNDBOXSELECTEDRENDERERZ, -1);
101         cc.Node.prototype.addChild.call(this, this._frontCrossRenderer, ccs.FRONTCROSSRENDERERZ, -1);
102         cc.Node.prototype.addChild.call(this, this._backGroundBoxDisabledRenderer, ccs.BACKGROUNDBOXDISABLEDRENDERER, -1);
103         cc.Node.prototype.addChild.call(this, this._frontCrossDisabledRenderer, ccs.FRONTCROSSDISABLEDRENDERER, -1);
104     },
105 
106     /**
107      * Load textures for checkbox.
108      * @param {String} backGround
109      * @param {String} backGroundSelected
110      * @param {String} cross
111      * @param {String} backGroundDisabled
112      * @param {String} frontCrossDisabled
113      * @param {ccs.TextureResType} texType
114      */
115     loadTextures: function (backGround, backGroundSelected, cross, backGroundDisabled, frontCrossDisabled, texType) {
116         this.loadTextureBackGround(backGround, texType);
117         this.loadTextureBackGroundSelected(backGroundSelected, texType);
118         this.loadTextureFrontCross(cross, texType);
119         this.loadTextureBackGroundDisabled(backGroundDisabled, texType);
120         this.loadTextureFrontCrossDisabled(frontCrossDisabled, texType);
121     },
122 
123     /**
124      * Load backGround texture for checkbox.
125      * @param {String} backGround
126      * @param {ccs.TextureResType} texType
127      */
128     loadTextureBackGround: function (backGround, texType) {
129         if (!backGround) {
130             return;
131         }
132         texType = texType || ccs.TextureResType.local;
133         this._backGroundFileName = backGround;
134         this._backGroundTexType = texType;
135         var bgBoxRenderer = this._backGroundBoxRenderer;
136         switch (this._backGroundTexType) {
137             case ccs.TextureResType.local:
138                 bgBoxRenderer.initWithFile(backGround);
139                 break;
140             case ccs.TextureResType.plist:
141                 bgBoxRenderer.initWithSpriteFrameName(backGround);
142                 break;
143             default:
144                 break;
145         }
146 
147         this.updateRGBAToRenderer(bgBoxRenderer);
148         this.updateAnchorPoint();
149         this.updateFlippedX();
150         this.updateFlippedY();
151         if(!bgBoxRenderer.textureLoaded()){
152             this._backGroundBoxRenderer.setContentSize(this._customSize);
153             bgBoxRenderer.addLoadedEventListener(function(){
154                 this.backGroundTextureScaleChangedWithSize();
155             },this);
156         }
157         this.backGroundTextureScaleChangedWithSize();
158     },
159     /**
160      * Load backGroundSelected texture for checkbox.
161      * @param {String} backGroundSelected
162      * @param {ccs.TextureResType} texType
163      */
164     loadTextureBackGroundSelected: function (backGroundSelected, texType) {
165         if (!backGroundSelected) {
166             return;
167         }
168         texType = texType || ccs.TextureResType.local;
169         this._backGroundSelectedFileName = backGroundSelected;
170         this._backGroundSelectedTexType = texType;
171         switch (this._backGroundSelectedTexType) {
172             case ccs.TextureResType.local:
173                 this._backGroundSelectedBoxRenderer.initWithFile(backGroundSelected);
174                 break;
175             case ccs.TextureResType.plist:
176                 this._backGroundSelectedBoxRenderer.initWithSpriteFrameName(backGroundSelected);
177                 break;
178             default:
179                 break;
180         }
181         this.updateRGBAToRenderer(this._backGroundSelectedBoxRenderer);
182         this.updateAnchorPoint();
183         this.updateFlippedX();
184         this.updateFlippedY();
185         this.backGroundSelectedTextureScaleChangedWithSize();
186     },
187 
188     /**
189      * Load cross texture for checkbox.
190      * @param {String} cross
191      * @param {ccs.TextureResType} texType
192      */
193     loadTextureFrontCross: function (cross, texType) {
194         if (!cross) {
195             return;
196         }
197         texType = texType || ccs.TextureResType.local;
198         this._frontCrossFileName = cross;
199         this._frontCrossTexType = texType;
200         switch (this._frontCrossTexType) {
201             case ccs.TextureResType.local:
202                 this._frontCrossRenderer.initWithFile(cross);
203                 break;
204             case ccs.TextureResType.plist:
205                 this._frontCrossRenderer.initWithSpriteFrameName(cross);
206                 break;
207             default:
208                 break;
209         }
210         this.updateRGBAToRenderer(this._frontCrossRenderer);
211         this.updateAnchorPoint();
212         this.updateFlippedX();
213         this.updateFlippedY();
214         this.frontCrossTextureScaleChangedWithSize();
215     },
216 
217     /**
218      * Load backGroundDisabled texture for checkbox.
219      * @param {String} backGroundDisabled
220      * @param {ccs.TextureResType} texType
221      */
222     loadTextureBackGroundDisabled: function (backGroundDisabled, texType) {
223         if (!backGroundDisabled) {
224             return;
225         }
226         texType = texType || ccs.TextureResType.local;
227         this._backGroundDisabledFileName = backGroundDisabled;
228         this._backGroundDisabledTexType = texType;
229         switch (this._backGroundDisabledTexType) {
230             case ccs.TextureResType.local:
231                 this._backGroundBoxDisabledRenderer.initWithFile(backGroundDisabled);
232                 break;
233             case ccs.TextureResType.plist:
234                 this._backGroundBoxDisabledRenderer.initWithSpriteFrameName(backGroundDisabled);
235                 break;
236             default:
237                 break;
238         }
239         this.updateRGBAToRenderer(this._backGroundBoxDisabledRenderer);
240         this.updateAnchorPoint();
241         this.updateFlippedX();
242         this.updateFlippedY();
243         this.backGroundDisabledTextureScaleChangedWithSize();
244     },
245 
246     /**
247      * Load frontCrossDisabled texture for checkbox.
248      * @param {String} frontCrossDisabled
249      * @param {ccs.TextureResType} texType
250      */
251     loadTextureFrontCrossDisabled: function (frontCrossDisabled, texType) {
252         if (!frontCrossDisabled) {
253             return;
254         }
255         texType = texType || ccs.TextureResType.local;
256         this._frontCrossDisabledFileName = frontCrossDisabled;
257         this._frontCrossDisabledTexType = texType;
258         switch (this._frontCrossDisabledTexType) {
259             case ccs.TextureResType.local:
260                 this._frontCrossDisabledRenderer.initWithFile(frontCrossDisabled);
261                 break;
262             case ccs.TextureResType.plist:
263                 this._frontCrossDisabledRenderer.initWithSpriteFrameName(frontCrossDisabled);
264                 break;
265             default:
266                 break;
267         }
268         this.updateRGBAToRenderer(this._frontCrossDisabledRenderer);
269         this.updateAnchorPoint();
270         this.updateFlippedX();
271         this.updateFlippedY();
272         this.frontCrossDisabledTextureScaleChangedWithSize();
273     },
274 
275     onTouchEnded: function (touch , event) {
276         var touchPoint = touch.getLocation();
277         this._touchEndPos.x = touchPoint.x;
278         this._touchEndPos.y = touchPoint.y;
279         if (this._focus) {
280             this.releaseUpEvent();
281             if (this._isSelected) {
282                 this.setSelectedState(false);
283                 this.unSelectedEvent();
284             }
285             else {
286                 this.setSelectedState(true);
287                 this.selectedEvent();
288             }
289         }
290         this.setFocused(false);
291         var widgetParent = this.getWidgetParent();
292         if(widgetParent){
293             widgetParent.checkChildInfo(2, this, touchPoint);
294         }
295     },
296 
297     onPressStateChangedToNormal: function () {
298         this._backGroundBoxRenderer.setVisible(true);
299         this._backGroundSelectedBoxRenderer.setVisible(false);
300         this._backGroundBoxDisabledRenderer.setVisible(false);
301         this._frontCrossDisabledRenderer.setVisible(false);
302     },
303 
304     onPressStateChangedToPressed: function () {
305         this._backGroundBoxRenderer.setVisible(false);
306         this._backGroundSelectedBoxRenderer.setVisible(true);
307         this._backGroundBoxDisabledRenderer.setVisible(false);
308         this._frontCrossDisabledRenderer.setVisible(false);
309     },
310 
311     onPressStateChangedToDisabled: function () {
312         this._backGroundBoxRenderer.setVisible(false);
313         this._backGroundSelectedBoxRenderer.setVisible(false);
314         this._backGroundBoxDisabledRenderer.setVisible(true);
315         this._frontCrossRenderer.setVisible(false);
316         if (this._isSelected) {
317             this._frontCrossDisabledRenderer.setVisible(true);
318         }
319     },
320 
321     setSelectedState: function (selected) {
322         if (selected == this._isSelected) {
323             return;
324         }
325         this._isSelected = selected;
326         this._frontCrossRenderer.setVisible(this._isSelected);
327     },
328 
329     getSelectedState: function () {
330         return this._isSelected;
331     },
332 
333     selectedEvent: function () {
334         if (this._checkBoxEventListener && this._checkBoxEventSelector) {
335             this._checkBoxEventSelector.call(this._checkBoxEventListener, this, ccs.CheckBoxEventType.selected);
336         }
337     },
338 
339     unSelectedEvent: function () {
340         if (this._checkBoxEventListener && this._checkBoxEventSelector) {
341             this._checkBoxEventSelector.call(this._checkBoxEventListener, this, ccs.CheckBoxEventType.unselected);
342         }
343     },
344 
345     /**
346      * add event listener
347      * @param {Function} selector
348      * @param {Object} target
349      */
350     addEventListenerCheckBox: function (selector, target) {
351         this._checkBoxEventSelector = selector;
352         this._checkBoxEventListener = target;
353     },
354 
355     updateFlippedX: function () {
356         this._backGroundBoxRenderer.setFlippedX(this._flippedX);
357         this._backGroundSelectedBoxRenderer.setFlippedX(this._flippedX);
358         this._frontCrossRenderer.setFlippedX(this._flippedX);
359         this._backGroundBoxDisabledRenderer.setFlippedX(this._flippedX);
360         this._frontCrossDisabledRenderer.setFlippedX(this._flippedX);
361     },
362 
363     updateFlippedY: function () {
364         this._backGroundBoxRenderer.setFlippedY(this._flippedY);
365         this._backGroundSelectedBoxRenderer.setFlippedY(this._flippedY);
366         this._frontCrossRenderer.setFlippedY(this._flippedY);
367         this._backGroundBoxDisabledRenderer.setFlippedY(this._flippedY);
368         this._frontCrossDisabledRenderer.setFlippedY(this._flippedY);
369     },
370 
371     /**
372      * override "setAnchorPoint" of widget.
373      * @param {cc.Point|Number} point The anchor point of UICheckBox or The anchor point.x of UICheckBox.
374      * @param {Number} [y] The anchor point.y of UICheckBox.
375      */
376     setAnchorPoint: function (point, y) {
377         if(y === undefined){
378 	        ccs.Widget.prototype.setAnchorPoint.call(this, point);
379 	        this._backGroundBoxRenderer.setAnchorPoint(point);
380 	        this._backGroundSelectedBoxRenderer.setAnchorPoint(point);
381 	        this._backGroundBoxDisabledRenderer.setAnchorPoint(point);
382 	        this._frontCrossRenderer.setAnchorPoint(point);
383 	        this._frontCrossDisabledRenderer.setAnchorPoint(point);
384         }else{
385 	        ccs.Widget.prototype.setAnchorPoint.call(this, point, y);
386 	        this._backGroundBoxRenderer.setAnchorPoint(point, y);
387 	        this._backGroundSelectedBoxRenderer.setAnchorPoint(point, y);
388 	        this._backGroundBoxDisabledRenderer.setAnchorPoint(point, y);
389 	        this._frontCrossRenderer.setAnchorPoint(point, y);
390 	        this._frontCrossDisabledRenderer.setAnchorPoint(point, y);
391         }
392     },
393 
394     onSizeChanged: function () {
395         ccs.Widget.prototype.onSizeChanged.call(this);
396         this.backGroundTextureScaleChangedWithSize();
397         this.backGroundSelectedTextureScaleChangedWithSize();
398         this.frontCrossTextureScaleChangedWithSize();
399         this.backGroundDisabledTextureScaleChangedWithSize();
400         this.frontCrossDisabledTextureScaleChangedWithSize();
401     },
402 
403     /**
404      * override "getContentSize" method of widget.
405      * @returns {cc.Size}
406      */
407     getContentSize: function () {
408         return this._backGroundBoxRenderer.getContentSize();
409     },
410 
411     /**
412      * override "getVirtualRenderer" method of widget.
413      * @returns {cc.Node}
414      */
415     getVirtualRenderer: function () {
416         return this._backGroundBoxRenderer;
417     },
418 
419     backGroundTextureScaleChangedWithSize: function () {
420         if (this._ignoreSize) {
421             this._backGroundBoxRenderer.setScale(1.0);
422             var locBackSize = this._backGroundBoxRenderer.getContentSize();
423             this._size.width = locBackSize.width;
424             this._size.height = locBackSize.height;
425         }
426         else {
427             var textureSize = this._backGroundBoxRenderer.getContentSize();
428             if (textureSize.width <= 0.0 || textureSize.height <= 0.0) {
429                 this._backGroundBoxRenderer.setScale(1.0);
430                 return;
431             }
432             var scaleX = this._size.width / textureSize.width;
433             var scaleY = this._size.height / textureSize.height;
434             this._backGroundBoxRenderer.setScaleX(scaleX);
435             this._backGroundBoxRenderer.setScaleY(scaleY);
436         }
437     },
438 
439     backGroundSelectedTextureScaleChangedWithSize: function () {
440         if (this._ignoreSize) {
441             this._backGroundSelectedBoxRenderer.setScale(1.0);
442         }
443         else {
444             var textureSize = this._backGroundSelectedBoxRenderer.getContentSize();
445             if (textureSize.width <= 0.0 || textureSize.height <= 0.0) {
446                 this._backGroundSelectedBoxRenderer.setScale(1.0);
447                 return;
448             }
449             var scaleX = this._size.width / textureSize.width;
450             var scaleY = this._size.height / textureSize.height;
451             this._backGroundSelectedBoxRenderer.setScaleX(scaleX);
452             this._backGroundSelectedBoxRenderer.setScaleY(scaleY);
453         }
454     },
455 
456     frontCrossTextureScaleChangedWithSize: function () {
457         if (this._ignoreSize) {
458             this._frontCrossRenderer.setScale(1.0);
459         }
460         else {
461             var textureSize = this._frontCrossRenderer.getContentSize();
462             if (textureSize.width <= 0.0 || textureSize.height <= 0.0) {
463                 this._frontCrossRenderer.setScale(1.0);
464                 return;
465             }
466             var scaleX = this._size.width / textureSize.width;
467             var scaleY = this._size.height / textureSize.height;
468             this._frontCrossRenderer.setScaleX(scaleX);
469             this._frontCrossRenderer.setScaleY(scaleY);
470         }
471     },
472 
473     backGroundDisabledTextureScaleChangedWithSize: function () {
474         if (this._ignoreSize) {
475             this._backGroundBoxDisabledRenderer.setScale(1.0);
476         }
477         else {
478             var textureSize = this._backGroundBoxDisabledRenderer.getContentSize();
479             if (textureSize.width <= 0.0 || textureSize.height <= 0.0) {
480                 this._backGroundBoxDisabledRenderer.setScale(1.0);
481                 return;
482             }
483             var scaleX = this._size.width / textureSize.width;
484             var scaleY = this._size.height / textureSize.height;
485             this._backGroundBoxDisabledRenderer.setScaleX(scaleX);
486             this._backGroundBoxDisabledRenderer.setScaleY(scaleY);
487         }
488     },
489 
490     frontCrossDisabledTextureScaleChangedWithSize: function () {
491         if (this._ignoreSize) {
492             this._frontCrossDisabledRenderer.setScale(1.0);
493         }
494         else {
495             var textureSize = this._frontCrossDisabledRenderer.getContentSize();
496             if (textureSize.width <= 0.0 || textureSize.height <= 0.0) {
497                 this._frontCrossDisabledRenderer.setScale(1.0);
498                 return;
499             }
500             var scaleX = this._size.width / textureSize.width;
501             var scaleY = this._size.height / textureSize.height;
502             this._frontCrossDisabledRenderer.setScaleX(scaleX);
503             this._frontCrossDisabledRenderer.setScaleY(scaleY);
504         }
505     },
506 
507 
508     updateTextureColor: function () {
509         this.updateColorToRenderer(this._backGroundBoxRenderer);
510         this.updateColorToRenderer(this._backGroundSelectedBoxRenderer);
511         this.updateColorToRenderer(this._frontCrossRenderer);
512         this.updateColorToRenderer(this._backGroundBoxDisabledRenderer);
513         this.updateColorToRenderer(this._frontCrossDisabledRenderer);
514     },
515 
516     updateTextureOpacity: function () {
517         this.updateOpacityToRenderer(this._backGroundBoxRenderer);
518         this.updateOpacityToRenderer(this._backGroundSelectedBoxRenderer);
519         this.updateOpacityToRenderer(this._frontCrossRenderer);
520         this.updateOpacityToRenderer(this._backGroundBoxDisabledRenderer);
521         this.updateOpacityToRenderer(this._frontCrossDisabledRenderer);
522     },
523 
524     updateTextureRGBA: function () {
525         this.updateRGBAToRenderer(this._backGroundBoxRenderer);
526         this.updateRGBAToRenderer(this._backGroundSelectedBoxRenderer);
527         this.updateRGBAToRenderer(this._frontCrossRenderer);
528         this.updateRGBAToRenderer(this._backGroundBoxDisabledRenderer);
529         this.updateRGBAToRenderer(this._frontCrossDisabledRenderer);
530     },
531     
532     /**
533      * Returns the "class name" of widget.
534      * @returns {string}
535      */
536     getDescription: function () {
537         return "CheckBox";
538     },
539 
540     createCloneInstance: function () {
541         return ccs.CheckBox.create();
542     },
543 
544     copySpecialProperties: function (uiCheckBox) {
545         this.loadTextureBackGround(uiCheckBox._backGroundFileName, uiCheckBox._backGroundTexType);
546         this.loadTextureBackGroundSelected(uiCheckBox._backGroundSelectedFileName, uiCheckBox._backGroundSelectedTexType);
547         this.loadTextureFrontCross(uiCheckBox._frontCrossFileName, uiCheckBox._frontCrossTexType);
548         this.loadTextureBackGroundDisabled(uiCheckBox._backGroundDisabledFileName, uiCheckBox._backGroundDisabledTexType);
549         this.loadTextureFrontCrossDisabled(uiCheckBox._frontCrossDisabledFileName, uiCheckBox._frontCrossDisabledTexType);
550         this.setSelectedState(uiCheckBox._isSelected);
551     }
552 });
553 /**
554  * allocates and initializes a UICheckBox.
555  * @constructs
556  * @return {ccs.CheckBox}
557  * @example
558  * // example
559  * var uiCheckBox = ccs.CheckBox.create();
560  */
561 ccs.CheckBox.create = function () {
562     var uiCheckBox = new ccs.CheckBox();
563     if (uiCheckBox && uiCheckBox.init()) {
564         return uiCheckBox;
565     }
566     return null;
567 };
568