You should not modify the UI directly from DSP code.
However, you could modify the UI from UI code, based on a state controlled by the DSP code. Add a bool Module::lfoMode variable and set it from DSP code. Override ModuleWidget::step() and in it, call the superclass method and hide/show the desired ParamWidget based on the value of Module::lfoMode.
I’m curious, I know we should not use dynamic_cast in DSP code. Even if the UI thread is not time critical doesn’t a dynamic_cast in step() still need more CPU cycles for every frame than accessing a pointer?
Depending on what you have in mind and their visual appearance, please note that it’s generally considered non-idiomatic to conceal UI widgets that appear to be physical elements, rather than drawn on an interactive display.
You’re right that it shouldn’t be called in DSP code, but it should be fine in UI code. I can’t imagine it taking more than 100ns, and in this case it’s only called once every 1/60 seconds, so it’ll only contribute to 0.0005% CPU. If you’re nervous about using it, use reinterpret_cast, since that takes zero cycles and you know the derived type is a MyModule.
Also this. There are tons of disadvantages in automatically hiding widgets. I prefer my panels to not change, and I’m sure most users agree.
Curious: why this would be “idiomatic”? I could see the knob change position (due to different range). So basically, would be “unreal” in both case in a real-hardware scenario, isn’t?
Changing param ranges isn’t really supported by VCV. You shouldn’t rely on unsupported behavior. You also shouldn’t really be touching ParamQuantity with DSP code. It belongs more to the UI.
Why do you want to do this on the parameter level? Just let the parameter run from 0.0 to 1.0 (or any other meaningful range) and handle the different modes internally in the process routine.
Changing the configuration of the knob label (using the optional parameters of configParam) would be a lot less disruptive than actually changing the min and Max values.
You shouldn’t need any non-native code.
If you change the min and Max, its difficult to have a consistent behaviour for the knob when you change the range. The knob position might or might not shift. I’ve seen it done and the code is messy and unsatisfying.
Personally I’d keep a single range and just change the display rules, and the internal interpretation.