How do I read/compare a 'label' background colour?


#1

Remedial question… I am trying to run through tutorials and at the same time try some of my own experimentation. I created a GUI interface with 4 buttons and 4 labels, and I’m trying to have the buttons cause the ‘label’ field colors to change each time I press the button (e.g. ‘button 1’ will toggle ‘label 1’ to switch between red or blue each time I press the button), but I seem to be unable to ‘read and compare’ the current label color to see which state it’s currently in (i.e. red or blue) to use in an if/else statement. My local guru provided me with the line : " if (label2->isColourSpecified(Colour(0xFF0010ff)) " which give me the error message: " ‘bool juce::Companent::is ColourSpecified(int) const’:cannot convert argument 1 from ‘juce::Colour’ to ‘int’ ". Any suggestions as to what I’m doing wrong?


#2

The error message is giving you a hint:

‘bool juce::Companent::isColourSpecified(int) const’:cannot convert argument 1 from ‘juce::Colour’ to ‘int’

The isColourSpecified function expects an integer, not a Colour. If we then look at the declaration of that function we can see its documentation:

/** Returns true if the specified colour ID has been explicitly set using the
    setColour() method.
*/
bool isColourSpecified (int colourId) const noexcept;

Is this what you actually want to find out? I suspect the function you need might be declared a few lines above

/** Looks for a colour that has been registered with the given colour ID number.

    If a colour has been set for this ID number using setColour(), then it is
    returned. If none has been set, it will just return Colours::black.

    The colour IDs for various purposes are stored as enums in the components that
    they are relevant to - for an example, see Slider::ColourIds,
    Label::ColourIds, TextEditor::ColourIds, TreeView::ColourIds, etc.

    If you're looking up a colour for use in drawing a component, it's usually
    best not to call this directly, but to use the Component::findColour() method
    instead. That will first check whether a suitable colour has been registered
    directly with the component, and will fall-back on calling the component's
    LookAndFeel's findColour() method if none is found.

    @see setColour, Component::findColour, Component::setColour
*/
Colour findColour (int colourId) const noexcept;

where you can use Label::backgroundColourId to specify the background.


#3

I’m just trying to grasp the correct technique(s) that I need to use when referring to different components and their attributes. I used the GUI editor in JUCE to create a simple form with 4 labels, 4 buttons, and one rotary slider. I first want to try to just get the background and text color of each of the 4 labels to switch back and forth between 2 colors when I press the 4 buttons, using a simple if/else statement to examine the current background color of the label, compare it to 1 of my 2 ‘chosen’ colors and if they don’t match (regardless of what the current color is), change to the ‘first’ color, while if they do match, use the ‘else’ statement to change it to the 2nd ‘chosen’ color. Here is a segment of the code that was generated, and that I’m trying to modify…--------------------------------------------------------
void CustomComponent::buttonClicked (Button* buttonThatWasClicked)
{
//[UserbuttonClicked_Pre]
//[/UserbuttonClicked_Pre]

if (buttonThatWasClicked == textButton)
{
	//[UserButtonCode_textButton] -- add your button handler code here..
    //[/UserButtonCode_textButton]
}
else if (buttonThatWasClicked == textButton2)
{
    //[UserButtonCode_textButton2] -- add your button handler code here..
	if (label2->isColourSpecified(Colour(0xff0010ff)))
	{
		label2->setColour(Label::backgroundColourId, Colour(0xffff0000));
		label2->setColour(Label::textColourId, Colours::black);
	}
	else
	{
		label2->setColour(Label::backgroundColourId, Colour(0xff0010ff));
		label2->setColour(Label::textColourId, Colours::white);
	}
    //[/UserButtonCode_textButton2]
}
else if (buttonThatWasClicked == textButton3)


etc, for the 4th button

I’m sorry if I’m being dense, but I still feel like I’m missing something.


#4

First of all, I would advise against using the colour to decide the state.
The Button class has a methodology to toggle between two states:
Button::setClickingTogglesState (true);

Now you can use getToggleState of your textButton:

else if (buttonThatWasClicked == textButton2)
{
    //[UserButtonCode_textButton2] -- add your button handler code here..
	if (textButton2->getToggleState())
	{
		label2->setColour(Label::backgroundColourId, Colour(0xffff0000));
		label2->setColour(Label::textColourId, Colours::black);
	}
	else
	{
		label2->setColour(Label::backgroundColourId, Colour(0xff0010ff));
		label2->setColour(Label::textColourId, Colours::white);
	}
    //[/UserButtonCode_textButton2]
}

Or in less rows:

auto isOn = textButton2->getToggleState();
label2->setColour(Label::backgroundColourId, isOn ? Colour(0xffff0000) : Colour(0xff0010ff));
label2->setColour(Label::textColourId,       isOn ? Colours::black : Colours::white);

The method your local guru recommended, is unsuitable, as @t0m pointed out. It tells you, if a colour was set for a specific role (role being ColourId). But you want to know the actual colour:

if (label2->findColour (Label::textColourId) == Colours::white)
{
    label2->setColour(Label::backgroundColourId, Colour(0xffff0000));
    label2->setColour(Label::textColourId, Colours::black);
}
else
{
    label2->setColour(Label::backgroundColourId, Colour(0xff0010ff));
    label2->setColour(Label::textColourId, Colours::white);
}

HTH


#5

I understand that using the background color is a poor technique, and I actually don’t care about toggling the color other than to provide me with a quick visual feedback to know the code is making it through both if/else conditions. What I’m trying to grasp (and I always have these ‘mental blocks’) is what the difference is between “…if a colour was set for a specific role…” and “…the actual colour…” and why I don’t seem to be able to read the colour value of the background and compare it to a value? From looking at the documentation, I thought perhaps the “ColourSpecified” method(?) examined the label ‘textColourID’ rather than the ‘backgroundColourID’ value, but apparently not.
I just trying to get it clear in my mind how to correctly refer to the different components and their attributes.
Again, I realize I’m being really thick, but what am I missing when I try to evaluate that attribute?


#6

I see. The insight might be found in the LookAndFeel methods.
To make the Components easily adaptable to your taste, every “thing” that is being painted is assigned a ColourId (in general speak colour role). You find the available Ids in each Component, like for your Label: Label::ColourIds.
Hence if you call “setColour”, you have to specify, what this colour is used for.

Now, if you want ALL label’s background colours, you don’t have to do that on all labels. Instead there is the LookAndFeel class. If a class doesn’t have a lookAndFeel, it uses the parents lookAndFeel and so on.
So you can call in your component as first thing:

auto& lookAndFeel = getLookAndFeel();
lookAndFeel.setColour (Label::backGroundColourId, Colours::red);

which will turn all labels backgrounds red, that use that lookAndFeel instance.

Hope that makes it more clear.

And one more thing: isColourSpecified checks, if this specific label has it’s own colour set, which might or might not be different from the colour in the lookAndFeel.