I wish there was a “Tips & Tricks” section.
The button in the screenshot was made without having to declare a “Label”. This may only be an enlightenment for beginners, but here it goes;
As I started work on a synthesizer with 100+ knobs, I found it tedious to declare and implement a “Label” for each knob, plus I wanted the value to be shown right in the middle of the knob.
Here is my custom LookAndFeel class, which some might find useful. Feel free to omit what you do not need.
class ValueLabelLookAndFeel : public LookAndFeel_V4 {
public:
void drawRotarySlider (Graphics& g, int x, int y, int width, int height, float sliderPos,
const float rotaryStartAngle, const float rotaryEndAngle, Slider& slider) override
{
auto radius = jmin (width / 2.25, height / 2.25) - 4.5;
auto centreX = x + width * 0.4975f;
auto centreY = y + height * 0.44f;
auto rx = centreX - radius;
auto ry = centreY - radius;
auto rw = radius * 2;
auto angle = rotaryStartAngle + sliderPos * (rotaryEndAngle - rotaryStartAngle);
auto isMouseOver = slider.isMouseOverOrDragging () && slider.isEnabled ();
// Box and outline of knob area
g.setColour (slider.findColour (Slider::backgroundColourId));
g.fillRect (x, y, width, height);
g.setColour (Colour::fromRGB(16, 16, 16));
g.drawRect (x, y, width, height);
// Knob fill
g.setColour (slider.findColour (Slider::rotarySliderFillColourId).
withAlpha (isMouseOver ? 1.0f : 0.7f));
g.fillEllipse (rx, ry, rw, rw);
// Knob outline
g.setColour (slider.findColour (Slider::rotarySliderOutlineColourId).
withAlpha (isMouseOver ? 1.0f : 0.7f));
g.drawEllipse (rx, ry, rw, rw, 1.0f);
// Knob pointer
Path p;
auto pointerLength = radius * 0.5f;
auto pointerThickness = width * 0.05f;
p.addRectangle (-pointerThickness * 0.5f, -radius, pointerThickness, pointerLength);
p.applyTransform (AffineTransform::rotation (angle).translated (centreX, centreY));
g.setColour (slider.findColour (Slider::thumbColourId));
g.fillPath (p);
// Value
g.setColour (Colours::black);
g.setFont (radius * 0.4f);
g.drawSingleLineText (String (slider.getValue ()), centreX, height * 0.5f,
Justification::centred);
// Label
g.setColour (slider.findColour (Slider::textBoxTextColourId));
g.setFont (radius * 0.55f);
g.drawSingleLineText (slider.getProperties ()[slider.getComponentID()], centreX,
height * 0.985f, Justification::centred);
}
};
The key to getting a label to the knob, is using component properties, thanks @Xenakios for this suggestion.
So I set my knob as this;
setLookAndFeel (&valueLabelLF);
level.setComponentID ("LEVEL");
levelKnob[module].getProperties ().set (levelKnob[module].getComponentID(), "LEVEL");
level.setSliderStyle (Slider::SliderStyle::Rotary);
level.setColour (Slider::rotarySliderFillColourId, Colours::blue);
level.setColour (Slider::rotarySliderOutlineColourId, Colours::white);
level.setRange (0, 1, 0.01f);
level.setValue (0.5f);
level.setTextBoxStyle (Slider::TextEntryBoxPosition::NoTextBox, 0, 0, 0);
addAndMakeVisible (level);