1 /**************************************************************************** 2 Copyright (c) 2010-2012 cocos2d-x.org 3 Copyright (c) 2008-2010 Ricardo Quesada 4 Copyright (c) 2011 Zynga 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 cc.TextFieldTTF = cc.LabelTTF.extend(/** @lends cc.TextFieldTTF# */{ 94 delegate:null, 95 colorSpaceHolder:null, 96 97 _lens:null, 98 _inputText:"", 99 _placeHolder:"", 100 _charCount:0, 101 _className:"TextFieldTTF", 102 103 ctor:function () { 104 this.colorSpaceHolder = cc.color(127, 127, 127); 105 cc.imeDispatcher.addDelegate(this); 106 cc.LabelTTF.prototype.ctor.call(this); 107 }, 108 109 /** 110 * @return {cc.Node} 111 */ 112 getDelegate:function () { 113 return this.delegate; 114 }, 115 116 /** 117 * @param {cc.Node} value 118 */ 119 setDelegate:function (value) { 120 this.delegate = value; 121 }, 122 123 /** 124 * @return {Number} 125 */ 126 getCharCount:function () { 127 return this._charCount; 128 }, 129 130 /** 131 * @return {cc.Color} 132 */ 133 getColorSpaceHolder:function () { 134 return this.colorSpaceHolder; 135 }, 136 137 /** 138 * @param {cc.Color} value 139 */ 140 setColorSpaceHolder:function (value) { 141 this.colorSpaceHolder = value; 142 }, 143 /** 144 * Initializes the cc.TextFieldTTF with a font name, alignment, dimension and font size 145 * @param {String} placeholder 146 * @param {cc.Size} dimensions 147 * @param {Number} alignment 148 * @param {String} fontName 149 * @param {Number} fontSize 150 * @return {Boolean} 151 * @example 152 * //example 153 * var textField = new cc.TextFieldTTF(); 154 * // When five parameters 155 * textField.initWithPlaceHolder("<click here for input>", cc.size(100,50), cc.TEXT_ALIGNMENT_LEFT,"Arial", 32); 156 * // When three parameters 157 * textField.initWithPlaceHolder("<click here for input>", "Arial", 32); 158 */ 159 initWithPlaceHolder:function (placeholder, dimensions, alignment, fontName, fontSize) { 160 switch (arguments.length) { 161 case 5: 162 if (placeholder) { 163 this._placeHolder = placeholder; 164 } 165 return this.initWithString(this._placeHolder,fontName, fontSize, dimensions, alignment); 166 break; 167 case 3: 168 if (placeholder) { 169 this._placeHolder = placeholder; 170 } 171 fontName = arguments[1]; 172 fontSize = arguments[2]; 173 return this.initWithString(this._placeHolder, fontName, fontSize); 174 break; 175 default: 176 throw "Argument must be non-nil "; 177 break; 178 } 179 }, 180 181 /** 182 * Input text property 183 * @param {String} text 184 */ 185 setString:function (text) { 186 text = String(text); 187 this._inputText = text || ""; 188 189 // if there is no input text, display placeholder instead 190 if (!this._inputText.length) 191 cc.LabelTTF.prototype.setString.call(this, this._placeHolder); 192 else 193 cc.LabelTTF.prototype.setString.call(this,this._inputText); 194 this._charCount = this._inputText.length; 195 }, 196 197 /** 198 * @return {String} 199 */ 200 getString:function () { 201 return this._inputText; 202 }, 203 204 /** 205 * @param {String} text 206 */ 207 setPlaceHolder:function (text) { 208 this._placeHolder = text || ""; 209 if (!this._inputText.length) { 210 cc.LabelTTF.prototype.setString.call(this,this._placeHolder); 211 } 212 }, 213 214 /** 215 * @return {String} 216 */ 217 getPlaceHolder:function () { 218 return this._placeHolder; 219 }, 220 221 /** 222 * @param {CanvasContext} ctx 223 */ 224 draw:function (ctx) { 225 //console.log("size",this._contentSize); 226 var context = ctx || cc._renderContext; 227 if (this.delegate && this.delegate.onDraw(this)) 228 return; 229 230 if (this._inputText && this._inputText.length > 0) { 231 cc.LabelTTF.prototype.draw.call(this, context); 232 return; 233 } 234 235 // draw placeholder 236 var color = this.color; 237 this.color = this.colorSpaceHolder; 238 if(cc._renderType === cc._RENDER_TYPE_CANVAS) 239 this._updateTexture(); 240 cc.LabelTTF.prototype.draw.call(this, context); 241 this.color = color; 242 }, 243 244 ////////////////////////////////////////////////////////////////////////// 245 // CCIMEDelegate interface 246 ////////////////////////////////////////////////////////////////////////// 247 /** 248 * Open keyboard and receive input text. 249 * @return {Boolean} 250 */ 251 attachWithIME:function () { 252 return cc.imeDispatcher.attachDelegateWithIME(this); 253 }, 254 255 /** 256 * End text input and close keyboard. 257 * @return {Boolean} 258 */ 259 detachWithIME:function () { 260 return cc.imeDispatcher.detachDelegateWithIME(this); 261 }, 262 263 /** 264 * @return {Boolean} 265 */ 266 canAttachWithIME:function () { 267 return (this.delegate) ? (!this.delegate.onTextFieldAttachWithIME(this)) : true; 268 }, 269 270 /** 271 * When the delegate detach with IME, this method call by CCIMEDispatcher. 272 */ 273 didAttachWithIME:function () { 274 }, 275 276 /** 277 * @return {Boolean} 278 */ 279 canDetachWithIME:function () { 280 return (this.delegate) ? (!this.delegate.onTextFieldDetachWithIME(this)) : true; 281 }, 282 283 /** 284 * When the delegate detach with IME, this method call by CCIMEDispatcher. 285 */ 286 didDetachWithIME:function () { 287 }, 288 289 /** 290 * Delete backward 291 */ 292 deleteBackward:function () { 293 var strLen = this._inputText.length; 294 if (strLen == 0) 295 return; 296 297 // get the delete byte number 298 var deleteLen = 1; // default, erase 1 byte 299 300 if (this.delegate && this.delegate.onTextFieldDeleteBackward(this, this._inputText[strLen - deleteLen], deleteLen)) { 301 // delegate don't want delete backward 302 return; 303 } 304 305 // if delete all text, show space holder string 306 if (strLen <= deleteLen) { 307 this._inputText = ""; 308 this._charCount = 0; 309 cc.LabelTTF.prototype.setString.call(this,this._placeHolder); 310 return; 311 } 312 313 // set new input text 314 var sText = this._inputText.substring(0, strLen - deleteLen); 315 this.string = sText; 316 }, 317 318 /** 319 * Remove delegate 320 */ 321 removeDelegate:function () { 322 cc.imeDispatcher.removeDelegate(this); 323 }, 324 325 /** 326 * @param {String} text 327 * @param {Number} len 328 */ 329 insertText:function (text, len) { 330 var sInsert = text; 331 332 // insert \n means input end 333 var pos = sInsert.indexOf('\n'); 334 if (pos > -1) { 335 sInsert = sInsert.substring(0, pos); 336 } 337 338 if (sInsert.length > 0) { 339 if (this.delegate && this.delegate.onTextFieldInsertText(this, sInsert, sInsert.length)) { 340 // delegate doesn't want insert text 341 return; 342 } 343 344 var sText = this._inputText + sInsert; 345 this._charCount = sText.length; 346 this.string = sText; 347 } 348 349 if (pos == -1) 350 return; 351 352 // '\n' has inserted, let delegate process first 353 if (this.delegate && this.delegate.onTextFieldInsertText(this, "\n", 1)) 354 return; 355 356 // if delegate hasn't process, detach with ime as default 357 this.detachWithIME(); 358 }, 359 /** 360 * @return {String} 361 */ 362 getContentText:function () { 363 return this._inputText; 364 }, 365 366 ////////////////////////////////////////////////////////////////////////// 367 // keyboard show/hide notification 368 ////////////////////////////////////////////////////////////////////////// 369 keyboardWillShow:function (info) { 370 }, 371 keyboardDidShow:function (info) { 372 }, 373 keyboardWillHide:function (info) { 374 }, 375 keyboardDidHide:function (info) { 376 } 377 }); 378 379 window._p = cc.TextFieldTTF.prototype; 380 381 // Extended properties 382 /** @expose */ 383 _p.charCount; 384 cc.defineGetterSetter(_p, "charCount", _p.getCharCount); 385 /** @expose */ 386 _p.placeHolder; 387 cc.defineGetterSetter(_p, "placeHolder", _p.getPlaceHolder, _p.setPlaceHolder); 388 delete window._p; 389 390 /** 391 * creates a cc.TextFieldTTF from a fontName, alignment, dimension and font size 392 * @param {String} placeholder 393 * @param {cc.Size} dimensions 394 * @param {Number} alignment 395 * @param {String} fontName 396 * @param {Number} fontSize 397 * @return {cc.TextFieldTTF|Null} 398 * @example 399 * //example 400 * // When five parameters 401 * var textField = cc.TextFieldTTF.create("<click here for input>", cc.size(100,50), cc.TEXT_ALIGNMENT_LEFT,"Arial", 32); 402 * // When three parameters 403 * var textField = cc.TextFieldTTF.create("<click here for input>", "Arial", 32); 404 */ 405 cc.TextFieldTTF.create = function (placeholder, dimensions, alignment, fontName, fontSize) { 406 var ret; 407 switch (arguments.length) { 408 case 5: 409 ret = new cc.TextFieldTTF(); 410 if (ret && ret.initWithPlaceHolder("", dimensions, alignment, fontName, fontSize)) { 411 if (placeholder) 412 ret.placeHolder = placeholder; 413 return ret; 414 } 415 return null; 416 break; 417 case 3: 418 ret = new cc.TextFieldTTF(); 419 fontName = arguments[1]; 420 fontSize = arguments[2]; 421 if (ret && ret.initWithString("", fontName, fontSize)) { 422 if (placeholder) 423 ret.placeHolder = placeholder; 424 return ret; 425 } 426 return null; 427 break; 428 default: 429 throw "Argument must be non-nil "; 430 break; 431 } 432 }; 433 434