TextButton assert in LookAndFeel_V2


#1

TextButton crashes in LookAndFeel_V2 if you set a width < 6, because it paints on a graphics with negative width:

void LookAndFeel_V2::drawButtonText (Graphics& g, TextButton& button, bool /*isMouseOverButton*/, bool /*isButtonDown*/)
{
    Font font (getTextButtonFont (button, button.getHeight()));
    g.setFont (font);
    g.setColour (button.findColour (button.getToggleState() ? TextButton::textColourOnId
                                                            : TextButton::textColourOffId)
                       .withMultipliedAlpha (button.isEnabled() ? 1.0f : 0.5f));

    const int yIndent = jmin (4, button.proportionOfHeight (0.3f));
    const int cornerSize = jmin (button.getHeight(), button.getWidth()) / 2;

    const int fontHeight = roundToInt (font.getHeight() * 0.6f);
    const int leftIndent  = jmin (fontHeight, 2 + cornerSize / (button.isConnectedOnLeft() ? 4 : 2));
    const int rightIndent = jmin (fontHeight, 2 + cornerSize / (button.isConnectedOnRight() ? 4 : 2));

    g.drawFittedText (button.getButtonText(),
                      leftIndent,
                      yIndent,
                      button.getWidth() - leftIndent - rightIndent,
                      button.getHeight() - yIndent * 2,
                      Justification::centred, 2);
}

...where leftIndent and rightIndent end up being 3.

It does not make too much sense to set the width so small, but with my dynamic Layout it happens if you resize to extreme values.

Would be nice if you could put something in it to avoid the crash.

Thanks


#2

I guess you're talking about an assertion, not a crash? So not actually a showstopper, but I guess

const int leftIndent = jmax (0, jmin (fontHeight, 2 + cornerSize / (button.isConnectedOnLeft() ? 4 : 2))); 
const int rightIndent = jmax (0, jmin (fontHeight, 2 + cornerSize / (button.isConnectedOnRight() ? 4 : 2)));

..would avoid it in your case?
 


#3

Here a proposed fix which simply checks before drawing the text:

-    g.drawFittedText (button.getButtonText(),
-                      leftIndent,
-                      yIndent,
-                      button.getWidth() - leftIndent - rightIndent,
-                      button.getHeight() - yIndent * 2,
-                      Justification::centred, 2);
+    if (button.getWidth() > leftIndent + rightIndent && button.getHeight() > yIndent * 2)
+    {
+        g.drawFittedText (button.getButtonText(),
+                          leftIndent,
+                          yIndent,
+                          button.getWidth() - leftIndent - rightIndent,
+                          button.getHeight() - yIndent * 2,
+                          Justification::centred, 2);
+    }

Cheers


#4

Yes, sorry. I didn't check what comes after the assert, but I thought it is there for a reason...

The change you proposed did not help. The indents are always positive, but the width minus the two indents needs to stay positive or equal zero.

That's why I posted (simultaneously) the condition, as drawing in an empty rectangle is pointless anyway.

I just renamed the topic...


#5

Thanks for the fix, works. Seems like the paint is not called with heights less than 2* yIndent, so all is good now.

Cheers