Mouse wheel vs. child components

I want to achieve the following functionality:

  • Parent component reads and handles all mouse wheel events.
  • Child components take care of all mouse clicks.

How to achieve that? It seems that the child components always handle mouse wheel and mouse clicks whenever the cursor is on top of them. Only when the cursor is not on top of any of the child components, then the parent seems to be handling the wheel.

Two options would be:

  • Add the parent component as a MouseListener of each of the child components, and handle mouse wheel events in the parent component
  • Set the child components to ignore all mouse interaction (setInterceptsMouseClicks (false, false)), and handle all mouse events in the parent component

beware that if you use setInterceptsMouseClicks(false, false) as a solution there might be some additional things that don’t work for those children anymore then. can be quite some edge case stuff like when you have a custom cursor image for specific components it only gets updated if the component accepts mouse events. if your child components are designed in a way that you define the mouse methods (mouseUp, mouseDown etc.) yourself you can also put callbacks in there like std::function<void()> that trigger an action which involves stuff in the parent component. that way you can ensure that all other component features still work the same, but if your child component is not juce::Component itself but some derived class of Component you should call the base class’ function of your mouseMethods in them as well to make sure to not interfere with existing functionality. that can look like this:

void mouseEnter(const juce::MouseEvent& evt) override
{
    onEnterCallback();
    WhateverTheBaseClassIs::mouseEnter(evt);
}

I already tried making the parent a MouseListener. The result was that parent responded to mouse wheel only when there was no child component under the mouse cursor. So it didn’t work properly.

With your option 2 do you mean that I forward all the mouse events to child components from the parent component?

The first option is probably the better option. Did you remember to call addMouseListener on each of the child components, to register the parent as a listener of the children?

The problem with that method is that the more I have different kinds of child components, the more I need to pass such callback functions as parameters into the child hierarchies. It would be fantastic if there was a way to put all that functionality into one place and be done with it.

Umm, no I didn’t. If I use addMouseListener on all the child components, does that mean that every time child component handles a mouse event, that same event gets passed on to the parent as well?

Yes, but you can use MouseEvent::originalComponent to find the component that originally received the event, and check whether or not it is the parent component.

1 Like

Awesome! I’ll try that method and see how it works.

Thanks!

AddMouseListener seems to work great. The big plus side is that you only need to tell the first child component to add it’s parent to be the listener. Then if you set the second parameter in the method as “true”, every single child component of that child automatically sends their mouse events to the parent you set as a listener. So only couple of lines of code is required and no need to go and set every single child in the hierarchy to add a new listener.