1 /**************************************************************************** 2 Copyright (c) 2010-2012 cocos2d-x.org 3 Copyright (c) 2012 James Chen 4 5 http://www.cocos2d-x.org 6 7 Permission is hereby granted, free of charge, to any person obtaining a copy 8 of this software and associated documentation files (the "Software"), to deal 9 in the Software without restriction, including without limitation the rights 10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 copies of the Software, and to permit persons to whom the Software is 12 furnished to do so, subject to the following conditions: 13 14 The above copyright notice and this permission notice shall be included in 15 all copies or substantial portions of the Software. 16 17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 THE SOFTWARE. 24 ****************************************************************************/ 25 26 /** 27 * @constant 28 * @type Number 29 */ 30 cc.KEYBOARD_RETURNTYPE_DEFAULT = 0; 31 32 /** 33 * @constant 34 * @type Number 35 */ 36 cc.KEYBOARD_RETURNTYPE_DONE = 1; 37 38 /** 39 * @constant 40 * @type Number 41 */ 42 cc.KEYBOARD_RETURNTYPE_SEND = 2; 43 44 /** 45 * @constant 46 * @type Number 47 */ 48 cc.KEYBOARD_RETURNTYPE_SEARCH = 3; 49 50 /** 51 * @constant 52 * @type Number 53 */ 54 cc.KEYBOARD_RETURNTYPE_GO = 4; 55 56 /** 57 * The EditBoxInputMode defines the type of text that the user is allowed * to enter. 58 * @constant 59 * @type Number 60 */ 61 cc.EDITBOX_INPUT_MODE_ANY = 0; 62 63 /** 64 * The user is allowed to enter an e-mail address. 65 * @constant 66 * @type Number 67 */ 68 cc.EDITBOX_INPUT_MODE_EMAILADDR = 1; 69 70 /** 71 * The user is allowed to enter an integer value. 72 * @constant 73 * @type Number 74 */ 75 cc.EDITBOX_INPUT_MODE_NUMERIC = 2; 76 77 /** 78 * The user is allowed to enter a phone number. 79 * @constant 80 * @type Number 81 */ 82 cc.EDITBOX_INPUT_MODE_PHONENUMBER = 3; 83 84 /** 85 * The user is allowed to enter a URL. 86 * @constant 87 * @type Number 88 */ 89 cc.EDITBOX_INPUT_MODE_URL = 4; 90 91 /** 92 * The user is allowed to enter a real number value. 93 * This extends kEditBoxInputModeNumeric by allowing a decimal point. 94 * @constant 95 * @type Number 96 */ 97 cc.EDITBOX_INPUT_MODE_DECIMAL = 5; 98 99 /** 100 * The user is allowed to enter any text, except for line breaks. 101 * @constant 102 * @type Number 103 */ 104 cc.EDITBOX_INPUT_MODE_SINGLELINE = 6; 105 106 /** 107 * Indicates that the text entered is confidential data that should be 108 * obscured whenever possible. This implies EDIT_BOX_INPUT_FLAG_SENSITIVE. 109 * @constant 110 * @type Number 111 */ 112 cc.EDITBOX_INPUT_FLAG_PASSWORD = 0; 113 114 /** 115 * Indicates that the text entered is sensitive data that the 116 * implementation must never store into a dictionary or table for use 117 * in predictive, auto-completing, or other accelerated input schemes. 118 * A credit card number is an example of sensitive data. 119 * @constant 120 * @type Number 121 */ 122 cc.EDITBOX_INPUT_FLAG_SENSITIVE = 1; 123 124 /** 125 * This flag is a hint to the implementation that during text editing, 126 * the initial letter of each word should be capitalized. 127 * @constant 128 * @type Number 129 */ 130 cc.EDITBOX_INPUT_FLAG_INITIAL_CAPS_WORD = 2; 131 132 /** 133 * This flag is a hint to the implementation that during text editing, 134 * the initial letter of each sentence should be capitalized. 135 * @constant 136 * @type Number 137 */ 138 cc.EDITBOX_INPUT_FLAG_INITIAL_CAPS_SENTENCE = 3; 139 140 /** 141 * Capitalize all characters automatically. 142 * @constant 143 * @type Number 144 */ 145 cc.EDITBOX_INPUT_FLAG_INITIAL_CAPS_ALL_CHARACTERS = 4; 146 147 cc.EditBoxDelegate = cc.Class.extend({ 148 /** 149 * This method is called when an edit box gains focus after keyboard is shown. 150 * @param {cc.EditBox} sender 151 */ 152 editBoxEditingDidBegin: function (sender) { 153 }, 154 155 /** 156 * This method is called when an edit box loses focus after keyboard is hidden. 157 * @param {cc.EditBox} sender 158 */ 159 editBoxEditingDidEnd: function (sender) { 160 }, 161 162 /** 163 * This method is called when the edit box text was changed. 164 * @param {cc.EditBox} sender 165 * @param {String} text 166 */ 167 editBoxTextChanged: function (sender, text) { 168 }, 169 170 /** 171 * This method is called when the return button was pressed or the outside area of keyboard was touched. 172 * @param {cc.EditBox} sender 173 */ 174 editBoxReturn: function (sender) { 175 } 176 }); 177 178 /** 179 * <p>cc.EditBox is a brief Class for edit box.<br/> 180 * You can use this widget to gather small amounts of text from the user.</p> 181 * 182 * @class 183 * @extends cc.ControlButton 184 * 185 * @property {String} string - Content string of edit box 186 * @property {String} maxLength - Max length of the content string 187 * @property {String} font - <@writeonly> Config font of edit box 188 * @property {String} fontName - <@writeonly> Config font name of edit box 189 * @property {Number} fontSize - <@writeonly> Config font size of edit box 190 * @property {cc.Color} fontColor - <@writeonly> Config font color of edit box 191 * @property {String} placeHolder - Place holder of edit box 192 * @property {String} placeHolderFont - <@writeonly> Config font of place holder 193 * @property {String} placeHolderFontName - <@writeonly> Config font name of place holder 194 * @property {Number} placeHolderFontSize - <@writeonly> Config font size of place holder 195 * @property {cc.Color} placeHolderFontColor - <@writeonly> Config font color of place holder 196 * @property {Number} inputFlag - <@writeonly> Input flag of edit box, one of the EditBoxInputFlag constants. e.g.cc.EDITBOX_INPUT_FLAG_PASSWORD 197 * @property {Object} delegate - <@writeonly> Delegate of edit box 198 * @property {Number} inputMode - <@writeonly> Input mode of the edit box. Value should be one of the EditBoxInputMode constants. 199 * @property {Number} returnType - <@writeonly> Return type of edit box, value should be one of the KeyboardReturnType constants. 200 * 201 */ 202 cc.EditBox = cc.ControlButton.extend({ 203 _domInputSprite: null, 204 205 _delegate: null, 206 _editBoxInputMode: cc.EDITBOX_INPUT_MODE_ANY, 207 _editBoxInputFlag: cc.EDITBOX_INPUT_FLAG_SENSITIVE, 208 _keyboardReturnType: cc.KEYBOARD_RETURNTYPE_DEFAULT, 209 210 _text: "", 211 _placeholderText: "", 212 _textColor: null, 213 _placeholderColor: null, 214 _maxLength: 50, 215 _adjustHeight: 18, 216 217 _edTxt: null, 218 _edFontSize: 14, 219 _edFontName: "Arial", 220 221 _placeholderFontName: "", 222 _placeholderFontSize: 14, 223 224 _tooltip: false, 225 _className:"EditBox", 226 227 /** 228 * * Constructor. 229 * */ 230 ctor: function (boxSize) { 231 cc.ControlButton.prototype.ctor.call(this); 232 233 this._textColor = cc.color.WHITE; 234 this._placeholderColor = cc.color.GRAY; 235 this.setContentSize(boxSize); 236 this._domInputSprite = new cc.Sprite(); 237 this._domInputSprite.draw = function(){ }; //redefine draw function 238 this.addChild(this._domInputSprite); 239 var selfPointer = this; 240 this._edTxt = document.createElement("input"); 241 this._edTxt.type = "text"; 242 this._edTxt.style.fontSize = this._edFontSize + "px"; 243 this._edTxt.style.color = "#000000"; 244 this._edTxt.style.border = 0; 245 this._edTxt.style.background = "transparent"; 246 //this._edTxt.style.paddingLeft = "2px"; 247 this._edTxt.style.width = "100%"; 248 this._edTxt.style.height = "100%"; 249 this._edTxt.style.active = 0; 250 this._edTxt.style.outline = "medium"; 251 252 // TODO the event listener will be remove when EditBox removes from parent. 253 this._edTxt.addEventListener("input", function () { 254 if (selfPointer._delegate && selfPointer._delegate.editBoxTextChanged) 255 selfPointer._delegate.editBoxTextChanged(selfPointer, this.value); 256 }); 257 this._edTxt.addEventListener("keypress", function (e) { 258 if (e.keyCode === cc.KEY.enter) { 259 e.stopPropagation(); 260 e.preventDefault(); 261 cc._canvas.focus(); 262 } 263 }); 264 this._edTxt.addEventListener("focus", function () { 265 if (this.value == selfPointer._placeholderText) { 266 this.value = ""; 267 this.style.fontSize = selfPointer._edFontSize + "px" ; 268 this.style.color = cc.colorToHex(selfPointer._textColor); 269 } 270 if (selfPointer._delegate && selfPointer._delegate.editBoxEditingDidBegin) 271 selfPointer._delegate.editBoxEditingDidBegin(selfPointer); 272 }); 273 this._edTxt.addEventListener("blur", function () { 274 if (this.value == "") { 275 this.value = selfPointer._placeholderText; 276 this.style.fontSize = selfPointer._placeholderFontSize + "px" ; 277 this.style.color = cc.colorToHex(selfPointer._placeholderColor); 278 } 279 if (selfPointer._delegate && selfPointer._delegate.editBoxEditingDidEnd) 280 selfPointer._delegate.editBoxEditingDidEnd(selfPointer); 281 if (selfPointer._delegate && selfPointer._delegate.editBoxReturn) 282 selfPointer._delegate.editBoxReturn(selfPointer); 283 }); 284 285 cc.DOM.convert(this._domInputSprite); 286 this._domInputSprite.dom.appendChild(this._edTxt); 287 this._domInputSprite.dom.showTooltipDiv = false; 288 this._domInputSprite.dom.style.width = (boxSize.width - 6) +"px"; 289 this._domInputSprite.dom.style.height = (boxSize.height - 6) +"px"; 290 291 //this._domInputSprite.dom.style.borderWidth = "1px"; 292 //this._domInputSprite.dom.style.borderStyle = "solid"; 293 //this._domInputSprite.dom.style.borderRadius = "8px"; 294 this._domInputSprite.canvas.remove(); 295 }, 296 297 /** 298 * Set the font. 299 * @param {String} fontName The font name. 300 * @param {Number} fontSize The font size. 301 */ 302 setFont: function (fontName, fontSize) { 303 this._edFontSize = fontSize; 304 this._edFontName = fontName; 305 this._setFontToEditBox(); 306 }, 307 308 _setFont: function (fontStyle) { 309 var res = cc.LabelTTF._fontStyleRE.exec(fontStyle); 310 if(res) { 311 this._edFontSize = parseInt(res[1]); 312 this._edFontName = res[2]; 313 this._setFontToEditBox(); 314 } 315 }, 316 317 /** 318 * set fontName 319 * @param {String} fontName 320 */ 321 setFontName: function(fontName){ 322 this._edFontName = fontName; 323 this._setFontToEditBox(); 324 }, 325 326 /** 327 * set fontSize 328 * @param {Number} fontSize 329 */ 330 setFontSize: function(fontSize){ 331 this._edFontSize = fontSize; 332 this._setFontToEditBox(); 333 }, 334 335 _setFontToEditBox: function () { 336 if (this._edTxt.value != this._placeholderText){ 337 this._edTxt.style.fontFamily = this._edFontName; 338 this._edTxt.style.fontSize = this._edFontSize+"px"; 339 } 340 }, 341 342 /** 343 * Set the text entered in the edit box. 344 * @param {string} text The given text. 345 */ 346 setText: function (text) { 347 if (text != null) { 348 if (text == "") { 349 this._edTxt.value = this._placeholderText; 350 this._edTxt.style.color = cc.colorToHex(this._placeholderColor); 351 } else { 352 this._edTxt.value = text; 353 this._edTxt.style.color = cc.colorToHex(this._textColor); 354 } 355 } 356 }, 357 358 /** 359 * Set the font color of the widget's text. 360 * @param {cc.Color} color 361 */ 362 setFontColor: function (color) { 363 this._textColor = color; 364 if (this._edTxt.value != this._placeholderText) { 365 this._edTxt.style.color = cc.colorToHex(color); 366 } 367 }, 368 369 /** 370 * <p> 371 * Sets the maximum input length of the edit box. <br/> 372 * Setting this value enables multiline input mode by default. 373 * </p> 374 * @param {Number} maxLength The maximum length. 375 */ 376 setMaxLength: function (maxLength) { 377 if (!isNaN(maxLength) && maxLength > 0) { 378 this._maxLength = maxLength; 379 this._edTxt.maxLength = maxLength; 380 } 381 }, 382 383 /** 384 * Gets the maximum input length of the edit box. 385 * @return {Number} Maximum input length. 386 */ 387 getMaxLength: function () { 388 return this._maxLength; 389 }, 390 391 /** 392 * Set a text in the edit box that acts as a placeholder when an edit box is empty. 393 * @param {string} text The given text. 394 */ 395 setPlaceHolder: function (text) { 396 if (text != null) { 397 var oldPlaceholderText = this._placeholderText; 398 this._placeholderText = text; 399 if (this._edTxt.value == oldPlaceholderText) { 400 this._edTxt.value = text; 401 this._edTxt.style.color = cc.colorToHex(this._placeholderColor); 402 this._setPlaceholderFontToEditText(); 403 } 404 } 405 }, 406 407 /** 408 * Set the placeholder's font. 409 * @param {String} fontName 410 * @param {Number} fontSize 411 */ 412 setPlaceholderFont: function (fontName, fontSize) { 413 this._placeholderFontName = fontName; 414 this._placeholderFontSize = fontSize; 415 this._setPlaceholderFontToEditText(); 416 }, 417 _setPlaceholderFont: function (fontStyle) { 418 var res = cc.LabelTTF._fontStyleRE.exec(fontStyle); 419 if(res) { 420 this._placeholderFontName = res[2]; 421 this._placeholderFontSize = parseInt(res[1]); 422 this._setPlaceholderFontToEditText(); 423 } 424 }, 425 426 /** 427 * Set the placeholder's fontName. 428 * @param {String} fontName 429 */ 430 setPlaceholderFontName: function (fontName) { 431 this._placeholderFontName = fontName; 432 this._setPlaceholderFontToEditText(); 433 }, 434 435 /** 436 * Set the placeholder's fontSize. 437 * @param {Number} fontSize 438 */ 439 setPlaceholderFontSize: function (fontSize) { 440 this._placeholderFontSize = fontSize; 441 this._setPlaceholderFontToEditText(); 442 }, 443 444 _setPlaceholderFontToEditText: function () { 445 if (this._edTxt.value == this._placeholderText){ 446 this._edTxt.style.fontFamily = this._placeholderFontName; 447 this._edTxt.style.fontSize = this._placeholderFontSize + "px"; 448 } 449 }, 450 451 /** 452 * Set the font color of the placeholder text when the edit box is empty. 453 * @param {cc.Color} color 454 */ 455 setPlaceholderFontColor: function (color) { 456 this._placeholderColor = color; 457 if (this._edTxt.value == this._placeholderText) { 458 this._edTxt.style.color = cc.colorToHex(color); 459 } 460 }, 461 462 /** 463 * Set the input flags that are to be applied to the edit box. 464 * @param {Number} inputFlag One of the EditBoxInputFlag constants. 465 * e.g.cc.EDITBOX_INPUT_FLAG_PASSWORD 466 */ 467 setInputFlag: function (inputFlag) { 468 this._editBoxInputFlag = inputFlag; 469 if (inputFlag == cc.EDITBOX_INPUT_FLAG_PASSWORD) 470 this._edTxt.type = "password"; 471 else 472 this._edTxt.type = "text"; 473 }, 474 475 /** 476 * Gets the input string of the edit box. 477 * @return {string} 478 */ 479 getText: function () { 480 return this._edTxt.value; 481 }, 482 483 /** 484 * Init edit box with specified size. 485 * @param {cc.Size} size 486 * @param {cc.Color | cc.Scale9Sprite} normal9SpriteBg 487 */ 488 initWithSizeAndBackgroundSprite: function (size, normal9SpriteBg) { 489 if (this.initWithBackgroundSprite(normal9SpriteBg)) { 490 this._domInputSprite.x = 3; 491 this._domInputSprite.y = 3; 492 493 this.setZoomOnTouchDown(false); 494 this.setPreferredSize(size); 495 this.x = 0; 496 this.y = 0; 497 this._addTargetWithActionForControlEvent(this, this.touchDownAction, cc.CONTROL_EVENT_TOUCH_UP_INSIDE); 498 return true; 499 } 500 return false; 501 }, 502 503 /* override functions */ 504 /** 505 * Set the delegate for edit box. 506 */ 507 setDelegate: function (delegate) { 508 this._delegate = delegate; 509 }, 510 511 /** 512 * Get a text in the edit box that acts as a placeholder when an 513 * edit box is empty. 514 * @return {String} 515 */ 516 getPlaceHolder: function () { 517 return this._placeholderText; 518 }, 519 520 /** 521 * Set the input mode of the edit box. 522 * @param {Number} inputMode One of the EditBoxInputMode constants. 523 */ 524 setInputMode: function (inputMode) { 525 this._editBoxInputMode = inputMode; 526 }, 527 528 /** 529 * Set the return type that are to be applied to the edit box. 530 * @param {Number} returnType One of the CCKeyboardReturnType constants. 531 */ 532 setReturnType: function (returnType) { 533 this._keyboardReturnType = returnType; 534 }, 535 536 keyboardWillShow: function (info) { 537 var rectTracked = cc.EditBox.getRect(this); 538 // some adjustment for margin between the keyboard and the edit box. 539 rectTracked.y -= 4; 540 // if the keyboard area doesn't intersect with the tracking node area, nothing needs to be done. 541 if (!rectTracked.intersectsRect(info.end)) { 542 cc.log("needn't to adjust view layout."); 543 return; 544 } 545 546 // assume keyboard at the bottom of screen, calculate the vertical adjustment. 547 this._adjustHeight = info.end.getMaxY() - rectTracked.getMinY(); 548 // CCLOG("CCEditBox:needAdjustVerticalPosition(%f)", m_fAdjustHeight); 549 550 //callback 551 }, 552 keyboardDidShow: function (info) { 553 }, 554 keyboardWillHide: function (info) { 555 //if (m_pEditBoxImpl != NULL) { 556 // m_pEditBoxImpl->doAnimationWhenKeyboardMove(info.duration, -m_fAdjustHeight); 557 //} 558 }, 559 keyboardDidHide: function (info) { 560 }, 561 562 touchDownAction: function (sender, controlEvent) { 563 //this._editBoxImpl.openKeyboard(); 564 }, 565 566 //HTML5 Only 567 initWithBackgroundColor: function (size, bgColor) { 568 this._edWidth = size.width; 569 this.dom.style.width = this._edWidth.toString() + "px"; 570 this._edHeight = size.height; 571 this.dom.style.height = this._edHeight.toString() + "px"; 572 this.dom.style.backgroundColor = cc.colorToHex(bgColor); 573 } 574 }); 575 576 window._p = cc.EditBox.prototype; 577 578 // Extended properties 579 /** @expose */ 580 _p.font; 581 cc.defineGetterSetter(_p, "font", null, _p._setFont); 582 /** @expose */ 583 _p.fontName; 584 cc.defineGetterSetter(_p, "fontName", null, _p.setFontName); 585 /** @expose */ 586 _p.fontSize; 587 cc.defineGetterSetter(_p, "fontSize", null, _p.setFontSize); 588 /** @expose */ 589 _p.fontColor; 590 cc.defineGetterSetter(_p, "fontColor", null, _p.setFontColor); 591 /** @expose */ 592 _p.string; 593 cc.defineGetterSetter(_p, "string", _p.getText, _p.setText); 594 /** @expose */ 595 _p.maxLength; 596 cc.defineGetterSetter(_p, "maxLength", _p.getMaxLength, _p.setMaxLength); 597 /** @expose */ 598 _p.placeHolder; 599 cc.defineGetterSetter(_p, "placeHolder", _p.getPlaceHolder, _p.setPlaceHolder); 600 /** @expose */ 601 _p.placeHolderFont; 602 cc.defineGetterSetter(_p, "placeHolderFont", null, _p._setPlaceholderFont); 603 /** @expose */ 604 _p.placeHolderFontName; 605 cc.defineGetterSetter(_p, "placeHolderFontName", null, _p.setPlaceholderFontName); 606 /** @expose */ 607 _p.placeHolderFontSize; 608 cc.defineGetterSetter(_p, "placeHolderFontSize", null, _p.setPlaceholderFontSize); 609 /** @expose */ 610 _p.placeHolderFontColor; 611 cc.defineGetterSetter(_p, "placeHolderFontColor", null, _p.setPlaceholderFontColor); 612 /** @expose */ 613 _p.inputFlag; 614 cc.defineGetterSetter(_p, "inputFlag", null, _p.setInputFlag); 615 /** @expose */ 616 _p.delegate; 617 cc.defineGetterSetter(_p, "delegate", null, _p.setDelegate); 618 /** @expose */ 619 _p.inputMode; 620 cc.defineGetterSetter(_p, "inputMode", null, _p.setInputMode); 621 /** @expose */ 622 _p.returnType; 623 cc.defineGetterSetter(_p, "returnType", null, _p.setReturnType); 624 625 delete window._p; 626 627 cc.EditBox.getRect = function (node) { 628 var contentSize = node.getContentSize(); 629 var rect = cc.rect(0, 0, contentSize.width, contentSize.height); 630 return cc.RectApplyAffineTransform(rect, node.nodeToWorldTransform()); 631 }; 632 633 /** 634 * create a edit box with size and background-color or 635 * @param {cc.Size} size 636 * @param {cc.Color | cc.Scale9Sprite } normal9SpriteBg 637 */ 638 cc.EditBox.create = function (size, normal9SpriteBg, press9SpriteBg, disabled9SpriteBg) { 639 var edbox = new cc.EditBox(size); 640 if (normal9SpriteBg instanceof cc.Color) { 641 edbox.setBackgroundColor(normal9SpriteBg); 642 } else { 643 //Todo 644 if (edbox.initWithSizeAndBackgroundSprite(size, normal9SpriteBg)) { 645 if (press9SpriteBg) 646 edbox.setBackgroundSpriteForState(press9SpriteBg, cc.CONTROL_STATE_HIGHLIGHTED); 647 648 if (disabled9SpriteBg) 649 edbox.setBackgroundSpriteForState(disabled9SpriteBg, cc.CONTROL_STATE_DISABLED); 650 } 651 } 652 return edbox; 653 }; 654 655 656 657 658