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