1 /**************************************************************************** 2 Copyright (c) 2011-2012 cocos2d-x.org 3 Copyright (c) 2013-2014 Chukong Technologies Inc. 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 ccui.LayoutComponent_ReferencePoint = { 27 BOTTOM_LEFT: 0, 28 TOP_LEFT: 1, 29 BOTTOM_RIGHT: 2, 30 TOP_RIGHT: 3 31 }; 32 ccui.LayoutComponent_PositionType = { 33 Position: 0, 34 RelativePosition: 1, 35 PreRelativePosition: 2, 36 PreRelativePositionEnable: 3 37 }; 38 ccui.LayoutComponent_SizeType = { 39 Size: 0, 40 PreSize: 1, 41 PreSizeEnable: 2 42 }; 43 44 //refactor since v3.3 45 ccui.LayoutComponent = cc.Component.extend({ 46 _horizontalEdge: 0, 47 _verticalEdge: 0, 48 49 _leftMargin: 0, 50 _rightMargin: 0, 51 _bottomMargin: 0, 52 _topMargin: 0, 53 54 _usingPositionPercentX: false, 55 _positionPercentX: 0, 56 _usingPositionPercentY: false, 57 _positionPercentY: 0, 58 59 _usingStretchWidth: false, 60 _usingStretchHeight: false, 61 62 _percentWidth: 0, 63 _usingPercentWidth: false, 64 65 _percentHeight: 0, 66 _usingPercentHeight: false, 67 68 _actived: true, 69 _isPercentOnly: false, 70 71 ctor: function () { 72 this._name = ccui.LayoutComponent.NAME; 73 }, 74 75 init: function () { 76 var ret = true; 77 78 if (!cc.Component.prototype.init.call(this)) { 79 return false; 80 } 81 82 //put layout component initalized code here 83 84 return ret; 85 }, 86 87 getPercentContentSize: function () { 88 return cc.p(this._percentWidth, this._percentHeight); 89 }, 90 setPercentContentSize: function (percent) { 91 this.setPercentWidth(percent.x); 92 this.setPercentHeight(percent.y); 93 }, 94 95 setUsingPercentContentSize: function (isUsed) { 96 this._usingPercentWidth = this._usingPercentHeight = isUsed; 97 }, 98 99 //old 100 SetActiveEnable: function (enable) { 101 this._actived = enable; 102 }, 103 104 //v3.3 105 getUsingPercentContentSize: function () { 106 return this._usingPercentWidth && this._usingPercentHeight; 107 }, 108 109 //position & margin 110 getAnchorPosition: function () { 111 return this._owner.getAnchorPoint(); 112 }, 113 114 setAnchorPosition: function (point, y) { 115 var oldRect = this._owner.getBoundingBox(); 116 this._owner.setAnchorPoint(point, y); 117 var newRect = this._owner.getBoundingBox(); 118 var offSetX = oldRect.x - newRect.x, offSetY = oldRect.y - newRect.y; 119 120 var ownerPosition = this._owner.getPosition(); 121 ownerPosition.x += offSetX; 122 ownerPosition.y += offSetY; 123 this.setPosition(ownerPosition); 124 }, 125 126 getPosition: function () { 127 return this._owner.getPosition(); 128 }, 129 130 setPosition: function (position, y) { 131 var parent = this._getOwnerParent(), x; 132 if (parent != null) { 133 if (y === undefined) { 134 x = position.x; 135 y = position.y; 136 } else 137 x = position; 138 var parentSize = parent.getContentSize(); 139 140 if (parentSize.width !== 0) 141 this._positionPercentX = x / parentSize.width; 142 else { 143 this._positionPercentX = 0; 144 if (this._usingPositionPercentX) 145 x = 0; 146 } 147 148 if (parentSize.height !== 0) 149 this._positionPercentY = y / parentSize.height; 150 else { 151 this._positionPercentY = 0; 152 if (this._usingPositionPercentY) 153 y = 0; 154 } 155 156 this._owner.setPosition(x, y); 157 this._refreshHorizontalMargin(); 158 this._refreshVerticalMargin(); 159 } else 160 this._owner.setPosition(position, y); 161 }, 162 163 isPositionPercentXEnabled: function () { 164 return this._usingPositionPercentX; 165 }, 166 setPositionPercentXEnabled: function (isUsed) { 167 this._usingPositionPercentX = isUsed; 168 if (this._usingPositionPercentX) 169 this._horizontalEdge = ccui.LayoutComponent.horizontalEdge.NONE; 170 }, 171 172 getPositionPercentX: function () { 173 return this._positionPercentX; 174 }, 175 setPositionPercentX: function (percentMargin) { 176 this._positionPercentX = percentMargin; 177 178 var parent = this._getOwnerParent(); 179 if (parent !== null) { 180 this._owner.setPositionX(parent.width * this._positionPercentX); 181 this._refreshHorizontalMargin(); 182 } 183 }, 184 185 isPositionPercentYEnabled: function () { 186 return this._usingPositionPercentY; 187 }, 188 setPositionPercentYEnabled: function (isUsed) { 189 this._usingPositionPercentY = isUsed; 190 if (this._usingPositionPercentY) 191 this._verticalEdge = ccui.LayoutComponent.verticalEdge.NONE; 192 }, 193 194 getPositionPercentY: function () { 195 return this._positionPercentY; 196 }, 197 setPositionPercentY: function (percentMargin) { 198 this._positionPercentY = percentMargin; 199 200 var parent = this._getOwnerParent(); 201 if (parent !== null) { 202 this._owner.setPositionY(parent.height * this._positionPercentY); 203 this._refreshVerticalMargin(); 204 } 205 }, 206 207 getHorizontalEdge: function () { 208 return this._horizontalEdge; 209 }, 210 setHorizontalEdge: function (hEdge) { 211 this._horizontalEdge = hEdge; 212 if (this._horizontalEdge !== ccui.LayoutComponent.horizontalEdge.NONE) 213 this._usingPositionPercentX = false; 214 215 var parent = this._getOwnerParent(); 216 if (parent !== null) { 217 var ownerPoint = this._owner.getPosition(); 218 var parentSize = parent.getContentSize(); 219 if (parentSize.width !== 0) 220 this._positionPercentX = ownerPoint.x / parentSize.width; 221 else { 222 this._positionPercentX = 0; 223 ownerPoint.x = 0; 224 if (this._usingPositionPercentX) 225 this._owner.setPosition(ownerPoint); 226 } 227 this._refreshHorizontalMargin(); 228 } 229 }, 230 231 getVerticalEdge: function () { 232 return this._verticalEdge; 233 }, 234 setVerticalEdge: function (vEdge) { 235 this._verticalEdge = vEdge; 236 if (this._verticalEdge !== ccui.LayoutComponent.verticalEdge.NONE) 237 this._usingPositionPercentY = false; 238 239 var parent = this._getOwnerParent(); 240 if (parent !== null) { 241 var ownerPoint = this._owner.getPosition(); 242 var parentSize = parent.getContentSize(); 243 if (parentSize.height !== 0) 244 this._positionPercentY = ownerPoint.y / parentSize.height; 245 else { 246 this._positionPercentY = 0; 247 ownerPoint.y = 0; 248 if (this._usingPositionPercentY) 249 this._owner.setPosition(ownerPoint); 250 } 251 this._refreshVerticalMargin(); 252 } 253 }, 254 255 getLeftMargin: function () { 256 return this._leftMargin; 257 }, 258 setLeftMargin: function (margin) { 259 this._leftMargin = margin; 260 }, 261 262 getRightMargin: function () { 263 return this._rightMargin; 264 }, 265 setRightMargin: function (margin) { 266 this._rightMargin = margin; 267 }, 268 269 getTopMargin: function () { 270 return this._topMargin; 271 }, 272 setTopMargin: function (margin) { 273 this._topMargin = margin; 274 }, 275 276 getBottomMargin: function () { 277 return this._bottomMargin; 278 }, 279 setBottomMargin: function (margin) { 280 this._bottomMargin = margin; 281 }, 282 283 //size & 284 getSize: function () { 285 return this.getOwner().getContentSize(); 286 }, 287 setSize: function (size) { 288 var parent = this._getOwnerParent(); 289 if (parent !== null) { 290 var ownerSize = size, parentSize = parent.getContentSize(); 291 292 if (parentSize.width !== 0) 293 this._percentWidth = ownerSize.width / parentSize.width; 294 else { 295 this._percentWidth = 0; 296 if (this._usingPercentWidth) 297 ownerSize.width = 0; 298 } 299 300 if (parentSize.height !== 0) 301 this._percentHeight = ownerSize.height / parentSize.height; 302 else { 303 this._percentHeight = 0; 304 if (this._usingPercentHeight) 305 ownerSize.height = 0; 306 } 307 308 this._owner.setContentSize(ownerSize); 309 310 this._refreshHorizontalMargin(); 311 this._refreshVerticalMargin(); 312 } 313 else 314 this._owner.setContentSize(size); 315 }, 316 317 isPercentWidthEnabled: function () { 318 return this._usingPercentWidth; 319 }, 320 setPercentWidthEnabled: function (isUsed) { 321 this._usingPercentWidth = isUsed; 322 if (this._usingPercentWidth) 323 this._usingStretchWidth = false; 324 }, 325 326 getSizeWidth: function () { 327 return this._owner.width; 328 }, 329 setSizeWidth: function (width) { 330 var ownerSize = this._owner.getContentSize(); 331 ownerSize.width = width; 332 333 var parent = this._getOwnerParent(); 334 if (parent !== null) { 335 var parentSize = parent.getContentSize(); 336 if (parentSize.width !== 0) 337 this._percentWidth = ownerSize.width / parentSize.width; 338 else { 339 this._percentWidth = 0; 340 if (this._usingPercentWidth) 341 ownerSize.width = 0; 342 } 343 this._owner.setContentSize(ownerSize); 344 this._refreshHorizontalMargin(); 345 } else 346 this._owner.setContentSize(ownerSize); 347 }, 348 349 getPercentWidth: function () { 350 return this._percentWidth; 351 }, 352 setPercentWidth: function (percentWidth) { 353 this._percentWidth = percentWidth; 354 355 var parent = this._getOwnerParent(); 356 if (parent !== null) { 357 var ownerSize = this._owner.getContentSize(); 358 ownerSize.width = parent.width * this._percentWidth; 359 this._owner.setContentSize(ownerSize); 360 this._refreshHorizontalMargin(); 361 } 362 }, 363 364 isPercentHeightEnabled: function () { 365 return this._usingPercentHeight; 366 }, 367 setPercentHeightEnabled: function (isUsed) { 368 this._usingPercentHeight = isUsed; 369 if (this._usingPercentHeight) 370 this._usingStretchHeight = false; 371 }, 372 373 getSizeHeight: function () { 374 return this._owner.height; 375 }, 376 setSizeHeight: function (height) { 377 var ownerSize = this._owner.getContentSize(); 378 ownerSize.height = height; 379 380 var parent = this._getOwnerParent(); 381 if (parent !== null) { 382 var parentSize = parent.getContentSize(); 383 if (parentSize.height !== 0) 384 this._percentHeight = ownerSize.height / parentSize.height; 385 else { 386 this._percentHeight = 0; 387 if (this._usingPercentHeight) 388 ownerSize.height = 0; 389 } 390 this._owner.setContentSize(ownerSize); 391 this._refreshVerticalMargin(); 392 } 393 else 394 this._owner.setContentSize(ownerSize); 395 }, 396 397 getPercentHeight: function () { 398 return this._percentHeight; 399 }, 400 setPercentHeight: function (percentHeight) { 401 this._percentHeight = percentHeight; 402 403 var parent = this._getOwnerParent(); 404 if (parent !== null) { 405 var ownerSize = this._owner.getContentSize(); 406 ownerSize.height = parent.height * this._percentHeight; 407 this._owner.setContentSize(ownerSize); 408 this._refreshVerticalMargin(); 409 } 410 }, 411 412 isStretchWidthEnabled: function () { 413 return this._usingStretchWidth; 414 }, 415 setStretchWidthEnabled: function (isUsed) { 416 this._usingStretchWidth = isUsed; 417 if (this._usingStretchWidth) 418 this._usingPercentWidth = false; 419 }, 420 421 isStretchHeightEnabled: function () { 422 return this._usingStretchHeight; 423 }, 424 setStretchHeightEnabled: function (isUsed) { 425 this._usingStretchHeight = isUsed; 426 if (this._usingStretchHeight) 427 this._usingPercentHeight = false; 428 }, 429 430 setPercentOnlyEnabled: function(enable){ 431 this._isPercentOnly = enable; 432 }, 433 434 setActiveEnabled: function (enable) { 435 this._actived = enable; 436 }, 437 refreshLayout: function () { 438 if(!this._actived) 439 return; 440 441 var parent = this._getOwnerParent(); 442 if (parent === null) 443 return; 444 445 var parentSize = parent.getContentSize(), locOwner = this._owner; 446 var ownerAnchor = locOwner.getAnchorPoint(), ownerSize = locOwner.getContentSize(); 447 var ownerPosition = locOwner.getPosition(); 448 449 switch (this._horizontalEdge) { 450 case ccui.LayoutComponent.horizontalEdge.NONE: 451 if (this._usingStretchWidth && !this._isPercentOnly) { 452 ownerSize.width = parentSize.width * this._percentWidth; 453 ownerPosition.x = this._leftMargin + ownerAnchor.x * ownerSize.width; 454 } else { 455 if (this._usingPositionPercentX) 456 ownerPosition.x = parentSize.width * this._positionPercentX; 457 if (this._usingPercentWidth) 458 ownerSize.width = parentSize.width * this._percentWidth; 459 } 460 break; 461 case ccui.LayoutComponent.horizontalEdge.LEFT: 462 if(this._isPercentOnly) 463 break; 464 if (this._usingPercentWidth || this._usingStretchWidth) 465 ownerSize.width = parentSize.width * this._percentWidth; 466 ownerPosition.x = this._leftMargin + ownerAnchor.x * ownerSize.width; 467 break; 468 case ccui.LayoutComponent.horizontalEdge.RIGHT: 469 if(this._isPercentOnly) 470 break; 471 if (this._usingPercentWidth || this._usingStretchWidth) 472 ownerSize.width = parentSize.width * this._percentWidth; 473 ownerPosition.x = parentSize.width - (this._rightMargin + (1 - ownerAnchor.x) * ownerSize.width); 474 break; 475 case ccui.LayoutComponent.horizontalEdge.CENTER: 476 if(this._isPercentOnly) 477 break; 478 if (this._usingStretchWidth) { 479 ownerSize.width = parentSize.width - this._leftMargin - this._rightMargin; 480 if (ownerSize.width < 0) 481 ownerSize.width = 0; 482 ownerPosition.x = this._leftMargin + ownerAnchor.x * ownerSize.width; 483 } else { 484 if (this._usingPercentWidth) 485 ownerSize.width = parentSize.width * this._percentWidth; 486 ownerPosition.x = parentSize.width * this._positionPercentX; 487 } 488 break; 489 default: 490 break; 491 } 492 493 switch (this._verticalEdge) { 494 case ccui.LayoutComponent.verticalEdge.NONE: 495 if (this._usingStretchHeight && !this._isPercentOnly) { 496 ownerSize.height = parentSize.height * this._percentHeight; 497 ownerPosition.y = this._bottomMargin + ownerAnchor.y * ownerSize.height; 498 } else { 499 if (this._usingPositionPercentY) 500 ownerPosition.y = parentSize.height * this._positionPercentY; 501 if (this._usingPercentHeight) 502 ownerSize.height = parentSize.height * this._percentHeight; 503 } 504 break; 505 case ccui.LayoutComponent.verticalEdge.BOTTOM: 506 if(this._isPercentOnly) 507 break; 508 if (this._usingPercentHeight || this._usingStretchHeight) 509 ownerSize.height = parentSize.height * this._percentHeight; 510 ownerPosition.y = this._bottomMargin + ownerAnchor.y * ownerSize.height; 511 break; 512 case ccui.LayoutComponent.verticalEdge.TOP: 513 if(this._isPercentOnly) 514 break; 515 if (this._usingPercentHeight || this._usingStretchHeight) 516 ownerSize.height = parentSize.height * this._percentHeight; 517 ownerPosition.y = parentSize.height - (this._topMargin + (1 - ownerAnchor.y) * ownerSize.height); 518 break; 519 case ccui.LayoutComponent.verticalEdge.CENTER: 520 if(this._isPercentOnly) 521 break; 522 if (this._usingStretchHeight) { 523 ownerSize.height = parentSize.height - this._topMargin - this._bottomMargin; 524 if (ownerSize.height < 0) 525 ownerSize.height = 0; 526 ownerPosition.y = this._bottomMargin + ownerAnchor.y * ownerSize.height; 527 } else { 528 if(this._usingPercentHeight) 529 ownerSize.height = parentSize.height * this._percentHeight; 530 ownerPosition.y = parentSize.height * this._positionPercentY; 531 } 532 break; 533 default: 534 break; 535 } 536 537 locOwner.setPosition(ownerPosition); 538 locOwner.setContentSize(ownerSize); 539 540 if(locOwner instanceof ccui.PageView){ 541 locOwner.forceDoLayout(); 542 543 var layoutVector = locOwner.getPages(); 544 for(var i=0; i<layoutVector.length; i++){ 545 ccui.helper.doLayout(layoutVector[i]); 546 } 547 }else{ 548 ccui.helper.doLayout(locOwner); 549 } 550 }, 551 552 _getOwnerParent: function () { 553 return this._owner ? this._owner.getParent() : null; 554 }, 555 _refreshHorizontalMargin: function () { 556 var parent = this._getOwnerParent(); 557 if (parent === null) 558 return; 559 560 var ownerPoint = this._owner.getPosition(), ownerAnchor = this._owner.getAnchorPoint(); 561 var ownerSize = this._owner.getContentSize(), parentSize = parent.getContentSize(); 562 563 this._leftMargin = ownerPoint.x - ownerAnchor.x * ownerSize.width; 564 this._rightMargin = parentSize.width - (ownerPoint.x + (1 - ownerAnchor.x) * ownerSize.width); 565 }, 566 _refreshVerticalMargin: function () { 567 var parent = this._getOwnerParent(); 568 if (parent === null) 569 return; 570 571 var ownerPoint = this._owner.getPosition(), ownerAnchor = this._owner.getAnchorPoint(); 572 var ownerSize = this._owner.getContentSize(), parentSize = parent.getContentSize(); 573 574 this._bottomMargin = ownerPoint.y - ownerAnchor.y * ownerSize.height; 575 this._topMargin = parentSize.height - (ownerPoint.y + (1 - ownerAnchor.y) * ownerSize.height); 576 } 577 }); 578 579 ccui.LayoutComponent.horizontalEdge = {NONE: 0, LEFT: 1, RIGHT: 2, CENTER: 3}; 580 ccui.LayoutComponent.verticalEdge = {NONE: 0, BOTTOM: 1, TOP: 2, CENTER: 3}; 581 582 ccui.LayoutComponent.NAME = "__ui_layout"; 583 ccui.LayoutComponent.bindLayoutComponent = function (node) { 584 var layout = node.getComponent(ccui.LayoutComponent.NAME); 585 if (layout !== undefined) 586 return layout; 587 588 layout = new ccui.LayoutComponent(); 589 if (layout && layout.init()) { 590 node.addComponent(layout); 591 return layout; 592 } 593 return null; 594 };