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