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