mirror of https://github.com/axmolengine/axmol.git
Merge pull request #5257 from dumganhar/iss3871-stop-propagation-fix
closed #3871: event->stopPropagation can't work for EventListenerAllAtOnce. And add relevant test case.
This commit is contained in:
commit
fa995c27fb
|
@ -815,7 +815,7 @@ void EventDispatcher::dispatchTouchEvent(EventTouch* event)
|
|||
if (event->isStopped())
|
||||
{
|
||||
updateListeners(event);
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -23,6 +23,7 @@ std::function<Layer*()> createFunctions[] =
|
|||
CL(RemoveListenerAfterAddingTest),
|
||||
CL(DirectorEventTest),
|
||||
CL(GlobalZTouchTest),
|
||||
CL(StopPropagationTest),
|
||||
};
|
||||
|
||||
unsigned int TEST_CASE_COUNT = sizeof(createFunctions) / sizeof(createFunctions[0]);
|
||||
|
@ -866,10 +867,10 @@ GlobalZTouchTest::GlobalZTouchTest()
|
|||
, _accum(0)
|
||||
{
|
||||
|
||||
auto listener1 = EventListenerTouchOneByOne::create();
|
||||
listener1->setSwallowTouches(true);
|
||||
auto listener = EventListenerTouchOneByOne::create();
|
||||
listener->setSwallowTouches(true);
|
||||
|
||||
listener1->onTouchBegan = [](Touch* touch, Event* event){
|
||||
listener->onTouchBegan = [](Touch* touch, Event* event){
|
||||
auto target = static_cast<Sprite*>(event->getCurrentTarget());
|
||||
|
||||
Point locationInNode = target->convertToNodeSpace(touch->getLocation());
|
||||
|
@ -885,12 +886,12 @@ GlobalZTouchTest::GlobalZTouchTest()
|
|||
return false;
|
||||
};
|
||||
|
||||
listener1->onTouchMoved = [](Touch* touch, Event* event){
|
||||
listener->onTouchMoved = [](Touch* touch, Event* event){
|
||||
auto target = static_cast<Sprite*>(event->getCurrentTarget());
|
||||
target->setPosition(target->getPosition() + touch->getDelta());
|
||||
};
|
||||
|
||||
listener1->onTouchEnded = [=](Touch* touch, Event* event){
|
||||
listener->onTouchEnded = [=](Touch* touch, Event* event){
|
||||
auto target = static_cast<Sprite*>(event->getCurrentTarget());
|
||||
log("sprite onTouchesEnded.. ");
|
||||
target->setOpacity(255);
|
||||
|
@ -901,7 +902,6 @@ GlobalZTouchTest::GlobalZTouchTest()
|
|||
for (int i = 0; i < SPRITE_COUNT; i++)
|
||||
{
|
||||
Sprite *sprite;
|
||||
auto parent = Node::create();
|
||||
if(i==4)
|
||||
{
|
||||
sprite = Sprite::create("Images/CyanSquare.png");
|
||||
|
@ -913,10 +913,9 @@ GlobalZTouchTest::GlobalZTouchTest()
|
|||
sprite = Sprite::create("Images/YellowSquare.png");
|
||||
}
|
||||
|
||||
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite);
|
||||
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener->clone(), sprite);
|
||||
|
||||
parent->addChild(sprite);
|
||||
this->addChild(parent);
|
||||
this->addChild(sprite);
|
||||
|
||||
Size visibleSize = Director::getInstance()->getVisibleSize();
|
||||
sprite->setPosition(VisibleRect::left().x + visibleSize.width / (SPRITE_COUNT - 1) * i, VisibleRect::center().y);
|
||||
|
@ -945,3 +944,147 @@ std::string GlobalZTouchTest::subtitle() const
|
|||
return "Blue Sprite should change go from foreground to background";
|
||||
}
|
||||
|
||||
StopPropagationTest::StopPropagationTest()
|
||||
{
|
||||
static const int TAG_BLUE_SPRITE = 101;
|
||||
static const int TAG_BLUE_SPRITE2 = 102;
|
||||
|
||||
auto touchOneByOneListener = EventListenerTouchOneByOne::create();
|
||||
touchOneByOneListener->setSwallowTouches(true);
|
||||
|
||||
touchOneByOneListener->onTouchBegan = [=](Touch* touch, Event* event){
|
||||
// Skip if don't touch top half screen.
|
||||
if (!this->isPointInTopHalfAreaOfScreen(touch->getLocation()))
|
||||
return false;
|
||||
|
||||
auto target = static_cast<Sprite*>(event->getCurrentTarget());
|
||||
CCASSERT(target->getTag() == TAG_BLUE_SPRITE, "Yellow blocks shouldn't response event.");
|
||||
|
||||
if (this->isPointInNode(touch->getLocation(), target))
|
||||
{
|
||||
target->setOpacity(180);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Stop propagation, so yellow blocks will not be able to receive event.
|
||||
event->stopPropagation();
|
||||
return false;
|
||||
};
|
||||
|
||||
touchOneByOneListener->onTouchEnded = [=](Touch* touch, Event* event){
|
||||
auto target = static_cast<Sprite*>(event->getCurrentTarget());
|
||||
target->setOpacity(255);
|
||||
};
|
||||
|
||||
auto touchAllAtOnceListener = EventListenerTouchAllAtOnce::create();
|
||||
touchAllAtOnceListener->onTouchesBegan = [=](const std::vector<Touch*>& touches, Event* event){
|
||||
// Skip if don't touch top half screen.
|
||||
if (this->isPointInTopHalfAreaOfScreen(touches[0]->getLocation()))
|
||||
return;
|
||||
|
||||
auto target = static_cast<Sprite*>(event->getCurrentTarget());
|
||||
CCASSERT(target->getTag() == TAG_BLUE_SPRITE2, "Yellow blocks shouldn't response event.");
|
||||
|
||||
if (this->isPointInNode(touches[0]->getLocation(), target))
|
||||
{
|
||||
target->setOpacity(180);
|
||||
}
|
||||
// Stop propagation, so yellow blocks will not be able to receive event.
|
||||
event->stopPropagation();
|
||||
};
|
||||
|
||||
touchAllAtOnceListener->onTouchesEnded = [=](const std::vector<Touch*>& touches, Event* event){
|
||||
// Skip if don't touch top half screen.
|
||||
if (this->isPointInTopHalfAreaOfScreen(touches[0]->getLocation()))
|
||||
return;
|
||||
|
||||
auto target = static_cast<Sprite*>(event->getCurrentTarget());
|
||||
CCASSERT(target->getTag() == TAG_BLUE_SPRITE2, "Yellow blocks shouldn't response event.");
|
||||
|
||||
if (this->isPointInNode(touches[0]->getLocation(), target))
|
||||
{
|
||||
target->setOpacity(255);
|
||||
}
|
||||
// Stop propagation, so yellow blocks will not be able to receive event.
|
||||
event->stopPropagation();
|
||||
};
|
||||
|
||||
auto keyboardEventListener = EventListenerKeyboard::create();
|
||||
keyboardEventListener->onKeyPressed = [](EventKeyboard::KeyCode key, Event* event){
|
||||
auto target = static_cast<Sprite*>(event->getCurrentTarget());
|
||||
CCASSERT(target->getTag() == TAG_BLUE_SPRITE || target->getTag() == TAG_BLUE_SPRITE2, "Yellow blocks shouldn't response event.");
|
||||
// Stop propagation, so yellow blocks will not be able to receive event.
|
||||
event->stopPropagation();
|
||||
};
|
||||
|
||||
const int SPRITE_COUNT = 8;
|
||||
|
||||
for (int i = 0; i < SPRITE_COUNT; i++)
|
||||
{
|
||||
Sprite* sprite;
|
||||
Sprite* sprite2;
|
||||
|
||||
if(i==4)
|
||||
{
|
||||
sprite = Sprite::create("Images/CyanSquare.png");
|
||||
sprite->setTag(TAG_BLUE_SPRITE);
|
||||
addChild(sprite, 100);
|
||||
|
||||
sprite2 = Sprite::create("Images/CyanSquare.png");
|
||||
sprite2->setTag(TAG_BLUE_SPRITE2);
|
||||
addChild(sprite2, 100);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite = Sprite::create("Images/YellowSquare.png");
|
||||
addChild(sprite, 0);
|
||||
sprite2 = Sprite::create("Images/YellowSquare.png");
|
||||
addChild(sprite2, 0);
|
||||
}
|
||||
|
||||
_eventDispatcher->addEventListenerWithSceneGraphPriority(touchOneByOneListener->clone(), sprite);
|
||||
_eventDispatcher->addEventListenerWithSceneGraphPriority(keyboardEventListener->clone(), sprite);
|
||||
|
||||
_eventDispatcher->addEventListenerWithSceneGraphPriority(touchAllAtOnceListener->clone(), sprite2);
|
||||
_eventDispatcher->addEventListenerWithSceneGraphPriority(keyboardEventListener->clone(), sprite2);
|
||||
|
||||
|
||||
Size visibleSize = Director::getInstance()->getVisibleSize();
|
||||
sprite->setPosition(VisibleRect::left().x + visibleSize.width / (SPRITE_COUNT - 1) * i, VisibleRect::center().y + sprite2->getContentSize().height/2 +10);
|
||||
sprite2->setPosition(VisibleRect::left().x + visibleSize.width / (SPRITE_COUNT - 1) * i, VisibleRect::center().y - sprite2->getContentSize().height/2-10);
|
||||
}
|
||||
}
|
||||
|
||||
bool StopPropagationTest::isPointInNode(Point pt, Node* node)
|
||||
{
|
||||
Point locationInNode = node->convertToNodeSpace(pt);
|
||||
Size s = node->getContentSize();
|
||||
Rect rect = Rect(0, 0, s.width, s.height);
|
||||
|
||||
if (rect.containsPoint(locationInNode))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool StopPropagationTest::isPointInTopHalfAreaOfScreen(Point pt)
|
||||
{
|
||||
Size winSize = Director::getInstance()->getWinSize();
|
||||
|
||||
if (pt.y >= winSize.height/2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string StopPropagationTest::title() const
|
||||
{
|
||||
return "Stop Propagation Test";
|
||||
}
|
||||
|
||||
std::string StopPropagationTest::subtitle() const
|
||||
{
|
||||
return "Shouldn't crash and only blue block could be clicked";
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ public:
|
|||
class EventDispatcherTestDemo : public BaseTest
|
||||
{
|
||||
public:
|
||||
virtual void onEnter();
|
||||
virtual void onEnter() override;
|
||||
virtual std::string title() const override;
|
||||
virtual std::string subtitle() const override;
|
||||
void backCallback(Object* sender);
|
||||
|
@ -151,4 +151,18 @@ protected:
|
|||
float _accum;
|
||||
};
|
||||
|
||||
class StopPropagationTest : public EventDispatcherTestDemo
|
||||
{
|
||||
public:
|
||||
CREATE_FUNC(StopPropagationTest);
|
||||
StopPropagationTest();
|
||||
|
||||
virtual std::string title() const override;
|
||||
virtual std::string subtitle() const override;
|
||||
|
||||
protected:
|
||||
bool isPointInNode(Point pt, Node* node);
|
||||
bool isPointInTopHalfAreaOfScreen(Point pt);
|
||||
};
|
||||
|
||||
#endif /* defined(__samples__NewEventDispatcherTest__) */
|
||||
|
|
Loading…
Reference in New Issue