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.UICCTextField
 28  * @class
 29  * @extends cc.TextFieldTTF
 30  *
 31  * @property {Boolean}  maxLengthEnabled    - Indicate whether max length limit is enabled
 32  * @property {Number}   maxLength           - The max length of the text field
 33  * @property {Boolean}  passwordEnabled     - Indicate whether the text field is for entering password
 34  */
 35 ccui.UICCTextField = cc.TextFieldTTF.extend(/** @lends ccui.UICCTextField# */{
 36     _maxLengthEnabled: false,
 37     _maxLength: 0,
 38     _passwordEnabled: false,
 39     _passwordStyleText: "",
 40     _attachWithIME: false,
 41     _detachWithIME: false,
 42     _insertText: false,
 43     _deleteBackward: false,
 44     _className: "UICCTextField",
 45     _textFieldRendererAdaptDirty: true,
 46 
 47     ctor: function () {
 48         cc.TextFieldTTF.prototype.ctor.call(this);
 49         this._maxLengthEnabled = false;
 50         this._maxLength = 0;
 51         this._passwordEnabled = false;
 52         this._passwordStyleText = "*";
 53         this._attachWithIME = false;
 54         this._detachWithIME = false;
 55         this._insertText = false;
 56         this._deleteBackward = false;
 57     },
 58 
 59     onEnter: function () {
 60         cc.TextFieldTTF.prototype.onEnter.call(this);
 61         cc.TextFieldTTF.prototype.setDelegate.call(this, this);
 62     },
 63 
 64     //CCTextFieldDelegate
 65     onTextFieldAttachWithIME: function (sender) {
 66         this.setAttachWithIME(true);
 67         return false;
 68     },
 69 
 70     onTextFieldInsertText: function (sender, text, len) {
 71         if (len == 1 && text == "\n")
 72             return false;
 73 
 74         this.setInsertText(true);
 75         return (this._maxLengthEnabled) && (cc.TextFieldTTF.prototype.getCharCount.call(this) >= this._maxLength);
 76     },
 77 
 78     onTextFieldDeleteBackward: function (sender, delText, nLen) {
 79         this.setDeleteBackward(true);
 80         return false;
 81     },
 82 
 83     onTextFieldDetachWithIME: function (sender) {
 84         this.setDetachWithIME(true);
 85         return false;
 86     },
 87 
 88     insertText: function (text, len) {
 89         var input_text = text;
 90 
 91         if (text != "\n"){
 92             if (this._maxLengthEnabled){
 93                 var text_count = this.getString().length;
 94                 if (text_count >= this._maxLength){
 95                     // password
 96                     if (this._passwordEnabled)
 97                         this.setPasswordText(this.getString());
 98                     return;
 99                 }
100             }
101         }
102         cc.TextFieldTTF.prototype.insertText.call(this, input_text, len);
103 
104         // password
105         if (this._passwordEnabled && cc.TextFieldTTF.prototype.getCharCount.call(this) > 0)
106             this.setPasswordText(this.getString());
107     },
108 
109     deleteBackward: function () {
110         cc.TextFieldTTF.prototype.deleteBackward.call(this);
111 
112         if (cc.TextFieldTTF.prototype.getCharCount.call(this) > 0 && this._passwordEnabled)
113             this.setPasswordText(this._inputText);
114     },
115 
116     openIME: function () {
117         cc.TextFieldTTF.prototype.attachWithIME.call(this);
118     },
119 
120     closeIME: function () {
121         cc.TextFieldTTF.prototype.detachWithIME.call(this);
122     },
123 
124     setMaxLengthEnabled: function (enable) {
125         this._maxLengthEnabled = enable;
126     },
127 
128     isMaxLengthEnabled: function () {
129         return this._maxLengthEnabled;
130     },
131 
132     setMaxLength: function (length) {
133         this._maxLength = length;
134     },
135 
136     getMaxLength: function () {
137         return this._maxLength;
138     },
139 
140     getCharCount: function () {
141         return cc.TextFieldTTF.prototype.getCharCount.call(this);
142     },
143 
144     setPasswordEnabled: function (enable) {
145         this._passwordEnabled = enable;
146     },
147 
148     isPasswordEnabled: function () {
149         return this._passwordEnabled;
150     },
151 
152     setPasswordStyleText: function (styleText) {
153         if (styleText.length > 1)
154             return;
155         var header = styleText.charCodeAt(0);
156         if (header < 33 || header > 126)
157             return;
158         this._passwordStyleText = styleText;
159     },
160 
161     setPasswordText: function (text) {
162         var tempStr = "";
163         var text_count = text.length;
164         var max = text_count;
165 
166         if (this._maxLengthEnabled && text_count > this._maxLength)
167             max = this._maxLength;
168 
169         for (var i = 0; i < max; ++i)
170             tempStr += this._passwordStyleText;
171 
172         cc.LabelTTF.prototype.setString.call(this, tempStr);
173     },
174 
175     setAttachWithIME: function (attach) {
176         this._attachWithIME = attach;
177     },
178 
179     getAttachWithIME: function () {
180         return this._attachWithIME;
181     },
182 
183     setDetachWithIME: function (detach) {
184         this._detachWithIME = detach;
185     },
186 
187     getDetachWithIME: function () {
188         return this._detachWithIME;
189     },
190 
191     setInsertText: function (insert) {
192         this._insertText = insert;
193     },
194 
195     getInsertText: function () {
196         return this._insertText;
197     },
198 
199     setDeleteBackward: function (deleteBackward) {
200         this._deleteBackward = deleteBackward;
201     },
202 
203     getDeleteBackward: function () {
204         return this._deleteBackward;
205     },
206 
207     init: function () {
208         if (ccui.Widget.prototype.init.call(this)) {
209             this.setTouchEnabled(true);
210             return true;
211         }
212         return false;
213     },
214 
215     onDraw: function (sender) {
216         return false;
217     }
218 });
219 
220 ccui.UICCTextField.create = function (placeholder, fontName, fontSize) {
221     var ret = new ccui.UICCTextField();
222     if (ret && ret.initWithString("", fontName, fontSize)) {
223         if (placeholder)
224             ret.setPlaceHolder(placeholder);
225         return ret;
226     }
227     return null;
228 };
229 
230 /**
231  * Base class for ccui.TextField
232  * @class
233  * @extends ccui.Widget
234  *
235  * @property {String}   string              - The content string of the label
236  * @property {Number}   placeHolder         - The place holder of the text field
237  * @property {String}   font                - The text field font with a style string: e.g. "18px Verdana"
238  * @property {String}   fontName            - The text field font name
239  * @property {Number}   fontSize            - The text field font size
240  * @property {Boolean}  maxLengthEnabled    - Indicate whether max length limit is enabled
241  * @property {Number}   maxLength           - The max length of the text field
242  * @property {Boolean}  passwordEnabled     - Indicate whether the text field is for entering password
243  */
244 ccui.TextField = ccui.Widget.extend(/** @lends ccui.TextField# */{
245     _textFieldRenderer: null,
246     _touchWidth: 0,
247     _touchHeight: 0,
248     _useTouchArea: false,
249     _textFieldEventListener: null,
250     _textFieldEventSelector: null,
251     _passwordStyleText: "",
252     _textFieldRendererAdaptDirty: true,
253     _fontName: "",
254     _fontSize: 12,
255 
256     /**
257      * allocates and initializes a UITextField.
258      * Constructor of ccui.TextField
259      * @example
260      * // example
261      * var uiTextField = new ccui.TextField();
262      */
263     ctor: function () {
264         ccui.Widget.prototype.ctor.call(this);
265     },
266 
267     init: function(){
268         if(ccui.Widget.prototype.init.call(this)){
269             this.setTouchEnabled(true);
270             return true;
271         }
272         return false;
273     },
274 
275     onEnter: function () {
276         ccui.Widget.prototype.onEnter.call(this);
277         this.scheduleUpdate();
278     },
279 
280     _initRenderer: function () {
281         this._textFieldRenderer = ccui.UICCTextField.create("input words here", "Thonburi", 20);
282         this.addProtectedChild(this._textFieldRenderer, ccui.TextField.RENDERER_ZORDER, -1);
283     },
284 
285     /**
286      * Set touch size
287      * @param {cc.Size} size
288      */
289     setTouchSize: function (size) {
290         this._touchWidth = size.width;
291         this._touchHeight = size.height;
292     },
293 
294     setTouchAreaEnabled: function(enable){
295         this._useTouchArea = enable;
296     },
297 
298     hitTest: function(pt){
299         if (this._useTouchArea) {
300             var nsp = this.convertToNodeSpace(pt);
301             var bb = cc.rect(
302                 -this._touchWidth * this._anchorPoint.x,
303                 -this._touchHeight * this._anchorPoint.y,
304                 this._touchWidth, this._touchHeight
305             );
306 
307             return ( nsp.x >= bb.x && nsp.x <= bb.x + bb.width &&
308                 nsp.y >= bb.y && nsp.y <= bb.y + bb.height );
309         } else
310             return ccui.Widget.prototype.hitTest.call(this, pt);
311     },
312 
313     /**
314      * Get touch size.
315      * @returns {cc.Size}
316      */
317     getTouchSize: function () {
318         return cc.size(this._touchWidth, this._touchHeight);
319     },
320 
321     /**
322      *  Changes the string value of textField.
323      * @deprecated
324      * @param {String} text
325      */
326     setText: function (text) {
327         cc.log("Please use the setString");
328         this.setString(text);
329     },
330 
331     /**
332      *  Changes the string value of textField.
333      * @param {String} text
334      */
335     setString: function (text) {
336         if (!text) {
337             return;
338         }
339         text = String(text);
340         if (this.isMaxLengthEnabled()) {
341             text = text.substr(0, this.getMaxLength());
342         }
343         if (this.isPasswordEnabled()) {
344             this._textFieldRenderer.setPasswordText(text);
345             this._textFieldRenderer.setString("");
346             this._textFieldRenderer.insertText(text, text.length);
347         } else {
348             this._textFieldRenderer.setString(text);
349         }
350         this._textFieldRendererAdaptDirty = true;
351         this._updateContentSizeWithTextureSize(this._textFieldRenderer.getContentSize());
352     },
353 
354     /**
355      * @param {String} value
356      */
357     setPlaceHolder: function (value) {
358         this._textFieldRenderer.setPlaceHolder(value);
359         this._textFieldRendererAdaptDirty = true;
360         this._updateContentSizeWithTextureSize(this._textFieldRenderer.getContentSize());
361     },
362 
363     /**
364      * @returns {String}
365      */
366     getPlaceHolder: function () {
367         return this._textFieldRenderer.getPlaceHolder();
368     },
369 
370     /**
371      * Set font size for text field content
372      * @param {Number} size
373      */
374     setFontSize: function (size) {
375         this._textFieldRenderer.setFontSize(size);
376         this._fontSize = size;
377         this._textFieldRendererAdaptDirty = true;
378         this._updateContentSizeWithTextureSize(this._textFieldRenderer.getContentSize());
379     },
380 
381     /**
382      * Get font size for text field content
383      * @return {Number} size
384      */
385     getFontSize: function () {
386         return this._fontSize;
387     },
388 
389     /**
390      * Set font name for text field content
391      * @param {String} name
392      */
393     setFontName: function (name) {
394         this._textFieldRenderer.setFontName(name);
395         this._fontName = name;
396         this._textFieldRendererAdaptDirty = true;
397         this._updateContentSizeWithTextureSize(this._textFieldRenderer.getContentSize());
398     },
399 
400     /**
401      * Get font name for text field content
402      * @return {String} font name
403      */
404     getFontName: function () {
405         return this._fontName;
406     },
407 
408     /**
409      * detach with IME
410      */
411     didNotSelectSelf: function () {
412         this._textFieldRenderer.detachWithIME();
413     },
414 
415     /**
416      * get textField string value
417      * @deprecated
418      * @returns {String}
419      */
420     getStringValue: function () {
421         cc.log("Please use the getString");
422         return this.getString();
423     },
424 
425     /**
426      * get textField string value
427      * @returns {String}
428      */
429     getString: function () {
430         return this._textFieldRenderer.getString();
431     },
432 
433     getStringLength: function(){
434         return this._textFieldRenderer.getStringLength();
435     },
436 
437     /**
438      * touch began
439      * @param {cc.Point} touchPoint
440      */
441     onTouchBegan: function (touchPoint, unusedEvent) {
442         var self = this;
443         var pass = ccui.Widget.prototype.onTouchBegan.call(self, touchPoint, unusedEvent);
444         if (self._hit) {
445             setTimeout(function(){
446                 self._textFieldRenderer.attachWithIME();
447             }, 0);
448         }
449         return pass;
450     },
451 
452     /**
453      * @param {Boolean} enable
454      */
455     setMaxLengthEnabled: function (enable) {
456         this._textFieldRenderer.setMaxLengthEnabled(enable);
457     },
458 
459     /**
460      * @returns {Boolean}
461      */
462     isMaxLengthEnabled: function () {
463         return this._textFieldRenderer.isMaxLengthEnabled();
464     },
465 
466     /**
467      * @param {number} length
468      */
469     setMaxLength: function (length) {
470         this._textFieldRenderer.setMaxLength(length);
471         this.setString(this.getString());
472     },
473 
474     /**
475      * @returns {number} length
476      */
477     getMaxLength: function () {
478         return this._textFieldRenderer.getMaxLength();
479     },
480 
481     /**
482      * @param {Boolean} enable
483      */
484     setPasswordEnabled: function (enable) {
485         this._textFieldRenderer.setPasswordEnabled(enable);
486     },
487 
488     /**
489      * @returns {Boolean}
490      */
491     isPasswordEnabled: function () {
492         return this._textFieldRenderer.isPasswordEnabled();
493     },
494 
495     setPasswordStyleText: function(styleText){
496         this._textFieldRenderer.setPasswordStyleText(styleText);
497         this._passwordStyleText = styleText;
498 
499         this.setString(this.getString());
500     },
501 
502     /**
503      * @returns {String}
504      */
505     getPasswordStyleText: function () {
506         return this._passwordStyleText;
507     },
508 
509     update: function (dt) {
510         if (this.getAttachWithIME()) {
511             this._attachWithIMEEvent();
512             this.setAttachWithIME(false);
513         }
514         if (this.getDetachWithIME()) {
515             this._detachWithIMEEvent();
516             this.setDetachWithIME(false);
517         }
518         if (this.getInsertText()) {
519             this._insertTextEvent();
520             this.setInsertText(false);
521 
522             this._textFieldRendererAdaptDirty = true;
523             this._updateContentSizeWithTextureSize(this._textFieldRenderer.getContentSize());
524         }
525         if (this.getDeleteBackward()) {
526             this._deleteBackwardEvent();
527             this.setDeleteBackward(false);
528 
529             this._textFieldRendererAdaptDirty = true;
530             this._updateContentSizeWithTextureSize(this._textFieldRenderer.getContentSize());
531         }
532     },
533 
534     /**
535      * get whether attach with IME.
536      * @returns {Boolean}
537      */
538     getAttachWithIME: function () {
539         return this._textFieldRenderer.getAttachWithIME();
540     },
541 
542     /**
543      * set attach with IME.
544      * @param {Boolean} attach
545      */
546     setAttachWithIME: function (attach) {
547         this._textFieldRenderer.setAttachWithIME(attach);
548     },
549 
550     /**
551      * get whether eetach with IME.
552      * @returns {Boolean}
553      */
554     getDetachWithIME: function () {
555         return this._textFieldRenderer.getDetachWithIME();
556     },
557 
558     /**
559      * set detach with IME.
560      * @param {Boolean} detach
561      */
562     setDetachWithIME: function (detach) {
563         this._textFieldRenderer.setDetachWithIME(detach);
564     },
565 
566     /**
567      * get insertText
568      * @returns {String}
569      */
570     getInsertText: function () {
571         return this._textFieldRenderer.getInsertText();
572     },
573 
574     /**
575      * set insertText
576      * @param {String} insertText
577      */
578     setInsertText: function (insertText) {
579         this._textFieldRenderer.setInsertText(insertText);
580     },
581 
582     /**
583      * @returns {Boolean}
584      */
585     getDeleteBackward: function () {
586         return this._textFieldRenderer.getDeleteBackward();
587     },
588 
589     /**
590      * @param {Boolean} deleteBackward
591      */
592     setDeleteBackward: function (deleteBackward) {
593         this._textFieldRenderer.setDeleteBackward(deleteBackward);
594     },
595 
596     _attachWithIMEEvent: function () {
597         if (this._textFieldEventListener && this._textFieldEventSelector)
598             this._textFieldEventSelector.call(this._textFieldEventListener, this, ccui.TextField.EVENT_ATTACH_WITH_IME);
599         if (this._eventCallback)
600             this._eventCallback(this, ccui.TextField.EVENT_ATTACH_WITH_IME);
601     },
602 
603     _detachWithIMEEvent: function () {
604         if (this._textFieldEventListener && this._textFieldEventSelector)
605             this._textFieldEventSelector.call(this._textFieldEventListener, this, ccui.TextField.EVENT_DETACH_WITH_IME);
606         if (this._eventCallback)
607             this._eventCallback(this, ccui.TextField.EVENT_DETACH_WITH_IME);
608     },
609 
610     _insertTextEvent: function () {
611         if (this._textFieldEventListener && this._textFieldEventSelector)
612             this._textFieldEventSelector.call(this._textFieldEventListener, this, ccui.TextField.EVENT_INSERT_TEXT);
613         if (this._eventCallback)
614             this._eventCallback(this, ccui.TextField.EVENT_INSERT_TEXT);
615     },
616 
617     _deleteBackwardEvent: function () {
618         if (this._textFieldEventListener && this._textFieldEventSelector)
619             this._textFieldEventSelector.call(this._textFieldEventListener, this, ccui.TextField.EVENT_DELETE_BACKWARD);
620         if (this._eventCallback)
621             this._eventCallback(this, ccui.TextField.EVENT_DELETE_BACKWARD);
622     },
623 
624     /**
625      * add event listener
626      * @param {Object} target
627      * @param {Function} selector
628      * @deprecated
629      */
630     addEventListenerTextField: function (selector, target) {
631         this._textFieldEventSelector = selector;
632         this._textFieldEventListener = target;
633     },
634 
635     addEventListener: function(callback){
636         this._eventCallback = callback;
637     },
638 
639     _onSizeChanged: function () {
640         ccui.Widget.prototype._onSizeChanged.call(this);
641         this._textFieldRendererAdaptDirty = true;
642     },
643 
644     _adaptRenderers: function(){
645         if (this._textFieldRendererAdaptDirty) {
646             this._textfieldRendererScaleChangedWithSize();
647             this._textFieldRendererAdaptDirty = false;
648         }
649     },
650 
651     _textfieldRendererScaleChangedWithSize: function () {
652         if (!this._ignoreSize)
653             this._textFieldRenderer.setDimensions(this._contentSize);
654         this._textFieldRenderer.setPosition(this._contentSize.width / 2, this._contentSize.height / 2);
655     },
656 
657     getVirtualRendererSize: function(){
658         return this._textFieldRenderer.getContentSize();
659     },
660 
661     /**
662      * override "getContentSize" method of widget.
663      * @returns {cc.Node}
664      */
665     getVirtualRenderer: function () {
666         return this._textFieldRenderer;
667     },
668 
669     /**
670      * Returns the "class name" of widget.
671      * @returns {string}
672      */
673     getDescription: function () {
674         return "TextField";
675     },
676 
677     attachWithIME: function () {
678         this._textFieldRenderer.attachWithIME();
679     },
680 
681     _createCloneInstance: function () {
682         return ccui.TextField.create();
683     },
684 
685     _copySpecialProperties: function (textField) {
686         this.setString(textField._textFieldRenderer.getString());
687         this.setPlaceHolder(textField.getString());
688         this.setFontSize(textField._textFieldRenderer.getFontSize());
689         this.setFontName(textField._textFieldRenderer.getFontName());
690         this.setMaxLengthEnabled(textField.isMaxLengthEnabled());
691         this.setMaxLength(textField.getMaxLength());
692         this.setPasswordEnabled(textField.isPasswordEnabled());
693         this.setPasswordStyleText(textField._passwordStyleText);
694         this.setAttachWithIME(textField.getAttachWithIME());
695         this.setDetachWithIME(textField.getDetachWithIME());
696         this.setInsertText(textField.getInsertText());
697         this.setDeleteBackward(textField.getDeleteBackward());
698     },
699 
700     setTextAreaSize: function(size){
701         this.setContentSize(size);
702     },
703 
704     setTextHorizontalAlignment: function(alignment){
705         this._textFieldRenderer.setHorizontalAlignment(alignment);
706     },
707 
708     setTextVerticalAlignment: function(alignment){
709         this._textFieldRenderer.setVerticalAlignment(alignment);
710     },
711     _setFont: function (font) {
712         this._textFieldRender._setFont(font);
713         this._textFieldRendererAdaptDirty = true;
714     },
715 
716     _getFont: function () {
717         return this._textFieldRender._getFont();
718     }
719 });
720 
721 ccui.TextField.create = function(placeholder, fontName, fontSize){
722     var widget = new ccui.TextField();
723     if (widget && widget.init()) {
724         if(placeholder && fontName && fontSize){
725             widget.setPlaceHolder(placeholder);
726             widget.setFontName(fontName);
727             widget.setFontSize(fontSize);
728         }
729         return widget;
730     }
731     return null;
732 
733 };
734 
735 var _p = ccui.TextField.prototype;
736 
737 // Extended properties
738 /** @expose */
739 _p.string;
740 cc.defineGetterSetter(_p, "string", _p.getString, _p.setString);
741 /** @expose */
742 _p.placeHolder;
743 cc.defineGetterSetter(_p, "placeHolder", _p.getPlaceHolder, _p.setPlaceHolder);
744 /** @expose */
745 _p.font;
746 cc.defineGetterSetter(_p, "font", _p._getFont, _p._setFont);
747 /** @expose */
748 _p.fontSize;
749 cc.defineGetterSetter(_p, "fontSize", _p.getFontSize, _p.setFontSize);
750 /** @expose */
751 _p.fontName;
752 cc.defineGetterSetter(_p, "fontName", _p.getFontName, _p.setFontName);
753 /** @expose */
754 _p.maxLengthEnabled;
755 cc.defineGetterSetter(_p, "maxLengthEnabled", _p.isMaxLengthEnabled, _p.setMaxLengthEnabled);
756 /** @expose */
757 _p.maxLength;
758 cc.defineGetterSetter(_p, "maxLength", _p.getMaxLength, _p.setMaxLength);
759 /** @expose */
760 _p.passwordEnabled;
761 cc.defineGetterSetter(_p, "passwordEnabled", _p.isPasswordEnabled, _p.setPasswordEnabled);
762 
763 _p = null;
764 
765 /**
766  * allocates and initializes a UITextField.
767  * @deprecated
768  * @return {ccui.TextField}
769  * @example
770  * // example
771  * var uiTextField = ccui.TextField.create();
772  */
773 ccui.TextField.create = function () {
774     return new ccui.TextField();
775 };
776 
777 // Constants
778 //TextField event
779 ccui.TextField.EVENT_ATTACH_WITH_IME = 0;
780 ccui.TextField.EVENT_DETACH_WITH_IME = 1;
781 ccui.TextField.EVENT_INSERT_TEXT = 2;
782 ccui.TextField.EVENT_DELETE_BACKWARD = 3;
783 
784 ccui.TextField.RENDERER_ZORDER = -1;