Audacity 3.2.0
Classes | Public Member Functions | Static Public Member Functions | Public Attributes | List of all members
LV2Validator Class Referencefinal

#include <LV2Validator.h>

Inheritance diagram for LV2Validator:
[legend]
Collaboration diagram for LV2Validator:
[legend]

Classes

struct  PlainUIControl
 
struct  Timer
 This must be destroyed before mSuilInstance. More...
 
struct  UI
 

Public Member Functions

 LV2Validator (EffectBase &effect, const LilvPlugin &plug, LV2Instance &instance, EffectSettingsAccess &access, const EffectOutputs *pOutputs, double sampleRate, const LV2FeaturesList &features, const LV2Ports &ports, wxWindow *parent, bool useGUI)
 
 ~LV2Validator () override
 
bool ValidateUI () override
 Get settings data from the panel; may make error dialogs and return false. More...
 
bool UpdateUI () override
 Update appearance of the panel for changes in settings. More...
 
bool IsGraphicalUI () override
 
void Disconnect () override
 On the first call only, may disconnect from further event handling. More...
 
int ui_resize (int width, int height) override
 
void ui_closed () override
 
void SizeRequest (GtkWidget *widget, GtkRequisition *requisition)
 
bool BuildFancy (std::unique_ptr< LV2Wrapper > pWrapper, const EffectSettings &settings)
 
bool BuildPlain (EffectSettingsAccess &access)
 
void suil_port_write (uint32_t port_index, uint32_t buffer_size, uint32_t protocol, const void *buffer) override
 
uint32_t suil_port_index (const char *port_symbol) override
 
void UpdateControlPortValue (LV2EffectSettings &settings, size_t controlPortIndex, float value)
 
void OnTrigger (wxCommandEvent &evt)
 
void OnToggle (wxCommandEvent &evt)
 
void OnChoice (wxCommandEvent &evt)
 
void OnText (wxCommandEvent &evt)
 
void OnSlider (wxCommandEvent &evt)
 
void OnIdle (wxIdleEvent &evt)
 
void OnSize (wxSizeEvent &evt)
 
void SetSlider (const LV2ControlPortState &state, const PlainUIControl &ctrl)
 
- Public Member Functions inherited from EffectUIValidator
 EffectUIValidator (EffectUIClientInterface &effect, EffectSettingsAccess &access)
 
virtual ~EffectUIValidator ()
 
virtual bool ValidateUI ()=0
 Get settings data from the panel; may make error dialogs and return false. More...
 
virtual bool UpdateUI ()
 Update appearance of the panel for changes in settings. More...
 
virtual bool IsGraphicalUI ()
 
virtual void Disconnect ()
 On the first call only, may disconnect from further event handling. More...
 
virtual void OnClose ()
 
- Public Member Functions inherited from Observer::Publisher< EffectSettingChanged >
 Publisher (ExceptionPolicy *pPolicy=nullptr, Alloc a={})
 Constructor supporting type-erased custom allocation/deletion. More...
 
 Publisher (Publisher &&)=default
 
Publisheroperator= (Publisher &&)=default
 
Subscription Subscribe (Callback callback)
 Connect a callback to the Publisher; later-connected are called earlier. More...
 
Subscription Subscribe (Object &obj, Return(Object::*callback)(Args...))
 Overload of Subscribe takes an object and pointer-to-member-function. More...
 

Static Public Member Functions

static void size_request (GtkWidget *widget, GtkRequisition *requisition, LV2Validator *pValidator)
 
static std::shared_ptr< SuilHost > GetSuilHost ()
 
- Static Public Member Functions inherited from EffectUIValidator
static bool EnableApply (wxWindow *parent, bool enable=true)
 Enable or disable the Apply button of the dialog that contains parent. More...
 
static bool EnablePreview (wxWindow *parent, bool enable=true)
 

Public Attributes

const LilvPlugin & mPlug
 
const EffectType mType
 
LV2InstancemInstance
 
const EffectOutputsmpOutputs {}
 
const double mSampleRate
 
const LV2PortsmPorts
 
std::unique_ptr< LV2WrappermpWrapper
 
std::optional< const LV2UIFeaturesListmUIFeatures
 
LV2PortUIStates mPortUIStates
 
std::shared_ptr< SuilHost > mSuilHost
 
wxWindow * mParent
 
bool mUseGUI {}
 
std::vector< PlainUIControlmPlainUIControls
 Array in correspondence with the control ports. More...
 
struct LV2Validator::UI mUI
 
wxSize mNativeWinInitialSize { wxDefaultSize }
 
wxSize mNativeWinLastSize { wxDefaultSize }
 
bool mResizing { false }
 
bool mResized { false }
 
wxWeakRef< wxDialog > mDialog
 
bool mExternalUIClosed { false }
 
LV2Validator::Timer mTimer
 
const LV2UI_Idle_Interface * mUIIdleInterface {}
 
const LV2UI_Show_Interface * mUIShowInterface {}
 
NumericTextCtrlmDuration {}
 

Additional Inherited Members

- Public Types inherited from Observer::Publisher< EffectSettingChanged >
using message_type = EffectSettingChanged
 
using CallbackReturn = std::conditional_t< true, void, bool >
 
using Callback = std::function< CallbackReturn(const EffectSettingChanged &) >
 Type of functions that can be connected to the Publisher. More...
 
- Static Public Attributes inherited from EffectUIValidator
static constexpr int kPlayID = 20102
 
- Static Public Attributes inherited from Observer::Publisher< EffectSettingChanged >
static constexpr bool notifies_all
 
- Protected Member Functions inherited from EffectUIValidator
template<typename EventTag , typename Class , typename Event >
void BindTo (wxEvtHandler &src, const EventTag &eventType, void(Class::*pmf)(Event &))
 
- Protected Member Functions inherited from Observer::Publisher< EffectSettingChanged >
CallbackReturn Publish (const EffectSettingChanged &message)
 Send a message to connected callbacks. More...
 
- Protected Attributes inherited from EffectUIValidator
EffectUIClientInterfacemEffect
 
EffectSettingsAccessmAccess
 
bool mUIClosed { false }
 
- Private Member Functions inherited from LV2UIFeaturesList::UIHandler
virtual ~UIHandler ()
 
virtual int ui_resize (int width, int height)=0
 
virtual void ui_closed ()=0
 
virtual void suil_port_write (uint32_t port_index, uint32_t buffer_size, uint32_t protocol, const void *buffer)=0
 
virtual uint32_t suil_port_index (const char *port_symbol)=0
 

Detailed Description

Definition at line 50 of file LV2Validator.h.

Constructor & Destructor Documentation

◆ LV2Validator()

LV2Validator::LV2Validator ( EffectBase effect,
const LilvPlugin &  plug,
LV2Instance instance,
EffectSettingsAccess access,
const EffectOutputs pOutputs,
double  sampleRate,
const LV2FeaturesList features,
const LV2Ports ports,
wxWindow *  parent,
bool  useGUI 
)

Definition at line 102 of file LV2Validator.cpp.

108 : EffectUIValidator{ effect, access }
109 , mPlug{ plug }
110 , mType{ effect.GetType() }
111 , mInstance{ instance }
112 , mpOutputs{ pOutputs }
113 , mSampleRate{ sampleRate }
114 , mPorts{ ports }
115 , mPortUIStates{ instance.GetPortStates(), ports }
116 , mParent{ parent }
117 , mUseGUI{ useGUI }
118{
119 if (mParent)
120 mParent->PushEventHandler(this);
121}
virtual EffectType GetType() const =0
Type determines how it behaves.
Interface for transferring values from a panel of effect controls.
Definition: EffectPlugin.h:239
const LV2PortStates & GetPortStates() const
Definition: LV2Instance.h:36
const LV2Ports & mPorts
Definition: LV2Validator.h:106
const double mSampleRate
Definition: LV2Validator.h:105
const EffectOutputs * mpOutputs
Definition: LV2Validator.h:104
wxWindow * mParent
Definition: LV2Validator.h:112
LV2PortUIStates mPortUIStates
Definition: LV2Validator.h:109
LV2Instance & mInstance
Definition: LV2Validator.h:103
const EffectType mType
Definition: LV2Validator.h:102
const LilvPlugin & mPlug
Definition: LV2Validator.h:101

References mParent.

◆ ~LV2Validator()

LV2Validator::~LV2Validator ( )
override

Definition at line 181 of file LV2Validator.cpp.

182{
183 Disconnect();
184}
void Disconnect() override
On the first call only, may disconnect from further event handling.

References Disconnect().

Here is the call graph for this function:

Member Function Documentation

◆ BuildFancy()

bool LV2Validator::BuildFancy ( std::unique_ptr< LV2Wrapper pWrapper,
const EffectSettings settings 
)
Precondition
pWrapper != nullptr

Definition at line 202 of file LV2Validator.cpp.

204{
205 assert(pWrapper);
206 auto &wrapper = *pWrapper;
207 mpWrapper = move(pWrapper);
208 using namespace LV2Symbols;
209 // Set the native UI type
210 const char *nativeType =
211#if defined(__WXGTK3__)
212 LV2_UI__Gtk3UI;
213#elif defined(__WXGTK__)
214 LV2_UI__GtkUI;
215#elif defined(__WXMSW__)
216 LV2_UI__WindowsUI;
217#elif defined(__WXMAC__)
218 LV2_UI__CocoaUI;
219#endif
220
221 // Determine if the plugin has a supported UI
222 const LilvUI *ui = nullptr;
223 const LilvNode *uiType = nullptr;
224 using LilvUIsPtr = Lilv_ptr<LilvUIs, lilv_uis_free>;
225 LilvUIsPtr uis{ lilv_plugin_get_uis(&mPlug) };
226 if (uis) {
227 if (LilvNodePtr containerType{ lilv_new_uri(gWorld, nativeType) }) {
228 LILV_FOREACH(uis, iter, uis.get()) {
229 ui = lilv_uis_get(uis.get(), iter);
230 if (lilv_ui_is_supported(ui,
231 suil_ui_supported, containerType.get(), &uiType))
232 break;
233 if (lilv_ui_is_a(ui, node_Gtk) || lilv_ui_is_a(ui, node_Gtk3)) {
234 uiType = node_Gtk;
235 break;
236 }
237 ui = nullptr;
238 }
239 }
240 }
241
242 // Check for other supported UIs
243 if (!ui && uis) {
244 LILV_FOREACH(uis, iter, uis.get()) {
245 ui = lilv_uis_get(uis.get(), iter);
246 if (lilv_ui_is_a(ui, node_ExternalUI) || lilv_ui_is_a(ui, node_ExternalUIOld)) {
247 uiType = node_ExternalUI;
248 break;
249 }
250 ui = NULL;
251 }
252 }
253
254 // No usable UI found
255 if (ui == NULL)
256 return false;
257
258 const auto uinode = lilv_ui_get_uri(ui);
259 lilv_world_load_resource(gWorld, uinode);
261 auto &instance = wrapper.GetInstance();
262 auto &features = mUIFeatures.emplace(
263 wrapper.GetFeatures(), &handler, uinode, &instance,
264 (uiType == node_ExternalUI) ? nullptr : mParent);
265 if (!features.mOk)
266 return false;
267
268 const char *containerType;
269 if (uiType == node_ExternalUI)
270 containerType = LV2_EXTERNAL_UI__Widget;
271 else {
272 containerType = nativeType;
273#if defined(__WXGTK__)
274 // Make sure the parent has a window
275 if (!gtk_widget_get_window(GTK_WIDGET(mParent->m_wxwindow)))
276 gtk_widget_realize(GTK_WIDGET(mParent->m_wxwindow));
277#endif
278 }
279
280 // Set before creating the UI instance so the initial size (if any) can be captured
281 mNativeWinInitialSize = wxDefaultSize;
282 mNativeWinLastSize = wxDefaultSize;
283
284 // Create the suil host
285 if (!(mSuilHost = GetSuilHost()))
286 return false;
287
288#if defined(__WXMSW__)
289 // Plugins may have dependencies that need to be loaded from the same path
290 // as the main DLL, so add this plugin's path to the DLL search order.
291 LilvCharsPtr libPath{
292 lilv_file_uri_parse(lilv_node_as_uri(lilv_ui_get_binary_uri(ui)),
293 nullptr)
294 };
295 const auto path = wxPathOnly(libPath.get());
296 SetDllDirectory(path.c_str());
297 auto cleanup = finally([&]{ SetDllDirectory(nullptr); });
298#endif
299
300 LilvCharsPtr bundlePath{
301 lilv_file_uri_parse(lilv_node_as_uri(lilv_ui_get_bundle_uri(ui)), nullptr)
302 };
303 LilvCharsPtr binaryPath{
304 lilv_file_uri_parse(lilv_node_as_uri(lilv_ui_get_binary_uri(ui)), nullptr)
305 };
306
307 // The void* that the instance passes back to our write and index
308 // callback functions, which were given to suil_host_new:
309 UIHandler *pHandler = this;
310
311 // Reassign the sample rate, which is pointed to by options, which are
312 // pointed to by features, before we tell the library the features
313 mUI.mSuilInstance.reset(suil_instance_new(mSuilHost.get(),
314 pHandler, containerType,
315 lilv_node_as_uri(lilv_plugin_get_uri(&mPlug)),
316 lilv_node_as_uri(lilv_ui_get_uri(ui)), lilv_node_as_uri(uiType),
317 bundlePath.get(), binaryPath.get(),
318 features.GetFeaturePointers().data()));
319
320 // Bail if the instance (no compatible UI) couldn't be created
321 if (!mUI.mSuilInstance)
322 return false;
323
324 if (uiType == node_ExternalUI) {
325 mParent->SetMinSize(wxDefaultSize);
327 suil_instance_get_widget(mUI.mSuilInstance.get()));
328 mTimer.Start(20);
330 } else {
331 const auto widget = static_cast<WXWidget>(
332 suil_instance_get_widget(mUI.mSuilInstance.get()));
333
334#if defined(__WXGTK__)
335 // Needed by some plugins (e.g., Invada) to ensure the display is fully
336 // populated.
337 gtk_widget_show_all(widget);
338
339 // See note at size_request()
340 g_signal_connect(widget, "size-request", G_CALLBACK(LV2Validator::size_request), this);
341#endif
342
343 wxWindowPtr< NativeWindow > pNativeWin{ safenew NativeWindow() };
344 if (!pNativeWin->Create(mParent, widget))
345 return false;
346 mUI.mNativeWin = pNativeWin;
347 pNativeWin->Bind(wxEVT_SIZE, &LV2Validator::OnSize, this);
348
349 // The plugin called the LV2UI_Resize::ui_resize function to set the size before
350 // the native window was created, so set the size now.
351 if (mNativeWinInitialSize != wxDefaultSize)
352 pNativeWin->SetMinSize(mNativeWinInitialSize);
353
354 wxSizerItem *si = NULL;
355 auto vs = std::make_unique<wxBoxSizer>(wxVERTICAL);
356 auto hs = std::make_unique<wxBoxSizer>(wxHORIZONTAL);
357 if (features.mNoResize) {
358 si = hs->Add(pNativeWin.get(), 0, wxCENTER);
359 vs->Add(hs.release(), 1, wxCENTER);
360 } else {
361 si = hs->Add(pNativeWin.get(), 1, wxEXPAND);
362 vs->Add(hs.release(), 1, wxEXPAND);
363 }
364 if (!si)
365 return false;
366 mParent->SetSizerAndFit(vs.release());
367 }
368
369 mUIIdleInterface = static_cast<const LV2UI_Idle_Interface *>(
370 suil_instance_extension_data(mUI.mSuilInstance.get(), LV2_UI__idleInterface));
371
372 mUIShowInterface = static_cast<const LV2UI_Show_Interface *>(
373 suil_instance_extension_data(mUI.mSuilInstance.get(), LV2_UI__showInterface));
374
375// if (mUIShowInterface && mUIShowInterface->show) {
376// mUIShowInterface->show(suil_instance_get_handle(mSuilInstance));
377// }
378
379#ifdef __WXMAC__
380#ifdef __WX_EVTLOOP_BUSY_WAITING__
381 wxEventLoop::SetBusyWaiting(true);
382#endif
383#endif
384
385 return true;
386}
std::unique_ptr< Type, Lilv_deleter< Type, f > > Lilv_ptr
Generate classes of smart pointers to lv2 resources.
Definition: LV2Utils.h:26
Lilv_ptr< LilvNode, lilv_node_free > LilvNodePtr
Definition: LV2Utils.h:33
Lilv_ptr< char, free_chars > LilvCharsPtr
Definition: LV2Utils.h:29
#define safenew
Definition: MemoryX.h:10
void OnSize(wxSizeEvent &evt)
const LV2UI_Idle_Interface * mUIIdleInterface
Definition: LV2Validator.h:158
std::shared_ptr< SuilHost > mSuilHost
Definition: LV2Validator.h:111
wxSize mNativeWinInitialSize
Definition: LV2Validator.h:142
struct LV2Validator::UI mUI
static std::shared_ptr< SuilHost > GetSuilHost()
LV2Validator::Timer mTimer
wxSize mNativeWinLastSize
Definition: LV2Validator.h:143
std::optional< const LV2UIFeaturesList > mUIFeatures
Definition: LV2Validator.h:108
const LV2UI_Show_Interface * mUIShowInterface
Definition: LV2Validator.h:159
static void size_request(GtkWidget *widget, GtkRequisition *requisition, LV2Validator *pValidator)
std::unique_ptr< LV2Wrapper > mpWrapper
Definition: LV2Validator.h:107
#define LV2_EXTERNAL_UI_SHOW(ptr)
#define LV2_EXTERNAL_UI__Widget
LilvWorld * gWorld
Definition: LV2Symbols.cpp:31
Abstraction of host services that a plug-ins native UI needs.
LV2_External_UI_Widget * mExternalWidget
Definition: LV2Validator.h:154
wxWindowPtr< NativeWindow > mNativeWin
Definition: LV2Validator.h:136
SuilInstancePtr mSuilInstance
Definition: LV2Validator.h:135

References GetSuilHost(), LV2Symbols::gWorld, cloud::audiocom::anonymous_namespace{AuthorizationHandler.cpp}::handler, LV2_EXTERNAL_UI__Widget, LV2_EXTERNAL_UI_SHOW, LV2Validator::Timer::mExternalWidget, LV2Validator::UI::mNativeWin, mNativeWinInitialSize, mNativeWinLastSize, mParent, mPlug, mpWrapper, mSuilHost, LV2Validator::UI::mSuilInstance, mTimer, mUI, mUIFeatures, mUIIdleInterface, mUIShowInterface, OnSize(), safenew, and size_request().

Here is the call graph for this function:

◆ BuildPlain()

bool LV2Validator::BuildPlain ( EffectSettingsAccess access)

Captures a const reference to value!

Function to revisit the controls just added above

Definition at line 388 of file LV2Validator.cpp.

389{
390 auto &portUIStates = mPortUIStates;
391 auto &settings = access.Get();
394
395 int numCols = 5;
396 wxSizer *innerSizer;
397
398 assert(mParent); // To justify safenew
399 const auto w = safenew wxScrolledWindow(mParent,
400 wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL | wxTAB_TRAVERSAL);
401
402 {
403 auto outerSizer = std::make_unique<wxBoxSizer>(wxVERTICAL);
404 w->SetScrollRate(0, 20);
405 // This fools NVDA into not saying "Panel" when the dialog gets focus
406 w->SetName(wxT("\a"));
407 w->SetLabel(wxT("\a"));
408 outerSizer->Add(w, 1, wxEXPAND);
409
410 auto uInnerSizer = std::make_unique<wxBoxSizer>(wxVERTICAL);
411 innerSizer = uInnerSizer.get();
412
413 // Add the duration control, if a generator
414 if (mType == EffectTypeGenerate) {
415 auto sizer = std::make_unique<wxBoxSizer>(wxHORIZONTAL);
416 auto item = safenew wxStaticText(w, 0, _("&Duration:"));
417 sizer->Add(item, 0, wxALIGN_CENTER | wxALL, 5);
418 auto &extra = settings.extra;
420 NumericConverter::TIME, extra.GetDurationFormat(),
421 extra.GetDuration(), mSampleRate,
423 mDuration->SetName( XO("Duration") );
424 sizer->Add(mDuration, 0, wxALIGN_CENTER | wxALL, 5);
425 auto groupSizer =
426 std::make_unique<wxStaticBoxSizer>(wxVERTICAL, w, _("Generator"));
427 groupSizer->Add(sizer.release(), 0, wxALIGN_CENTER | wxALL, 5);
428 innerSizer->Add(groupSizer.release(), 0, wxEXPAND | wxALL, 5);
429 }
430
431 // Make other controls, grouped into static boxes that are named
432 // according to certain control port metadata
433 auto groups = mPorts.mGroups; // mutable copy
434 std::sort(groups.begin(), groups.end(), TranslationLess);
435 for (auto &label: groups) {
436 auto gridSizer = std::make_unique<wxFlexGridSizer>(numCols, 5, 5);
437 gridSizer->AddGrowableCol(3);
438 for (auto & p : mPorts.mGroupMap.at(label)) /* won't throw */ {
439 auto &state = portUIStates.mControlPortStates[p];
440 auto &port = state.mpPort;
441 auto &ctrl = mPlainUIControls[p];
442 const auto &value = values[p];
443 auto labelText = port->mName;
444 if (!port->mUnits.empty())
445 labelText += XO("(%s)").Format(port->mUnits).Translation();
446
447 // A "trigger" port gets a row with just a pushbutton
448 if (port->mTrigger) {
449 gridSizer->Add(1, 1, 0);
450
451 assert(w); // To justify safenew
452 auto b = safenew wxButton(w, ID_Triggers + p, labelText);
453 gridSizer->Add(b, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
454 ctrl.button = b;
455
456 gridSizer->Add(1, 1, 0);
457 gridSizer->Add(1, 1, 0);
458 gridSizer->Add(1, 1, 0);
459 continue;
460 }
461
462 // Any other kind of port gets a name text...
463 auto item = safenew wxStaticText(w, wxID_ANY, labelText + wxT(":"),
464 wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
465 gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT);
466
467 // ... then appropriate controls and static texts in other columns
468 if (port->mToggle) {
469 // Toggle port gets a checkbox
470 auto c = safenew wxCheckBox(w, ID_Toggles + p, wxT(""));
471 c->SetName(labelText);
472 c->SetValue(value > 0);
473 gridSizer->Add(c, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
474 ctrl.checkbox = c;
475
476 gridSizer->Add(1, 1, 0);
477 gridSizer->Add(1, 1, 0);
478 gridSizer->Add(1, 1, 0);
479 }
480 else if (port->mEnumeration) {
481 // Enumeration port gets a choice control
482 // Discretize the value (all ports hold a float value) to
483 // determine the intial selection
484 auto s = port->Discretize(value);
485 auto c = safenew wxChoice(w, ID_Choices + p);
486 c->SetName(labelText);
487 c->Append(port->mScaleLabels);
488 c->SetSelection(s);
489 gridSizer->Add(c, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
490 ctrl.choice = c;
491
492 gridSizer->Add(1, 1, 0);
493 gridSizer->Add(1, 1, 0);
494 gridSizer->Add(1, 1, 0);
495 }
496 else if (!port->mIsInput) {
497 // Real-valued output gets a meter control
498 gridSizer->Add(1, 1, 0);
499 gridSizer->Add(1, 1, 0);
500
501 static float sink;
502 const auto pOutputValues =
503 static_cast<const LV2EffectOutputs*>(mpOutputs);
504 const auto pValue =
505 pOutputValues ? &pOutputValues->values[p] : &sink;
507 auto m = safenew LV2EffectMeter(w, port, *pValue);
508 gridSizer->Add(m, 0, wxALIGN_CENTER_VERTICAL | wxEXPAND);
509 ctrl.meter = m;
510
511 gridSizer->Add(1, 1, 0);
512 }
513 else {
514 // Numerical input gets a text input, with a validator...
515 auto t = safenew wxTextCtrl(w, ID_Texts + p, wxT(""));
516 t->SetName(labelText);
517 gridSizer->Add(t, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
518 ctrl.mText = t;
519 auto rate = port->mSampleRate ? mSampleRate : 1.0f;
520 state.mLo = port->mMin * rate;
521 state.mHi = port->mMax * rate;
522 state.mTmp = value * rate;
523 if (port->mInteger) {
524 IntegerValidator<float> vld(&state.mTmp);
525 vld.SetRange(state.mLo, state.mHi);
526 t->SetValidator(vld);
527 }
528 else {
529 FloatingPointValidator<float> vld(6, &state.mTmp);
530 vld.SetRange(state.mLo, state.mHi);
531
532 // Set number of decimal places
533 float range = state.mHi - state.mLo;
534 auto style = range < 10
535 ? NumValidatorStyle::THREE_TRAILING_ZEROES
536 : range < 100
537 ? NumValidatorStyle::TWO_TRAILING_ZEROES
538 : NumValidatorStyle::ONE_TRAILING_ZERO;
539 vld.SetStyle(style);
540 t->SetValidator(vld);
541 }
542
543 // ... optional lower-bound static text ...
544 if (port->mHasLo) {
545 wxString str;
546 if (port->mInteger || port->mSampleRate)
547 str.Printf(wxT("%d"), (int) lrintf(state.mLo));
548 else
549 str = Internat::ToDisplayString(state.mLo);
550 item = safenew wxStaticText(w, wxID_ANY, str);
551 gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT);
552 }
553 else
554 gridSizer->Add(1, 1, 0);
555
556 // ... a slider ...
557 auto s = safenew wxSliderWrapper(w, ID_Sliders + p,
558 0, 0, 1000, wxDefaultPosition, { 150, -1 });
559 s->SetName(labelText);
560 gridSizer->Add(s, 0, wxALIGN_CENTER_VERTICAL | wxEXPAND);
561 ctrl.slider = s;
562
563 // ... and optional upper-bound static text
564 if (port->mHasHi) {
565 wxString str;
566 if (port->mInteger || port->mSampleRate)
567 str.Printf(wxT("%d"), (int) lrintf(state.mHi));
568 else
569 str = Internat::ToDisplayString(state.mHi);
570 item = safenew wxStaticText(w, wxID_ANY, str);
571 gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
572 }
573 else
574 gridSizer->Add(1, 1, 0);
575 }
576 }
577
578 auto groupSizer = std::make_unique<wxStaticBoxSizer>(
579 wxVERTICAL, w, label.Translation());
580 groupSizer->Add(gridSizer.release(), 1, wxEXPAND | wxALL, 5);
581 innerSizer->Add(groupSizer.release(), 0, wxEXPAND | wxALL, 5);
582 }
583
584 innerSizer->Layout();
585
587 auto VisitCells = [&, cnt = innerSizer->GetChildren().GetCount()](auto f){
588 for (size_t i = (mType == EffectTypeGenerate); i < cnt; ++i) {
589 // For each group (skipping duration) visit the grid sizer
590 auto groupSizer = innerSizer->GetItem(i)->GetSizer();
591 auto gridSizer = static_cast<wxFlexGridSizer *>(
592 groupSizer->GetItem(size_t{0})->GetSizer());
593 auto items = gridSizer->GetChildren().GetCount();
594 size_t cols = gridSizer->GetCols();
595 for (size_t j = 0; j < items; ++j) {
596 // For each grid item
597 auto item = gridSizer->GetItem(j);
598 f(item, j, cols);
599 }
600 }
601 };
602
603 // Calculate the maximum width of all columns (bypass Generator sizer)
604 std::vector<int> widths(numCols);
605 VisitCells([&](wxSizerItem *item, size_t j, size_t cols){
606 auto &width = widths[j % cols];
607 width = std::max(width, item->GetSize().GetWidth());
608 });
609
610 // Set each column in all of the groups to the same width.
611 VisitCells([&](wxSizerItem *item, size_t j, size_t cols){
612 int flags = item->GetFlag();
613 if (flags & wxEXPAND)
614 return;
615 if (flags & wxALIGN_RIGHT)
616 flags = (flags & ~wxALL) | wxLEFT;
617 else
618 flags = (flags & ~wxALL) | wxRIGHT;
619 item->SetFlag(flags);
620 item->SetBorder(widths[j % cols] - item->GetMinSize().GetWidth());
621 });
622
623 w->SetSizer(uInnerSizer.release());
624
625 mParent->SetSizer(outerSizer.release());
626 } // scope of unique_ptrs of sizers
627
628 // Try to give the window a sensible default/minimum size
629 wxSize sz1 = innerSizer->GetMinSize();
630 wxSize sz2 = mParent->GetMinSize();
631 w->SetMinSize( { -1, std::min(sz1.y, sz2.y) } );
632
633 // And let the parent reduce to the NEW minimum if possible
634 mParent->SetMinSize(w->GetMinSize());
635
636 return true;
637}
wxT("CloseDown"))
int min(int a, int b)
#define str(a)
@ EffectTypeGenerate
const wxChar * values
XO("Cut/Copy/Paste")
#define _(s)
Definition: Internat.h:75
LV2EffectSettings & GetSettings(EffectSettings &settings)
Definition: LV2Ports.h:215
@ ID_Triggers
@ ID_Texts
@ ID_Duration
@ ID_Choices
@ ID_Sliders
@ ID_Toggles
TranslatableString label
Definition: TagsEditor.cpp:164
static Settings & settings()
Definition: TrackInfo.cpp:87
bool TranslationLess(const TranslatableString &a, const TranslatableString &b)
A commonly needed sort comparator, which depends on the language setting.
virtual const EffectSettings & Get()=0
static wxString ToDisplayString(double numberToConvert, int digitsAfterDecimalPoint=-1)
Convert a number to a string, uses the user's locale's decimal separator.
Definition: Internat.cpp:161
UI widget that watches a floating point location and then updates a bar.
std::unordered_map< TranslatableString, std::vector< int > > mGroupMap
Definition: LV2Ports.h:285
TranslatableStrings mGroups
Definition: LV2Ports.h:284
LV2ControlPortArray mControlPorts
Definition: LV2Ports.h:283
NumericTextCtrl * mDuration
Definition: LV2Validator.h:160
std::vector< PlainUIControl > mPlainUIControls
Array in correspondence with the control ports.
Definition: LV2Validator.h:128
void SetName(const TranslatableString &name)
wxString Translation() const
#define lrintf(flt)
Definition: float_cast.h:170
Carry output control port information back to main thread.
Definition: LV2Ports.h:228
std::vector< float > values
vector of values in correspondence with the control ports
Definition: LV2Ports.h:233
std::vector< float > values
vector of values in correspondence with the control ports
Definition: LV2Ports.h:208
Options & AutoPos(bool enable)

References _, NumericTextCtrl::Options::AutoPos(), EffectTypeGenerate, EffectSettingsAccess::Get(), GetSettings(), ID_Choices, ID_Duration, ID_Sliders, ID_Texts, ID_Toggles, ID_Triggers, label, lrintf, LV2Ports::mControlPorts, mDuration, LV2Ports::mGroupMap, LV2Ports::mGroups, min(), mParent, mPlainUIControls, mPorts, mPortUIStates, mpOutputs, mSampleRate, mType, safenew, NumericTextCtrl::SetName(), settings(), str, NumericConverter::TIME, Internat::ToDisplayString(), TranslatableString::Translation(), TranslationLess(), values, LV2EffectSettings::values, LV2EffectOutputs::values, wxT(), and XO().

Here is the call graph for this function:

◆ Disconnect()

void LV2Validator::Disconnect ( )
overridevirtual

On the first call only, may disconnect from further event handling.

Default implemantation does nothing

Reimplemented from EffectUIValidator.

Definition at line 158 of file LV2Validator.cpp.

159{
160 // Disconnect the plain UI output meters
161 if (!mPlainUIControls.empty()) {
162 size_t p = 0;
163 for (auto &port : mPorts.mControlPorts) {
164 if (!port->mIsInput)
165 if (auto &pMeter = mPlainUIControls[p].meter) {
166 pMeter->Disconnect();
167 pMeter = nullptr;
168 }
169 ++p;
170 }
171 }
172 // The idle event handler for the fancy UI output must disconnect too
173 mpOutputs = nullptr;
174 if (mParent) {
175 mParent->PopEventHandler();
176 mParent = nullptr;
177 }
178 mUI.Destroy();
179}

References LV2Validator::UI::Destroy(), LV2Ports::mControlPorts, mParent, mPlainUIControls, mPorts, mpOutputs, and mUI.

Referenced by ~LV2Validator().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetSuilHost()

std::shared_ptr< SuilHost > LV2Validator::GetSuilHost ( )
static

Definition at line 186 of file LV2Validator.cpp.

187{
188 // This is a unique_ptr specialization
189 using SuilHostPtr = Lilv_ptr<SuilHost, suil_host_free>;
190 // The host has no dependency on the plug-in and can be shared among
191 // validators
192 static std::weak_ptr<SuilHost> sSuilHost;
193 std::shared_ptr<SuilHost> result = sSuilHost.lock();
194 if (!result)
195 // shared_ptr erases type of custom deleter of SuilHostPtr
196 sSuilHost = result = SuilHostPtr{ suil_host_new(
198 LV2UIFeaturesList::suil_port_index, nullptr, nullptr) };
199 return result;
200}
static uint32_t suil_port_index(SuilController controller, const char *port_symbol)
static void suil_port_write(SuilController controller, uint32_t port_index, uint32_t buffer_size, uint32_t protocol, const void *buffer)

References LV2UIFeaturesList::suil_port_index(), and LV2UIFeaturesList::suil_port_write().

Referenced by BuildFancy().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ IsGraphicalUI()

bool LV2Validator::IsGraphicalUI ( )
overridevirtual

Default implementation returns false

Returns
true if using a native plug-in UI, not widgets

Reimplemented from EffectUIValidator.

Definition at line 143 of file LV2Validator.cpp.

144{
145 return mUseGUI;
146}

◆ OnChoice()

void LV2Validator::OnChoice ( wxCommandEvent &  evt)

Definition at line 760 of file LV2Validator.cpp.

761{
762 size_t idx = evt.GetId() - ID_Choices;
763 auto & port = mPorts.mControlPorts[idx];
766 GetSettings(settings), idx, port->mScaleValues[evt.GetInt()]);
767 return nullptr;
768 });
769}
void ModifySettings(Function &&function)
Do a correct read-modify-write of settings.
EffectSettingsAccess & mAccess
Definition: EffectPlugin.h:297
void UpdateControlPortValue(LV2EffectSettings &settings, size_t controlPortIndex, float value)
Externalized state of a plug-in.

References GetSettings(), ID_Choices, EffectUIValidator::mAccess, LV2Ports::mControlPorts, EffectSettingsAccess::ModifySettings(), mPorts, settings(), and UpdateControlPortValue().

Here is the call graph for this function:

◆ OnIdle()

void LV2Validator::OnIdle ( wxIdleEvent &  evt)

Definition at line 817 of file LV2Validator.cpp.

818{
819 evt.Skip();
820 if (!mUI.mSuilInstance)
821 return;
822
823 if (mExternalUIClosed) {
824 mExternalUIClosed = false;
825 if (mDialog)
826 mDialog->Close();
827 return;
828 }
829
830 if (mUIIdleInterface) {
831 const auto handle = suil_instance_get_handle(mUI.mSuilInstance.get());
832 if (mUIIdleInterface->idle && mUIIdleInterface->idle(handle)) {
834 mUIShowInterface->hide(handle);
835 if (mDialog)
836 mDialog->Close();
837 return;
838 }
839 }
840
841 auto &portUIStates = mPortUIStates;
842
843 if (auto &atomState = portUIStates.mControlOut) {
844 atomState->SendToDialog([&](const LV2_Atom *atom, uint32_t size){
845 suil_instance_port_event(mUI.mSuilInstance.get(),
846 atomState->mpPort->mIndex, size,
847 // Means this event sends some structured data:
848 LV2Symbols::urid_EventTransfer, atom);
849 });
850 }
851
852 // Is this idle time polling for changes of input redundant with
853 // TransferDataToWindow or is it really needed? Probably harmless.
854 // In case of output control port values though, it is needed for metering.
855 mAccess.Flush();
857 auto pOutputValues = static_cast<const LV2EffectOutputs *>(mpOutputs);
858
859 size_t index = 0; for (auto &state : portUIStates.mControlPortStates) {
860 auto &port = state.mpPort;
861
862 const auto pValue = port->mIsInput
863 ? &values[index]
864 : pOutputValues ? &pOutputValues->values[index]
865 : nullptr;
866 if (pValue) {
867 auto &value = *pValue;
868 // Let UI know that a port's value has changed
869 if (value != state.mLst) {
870 suil_instance_port_event(mUI.mSuilInstance.get(),
871 port->mIndex, sizeof(value),
872 /* Means this event sends a float: */ 0,
873/*
874 Quoting what suil.h says about the next argument (which is good):
875
876 The `buffer` must be valid only for the duration of this call, the UI must
877 not keep a reference to it.
878 */
879 &value);
880 state.mLst = value;
881 }
882 }
883 ++index;
884 }
885}
virtual void Flush()=0
Make the last Set changes "persistent" in underlying storage.
wxWeakRef< wxDialog > mDialog
Definition: LV2Validator.h:149
bool mExternalUIClosed
Definition: LV2Validator.h:150

References EffectSettingsAccess::Flush(), EffectSettingsAccess::Get(), GetSettings(), EffectUIValidator::mAccess, mDialog, mExternalUIClosed, mPortUIStates, mpOutputs, LV2Validator::UI::mSuilInstance, mUI, mUIIdleInterface, mUIShowInterface, size, values, and LV2EffectSettings::values.

Here is the call graph for this function:

◆ OnSize()

void LV2Validator::OnSize ( wxSizeEvent &  evt)

Definition at line 887 of file LV2Validator.cpp.

888{
889 evt.Skip();
890
891 // Don't do anything here if we're recursing
892 if (mResizing)
893 return;
894
895 // Indicate resizing is occurring
896 mResizing = true;
897
898 // Can only resize AFTER the dialog has been completely created and
899 // there's no need to resize if we're already at the desired size.
900 if (mDialog && evt.GetSize() != mNativeWinLastSize) {
901 // Save the desired size and set the native window to match
902 mNativeWinLastSize = evt.GetSize();
903 mUI.mNativeWin->SetMinSize(mNativeWinLastSize);
904
905 // Clear the minimum size of the parent window to allow the following
906 // Fit() to make proper adjustments
907 mParent->SetMinSize(wxDefaultSize);
908
909#if defined(__WXGTK__)
910 // If the user resized the native window, then we need to also
911 // clear the dialogs minimum size. If this isn't done, the dialog
912 // will not resize properly when going from a larger size to a smaller
913 // size (due to the minimum size constraint).
914 //
915 // In this case, mResized has been set by the "size_request()" function
916 // to indicate that this is a plugin generated resize request.
917 if (mResized)
918 mDialog->SetMinSize(wxDefaultSize);
919
920 // Resize dialog
921 mDialog->Fit();
922
923 // Reestablish the minimum (and maximum) now that the dialog
924 // has is desired size.
925 if (mResized) {
926 mDialog->SetMinSize(mDialog->GetSize());
927 if (mUIFeatures && mUIFeatures->mNoResize)
928 mDialog->SetMaxSize(mDialog->GetSize());
929 }
930
931 // Tell size_request() that the native window was just resized.
932 mResized = true;
933#else
934 // Resize the dialog to fit its content.
935 mDialog->Fit();
936#endif
937 }
938
939 // No longer resizing
940 mResizing = false;
941}

References mDialog, LV2Validator::UI::mNativeWin, mNativeWinLastSize, mParent, mResized, mResizing, mUI, and mUIFeatures.

Referenced by BuildFancy().

Here is the caller graph for this function:

◆ OnSlider()

void LV2Validator::OnSlider ( wxCommandEvent &  evt)

Definition at line 788 of file LV2Validator.cpp.

789{
790 size_t idx = evt.GetId() - ID_Sliders;
791 auto &state = mPortUIStates.mControlPortStates[idx];
792 auto &port = state.mpPort;
793 float lo = state.mLo;
794 float hi = state.mHi;
795 if (port->mLogarithmic) {
796 lo = logf(lo);
797 hi = logf(hi);
798 }
799 state.mTmp = (((float) evt.GetInt()) / 1000.0) * (hi - lo) + lo;
800 state.mTmp = std::clamp(state.mTmp, lo, hi);
801 state.mTmp = port->mLogarithmic ? expf(state.mTmp) : state.mTmp;
804 GetSettings(settings), idx,
805 port->mSampleRate ? state.mTmp / mSampleRate : state.mTmp);
806 return nullptr;
807 });
808 mPlainUIControls[idx].mText->GetValidator()->TransferToWindow();
809}
LV2ControlPortStateArray mControlPortStates
Definition: LV2Ports.h:304

References GetSettings(), ID_Sliders, EffectUIValidator::mAccess, LV2PortUIStates::mControlPortStates, EffectSettingsAccess::ModifySettings(), mPlainUIControls, mPortUIStates, mSampleRate, settings(), and UpdateControlPortValue().

Here is the call graph for this function:

◆ OnText()

void LV2Validator::OnText ( wxCommandEvent &  evt)

Definition at line 771 of file LV2Validator.cpp.

772{
773 size_t idx = evt.GetId() - ID_Texts;
774 auto &state = mPortUIStates.mControlPortStates[idx];
775 auto &port = state.mpPort;
776 auto &ctrl = mPlainUIControls[idx];
777 if (ctrl.mText->GetValidator()->TransferFromWindow()) {
780 GetSettings(settings), idx,
781 port->mSampleRate ? state.mTmp / mSampleRate : state.mTmp);
782 return nullptr;
783 });
784 SetSlider(state, ctrl);
785 }
786}
void SetSlider(const LV2ControlPortState &state, const PlainUIControl &ctrl)

References GetSettings(), ID_Texts, EffectUIValidator::mAccess, LV2PortUIStates::mControlPortStates, EffectSettingsAccess::ModifySettings(), mPlainUIControls, mPortUIStates, mSampleRate, SetSlider(), settings(), and UpdateControlPortValue().

Here is the call graph for this function:

◆ OnToggle()

void LV2Validator::OnToggle ( wxCommandEvent &  evt)

Definition at line 750 of file LV2Validator.cpp.

751{
752 size_t idx = evt.GetId() - ID_Toggles;
755 GetSettings(settings), idx, evt.GetInt() ? 1.0 : 0.0);
756 return nullptr;
757 });
758}

References GetSettings(), ID_Toggles, EffectUIValidator::mAccess, EffectSettingsAccess::ModifySettings(), settings(), and UpdateControlPortValue().

Here is the call graph for this function:

◆ OnTrigger()

void LV2Validator::OnTrigger ( wxCommandEvent &  evt)

Definition at line 740 of file LV2Validator.cpp.

741{
742 size_t idx = evt.GetId() - ID_Triggers;
743 auto & port = mPorts.mControlPorts[idx];
746 return nullptr;
747 });
748}

References GetSettings(), ID_Triggers, EffectUIValidator::mAccess, LV2Ports::mControlPorts, EffectSettingsAccess::ModifySettings(), mPorts, settings(), and UpdateControlPortValue().

Here is the call graph for this function:

◆ SetSlider()

void LV2Validator::SetSlider ( const LV2ControlPortState state,
const PlainUIControl ctrl 
)

Definition at line 706 of file LV2Validator.cpp.

708{
709 float lo = state.mLo;
710 float hi = state.mHi;
711 float val = state.mTmp;
712 if (state.mpPort->mLogarithmic) {
713 lo = logf(lo);
714 hi = logf(hi);
715 val = logf(val);
716 }
717 ctrl.slider->SetValue(lrintf((val - lo) / (hi - lo) * 1000.0));
718}
float mLo
Lower bound, as scaled by sample rate if that is required.
Definition: LV2Ports.h:250
float mHi
Upper bound, as scaled by sample rate if that is required.
Definition: LV2Ports.h:252
float mTmp
Value of UI control, as scaled by sample rate if that is required.
Definition: LV2Ports.h:248
const LV2ControlPortPtr mpPort
Definition: LV2Ports.h:244

References lrintf, LV2ControlPortState::mHi, LV2ControlPortState::mLo, LV2ControlPortState::mpPort, LV2ControlPortState::mTmp, and LV2Validator::PlainUIControl::slider.

Referenced by OnText(), and UpdateUI().

Here is the caller graph for this function:

◆ size_request()

void LV2Validator::size_request ( GtkWidget *  widget,
GtkRequisition *  requisition,
LV2Validator pValidator 
)
static

Definition at line 1013 of file LV2Validator.cpp.

1015{
1016 pValidator->SizeRequest(widget, requisition);
1017}
void SizeRequest(GtkWidget *widget, GtkRequisition *requisition)

References SizeRequest().

Referenced by BuildFancy().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SizeRequest()

void LV2Validator::SizeRequest ( GtkWidget *  widget,
GtkRequisition *  requisition 
)

Definition at line 1019 of file LV2Validator.cpp.

1020{
1021 // Don't do anything if the OnSize() method is active
1022 if (!mResizing) {
1023 // If the OnSize() routine has processed an event, mResized will be true,
1024 // so just set the widgets size.
1025 if (mResized) {
1026 gtk_widget_set_size_request(widget,
1028 mResized = false;
1029 }
1030 // Otherwise, the plugin has resized the widget and we need to let WX know
1031 // about it.
1032 else if (mUI.mNativeWin) {
1033 mResized = true;
1034 wxSizeEvent se(wxSize(requisition->width, requisition->height));
1035 se.SetEventObject(mUI.mNativeWin.get());
1036 mUI.mNativeWin->GetEventHandler()->AddPendingEvent(se);
1037 }
1038 }
1039}

References LV2Validator::UI::mNativeWin, mNativeWinLastSize, mResized, mResizing, and mUI.

Referenced by size_request().

Here is the caller graph for this function:

◆ suil_port_index()

uint32_t LV2Validator::suil_port_index ( const char *  port_symbol)
overridevirtual

Implements LV2UIFeaturesList::UIHandler.

Definition at line 996 of file LV2Validator.cpp.

997{
998 for (size_t i = 0, cnt = lilv_plugin_get_num_ports(&mPlug); i < cnt; ++i) {
999 const auto port = lilv_plugin_get_port_by_index(&mPlug, i);
1000 if (strcmp(port_symbol,
1001 lilv_node_as_string(lilv_port_get_symbol(&mPlug, port))) == 0)
1002 return lilv_port_get_index(&mPlug, port);
1003 }
1004 return LV2UI_INVALID_PORT_INDEX;
1005}

References mPlug.

◆ suil_port_write()

void LV2Validator::suil_port_write ( uint32_t  port_index,
uint32_t  buffer_size,
uint32_t  protocol,
const void *  buffer 
)
overridevirtual

Implements LV2UIFeaturesList::UIHandler.

Definition at line 967 of file LV2Validator.cpp.

969{
970 // Handle implicit floats
971 if (protocol == 0 && buffer_size == sizeof(float)) {
972 if (auto it = mPorts.mControlPortMap.find(port_index);
973 it != mPorts.mControlPortMap.end())
974 {
975 const auto value = *static_cast<const float*>(buffer);
978 {
979 GetSettings(settings).values[it->second] = value;
980 return nullptr;
981 });
982
983
984 Publish({ size_t(port_index), value });
985 }
986 }
987 // Handle event transfers
988 else if (protocol == LV2Symbols::urid_EventTransfer) {
989 auto &portUIStates = mPortUIStates;
990 auto &atomPortState = portUIStates.mControlIn;
991 if (atomPortState && port_index == atomPortState->mpPort->mIndex)
992 atomPortState->ReceiveFromDialog(buffer, buffer_size);
993 }
994}
LV2AtomPortStatePtr mControlIn
Definition: LV2Ports.h:302
std::unordered_map< uint32_t, size_t > mControlPortMap
Definition: LV2Ports.h:288
CallbackReturn Publish(const EffectSettingChanged &message)
Send a message to connected callbacks.
Definition: Observer.h:207

References GetSettings(), EffectUIValidator::mAccess, LV2PortUIStates::mControlIn, LV2Ports::mControlPortMap, EffectSettingsAccess::ModifySettings(), mPorts, mPortUIStates, Observer::Publisher< EffectSettingChanged >::Publish(), settings(), and LV2EffectSettings::values.

Here is the call graph for this function:

◆ ui_closed()

void LV2Validator::ui_closed ( )
overridevirtual

Implements LV2UIFeaturesList::UIHandler.

Definition at line 961 of file LV2Validator.cpp.

962{
963 mExternalUIClosed = true;
964}

References mExternalUIClosed.

◆ ui_resize()

int LV2Validator::ui_resize ( int  width,
int  height 
)
overridevirtual

Implements LV2UIFeaturesList::UIHandler.

Definition at line 947 of file LV2Validator.cpp.

948{
949 // Queue a wxSizeEvent to resize the plugins UI
950 if (mUI.mNativeWin) {
951 wxSizeEvent sw{ wxSize{ width, height } };
952 sw.SetEventObject(mUI.mNativeWin.get());
953 mUI.mNativeWin->GetEventHandler()->AddPendingEvent(sw);
954 }
955 else
956 // The window hasn't been created yet, so record the desired size
957 mNativeWinInitialSize = { width, height };
958 return 0;
959}

References LV2Validator::UI::mNativeWin, mNativeWinInitialSize, and mUI.

◆ UpdateControlPortValue()

void LV2Validator::UpdateControlPortValue ( LV2EffectSettings settings,
size_t  controlPortIndex,
float  value 
)

Definition at line 720 of file LV2Validator.cpp.

722{
723 const auto currentValue = settings.values[controlPortIndex];
724
725 // LV2 implementation allows to edit the values
726 // using text boxes too. Provide sufficiently small epsilon
727 // to distinguish between the values.
728 // (for example, conversion from the text representation
729 // is always lossy, so direct comparison of the values
730 // is not possible, nor should it be used for float values)
731 const auto epsilon = 1e-5f;
732
733 if (std::abs(currentValue - value) < epsilon)
734 return;
735
736 settings.values[controlPortIndex] = value;
737 Publish({ mPorts.mControlPorts[controlPortIndex]->mIndex, value });
738}

References LV2Ports::mControlPorts, mPorts, Observer::Publisher< EffectSettingChanged >::Publish(), and settings().

Referenced by OnChoice(), OnSlider(), OnText(), OnToggle(), and OnTrigger().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ UpdateUI()

bool LV2Validator::UpdateUI ( )
overridevirtual

Update appearance of the panel for changes in settings.

Default implementation does nothing, returns true

Returns
true if successful

Reimplemented from EffectUIValidator.

Definition at line 639 of file LV2Validator.cpp.

640{
641 const auto &mySettings = GetSettings(mAccess.Get());
642 auto pMaster = mInstance.GetMaster();
643
644 if (pMaster && mySettings.mpState) {
645 // Maybe there are other important side effects on the instance besides
646 // changes of port values
647 lilv_state_restore(mySettings.mpState.get(), &pMaster->GetInstance(),
648 nullptr, nullptr, 0, nullptr);
649 // Destroy the short lived carrier of preset state
650 mySettings.mpState.reset();
651 }
652
653 auto &values = mySettings.values;
654 {
655 size_t index = 0; for (auto & state : mPortUIStates.mControlPortStates) {
656 auto &port = state.mpPort;
657 if (port->mIsInput)
658 state.mTmp =
659 values[index] * (port->mSampleRate ? mSampleRate : 1.0);
660 ++index;
661 }
662 }
663
664 if (mUseGUI) {
665 // fancy UI
666 if (mUI.mSuilInstance) {
667 size_t index = 0;
668 for (auto & port : mPorts.mControlPorts) {
669 if (port->mIsInput)
670 suil_instance_port_event(mUI.mSuilInstance.get(),
671 port->mIndex, sizeof(float),
672 /* Means this event sends a float: */ 0,
673 &values[index]);
674 ++index;
675 }
676 }
677 return true;
678 }
679
680 // else plain UI
681 // Visiting controls by groups
682 for (auto & group : mPorts.mGroups) {
683 const auto & params = mPorts.mGroupMap.at(group); /* won't throw */
684 for (auto & param : params) {
685 auto &state = mPortUIStates.mControlPortStates[param];
686 auto &port = state.mpPort;
687 auto &ctrl = mPlainUIControls[param];
688 auto &value = values[param];
689 if (port->mTrigger)
690 continue;
691 else if (port->mToggle)
692 ctrl.checkbox->SetValue(value > 0);
693 else if (port->mEnumeration) // Check before integer
694 ctrl.choice->SetSelection(port->Discretize(value));
695 else if (port->mIsInput) {
696 state.mTmp = value * (port->mSampleRate ? mSampleRate : 1.0f);
697 SetSlider(state, ctrl);
698 }
699 }
700 }
701 if (mParent && !mParent->TransferDataToWindow())
702 return false;
703 return true;
704}
EffectDistortionSettings params
Definition: Distortion.cpp:75
const LV2Wrapper * GetMaster() const
Definition: LV2Instance.h:46

References EffectSettingsAccess::Get(), LV2Instance::GetMaster(), GetSettings(), EffectUIValidator::mAccess, LV2Ports::mControlPorts, LV2PortUIStates::mControlPortStates, LV2Ports::mGroupMap, LV2Ports::mGroups, mInstance, mParent, mPlainUIControls, mPorts, mPortUIStates, mSampleRate, LV2Validator::UI::mSuilInstance, mUI, mUseGUI, params, SetSlider(), and values.

Here is the call graph for this function:

◆ ValidateUI()

bool LV2Validator::ValidateUI ( )
overridevirtual

Get settings data from the panel; may make error dialogs and return false.

Returns
true only if panel settings are acceptable

Implements EffectUIValidator.

Definition at line 148 of file LV2Validator.cpp.

149{
152 settings.extra.SetDuration(mDuration->GetValue());
153 return nullptr;
154 });
155 return true;
156}

References EffectTypeGenerate, NumericConverter::GetValue(), EffectUIValidator::mAccess, mDuration, EffectSettingsAccess::ModifySettings(), mType, and settings().

Here is the call graph for this function:

Member Data Documentation

◆ mDialog

wxWeakRef<wxDialog> LV2Validator::mDialog

Definition at line 149 of file LV2Validator.h.

Referenced by OnIdle(), and OnSize().

◆ mDuration

NumericTextCtrl* LV2Validator::mDuration {}

Definition at line 160 of file LV2Validator.h.

Referenced by BuildPlain(), and ValidateUI().

◆ mExternalUIClosed

bool LV2Validator::mExternalUIClosed { false }

Definition at line 150 of file LV2Validator.h.

Referenced by OnIdle(), and ui_closed().

◆ mInstance

LV2Instance& LV2Validator::mInstance

Definition at line 103 of file LV2Validator.h.

Referenced by UpdateUI().

◆ mNativeWinInitialSize

wxSize LV2Validator::mNativeWinInitialSize { wxDefaultSize }

Definition at line 142 of file LV2Validator.h.

Referenced by BuildFancy(), and ui_resize().

◆ mNativeWinLastSize

wxSize LV2Validator::mNativeWinLastSize { wxDefaultSize }

Definition at line 143 of file LV2Validator.h.

Referenced by BuildFancy(), OnSize(), and SizeRequest().

◆ mParent

wxWindow* LV2Validator::mParent

Definition at line 112 of file LV2Validator.h.

Referenced by BuildFancy(), BuildPlain(), Disconnect(), LV2Validator(), OnSize(), and UpdateUI().

◆ mPlainUIControls

std::vector<PlainUIControl> LV2Validator::mPlainUIControls

Array in correspondence with the control ports.

Definition at line 128 of file LV2Validator.h.

Referenced by BuildPlain(), Disconnect(), OnSlider(), OnText(), and UpdateUI().

◆ mPlug

const LilvPlugin& LV2Validator::mPlug

Definition at line 101 of file LV2Validator.h.

Referenced by BuildFancy(), and suil_port_index().

◆ mPorts

const LV2Ports& LV2Validator::mPorts

◆ mPortUIStates

LV2PortUIStates LV2Validator::mPortUIStates

Definition at line 109 of file LV2Validator.h.

Referenced by BuildPlain(), OnIdle(), OnSlider(), OnText(), suil_port_write(), and UpdateUI().

◆ mpOutputs

const EffectOutputs* LV2Validator::mpOutputs {}

Definition at line 104 of file LV2Validator.h.

Referenced by BuildPlain(), Disconnect(), and OnIdle().

◆ mpWrapper

std::unique_ptr<LV2Wrapper> LV2Validator::mpWrapper

Definition at line 107 of file LV2Validator.h.

Referenced by BuildFancy().

◆ mResized

bool LV2Validator::mResized { false }

Definition at line 146 of file LV2Validator.h.

Referenced by OnSize(), and SizeRequest().

◆ mResizing

bool LV2Validator::mResizing { false }

Definition at line 144 of file LV2Validator.h.

Referenced by OnSize(), and SizeRequest().

◆ mSampleRate

const double LV2Validator::mSampleRate

Definition at line 105 of file LV2Validator.h.

Referenced by BuildPlain(), OnSlider(), OnText(), and UpdateUI().

◆ mSuilHost

std::shared_ptr<SuilHost> LV2Validator::mSuilHost

Definition at line 111 of file LV2Validator.h.

Referenced by BuildFancy().

◆ mTimer

LV2Validator::Timer LV2Validator::mTimer

Referenced by BuildFancy().

◆ mType

const EffectType LV2Validator::mType

Definition at line 102 of file LV2Validator.h.

Referenced by BuildPlain(), and ValidateUI().

◆ mUI

struct LV2Validator::UI LV2Validator::mUI

◆ mUIFeatures

std::optional<const LV2UIFeaturesList> LV2Validator::mUIFeatures

Definition at line 108 of file LV2Validator.h.

Referenced by BuildFancy(), and OnSize().

◆ mUIIdleInterface

const LV2UI_Idle_Interface* LV2Validator::mUIIdleInterface {}

Definition at line 158 of file LV2Validator.h.

Referenced by BuildFancy(), and OnIdle().

◆ mUIShowInterface

const LV2UI_Show_Interface* LV2Validator::mUIShowInterface {}

Definition at line 159 of file LV2Validator.h.

Referenced by BuildFancy(), and OnIdle().

◆ mUseGUI

bool LV2Validator::mUseGUI {}

Definition at line 113 of file LV2Validator.h.

Referenced by UpdateUI().


The documentation for this class was generated from the following files: