[SOLVED] ImageButton onClick method not running

Hello all,

Declared the ImageButton in the PlugineEditor header file and this code is in the constructor of the plugin editor. This all compiles no matter what I put in the onClick method none of it runs. Any help would be greatly appreciated. I put a simple change of text as a test but other things will go in there once it is working.

const auto upImage = ImageCache::getFromMemory (BinaryData::uparrow_png, BinaryData::uparrow_pngSize);
    const auto downImage = ImageCache::getFromMemory (BinaryData::downarrow_png, BinaryData::downarrow_pngSize);
    
    upButton.setImages (false, true, true, upImage, 1.0f, {Colour(0xa75a3131)}, upImage, 1.0f, {Colour(0xa55a3131)}, upImage, 1.0f, {Colour(0x815a3131)}, 0.0f);
    downButton.setImages (false, true, true, downImage, 1.0f, {Colour(0x975a3131)}, downImage, 1.0f, {Colour(0x855a3131)}, downImage, 1.0f, {Colour(0x805a3131)}, 0.0f);
    
    addAndMakeVisible(upButton);
    addAndMakeVisible(downButton);
    
    upButton.onClick = [this] 
    {
        
        keyLabel.setText("Testing: up", juce::dontSendNotification);
    };
    
    downButton.onClick = [this] 
    {
         keyLabel.setText("Testing: down", juce::dontSendNotification);
    };

Put a breakpoint in there, to double verify it’s not getting called.

1 Like

Hello,

Thanks for the suggestion! I need to reach out more totally forgot about break points. Still no luck though. Now I am certain the onClick method for either button is not running. I have TextButtons that are working fine. Not sure where to go with this one. I don’t think I have to manually add listeners in this case.

upButton.onClick = [this] 
    {
        
        DBG("Up button pressed");
        
    };
    
    downButton.onClick = [this] 
    {
       
         DBG("Down button pressed");
         
    };

Set the handlers before you addAndMakeVisible() …

1 Like

@anon48770766 that didn’t make a difference but it got me thinking I moved that entire code to the bottom of the constructor just before the setSize method. Looks like because I had positioned these buttons relative to some other components in resized() I had to do addAndMakeVisible after these component’s addAndMakeVisible and it works now. Guess the ordering is more important than I thought. This is now solved.

3 Likes

That seems to indicate that there was some other component that was “in front of” your buttons, and was preventing the mouse clicks from reaching the buttons underneath.

By default, each addAndMakeVisible() adds its component in front of all the other already present, resulting in an interface that is mounted “from back to front”.

That being said, moving the addAndMakeVisible() calls for those buttons to the end of the constructor, has probably resulted in bringing them after the addAndMakeVisible() for the obstructing component, bringing the buttons in front of it, and making them clickable again.

If that code rearrangement doesn’t feel like the right thing to do in your code (for example, logically it could belong to earlier stages of the constructor), there are some other solutions you could consider:

  1. if you add the obstructing component after the buttons, you can pass 0 as a second argument to addAndMakeVisible (obstructingComponent, 0) which results in putting the obstructingComponent at the back of everything else, included the buttons if they are already present

  2. if you don’t care about mouse activity on the obstructing component, you can disregard that entirely by calling obstructingComponent.setInterceptMouseClicks (false, false). In this case, it doesn’t matter if the obstructing component is in front of the buttons, because mause events will go through it

  3. If your obstructing component has for example a circular shape (e.g. a knob) and your buttons are obstructed because they fall in the transparent region that lies between the knob circle and the rectangular bounds of the obstructing component, then you could consider overriding the hitTest() method of the obstructing component to return true only for the “solid” part of your component, so that events that happen in the transparent part fall through it.

2 Likes

@yfede Thank you for those suggestions. I prefer the buttons at the bottom of the constructor for my own logic because they do come on top of everything added so far. Thank you for the incite into how Juce displays components I will probably use those pointers a little later. Still a bit new to JUCE am becoming more of a fan of it. Thanks again!

1 Like