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