Setting TextButton font size

Hi there!

I was wondering if it was possible to set the size of a textbutton’s font without having to create a look and feel class for it. I’ve read everything on this thread:

so I’m not particularly hopeful but I was just wondering if things had changed since 2011.

Thanks!

Toby

1 Like

TextButton::changeWidthToFitText() and TextButton::getBestWidthForHeight() ?

I second @ TobyKrotos question.

And to @ [matkatmusic] your suggestions are great if you do NOT care about the button width, however in most cases designing a layout, I would assume most do need their specified button width and height to be EXACTLY as they set it. In other words, what is needed is a way to specify font scaling to fit specified button width and height.

This thread is 2 years old. Don’t revive old topics @DKDiveDude. Start new threads and link to the old thread.

If you need custom text positioning, override the LookAndFeel function that draws a textButton.

What I am trying to say, is that I think it is silly that you have to override LookAndFeel just to specify the text button size!

TextButton tb;
tb.setBounds( 0, 0, 200, 30 );

???

I think you’re confusing text positioning with component positioning

I think it is silly that you have to override LookAndFeel just to specify the text button size

That is exactly what is happening, the font size of TextButton takes the height already into account:

And secondly drawing the text of a textButton (identical in V2-V4) uses “drawFittedText”, which automatically shrinks the text size so it fits:

@daniel Ok then please explain this;

button-text-not-ftting

And note that I “turned off” my LookAndFeelClass and the button still came out like that!

I am not questioning positioning.

I need to make my button text scaled to fit my exact button size, and it does not, in at least one particular case. See screenshot above.

That’s because it’s using the default LookAndFeel class.

Have you bothered to look at the implementation of paintButton()?

void LookAndFeel_V2::drawButtonText (Graphics& g, TextButton& button,
                                     bool /*shouldDrawButtonAsHighlighted*/, bool /*shouldDrawButtonAsDown*/)
{
    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));
    const int textWidth = button.getWidth() - leftIndent - rightIndent;

    if (textWidth > 0)
        g.drawFittedText (button.getButtonText(),
                          leftIndent, yIndent, textWidth, button.getHeight() - yIndent * 2,
                          Justification::centred, 2);
}

Have you looked at how Graphics::drawFittedText() works?

That happens deep inside the GlyphArrangement. There is somewhere a minimum defined (I only found the minimumHorizontalScale, which defaults to 0.7, but I would have to dig deeper.

Basically the Button text maximum size is 16 pixels, and the drawFittedText usually reduces the font size, until it fits into the rectangle. But there is a minimum limit, since a font size doesn’t make sense after a certain size. So the code prefers the ... ellipsis.

Play a bit with the button size to see the effect.

I am afraid you will have to sacrifice more screen estate, find a shorter description, or draw a pictogram.

Yes I have that exact class now inside my own LookAndFeel trying to make it work for my need.

Thanks a bunch though :slight_smile:

You can’t use drawFittedText(), as @daniel said, because it internally uses a GlyphArrangement member function to position the text, which will truncate if you have too much text.

Change your button name, or make your button bigger if you want your button text to not be truncated.

Or you can convert your text into paths, and squish that into whatever sized bounding box you need. See my example code in the thread about how to rotate text.

There seems to be nothing wrong with drawFittedText, as this works just fine;

g.drawFittedText (button.getButtonText (),
				0, 0, button.getWidth(), button.getHeight (),

Problem is all the HARD CODED padding LookAndFeel slaps on!

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

If you knew the answer already, why even dig up this old thread?

Because I second a way to specify a setting to scale button text. The drawButtonText is to me obviously flawed and should be fixed!

1 Like

If you want to customize the way a button (or any other widget in JUCE) looks, you override the LookAndFeel member function that draws the component.

Yes I know that, thank you very much!

However I think it is absurd I have to override just to make my text fit a button!

In other words I believe the class function is inadequate, or faulty, as I shown that it did NOT fit my text!

So that is why I seconded the originals posters question (request)!

I rewrote the LookAndFeel drawButtonText function so it makes text fit - period!

void drawButtonText (Graphics& g, TextButton& button,
		bool /*shouldDrawButtonAsHighlighted*/, bool /*shouldDrawButtonAsDown*/)
	{
		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 = button.proportionOfHeight (0.1f);
		const int cornerSize = jmin (button.getHeight (), button.getWidth ()) / 2;

		const int leftIndent = cornerSize / (button.isConnectedOnLeft () ? 
                               yIndent * 2 : yIndent);
		const int rightIndent = cornerSize / (button.isConnectedOnRight () ? 
                                yIndent * 2 : yIndent);
		const int textWidth = button.getWidth () - leftIndent - rightIndent;

		if (textWidth > 0)
			g.drawFittedText (button.getButtonText (),
				leftIndent, yIndent, textWidth, button.getHeight () - yIndent * 2,
				Justification::centred, 2);
	}

With this all my other button’s text stayed the same size, and now my text fits on this button too;
button-text-not-ftting

I find it extremely frustrating I have to spend time and overwrite something that should work. I could be using my time much better with actual audio stuff instead of simple text button!

2 Likes

Revised drawButtonText, see above, so it now fits all text, with that all my other buttons text’s stayed exactly the same.

button-text-not-ftting