Who called setValue?


#1

I have another little problem. My editor has a group of combo boxes that need to be changed based on the setting of a single knob. Changing the value of a combo box programmatically is easy enough, but the behavior of the editor must depend on who made the change. I don’t want any extra logic to execute if the editor made the change, but if a human did it, there are other things that need to happen. The thing is, comboBoxChanged doesn’t seem to have any way of knowing where the change originated.

So I’m wondering about this problem; also what to do about this kind of situation in general. Is this where that update message flag in the set value methods comes in?


#2

Yes, you have to do it with that flag, like you say.


#3

Actually, I’ve been thinking about it, and the thing that’s bothering me is broader in scope. The problem that started this thread is a separate, smaller problem that indeed is solved by the proper use of the update message flag.

If a human moves the slider, sliderValueChanged needs to tell both the host and the filter about it. In this case, the filter must not trigger a change message to the editor because the slider will already be repainted as it should. On the other hand, if the host is automating, the editor doesn’t know to repaint unless the filter tells it to (right?), which means that the filter must trigger the change message. Unfortunately, setParameter lacks any means of communicating whether the change is automatic or manual.

We could try to solve the problem by making setParameter call sendChangeMessage no matter what, and letting the editor figure out whether or not to change the slider value. But then how would the editor know whether the change message resulted from human activity or from the host automation? We could set a flag in sliderValueChanged, but if the human is manipulating a slider while the host is trying to automate it, the editor might attribute the set flag to the wrong change in the filter, and call setValue when it shouldn’t, or not call it when it should, or both.

Another approach might be to have the editor call setValue every time it’s told of a change in the filter. This seems to be right out because setValue would be called twice for every human-caused change.

Perhaps some tricky deriving and overriding would work, but that seems like a whole lot of effort just to make things behave properly. I’m even beginning to doubt whether this is JUCE’s problem. Again, maybe I’m missing something. Am I looking at things in a completely wrong way?


#4

Have you read this thread:

http://www.rawmaterialsoftware.com/juceforum/viewtopic.php?t=1238

there was a small discussion on the same issue there.


#5

Hmmmm, thanks Valley. Maybe I shouldn’t worry about it so much.


#6

Hmmmm, thanks Valley. Maybe I shouldn’t worry about it so much.


#7

Somehow I missed that other thread.

It seems that the following sequence doesn’t bother people that much:

  • User interacts with a control
  • setParameterNotifyingHost
  • setParameter
  • sendChangeMessage()
    — async
  • if(value != newvalue) set component value without sending a new message

However what if the user is dragging the control? when we try to set the control value as a result from setParameter, the current control value as already a new value, and trying to change it will cause some really bad looking jittering on the control position.

I have this problem especially on Mac. The async call seems to take more time than on my PC. As a result the differences between, the current and old value start to be really significant.

I already mentionned this in another post and one solution would consist in avoiding to set the control’s value when it is being dragged.

However I see this as a workaround and I’d like to know if there are better solutions that fits nicely with the standard classes. Here I should subclass every control I use just to add a single drag flag.


#8

You could just use a call like isMouseButtonDown to see if they’re dragging the slider. (Not ideal, I guess)


#9

thanks, I missed that one. at least I don’t have to subclass each components I use.

It would be interresting to have this state logic directly inside the standard components. Unless there’s a better solution.


#10

[quote=“mdsp”]Somehow I missed that other thread.

It seems that the following sequence doesn’t bother people that much:

  • User interacts with a control
  • setParameterNotifyingHost
  • setParameter
  • sendChangeMessage()
    — async
  • if(value != newvalue) set component value without sending a new message

However what if the user is dragging the control? when we try to set the control value as a result from setParameter, the current control value as already a new value, and trying to change it will cause some really bad looking jittering on the control position.[/quote]

I use basically the algo given above, and I don’t seem to have jitter problems (PC and Mac). But I’m using rotary sliders, so it may not be so obvious.

I was also worried about this kind of jitter, but I stopped worrying when I didn’t see it in my UI. I still don’t like the duplicate updates, though.

This is a problem I’ve seen in every toolkit I’ve tried. It happens because sliders are both view and controller, and arguably model as well, since they hold a value.

One day I may finally get sick enough of it to write a slider which doesn’t know its value, and which doesn’t update its own view in response to a mouse drag. Then you could split these things apart and have done with this problem.


#11