setInterceptsMouseClicks to disallow clicks on children?


#1

Hi,

I want to use setInterceptsMouseClicks, in order to disallow clicks on child components. Is that possible?

To be specific:
I have a parent component, which contains a slider. In the parent component I set
setInterceptsMouseClicks(true, false)
In other words: clicks on this component are allowed, but not on child components (the second boolean parameter is for allowClicksOnChildComponents, which I set to false).

But I still can click on the slider an modify it. So clicks on the children are still working.

I guess, I am using setInterceptsMouseClicks the wrong way?
Is there a way, to prevent child components from getting mouse clicks? Without telling each child separately to ingore mouse clicks?

I am asking, because I want to forward mouse clicks manually to the children. Before forwarding them, I want to run certain actions first.


#2

I believe the click moves the other way - it is received first by the child and then goes up the chain.


#3

Not really, the click is received from the ComponentPeer, and it will traverse via Component::hitTest(), until it finds the Component in the most specific leaf of the hierarchy.
The flag from setInterceptMouseClicks is used in hitTest:

If you have problems here, it might be worth to point out, that the parent is not, where the Component is a class member of, but rather, on which class you called addAndMakeVisible (child). Maybe this is the culprit?


#4

Hi Daniel,

well, what I am doing is this:
I created a fresh project from the projucer. Then I just add a slider to the MainComponent, nothing else. I am using this code:

MainComponent::MainComponent()
{
    setSize (600, 400);
    addAndMakeVisible(slider);
    setInterceptsMouseClicks(true, false);
}

void MainComponent::resized()
{
    // This is called when the MainComponent is resized.
    // If you add any child components, this is where you should
    // update their positions.
    
    slider.setBounds(50,50,150,100);
}

As you can see, I added three lines to the CPP file, which the Projucer created:

addAndMakeVisible(slider);
setInterceptsMouseClicks(true, false);

and

slider.setBounds(50,50,150,100);

The result is: I can click on the child slider component, even though I disabled clicks on children in the call to setInterceptsMouseClicks().

But I think: I might be using setInterceptsMouseClicks() in the wrong way. It is probably not made for what I want it to do :slight_smile:


#5

My understanding was, that the event traversal is steered by calling hitTest(). However, there are two internal methods, Component::contains(), which calls hitTest and would behave as we both expected it, but then there is reallyContains(), which ignores the interceptMouseClicks flags.

Now the methods isMouseOver(), isMouseDown() etc. ignore the hierarchy of components, but rather use the MouseSource::getComponentUnderMouse()

I am not sure if that is by design or by accident, that the interceptsMouseClicks() is now circumvented.