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 6 http://www.cocos2d-x.org 7 8 Permission is hereby granted, free of charge, to any person obtaining a copy 9 of this software and associated documentation files (the "Software"), to deal 10 in the Software without restriction, including without limitation the rights 11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 copies of the Software, and to permit persons to whom the Software is 13 furnished to do so, subject to the following conditions: 14 15 The above copyright notice and this permission notice shall be included in 16 all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 THE SOFTWARE. 25 ****************************************************************************/ 26 27 /** 28 * Text field delegate 29 * @class 30 * @extends cc.Class 31 */ 32 cc.TextFieldDelegate = cc.Class.extend(/** @lends cc.TextFieldDelegate# */{ 33 /** 34 * If the sender doesn't want to attach with IME, return true; 35 * @param {cc.TextFieldTTF} sender 36 * @return {Boolean} 37 */ 38 onTextFieldAttachWithIME:function (sender) { 39 return false; 40 }, 41 42 /** 43 * If the sender doesn't want to detach with IME, return true; 44 * @param {cc.TextFieldTTF} sender 45 * @return {Boolean} 46 */ 47 onTextFieldDetachWithIME:function (sender) { 48 return false; 49 }, 50 51 /** 52 * If the sender doesn't want to insert the text, return true; 53 * @param {cc.TextFieldTTF} sender 54 * @param {String} text 55 * @param {Number} len 56 * @return {Boolean} 57 */ 58 onTextFieldInsertText:function (sender, text, len) { 59 return false 60 }, 61 62 /** 63 * If the sender doesn't want to delete the delText, return true; 64 * @param {cc.TextFieldTTF} sender 65 * @param {String} delText 66 * @param {Number} len 67 * @return {Boolean} 68 */ 69 onTextFieldDeleteBackward:function (sender, delText, len) { 70 return false; 71 }, 72 73 /** 74 * If doesn't want draw sender as default, return true. 75 * @param {cc.TextFieldTTF} sender 76 * @return {Boolean} 77 */ 78 onDraw:function (sender) { 79 return false; 80 } 81 }); 82 83 /** 84 * A simple text input field with TTF font. 85 * @class 86 * @extends cc.LabelTTF 87 * 88 * @property {cc.Node} delegate - Delegate 89 * @property {Number} charCount - <@readonly> Characators count 90 * @property {String} placeHolder - Place holder for the field 91 * @property {cc.Color} colorSpaceHolder 92 */ 93 cc.TextFieldTTF = cc.LabelTTF.extend(/** @lends cc.TextFieldTTF# */{ 94 delegate:null, 95 colorSpaceHolder:null, 96 97 _lens:null, 98 _inputText:"", 99 _placeHolder:"", 100 _charCount:0, 101 _className:"TextFieldTTF", 102 103 /** 104 * creates a cc.TextFieldTTF from a fontName, alignment, dimension and font size <br/> 105 * Constructor of cc.TextFieldTTF 106 * @param {String} placeholder 107 * @param {cc.Size} dimensions 108 * @param {Number} alignment 109 * @param {String} fontName 110 * @param {Number} fontSize 111 * @example 112 * //example 113 * // When five parameters 114 * var textField = cc.TextFieldTTF.create("<click here for input>", cc.size(100,50), cc.TEXT_ALIGNMENT_LEFT,"Arial", 32); 115 * // When three parameters 116 * var textField = cc.TextFieldTTF.create("<click here for input>", "Arial", 32); 117 */ 118 ctor:function (placeholder, dimensions, alignment, fontName, fontSize) { 119 this.colorSpaceHolder = cc.color(127, 127, 127); 120 cc.imeDispatcher.addDelegate(this); 121 cc.LabelTTF.prototype.ctor.call(this); 122 123 if(fontSize !== undefined){ 124 this.initWithPlaceHolder("", dimensions, alignment, fontName, fontSize); 125 if(placeholder) 126 this.setPlaceHolder(placeholder); 127 }else if(fontName === undefined && alignment !== undefined){ 128 this.initWithString("", arguments[1], arguments[2]); 129 if(placeholder) 130 this.setPlaceHolder(placeholder); 131 } 132 }, 133 134 /** 135 * @return {cc.Node} 136 */ 137 getDelegate:function () { 138 return this.delegate; 139 }, 140 141 /** 142 * @param {cc.Node} value 143 */ 144 setDelegate:function (value) { 145 this.delegate = value; 146 }, 147 148 /** 149 * @return {Number} 150 */ 151 getCharCount:function () { 152 return this._charCount; 153 }, 154 155 /** 156 * @return {cc.Color} 157 */ 158 getColorSpaceHolder:function () { 159 return this.colorSpaceHolder; 160 }, 161 162 /** 163 * @param {cc.Color} value 164 */ 165 setColorSpaceHolder:function (value) { 166 this.colorSpaceHolder = value; 167 }, 168 /** 169 * Initializes the cc.TextFieldTTF with a font name, alignment, dimension and font size 170 * @param {String} placeholder 171 * @param {cc.Size} dimensions 172 * @param {Number} alignment 173 * @param {String} fontName 174 * @param {Number} fontSize 175 * @return {Boolean} 176 * @example 177 * //example 178 * var textField = new cc.TextFieldTTF(); 179 * // When five parameters 180 * textField.initWithPlaceHolder("<click here for input>", cc.size(100,50), cc.TEXT_ALIGNMENT_LEFT,"Arial", 32); 181 * // When three parameters 182 * textField.initWithPlaceHolder("<click here for input>", "Arial", 32); 183 */ 184 initWithPlaceHolder:function (placeholder, dimensions, alignment, fontName, fontSize) { 185 switch (arguments.length) { 186 case 5: 187 if (placeholder) { 188 this.setPlaceHolder(placeholder); 189 } 190 return this.initWithString(this._placeHolder,fontName, fontSize, dimensions, alignment); 191 break; 192 case 3: 193 if (placeholder) { 194 this.setPlaceHolder(placeholder); 195 } 196 return this.initWithString(this._placeHolder, arguments[1], arguments[2]); 197 break; 198 default: 199 throw "Argument must be non-nil "; 200 break; 201 } 202 }, 203 204 /** 205 * Input text property 206 * @param {String} text 207 */ 208 setString:function (text) { 209 text = String(text); 210 this._inputText = text || ""; 211 212 // if there is no input text, display placeholder instead 213 if (!this._inputText.length) 214 cc.LabelTTF.prototype.setString.call(this, this._placeHolder); 215 else 216 cc.LabelTTF.prototype.setString.call(this,this._inputText); 217 this._charCount = this._inputText.length; 218 }, 219 220 /** 221 * @return {String} 222 */ 223 getString:function () { 224 return this._inputText; 225 }, 226 227 /** 228 * @param {String} text 229 */ 230 setPlaceHolder:function (text) { 231 this._placeHolder = text || ""; 232 if (!this._inputText.length) { 233 cc.LabelTTF.prototype.setString.call(this,this._placeHolder); 234 } 235 }, 236 237 /** 238 * @return {String} 239 */ 240 getPlaceHolder:function () { 241 return this._placeHolder; 242 }, 243 244 /** 245 * @param {CanvasContext} ctx 246 */ 247 draw:function (ctx) { 248 //console.log("size",this._contentSize); 249 var context = ctx || cc._renderContext; 250 if (this.delegate && this.delegate.onDraw(this)) 251 return; 252 253 if (this._inputText && this._inputText.length > 0) { 254 cc.LabelTTF.prototype.draw.call(this, context); 255 return; 256 } 257 258 // draw placeholder 259 var color = this.color; 260 this.color = this.colorSpaceHolder; 261 if(cc._renderType === cc._RENDER_TYPE_CANVAS) 262 this._updateTexture(); 263 cc.LabelTTF.prototype.draw.call(this, context); 264 this.color = color; 265 }, 266 267 visit: function(ctx){ 268 this._super(ctx); 269 }, 270 271 ////////////////////////////////////////////////////////////////////////// 272 // CCIMEDelegate interface 273 ////////////////////////////////////////////////////////////////////////// 274 /** 275 * Open keyboard and receive input text. 276 * @return {Boolean} 277 */ 278 attachWithIME:function () { 279 return cc.imeDispatcher.attachDelegateWithIME(this); 280 }, 281 282 /** 283 * End text input and close keyboard. 284 * @return {Boolean} 285 */ 286 detachWithIME:function () { 287 return cc.imeDispatcher.detachDelegateWithIME(this); 288 }, 289 290 /** 291 * @return {Boolean} 292 */ 293 canAttachWithIME:function () { 294 return (this.delegate) ? (!this.delegate.onTextFieldAttachWithIME(this)) : true; 295 }, 296 297 /** 298 * When the delegate detach with IME, this method call by CCIMEDispatcher. 299 */ 300 didAttachWithIME:function () { 301 }, 302 303 /** 304 * @return {Boolean} 305 */ 306 canDetachWithIME:function () { 307 return (this.delegate) ? (!this.delegate.onTextFieldDetachWithIME(this)) : true; 308 }, 309 310 /** 311 * When the delegate detach with IME, this method call by CCIMEDispatcher. 312 */ 313 didDetachWithIME:function () { 314 }, 315 316 /** 317 * Delete backward 318 */ 319 deleteBackward:function () { 320 var strLen = this._inputText.length; 321 if (strLen == 0) 322 return; 323 324 // get the delete byte number 325 var deleteLen = 1; // default, erase 1 byte 326 327 if (this.delegate && this.delegate.onTextFieldDeleteBackward(this, this._inputText[strLen - deleteLen], deleteLen)) { 328 // delegate don't want delete backward 329 return; 330 } 331 332 // if delete all text, show space holder string 333 if (strLen <= deleteLen) { 334 this._inputText = ""; 335 this._charCount = 0; 336 cc.LabelTTF.prototype.setString.call(this,this._placeHolder); 337 return; 338 } 339 340 // set new input text 341 this.string = this._inputText.substring(0, strLen - deleteLen); 342 }, 343 344 /** 345 * Remove delegate 346 */ 347 removeDelegate:function () { 348 cc.imeDispatcher.removeDelegate(this); 349 }, 350 351 /** 352 * @param {String} text 353 * @param {Number} len 354 */ 355 insertText:function (text, len) { 356 var sInsert = text; 357 358 // insert \n means input end 359 var pos = sInsert.indexOf('\n'); 360 if (pos > -1) { 361 sInsert = sInsert.substring(0, pos); 362 } 363 364 if (sInsert.length > 0) { 365 if (this.delegate && this.delegate.onTextFieldInsertText(this, sInsert, sInsert.length)) { 366 // delegate doesn't want insert text 367 return; 368 } 369 370 var sText = this._inputText + sInsert; 371 this._charCount = sText.length; 372 this.string = sText; 373 } 374 375 if (pos == -1) 376 return; 377 378 // '\n' has inserted, let delegate process first 379 if (this.delegate && this.delegate.onTextFieldInsertText(this, "\n", 1)) 380 return; 381 382 // if delegate hasn't process, detach with ime as default 383 this.detachWithIME(); 384 }, 385 /** 386 * @return {String} 387 */ 388 getContentText:function () { 389 return this._inputText; 390 }, 391 392 ////////////////////////////////////////////////////////////////////////// 393 // keyboard show/hide notification 394 ////////////////////////////////////////////////////////////////////////// 395 keyboardWillShow:function (info) { 396 }, 397 keyboardDidShow:function (info) { 398 }, 399 keyboardWillHide:function (info) { 400 }, 401 keyboardDidHide:function (info) { 402 } 403 }); 404 405 var _p = cc.TextFieldTTF.prototype; 406 407 // Extended properties 408 /** @expose */ 409 _p.charCount; 410 cc.defineGetterSetter(_p, "charCount", _p.getCharCount); 411 /** @expose */ 412 _p.placeHolder; 413 cc.defineGetterSetter(_p, "placeHolder", _p.getPlaceHolder, _p.setPlaceHolder); 414 415 416 /** 417 * creates a cc.TextFieldTTF from a fontName, alignment, dimension and font size 418 * @param {String} placeholder 419 * @param {cc.Size} dimensions 420 * @param {Number} alignment 421 * @param {String} fontName 422 * @param {Number} fontSize 423 * @return {cc.TextFieldTTF|Null} 424 * @example 425 * //example 426 * // When five parameters 427 * var textField = cc.TextFieldTTF.create("<click here for input>", cc.size(100,50), cc.TEXT_ALIGNMENT_LEFT,"Arial", 32); 428 * // When three parameters 429 * var textField = cc.TextFieldTTF.create("<click here for input>", "Arial", 32); 430 */ 431 cc.TextFieldTTF.create = function (placeholder, dimensions, alignment, fontName, fontSize) { 432 return new cc.TextFieldTTF(placeholder, dimensions, alignment, fontName, fontSize); 433 }; 434 435