Button font

I just cannot seem to get button text sizes to change.  I have tried overriding getTextButtonFont, getFont l-f methods.  I tried doing it to my buttons specifically(I am using textButtons and drawableButtons), but I cannot get the text sizes to change.

I have seen discussons about this on the board, but no code examples.  I am not a c++ wizard so maybe that is why I just don't get it.  Does anyone have a simple example of code I can look at that does this?

 

Thanks.

No answers yet.  Maybe some one can tell me the errors of my ways.  The button I am using is defined like this:

class MyButton: public DrawableButton

In one of the threads Jules said to override the getTextButtonFont method in a custom look and feel.  So I created another class like this:

class MyFeel : public LookAndFeel_V3
{
public:
    MyFeel() {};
    ~MyFeel() {};
    int getDefaultFontSize () { return 5; }
    Font getTextButtonFont (TextButton&, int buttonHeight)  { return Font(5.f); }
};

 

Then in the beginning of main I did this:

l_f = new MyFeel;
LookAndFeel::setDefaultLookAndFeel(l_f);
setLookAndFeel(l_f);

The title bar changes to the V3 look and feel but no change in text size. 

When Jules said override the getTextButtonFont in look and feel is this whay he meant or have I completely missed the mark??

 

I would expect the font in the buttons to be tiny, but nothing happens.

 

Too many possibilities here to know what's wrong, but if I had this problem I'd just debug into the button's paint routine and see where it's getting the font from. That should instantly show you what's going on.

drawButtonText() uses Graphics::drawFittedText(), so it'll always resize the font to fit the button.. you'll need to overwrite LookAndFeel_V2::drawButtonText() to change the drawing code.

 

Rail

1 Like

I’m trying to do the same as OP, change the font size used by a textbutton.

I have my own lookandfeel class inheriting from LookAndFeel_V4. My lookandfeel class has the standard drawFittedText() function and this doesn’t happen. Do I have to update the lookandfeel’s class idea of buttonHeight from PluginEditor::Resized() or something? I can create a font in my lookandfeel class for getTextButtonFont() to return but this won’t update the button when my plugin is reized.

So I want the font to be held and set in my lookandfeel class but the size of it changed by PluginEditor. How do I do this?

Apologies for dragging up an old post, seemed too similar to start a new one.

Well, you don’t have to change the font to get this effect. The resize() will change the bounds of the TextButton, and the bounds are used in the paint using Graphics::drawFittedText().
The docs to drawFittedText state:

If the text is too big, it’ll be squashed horizontally or broken over multiple lines if the maximumLinesToUse value allows this. If the text just won’t fit into the space, it’ll cram as much as possible in there, and put some ellipsis at the end to show that it’s been truncated.

Does this happen in your case?

Replace:

Graphics::drawFittedText()

with

Graphics::drawText()

in your L&F

Rail

@Rail_Jon_Rogut I read it like Vincent wants it the other way round than in the OP, that the font size IS controlled by the resize, vs. the OP wanted it NOT to change the font size.

@vincent can you please clarify?

Well he could always look at the source code… search for drawButtonText will take him to paintButton() which he’ll see is called from Button::paint() … so if the button is resized it should generate a paint()

Rail

Yes exactly, Font object is in my lookandfeel module and used for the text buttons there. The plugin size should change the font size appropriately though. Although…

Yes, the text gets smaller and truncates if there’s not enough room for it all. But I need the text to get bigger too. The buttons just contain + and - so look pretty empty with one tiny symbol in the middle of a big button.

Speaking strictly for myself, I prefer to do it all in paint(). I just do something like this:

juce::Rectangle<float> rect_tmp = my_button->getBounds().toFloat();
g.drawText(my_button->getName(), rect_tmp.translated(myX * 3, 0), Justification::centred); 

That way you have entire and full control over the text without having to deal with drafting through 14 layers of 4 versions of Look ‘n’ Feel to find the damn thing. If you need to draw over the button, do it in paintOverChildren() instead of paint(). We do fully resizable UIs, so it’s just easier this way.

(I actually use TextButton throughout, set alpha to zero, and draw the entirety of the button in paint(), but I’m a bit barmy that way. Maybe not the course of action unless you really like procedural drawing.)

That’s a good work around, though the text is drawn behind the button this way?

Just make a paintOverChildren(Graphics& g) function and you can draw on top of the buttons. As I said, I just use TextButton, set it to alpha 0, and draw all my buttons in paint() because I don’t like fighting with Look n Feel. But I also said I’m a little barmy.

Yes, I’d just like to confirm to any readers that that’s definitely barmy! Please don’t follow this as advice!

1 Like

A “why” would be nice. I mean, we’ve shipped 12 products on 14 platforms doing things this way, and if it’s the worst thing ever (aside from it not following some Secret Thing Decided In The Star Chamber), it’d be great to have a reason for that.

(Note that my comment was necessarily simplistic. I tend to make custom Components for everything, but I’ll use the base Slider and TextButton for the parameter handling. If you’re thinking about typing a lengthy discourse on why the entire UI shouldn’t be drawn in paint()…)

OK, well it’s mainly an example of tight coupling between two classes which should be entirely independent… What if you wanted to change the component hierarchy, or clip/overlap the child components, draw them in a different order, or put them in a scrollable sub-view, or re-use them in another parent component, etc…?

It’s not the responsibility of the parent component class to understand how to draw its children - that logic belongs elsewhere: either in the child component itself or preferably in a look-and-feel-type class which is specifically to handle your UI theme.

Key concepts are coupling Coupling (computer programming) - Wikipedia
And single-responsibility principle
Single responsibility principle - Wikipedia

So basically - sure, you can write code like that, get it working, and ship products. People ship awesome products containing even worse architectural sins than this all the time. But if you want to write code that’s maintainable and easy to work with, you need to be more careful about this kind of pattern.

I would have thought that was self-evident. (Until that thread of the other day about why everything shouldn’t be in one .cpp file anyhow) But, we’re talking about plugins here, not Excel. Anyone that makes more than one product knows what can be containerized or not.

Or, to put it another way… if I’m using TextButton unaltered, handing it a component ID, and just painting it in paint() instead of overriding its paint in Look n Feel, and each plugin has a unique look, I’m actually following the coupling concept more closely than someone who has to Look n Feel and set() every single button in to submission. (Assuming that our company method is to make each sub-panel a Component, and that these Components are designed for re-use; we use a common coloring scheme that is set in Look n Feel, so I can drag the entire envelope panel from Quanta, and throw it in a new product, and it will work the same, and just be a different color. Despite evidence to the contrary, I’m not a complete fucking idiot. I’ll accept arguments for the obverse, however.)

…I’m struggling to detect whether you’re actually pissed-off and think I was insulting you, or whether you’re just bantering…

Just for the record, I wasn’t making any kind of personal attack, and certainly in your products it sounds like you’ve got extremely good reasons for doing things that way - perhaps it’s the ideal/only way to meet the use-case you have.

But just based on the snippet of information you posted on this thread - i.e. suggesting moving the painting of a child component into its parent component, I was flagging the fact that that’s really bad advice to give out in general, and could lead impressionable beginners into very bad habits!

1 Like

I didn’t think you were insulting me. I was genuinely concerned there was a good reason for not painting over an invisible button (like, a technical reason that would slow down rendering).

Resizable UIs present a considerable challenge; it quickly became apparent to me that JUCE’s idea of a resizable UI (which is more like the web’s) isn’t really compatible with what customers think a resizable UI is (scaling) and I’ve developed a fairly extensive catalog of methods for doing a pure vector, entirely scalable UI. A lot of these methods involve, for simplicity’s sake, using an invisible Slider or TextButton, or group thereof, and wrapping it in a new Component and using that Component’s paint() method to actually draw the control.

For a single button that isn’t behaving, you’re absolutely correct; my method is dumb. But if it’s my company’s policy to create controls this way… I don’t have to impress you or the UI coders at Waves. I have to ship a product that works, and that our employees can support and extend, and that have a lifespan. The fact that Look And Feel is V4, and is as scattershot and haphazard as it is reinforces my opinion that, in this particular case, I don’t believe I’m wrong.

My overarching point was that there are multiple ways to skin this particular cat, and they’re context-sensitive.