setNumDecimalPlacesToDisplay() not behaving [SOLVED]

Hi I’m trying to use Slider::setNumDecimalPlacesToDisplay() to control the amount of places after the comma. At first it worked, but at some point in development it just started doing it’s own thing.
According to this post, that is due to the SliderAttachment using its own function, which I can set to nullptr.
However, after doing so, I still get the max amount of places, instead of the ones I specified

I found a solution! For any future lost traveler looking for the answer:

I overwrote the slider derived classes getTextFromValue() function like so:

String Knob::getTextFromValue(double value) {
  std::stringstream stream;
  stream << std::fixed << std::setprecision(getNumDecimalPlacesToDisplay()) << value << getTextValueSuffix().toStdString();
  std::string s = stream.str();
  return s;
}

But you have to set setNumDecimalPlacesToDisplay() after you connect the SliderAttchement to your slider. The slider attachment will reset that value for some reason.

Phew, that’s a bit too complicated.

a) since you use the SliderAttachment anyway, best to set the lambda when constructing your AudioParameterFloat, that way the display in the host’s automation display, the GenericAudioProcessorEditor and the attached Slider will be consistent
b) if you still want to override the behaviour of the Slider, you can set the lambda of the Slider and save the inheriting
c) you can do the decimal places of your string in the String class:

String Knob::getTextFromValue(double value) 
{
    return String (value, getNumDecimalPlacesToDisplay());
}

( I remember there was some confusion a few months back, when that version didn’t fill with zeroes. I believe this is fixed now)

1 Like

A cool, I wan’t aware of the lambda in SliderAttachment, I will rework the thing tonight, thanks for your input :slight_smile:

Yes, it propagates the parameter’s behaviour to the slider, so the attachment is only used to synchronise, it’s not configured in itself:

I would love to see the same thing happening for the ComboBoxAttachment, it could (and should) copy the choices from an AudioParameterChoice to the ComboBox.

It’s one dynamic_cast and a few lines:

    Pimpl (AudioProcessorValueTreeState& s, const String& p, ComboBox& c)
        : AttachedControlBase (s, p), combo (c), ignoreCallbacks (false)
    {
        if (auto* param = dynamic_cast<AudioParameterChoice*>(state.getParameter (paramID)))
        {
            if (combo.getNumItems() == 0)  // leaves the user the choice to define his/her own
                combo.addItemList (param->choices, 1);
        }

        sendInitialUpdate();
        combo.addListener (this);
    }

How about that, @t0m or @ed95 ?

yeah +1 for the combobox. I was really confused when the values chosen didn’t propagate to the audio param, since you quite literally set them up to very specific values.

What, specifically, do you pass? I’m trying

[this](float value, int maximumStringLength) -> String { return String(value, maximumStringLength); }));

as the lambda but I’m not matching the constructor (which was working before).

@Tote_Bag Strange, this one works for me:

I never used the fancy format using the -> String, I would expect it to work as well though.
But I would avoid to capture this, since you don’t need it anyway.
Maybe you missed a parameter before, so the lambda occurs actually on the wrong position?

Another thing to mention: the AudioParameterFloat takes float values, vs. the slider takes doubles. But that is handled behind the scenes by implicit cast, AFAIK. So for the parameter this should work.

Yep, I was missing a parameter, the string before “plugin category” parameter. Thank you!

Also yeah I also fixed it so I’m doing [] instead of [this]