ComboBox and Custom Look And Feel

Hey everybody,

I’m struggeling with the Combobox and a custom look and feel. So I created a class for my custom Look And Feel to make my combobox appear as I want. The Combobox is actually just a dropdown menu to select channels. The button to see the dropdownmenu is what I want to change actually. It should be a rectangle with a Textbox in there which says in the one Box Input and in the other Box Output. I already struggled to make the text visible but with some try and errors I figured that I have to draw the text.

void LookAndFeel::drawComboBox(juce::Graphics& g, int width, int height, bool isButtonDown, int buttonX, int buttonY, int buttonW, int buttonH, juce::ComboBox& box)
{
	g.fillAll(box.findColour(juce::ComboBox::backgroundColourId));

	if (box.getText().isEmpty()) {
		g.drawText(box.getTextWhenNothingSelected(), box.getLocalBounds(), juce::Justification::centredLeft, true);
	}
	else {
		g.drawText(box.getText(), box.getLocalBounds(), juce::Justification::centredLeft, true);
	}
}

Now I adjusted also the create ComboboxTextBox and positionComboBoxText but I don’t understand two things here:

createComboBoxTextBox returns the label to write into and I have the box parameter. I thought I create the label here and I use the box to get the text I set for the coresponding component but that didn’t work, so for what is actually the box parameter for? Or what could I do here at this point with it. Maybe I get the function wrong.
BTW, can somebody explain to me the documentation of the functions here? I look up the docs but I can’t find any descriptions or examples how to use the functions. Being a beginner and learning juce and c++ after learning other program languages and frameworks leads me sometimes faster into missunderstanding because it looks very similar but then I figure it’s meant a bit different than thought initially.
My function look like this now:

juce::Label* LookAndFeel::createComboBoxTextBox(juce::ComboBox& box)
{
	auto* label = new juce::Label();
	label->setFont(juce::Font(15.0f));
	label->setColour(juce::Label::textColourId, juce::Colours::black);
	label->setJustificationType(juce::Justification::centred);
	label->setEditable(false, false, false);
	return label;
}

It creates the label and sets the options I need to set so far and it works but it has the taste to me it’s maybe not used as intended or is it?

Next thing I don’t understand, why is there an extra function for positioning the textbox? positionComboBoxText I mean. Why is there a label parameter and a box parameter? Do I put them together in this function? What is a possible usecase ? I use it now to position the textbox of course but I was wondering, if I could not only do it in the createComboBoxTextBox. I have the label and the box there too. I guess it is something behind it that it’s important to splitt the function but I could also understand something not right here. Here is how I use the function at the moment:

void LookAndFeel::positionComboBoxText(juce::ComboBox& box, juce::Label& label)
{
	juce::Rectangle<int> labelBounds = box.getLocalBounds();
	labelBounds.reduce(5, 0);
	label.setBounds(labelBounds.reduced(2, 0));
}

Do I use it the right way? Now also the Text is aligned to the left and I actually want the text centered. And here was the point where I thought asking you here in the forum. Again I struggle to postion the text right. I thought I do it in the label function(createComboBoxTextBox) but my changes aren’t visible. I think I understood something wrong here, can somebody help me please :slight_smile:

p.s.: I understand that it works if I align it in the drawComboBox, but then I don’t understand why do I have the other two functions.

I haven’t used createComboBoxTextBox before. If you want to customize the label itself, you may also override drawLabel, e.g.

void drawLabel(juce::Graphics &g, juce::Label &label) override {
    // set font colour & size
    g.drawText(label.getText(), label.getLocalBounds(), juce::Justification::centred);
}

BTW, the look-and-feels documentation always makes me confused … It is just a list of function names without any examples or descriptions :sweat_smile:

Puh sounds a bit complicated with the docs and understanding how it’s meant. But is the approach I did also ok’ish then? I mean sure I can also override the drawLabel function but is it worth it for one line of code more or less.

Good to know that it’s really a list. At least I can stop searching then :slight_smile:

OK just figured I have to use drawLabel. I think that is what you were pointing me to @zsliu98 ?
If I do it my old aproach, the text is drawn double times.

Cause you actually want to customize the internal label of combobox, I think drawLabel might be the right approach.

Yes in deed!
Another question came up while implementing. What is a good approach with the colors? I set a lot of colours in my constructor of the look and feel but now I face that if I have to change a color, for example the shadow of the buttons, I change the colour in the function and an unwanted sideeffect is that it changes for all following fill functions which is not my intention. Is there for all elements a static accessor to set the colour in the constructor or is ok if I change the colour inside of my functions too. Does it actually make sense then to set the colours in the constructor? I do it because I saw it in the tutorial like that but I don’t remember why at the moment.