Update graphics on parameter change

Hey everyone,
I’ve been working with the iPlug2 framework a lot for the past month and have gotten some good things from it. Right now, I have a project that has an LCD-like display (bitmap text) and a knob attached to an enum parameter (for distortion modes). What would be a good way to update the bitmap text whenever the knob changes?
Thanks in advance, and sorry if the answer is obvious :slight_smile:

There’s a similar topic here: Updating parameters and control labels dynamically

I think you want to override the OnParamChange(paramIndex) function in order to update your LCD display whenever the parameter associated with the knob changes.

Thanks, I just now good a good look over it and implemented OnParamChange(paramIndex) with an override. I ended up with a loading error whenever I included GetGUI() in OnParamChange(). I was able to reproduce the error on my test plugin, so I’m not sure if I’m just unlucky or just overlooking something. I was able to get it to work with OnIdle(), though right now I am loading the bitmap every single time for the knob in OnIdle(). I couldn’t figure a out a way to use the one declared in the constructor. Should GetGui() not be working in OnParamChange()?

I think instead of GetGUI() you can use GetControlWithTag(kCtrlTag). So when you create your bitmap control, you give it a tag (instead of the usual NoTag), and then by using the function above with the appropriate tag, you can get a pointer directly to the bitmap.

1 Like

The problem that you are facing is that parameters are persistent, while the GUI is not (the GUI is destroyed when you close the plug-in window). When you call GetUI() within OnParamChange you need to check the result first before dereferencing it, because it might be a nullptr. For example:
if(auto graphics = GetUI()) { graphics->doSomethingWithYourControl(...); }
GetControlWithTag is a member function of the GUI so there is no way around the above check.
And as an alternative to OnParamChange you could also register a callback function in your knob, where it is safe to assume that the GUI is actually there (the knob is obviously in the GUI). I guess there are tons of examples in the iplug2 repo on how to do this.

2 Likes

I hope I can clarify a few things here:

Firstly, in iplug2 OnParamChangeUI() should be used to do GUI things and not OnParamChange(). However, you probably don’t need that because…

If you want the control to always relate to the parameter (particularly if it essentially displays this parameter, but even if it does other things) then the idiomatic and best way to do this is to bind the control to the parameter index. Two controls can be bound to the same parameter index, and that is the simplest and best way to do it.

You then look at the parameter in Draw() or if you need to pre-calculate (which I wouldn’t simply for selecting a text item from an enum for example) then you can I believe override SetValue() for the control (and call super before your custom additions).

Note that controls can read parameter values using GetParam() if you don’t want the normalised value that’ll be returned by GetValue(). If your text string is in the parameter you could also use this to read it.

Sending messages to controls is needed for other things (showing/hiding/things not involving parameters etc.) but it should be avoided for simple cases of linking controls to a parameter value for control OR display. iplug2 implements this all in a much easier way than iplug1, where such things are necessary. It also allows multiple parameters bound to a single control, and the control gets updated for all changes. I see messaging controls as a last resort where it simply doesn’t fit the more normal model.

In terms of GUI persistency you can restore GUI state, but this requires a bit more code to deal with (especially if it needs storing in plugin state). However, it doesn’t sound like any of this is necessary here.

4 Likes

Thanks, that makes a lot of sense. I created a custom IControl control and in Draw() I get my parameter (kDistortModes). I tried using GetValue() and also GetParameter(), but when I tried to fetch the value for kDistortModes, I ended up with an assertion error when I would open the plugin. The error does not appear if I do not include GetValue() or GetParameter(). I’m guessing it is trying to get something that doesn’t exist, but can’t figure out what exactly to do. Thanks!

Edit: It was my own stupidity, everything you wrote was correct. I was trying to get kDistortModes by GetValue(kDistortModes), which did some funky stuff. If anyone else ever falls into that trap-

distortText[static_cast<int>(GetValue()*4)]

works for now (where distortText is a char array of the params. I could probably clean it up a bit more, but it works).

Great! Glad to help!

1 Like