What's the proper way to create a custom colourScheme?

Hi,
I’m currently working with the standard LookAndFeel_V4 colourSchemes and was wondering how to create a custom one? I did not find some info on the forum appart from other LookAndFeel discussions.

Let’s say I want to have a custom dark scheme called customDarkScheme, this is what I would do but cannot get it right :

auto customDarkScheme = new LookAndFeel_V4::colourScheme();
LookAndFeel_V4::setColourScheme(customDarkScheme);

customDarkScheme->setUIColour(ColourScheme::UIColour::windowBackground, juce::Colours::yellow);
/** and all the 8 other UIColour */
lookAndFeelChanged();

Is it the way to create a scheme, set as default and assign its UIColours?

I noticed that :
LookAndFeel_V4::getCurrentColourScheme().getUIColour (ColourScheme::UIColour::windowBackground)
This does not return this current scheme particular colour. I think I am missing something about the scheme concept :slight_smile:

Thanks for your help
Damien

Hi,
I really struggle to get the setUIColour to update the current custom lookandfeel:

Here’s the way I update the UIColours inside the property fields of my GUI settings: (this is working)


            /** Stores the current LnF ColourScheme **/
            auto* currentLookAndFeel = dynamic_cast<LookAndFeel_V4*>(&getLookAndFeel());
            auto currentLookAndFeelScheme = currentLookAndFeel->getCurrentColourScheme();
            
            /** Updates UIColours  property fields from the current ColourScheme **/
            setProperty(Ids::uiPanelUIColourWindowBackground, (String) currentLookAndFeelScheme.getUIColour (ColourScheme::UIColour::windowBackground).toString());
            setProperty(Ids::uiPanelUIColourWidgetBackground, (String) currentLookAndFeelScheme.getUIColour (ColourScheme::UIColour::widgetBackground).toString());
            setProperty(Ids::uiPanelUIColourMenuBackground, (String) currentLookAndFeelScheme.getUIColour (ColourScheme::UIColour::menuBackground).toString());
            setProperty(Ids::uiPanelUIColourOutline, (String) currentLookAndFeelScheme.getUIColour (ColourScheme::UIColour::outline).toString());
            setProperty(Ids::uiPanelUIColourDefaultText, (String) currentLookAndFeelScheme.getUIColour (ColourScheme::UIColour::defaultText).toString());
            setProperty(Ids::uiPanelUIColourDefaultFill, (String) currentLookAndFeelScheme.getUIColour (ColourScheme::UIColour::defaultFill).toString());
            setProperty(Ids::uiPanelUIColourHighlightedText, (String) currentLookAndFeelScheme.getUIColour (ColourScheme::UIColour::highlightedText).toString());
            setProperty(Ids::uiPanelUIColourHighlightedFill, (String) currentLookAndFeelScheme.getUIColour (ColourScheme::UIColour::highlightedFill).toString());
            setProperty(Ids::uiPanelUIColourMenuText, (String) (String) currentLookAndFeelScheme.getUIColour (ColourScheme::UIColour::menuText).toString());

Capture d’écran, le 2024-02-26 à 00.37.10

And this is how I did my script to update all the uiColours of a given LookAndFeel_V4 and update the look of my project with the new colourScheme :


            auto* customLookAndFeel = dynamic_cast<LookAndFeel_V4*>(&getLookAndFeel());
            auto customLookAndFeelScheme = customLookAndFeel->getCurrentColourScheme();
            
            customLookAndFeelScheme.setUIColour(juce::LookAndFeel_V4::ColourScheme::windowBackground, VAR2COLOUR (owner.getProperty(Ids::uiPanelUIColourWindowBackground)));
            customLookAndFeelScheme.setUIColour(juce::LookAndFeel_V4::ColourScheme::widgetBackground, VAR2COLOUR (owner.getProperty(Ids::uiPanelUIColourWidgetBackground)));
            customLookAndFeelScheme.setUIColour(juce::LookAndFeel_V4::ColourScheme::menuBackground, VAR2COLOUR (owner.getProperty(Ids::uiPanelUIColourMenuBackground)));
            customLookAndFeelScheme.setUIColour(juce::LookAndFeel_V4::ColourScheme::outline, VAR2COLOUR (owner.getProperty(Ids::uiPanelUIColourOutline)));
            customLookAndFeelScheme.setUIColour(juce::LookAndFeel_V4::ColourScheme::defaultText, VAR2COLOUR (owner.getProperty(Ids::uiPanelUIColourDefaultText)));
            customLookAndFeelScheme.setUIColour(juce::LookAndFeel_V4::ColourScheme::defaultFill, VAR2COLOUR (owner.getProperty(Ids::uiPanelUIColourDefaultFill)));
            customLookAndFeelScheme.setUIColour(juce::LookAndFeel_V4::ColourScheme::highlightedText, VAR2COLOUR (owner.getProperty(Ids::uiPanelUIColourHighlightedText)));
            customLookAndFeelScheme.setUIColour(juce::LookAndFeel_V4::ColourScheme::highlightedFill, VAR2COLOUR (owner.getProperty(Ids::uiPanelUIColourHighlightedFill)));
            customLookAndFeelScheme.setUIColour(juce::LookAndFeel_V4::ColourScheme::menuText, VAR2COLOUR (owner.getProperty(Ids::uiPanelUIColourMenuText)));

            setLookAndFeel(customLookAndFeel);
            lookAndFeelChanged();

getUIColour() updates properly my fields in my property pane from the current lookandfeel, but when I update them with the colour picker, it’s supposed to trigger the script above when the value change, and the script should set the lookandfeel with the updated UI colours. I pick the colour, the colour updates un the field, but nothing happens with the GUI lookandfeel, window colours, widgets etc stay the same.

getUIColour is ok, but setUIColour doesn’t affect the UI colour, I’m probably missing something important with the whole process.

If someone who’s used to working with the colourScheme subclass could help that would be awesome.
Thanks in advance.
Damien

I used the ColourScheme constructor inside a static function to create the color scheme.

ui.h

static juce::LookAndFeel_V4::ColourScheme getCustomColorScheme();

ui.cpp

juce::LookAndFeel_V4::ColourScheme getCustomColorScheme()
{
    return juce::LookAndFeel_V4::ColourScheme(
        juce::Colours::black,       // windowBackground
        juce::Colours::floralwhite, // widgetBackground
        juce::Colours::aqua,        // menuBackground
        juce::Colours::orangered,         // outline
        juce::Colours::darkslategrey,    // defaultText
        juce::Colours::aqua,       // defaultFill
        juce::Colours::black,      // highlightedText
        juce::Colours::chartreuse, // highlightedFill
        juce::Colours::aqua         // menuText
    );
}

Extend the V4 look and feel

custom_look_and_feel.h

class CustomLookAndFeel : public juce::LookAndFeel_V4
{
public:
    CustomLookAndFeel();
};

And set the custom color scheme for the look and feel.

custom_look_and_feel.cpp

CustomLookAndFeel::CustomLookAndFeel()
{
    setColourScheme(getCustomColorScheme());
}

Then in your editor or component use your custom look and feel.

// In your editor or component constructor
setLookAndFeel(new CustomLookAndFeel());

The color codes for the ColourScheme constructor have to be provided in order and there has to be 9 of them.

2 Likes

If your not too far down the road, you could also use a value tree to store hex values for different colours along with the context of where they are to be used, with different colour schemes stored on disk. You can then use a ColourManager which components can request what colours to use depending on the context. Maybe they query the ColourManager when a repaint is trigger to find a specific colour for a control or background etc

I find that that using a custom LookAndFeel method can get unwieldy very fast.

2 Likes

Thanks for your replies, I’ll look into that.
I was more focused on the. setUIColour() function that was not updating properly. I should work with the whole colourscheme and colours enums to streamline the process of updating custom colours.
I will update here soon with my final results.
Thanks!
Damien