Skip to content

Commit 78c44fa

Browse files
committed
brought in PR 18651
cocos2d#18651
1 parent 1b974bc commit 78c44fa

File tree

4 files changed

+161
-49
lines changed

4 files changed

+161
-49
lines changed

cocos/ui/UILayout.cpp

Lines changed: 94 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ _isInterceptTouch(false),
9292
_loopFocus(false),
9393
_passFocusToChild(true),
9494
_isFocusPassing(false),
95-
_stencilRadius(0.0f)
95+
_stencilRadius(0.0f)
9696
{
9797
//no-op
9898
}
@@ -235,7 +235,11 @@ void Layout::visit(Renderer *renderer, const Mat4 &parentTransform, uint32_t par
235235
{
236236
return;
237237
}
238-
238+
239+
// STEVE: https://github.com/cocos2d/cocos2d-x/pull/18651/files
240+
if(FLAGS_TRANSFORM_DIRTY & parentFlags || _transformUpdated || _contentSizeDirty)
241+
_clippingRectDirty = true;
242+
239243
adaptRenderers();
240244
doLayout();
241245

@@ -255,7 +259,11 @@ void Layout::visit(Renderer *renderer, const Mat4 &parentTransform, uint32_t par
255259
}
256260
else
257261
{
258-
Widget::visit(renderer, parentTransform, parentFlags);
262+
//Widget::visit(renderer, parentTransform, parentFlags);
263+
264+
// STEVE: https://github.com/cocos2d/cocos2d-x/pull/18651/files
265+
//no need to adapt render again
266+
ProtectedNode::visit(renderer, parentTransform, parentFlags);
259267
}
260268
}
261269

@@ -460,10 +468,21 @@ const Rect& Layout::getClippingRect()
460468
{
461469
if (_clippingRectDirty)
462470
{
463-
Vec2 worldPos = convertToWorldSpace(Vec2::ZERO);
464-
AffineTransform t = getNodeToWorldAffineTransform();
465-
float scissorWidth = _contentSize.width*t.a;
466-
float scissorHeight = _contentSize.height*t.d;
471+
// STEVE: https://github.com/cocos2d/cocos2d-x/pull/18651/files
472+
// Vec2 worldPos = convertToWorldSpace(Vec2::ZERO);
473+
// AffineTransform t = getNodeToWorldAffineTransform();
474+
475+
Vec2 worldPos1 = convertToWorldSpace(Vec2::ZERO);
476+
Vec2 worldPos2 = convertToWorldSpace(Vec2(_contentSize.width, _contentSize.height));
477+
//Node can be flipped
478+
Vec2 worldPos = Vec2(std::min(worldPos1.x, worldPos2.x), std::min(worldPos1.y, worldPos2.y));
479+
480+
// STEVE: https://github.com/cocos2d/cocos2d-x/pull/18651/files
481+
// float scissorWidth = _contentSize.width*t.a;
482+
// float scissorHeight = _contentSize.height*t.d;
483+
float scissorWidth = fabs(worldPos2.x - worldPos1.x);
484+
float scissorHeight = fabs(worldPos2.y - worldPos1.y);
485+
467486
Rect parentClippingRect;
468487
Layout* parent = this;
469488

@@ -479,54 +498,80 @@ const Rect& Layout::getClippingRect()
479498
}
480499
}
481500
}
482-
501+
502+
// STEVE: https://github.com/cocos2d/cocos2d-x/pull/18651/files
503+
// if (_clippingParent)
504+
// {
505+
// parentClippingRect = _clippingParent->getClippingRect();
506+
// float finalX = worldPos.x - (scissorWidth * _anchorPoint.x);
507+
// float finalY = worldPos.y - (scissorHeight * _anchorPoint.y);
508+
// float finalWidth = scissorWidth;
509+
// float finalHeight = scissorHeight;
510+
//
511+
// float leftOffset = worldPos.x - parentClippingRect.origin.x;
512+
// if (leftOffset < 0.0f)
513+
// {
514+
// finalX = parentClippingRect.origin.x;
515+
// finalWidth += leftOffset;
516+
// }
517+
// float rightOffset = (worldPos.x + scissorWidth) - (parentClippingRect.origin.x + parentClippingRect.size.width);
518+
// if (rightOffset > 0.0f)
519+
// {
520+
// finalWidth -= rightOffset;
521+
// }
522+
// float topOffset = (worldPos.y + scissorHeight) - (parentClippingRect.origin.y + parentClippingRect.size.height);
523+
// if (topOffset > 0.0f)
524+
// {
525+
// finalHeight -= topOffset;
526+
// }
527+
// float bottomOffset = worldPos.y - parentClippingRect.origin.y;
528+
// if (bottomOffset < 0.0f)
529+
// {
530+
// finalY = parentClippingRect.origin.y;
531+
// finalHeight += bottomOffset;
532+
// }
533+
// if (finalWidth < 0.0f)
534+
// {
535+
// finalWidth = 0.0f;
536+
// }
537+
// if (finalHeight < 0.0f)
538+
// {
539+
// finalHeight = 0.0f;
540+
// }
541+
// _clippingRect.origin.x = finalX;
542+
// _clippingRect.origin.y = finalY;
543+
// _clippingRect.size.width = finalWidth;
544+
// _clippingRect.size.height = finalHeight;
545+
// }
546+
// else
547+
// {
548+
// _clippingRect.origin.x = worldPos.x - (scissorWidth * _anchorPoint.x);
549+
// _clippingRect.origin.y = worldPos.y - (scissorHeight * _anchorPoint.y);
550+
// _clippingRect.size.width = scissorWidth;
551+
// _clippingRect.size.height = scissorHeight;
552+
// }
553+
// _clippingRectDirty = false;
554+
483555
if (_clippingParent)
484556
{
485557
parentClippingRect = _clippingParent->getClippingRect();
486-
float finalX = worldPos.x - (scissorWidth * _anchorPoint.x);
487-
float finalY = worldPos.y - (scissorHeight * _anchorPoint.y);
488-
float finalWidth = scissorWidth;
489-
float finalHeight = scissorHeight;
490-
491-
float leftOffset = worldPos.x - parentClippingRect.origin.x;
492-
if (leftOffset < 0.0f)
493-
{
494-
finalX = parentClippingRect.origin.x;
495-
finalWidth += leftOffset;
496-
}
497-
float rightOffset = (worldPos.x + scissorWidth) - (parentClippingRect.origin.x + parentClippingRect.size.width);
498-
if (rightOffset > 0.0f)
499-
{
500-
finalWidth -= rightOffset;
501-
}
502-
float topOffset = (worldPos.y + scissorHeight) - (parentClippingRect.origin.y + parentClippingRect.size.height);
503-
if (topOffset > 0.0f)
504-
{
505-
finalHeight -= topOffset;
506-
}
507-
float bottomOffset = worldPos.y - parentClippingRect.origin.y;
508-
if (bottomOffset < 0.0f)
509-
{
510-
finalY = parentClippingRect.origin.y;
511-
finalHeight += bottomOffset;
512-
}
513-
if (finalWidth < 0.0f)
514-
{
515-
finalWidth = 0.0f;
516-
}
517-
if (finalHeight < 0.0f)
518-
{
519-
finalHeight = 0.0f;
520-
}
521-
_clippingRect.origin.x = finalX;
522-
_clippingRect.origin.y = finalY;
523-
_clippingRect.size.width = finalWidth;
524-
_clippingRect.size.height = finalHeight;
558+
559+
// STEVE: https://github.com/cocos2d/cocos2d-x/pull/18651/files
560+
_clippingRect.origin.x = std::max(parentClippingRect.origin.x, worldPos.x);
561+
_clippingRect.origin.y = std::max(parentClippingRect.origin.y, worldPos.y);
562+
563+
float right = std::min(parentClippingRect.origin.x + parentClippingRect.size.width, worldPos.x + scissorWidth);
564+
float top = std::min(parentClippingRect.origin.y + parentClippingRect.size.height, worldPos.y + scissorHeight);
565+
566+
_clippingRect.size.width = std::max(0.0f, right - _clippingRect.origin.x);
567+
_clippingRect.size.height = std::max(0.0f, top - _clippingRect.origin.y);
525568
}
526569
else
527570
{
528-
_clippingRect.origin.x = worldPos.x - (scissorWidth * _anchorPoint.x);
529-
_clippingRect.origin.y = worldPos.y - (scissorHeight * _anchorPoint.y);
571+
// STEVE: https://github.com/cocos2d/cocos2d-x/pull/18651/files
572+
_clippingRect.origin.x = worldPos.x;
573+
_clippingRect.origin.y = worldPos.y;
574+
530575
_clippingRect.size.width = scissorWidth;
531576
_clippingRect.size.height = scissorHeight;
532577
}

cocos/ui/UIScrollView.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,8 @@ void ScrollView::startAutoScroll(const Vec2& deltaMove, float timeInSec, bool at
491491
Vec2 afterOutOfBoundary = getHowMuchOutOfBoundary(adjustedDeltaMove);
492492
if(currentOutOfBoundary.x * afterOutOfBoundary.x > 0 || currentOutOfBoundary.y * afterOutOfBoundary.y > 0)
493493
{
494+
// STEVE: added from https://github.com/cocos2d/cocos2d-x/pull/18650/files
495+
_autoScrollBrakingStartPosition = getInnerContainerPosition(); // STEVE
494496
_autoScrollBraking = true;
495497
}
496498
}

tests/cpp-tests/Classes/UITest/CocoStudioGUITest/UILayoutTest/UILayoutTest.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ UILayoutTests::UILayoutTests()
1818
ADD_TEST_CASE(UILayoutComponentTest);
1919
ADD_TEST_CASE(UILayoutComponent_Berth_Test);
2020
ADD_TEST_CASE(UILayoutComponent_Berth_Stretch_Test);
21+
ADD_TEST_CASE(UILayout_Clipping_Test);
2122
}
2223

2324
// UILayoutTest
@@ -932,3 +933,58 @@ bool UILayoutComponent_Berth_Stretch_Test::init()
932933
}
933934
return false;
934935
}
936+
937+
bool UILayout_Clipping_Test::init()
938+
{
939+
if (UIScene::init())
940+
{
941+
Size widgetSize = _widget->getContentSize();
942+
943+
// Add the alert
944+
Text* alert = Text::create("Left & Right must look same", "fonts/Marker Felt.ttf", 30 );
945+
alert->setColor(Color3B(159, 168, 176));
946+
alert->setPosition(Vec2(widgetSize.width / 2.0f,
947+
widgetSize.height / 2.0f - alert->getContentSize().height * 3.075f));
948+
949+
_uiLayer->addChild(alert);
950+
951+
Layout* layout1 = Layout::create();
952+
layout1->setClippingEnabled(true);
953+
layout1->setContentSize(Size(widgetSize.width/4, widgetSize.height/3));
954+
layout1->setClippingType(cocos2d::ui::Layout::ClippingType::SCISSOR);
955+
layout1->setPosition(Vec2(widgetSize.width / 4.0f, widgetSize.height / 2.0f ));
956+
layout1->setAnchorPoint(Vec2(0.5, 0.5));
957+
_uiLayer->addChild(layout1);
958+
959+
Layout* sublayout1 = Layout::create();
960+
sublayout1->setClippingEnabled(true);
961+
sublayout1->setBackGroundImage("cocosui/Hello.png");
962+
sublayout1->setContentSize(Size(widgetSize.width/6, widgetSize.width/2));
963+
sublayout1->setClippingType(cocos2d::ui::Layout::ClippingType::STENCIL);
964+
sublayout1->setPosition(Vec2(widgetSize.width / 8.0f + widgetSize.width / 16.0f, widgetSize.height / 6.0f ));
965+
sublayout1->setAnchorPoint(Vec2(0.5, 0.5));
966+
sublayout1->runAction(RepeatForever::create(Sequence::createWithTwoActions(MoveBy::create(2, Vec2(-widgetSize.width/8, 0)), MoveBy::create(2, Vec2(widgetSize.width/8, 0)))));
967+
layout1->addChild(sublayout1);
968+
969+
Layout* layout2 = Layout::create();
970+
layout2->setClippingEnabled(true);
971+
layout2->setContentSize(Size(widgetSize.width/4, widgetSize.height/3));
972+
layout2->setClippingType(cocos2d::ui::Layout::ClippingType::SCISSOR);
973+
layout2->setPosition(Vec2(widgetSize.width *3.0f / 4.0f, widgetSize.height / 2.0f ));
974+
layout2->setAnchorPoint(Vec2(0.5, 0.5));
975+
_uiLayer->addChild(layout2);
976+
977+
Layout* sublayout2 = Layout::create();
978+
sublayout2->setClippingEnabled(true);
979+
sublayout2->setBackGroundImage("cocosui/Hello.png");
980+
sublayout2->setContentSize(Size(widgetSize.width/6, widgetSize.width/2));
981+
sublayout2->setClippingType(cocos2d::ui::Layout::ClippingType::SCISSOR);
982+
sublayout2->setPosition(Vec2(widgetSize.width / 8.0f + widgetSize.width / 16.0f, widgetSize.height / 6.0f ));
983+
sublayout2->setAnchorPoint(Vec2(0.5, 0.5));
984+
sublayout2->runAction(RepeatForever::create(Sequence::createWithTwoActions(MoveBy::create(2, Vec2(-widgetSize.width/8, 0)), MoveBy::create(2, Vec2(widgetSize.width/8, 0)))));
985+
layout2->addChild(sublayout2);
986+
987+
return true;
988+
}
989+
return false;
990+
}

tests/cpp-tests/Classes/UITest/CocoStudioGUITest/UILayoutTest/UILayoutTest.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,4 +161,13 @@ class UILayoutComponent_Berth_Stretch_Test : public UILayoutComponentTest
161161
CREATE_FUNC(UILayoutComponent_Berth_Stretch_Test);
162162
};
163163

164+
class UILayout_Clipping_Test : public UILayoutComponentTest
165+
{
166+
public:
167+
virtual bool init() override;
168+
169+
CREATE_FUNC(UILayout_Clipping_Test);
170+
};
171+
172+
164173
#endif /* defined(__TestCpp__UILayoutTest__) */

0 commit comments

Comments
 (0)