Overlapping events

Hi,
I’m having problems with buttons events.
in my main scene, I’ve a ‘Play’ button and this is the event that I defined:

bPlay->addTouchEventListener(CC_CALLBACK_1(EventHandler::onTouchButtonPlay, EventHandler::getInstance()));

It works fine.
Below Play button, I’ve another button, and when I touch that button it opens a window (i created a layer and added a window image, with buttons).

One of the buttons that I added in the window, is overlapped with the Play button, because, despite of I’m “simulating” a window with a layer, the scene is the same.

This is the event that I defined in the button (window button):

 buttonWindow->addTouchEventListener([&](Ref* sender, cocos2d::ui::Widget::TouchEventType type)
        {
.
.
.
        });

The problem is, when I touch the window button, the action is the event that I defined for Play button instead of the event that I defined for window button.

This is because the buttons are overlapped.
How can I solve it? Can I define / set / unset a event priority for buttons? If yes, how to?

Thanks

I think you should show more code to help us understand. I think this has something to do with the priority of each event.

What code do you would like to view?
When I touch the button for opens the window, this is the layer that I added:

auto layout = ui::Layout::create();
layout->setName("layout");
layout->setTouchEnabled(true);
layout->setSwallowTouches(true);
layout->setContentSize(winSize);
layout->setAnchorPoint(Vec2(0, 0));
layout->setPosition(Vec2(0, 0));
layout->setBackGroundColor(Color3B::BLACK);
layout->setBackGroundColorType(ui::Layout::BackGroundColorType::SOLID);
layout->setBackGroundColorOpacity(170);
Director::getInstance()->getRunningScene()->addChild(layout);

After that, I add all window buttons, images, etc. to the layout.
In the first post I show how I define the events…

I’m sure the problem is for overlapping, I don’t have doubts. Because I tested it.

by overlapping you mean the events are overlapping? Or the button icons are overlapping each other?

The button icons are overlapping each other, and that’s the problem.

I’m sure because I moved the window-button position for no overlap 100% Play button. I overlaped 50% Play button, and if i touch the button on the left side the event is ok, and on the right side (overlapped), the event is the wrong.

oh, I see. Sorry. I thought you meant events. Can you show me a picture? I use one buttons position to set the next one + some padding.

@slackmoehrle I could solve the problem moving the button positions, but that’s not the point. The point here, is if exist some method in the framework that help’s me to solve this problem, for example, setting priorities in the events on touch.

For example.
If I’ve two buttons overlapped, and both buttons has events on touch. When I touch to the buttons, what’s the logic in the framework for determinate what event should be enter? If I could set priorities, it would be nice.

This is my case.

‘No’ button is overlapped to the orange button that’s behind, and ‘Yes’ button to the green button that’s behind.

oh, I’m so sorry, I think I have misunderstood from the start.

So you have 2 buttons on top of each other and if you press si you are having si and the button behind it executed?

If so, yes, event priority is what you want.

So just show me the code for both buttons and I can make the changes.

Edit, just to be sure, this is 3.x and not 2.x, right? My answer would be different :slight_smile:

Yes, i’m using cocos2d-x 3.16.
If I press ‘Si’ the game enters to the event of the green button behind.
If I press ‘No’ the game enters to the event of the orange button behind.

Both actions are wrong.
If I press ‘Si’ the game should enters to the event of the ‘Si’ button.
And If I press ‘No’ the game should enters to the event of the ‘No’ button.

In the first post I showed how i’m defining the button events, with addTouchEventListener

The question is, how can I set priority in the button ‘Si’ if it exists.
And how can I set priority in the button ‘No’ if it exists.

I do something like this:

// touch events.
    auto listener = cocos2d::EventListenerTouchOneByOne::create();
    listener->setSwallowTouches(true);
    
    listener->onTouchBegan = [&](cocos2d::Touch* touch, cocos2d::Event* event)
    {
        if (!_gameObject->Instance()->getGameIsPaused())
        {
            cocos2d::Vec2 p = touch->getLocation();
            cocos2d::Rect rect = this->getBoundingBox();
            
            if(rect.containsPoint(p))
            {
                CornSprite::touchEvent(touch);
                return true;
            }
        }
        
        return false;
    };
    
    listener->onTouchEnded = [=](cocos2d::Touch* touch, cocos2d::Event* event)
    {
    };
    
    cocos2d::Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);

or I may just return true in onTouchBegan() and put all my logic in onTouchEnded(). depends upon what I am doing.

Yes, I could add a general event and depending the location that I press, I could executes different methods. That’s one solution, but in my opinion, isn’t the best. Because i’m fixing the problem adding a new event.

In my case, I only want to set prioritys in the button events for this case, i don’t want to add a new event.
But well, if it’s impossible…

I guess I don’t use buttons enough. I use Sprites normally to act as my buttons. Let me look at cpp-tests to see what is possible.

Ok, this is the green button behind.

cocos2d::ui::Button *bPlay = cocos2d::ui::Button::create("buttons/btnPlay.png");
bPlay->setName("buttonPlay");
bPlay->setPosition(Vec2(position));
bPlay->addTouchEventListener(CC_CALLBACK_1(EventHandler::onTouchButtonPlay, EventHandler::getInstance())); 
bPlay->setScale(buttonScaleX, buttonScaleY);
GameManager::getInstance()->getScene()->addChild(bPlay);

And this is ‘Si’ button:

cocos2d::ui::Button *bYes = cocos2d::ui::Button::create("buttons/btnGreen.png");
bYes->setName("buttonYes");
bYes->setPosition(Vec2(position));
bYes->addTouchEventListener([&](Ref* sender, cocos2d::ui::Widget::TouchEventType type)
{
YesAction();              
});
bYes->setScale(buttonScaleX, buttonScaleY);
GameManager::getInstance()->getScene()->getChildByName("layout")->addChild(bYes);

Some time ago I found this. A ModalLayer for cocos2d-x. I didn’t tested it yet, but it seems to the solution for your problem.

Thanks @mars3142, but if I understood good, this solution is the same that @slackmoehrle proposes me, because ModalLayer is creating an EventListenerTouchOneByOne for catch all events in the screen. The only difference is that it is encapsulated in a custom class called “ModalLayer”, but this is a custom class, not a framework solution. With this solution i’m solving the problem adding a new event… I think this isn’t correct, but, if you have comments, i hear advices :sunglasses:

An important data.
Look this image:

If I touch to ‘Si’ or ‘No’ I’ve the problem that i mentioned before.
But if i try to touch to this icon, when the window/layout is open:

42

The framework doesn’t call to the event, and that’s perfect. When I close the window, the event of the icon returns to work.

Conclusion, I think the Layout works fine, because it desactives events, but I’ve the problem with the events in overlapped buttons.
@zhangxm what do you think? the framework proposes some solution for it? or maybe it’s a bug?

@drelaptop can you take a look at this?

@tranthor we can’t set the priority of button event, and I think @mars3142 said is a good solution.

@drelaptop Why this issue is not consider a bug in the framework?
In my last post I commented that the problem is only in overlapped buttons, not in all.
Can the team check this? Maybe I’m right… or maybe not :slight_smile: