mouseOver and setInterceptsMouseClicks false

Hi,

How could I get the mouse over status of a component without stealing the mouse events for the Component below in the z order ?

Thanks !

Basically I have a decorator around a button and would like to avoid to add explicitly a listener on the button itself because the two widget don’t know each other

in order for mouseOver to work you have to setInterceptsMouseClicks to true as far as i know. so maybe your question could be rephrased as “how can I trigger the button without having clicked on the button?” and i think you could do that by manually calling the button’s mouseUp method in your decorator component’s mouseUp

The decorator don’t know the button below so it would be best if I can avoid tying the two widgets together

Use a globalMouseListener. In the constructor:

setInterceptsMouseClicks (false, true);
Desktop::getInstance().addGlobalMouseListener (this);

Now the component’s mouse functions are called at all mouse move events. For example, mouseEnter will be called whenever the mouse enters any component. So you have to check the screen position of the events.

void mouseMove (const MouseEvent& e) override
{
    if (getScreenBounds().contains (e.getScreenPosition()))
        DBG ("inside");
    else
        DBG ("outside");
}

Perfect !

Thanks a lot !

1 Like

your decorator wouldn’t have to know about the button tho. it could just be given a reference to its std::function<()> onClick function. that way you’d have direct access at the button without checking which component sent a specific mouse event

I had the same problem and I just added the parent class as mouse listener to the child class.
Then you can just use MouseEvent::getEventRelativeTo() to get a mouse event relative to your component.
Two LOC and no global mouse listener is needed.

I’m not sure I follow. Could you post some actual code?

It was something like this:

//parent constructor 
child.addMouseListener(this, false);

//also in parent 
void mouseMove (const MouseEvent& e) override
{
    if (e.originalComponent == &child)
    {
    	auto relEvent = e.getRelativeTo(this); //changes event data to refer to this components coordinate space
    	doStuff(relEvent);
    	return;
    }
}

Ah, got it! Thanks for posting.

But the two widgets of the OP are not related, that is, one is not the parent of, or has a reference to, the other.

If both widgets have the same parent, though, I guess one could do something like:

//parent constructor
button.addMouseListener (&decorator, false);

etc.

But the OP wanted to avoid tying the two widgets together, which this would in a way do.

1 Like