jimc
June 16, 2018, 10:28am
1
Is this the right way to have a button appear on a component when the user mouse-overs its parent?
class Row : public Component
{
public:
Row()
{
addAndMakeVisible(buttonAppearsDuringMouseOver);
buttonAppearsDuringMouseOver.addMouseListener(this, false);
}
void paint (Graphics& g) override
{
g.fillAll (Colours::darkcyan);
}
void resized() override
{
buttonAppearsDuringMouseOver.setBounds(getLocalBounds().withWidth(50).reduced(2));
}
void mouseEnter(const MouseEvent&) override
{
buttonAppearsDuringMouseOver.setVisible(true);
}
void mouseExit(const MouseEvent&) override
{
buttonAppearsDuringMouseOver.setVisible(false);
}
TextButton buttonAppearsDuringMouseOver{"PUSH"};
};
You don’t need
buttonAppearsDuringMouseOver.addMouseListener(this, false);
Component handles the MouseListener for you
Rail
1 Like
jimc
June 16, 2018, 10:34am
3
Doesn’t work without that. As the mouse moves over the button it disappears. (i.e. exits the parent component and enters the child component).
My solution works but has a completely unnecessary set of calls to setVisible when the mouse moves between components.
jimc
June 16, 2018, 10:36am
4
As a PIP … my first PIP
/*******************************************************************************
The block below describes the properties of this PIP. A PIP is a short snippet
of code that can be read by the Projucer and used to generate a JUCE project.
BEGIN_JUCE_PIP_METADATA
name: MouseOver
dependencies: juce_core, juce_data_structures, juce_events, juce_graphics, juce_gui_basics
exporters: vs2017
type: Component
mainClass: MyComponent
END_JUCE_PIP_METADATA
*******************************************************************************/
#pragma once
class MyComponent : public Component
{
public:
MyComponent()
{
setSize (600, 400);
addAndMakeVisible(row);
}
void paint (Graphics& g) override
{
g.fillAll (Colours::black);
}
void resized() override
{
row.setBounds(getLocalBounds().withSizeKeepingCentre(getWidth() - 40, 25));
}
class Row : public Component
{
public:
Row()
{
Component::setName("ROW");
addAndMakeVisible(buttonAppearsDuringMouseOver);
buttonAppearsDuringMouseOver.addMouseListener(this, false);
}
void paint (Graphics& g) override
{
g.fillAll (Colours::darkcyan);
}
void resized() override
{
buttonAppearsDuringMouseOver.setBounds(getLocalBounds().withWidth(50).reduced(2));
}
void mouseEnter(const MouseEvent&e) override
{
DBG("mouseEnter " + e.eventComponent->getName());
buttonAppearsDuringMouseOver.setVisible(true);
}
void mouseExit(const MouseEvent&e) override
{
DBG("mouseExit " + e.eventComponent->getName());
buttonAppearsDuringMouseOver.setVisible(false);
}
TextButton buttonAppearsDuringMouseOver{"PUSH"};
};
private:
Row row;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MyComponent)
};
daniel
June 16, 2018, 11:00am
5
I’m not sure if it will work, but maybe try to set setInterceptsMouseClicks (false, false)
on the Textbutton.
The idea is, it will exclude it from hitTest, so the mouseEnter and mouseExit on the button would no longer happen. But the TextButton will receive the mouse callbacks from listening to the parent.
So the last thing will be to check on mouseDown (or mouseUp), if the event is in the TextButton’s bounds.
1 Like
Aah… well if you add it, don’t forget to removeMouseListener() in the destructor.
Rail