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 * @param {String} placeholder 94 * @param {cc.Size} dimensions 95 * @param {Number} alignment 96 * @param {String} fontName 97 * @param {Number} fontSize 98 * 99 * @example 100 * //example 101 * // When five parameters 102 * var textField = new cc.TextFieldTTF("<click here for input>", cc.size(100,50), cc.TEXT_ALIGNMENT_LEFT,"Arial", 32); 103 * // When three parameters 104 * var textField = new cc.TextFieldTTF("<click here for input>", "Arial", 32); 105 */ 106 cc.TextFieldTTF = cc.LabelTTF.extend(/** @lends cc.TextFieldTTF# */{ 107 delegate:null, 108 colorSpaceHolder:null, 109 110 _lens:null, 111 _inputText:"", 112 _placeHolder:"", 113 _charCount:0, 114 _className:"TextFieldTTF", 115 116 /** 117 * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function. <br /> 118 * creates a cc.TextFieldTTF from a fontName, alignment, dimension and font size. 119 * @param {String} placeholder 120 * @param {cc.Size} dimensions 121 * @param {Number} alignment 122 * @param {String} fontName 123 * @param {Number} fontSize 124 */ 125 ctor:function (placeholder, dimensions, alignment, fontName, fontSize) { 126 this.colorSpaceHolder = cc.color(127, 127, 127); 127 cc.imeDispatcher.addDelegate(this); 128 cc.LabelTTF.prototype.ctor.call(this); 129 130 if(fontSize !== undefined){ 131 this.initWithPlaceHolder("", dimensions, alignment, fontName, fontSize); 132 if(placeholder) 133 this.setPlaceHolder(placeholder); 134 }else if(fontName === undefined && alignment !== undefined){ 135 this.initWithString("", arguments[1], arguments[2]); 136 if(placeholder) 137 this.setPlaceHolder(placeholder); 138 } 139 }, 140 141 /** 142 * Gets the delegate. 143 * @return {cc.Node} 144 */ 145 getDelegate:function () { 146 return this.delegate; 147 }, 148 149 /** 150 * Set the delegate. 151 * @param {cc.Node} value 152 */ 153 setDelegate:function (value) { 154 this.delegate = value; 155 }, 156 157 /** 158 * Gets the char count. 159 * @return {Number} 160 */ 161 getCharCount:function () { 162 return this._charCount; 163 }, 164 165 /** 166 * Gets the color of space holder. 167 * @return {cc.Color} 168 */ 169 getColorSpaceHolder:function () { 170 return this.colorSpaceHolder; 171 }, 172 173 /** 174 * Gets the color of space holder. 175 * @param {cc.Color} value 176 */ 177 setColorSpaceHolder:function (value) { 178 this.colorSpaceHolder = value; 179 }, 180 181 /** 182 * Initializes the cc.TextFieldTTF with a font name, alignment, dimension and font size 183 * @param {String} placeholder 184 * @param {cc.Size} dimensions 185 * @param {Number} alignment 186 * @param {String} fontName 187 * @param {Number} fontSize 188 * @return {Boolean} 189 * @example 190 * //example 191 * var textField = new cc.TextFieldTTF(); 192 * // When five parameters 193 * textField.initWithPlaceHolder("<click here for input>", cc.size(100,50), cc.TEXT_ALIGNMENT_LEFT,"Arial", 32); 194 * // When three parameters 195 * textField.initWithPlaceHolder("<click here for input>", "Arial", 32); 196 */ 197 initWithPlaceHolder:function (placeholder, dimensions, alignment, fontName, fontSize) { 198 switch (arguments.length) { 199 case 5: 200 if (placeholder) { 201 this.setPlaceHolder(placeholder); 202 } 203 return this.initWithString(this._placeHolder,fontName, fontSize, dimensions, alignment); 204 break; 205 case 3: 206 if (placeholder) { 207 this.setPlaceHolder(placeholder); 208 } 209 return this.initWithString(this._placeHolder, arguments[1], arguments[2]); 210 break; 211 default: 212 throw "Argument must be non-nil "; 213 break; 214 } 215 }, 216 217 /** 218 * Input text property 219 * @param {String} text 220 */ 221 setString:function (text) { 222 text = String(text); 223 this._inputText = text || ""; 224 225 // if there is no input text, display placeholder instead 226 if (!this._inputText.length) 227 cc.LabelTTF.prototype.setString.call(this, this._placeHolder); 228 else 229 cc.LabelTTF.prototype.setString.call(this,this._inputText); 230 this._charCount = this._inputText.length; 231 }, 232 233 /** 234 * Gets the string 235 * @return {String} 236 */ 237 getString:function () { 238 return this._inputText; 239 }, 240 241 /** 242 * Set the place holder. <br /> 243 * display this string if string equal "". 244 * @param {String} text 245 */ 246 setPlaceHolder:function (text) { 247 this._placeHolder = text || ""; 248 if (!this._inputText.length) { 249 cc.LabelTTF.prototype.setString.call(this,this._placeHolder); 250 } 251 }, 252 253 /** 254 * Gets the place holder. <br /> 255 * default display string. 256 * @return {String} 257 */ 258 getPlaceHolder:function () { 259 return this._placeHolder; 260 }, 261 262 /** 263 * Render function using the canvas 2d context or WebGL context, internal usage only, please do not call this function. 264 * @param {CanvasRenderingContext2D | WebGLRenderingContext} ctx The render context 265 */ 266 draw:function (ctx) { 267 //console.log("size",this._contentSize); 268 var context = ctx || cc._renderContext; 269 if (this.delegate && this.delegate.onDraw(this)) 270 return; 271 272 if (this._inputText && this._inputText.length > 0) { 273 cc.LabelTTF.prototype.draw.call(this, context); 274 return; 275 } 276 277 // draw placeholder 278 var color = this.color; 279 this.color = this.colorSpaceHolder; 280 if(cc._renderType === cc._RENDER_TYPE_CANVAS) 281 this._updateTexture(); 282 cc.LabelTTF.prototype.draw.call(this, context); 283 this.color = color; 284 }, 285 286 /** 287 * Recursive method that visit its children and draw them. 288 * @param {CanvasRenderingContext2D|WebGLRenderingContext} ctx 289 */ 290 visit: function(ctx){ 291 this._super(ctx); 292 }, 293 294 ////////////////////////////////////////////////////////////////////////// 295 // CCIMEDelegate interface 296 ////////////////////////////////////////////////////////////////////////// 297 /** 298 * Open keyboard and receive input text. 299 * @return {Boolean} 300 */ 301 attachWithIME:function () { 302 return cc.imeDispatcher.attachDelegateWithIME(this); 303 }, 304 305 /** 306 * End text input and close keyboard. 307 * @return {Boolean} 308 */ 309 detachWithIME:function () { 310 return cc.imeDispatcher.detachDelegateWithIME(this); 311 }, 312 313 /** 314 * Return whether to allow attach with IME. 315 * @return {Boolean} 316 */ 317 canAttachWithIME:function () { 318 return (this.delegate) ? (!this.delegate.onTextFieldAttachWithIME(this)) : true; 319 }, 320 321 /** 322 * When the delegate detach with IME, this method call by CCIMEDispatcher. 323 */ 324 didAttachWithIME:function () { 325 }, 326 327 /** 328 * Return whether to allow detach with IME. 329 * @return {Boolean} 330 */ 331 canDetachWithIME:function () { 332 return (this.delegate) ? (!this.delegate.onTextFieldDetachWithIME(this)) : true; 333 }, 334 335 /** 336 * When the delegate detach with IME, this method call by CCIMEDispatcher. 337 */ 338 didDetachWithIME:function () { 339 }, 340 341 /** 342 * Delete backward 343 */ 344 deleteBackward:function () { 345 var strLen = this._inputText.length; 346 if (strLen == 0) 347 return; 348 349 // get the delete byte number 350 var deleteLen = 1; // default, erase 1 byte 351 352 if (this.delegate && this.delegate.onTextFieldDeleteBackward(this, this._inputText[strLen - deleteLen], deleteLen)) { 353 // delegate don't want delete backward 354 return; 355 } 356 357 // if delete all text, show space holder string 358 if (strLen <= deleteLen) { 359 this._inputText = ""; 360 this._charCount = 0; 361 cc.LabelTTF.prototype.setString.call(this,this._placeHolder); 362 return; 363 } 364 365 // set new input text 366 this.string = this._inputText.substring(0, strLen - deleteLen); 367 }, 368 369 /** 370 * Remove delegate 371 */ 372 removeDelegate:function () { 373 cc.imeDispatcher.removeDelegate(this); 374 }, 375 376 /** 377 * Append the text. <br /> 378 * Input the character. 379 * @param {String} text 380 * @param {Number} len 381 */ 382 insertText:function (text, len) { 383 var sInsert = text; 384 385 // insert \n means input end 386 var pos = sInsert.indexOf('\n'); 387 if (pos > -1) { 388 sInsert = sInsert.substring(0, pos); 389 } 390 391 if (sInsert.length > 0) { 392 if (this.delegate && this.delegate.onTextFieldInsertText(this, sInsert, sInsert.length)) { 393 // delegate doesn't want insert text 394 return; 395 } 396 397 var sText = this._inputText + sInsert; 398 this._charCount = sText.length; 399 this.string = sText; 400 } 401 402 if (pos == -1) 403 return; 404 405 // '\n' has inserted, let delegate process first 406 if (this.delegate && this.delegate.onTextFieldInsertText(this, "\n", 1)) 407 return; 408 409 // if delegate hasn't process, detach with ime as default 410 this.detachWithIME(); 411 }, 412 413 /** 414 * Gets the input text. 415 * @return {String} 416 */ 417 getContentText:function () { 418 return this._inputText; 419 }, 420 421 ////////////////////////////////////////////////////////////////////////// 422 // keyboard show/hide notification 423 ////////////////////////////////////////////////////////////////////////// 424 keyboardWillShow:function (info) { 425 }, 426 keyboardDidShow:function (info) { 427 }, 428 keyboardWillHide:function (info) { 429 }, 430 keyboardDidHide:function (info) { 431 } 432 }); 433 434 var _p = cc.TextFieldTTF.prototype; 435 436 // Extended properties 437 /** @expose */ 438 _p.charCount; 439 cc.defineGetterSetter(_p, "charCount", _p.getCharCount); 440 /** @expose */ 441 _p.placeHolder; 442 cc.defineGetterSetter(_p, "placeHolder", _p.getPlaceHolder, _p.setPlaceHolder); 443 444 445 /** 446 * Please use new TextFieldTTF instead. <br /> 447 * Creates a cc.TextFieldTTF from a fontName, alignment, dimension and font size. 448 * @deprecated since v3.0 Please use new TextFieldTTF instead. 449 * @param {String} placeholder 450 * @param {cc.Size} dimensions 451 * @param {Number} alignment 452 * @param {String} fontName 453 * @param {Number} fontSize 454 * @return {cc.TextFieldTTF|Null} 455 * @example 456 * //example 457 * // When five parameters 458 * var textField = cc.TextFieldTTF.create("<click here for input>", cc.size(100,50), cc.TEXT_ALIGNMENT_LEFT,"Arial", 32); 459 * // When three parameters 460 * var textField = cc.TextFieldTTF.create("<click here for input>", "Arial", 32); 461 */ 462 cc.TextFieldTTF.create = function (placeholder, dimensions, alignment, fontName, fontSize) { 463 return new cc.TextFieldTTF(placeholder, dimensions, alignment, fontName, fontSize); 464 }; 465 466