setInterceptsMouseClicks - what does "child" mean?

Hello,
I am not sure if I understand the concept of allowClicksOnChildComponents.

Does “child” relate to declaration or does it relate to use of addChildComponent()?

I mean, if I have my own class:

class MyParentComponent : public Component
{
    Component childComponent;
}

class SomeOtherComponent : public Component
{
}

So here childComponent is definitely child of MyParentComponent.
But what if I NEVER call:
MyParentComponent::addChildComponent(otherComponent);

But instead I call:
SomeOtherComponent::addChildComponent(otherComponent);

then is childComponent really seen as child for MyParentComponent::setInterceptsMouseClicks() ?

For me it seems obvious that in that scenario childComponent is not child for MyParentComponent.
But I am not sure because I have following problem:
in SomeOtherComponent I have override the mouseEnter() and mouseExit() and I also called:
SomeOtherComponent::setInterceptsMouseClicks(true, true);

But even though when I enter mouse on childComponent (which is child of SomeOtherComponent) there is called SomeOtherComponent::mouseExit().

That’s why I started wondering what I do wrong?

I want to call mouseEnter() for parent component no matter above which child component I am.
For any help great thanks in advance.
Best Regards

one of the arguments is for wether or not the component you’re currently on should let mouse events through or not. and the other argument is wether or not components that are part of this component (children) should let mouse events through or not. letting mouse events through means that they are not caught and consumed by the mouse-methods like mouseDown etc. but just passed on to the next layer of components and it would go on and on until there is either a component where setInterceptsMouseClicks is true or it’s just the top layer component, the parent of all components so to say

In your example, childComponent is a member variable, it is not a child component! A child is only when you add them to a parent component using addChildComponent or addAndMakeVisible

image
here’s a little demo. the purple box is the top layer component. the red box is a child component of the purple one with setIntercerptMouseClicks(false, true) and the orange boxes are children of the red one. so the blue mouseclick would give the mouse event to the purple box, the green mouse click gives it to the orange box and the white mouse click also gives it to the purple box

To sum it up: n this context child component has nothing to do with inheritance. So MyParentComponent::addChildComponent() is meaningless, unless you override addChildComponent, which you shouldn’t do.

The child is meant in terms of hierarchy of components.

here’s a little demo. the purple box is the top layer component. the red box is a child component of the purple one with setIntercerptMouseClicks(false, true) and the orange boxes are children of the red one. so the blue mouseclick would give the mouse event to the purple box, the green mouse click gives it to the orange box and the white mouse click also gives it to the purple box

Hmm… Great thanks for your super demo. Now I understand it clearly.
And it works for me as you described and I am happy with it. But the only problem I have is:
I need to know if mouse enter or exit purple box NO MATTER if it’s blue, green or white mouse click.

And I can even say it works now almost as I described, but when I enter orange box I suddenly get for purple box both events “exit” and than “enter”. Why is that? I don’t want to call for purple box mouseEnter when I enter on orange box, because I’ve already enter purple box before I enter orange. I have some mess with those mouse enter and exit events.

Please notice I don’t even need any clicks or dragging for purple box, I don’t even need to know if mouse is over purple or not, I just need to capture the moment of enter and exit purple box.

Unfortunately that is how juce works. The mouse is always exactly over one component, so if it enters a child component, it leaves the parent by definition.

It is tricky to get a simple solution. If you assume it stays over the parent if it enters the child, the child could have a common edge with the parent, so the mouse could leave the parent on that path without being noticed.

Maybe an alternative solution is a timer checking the global mouse position (via MouseInputSource) if it is over the component you want to watch.

OK daniel, great thanks for your advices. I will try to manage it in some way.

I’ve just got the idea. I am not sure if it’s proper.
Finally it works, but not sure if it’s safety.
Maybe you could tell me if it’s ok solution.

To explain let’s get back to Mrugalla demo.
So I think to receive my purpose, I can just create one more component as a child of purple box, and make that component transparent and on top of all other components in purple box, and make it setInterceptsMouseClicks(true, true); but inside that component I override all mouse event methods and inside of them I will just call getParentComponent().

For example like that:

void mouseDrag(const MouseEvent &e)
{
   getParentComponent()->mouseDrag(e);
}

Do you think it’s OK?

I would advise against that idea:

  • first the MouseEvent is relative to the positions of the component, so the information in the parent component mouseDrag will be off.
  • second the mouseDrag is only sent to the currently dragging after you pressed the button.
  • third you won’t be able to understand if you have an original MouseEvent or a forwarded, so it will be confusing.

If you could describe your use case/workflow it would be easier to suggest possible solutions.

Thanks daniel for your help.

My case is like that:
I have parametric equaliser with four filters (low cut, bell eq1, bell eq2, high cut).
And I have also window with chart/graph representation of all eq curves.

For each one filter I have sliders like frequency, gain, Q etc.

And those sliders I have grouped in separate BOXes, like: one box for low cut frequency and res, second box Eq1 frequency, gain and Q, etc.

And now I want to capture when mouse enter/exit over the BOXes, and then highlight/unhighlight corresponding parts of chart. But I don’t want to do it again when I enter/exit each sliders in the BOX.

I hope I explained it clearly.

Now I have some new idea. Maybe I can use the isMouseOver in some way?

I think that is a great idea. I would start a timer with 10Hz on mouseEnter and check if the mouse is still over the panel using the isMouseOver() and stop the timer once isMouseOver() returns false…

not sure if i understand the issue fully but if this is about components that should change in some way when something happens in an entirely different component maybe it would make sense to build some sort of listener system that sends actions to a shared vector of pointers to the other components when the thing should happen, so that it’s less about when the mouse leaves a component and more about just when it enters a component. reminds me of a problem i once had where i needed to “deselect” a lot of components when another related component was clicked, so they all had to repaint to show their new selection-state

OK, great thanks for your help. But it looks like it’s very tricky to know if cursor is above whole plugin window. It looks like I need to check it inside mouseEnter() / mouseExit() of each one `Component that is visible on my plugin window. It seems ridiculous, isn’t it?
Or isn’t there any simple method to be notified when mouse cursor enter/exit plugin window?