ComboBox and LookAndFeel

Hello Jules !

I have a problem with the LookAndFeel class and the ComboBox class. I have created a custom LookAndFeel class with custom drawing functions, and which inits a few colours, like the ComboBox::textColourId.

In the PluginEditor class constructor from one of my plug-in, I have written this code :

setLookAndFeel(&theLookAndFeel); 

...

addAndMakeVisible(comboAlgorithm = new ComboBox()); 
comboAlgorithm->addListener(this);

All the controls I have instancied this far have their properties related with the LookAndFeel object I have put at the first line. However, for a reason I have not been able to get, some properties are not given to the ComboBox, such as the colour of its text. To be able to have my ComboBox displaying how I want, I need to do this :


setLookAndFeel(&theLookAndFeel); 

... 

addAndMakeVisible(comboAlgorithm = new ComboBox()); 
comboAlgorithm->setColour(ComboBox::textColourId, getLookAndFeel().findColour(ComboBox::textColourId));
comboAlgorithm->addListener(this);

This is the only property from the ComboBox which is not got from the custom LookAndFeel class. It has the right colours and the right display for everything but the text colour. An idea about that issue ? I can't tell if it's because of what I have written, or a typo in the Juce code...

Thanks !

Hard to tell what's going on from that, but perhaps you should just remove the colour setting and let it pick up the value from the L+F, e.g. 
comboAlgorithm->removeColour (ComboBox::textColourId)

Not sure to get what you mean. My problem is that the ComboBox should pick up the value from the L+F, but the one actually used if the default one. Using the removeColour function is equivalent with taking the default one (without my custom L+F), which is exactly what I don't want to do ?

I may have not been clear : my ComboBox is associated with the right L+F. When it is displayed, it gets the right colours for - say- the background, but not for the text, until I add the sentence "comboAlgorithm->setColour(ComboBox::textColourId, getLookAndFeel().findColour(ComboBox::textColourId));" which shouldn't be necessary (since the Colour I pick is from the L+F ComboBox property, which means the information I need is in the right place)...

An idea ?

Not sure.. Can you give me a self-contained lump of code that I could paste somewhere to see this myself?

I have written some code which makes the bug appear :


class CustomLookAndFeel   : public LookAndFeel_V2
{
public:
    CustomLookAndFeel()
    {
        const Colour infoColour (255, 128, 0);
        const Colour backgroundColour (0, 0, 0);
        const Colour textColour (255, 255, 255);

        setColour(ComboBox::backgroundColourId, backgroundColour);
        setColour(ComboBox::textColourId, textColour);
        setColour(ComboBox::arrowColourId, infoColour);
        setColour(ComboBox::buttonColourId, infoColour);
        setColour(ComboBox::outlineColourId, infoColour);
    }

    ~CustomLookAndFeel()
    {
    }
};

class TestAudioProcessorEditor  : public AudioProcessorEditor
{
    CustomLookAndFeel theLookAndFeel;
    ComboBox *comboTest;

public:
    TestAudioProcessorEditor (TestAudioProcessor* ownerFilter)
    {
        setLookAndFeel(&theLookAndFeel);

        // -------------------------------------------------------------------------

        addAndMakeVisible(comboTest = new ComboBox());
        //comboTest->setColour(ComboBox::textColourId, theLookAndFeel.findColour(ComboBox::textColourId));
        comboTest->addItem("no oversampling", 1);
        comboTest->addItem("oversampling 2 times", 2);
        comboTest->setSelectedId(1, dontSendNotification);

        // -------------------------------------------------------------------------
        
        // This is where our plugin's editor size is set.
        setSize (600, 100);
    }

    ~TestAudioProcessorEditor()
    {    deleteAllChildren();
    }

    //==============================================================================
    // This is just a standard Juce paint method...
    void paint (Graphics& g)
    {    g.fillAll (theLookAndFeel.findColour(ComboBox::backgroundColourId));
    }

};

This wasn't exactly self-contained and I had to hack it around to make it run, but AFAICT it all works correctly, and the colour is the same regardless of whether that setColour call is commented-out or not.

So, I forgot to tell I'm doing this with VS2008 and WIndows XP, but I'm not sure it is the problem...

I have created a new project using the IntroJucer, a GUI application with a main.cpp and a basic window, with the last version of JUCE code. Because I'm on Windows XP, I disable the DirectWrite flag, I save and then I open the project with Visual Studio.

Here is the modified MainComponent.cpp


/*

This file was auto-generated!

==============================================================================
*/

#include “MainComponent.h”

//==============================================================================
MainContentComponent::MainContentComponent()
{
setLookAndFeel(&theLF);

// -------------------------------------------------------------------------

addAndMakeVisible(comboTest = new ComboBox());
//comboTest->setColour(ComboBox::textColourId, theLF.findColour(ComboBox::textColourId));
comboTest->addItem("no oversampling", 1);
comboTest->addItem("oversampling 2 times", 2);
comboTest->setSelectedId(1, dontSendNotification);

setSize (500, 400);

}

MainContentComponent::~MainContentComponent()
{ deleteAllChildren();
}

void MainContentComponent::paint (Graphics& g)
{
g.fillAll (Colour (0xffeeddff));

g.setFont (Font (16.0f));
g.setColour (Colours::black);
g.drawText ("Hello World!", getLocalBounds(), Justification::centred, true);

}

void MainContentComponent::resized()
{
// This is called when the MainContentComponent is resized.
// If you add any child components, this is where you should
// update their positions.
comboTest->setBounds(20,20,200,20);
}

Here is the modified MainComponent.h


/*

This file was auto-generated!

==============================================================================
*/

#ifndef MAINCOMPONENT_H_INCLUDED
#define MAINCOMPONENT_H_INCLUDED

#include “…/JuceLibraryCode/JuceHeader.h”

class CustomLookAndFeel : public LookAndFeel_V2
{
public:
CustomLookAndFeel()
{
const Colour infoColour (255, 128, 0);
const Colour backgroundColour (0, 0, 0);
const Colour textColour (255, 255, 255);

    setColour(ComboBox::backgroundColourId, backgroundColour);
    setColour(ComboBox::textColourId, textColour);
    setColour(ComboBox::arrowColourId, infoColour);
    setColour(ComboBox::buttonColourId, infoColour);
    setColour(ComboBox::outlineColourId, infoColour);
}

~CustomLookAndFeel()
{
}

};

//==============================================================================
/*
This component lives inside our window, and this is where you should put all
your controls and content.
*/
class MainContentComponent : public Component
{
CustomLookAndFeel theLF;
ComboBox *comboTest;

public:
//==============================================================================
MainContentComponent();
~MainContentComponent();

void paint (Graphics&);
void resized();

private:
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent)
};

#endif // MAINCOMPONENT_H_INCLUDED

When I run the project, I got the following display depending on the line commented or not

As you can see, on the second part we can't see the text, which keeps the default black colour... I just did what I have written, and the bug appears...

Try again now..

That works ! Thanks a lot !