Hello,
I’am trying to bind a button click in my UI to a Label in the UI. So when I click the button I want my Label text to update to whatever value I set. I have been able to follow the example described about standalone library bindings by using the IModelBinding interface and set up a handler for my button click:
binding->addValue(Value::make("MyButtonControlTag"),
UIDesc::ValueCalls::onAction([this](auto &v)
{
this->myFunction();
}));
This calls myFunction whenever I click the button. But I don’t know how to get my Label to update its text from this handler. Am I suppose to register anything somewhere?
I have tried studying the examples minesweeper and standalone but don’t really grasp all the delegates., controllers, adapters and listeners class inheritance party.
I found though in minesweeper that the Label displaying mines with the control-tag Flags is updated whenever you click on a square. I tried to do something similar with the usage of Value::performStringValueEdit function but the application just crashes for me
binding->addValue(Value::make("MyButtonControlTag"),
UIDesc::ValueCalls::onAction([&](auto &v)
{
auto label= binding->getValue("MyLabelControlTag");
Value::performStringValueEdit(*label, "My new string value");
v.performEdit(0.); }));
Am I on the right path or do I misunderstand it completely on how to do this binding? I don’t want to pass a specific value of any other ui component that needs to be calculated to be displayed by the label text. I just want to update a specific Label in the UI with a new string value whenever I click a certain button. This is a standalone application btw and not a plugin.
/Erik
You’re on the right track, but you also need to add the value with the name “MyLabelControlTag” to the binding:
binding->addValue (Value::makeStringValue("MyLabelControlTag", "initial text");
I had already added the value “MyLabelControlTag” to the bidning. I just didn’t paste that part of the code. I tried putting the line auto label= binding->getValue(“MyLabelControlTag”)
inside the lambda function as well but that also crashed.
auto binding = UIDesc::ModelBindingCallbacks::make();
binding->addValue(Value::makeStringValue("MyLabelControlTag", "initial text"));
auto label= binding->getValue("MyLabelControlTag");
binding->addValue(Value::make("MyButtonControlTag"),
UIDesc::ValueCalls::onAction([&](auto &v)
{
v.performEdit(0.);
Value::performStringValueEdit(*label, "My new string");
}));
The call stack of the crash looks like this:
KernelBase.dll!00007ff8ee79536c() (Unknown Source:0)
vcruntime140d.dll!00007ff8c171b760() (Unknown Source:0)
vcruntime140d.dll!00007ff8c171ab83() (Unknown Source:0)
Host.exe!VSTGUI::Interface::dynamicCast<VSTGUI::Standalone::IStringValue>() Line 34 (c:\Users\erikg\Development\audio_plugins\iPlug2\Dependencies\IPlug\VST3_SDK\vstgui4\vstgui\standalone\include\interface.h:34)
Host.exe!VSTGUI::Standalone::Value::performStringValueEdit(VSTGUI::Standalone::IValue & value, const VSTGUI::UTF8String & str) Line 257 (c:\Users\erikg\Development\audio_plugins\iPlug2\Dependencies\IPlug\VST3_SDK\vstgui4\vstgui\standalone\include\helpers\value.h:257)
Host.exe!<lambda_fa3cc6a6fcefaa148424b59c950804ec>::operator()<VSTGUI::Standalone::IValue>(VSTGUI::Standalone::IValue & v) Line 96 (c:\Users\erikg\Development\audio_plugins\Host\source\myapp.cpp:96)
Host.exe!std::invoke<<lambda_fa3cc6a6fcefaa148424b59c950804ec> &,VSTGUI::Standalone::IValue &>(MyApplication::finishLaunching::__l2::<lambda_fa3cc6a6fcefaa148424b59c950804ec> & _Obj, VSTGUI::Standalone::IValue & _Arg1) Line 1587 (c:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\include\type_traits:1587)
Host.exe!std::_Invoker_ret<void>::_Call<<lambda_fa3cc6a6fcefaa148424b59c950804ec> &,VSTGUI::Standalone::IValue &>(MyApplication::finishLaunching::__l2::<lambda_fa3cc6a6fcefaa148424b59c950804ec> & _Func, VSTGUI::Standalone::IValue & <_Vals_0>) Line 674 (c:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\include\functional:674)
Host.exe!std::_Func_impl_no_alloc<<lambda_fa3cc6a6fcefaa148424b59c950804ec>,void,VSTGUI::Standalone::IValue &>::_Do_call(VSTGUI::Standalone::IValue & <_Args_0>) Line 834 (c:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\include\functional:834)
Host.exe!std::_Func_class<void,VSTGUI::Standalone::IValue &>::operator()(VSTGUI::Standalone::IValue & <_Args_0>) Line 875 (c:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\include\functional:875)
Host.exe!VSTGUI::Standalone::UIDesc::ValueCalls::onAction::__l2::<lambda>(VSTGUI::Standalone::IValue & v) Line 48 (c:\Users\erikg\Development\audio_plugins\iPlug2\Dependencies\IPlug\VST3_SDK\vstgui4\vstgui\standalone\include\helpers\uidesc\modelbinding.h:48)
Host.exe!std::invoke<void <lambda>(VSTGUI::Standalone::IValue &) &,VSTGUI::Standalone::IValue &>(VSTGUI::Standalone::UIDesc::ValueCalls::onAction::__l2::void <lambda>(VSTGUI::Standalone::IValue &) & _Obj, VSTGUI::Standalone::IValue & _Arg1) Line 1587 (c:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\include\type_traits:1587)
Host.exe!std::_Invoker_ret<void>::_Call<void <lambda>(VSTGUI::Standalone::IValue &) &,VSTGUI::Standalone::IValue &>(VSTGUI::Standalone::UIDesc::ValueCalls::onAction::__l2::void <lambda>(VSTGUI::Standalone::IValue &) & _Func, VSTGUI::Standalone::IValue & <_Vals_0>) Line 674 (c:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\include\functional:674)
Host.exe!std::_Func_impl_no_alloc<void <lambda>(VSTGUI::Standalone::IValue &),void,VSTGUI::Standalone::IValue &>::_Do_call(VSTGUI::Standalone::IValue & <_Args_0>) Line 834 (c:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\include\functional:834)
Host.exe!std::_Func_class<void,VSTGUI::Standalone::IValue &>::operator()(VSTGUI::Standalone::IValue & <_Args_0>) Line 875 (c:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\include\functional:875)
Host.exe!VSTGUI::Standalone::UIDesc::ModelBindingCallbacks::onEndEdit(VSTGUI::Standalone::IValue & value) Line 141 (c:\Users\erikg\Development\audio_plugins\iPlug2\Dependencies\IPlug\VST3_SDK\vstgui4\vstgui\standalone\include\helpers\uidesc\modelbinding.h:141)
Host.exe!VSTGUI::Standalone::Detail::`anonymous-namespace'::Value::endEdit::__l7::<lambda>(VSTGUI::Standalone::IValueListener * l) Line 371 (c:\Users\erikg\Development\audio_plugins\iPlug2\Dependencies\IPlug\VST3_SDK\vstgui4\vstgui\standalone\source\helpers\value.cpp:371)
Host.exe!VSTGUI::DispatchList<VSTGUI::Standalone::IValueListener *>::forEach<void <lambda>(VSTGUI::Standalone::IValueListener *)>(VSTGUI::Standalone::Detail::`anonymous-namespace'::Value::endEdit::__l7::void <lambda>(VSTGUI::Standalone::IValueListener *) proc) Line 173 (c:\Users\erikg\Development\audio_plugins\iPlug2\Dependencies\IPlug\VST3_SDK\vstgui4\vstgui\lib\dispatchlist.h:173)
Host.exe!VSTGUI::Standalone::Detail::`anonymous namespace'::Value::endEdit() Line 373 (c:\Users\erikg\Development\audio_plugins\iPlug2\Dependencies\IPlug\VST3_SDK\vstgui4\vstgui\standalone\source\helpers\value.cpp:373)
Host.exe!VSTGUI::Standalone::`anonymous namespace'::ValueWrapper::controlEndEdit(VSTGUI::CControl * control) Line 187 (c:\Users\erikg\Development\audio_plugins\iPlug2\Dependencies\IPlug\VST3_SDK\vstgui4\vstgui\standalone\source\uidescriptionwindowcontroller.cpp:187)
The return value of binding->getValue() is a shared_ptr you have to copy the shared pointer to the lambda and not access the memory of it via reference. Thus change UIDesc::ValueCalls::onAction([&](auto &v)
to UIDesc::ValueCalls::onAction([=](auto &v)
Thanks for your help! Worked perfectly!