1 /**************************************************************************** 2 Copyright (c) 2008-2010 Ricardo Quesada 3 Copyright (c) 2011-2012 cocos2d-x.org 4 Copyright (c) 2013-2014 Chukong Technologies 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 * The Spacer class 29 * @class 30 * @extends cc.Layer 31 */ 32 cc.Spacer = cc.Layer.extend(/** @lends cc.Spacer */{}); 33 34 cc.Spacer.verticalSpacer = function (space) { 35 var pRet = new cc.Spacer(); 36 pRet.init(); 37 pRet.setContentSize(0, space); 38 return pRet; 39 }; 40 41 cc.Spacer.horizontalSpacer = function (space) { 42 var pRet = new cc.Spacer(); 43 pRet.init(); 44 pRet.setContentSize(space, 0); 45 return pRet; 46 }; 47 48 /** 49 * MenuPassive: The menu passive ui component 50 * @class 51 * @extend cc.Layer 52 */ 53 cc.MenuPassive = cc.Layer.extend(/** @lends cc.MenuPassive# */{ 54 RGBAProtocol:true, 55 56 _color:null, 57 _opacity:0, 58 _className:"MenuPassive", 59 60 ctor:function () { 61 }, 62 63 /** Color: conforms with CCRGBAProtocol protocol */ 64 getColor:function () { 65 var locColor = this._color; 66 return cc.color(locColor.r, locColor.g, locColor.b, locColor.a); 67 }, 68 setColor:function (color) { 69 var locColor = this._color; 70 locColor.r = color.r; 71 locColor.g = color.g; 72 locColor.b = color.b; 73 74 if (this._children && this._children.length > 0) { 75 for (var i = 0; i < this._children.length; i++) { 76 if (this._children[i] && this._children[i].RGBAProtocol) { 77 this._children[i].setColor(color); 78 } 79 } 80 } 81 if (color.a !== undefined && !color.a_undefined) { 82 this.setOpacity(color.a); 83 } 84 }, 85 86 /** Opacity: conforms with CCRGBAProtocol protocol */ 87 getOpacity:function () { 88 return this._opacity; 89 }, 90 91 setOpacity:function (opacity) { 92 this._opacity = opacity; 93 94 if (this._children && this._children.length > 0) { 95 for (var i = 0; i < this._children.length; i++) { 96 if (this._children[i] && this._children[i].RGBAProtocol) { 97 this._children[i].setOpacity(opacity); 98 } 99 } 100 } 101 102 this._color.a = opacity; 103 }, 104 105 /** initializes a CCMenu with it's items */ 106 initWithItems:function (item, args) { 107 if (this.init()) { 108 //this.m_bIsTouchEnabled = false; 109 110 // menu in the center of the screen 111 var winSize = cc.director.getWinSize(); 112 113 // Set the default anchor point 114 this.ignoreAnchorPointForPosition(true); 115 this.setAnchorPoint(0.5, 0.5); 116 this.setContentSize(winSize); 117 118 this.setPosition(winSize.width / 2, winSize.height / 2); 119 var z = 0; 120 121 if (item) { 122 this.addChild(item, z); 123 for (var i = 0; i < args.length; i++) { 124 if (args[i]) { 125 z++; 126 this.addChild(args[i], z); 127 } 128 } 129 } 130 return true; 131 } 132 return false; 133 }, 134 135 /** align items vertically */ 136 alignItemsVertically:function () { 137 this.alignItemsVerticallyWithPadding(cc.DEFAULT_PADDING); 138 }, 139 140 /** align items vertically with padding 141 @since v0.7.2 142 */ 143 alignItemsVerticallyWithPadding:function (padding) { 144 var height = -padding; 145 146 var i; 147 if (this._children && this._children.length > 0) { 148 for (i = 0; i < this._children.length; i++) { 149 if (this._children[i]) { 150 height += this._children[i].getContentSize().height * this._children[i].getScaleY() + padding; 151 } 152 } 153 } 154 155 var width = 0; 156 var y = height / 2.0; 157 if (this._children && this._children.length > 0) { 158 for (i = 0; i < this._children.length; i++) { 159 if (this._children[i]) { 160 width = Math.max(width, this._children[i].getContentSize().width); 161 this._children[i].setPosition(0, y - this._children[i].getContentSize().height * this._children[i].getScaleY() / 2.0); 162 y -= this._children[i].getContentSize().height * this._children[i].getScaleY() + padding; 163 } 164 } 165 } 166 this.setContentSize(width, height); 167 }, 168 169 /** align items horizontally */ 170 alignItemsHorizontally:function () { 171 this.alignItemsHorizontallyWithPadding(cc.DEFAULT_PADDING); 172 }, 173 174 /** align items horizontally with padding 175 @since v0.7.2 176 */ 177 alignItemsHorizontallyWithPadding:function (padding) { 178 var width = -padding; 179 var i; 180 if (this._children && this._children.length > 0) { 181 for (i = 0; i < this._children.length; i++) { 182 if (this._children[i]) { 183 width += this._children[i].getContentSize().width * this._children[i].getScaleX() + padding; 184 } 185 } 186 } 187 188 var height = 0; 189 var x = -width / 2.0; 190 if (this._children && this._children.length > 0) { 191 for (i = 0; i < this._children.length; i++) { 192 if (this._children[i]) { 193 height = Math.max(height, this._children[i].getContentSize().height); 194 this._children[i].setPosition(x + this._children[i].getContentSize().width * this._children[i].getScaleX() / 2.0, 0); 195 x += this._children[i].getContentSize().width * this._children[i].getScaleX() + padding; 196 } 197 } 198 } 199 this.setContentSize(width, height); 200 }, 201 202 /** align items in rows of columns */ 203 alignItemsInColumns:function (columns) { 204 var rows = []; 205 var i; 206 for (i = 1; i < arguments.length; i++) { 207 rows.push(arguments[i]); 208 } 209 210 var height = -5; 211 var row = 0; 212 var rowHeight = 0; 213 var columnsOccupied = 0; 214 var rowColumns; 215 216 var tmp; 217 if (this._children && this._children.length > 0) { 218 for (i = 0; i < this._children.length; i++) { 219 if (this._children[i]) { 220 if(row >= rows.length){ 221 cc.log("cc.MenuPassive.alignItemsInColumns(): invalid row index"); 222 continue; 223 } 224 225 rowColumns = rows[row]; 226 // can not have zero columns on a row 227 if(!rowColumns) { 228 cc.log("cc.MenuPassive.alignItemsInColumns(): can not have zero columns on a row"); 229 continue; 230 } 231 232 tmp = this._children[i].getContentSize().height; 233 rowHeight = 0 | ((rowHeight >= tmp || (tmp == null)) ? rowHeight : tmp); 234 235 ++columnsOccupied; 236 if (columnsOccupied >= rowColumns) { 237 height += rowHeight + 5; 238 239 columnsOccupied = 0; 240 rowHeight = 0; 241 ++row; 242 } 243 } 244 } 245 } 246 247 // check if too many rows/columns for available menu items 248 //cc.assert(!columnsOccupied, ""); //? 249 250 var winSize = cc.director.getWinSize(); 251 252 row = 0; 253 rowHeight = 0; 254 rowColumns = 0; 255 var w = 0.0; 256 var x = 0.0; 257 var y = (height / 2); 258 if (this._children && this._children.length > 0) { 259 for (i = 0; i < this._children.length; i++) { 260 if (this._children[i]) { 261 if (rowColumns == 0) { 262 rowColumns = rows[row]; 263 w = winSize.width / (1 + rowColumns); 264 x = w; 265 } 266 267 tmp = this._children[i].getContentSize().height; 268 rowHeight = 0 | ((rowHeight >= tmp || (tmp == null)) ? rowHeight : tmp); 269 270 this._children[i].setPosition(x - winSize.width / 2, 271 y - this._children[i].getContentSize().height / 2); 272 273 x += w; 274 ++columnsOccupied; 275 276 if (columnsOccupied >= rowColumns) { 277 y -= rowHeight + 5; 278 279 columnsOccupied = 0; 280 rowColumns = 0; 281 rowHeight = 0; 282 ++row; 283 } 284 } 285 } 286 } 287 }, 288 289 /** align items in columns of rows */ 290 alignItemsInRows:function (rows) { 291 var columns = []; 292 var i; 293 for (i = 1; i < arguments.length; i++) { 294 columns.push(arguments[i]); 295 } 296 297 var columnWidths = []; 298 var columnHeights = []; 299 300 var width = -10; 301 var columnHeight = -5; 302 var column = 0; 303 var columnWidth = 0; 304 var rowsOccupied = 0; 305 var columnRows; 306 307 var tmp; 308 if (this._children && this._children.length > 0) { 309 for (i = 0; i < this._children.length; i++) { 310 if (this._children[i]) { 311 // check if too many menu items for the amount of rows/columns 312 if(column >= columns.length){ 313 cc.log("cc.MenuPassive.alignItemsInRows(): invalid row index"); 314 continue; 315 } 316 317 columnRows = columns[column]; 318 // can't have zero rows on a column 319 if(!columnRows) { 320 cc.log("cc.MenuPassive.alignItemsInColumns(): can't have zero rows on a column"); 321 continue; 322 } 323 324 // columnWidth = fmaxf(columnWidth, [item contentSize].width); 325 tmp = this._children[i].getContentSize().width; 326 columnWidth = 0 | ((columnWidth >= tmp || (tmp == null)) ? columnWidth : tmp); 327 328 columnHeight += 0 | (this._children[i].getContentSize().height + 5); 329 ++rowsOccupied; 330 331 if (rowsOccupied >= columnRows) { 332 columnWidths.push(columnWidth); 333 columnHeights.push(columnHeight); 334 width += columnWidth + 10; 335 336 rowsOccupied = 0; 337 columnWidth = 0; 338 columnHeight = -5; 339 ++column; 340 } 341 } 342 } 343 } 344 345 // check if too many rows/columns for available menu items. 346 //cc.assert(!rowsOccupied, ""); //? 347 348 var winSize = cc.director.getWinSize(); 349 350 column = 0; 351 columnWidth = 0; 352 columnRows = null; 353 var x = (-width / 2); 354 var y = 0.0; 355 if (this._children && this._children.length > 0) { 356 for (i = 0; i < this._children.length; i++) { 357 if (this._children[i]) { 358 if (columnRows == null) { 359 columnRows = columns[column]; 360 y = columnHeights[column]; 361 } 362 363 // columnWidth = fmaxf(columnWidth, [item contentSize].width); 364 tmp = this._children[i].getContentSize().width; 365 columnWidth = 0 | ((columnWidth >= tmp || (tmp == null)) ? columnWidth : tmp); 366 367 this._children[i].setPosition(x + columnWidths[column] / 2, y - winSize.height / 2); 368 369 y -= this._children[i].getContentSize().height + 10; 370 ++rowsOccupied; 371 372 if (rowsOccupied >= columnRows) { 373 x += columnWidth + 5; 374 rowsOccupied = 0; 375 columnRows = 0; 376 columnWidth = 0; 377 ++column; 378 } 379 } 380 } 381 } 382 }, 383 384 //RGBA protocol 385 setOpacityModifyRGB:function (bValue) { 386 }, 387 isOpacityModifyRGB:function () { 388 return false; 389 } 390 }); 391 392 /** creates an empty CCMenu */ 393 cc.MenuPassive.create = function (item) { 394 if (!item) { 395 item = null; 396 } 397 398 var argArr = []; 399 for (var i = 1; i < arguments.length; i++) { 400 argArr.push(arguments[i]); 401 } 402 403 var pRet = new cc.MenuPassive(); 404 if (pRet && pRet.initWithItems(item, argArr)) { 405 return pRet; 406 } 407 return null; 408 }; 409 410 /** creates a CCMenu with it's item, then use addChild() to add 411 * other items. It is used for script, it can't init with undetermined 412 * number of variables. 413 */ 414 cc.MenuPassive.createWithItem = function (item) { 415 return cc.MenuPassive.create(item, null); 416 };