Scale for Slider

I might have searched with the wrong words but I couldn’t really find an answer here. Is there the possibility in Juce or in the Juce::Slider Class, to display a scale next to it? I want to copy a desk fader and they are usually logarithmic and range from 6 to -inf. I was able to set this range in the slider and it performs great. But getting the scale right so that it shows always the right value - same as the textbox, not.
I tried several methods already but it was always that I was able to adjust the scale in the range from +6 - -6 more or less acurate but then under -6 it is getting more and more off.
In my code I put @daniel s Meter behind a vertical slider. By that I see a nice meter behind the fader already and that works also great so far. But now adjusting the tickmarks in the meter look and feel costs a lot. Doesn’t matter how close I get to the correct range, I wasn’t able to get all values match with the scale from the meter.

void LookAndFeel::drawTickMarks(juce::Graphics& g,
	foleys::LevelMeter::MeterFlags meterType,
	juce::Rectangle<float> bounds)
{
	const float tickInterval = (bounds.getHeight() / 8) * 0.85f;  // Example for 11 intervals from +10 dB to -100 dB
	const float tickStart = bounds.getX() - bounds.getWidth() * 0.001f;
	const float tickLength = bounds.getWidth();  // Length of the tick marks

	const std::vector<float> dbValues = { 6 , 0, -6, -15, -25, -35, -50, -60 };  // Logarithmic dB values

	g.setColour(findColour(foleys::LevelMeter::lmTicksColour));

	// Drawing ticks and labels
	float stretchFactor = 0.06f;
	if(bounds.getHeight() < 340)
		stretchFactor = 0.09f;

	for (size_t i = 0; i < dbValues.size(); ++i)
	{
		float y = bounds.getY() + i * tickInterval + bounds.getHeight() * stretchFactor;
		g.drawLine(tickStart, y, tickLength, y);  // Left side tick
		g.drawLine(bounds.getRight() * 0.3f, y, bounds.getRight() + tickLength * 1.35f, y);  // Right side tick

		// Drawing labels on the left side
		//juce::String label = juce::String(10 - 10 * i);  // Calculates the dB value
		//g.drawText(label, tickStart, y - 6, 30, 12, juce::Justification::left);
		float db = dbValues[i];
		juce::String label = juce::String(db);
		g.drawText(label, bounds.getX() - bounds.getWidth() + bounds.getWidth() * 0.5f, y - 6, 30, 12, juce::Justification::left);
	}
}

This approach is horrible I know, but i didn’t get closer. I would like to have somehow that I can read the range or scale from the slider actually and then just apply the range to the tickmarks spacing. I hope somebody can help me :slight_smile:

I’d probably be inclined to pass the slider to this draw method, so you can query values against the slider and get the position back from it.

Yes I already tried. I added a member variable which points to the slider from other look and feel methods. Since I only use this sliders in the app, it’s fine but it appears to me not very stable and kind of bit not like it should be used in that way. Do you know if there’s a good function from the slider to apply the range from it to the tickMarks? I already was reading about the normalisedRange and I thought I could get somehow the spaceing from it, so that I could apply that easy to the TikMarks but I couldn’t really find a way.

The NormalisableRange help if you have the range setup non linearly.
For a generic version you should probably take it into account.
But if you have it in linear dB values, you can use the numbers you get.

In the LookAndFeel drawLinearSlider you get an instance of the slider, so you have access to it’s range and even simpler you can call valueToProportionOfLength().

So just have a loop from minimum to maximum and call the valueToProportionOfLength to get the position.

Hey @daniel ,

thank you for your suggestion. It took a little time but now since I understood that the slider_.getHeight() funktion returns the height of the slider and the textbox and not only the slider-track. I feel like I digged deeper into JUCE then before now :slight_smile:
Here is the code which works perfectly and makes a nice log scale :slight_smile: … kind of felt in love with log scales now :joy:

void LookAndFeel::drawTickMarks(juce::Graphics& g,
	foleys::LevelMeter::MeterFlags meterType,
	juce::Rectangle<float> bounds)
{
	if (slider_)
	{
		const float tickStart = bounds.getX() - bounds.getWidth() * 0.001f;
		const float tickLength = bounds.getWidth();
		const std::vector<float> dbValues = { 6, 0, -6, -15, -25, -35, -50, -60 };
		for (int i = 0; i < dbValues.size(); ++i)
		{
			float y = getSliderLayout(*slider_).sliderBounds.getBottom() - getSliderLayout(*slider_).sliderBounds.getHeight() * slider_->valueToProportionOfLength(dbValues[i]);
			g.drawLine(bounds.getRight() * 0.3f, y, bounds.getRight() + tickLength * 1.35f, y);
			float db = dbValues[i];
			juce::String label = juce::String(db);
			g.drawText(label, bounds.getX() - bounds.getWidth() * 0.5f, y - 6, 30, 12, juce::Justification::left);
		}
	}
}
1 Like