ParameterChoiceComboBox implementation


#1

Hello everybody,

I'm trying to implement a ParameterChoiceComboBox class like the ParameterSlider in the juce demo plugin.

I overrided ComboBox::valueChanged() and Timer::timerCallback() as the ParameterSlider class does.

But sometimes, instead of the ParameterSlider, the ParameterChoiceComboBox component triggers the timerCallback just before valueChanged(), which reset the changes.

Fastest the timer is, more often the problem occured.

Is there any ComboBox callback that could be everytime triggered before the Timer one ?

Here is code :

class ParameterChoiceComboBox : public ComboBox, private Timer {
public:
  ParameterChoiceComboBox(AudioParameterChoice &p) : param(p) {
    for (int i = 0; i < param.choices.size(); ++i)
      addItem(param.choices[i], i + 1);
    startTimerHz(300); // Fast timer will bug everytime
    update();
  }
  void valueChanged(Value &v) override {
    ComboBox::valueChanged(v);
    param.setValueNotifyingHost((float)(ComboBox::getSelectedId() - 1) /
                                (float)(param.choices.size() - 1));
  }
  void timerCallback() override { update(); }
  void update() {
    if (param != ComboBox::getSelectedId() - 1)
      setSelectedId(param + 1, NotificationType::dontSendNotification);
  }
  AudioParameterChoice &param;
  JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ParameterChoiceComboBox)
};

 

Any help will be much appreciated

Cheers,

Louis


#2

Hi,

I think the reason why the ParameterSlider in the demo plugin works is this:

void updateSliderPos()    
{
    const float newValue = param.getValue();

    if (newValue != (float) Slider::getValue() && ! isMouseButtonDown())
        Slider::setValue (newValue);
}

Specifically, the additional condition ! isMouseButtonDown()

This prevents any updates from the timer callback while the mouse button is down (= while the user is changing the value).

Some similar logic for the combo box is missing from your example.


#3

Hello and thank you for your response,

You can notice that for sliders the wheel still works, even if isMouseButtonDown() returns false, i think because internal slider set and Slider::valueChanged() cannot be interlaced with the timerCallback()

And unfortunatly, for combobox there are no function like isMouseButtonDown() available or startedDragging()/stoppedDragging(), and even if one existed perhaps that Combobox::valueChanged() would still be triggered too late.

Perhaps i'm missing something.

Cheers,

Louis


#4

Hi Louis,

what about ComboBox::isPopupActive() const; ?

http://www.juce.com/doc/classComboBox#a3307a4dd3d9eb4983e6f1ed7cfaaf74e

Should be a good replacement for isMouseButtonDown().

Good Luck,
Daniel


#5

Hello,

Sorry I didn't see isPopupActive() before.

I just tried it, but it doesn't work. ComboBox::valueChanged() is called too late, isPopupActive() already returns false, so the timerCallback
may have been called meanwhile with isPopupActive() = false.

Thanks for your help,

Louis


#6
  void update() 
  {
    if (param != ComboBox::getSelectedId() - 1 && ! ComboBox::isPopupActive())
      ComboBox::setSelectedId(param + 1, NotificationType::dontSendNotification);
  }

 is that what you did?  

 I can't see why that wouldn't work.  


#7

Did this ever get resolved? I’m fighting this same thing right now.