Dynamic View Switching

Hi all,

I’m using the sweet WYSIWYG editor to create a View Switch Container containing two templates.
I can switch between these two views using the template-switch-control linked via control-tag to a segment button on the GUI and all works well.

The issue I’m tackling with is that I would like to dynamically update the switch control from within the plugin. So that when a user selects a new preset that requires that view to change, then it will. (for instance between a tempo synced/non synced control)

Currently nothing I’m doing short of physically interacting with that segment button will make the views switch and reflect the buttons actual state if it has changed via a new preset selection.

I’ve tried resending the linked ControlID value from elsewhere in the plugin but that doesn’t seem to help.

Is this even possible / what strategy would be best employed to achieve something like this?

Many thanks,
Jay

1 Like

You need to set the control tag of the segment button to the Parameter ID and use the same tag for the view switch container. I’ve used this many times.

Thanks for replying Arne.

That seems to be what I’ve done however the method isn’t operating correctly on preset changes.

The control tag I’m using, “ControlID::swtch” is currently written in the SegmentButton’s control-tag field and in the ViewSwitchContainer’s template-switch-control field and nowhere else in the editor. Is that right?

Doing that allows for expected operation when using the segment-button with the mouse.
But if I use Reaper to save & then load a new preset with a different segment-button state then that change is not reflected in the GUI’s ViewSwitchContainer. If I now close the GUI and reopen it, then the correct template is displayed there.

I have also tried implementing the segment button control differently as an option menu and a horizontal switch but get similar results.

In Ableton it seems that if I save and then reload a .vstpreset, then the second template in the ViewSwitch case will never be loaded. Also while moving the control in Ableton’s parameter list then the SegmentButton will change accordingly on the GUI but this will not update the ViewSwitchContainer state. However if the GUI is closed and you move that parameter then on reopening the GUI, the View will now display the correct state.

Is anything like that behaviour reproducable for you? or could I have made an implementation error?

Cheers

How do you save the state for that control ID?

Excellent question. Here’s the code using a bound integer for no reason named swtich which was declared in plugincore.h.

int swtich = 0;
then in plugincore.cpp;

bool PluginCore::initPluginParameters()
{
PluginParameter* piParam = nullptr;

piParam = new PluginParameter(controlID::swtch, “swtch”, “off,on”, “off”);
piParam->setBoundVariable(&swtich, boundVariableType::kInt);
addPluginParameter(piParam);

initPluginParameterArray();
return true;
}

This is much like I’ve been doing with all my other working parameters.

I’ve tried a few ways to toggle and then update this bound control from plugincore (toggling/updating a host message to it when I detect another parameter has changed) but the SwitchView always seems to be unresponsive to the bound control. Unless the GUI is closed/reopened.

I am using Windows 7 and the ASPiK framework BTW.

Cheers

I’m not familiar with ASPiK, so you have to ask Will why this is not working.

I have had the exact same problem with this view. The issue is that this view requires a control (button, etc…) not a parameter.

The code here (vstgui/uiviewswitchcontainer.cpp at vstgui4_9 · steinbergmedia/vstgui · GitHub) handles the case when the control changes not when the parameter value changes.

The code here vstgui/uiviewswitchcontainer.cpp at vstgui4_9 · steinbergmedia/vstgui · GitHub uses the tag to determine a control.

This code:

if (switchControlTag != -1)
{
	// find the switch Control
	switchControl = findControlForTag (viewSwitch->getParentView ()->asViewContainer (), switchControlTag, false);
	if (switchControl == nullptr)
	{
		switchControl = findControlForTag (viewSwitch->getFrame (), switchControlTag, true);
	}
	if (switchControl)
	{
		switchControl->registerControlListener (this);
		valueChanged (switchControl);
	}
}

clearly shows what is going on:

The tag is only used to find a control that drives it and a listener is set on the control not the value of the parameter. As a result, try to have 2 controls (2 buttons) with the same tag and you will see that this view doesn’t work if the value of the parameter gets changed by one of them… although the value of the parameter has changed! Or try to change the value from the RT and you will see it doesn’t work either. This explains what happens with your preset being reloaded… it changes the value of the parameter (which is right), not the control.

I know this problem very well as I bumped into it and is the reason why, in Jamba, I created a brand new one that actually ties to a parameter, not a control and so you can have as many controls as you want, change the value in RT, etc… and it still works. See Documentation or Code

He has a control. So it’s a different issue than what you had. I suspect the ASPiK framework at cause here.

Hi Yan,
Thanks for your insights on this and the linked code. I also experience that additional issue you mention where two controls linked to the switch’s ControlID will prevent the SwitchView from operating.
I probably won’t be able to utilize the Jamba framework in the near future though as I’m currently rather invested in ASPiK and doubt I have the skills to incorporate the two, but I’m very glad that there is at least a potential solution.

Thanks also Arne. I will ask Will to share his thoughts on this. However even given that there is something wrong with ASPiK, I would still likely find it necessary that the ViewSwitch responds from a parameter in the RT, if it currently doesn’t do so, as Yan is claiming.

Cheers

I’m unsure why Yan and you are having problems. If you use one control linked to a parameter to drive the view switch container then everything should work out of the box. If the host changes the parameter linked to the control per example via automation the control will notify the view switch container about it and it will then switch the contained view.

@Arne_Scheffler maybe this has been fixed since when I tried it, but I can guarantee you that changing the value of the parameter via RT was not being propagated properly. I was using VST 3.6.9 when this behavior was happening. And maybe it has been fixed since.

If it works now, then it should be super easy to verify:

  • have 2 controls tied to the same parameter (ex: toggle button)
  • let’s assume that the switch controller gets tied to Control 1 (the function calls findControlForTag to find one of them)
  • if you press Control 2, then the value of the parameter will be updated to the new value… which should trigger Control 1 to be also updated… which according to what you say should also trigger the view switch container to change view…

It seems that @Jay2 is reporting that this is not working…

Yan

I only use one control in my plug-ins. This works. I never checked if two controls will work or not. It should make no difference I think. Maybe the kind of control make the difference, I don’t know. If you provide example code, which is not working I can have a look.

Hi Arne,

I wanted to bring this issue up again as it is still persisting with the latest SDK.

It’s easy to verify this problem.

  1. Set up a plugin with a UIViewSwitchContainer and SwitchController to select between two views A and B.

  2. Save a preset named B with the View and Switch set to their B state.

  3. Reset the Switch/View to their A position.

  4. Load Preset B

The Switch will change but the View will not.

You’ll then need to click the Switch to set it to it back to it’s A state (resyncing it with the View) and then click it once more to set both the View and Switch to the desired B state.

I think Yan is correct with the problem he identified. I hope you could look into this for a future update.

Thanks

I still have no sample code to reproduce this issue. Please make a simple project that shows this behavior to help me find a solution.

I just built the helloworldwithVSTGUI.vst3 test example to show you.

I didn’t need to modify any code though.

Starting with a new helloworldwithVSTGUI.vst3 build.

I opened the WSIWYG editor and created two templates of the CView type and renamed those A and B.

For the B template I changed the background colour to red and left A’s black.

Lastly I created a ViewSwitchContainer and set it’s template-names field to A,B and it’s template-switch-control field to ParamOn.

Saved, rebuilt. That’s it.

On testing the ViewSwitch works as intended. When the switch is on the View is red and it’s black when it is off.

However this fails to update upon preset loading events as previously described.

I’m attaching my debug bundle VST3 so you can try it on Windows if you’re running that. I had to delete the nice looking knobs to fit the upload though.
helloworldWithVSTGUI.vst3.zip (3.0 MB)

Alternatively just copy plug.uidesc from the Resources I’ve sent onto a new helloworldwithGUI and build that.
Or try with a fresh build as described above.

Many thanks

OK thanks. Now I was able to fix the issue. Please cherry-pick this git commit for the fix: make sure all control listeners will be notified about control change… · steinbergmedia/vstgui@cfcf171 · GitHub

Goodness. Thankyou for resolving this.