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

#include <LV2Editor.h>

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

Classes

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

Public Member Functions

 LV2Editor (const StatelessEffectUIServices &effect, EffectType type, const LilvPlugin &plug, LV2Instance &instance, EffectSettingsAccess &access, const EffectOutputs *pOutputs, double sampleRate, const LV2FeaturesList &features, const LV2Ports &ports, wxWindow *parent, bool useGUI)
 
 ~LV2Editor () 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 EffectEditor
 EffectEditor (const EffectUIServices &services, EffectSettingsAccess &access)
 
virtual ~EffectEditor ()
 
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, LV2Editor *pEditor)
 
static std::shared_ptr< SuilHost > GetSuilHost ()
 
- Static Public Member Functions inherited from EffectEditor
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 LV2Editor::UI mUI
 
wxSize mNativeWinInitialSize { wxDefaultSize }
 
wxSize mNativeWinLastSize { wxDefaultSize }
 
bool mResizing { false }
 
bool mResized { false }
 
wxWeakRef< wxDialog > mDialog
 
bool mExternalUIClosed { false }
 
LV2Editor::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 EffectEditor
static constexpr int kPlayID = 20102
 
- Static Public Attributes inherited from Observer::Publisher< EffectSettingChanged >
static constexpr bool notifies_all
 
- Protected Member Functions inherited from EffectEditor
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 EffectEditor
const EffectUIServicesmUIServices
 
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 52 of file LV2Editor.h.

Constructor & Destructor Documentation

◆ LV2Editor()

LV2Editor::LV2Editor ( const StatelessEffectUIServices effect,
EffectType  type,
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 103 of file LV2Editor.cpp.

109 : EffectEditor{ effect, access }
110 , mPlug{ plug }
111 , mType{ type }
112 , mInstance{ instance }
113 , mpOutputs{ pOutputs }
115 , mPorts{ ports }
116 , mPortUIStates{ instance.GetPortStates(), ports }
117 , mParent{ parent }
118 , mUseGUI{ useGUI }
119{
120 if (mParent)
121 mParent->PushEventHandler(this);
122}
const LV2Ports & mPorts
Definition: LV2Editor.h:108
const LilvPlugin & mPlug
Definition: LV2Editor.h:103
LV2PortUIStates mPortUIStates
Definition: LV2Editor.h:111
const double mSampleRate
Definition: LV2Editor.h:107
LV2Instance & mInstance
Definition: LV2Editor.h:105
wxWindow * mParent
Definition: LV2Editor.h:114
const EffectOutputs * mpOutputs
Definition: LV2Editor.h:106
bool mUseGUI
Definition: LV2Editor.h:115
const EffectType mType
Definition: LV2Editor.h:104
const LV2PortStates & GetPortStates() const
Definition: LV2Instance.h:36

References mParent.

◆ ~LV2Editor()

LV2Editor::~LV2Editor ( )
override

Definition at line 182 of file LV2Editor.cpp.

183{
184 Disconnect();
185}
void Disconnect() override
On the first call only, may disconnect from further event handling.
Definition: LV2Editor.cpp:159

References Disconnect().

Here is the call graph for this function:

Member Function Documentation

◆ BuildFancy()

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

Definition at line 203 of file LV2Editor.cpp.

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

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

Here is the call graph for this function:

◆ BuildPlain()

bool LV2Editor::BuildPlain ( EffectSettingsAccess access)

Captures a const reference to value!

Function to revisit the controls just added above

Definition at line 389 of file LV2Editor.cpp.

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

Here is the call graph for this function:

◆ Disconnect()

void LV2Editor::Disconnect ( )
overridevirtual

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

Default implemantation does nothing

Reimplemented from EffectEditor.

Definition at line 159 of file LV2Editor.cpp.

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

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

Referenced by ~LV2Editor().

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

◆ GetSuilHost()

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

Definition at line 187 of file LV2Editor.cpp.

188{
189 // This is a unique_ptr specialization
190 using SuilHostPtr = Lilv_ptr<SuilHost, suil_host_free>;
191 // The host has no dependency on the plug-in and can be shared among
192 // validators
193 static std::weak_ptr<SuilHost> sSuilHost;
194 std::shared_ptr<SuilHost> result = sSuilHost.lock();
195 if (!result)
196 // shared_ptr erases type of custom deleter of SuilHostPtr
197 sSuilHost = result = SuilHostPtr{ suil_host_new(
199 LV2UIFeaturesList::suil_port_index, nullptr, nullptr) };
200 return result;
201}
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 LV2Editor::IsGraphicalUI ( )
overridevirtual

Default implementation returns false

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

Reimplemented from EffectEditor.

Definition at line 144 of file LV2Editor.cpp.

145{
146 return mUseGUI;
147}

◆ OnChoice()

void LV2Editor::OnChoice ( wxCommandEvent &  evt)

Definition at line 762 of file LV2Editor.cpp.

763{
764 size_t idx = evt.GetId() - ID_Choices;
765 auto & port = mPorts.mControlPorts[idx];
768 GetSettings(settings), idx, port->mScaleValues[evt.GetInt()]);
769 return nullptr;
770 });
771}
EffectSettingsAccess & mAccess
Definition: EffectEditor.h:92
void ModifySettings(Function &&function)
Do a correct read-modify-write of settings.
void UpdateControlPortValue(LV2EffectSettings &settings, size_t controlPortIndex, float value)
Definition: LV2Editor.cpp:722
Externalized state of a plug-in.

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

Here is the call graph for this function:

◆ OnIdle()

void LV2Editor::OnIdle ( wxIdleEvent &  evt)

Definition at line 819 of file LV2Editor.cpp.

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

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

Here is the call graph for this function:

◆ OnSize()

void LV2Editor::OnSize ( wxSizeEvent &  evt)

Definition at line 889 of file LV2Editor.cpp.

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

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

Referenced by BuildFancy().

Here is the caller graph for this function:

◆ OnSlider()

void LV2Editor::OnSlider ( wxCommandEvent &  evt)

Definition at line 790 of file LV2Editor.cpp.

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

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

Here is the call graph for this function:

◆ OnText()

void LV2Editor::OnText ( wxCommandEvent &  evt)

Definition at line 773 of file LV2Editor.cpp.

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

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

Here is the call graph for this function:

◆ OnToggle()

void LV2Editor::OnToggle ( wxCommandEvent &  evt)

Definition at line 752 of file LV2Editor.cpp.

753{
754 size_t idx = evt.GetId() - ID_Toggles;
757 GetSettings(settings), idx, evt.GetInt() ? 1.0 : 0.0);
758 return nullptr;
759 });
760}

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

Here is the call graph for this function:

◆ OnTrigger()

void LV2Editor::OnTrigger ( wxCommandEvent &  evt)

Definition at line 742 of file LV2Editor.cpp.

743{
744 size_t idx = evt.GetId() - ID_Triggers;
745 auto & port = mPorts.mControlPorts[idx];
748 return nullptr;
749 });
750}

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

Here is the call graph for this function:

◆ SetSlider()

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

Definition at line 708 of file LV2Editor.cpp.

710{
711 float lo = state.mLo;
712 float hi = state.mHi;
713 float val = state.mTmp;
714 if (state.mpPort->mLogarithmic) {
715 lo = logf(lo);
716 hi = logf(hi);
717 val = logf(val);
718 }
719 ctrl.slider->SetValue(lrintf((val - lo) / (hi - lo) * 1000.0));
720}
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 LV2Editor::PlainUIControl::slider.

Referenced by OnText(), and UpdateUI().

Here is the caller graph for this function:

◆ size_request()

void LV2Editor::size_request ( GtkWidget *  widget,
GtkRequisition *  requisition,
LV2Editor pEditor 
)
static

Definition at line 1015 of file LV2Editor.cpp.

1017{
1018 pEditor->SizeRequest(widget, requisition);
1019}
void SizeRequest(GtkWidget *widget, GtkRequisition *requisition)
Definition: LV2Editor.cpp:1021

References SizeRequest().

Referenced by BuildFancy().

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

◆ SizeRequest()

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

Definition at line 1021 of file LV2Editor.cpp.

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

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

Referenced by size_request().

Here is the caller graph for this function:

◆ suil_port_index()

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

Implements LV2UIFeaturesList::UIHandler.

Definition at line 998 of file LV2Editor.cpp.

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

References mPlug.

◆ suil_port_write()

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

Implements LV2UIFeaturesList::UIHandler.

Definition at line 969 of file LV2Editor.cpp.

971{
972 // Handle implicit floats
973 if (protocol == 0 && buffer_size == sizeof(float)) {
974 if (auto it = mPorts.mControlPortMap.find(port_index);
975 it != mPorts.mControlPortMap.end())
976 {
977 const auto value = *static_cast<const float*>(buffer);
980 {
981 GetSettings(settings).values[it->second] = value;
982 return nullptr;
983 });
984
985
986 Publish({ size_t(port_index), value });
987 }
988 }
989 // Handle event transfers
990 else if (protocol == LV2Symbols::urid_EventTransfer) {
991 auto &portUIStates = mPortUIStates;
992 auto &atomPortState = portUIStates.mControlIn;
993 if (atomPortState && port_index == atomPortState->mpPort->mIndex)
994 atomPortState->ReceiveFromDialog(buffer, buffer_size);
995 }
996}
LV2AtomPortStatePtr mControlIn
Definition: LV2Ports.h:308
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(), EffectEditor::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 LV2Editor::ui_closed ( )
overridevirtual

Implements LV2UIFeaturesList::UIHandler.

Definition at line 963 of file LV2Editor.cpp.

964{
965 mExternalUIClosed = true;
966}

References mExternalUIClosed.

◆ ui_resize()

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

Implements LV2UIFeaturesList::UIHandler.

Definition at line 949 of file LV2Editor.cpp.

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

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

◆ UpdateControlPortValue()

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

Definition at line 722 of file LV2Editor.cpp.

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

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 LV2Editor::UpdateUI ( )
overridevirtual

Update appearance of the panel for changes in settings.

Default implementation does nothing, returns true

Returns
true if successful

Reimplemented from EffectEditor.

Definition at line 641 of file LV2Editor.cpp.

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

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

Here is the call graph for this function:

◆ ValidateUI()

bool LV2Editor::ValidateUI ( )
overridevirtual

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

Returns
true only if panel settings are acceptable

Implements EffectEditor.

Definition at line 149 of file LV2Editor.cpp.

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

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

Here is the call graph for this function:

Member Data Documentation

◆ mDialog

wxWeakRef<wxDialog> LV2Editor::mDialog

Definition at line 151 of file LV2Editor.h.

Referenced by OnIdle(), and OnSize().

◆ mDuration

NumericTextCtrl* LV2Editor::mDuration {}

Definition at line 162 of file LV2Editor.h.

Referenced by BuildPlain(), and ValidateUI().

◆ mExternalUIClosed

bool LV2Editor::mExternalUIClosed { false }

Definition at line 152 of file LV2Editor.h.

Referenced by OnIdle(), and ui_closed().

◆ mInstance

LV2Instance& LV2Editor::mInstance

Definition at line 105 of file LV2Editor.h.

Referenced by UpdateUI().

◆ mNativeWinInitialSize

wxSize LV2Editor::mNativeWinInitialSize { wxDefaultSize }

Definition at line 144 of file LV2Editor.h.

Referenced by BuildFancy(), and ui_resize().

◆ mNativeWinLastSize

wxSize LV2Editor::mNativeWinLastSize { wxDefaultSize }

Definition at line 145 of file LV2Editor.h.

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

◆ mParent

wxWindow* LV2Editor::mParent

Definition at line 114 of file LV2Editor.h.

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

◆ mPlainUIControls

std::vector<PlainUIControl> LV2Editor::mPlainUIControls

Array in correspondence with the control ports.

Definition at line 130 of file LV2Editor.h.

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

◆ mPlug

const LilvPlugin& LV2Editor::mPlug

Definition at line 103 of file LV2Editor.h.

Referenced by BuildFancy(), and suil_port_index().

◆ mPorts

const LV2Ports& LV2Editor::mPorts

◆ mPortUIStates

LV2PortUIStates LV2Editor::mPortUIStates

Definition at line 111 of file LV2Editor.h.

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

◆ mpOutputs

const EffectOutputs* LV2Editor::mpOutputs {}

Definition at line 106 of file LV2Editor.h.

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

◆ mpWrapper

std::unique_ptr<LV2Wrapper> LV2Editor::mpWrapper

Definition at line 109 of file LV2Editor.h.

Referenced by BuildFancy().

◆ mResized

bool LV2Editor::mResized { false }

Definition at line 148 of file LV2Editor.h.

Referenced by OnSize(), and SizeRequest().

◆ mResizing

bool LV2Editor::mResizing { false }

Definition at line 146 of file LV2Editor.h.

Referenced by OnSize(), and SizeRequest().

◆ mSampleRate

const double LV2Editor::mSampleRate

Definition at line 107 of file LV2Editor.h.

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

◆ mSuilHost

std::shared_ptr<SuilHost> LV2Editor::mSuilHost

Definition at line 113 of file LV2Editor.h.

Referenced by BuildFancy().

◆ mTimer

LV2Editor::Timer LV2Editor::mTimer

Referenced by BuildFancy().

◆ mType

const EffectType LV2Editor::mType

Definition at line 104 of file LV2Editor.h.

Referenced by BuildPlain(), and ValidateUI().

◆ mUI

struct LV2Editor::UI LV2Editor::mUI

◆ mUIFeatures

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

Definition at line 110 of file LV2Editor.h.

Referenced by BuildFancy(), and OnSize().

◆ mUIIdleInterface

const LV2UI_Idle_Interface* LV2Editor::mUIIdleInterface {}

Definition at line 160 of file LV2Editor.h.

Referenced by BuildFancy(), and OnIdle().

◆ mUIShowInterface

const LV2UI_Show_Interface* LV2Editor::mUIShowInterface {}

Definition at line 161 of file LV2Editor.h.

Referenced by BuildFancy(), and OnIdle().

◆ mUseGUI

bool LV2Editor::mUseGUI {}

Definition at line 115 of file LV2Editor.h.

Referenced by UpdateUI().


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