Problem with Slider and Popup Display


#1

Hello everybody,
my first post here. I’m using Juce since a few months and never felt the need to modify any of the Juce source files, until yesterday when I was trying to find a way to show an alternate text in the Slider’s popup display. The only public method that allows adding text to the popup is setTextValueSuffix() so I can have both the actual value and my text in the popup, the problem is that the suffix is not updated immediately when that method is called, but the text box is. In juce_Slder.cpp at line 527 there’s the private member that stores the suffix text and calls updateText() but for some reason doesn’t call updatePopupDisplay() as well, so I just added it and now the suffix is properly updated as soon as I call setTextValueSuffix() while dragging the slider.

void setTextValueSuffix (const String& suffix)
{
    if (textSuffix != suffix)
    {
        textSuffix = suffix;
        updateText();
        updatePopupDisplay (getValue());
    }
}

I would suggest this to be implemented in a next update of Juce. Also, it would be useful to have a method to write custom text to the popup display, so I can have a slider with values, e.g. from 0 to 127 (the Midi scale) and the popup read values from -96 dB to 0 dB.


#2

You can do that by supplying lambdas how the text should be converted from and to the number:
Slider::valueFromTextFunction

like:

slider.valueFromTextFunction = [](String text) 
    {
        return Decibels::decibelsToGain (text.dropLastCharacters (3).getFloatValue());
    };
slider.textFromValueFunction = [](float value) 
    {
        return String (Decibels::gainToDecibels(value), 1) + " dB";
    };

Hope that helps.


#3

Thanks for your answer, Daniel. Unfortunately your method does not solve my problem, because the text is updated only after the value has changed, so if the slider range is between 0 and 127, and my text should vary between 0% and 100% (conversion made by my lambda function), I should have 100% when the slider reaches 127, I get 99% instead, and I get 100% if I move the slider at 126. It’s always one interaction behind. Same was with the suffix text. You should modify the source to apply the changes as soon as the lambda is assigned to textFromValueFunction.


#4

Also, my desire was to have two separate texts, the actual value, according to the slider’s range, into the (editable) text box, and an alternate readout text into the popup display.


#5

Well, to your first answer, I wanted to show you an example from a common use case, I didn’t intend to program it for you. You will have to figure out how to make your model so the maximum value matches the maximum number - left as an exercise…

The use case to have something different displayed in a popup is rather specific, so you shouldn’t expect, that the JUCE is adding that functionality (or maybe I didn’t understand it, it’s not my say anyway).

But you can do something similar by setting this converted value as tooltip of the Slider.

Hope that helps…


#6

I understand and appreciate the help, but there’s still a problem here: the texts in the text box and that in the popup display appear not to be synchronized.

I tried this, after reading your post:

		sld->onDragStart = [sld, this, ID] { sld->textFromValueFunction = [this, ID](float value) { return processor.getParameterReadout(ID); }; };
		sld->onDragEnd = [sld] { sld->textFromValueFunction = nullptr; sld->updateText(); };

It works, the text in the popup display is replaced by the text generated by my function getParameterReadout() but it’s not updated properly, so that the two texts always appear to be different, especially when you move the slider fast.

Besides, when I assign my lambda to textFromValueFunction I get warnings like this:

c:\juce\projects[…](191): note: see reference to function template instantiation ‘std::function<juce::String (double)> &std::function<juce::String (double)>::operator =<EditPanel::CreateParameter::<lambda_680ae807a6f2ea2d3550cb497deca47c>::()::<lambda_7b4d8295b40d4c8f9a7c27421bac8716>,juce::String,void>(_Fx &&)’ being compiled
1> with
1> [
1> _Fx=EditPanel::CreateParameter::<lambda_680ae807a6f2ea2d3550cb497deca47c>::()::<lambda_7b4d8295b40d4c8f9a7c27421bac8716>
1> ] (compiling source file …\Source\PluginProcessor.cpp)


#7

Ok, apologies… I copied the code from an AudioProcessorValueTreeState parameter, which works in floats. It can be easily changed:

slider.valueFromTextFunction = [](String text) 
    {
        return Decibels::decibelsToGain (text.dropLastCharacters (3).getDoubleValue());
    };
slider.textFromValueFunction = [](double value) 
    {
        return String (Decibels::gainToDecibels(value), 1) + " dB";
    };

I didn’t use the popup component though, so I can’t comment on that. I would have expected it uses the lambdas as well…


#8

Oh ok, this fixes the compiler warnings, I had totally overlooked the double vs. float difference.
But still the text in the popup display isn’t updated properly, it doesn’t follow the actual slider’s value.