Multiple fonts in custom look and feel

Hi, I have an app that is tabbed and each tab component has it’s own unique custom look and feel. Each of these tab components also needs its own embedded font that I create through createSystemTypefaceFor( ) and override getTypefaceForFont( ).

However, I am struggling to get the different look and feels to use their own font as in juce LookAndFeel::getTypefaceForFontFromLookAndFeel(const Font& font ) the font returned will only use the app’s getDefaultLookAndFeel( ) rather than the look and feel of the tab component.

I have tried setting the tab components to change the default look and feel by adding LookAndFeel::setDefaultLookAndFeel (&_tab1LookAndFeel); in the constructor but this doesn’t seem to work.

How do other people use different multiple embedded fonts in their applications?

1 Like

Simply use Component::setLookAndFeel(). This will set the look and feel only for this component and their children.

The procedure for a component is to look if a lookAndFeel is set, if not traverse the hierarchy, until a parent is found, that has a LookAndFeel defined, and use this one.
If none is found, it will use the one you set with LookAndFeel::setDefaultLookAndFeel…

Caveat: you need to own that LookAndFeel, preferably in a ScopedPointer. So take care in which order they are deleted. Probably a setLookAndFeel (nullptr) in the destructor could be needed.

HTH

Thanks for the reply daniel. Maybe I should have been more specific but the problem I am having is with fonts. Only the font set in the default look and feel is used, while I want to have my own font for each custom look and feel

I see. Indeed, looking into the LookAndFeel, there are several callbacks, e.g. getPopupMenuFont() . Did you try to override those in your custom LNF returning a specific font for that purpose?

I think it would be a good addition to allow setting a Font in a LNF instance to be used in all those callbacks, leaving them to adjust the size, which is the only thing they do at the moment…

Ok so I have found a solution by overriding the getFont() functions in LookAndFeel to return a Font with a custom font name. Then in my default LookAndFeel getTypefaceForFont() override I have an if statement that tests the name of which font to use. A bit hacky but it seems to work:

class Tab1LookAndFeel : public LookAndFeel_V4
{
public:
Font getLabelFont(Label &label) override;
Font getTextButtonFont (TextButton&, int buttonHeight) override;
}

Font Tab1LookAndFeel::getLabelFont(Label &label)
{
return Font (“Tab1Font”, label.getFont().getHeight(), Font::plain);
}

Font Tab1LookAndFeel::getTextButtonFont (TextButton&, int buttonHeight)
{
return Font (“Tab1Font”, jmin (15.0f, buttonHeight * 0.5f), Font::plain);
}

class DefaultLookAndFeel : public LookAndFeel_V4
{
public:
virtual Typeface::Ptr getTypefaceForFont (const Font&) override;
private:
Typeface::Ptr tab1Tf;
Typeface::Ptr defaulTf;
}

DefaultLookAndFeel::DefaultLookAndFeel()
{
tab1Tf = Typeface::createSystemTypefaceFor(BinaryData::tabfont_ttf,
BinaryData::tabfont_ttfSize);
defaultTf = Typeface::createSystemTypefaceFor(BinaryData::defaultfont_ttf,
BinaryData:: defaultfont_ttfSize);
}

Typeface::Ptr DefaultLookAndFeel::getTypefaceForFont (const Font& font)
{
if (font.getTypefaceName() == “Tab1Font”)
{
return tab1Tf;
}
else
{
return defaultTf;
}
}

Does anybody know why the font used is always the default LookAndFeel’s font and not the current one?