Button loses visibility when bounds are set anywhere but upper-left corner

Hello all,

I’ve come across some weird behavior I can’t seem to figure out. I’ve created a plugin with a simple GUI consisting of a background image (ImageComponent), some rotary sliders (custom class inheriting from Slider, thanks @matkatmusic for the awesome tutorial), and a button (custom class inheriting from Button). I have also created a custom LookAndFeel class. The background component and rotary sliders all render as expected, but the button is losing visibility when rendered in its intended position.

I am currently running JUCE v6.1.6 on Linux Mint 20.2.

I am ovrerriding the paintButton() method here:

void BypassButton::paintButton(juce::Graphics& g, 
                                bool shouldDrawButtonAsHighlighted,
                                bool shouldDrawButtonAsDown)
{
    juce::Colour bgColor;

    if(shouldDrawButtonAsDown)
    {
        bgColor = juce::Colours::grey;
    }
    else
    {
        bgColor = juce::Colours::silver;
    }

    getLookAndFeel().drawButtonBackground(g,
                                            *this,
                                            bgColor,
                                            shouldDrawButtonAsHighlighted,
                                            shouldDrawButtonAsDown);
}

And the drawButtonBackground() method:

void LookAndFeel::drawButtonBackground(juce::Graphics& g,
                            juce::Button& button,
                            const juce::Colour& backgroundColour,
                            bool shouldDrawButtonAsHighlighted,
                            bool shouldDrawButtonAsDown)
{
    g.setColour(backgroundColour);
    g.fillRoundedRectangle(button.getBounds().toFloat(), 4.5f);
}

I am setting the button’s bounds as so:

void PoopSmearerAudioProcessorEditor::paint (juce::Graphics& g)
{
    // (Our component is opaque, so we must completely fill the background with a solid colour)
    using namespace juce;
    g.fillAll (Colours::black);
}

void PoopSmearerAudioProcessorEditor::resized()
{
    // This is generally where you'll want to lay out the positions of any
    // subcomponents in your editor..
    using namespace juce;
    auto bounds = getLocalBounds();

    pedalBackground.setBounds(bounds);

    auto knobArea = pedalBackground.getKnobArea();  
    auto driveArea = pedalBackground.getDriveKnobArea();
    auto levelArea = pedalBackground.getLevelKnobArea();
    auto toneArea = pedalBackground.getToneKnobArea();
    auto buttonArea = pedalBackground.getButtonArea();
    
    bypassButton.setBounds(buttonArea);
    driveSlider.setBounds(driveArea);
    levelSlider.setBounds(levelArea);
    toneSlider.setBounds(toneArea);

    // DEBUG stuff
    if (bypassButton.isVisible())
    {
        printf("Button is visible\n");
    }
    else
    {
        printf("Button is not visible\n");
    }

    printf("Button Center: %d, %d\n", bypassButton.getBounds().getCentreX(), bypassButton.getBounds().getCentreY());
    // \DEBUG
    
}

And the pedalBackground.getButtonArea() method:

juce::Rectangle<int> PedalBackground::getButtonArea()
{
    auto pedalArea = getPedalArea();
    printf("pedalArea Width: %d\n", pedalArea.getWidth());
    auto pedalBottom = pedalArea.removeFromBottom(pedalArea.getHeight() * 0.66f);
    auto buttonLabelArea = juce::Rectangle<int>(pedalBottom.getWidth() * 0.8f,
                                                pedalBottom.getHeight() * 0.8f);
    buttonLabelArea.setCentre(pedalBottom.getCentre());
    auto buttonLabelBottom = buttonLabelArea.removeFromBottom(buttonLabelArea.getHeight() * 0.5f);
    auto buttonArea = juce::Rectangle<int>(buttonLabelBottom.getWidth() * 0.9f,
                                            buttonLabelBottom.getHeight() * 0.9f);
    // DEBUG stuff
    // buttonArea.setX(buttonLabelBottom.getX() / 2.f + (buttonLabelBottom.getWidth() * 0.05f));
    
    // buttonArea.setY(buttonLabelBottom.getY() / 2.f + (buttonLabelBottom.getHeight() * 0.05f));
    buttonArea.setCentre(buttonLabelBottom.getCentre());
    // DEBUG stuff
    printf("ButtonArea Width: %d\n", buttonArea.getWidth());
    printf("ButtonArea Height: %d\n", buttonArea.getHeight());
    printf("ButtonArea Center: %d, %d\n", buttonArea.getCentreX(), buttonArea.getCentreY());

    return buttonArea;
}

When compiled and run, the plugin renders without the button visible (it should be a silver rounded rectangle like the one with the text on it), as seen below:

However, the debug output shows:

pedalArea Width: 240
ButtonArea Width: 172
ButtonArea Height: 90
ButtonArea Center: 150, 352
Button is visible
Button Center: 150, 352

which are the expected values.

Even weirder, if I remove the buttonArea.setCentre(buttonLabelBottom.getCentre()); line from the getbuttonArea() method, the button renders as expected in the top left corner as expected (I’m new, so I can’t attach a second screrenshot).

If I move the button around from there, I can see the edges getting cut off as I move it away from the top corner.

My repo can be found at: GitHub - bobforcha/PoopSmearer

Please forgive my juvenile sense of humor.

If anyone can point me in the right direction, I would greatly appreciate it. This is my first non-tutorial plugin attempt, and it’s been great otherwise so far!

Thanks,

Bob Forcha

This text will be hidden

You called button.getBounds() in your draw button background method… you probably meant getLocalBounds()

1 Like

button.getLocalBounds() it was! Thanks so much @ImJimmi !

@bobforcha you’re welcome! I’m glad you enjoyed the tutorial!