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