1 /**************************************************************************** 2 Copyright (c) 2010-2012 cocos2d-x.org 3 4 http://www.cocos2d-x.org 5 6 Permission is hereby granted, free of charge, to any person obtaining a copy 7 of this software and associated documentation files (the "Software"), to deal 8 in the Software without restriction, including without limitation the rights 9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 copies of the Software, and to permit persons to whom the Software is 11 furnished to do so, subject to the following conditions: 12 13 The above copyright notice and this permission notice shall be included in 14 all copies or substantial portions of the Software. 15 16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 THE SOFTWARE. 23 ****************************************************************************/ 24 /** 25 * layoutBackGround color type 26 * @type {Object} 27 */ 28 ccs.LayoutBackGroundColorType = { 29 none: 0, 30 solid: 1, 31 gradient: 2 32 }; 33 34 /** 35 * Layout type 36 * @type {Object} 37 */ 38 ccs.LayoutType = { 39 absolute: 0, 40 linearVertical: 1, 41 linearHorizontal: 2, 42 relative: 3 43 }; 44 45 /** 46 * Base class for ccs.UILayout 47 * @class 48 * @extends ccs.UIWidget 49 */ 50 ccs.UILayout = ccs.UIWidget.extend(/** @lends ccs.UILayout# */{ 51 _clippingEnabled: null, 52 _backGroundScale9Enabled: null, 53 _backGroundImage: null, 54 _backGroundImageFileName: null, 55 _backGroundImageCapInsets: null, 56 _colorType: null, 57 _bgImageTexType: null, 58 _colorRender: null, 59 _gradientRender: null, 60 _color: null, 61 _startColor: null, 62 _endColor: null, 63 _alongVector: null, 64 _opacity: null, 65 _backGroundImageTextureSize: null, 66 _layoutType: null, 67 ctor: function () { 68 ccs.UIWidget.prototype.ctor.call(this); 69 this._clippingEnabled = false; 70 this._backGroundScale9Enabled = false; 71 this._backGroundImage = null; 72 this._backGroundImageFileName = ""; 73 this._backGroundImageCapInsets = cc.RectZero(); 74 this._colorType = ccs.LayoutBackGroundColorType.none; 75 this._bgImageTexType = ccs.TextureResType.local; 76 this._colorRender = null; 77 this._gradientRender = null; 78 this._color = cc.WHITE; 79 this._startColor = cc.WHITE; 80 this._endColor = cc.WHITE; 81 this._alongVector = cc.p(0, -1); 82 this._opacity = 255; 83 this._backGroundImageTextureSize = cc.SizeZero(); 84 this._layoutType = ccs.LayoutType.absolute; 85 this._widgetType = ccs.WidgetType.container; 86 }, 87 init: function () { 88 this._layoutParameterDictionary = {}; 89 this._children = []; 90 this.initRenderer(); 91 this._renderer.setZOrder(this._widgetZOrder); 92 if (this._renderer.RGBAProtocol) { 93 this._renderer.setCascadeColorEnabled(false); 94 this._renderer.setCascadeOpacityEnabled(false); 95 } 96 this.ignoreContentAdaptWithSize(false); 97 this.setSize(cc.SizeZero()); 98 this.setBright(true); 99 this.setAnchorPoint(cc.p(0, 0)); 100 this._scheduler = cc.Director.getInstance().getScheduler(); 101 return true; 102 }, 103 104 initRenderer: function () { 105 this._renderer = ccs.UIRectClippingNode.create(); 106 }, 107 108 /** 109 * Adds a locChild to the container. 110 * @param {ccs.UIWidget} locChild 111 * @returns {boolean} 112 */ 113 addChild: function (locChild) { 114 this.supplyTheLayoutParameterLackToChild(locChild); 115 return ccs.UIWidget.prototype.addChild.call(this, locChild); 116 }, 117 118 /** 119 * Gets if layout is clipping enabled. 120 * @returns {Boolean} 121 */ 122 isClippingEnabled: function () { 123 return this._clippingEnabled; 124 }, 125 126 hitTest: function (pt) { 127 var nsp = this._renderer.convertToNodeSpace(pt); 128 var bb = cc.rect(0.0, 0, this._size.width, this._size.height); 129 if (nsp.x >= bb.x && nsp.x <= bb.x + bb.width && nsp.y >= bb.y && nsp.y <= bb.y + bb.height) { 130 return true; 131 } 132 return false; 133 }, 134 135 /** 136 * Changes if layout can clip it's content and locChild. 137 * @param {Boolean} able 138 */ 139 setClippingEnabled: function (able) { 140 this._clippingEnabled = able; 141 if (this._renderer instanceof ccs.UIRectClippingNode) 142 this._renderer.setClippingEnabled(able); 143 }, 144 145 onSizeChanged: function () { 146 if (this._renderer instanceof ccs.UIRectClippingNode) 147 this._renderer.setClippingSize(this._size); 148 if(this.getDescription() == "Layout"){ 149 for (var i = 0; i < this._children.length; i++) { 150 var child = this._children[i]; 151 child.updateSizeAndPosition(); 152 } 153 this.doLayout(); 154 } 155 if (this._backGroundImage) { 156 this._backGroundImage.setPosition(cc.p(this._size.width / 2.0, this._size.height / 2.0)); 157 if (this._backGroundScale9Enabled) { 158 if (this._backGroundImage instanceof cc.Scale9Sprite) { 159 this._backGroundImage.setPreferredSize(this._size); 160 } 161 } 162 } 163 if (this._colorRender) { 164 this._colorRender.setContentSize(this._size); 165 } 166 if (this._gradientRender) { 167 this._gradientRender.setContentSize(this._size); 168 } 169 }, 170 171 /** 172 * Sets background iamge use scale9 renderer. 173 * @param {Boolean} able 174 */ 175 setBackGroundImageScale9Enabled: function (able) { 176 if (this._backGroundScale9Enabled == able) { 177 return; 178 } 179 this._renderer.removeChild(this._backGroundImage, true); 180 this._backGroundImage = null; 181 this._backGroundScale9Enabled = able; 182 if (this._backGroundScale9Enabled) { 183 this._backGroundImage = cc.Scale9Sprite.create(); 184 } 185 else { 186 this._backGroundImage = cc.Sprite.create(); 187 } 188 this._renderer.addChild(this._backGroundImage); 189 this._backGroundImage.setZOrder(-1); 190 this.setBackGroundImage(this._backGroundImageFileName, this._bgImageTexType); 191 this.setBackGroundImageCapInsets(this._backGroundImageCapInsets); 192 }, 193 194 /** 195 * Sets a background image for layout 196 * @param {String} fileName 197 * @param {ccs.TextureResType} texType 198 */ 199 setBackGroundImage: function (fileName, texType) { 200 if (!fileName) { 201 return; 202 } 203 texType = texType || ccs.TextureResType.local; 204 if (this._backGroundImage == null) { 205 this.addBackGroundImage(); 206 } 207 this._backGroundImageFileName = fileName; 208 this._bgImageTexType = texType; 209 if (this._backGroundScale9Enabled) { 210 switch (this._bgImageTexType) { 211 case ccs.TextureResType.local: 212 this._backGroundImage.initWithFile(fileName); 213 break; 214 case ccs.TextureResType.plist: 215 this._backGroundImage.initWithSpriteFrameName(fileName); 216 break; 217 default: 218 break; 219 } 220 this._backGroundImage.setPreferredSize(this._size); 221 } 222 else { 223 switch (this._bgImageTexType) { 224 case ccs.TextureResType.local: 225 this._backGroundImage.initWithFile(fileName); 226 break; 227 case ccs.TextureResType.plist: 228 this._backGroundImage.initWithSpriteFrameName(fileName); 229 break; 230 default: 231 break; 232 } 233 } 234 if (this._backGroundScale9Enabled) { 235 this._backGroundImage.setColor(this.getColor()); 236 this._backGroundImage.setOpacity(this.getOpacity()); 237 } 238 else { 239 this._backGroundImage.setColor(this.getColor()); 240 this._backGroundImage.setOpacity(this.getOpacity()); 241 } 242 this._backGroundImageTextureSize = this._backGroundImage.getContentSize(); 243 this._backGroundImage.setPosition(cc.p(this._size.width / 2.0, this._size.height / 2.0)); 244 }, 245 246 /** 247 * Sets a background image capinsets for layout, if the background image is a scale9 render. 248 * @param {cc.Rect} capInsets 249 */ 250 setBackGroundImageCapInsets: function (capInsets) { 251 this._backGroundImageCapInsets = capInsets; 252 if (this._backGroundScale9Enabled) { 253 this._backGroundImage.setCapInsets(capInsets); 254 } 255 }, 256 257 supplyTheLayoutParameterLackToChild: function (locChild) { 258 if (!locChild) { 259 return; 260 } 261 switch (this._layoutType) { 262 case ccs.LayoutType.absolute: 263 break; 264 case ccs.LayoutType.linearHorizontal: 265 case ccs.LayoutType.linearVertical: 266 var layoutParameter = locChild.getLayoutParameter(ccs.LayoutParameterType.linear); 267 if (!layoutParameter) { 268 locChild.setLayoutParameter(ccs.UILinearLayoutParameter.create()); 269 } 270 break; 271 case ccs.LayoutType.relative: 272 var layoutParameter = locChild.getLayoutParameter(ccs.LayoutParameterType.relative); 273 if (!layoutParameter) { 274 locChild.setLayoutParameter(ccs.UIRelativeLayoutParameter.create()); 275 } 276 break; 277 default: 278 break; 279 } 280 }, 281 282 /** 283 * init background image renderer. 284 */ 285 addBackGroundImage: function () { 286 if (this._backGroundScale9Enabled) { 287 this._backGroundImage = cc.Scale9Sprite.create(); 288 this._backGroundImage.setZOrder(-1); 289 this._renderer.addChild(this._backGroundImage); 290 this._backGroundImage.setPreferredSize(this._size); 291 } 292 else { 293 this._backGroundImage = cc.Sprite.create(); 294 this._backGroundImage.setZOrder(-1); 295 this._renderer.addChild(this._backGroundImage); 296 } 297 this._backGroundImage.setPosition(cc.p(this._size.width / 2.0, this._size.height / 2.0)); 298 }, 299 300 /** 301 * Remove the background image of layout. 302 */ 303 removeBackGroundImage: function () { 304 if (!this._backGroundImage) { 305 return; 306 } 307 this._renderer.removeChild(this._backGroundImage, true); 308 this._backGroundImage = null; 309 this._backGroundImageFileName = ""; 310 this._backGroundImageTextureSize = cc.SizeZero(); 311 }, 312 313 /** 314 * Sets Color Type for layout. 315 * @param {ccs.LayoutBackGroundColorType} type 316 */ 317 setBackGroundColorType: function (type) { 318 if (this._colorType == type) { 319 return; 320 } 321 switch (this._colorType) { 322 case ccs.LayoutBackGroundColorType.none: 323 if (this._colorRender) { 324 this._renderer.removeChild(this._colorRender, true); 325 this._colorRender = null; 326 } 327 if (this._gradientRender) { 328 this._renderer.removeChild(this._gradientRender, true); 329 this._gradientRender = null; 330 } 331 break; 332 case ccs.LayoutBackGroundColorType.solid: 333 if (this._colorRender) { 334 this._renderer.removeChild(this._colorRender, true); 335 this._colorRender = null; 336 } 337 break; 338 case ccs.LayoutBackGroundColorType.gradient: 339 if (this._gradientRender) { 340 this._renderer.removeChild(this._gradientRender, true); 341 this._gradientRender = null; 342 } 343 break; 344 default: 345 break; 346 } 347 this._colorType = type; 348 switch (this._colorType) { 349 case ccs.LayoutBackGroundColorType.none: 350 break; 351 case ccs.LayoutBackGroundColorType.solid: 352 this._colorRender = cc.LayerColor.create(); 353 this._colorRender.setContentSize(this._size); 354 this._colorRender.setOpacity(this._opacity); 355 this._colorRender.setColor(this._color); 356 this._renderer.addChild(this._colorRender, -2); 357 break; 358 case ccs.LayoutBackGroundColorType.gradient: 359 this._gradientRender = cc.LayerGradient.create(cc.c4b(255, 0, 0, 255), cc.c4b(0, 255, 0, 255)); 360 this._gradientRender.setContentSize(this._size); 361 this._gradientRender.setOpacity(this._opacity); 362 this._gradientRender.setStartColor(this._startColor); 363 this._gradientRender.setEndColor(this._endColor); 364 this._gradientRender.setVector(this._alongVector); 365 this._renderer.addChild(this._gradientRender, -2); 366 break; 367 default: 368 break; 369 } 370 }, 371 372 /** 373 * Sets background color for layout, if color type is LAYOUT_COLOR_SOLID 374 * @param {cc.c3b} color 375 * @param {cc.c3b} endColor 376 */ 377 setBackGroundColor: function (color, endColor) { 378 if (!endColor) { 379 this._color = color; 380 if (this._colorRender) { 381 this._colorRender.setColor(color); 382 } 383 } else { 384 this._startColor = color; 385 if (this._gradientRender) { 386 this._gradientRender.setStartColor(color); 387 } 388 this._endColor = endColor; 389 if (this._gradientRender) { 390 this._gradientRender.setEndColor(endColor); 391 } 392 } 393 }, 394 395 /** 396 * Sets background opacity layout. 397 * @param {number} opacity 398 */ 399 setBackGroundColorOpacity: function (opacity) { 400 this._opacity = opacity; 401 switch (this._colorType) { 402 case ccs.LayoutBackGroundColorType.none: 403 break; 404 case ccs.LayoutBackGroundColorType.solid: 405 this._colorRender.setOpacity(opacity); 406 break; 407 case ccs.LayoutBackGroundColorType.gradient: 408 this._gradientRender.setOpacity(opacity); 409 break; 410 default: 411 break; 412 } 413 }, 414 415 /** 416 * Sets background color vector for layout, if color type is LAYOUT_COLOR_GRADIENT 417 * @param {cc.Point} vector 418 */ 419 setBackGroundColorVector: function (vector) { 420 this._alongVector = vector; 421 if (this._gradientRender) { 422 this._gradientRender.setVector(vector); 423 } 424 }, 425 426 /** 427 * Sets background color 428 * @param {cc.c3b} color 429 */ 430 setColor: function (color) { 431 ccs.UIWidget.prototype.setColor.call(this, color); 432 if (this._backGroundImage) { 433 if (this._backGroundImage.RGBAProtocol) { 434 this._backGroundImage.setColor(color); 435 } 436 } 437 }, 438 439 /** 440 * Sets background opacity 441 * @param {number} opacity 442 */ 443 setOpacity: function (opacity) { 444 ccs.UIWidget.prototype.setOpacity.call(this, opacity); 445 if (this._backGroundImage) { 446 if (this._backGroundImage.RGBAProtocol) { 447 this._backGroundImage.setOpacity(opacity); 448 } 449 } 450 }, 451 452 /** 453 * Gets background image texture size. 454 * @returns {cc.Size} 455 */ 456 getBackGroundImageTextureSize: function () { 457 return this._backGroundImageTextureSize; 458 }, 459 460 /** 461 * Gets the content size of widget. 462 * @returns {cc.Size} 463 */ 464 getContentSize: function () { 465 return this._renderer.getContentSize(); 466 }, 467 468 /** 469 * Sets LayoutType. 470 * @param {ccs.LayoutType} type 471 */ 472 setLayoutType: function (type) { 473 this._layoutType = type; 474 var layoutChildrenArray = this.getChildren(); 475 var locChild = null; 476 for (var i = 0; i < layoutChildrenArray.length; i++) { 477 locChild = layoutChildrenArray[i]; 478 this.supplyTheLayoutParameterLackToChild(locChild); 479 } 480 }, 481 482 /** 483 * Gets LayoutType. 484 * @returns {null} 485 */ 486 getLayoutType: function () { 487 return this._layoutType; 488 }, 489 490 doLayout_LINEAR_VERTICAL: function () { 491 var layoutChildrenArray = this.getChildren(); 492 var layoutSize = this.getSize(); 493 var topBoundary = layoutSize.height; 494 for (var i = 0; i < layoutChildrenArray.length; ++i) { 495 var locChild = layoutChildrenArray[i]; 496 var locLayoutParameter = locChild.getLayoutParameter(ccs.LayoutParameterType.linear); 497 498 if (locLayoutParameter) { 499 var locChildGravity = locLayoutParameter.getGravity(); 500 var locAP = locChild.getAnchorPoint(); 501 var locSize = locChild.getSize(); 502 var locFinalPosX = locAP.x * locSize.width; 503 var locFinalPosY = topBoundary - ((1 - locAP.y) * locSize.height); 504 switch (locChildGravity) { 505 case ccs.UILinearGravity.none: 506 case ccs.UILinearGravity.left: 507 break; 508 case ccs.UILinearGravity.right: 509 locFinalPosX = layoutSize.width - ((1 - locAP.x) * locSize.width); 510 break; 511 case ccs.UILinearGravity.centerHorizontal: 512 locFinalPosX = layoutSize.width / 2 - locSize.width * (0.5 - locAP.x); 513 break; 514 default: 515 break; 516 } 517 var locMargin = locLayoutParameter.getMargin(); 518 locFinalPosX += locMargin.left; 519 locFinalPosY -= locMargin.top; 520 locChild.setPosition(cc.p(locFinalPosX, locFinalPosY)); 521 topBoundary = locChild.getBottomInParent() - locMargin.bottom; 522 } 523 } 524 }, 525 doLayout_LINEAR_HORIZONTAL: function () { 526 var layoutChildrenArray = this.getChildren(); 527 var layoutSize = this.getSize(); 528 var leftBoundary = 0; 529 for (var i = 0; i < layoutChildrenArray.length; ++i) { 530 var locChild = layoutChildrenArray[i]; 531 var locLayoutParameter = locChild.getLayoutParameter(ccs.LayoutParameterType.linear); 532 533 if (locLayoutParameter) { 534 var locChildGravity = locLayoutParameter.getGravity(); 535 var locAP = locChild.getAnchorPoint(); 536 var locSize = locChild.getSize(); 537 var locFinalPosX = leftBoundary + (locAP.x * locSize.width); 538 var locFinalPosY = layoutSize.height - (1 - locAP.y) * locSize.height; 539 switch (locChildGravity) { 540 case ccs.UILinearGravity.none: 541 case ccs.UILinearGravity.top: 542 break; 543 case ccs.UILinearGravity.bottom: 544 locFinalPosY = locAP.y * locSize.height; 545 break; 546 case ccs.UILinearGravity.centerVertical: 547 locFinalPosY = layoutSize.height / 2 - locSize.height * (0.5 - locAP.y); 548 break; 549 default: 550 break; 551 } 552 var locMargin = locLayoutParameter.getMargin(); 553 locFinalPosX += locMargin.left; 554 locFinalPosY -= locMargin.top; 555 locChild.setPosition(cc.p(locFinalPosX, locFinalPosY)); 556 leftBoundary = locChild.getRightInParent() + locMargin.right; 557 } 558 } 559 }, 560 doLayout_RELATIVE: function () { 561 var layoutChildrenArray = this.getChildren(); 562 var length = layoutChildrenArray.length; 563 var unlayoutChildCount = length; 564 var layoutSize = this.getSize(); 565 566 for (var i = 0; i < length; i++) { 567 var locChild = layoutChildrenArray[i]; 568 var locLayoutParameter = locChild.getLayoutParameter(ccs.LayoutParameterType.relative); 569 locLayoutParameter._put = false; 570 } 571 572 while (unlayoutChildCount > 0) { 573 for (var i = 0; i < length; i++) { 574 var locChild = layoutChildrenArray[i]; 575 var locLayoutParameter = locChild.getLayoutParameter(ccs.LayoutParameterType.relative); 576 577 if (locLayoutParameter) { 578 if (locLayoutParameter._put) { 579 continue; 580 } 581 var locAP = locChild.getAnchorPoint(); 582 var locSize = locChild.getSize(); 583 var locAlign = locLayoutParameter.getAlign(); 584 var locRelativeName = locLayoutParameter.getRelativeToWidgetName(); 585 var locRelativeWidget = null; 586 var locRelativeWidgetLP = null; 587 var locFinalPosX = 0; 588 var locFinalPosY = 0; 589 if (locRelativeName) { 590 locRelativeWidget = ccs.UIHelper.seekWidgetByRelativeName(this, locRelativeName); 591 if (locRelativeWidget) { 592 locRelativeWidgetLP = locRelativeWidget.getLayoutParameter(ccs.LayoutParameterType.relative); 593 } 594 } 595 switch (locAlign) { 596 case ccs.UIRelativeAlign.alignNone: 597 case ccs.UIRelativeAlign.alignParentTopLeft: 598 locFinalPosX = locAP.x * locSize.width; 599 locFinalPosY = layoutSize.height - ((1 - locAP.y) * locSize.height); 600 break; 601 case ccs.UIRelativeAlign.alignParentTopCenterHorizontal: 602 locFinalPosX = layoutSize.width * 0.5 - locSize.width * (0.5 - locAP.x); 603 locFinalPosY = layoutSize.height - ((1 - locAP.y) * locSize.height); 604 break; 605 case ccs.UIRelativeAlign.alignParentTopRight: 606 locFinalPosX = layoutSize.width - ((1 - locAP.x) * locSize.width); 607 locFinalPosY = layoutSize.height - ((1 - locAP.y) * locSize.height); 608 break; 609 case ccs.UIRelativeAlign.alignParentLeftCenterVertical: 610 locFinalPosX = locAP.x * locSize.width; 611 locFinalPosY = layoutSize.height * 0.5 - locSize.height * (0.5 - locAP.y); 612 break; 613 case ccs.UIRelativeAlign.centerInParent: 614 locFinalPosX = layoutSize.width * 0.5 - locSize.width * (0.5 - locAP.x); 615 locFinalPosY = layoutSize.height * 0.5 - locSize.height * (0.5 - locAP.y); 616 break; 617 case ccs.UIRelativeAlign.alignParentRightCenterVertical: 618 locFinalPosX = layoutSize.width - ((1 - locAP.x) * locSize.width); 619 locFinalPosY = layoutSize.height * 0.5 - locSize.height * (0.5 - locAP.y); 620 break; 621 case ccs.UIRelativeAlign.alignParentLeftBottom: 622 locFinalPosX = locAP.x * locSize.width; 623 locFinalPosY = locAP.y * locSize.height; 624 break; 625 case ccs.UIRelativeAlign.alignParentBottomCenterHorizontal: 626 locFinalPosX = layoutSize.width * 0.5 - locSize.width * (0.5 - locAP.x); 627 locFinalPosY = locAP.y * locSize.height; 628 break; 629 case ccs.UIRelativeAlign.alignParentRightBottom: 630 locFinalPosX = layoutSize.width - ((1 - locAP.x) * locSize.width); 631 locFinalPosY = locAP.y * locSize.height; 632 break; 633 634 case ccs.UIRelativeAlign.locationAboveLeftAlign: 635 if (locRelativeWidget) { 636 if (locRelativeWidgetLP && !locRelativeWidgetLP._put) { 637 continue; 638 } 639 var locationBottom = locRelativeWidget.getTopInParent(); 640 var locationLeft = locRelativeWidget.getLeftInParent(); 641 locFinalPosY = locationBottom + locAP.y * locSize.height; 642 locFinalPosX = locationLeft + locAP.x * locSize.width; 643 } 644 break; 645 case ccs.UIRelativeAlign.locationAboveCenter: 646 if (locRelativeWidget) { 647 if (locRelativeWidgetLP && !locRelativeWidgetLP._put) { 648 continue; 649 } 650 var rbs = locRelativeWidget.getSize(); 651 var locationBottom = locRelativeWidget.getTopInParent(); 652 653 locFinalPosY = locationBottom + locAP.y * locSize.height; 654 locFinalPosX = locRelativeWidget.getLeftInParent() + rbs.width * 0.5 + locAP.x * locSize.width - locSize.width * 0.5; 655 } 656 break; 657 case ccs.UIRelativeAlign.locationAboveRightAlign: 658 if (locRelativeWidget) { 659 if (locRelativeWidgetLP && !locRelativeWidgetLP._put) { 660 continue; 661 } 662 var locationBottom = locRelativeWidget.getTopInParent(); 663 var locationRight = locRelativeWidget.getRightInParent(); 664 locFinalPosY = locationBottom + locAP.y * locSize.height; 665 locFinalPosX = locationRight - (1 - locAP.x) * locSize.width; 666 } 667 break; 668 case ccs.UIRelativeAlign.locationLeftOfTopAlign: 669 if (locRelativeWidget) { 670 if (locRelativeWidgetLP && !locRelativeWidgetLP._put) { 671 continue; 672 } 673 var locationTop = locRelativeWidget.getTopInParent(); 674 var locationRight = locRelativeWidget.getLeftInParent(); 675 locFinalPosY = locationTop - (1 - locAP.y) * locSize.height; 676 locFinalPosX = locationRight - (1 - locAP.x) * locSize.width; 677 } 678 break; 679 case ccs.UIRelativeAlign.locationLeftOfCenter: 680 if (locRelativeWidget) { 681 if (locRelativeWidgetLP && !locRelativeWidgetLP._put) { 682 continue; 683 } 684 var rbs = locRelativeWidget.getSize(); 685 var locationRight = locRelativeWidget.getLeftInParent(); 686 locFinalPosX = locationRight - (1 - locAP.x) * locSize.width; 687 688 locFinalPosY = locRelativeWidget.getBottomInParent() + rbs.height * 0.5 + locAP.y * locSize.height - locSize.height * 0.5; 689 } 690 break; 691 case ccs.UIRelativeAlign.locationLeftOfBottomAlign: 692 if (locRelativeWidget) { 693 if (locRelativeWidgetLP && !locRelativeWidgetLP._put) { 694 continue; 695 } 696 var locationBottom = locRelativeWidget.getBottomInParent(); 697 var locationRight = locRelativeWidget.getLeftInParent(); 698 locFinalPosY = locationBottom + locAP.y * locSize.height; 699 locFinalPosX = locationRight - (1 - locAP.x) * locSize.width; 700 } 701 break; 702 case ccs.UIRelativeAlign.locationRightOfTopAlign: 703 if (locRelativeWidget) { 704 if (locRelativeWidgetLP && !locRelativeWidgetLP._put) { 705 continue; 706 } 707 var locationTop = locRelativeWidget.getTopInParent(); 708 var locationLeft = locRelativeWidget.getRightInParent(); 709 locFinalPosY = locationTop - (1 - locAP.y) * locSize.height; 710 locFinalPosX = locationLeft + locAP.x * locSize.width; 711 } 712 break; 713 case ccs.UIRelativeAlign.locationRightOfCenter: 714 if (locRelativeWidget) { 715 if (locRelativeWidgetLP && !locRelativeWidgetLP._put) { 716 continue; 717 } 718 var rbs = locRelativeWidget.getSize(); 719 var locationLeft = locRelativeWidget.getRightInParent(); 720 locFinalPosX = locationLeft + locAP.x * locSize.width; 721 722 locFinalPosY = locRelativeWidget.getBottomInParent() + rbs.height * 0.5 + locAP.y * locSize.height - locSize.height * 0.5; 723 } 724 break; 725 case ccs.UIRelativeAlign.locationRightOfBottomAlign: 726 if (locRelativeWidget) { 727 if (locRelativeWidgetLP && !locRelativeWidgetLP._put) { 728 continue; 729 } 730 var locationBottom = locRelativeWidget.getBottomInParent(); 731 var locationLeft = locRelativeWidget.getRightInParent(); 732 locFinalPosY = locationBottom + locAP.y * locSize.height; 733 locFinalPosX = locationLeft + locAP.x * locSize.width; 734 } 735 break; 736 case ccs.UIRelativeAlign.locationBelowLeftAlign: 737 if (locRelativeWidget) { 738 if (locRelativeWidgetLP && !locRelativeWidgetLP._put) { 739 continue; 740 } 741 var locationTop = locRelativeWidget.getBottomInParent(); 742 var locationLeft = locRelativeWidget.getLeftInParent(); 743 locFinalPosY = locationTop - (1 - locAP.y) * locSize.height; 744 locFinalPosX = locationLeft + locAP.x * locSize.width; 745 } 746 break; 747 case ccs.UIRelativeAlign.locationBelowCenter: 748 if (locRelativeWidget) { 749 if (locRelativeWidgetLP && !locRelativeWidgetLP._put) { 750 continue; 751 } 752 var rbs = locRelativeWidget.getSize(); 753 var locationTop = locRelativeWidget.getBottomInParent(); 754 755 locFinalPosY = locationTop - (1 - locAP.y) * locSize.height; 756 locFinalPosX = locRelativeWidget.getLeftInParent() + rbs.width * 0.5 + locAP.x * locSize.width - locSize.width * 0.5; 757 } 758 break; 759 case ccs.UIRelativeAlign.locationBelowRightAlign: 760 if (locRelativeWidget) { 761 if (locRelativeWidgetLP && !locRelativeWidgetLP._put) { 762 continue; 763 } 764 var locationTop = locRelativeWidget.getBottomInParent(); 765 var locationRight = locRelativeWidget.getRightInParent(); 766 locFinalPosY = locationTop - (1 - locAP.y) * locSize.height; 767 locFinalPosX = locationRight - (1 - locAP.x) * locSize.width; 768 } 769 break; 770 default: 771 break; 772 } 773 var locRelativeWidgetMargin; 774 var locMargin = locLayoutParameter.getMargin(); 775 if (locRelativeWidget) { 776 locRelativeWidgetMargin = locRelativeWidget.getLayoutParameter(ccs.LayoutParameterType.relative).getMargin(); 777 } 778 //handle margin 779 switch (locAlign) { 780 case ccs.UIRelativeAlign.alignNone: 781 case ccs.UIRelativeAlign.alignParentTopLeft: 782 locFinalPosX += locMargin.left; 783 locFinalPosY -= locMargin.top; 784 break; 785 case ccs.UIRelativeAlign.alignParentTopCenterHorizontal: 786 locFinalPosY -= locMargin.top; 787 break; 788 case ccs.UIRelativeAlign.alignParentTopRight: 789 locFinalPosX -= locMargin.right; 790 locFinalPosY -= locMargin.top; 791 break; 792 case ccs.UIRelativeAlign.alignParentLeftCenterVertical: 793 locFinalPosX += locMargin.left; 794 break; 795 case ccs.UIRelativeAlign.centerInParent: 796 break; 797 case ccs.UIRelativeAlign.alignParentRightCenterVertical: 798 locFinalPosX -= locMargin.right; 799 break; 800 case ccs.UIRelativeAlign.alignParentLeftBottom: 801 locFinalPosX += locMargin.left; 802 locFinalPosY += locMargin.bottom; 803 break; 804 case ccs.UIRelativeAlign.alignParentBottomCenterHorizontal: 805 locFinalPosY += locMargin.bottom; 806 break; 807 case ccs.UIRelativeAlign.alignParentRightBottom: 808 locFinalPosX -= locMargin.right; 809 locFinalPosY += locMargin.bottom; 810 break; 811 812 case ccs.UIRelativeAlign.locationAboveLeftAlign: 813 case ccs.UIRelativeAlign.locationAboveCenter: 814 case ccs.UIRelativeAlign.locationAboveRightAlign: 815 locFinalPosY += locMargin.bottom; 816 locFinalPosY += locRelativeWidgetMargin.top; 817 break; 818 case ccs.UIRelativeAlign.locationLeftOfTopAlign: 819 case ccs.UIRelativeAlign.locationLeftOfCenter: 820 case ccs.UIRelativeAlign.locationLeftOfBottomAlign: 821 locFinalPosX -= locMargin.right; 822 locFinalPosX -= locRelativeWidgetMargin.left; 823 break; 824 case ccs.UIRelativeAlign.locationRightOfTopAlign: 825 case ccs.UIRelativeAlign.locationRightOfCenter: 826 case ccs.UIRelativeAlign.locationRightOfBottomAlign: 827 locFinalPosX += locMargin.left; 828 locFinalPosX += locRelativeWidgetMargin.right; 829 break; 830 case ccs.UIRelativeAlign.locationBelowLeftAlign: 831 case ccs.UIRelativeAlign.locationBelowCenter: 832 case ccs.UIRelativeAlign.locationBelowRightAlign: 833 locFinalPosY -= locMargin.top; 834 locFinalPosY -= locRelativeWidgetMargin.bottom; 835 break; 836 default: 837 break; 838 } 839 locChild.setPosition(cc.p(locFinalPosX, locFinalPosY)); 840 locLayoutParameter._put = true; 841 unlayoutChildCount--; 842 } 843 } 844 } 845 }, 846 doLayout: function () { 847 switch (this._layoutType) { 848 case ccs.LayoutType.absolute: 849 break; 850 case ccs.LayoutType.linearVertical: 851 this.doLayout_LINEAR_VERTICAL(); 852 break; 853 case ccs.LayoutType.linearHorizontal: 854 this.doLayout_LINEAR_HORIZONTAL(); 855 break; 856 case ccs.LayoutType.relative: 857 this.doLayout_RELATIVE(); 858 break; 859 default: 860 break; 861 } 862 }, 863 864 /** 865 * Returns the "class name" of widget. 866 * @returns {string} 867 */ 868 getDescription: function () { 869 return "Layout"; 870 }, 871 872 createCloneInstance: function () { 873 return ccs.UILayout.create(); 874 }, 875 876 copyClonedWidgetChildren: function (model) { 877 ccs.UIWidget.prototype.copyClonedWidgetChildren.call(this, model); 878 this.doLayout(); 879 }, 880 881 copySpecialProperties: function (layout) { 882 this.setBackGroundImageScale9Enabled(layout._backGroundScale9Enabled); 883 this.setBackGroundImage(layout._backGroundImageFileName, layout._bgImageTexType); 884 this.setBackGroundImageCapInsets(layout._backGroundImageCapInsets); 885 this.setBackGroundColorType(layout._colorType); 886 this.setBackGroundColor(layout._color); 887 this.setBackGroundColor(layout._startColor, layout._endColor); 888 this.setBackGroundColorOpacity(layout._opacity); 889 this.setBackGroundColorVector(layout._alongVector); 890 this.setLayoutType(layout._layoutType); 891 this.setClippingEnabled(layout._clippingEnabled); 892 } 893 }); 894 /** 895 * allocates and initializes a UILayout. 896 * @constructs 897 * @return {ccs.UILayout} 898 * @example 899 * // example 900 * var uiLayout = ccs.UILayout.create(); 901 */ 902 ccs.UILayout.create = function () { 903 var layout = new ccs.UILayout(); 904 if (layout && layout.init()) { 905 return layout; 906 } 907 return null; 908 }; 909 910 ccs.UIRectClippingNode = cc.ClippingNode.extend({ 911 _innerStencil: null, 912 _enabled: null, 913 _arrRect: null, 914 _clippingSize: null, 915 _clippingEnabled: null, 916 ctor: function () { 917 cc.ClippingNode.prototype.ctor.call(this); 918 this._innerStencil = null; 919 this._enabled = true; 920 this._arrRect = []; 921 this._clippingSize = cc.size(50, 50); 922 this._clippingEnabled = false; 923 }, 924 925 init: function () { 926 this._innerStencil = cc.DrawNode.create(); 927 this._arrRect[0] = cc.p(0, 0); 928 this._arrRect[1] = cc.p(this._clippingSize.width, 0); 929 this._arrRect[2] = cc.p(this._clippingSize.width, this._clippingSize.height); 930 this._arrRect[3] = cc.p(0, this._clippingSize.height); 931 932 var green = cc.c4f(0, 1, 0, 1); 933 this._innerStencil.drawPoly(this._arrRect, 4, green, 0, green); 934 if (cc.Browser.supportWebGL) { 935 if (cc.ClippingNode.prototype.init.call(this, this._innerStencil)) { 936 return true; 937 } 938 } else { 939 this._stencil = this._innerStencil; 940 this._alphaThreshold = 1; 941 this._inverted = false; 942 return true; 943 } 944 945 return false; 946 }, 947 948 setClippingSize: function (size) { 949 this.setContentSize(size); 950 this._clippingSize = cc.size(size.width, size.height); 951 this._arrRect[0] = cc.p(0, 0); 952 this._arrRect[1] = cc.p(this._clippingSize.width, 0); 953 this._arrRect[2] = cc.p(this._clippingSize.width, this._clippingSize.height); 954 this._arrRect[3] = cc.p(0, this._clippingSize.height); 955 var green = cc.c4f(0, 1, 0, 1); 956 this._innerStencil.clear(); 957 this._innerStencil.drawPoly(this._arrRect, 4, green, 0, green); 958 }, 959 960 setClippingEnabled: function (enabled) { 961 this._clippingEnabled = enabled; 962 }, 963 964 visit: function (ctx) { 965 if (!this._enabled) { 966 return; 967 } 968 if (this._clippingEnabled) { 969 if (cc.Browser.supportWebGL) { 970 cc.ClippingNode.prototype.visit.call(this, ctx); 971 } else { 972 this.visitCanvas(ctx); 973 } 974 } 975 else { 976 cc.Node.prototype.visit.call(this, ctx); 977 } 978 }, 979 980 visitCanvas: function (ctx) { 981 // quick return if not visible 982 if (!this._visible) 983 return; 984 985 //visit for canvas 986 var context = ctx || cc.renderContext, i; 987 var children = this._children, locChild; 988 context.save(); 989 this.transform(context); 990 context.beginPath(); 991 var locContentSize = this.getContentSize(); 992 var locRect = cc.rect(0, 0, locContentSize.width, locContentSize.height); 993 var locEGL_ScaleX = cc.EGLView.getInstance().getScaleX(), locEGL_ScaleY = cc.EGLView.getInstance().getScaleY(); 994 995 context.rect(locRect.x * locEGL_ScaleX, locRect.y * locEGL_ScaleY, locRect.width * locEGL_ScaleX, -locRect.height * locEGL_ScaleY); 996 context.clip(); 997 context.closePath(); 998 var len = children.length; 999 if (len > 0) { 1000 this.sortAllChildren(); 1001 // draw children zOrder < 0 1002 for (i = 0; i < len; i++) { 1003 locChild = children[i]; 1004 if (locChild._zOrder < 0) 1005 locChild.visit(context); 1006 else 1007 break; 1008 } 1009 this.draw(context); 1010 for (; i < len; i++) { 1011 children[i].visit(context); 1012 } 1013 } else 1014 this.draw(context); 1015 1016 this._orderOfArrival = 0; 1017 context.restore(); 1018 }, 1019 1020 setEnabled: function (enabled) { 1021 this._enabled = enabled; 1022 }, 1023 1024 isEnabled: function () { 1025 return this._enabled; 1026 } 1027 }); 1028 ccs.UIRectClippingNode.create = function () { 1029 var node = new ccs.UIRectClippingNode(); 1030 if (node && node.init()) { 1031 return node; 1032 } 1033 return null; 1034 };