Audacity  3.0.3
EffectUI.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  EffectUI.cpp
6 
7  Leland Lucius
8 
9  Audacity(R) is copyright (c) 1999-2008 Audacity Team.
10  License: GPL v2. See License.txt.
11 
12 **********************************************************************/
13 
14 
15 #include "EffectUI.h"
16 
17 #include "Effect.h"
18 #include "EffectManager.h"
19 #include "../ProjectHistory.h"
20 #include "../ProjectWindowBase.h"
21 #include "../TrackPanelAx.h"
22 #include "RealtimeEffectManager.h"
23 
24 #if defined(EXPERIMENTAL_EFFECTS_RACK)
25 
26 #include "../UndoManager.h"
27 
28 #include <wx/dcmemory.h>
29 #include <wx/defs.h>
30 #include <wx/bmpbuttn.h>
31 #include <wx/button.h>
32 #include <wx/frame.h>
33 #include <wx/image.h>
34 #include <wx/imaglist.h>
35 #include <wx/settings.h>
36 #include <wx/sizer.h>
37 #include <wx/statline.h>
38 #include <wx/stattext.h>
39 #include <wx/timer.h>
40 #include <wx/tglbtn.h>
41 
42 #include "../commands/CommandContext.h"
43 #include "../Prefs.h"
44 #include "../Project.h"
45 #include "../widgets/wxPanelWrapper.h"
46 
47 #include "../../images/EffectRack/EffectRack.h"
48 
49 #define COL_POWER 0
50 #define COL_EDITOR 1
51 #define COL_UP 2
52 #define COL_DOWN 3
53 #define COL_FAV 4
54 #define COL_REMOVE 5
55 #define COL_NAME 6
56 #define NUMCOLS 7
57 
58 #define ID_BASE 20000
59 #define ID_RANGE 100
60 #define ID_POWER (ID_BASE + (COL_POWER * ID_RANGE))
61 #define ID_EDITOR (ID_BASE + (COL_EDITOR * ID_RANGE))
62 #define ID_UP (ID_BASE + (COL_UP * ID_RANGE))
63 #define ID_DOWN (ID_BASE + (COL_DOWN * ID_RANGE))
64 #define ID_FAV (ID_BASE + (COL_FAV * ID_RANGE))
65 #define ID_REMOVE (ID_BASE + (COL_REMOVE * ID_RANGE))
66 #define ID_NAME (ID_BASE + (COL_NAME * ID_RANGE))
67 
68 BEGIN_EVENT_TABLE(EffectRack, wxFrame)
69  EVT_CLOSE(EffectRack::OnClose)
70  EVT_TIMER(wxID_ANY, EffectRack::OnTimer)
71 
72  EVT_BUTTON(wxID_APPLY, EffectRack::OnApply)
73  EVT_TOGGLEBUTTON(wxID_CLEAR, EffectRack::OnBypass)
74 
75  EVT_COMMAND_RANGE(ID_REMOVE, ID_REMOVE + 99, wxEVT_COMMAND_BUTTON_CLICKED, EffectRack::OnRemove)
76  EVT_COMMAND_RANGE(ID_POWER, ID_POWER + 99, wxEVT_COMMAND_BUTTON_CLICKED, EffectRack::OnPower)
77  EVT_COMMAND_RANGE(ID_EDITOR, ID_EDITOR + 99, wxEVT_COMMAND_BUTTON_CLICKED, EffectRack::OnEditor)
78  EVT_COMMAND_RANGE(ID_UP, ID_UP + 99, wxEVT_COMMAND_BUTTON_CLICKED, EffectRack::OnUp)
79  EVT_COMMAND_RANGE(ID_DOWN, ID_DOWN + 99, wxEVT_COMMAND_BUTTON_CLICKED, EffectRack::OnDown)
80  EVT_COMMAND_RANGE(ID_FAV, ID_FAV + 99, wxEVT_COMMAND_BUTTON_CLICKED, EffectRack::OnFav)
82 
83 EffectRack::EffectRack( AudacityProject &project )
84 : wxFrame( &GetProjectFrame( project ),
85  wxID_ANY,
86  _("Effects Rack"),
87  wxDefaultPosition,
88  wxDefaultSize,
89  wxSYSTEM_MENU |
90  wxCLOSE_BOX |
91  wxCAPTION |
92  wxFRAME_NO_TASKBAR |
93  wxFRAME_FLOAT_ON_PARENT)
94 , mProject{ project }
95 {
96  mBypassing = false;
97  mNumEffects = 0;
98  mLastLatency = 0;
99  mTimer.SetOwner(this);
100 
101  mPowerPushed = CreateBitmap(power_on_16x16_xpm, false, false);
102  mPowerRaised = CreateBitmap(power_off_16x16_xpm, true, false);
103  mSettingsPushed = CreateBitmap(settings_up_16x16_xpm, false, true);
104  mSettingsRaised = CreateBitmap(settings_down_16x16_xpm, true, true);
105  mUpDisabled = CreateBitmap(up_9x16_xpm, true, true);
106  mUpPushed = CreateBitmap(up_9x16_xpm, false, true);
107  mUpRaised = CreateBitmap(up_9x16_xpm, true, true);
108  mDownDisabled = CreateBitmap(down_9x16_xpm, true, true);
109  mDownPushed = CreateBitmap(down_9x16_xpm, false, true);
110  mDownRaised = CreateBitmap(down_9x16_xpm, true, true);
111  mFavPushed = CreateBitmap(fav_down_16x16_xpm, false, false);
112  mFavRaised = CreateBitmap(fav_up_16x16_xpm, true, false);
113  mRemovePushed = CreateBitmap(remove_16x16_xpm, false, true);
114  mRemoveRaised = CreateBitmap(remove_16x16_xpm, true, true);
115 
116  {
117  auto bs = std::make_unique<wxBoxSizer>(wxVERTICAL);
118  mPanel = safenew wxPanelWrapper(this, wxID_ANY);
119  bs->Add(mPanel, 1, wxEXPAND);
120  SetSizer(bs.release());
121  }
122 
123  {
124  auto bs = std::make_unique<wxBoxSizer>(wxVERTICAL);
125  {
126  auto hs = std::make_unique<wxBoxSizer>(wxHORIZONTAL);
127  wxASSERT(mPanel); // To justify safenew
128  hs->Add(safenew wxButton(mPanel, wxID_APPLY, _("&Apply")), 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
129  hs->AddStretchSpacer();
130  mLatency = safenew wxStaticText(mPanel, wxID_ANY, _("Latency: 0"));
131  hs->Add(mLatency, 0, wxALIGN_CENTER);
132  hs->AddStretchSpacer();
133  hs->Add(safenew wxToggleButton(mPanel, wxID_CLEAR, _("&Bypass")), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
134  bs->Add(hs.release(), 0, wxEXPAND);
135  }
136  bs->Add(safenew wxStaticLine(mPanel, wxID_ANY), 0, wxEXPAND);
137 
138  {
139  auto uMainSizer = std::make_unique<wxFlexGridSizer>(7);
140  uMainSizer->AddGrowableCol(6);
141  uMainSizer->SetHGap(0);
142  uMainSizer->SetVGap(0);
143  bs->Add((mMainSizer = uMainSizer.release()), 1, wxEXPAND);
144  }
145 
146  mPanel->SetSizer(bs.release());
147  }
148 
149  wxString oldPath = gPrefs->GetPath();
150  gPrefs->SetPath(wxT("/EffectsRack"));
151  size_t cnt = gPrefs->GetNumberOfEntries();
152  gPrefs->SetPath(oldPath);
153 
155  for (size_t i = 0; i < cnt; i++)
156  {
157  wxString slot;
158  gPrefs->Read(wxString::Format(wxT("/EffectsRack/Slot%02d"), i), &slot);
159 
160  Effect *effect = em.GetEffect(slot.AfterFirst(wxT(',')));
161  if (effect)
162  {
163  Add(effect, slot.BeforeFirst(wxT(',')) == wxT("1"), true);
164  }
165  }
166 
167  Fit();
168 }
169 
170 EffectRack::~EffectRack()
171 {
172  gPrefs->DeleteGroup(wxT("/EffectsRack"));
173 
174  for (size_t i = 0, cnt = mEffects.size(); i < cnt; i++)
175  {
176  if (mFavState[i])
177  {
178  Effect *effect = mEffects[i];
179  gPrefs->Write(wxString::Format(wxT("/EffectsRack/Slot%02d"), i),
180  wxString::Format(wxT("%d,%s"),
181  mPowerState[i],
182  effect->GetID()));
183  }
184  }
185 }
186 
187 void EffectRack::Add(Effect *effect, bool active, bool favorite)
188 {
189  if (mEffects.end() != std::find(mEffects.begin(), mEffects.end(), effect))
190  {
191  return;
192  }
193 
194  wxBitmapButton *bb;
195 
196  wxASSERT(mPanel); // To justify safenew
197  bb = safenew wxBitmapButton(mPanel, ID_POWER + mNumEffects, mPowerRaised);
198  bb->SetBitmapSelected(mPowerRaised);
199  bb->SetName(_("Active State"));
200  bb->SetToolTip(_("Set effect active state"));
201  mPowerState.push_back(active);
202  if (active)
203  {
204  bb->SetBitmapLabel(mPowerPushed);
205  bb->SetBitmapSelected(mPowerPushed);
206  }
207  else
208  {
209  bb->SetBitmapLabel(mPowerRaised);
210  bb->SetBitmapSelected(mPowerRaised);
211  }
212  mMainSizer->Add(bb, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
213 
214  bb = safenew wxBitmapButton(mPanel, ID_EDITOR + mNumEffects, mSettingsRaised);
215  bb->SetBitmapSelected(mSettingsPushed);
216  bb->SetName(_("Show/Hide Editor"));
217  bb->SetToolTip(_("Open/close effect editor"));
218  mMainSizer->Add(bb, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
219 
220  bb = safenew wxBitmapButton(mPanel, ID_UP + mNumEffects, mUpRaised);
221  bb->SetBitmapSelected(mUpPushed);
222  bb->SetBitmapDisabled(mUpDisabled);
223  bb->SetName(_("Move Up"));
224  bb->SetToolTip(_("Move effect up in the rack"));
225  mMainSizer->Add(bb, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
226 
227  bb = safenew wxBitmapButton(mPanel, ID_DOWN + mNumEffects, mDownRaised);
228  bb->SetBitmapSelected(mDownPushed);
229  bb->SetBitmapDisabled(mDownDisabled);
230  bb->SetName(_("Move Down"));
231  bb->SetToolTip(_("Move effect down in the rack"));
232  mMainSizer->Add(bb, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
233 
234  bb = safenew wxBitmapButton(mPanel, ID_FAV + mNumEffects, mFavRaised);
235  bb->SetBitmapSelected(mFavPushed);
236  bb->SetName(_("Favorite"));
237  bb->SetToolTip(_("Mark effect as a favorite"));
238  mFavState.push_back(favorite);
239  if (favorite)
240  {
241  bb->SetBitmapLabel(mFavPushed);
242  bb->SetBitmapSelected(mFavPushed);
243  }
244  else
245  {
246  bb->SetBitmapLabel(mFavRaised);
247  bb->SetBitmapSelected(mFavRaised);
248  }
249  mMainSizer->Add(bb, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
250 
251  bb = safenew wxBitmapButton(mPanel, ID_REMOVE + mNumEffects, mRemoveRaised);
252  bb->SetBitmapSelected(mRemovePushed);
253  bb->SetName(_("Remove"));
254  bb->SetToolTip(_("Remove effect from the rack"));
255  mMainSizer->Add(bb, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
256 
257  wxStaticText *text = safenew wxStaticText(mPanel, ID_NAME + mNumEffects,
258  effect->GetName().Translation() );
259  text->SetToolTip(_("Name of the effect"));
260  mMainSizer->Add(text, 0, wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
261 
262  mMainSizer->Layout();
263  SetSize(GetMinSize());
264  Fit();
265  Update();
266 
267  mEffects.push_back(effect);
268  mNumEffects++;
269 
270  if (!mTimer.IsRunning())
271  {
272  mTimer.Start(1000);
273  }
274 
275  if (active)
276  {
277  UpdateActive();
278  }
279 }
280 
281 void EffectRack::OnClose(wxCloseEvent & evt)
282 {
283  Show(false);
284  evt.Veto();
285 }
286 
287 void EffectRack::OnTimer(wxTimerEvent & WXUNUSED(evt))
288 {
290  if (latency != mLastLatency)
291  {
292  mLatency->SetLabel(wxString::Format(_("Latency: %4d"), latency));
293  mLatency->Refresh();
294  mLastLatency = latency;
295  }
296 }
297 
298 void EffectRack::OnApply(wxCommandEvent & WXUNUSED(evt))
299 {
300  AudacityProject *project = &mProject;
301 
302  bool success = false;
303  auto state = UndoManager::Get( *project ).GetCurrentState();
304  auto cleanup = finally( [&] {
305  if(!success)
306  // This is like a rollback of state
307  ProjectHistory::Get( *project ).SetStateTo( state, false );
308  } );
309 
310  for (size_t i = 0, cnt = mEffects.size(); i < cnt; i++)
311  {
312  if (mPowerState[i])
313  {
314  if (!EffectUI::DoEffect(mEffects[i]->GetID(),
315  *project,
317  // If any effect fails (or throws), then stop.
318  return;
319  }
320  }
321 
322  success = true;
323 
324  // Only after all succeed, do the following.
325  for (size_t i = 0, cnt = mEffects.size(); i < cnt; i++)
326  {
327  if (mPowerState[i])
328  {
329  mPowerState[i] = false;
330 
331  wxBitmapButton *btn =
332  static_cast<wxBitmapButton *>(FindWindowById(ID_POWER + i));
333  btn->SetBitmapLabel(mPowerRaised);
334  btn->SetBitmapSelected(mPowerRaised);
335  }
336  }
337 
338  UpdateActive();
339 }
340 
341 void EffectRack::OnBypass(wxCommandEvent & evt)
342 {
343  mBypassing = evt.GetInt() != 0;
344  UpdateActive();
345 }
346 
347 void EffectRack::OnPower(wxCommandEvent & evt)
348 {
349  wxBitmapButton *btn = static_cast<wxBitmapButton *>(evt.GetEventObject());
350 
351  int index = GetEffectIndex(btn);
352  mPowerState[index] = !mPowerState[index];
353  if (mPowerState[index])
354  {
355  btn->SetBitmapLabel(mPowerPushed);
356  btn->SetBitmapSelected(mPowerPushed);
357  }
358  else
359  {
360  btn->SetBitmapLabel(mPowerRaised);
361  btn->SetBitmapSelected(mPowerRaised);
362  }
363 
364  UpdateActive();
365 }
366 
367 void EffectRack::OnEditor(wxCommandEvent & evt)
368 {
369  wxBitmapButton *btn = static_cast<wxBitmapButton *>(evt.GetEventObject());
370 
371  evt.Skip();
372 
373  int index = GetEffectIndex(btn);
374  if (index < 0)
375  {
376  return;
377  }
378 
379  auto pEffect = mEffects[index];
380  pEffect->ShowInterface( *GetParent(), EffectUI::DialogFactory,
381  pEffect->IsBatchProcessing() );
382 }
383 
384 void EffectRack::OnUp(wxCommandEvent & evt)
385 {
386  wxBitmapButton *btn = static_cast<wxBitmapButton *>(evt.GetEventObject());
387 
388  evt.Skip();
389 
390  int index = GetEffectIndex(btn);
391  if (index <= 0)
392  {
393  return;
394  }
395 
396  MoveRowUp(index);
397 }
398 
399 void EffectRack::OnDown(wxCommandEvent & evt)
400 {
401  wxBitmapButton *btn = static_cast<wxBitmapButton *>(evt.GetEventObject());
402 
403  evt.Skip();
404 
405  int index = GetEffectIndex(btn);
406  if (index < 0 || index == (mMainSizer->GetChildren().GetCount() / NUMCOLS) - 1)
407  {
408  return;
409  }
410 
411  MoveRowUp(index + 1);
412 }
413 
414 void EffectRack::OnFav(wxCommandEvent & evt)
415 {
416  wxBitmapButton *btn = static_cast<wxBitmapButton *>(evt.GetEventObject());
417 
418  int index = GetEffectIndex(btn);
419  mFavState[index] = !mFavState[index];
420  if (mFavState[index])
421  {
422  btn->SetBitmapLabel(mFavPushed);
423  btn->SetBitmapSelected(mFavPushed);
424  }
425  else
426  {
427  btn->SetBitmapLabel(mFavRaised);
428  btn->SetBitmapSelected(mFavRaised);
429  }
430 }
431 
432 void EffectRack::OnRemove(wxCommandEvent & evt)
433 {
434  wxBitmapButton *btn = static_cast<wxBitmapButton *>(evt.GetEventObject());
435 
436  evt.Skip();
437 
438  int index = GetEffectIndex(btn);
439  if (index < 0)
440  {
441  return;
442  }
443 
444  mEffects.erase(mEffects.begin() + index);
445  mPowerState.erase(mPowerState.begin() + index);
446  mFavState.erase(mFavState.begin() + index);
447 
448  if (mEffects.size() == 0)
449  {
450  if (mTimer.IsRunning())
451  {
452  mTimer.Stop();
453  }
454  }
455 
456  index *= NUMCOLS;
457 
458  for (int i = 0; i < NUMCOLS; i++)
459  {
460  std::unique_ptr<wxWindow> w {mMainSizer->GetItem(index)->GetWindow()};
461  mMainSizer->Detach(index);
462  }
463 
464  mMainSizer->Layout();
465  Fit();
466 
467  UpdateActive();
468 }
469 
470 wxBitmap EffectRack::CreateBitmap(const char *const xpm[], bool up, bool pusher)
471 {
472  wxMemoryDC dc;
473  wxBitmap pic(xpm);
474 
475  wxBitmap mod(pic.GetWidth() + 6, pic.GetHeight() + 6);
476  dc.SelectObject(mod);
477 #if defined( __WXGTK__ )
478  wxColour newColour = wxSystemSettings::GetColour( wxSYS_COLOUR_BACKGROUND );
479 #else
480  wxColour newColour = wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE );
481 #endif
482  dc.SetBackground(wxBrush(newColour));
483  dc.Clear();
484 
485  int offset = 3;
486  if (pusher)
487  {
488  if (!up)
489  {
490  offset += 1;
491  }
492  }
493  dc.DrawBitmap(pic, offset, offset, true);
494 
495  dc.SelectObject(wxNullBitmap);
496 
497  return mod;
498 }
499 
500 int EffectRack::GetEffectIndex(wxWindow *win)
501 {
502  int col = (win->GetId() - ID_BASE) / ID_RANGE;
503  int row;
504  int cnt = mMainSizer->GetChildren().GetCount() / NUMCOLS;
505  for (row = 0; row < cnt; row++)
506  {
507  wxSizerItem *si = mMainSizer->GetItem((row * NUMCOLS) + col);
508  if (si->GetWindow() == win)
509  {
510  break;
511  }
512  }
513 
514  if (row == cnt)
515  {
516  return -1;
517  }
518 
519  return row;
520 }
521 
522 void EffectRack::MoveRowUp(int row)
523 {
524  Effect *effect = mEffects[row];
525  mEffects.erase(mEffects.begin() + row);
526  mEffects.insert(mEffects.begin() + row - 1, effect);
527 
528  int state = mPowerState[row];
529  mPowerState.erase(mPowerState.begin() + row);
530  mPowerState.insert(mPowerState.begin() + row - 1, state);
531 
532  state = mFavState[row];
533  mFavState.erase(mFavState.begin() + row);
534  mFavState.insert(mFavState.begin() + row - 1, state);
535 
536  row *= NUMCOLS;
537 
538  for (int i = 0; i < NUMCOLS; i++)
539  {
540  wxSizerItem *si = mMainSizer->GetItem(row + NUMCOLS - 1);
541  wxWindow *w = si->GetWindow();
542  int flags = si->GetFlag();
543  int border = si->GetBorder();
544  int prop = si->GetProportion();
545  mMainSizer->Detach(row + NUMCOLS - 1);
546  mMainSizer->Insert(row - NUMCOLS, w, prop, flags, border);
547  }
548 
549  mMainSizer->Layout();
550  Refresh();
551 
552  UpdateActive();
553 }
554 
555 void EffectRack::UpdateActive()
556 {
557  mActive.clear();
558 
559  if (!mBypassing)
560  {
561  for (size_t i = 0, cnt = mEffects.size(); i < cnt; i++)
562  {
563  if (mPowerState[i])
564  {
565  mActive.push_back(mEffects[i]);
566  }
567  }
568  }
569 
571  { mActive.begin(), mActive.end() }
572  );
573 }
574 
575 namespace
576 {
578  []( AudacityProject &parent ) -> wxWeakRef< wxWindow > {
579  auto result = safenew EffectRack( parent );
580  result->CenterOnParent();
581  return result;
582  }
583 };
584 }
585 
586 EffectRack &EffectRack::Get( AudacityProject &project )
587 {
588  return project.AttachedWindows::Get< EffectRack >( sKey );
589 }
590 
591 #endif
592 
594 //
595 // EffectPanel
596 //
598 
599 class EffectPanel final : public wxPanelWrapper
600 {
601 public:
602  EffectPanel(wxWindow *parent)
603  : wxPanelWrapper(parent)
604  {
605  // This fools NVDA into not saying "Panel" when the dialog gets focus
608 
609  mAcceptsFocus = true;
610  }
611 
612  virtual ~EffectPanel()
613  {
614  }
615 
616  // ============================================================================
617  // wxWindow implementation
618  // ============================================================================
619 
620  bool AcceptsFocus() const override
621  {
622  return mAcceptsFocus;
623  }
624 
625  // So that wxPanel is not included in Tab traversal, when required - see wxWidgets bug 15581
626  bool AcceptsFocusFromKeyboard() const override
627  {
628  return mAcceptsFocus;
629  }
630 
631  // ============================================================================
632  // EffectPanel implementation
633  // ============================================================================
634  void SetAccept(bool accept)
635  {
636  mAcceptsFocus = accept;
637  }
638 
639 private:
641 };
642 
644 //
645 // EffectUIHost
646 //
648 
649 #include "../../images/Effect.h"
650 #include "../AudioIO.h"
651 #include "../CommonCommandFlags.h"
652 #include "../Menus.h"
653 #include "../prefs/GUISettings.h" // for RTL_WORKAROUND
654 #include "../Project.h"
655 #include "../ProjectAudioManager.h"
656 #include "../ShuttleGui.h"
657 #include "../ViewInfo.h"
658 #include "../commands/AudacityCommand.h"
659 #include "../commands/CommandContext.h"
660 #include "../widgets/AudacityMessageBox.h"
661 #include "../widgets/HelpSystem.h"
662 
663 #include <wx/bmpbuttn.h>
664 #include <wx/checkbox.h>
665 #include <wx/dcclient.h>
666 #include <wx/dcmemory.h>
667 #include <wx/menu.h>
668 #include <wx/settings.h>
669 #include <wx/sizer.h>
670 #include <wx/textctrl.h>
671 
672 #if defined(__WXMAC__)
673 #include <Cocoa/Cocoa.h>
674 #endif
675 
676 static const int kDummyID = 20000;
677 static const int kSaveAsID = 20001;
678 static const int kImportID = 20002;
679 static const int kExportID = 20003;
680 static const int kDefaultsID = 20004;
681 static const int kOptionsID = 20005;
682 static const int kUserPresetsDummyID = 20006;
683 static const int kDeletePresetDummyID = 20007;
684 static const int kMenuID = 20100;
685 static const int kEnableID = 20101;
686 static const int kPlayID = 20102;
687 static const int kRewindID = 20103;
688 static const int kFFwdID = 20104;
689 static const int kPlaybackID = 20105;
690 static const int kCaptureID = 20106;
691 static const int kUserPresetsID = 21000;
692 static const int kDeletePresetID = 22000;
693 static const int kFactoryPresetsID = 23000;
694 
695 BEGIN_EVENT_TABLE(EffectUIHost, wxDialogWrapper)
696 EVT_INIT_DIALOG(EffectUIHost::OnInitDialog)
697 EVT_ERASE_BACKGROUND(EffectUIHost::OnErase)
698 EVT_PAINT(EffectUIHost::OnPaint)
699 EVT_CLOSE(EffectUIHost::OnClose)
705 EVT_CHECKBOX(kEnableID, EffectUIHost::OnEnable)
718 
719 EffectUIHost::EffectUIHost(wxWindow *parent,
720  AudacityProject &project,
721  Effect *effect,
722  EffectUIClientInterface *client)
723 : wxDialogWrapper(parent, wxID_ANY, effect->GetName(),
724  wxDefaultPosition, wxDefaultSize,
725  wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMINIMIZE_BOX | wxMAXIMIZE_BOX)
726 {
727 #if defined(__WXMAC__)
728  // Make sure the effect window actually floats above the main window
729  [ [((NSView *)GetHandle()) window] setLevel:NSFloatingWindowLevel];
730 #endif
731 
732  SetName( effect->GetName() );
733  SetExtraStyle(GetExtraStyle() | wxWS_EX_VALIDATE_RECURSIVELY);
734 
735  mParent = parent;
736  mEffect = effect;
737  mCommand = NULL;
738  mClient = client;
739 
740  mProject = &project;
741 
742  mInitialized = false;
743  mSupportsRealtime = false;
744 
745  mDisableTransport = false;
746 
747  mEnabled = true;
748 
749  mPlayPos = 0.0;
750  mClient->SetHostUI(this);
751 }
752 
753 EffectUIHost::EffectUIHost(wxWindow *parent,
754  AudacityProject &project,
755  AudacityCommand *command,
756  EffectUIClientInterface *client)
757 : wxDialogWrapper(parent, wxID_ANY, XO("Some Command") /*command->GetName()*/,
758  wxDefaultPosition, wxDefaultSize,
759  wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMINIMIZE_BOX | wxMAXIMIZE_BOX)
760 {
761 #if defined(__WXMAC__)
762  // Make sure the effect window actually floats above the main window
763  [ [((NSView *)GetHandle()) window] setLevel:NSFloatingWindowLevel];
764 #endif
765 
766  //SetName( command->GetName() );
767  SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY);
768 
769  mParent = parent;
770  mEffect = NULL;
771  mCommand = command;
772  mClient = client;
773 
774  mProject = &project;
775 
776  mInitialized = false;
777  mSupportsRealtime = false;
778 
779  mDisableTransport = false;
780 
781  mEnabled = true;
782 
783  mPlayPos = 0.0;
784  mClient->SetHostUI(this);
785 }
786 
787 
788 
789 
791 {
792  CleanupRealtime();
793 
794  if (mClient)
795  {
796  if (mNeedsResume)
797  Resume();
798 
799  mClient->CloseUI();
800  mClient = NULL;
801  }
802 }
803 
804 // ============================================================================
805 // wxWindow implementation
806 // ============================================================================
807 
809 {
810  if( mEffect )
811  return mEffect->TransferDataToWindow();
812  if( mCommand )
813  return mCommand->TransferDataToWindow();
814  return false;
815 }
816 
818 {
819  if( mEffect)
821  if( mCommand)
823  return false;
824 }
825 
826 // ============================================================================
827 // wxDialog implementation
828 // ============================================================================
829 
831 {
832 #if defined(__WXMSW__)
833  // Swap the Close and Apply buttons
834  wxSizer *sz = mApplyBtn->GetContainingSizer();
835  wxASSERT(mApplyBtn->GetParent()); // To justify safenew
836  wxButton *apply = safenew wxButton(mApplyBtn->GetParent(), wxID_APPLY);
837  sz->Replace(mCloseBtn, apply);
838  sz->Replace(mApplyBtn, mCloseBtn);
839  sz->Layout();
840  mApplyBtn->Destroy();
841  mApplyBtn = apply;
842  mApplyBtn->SetDefault();
843  mApplyBtn->SetLabel(wxGetStockLabel(wxID_OK, 0));
844  mCloseBtn->SetLabel(wxGetStockLabel(wxID_CANCEL, 0));
845 #else
846  mApplyBtn->SetLabel(wxGetStockLabel(wxID_OK));
847  mCloseBtn->SetLabel(wxGetStockLabel(wxID_CANCEL));
848 #endif
849 
850  Layout();
851 
852  return wxDialogWrapper::ShowModal();
853 }
854 
855 // ============================================================================
856 // EffectUIHost implementation
857 // ============================================================================
858 
859 wxPanel *EffectUIHost::BuildButtonBar(wxWindow *parent)
860 {
865 
866  int margin = 0;
867 #if defined(__WXMAC__)
868  margin = 3; // I'm sure it's needed because of the order things are created...
869 #endif
870 
871  const auto bar = safenew wxPanelWrapper(parent, wxID_ANY);
872 
873  // This fools NVDA into not saying "Panel" when the dialog gets focus
874  bar->SetName(TranslatableString::Inaudible);
875  bar->SetLabel(TranslatableString::Inaudible);
876 
877  ShuttleGui S{ bar, eIsCreating,
878  false /* horizontal */,
879  { -1, -1 } /* minimum size */
880  };
881  {
882  S.SetBorder( margin );
883 
884  if (!mIsGUI)
885  {
886  mMenuBtn = S.Id( kMenuID )
887  .ToolTip(XO("Manage presets and options"))
888  .AddButton( XXO("&Manage"), wxALIGN_CENTER | wxTOP | wxBOTTOM );
889  }
890  else
891  {
892  mMenuBtn = S.Id( kMenuID )
893  .ToolTip(XO("Manage presets and options"))
894  .Name(XO("&Manage"))
895  .AddBitmapButton( CreateBitmap(effect_menu_xpm, true, true) );
896  mMenuBtn->SetBitmapPressed(CreateBitmap(effect_menu_xpm, false, true));
897  }
898 
899  S.AddSpace( 5, 5 );
900 
901  if (!mIsBatch)
902  {
903  if (!mIsGUI)
904  {
905  if (mSupportsRealtime)
906  {
907  mPlayToggleBtn = S.Id( kPlayID )
908  .ToolTip(XO("Start and stop playback"))
909  .AddButton( XXO("Start &Playback"),
910  wxALIGN_CENTER | wxTOP | wxBOTTOM );
911  }
912  else if (mEffect &&
914  (mEffect->GetType() != EffectTypeTool) )
915  {
916  mPlayToggleBtn = S.Id( kPlayID )
917  .ToolTip(XO("Preview effect"))
918  .AddButton( XXO("&Preview"),
919  wxALIGN_CENTER | wxTOP | wxBOTTOM );
920  }
921  }
922  else
923  {
924  mPlayBM = CreateBitmap(effect_play_xpm, true, false);
925  mPlayDisabledBM = CreateBitmap(effect_play_disabled_xpm, true, true);
926  mStopBM = CreateBitmap(effect_stop_xpm, true, false);
927  mStopDisabledBM = CreateBitmap(effect_stop_disabled_xpm, true, false);
928  mPlayBtn = S.Id( kPlayID ).AddBitmapButton( mPlayBM );
929  mPlayBtn->SetBitmapDisabled(mPlayDisabledBM);
930  mPlayBtn->SetBitmapPressed(CreateBitmap(effect_play_xpm, false, true));
931  if (!mSupportsRealtime)
932  {
933  mPlayBtn->SetToolTip(_("Preview effect"));
934 #if defined(__WXMAC__)
935  mPlayBtn->SetName(_("Preview effect"));
936 #else
937  mPlayBtn->SetLabel(_("&Preview effect"));
938 #endif
939  }
940  }
941 
942  if (mSupportsRealtime)
943  {
944  if (!mIsGUI)
945  {
946  mRewindBtn = S.Id( kRewindID )
947  .ToolTip(XO("Skip backward"))
948  .AddButton( XXO("Skip &Backward"),
949  wxALIGN_CENTER | wxTOP | wxBOTTOM );
950  }
951  else
952  {
953  mRewindBtn = S.Id( kRewindID )
954  .ToolTip(XO("Skip backward"))
955  .Name(XO("Skip &Backward"))
956  .AddBitmapButton( CreateBitmap(
957  effect_rewind_xpm, true, true) );
958  mRewindBtn->SetBitmapDisabled(
959  CreateBitmap(effect_rewind_disabled_xpm, true, false));
960  mRewindBtn->SetBitmapPressed(CreateBitmap(effect_rewind_xpm, false, true));
961  }
962 
963  if (!mIsGUI)
964  {
965  mFFwdBtn = S.Id( kFFwdID )
966  .ToolTip(XO("Skip forward"))
967  .AddButton( XXO("Skip &Forward"),
968  wxALIGN_CENTER | wxTOP | wxBOTTOM );
969  }
970  else
971  {
972  mFFwdBtn = S.Id( kFFwdID )
973  .ToolTip(XO("Skip forward"))
974  .Name(XO("Skip &Forward"))
975  .AddBitmapButton( CreateBitmap(
976  effect_ffwd_xpm, true, true) );
977  mFFwdBtn->SetBitmapDisabled(
978  CreateBitmap(effect_ffwd_disabled_xpm, true, false));
979  mFFwdBtn->SetBitmapPressed(CreateBitmap(effect_ffwd_xpm, false, true));
980  }
981 
982  S.AddSpace( 5, 5 );
983 
984  mEnableCb = S.Id( kEnableID )
985  .Position(wxALIGN_CENTER | wxTOP | wxBOTTOM)
986  .Name(XO("Enable"))
987  .AddCheckBox( XXO("&Enable"), mEnabled );
988  //
989  }
990  }
991  }
992 
993  bar->GetSizer()->SetSizeHints( bar );
994 
995  return bar;
996 }
997 
999 {
1000  {
1001  auto gAudioIO = AudioIO::Get();
1002  mDisableTransport = !gAudioIO->IsAvailable(mProject);
1003  mPlaying = gAudioIO->IsStreamActive(); // not exactly right, but will suffice
1004  mCapturing = gAudioIO->IsStreamActive() && gAudioIO->GetNumCaptureChannels() > 0 && !gAudioIO->IsMonitoring();
1005  }
1006 
1007  EffectPanel *w {};
1008  ShuttleGui S{ this, eIsCreating };
1009  {
1010  S.StartHorizontalLay( wxEXPAND );
1011  {
1012  Destroy_ptr<EffectPanel> uw{ safenew EffectPanel( S.GetParent() ) };
1013  RTL_WORKAROUND(uw.get());
1014 
1015  // Try to give the window a sensible default/minimum size
1016  uw->SetMinSize(wxSize(wxMax(600, mParent->GetSize().GetWidth() * 2 / 3),
1017  mParent->GetSize().GetHeight() / 2));
1018 
1019  ShuttleGui S1{ uw.get(), eIsCreating };
1020  if (!mClient->PopulateUI(S1))
1021  {
1022  return false;
1023  }
1024 
1025  S.Prop( 1 )
1026  .Position(wxEXPAND)
1027  .AddWindow((w = uw.release()));
1028  }
1029  S.EndHorizontalLay();
1030 
1031  S.StartPanel();
1032  {
1033  const auto bar = BuildButtonBar( S.GetParent() );
1034 
1035  long buttons;
1036  if ( mEffect && mEffect->ManualPage().empty() && mEffect->HelpPage().empty()) {
1037  buttons = eApplyButton | eCloseButton;
1038  this->SetAcceleratorTable(wxNullAcceleratorTable);
1039  }
1040  else {
1041  buttons = eApplyButton | eCloseButton | eHelpButton;
1042  wxAcceleratorEntry entries[1];
1043 #if defined(__WXMAC__)
1044  // Is there a standard shortcut on Mac?
1045 #else
1046  entries[0].Set(wxACCEL_NORMAL, (int) WXK_F1, wxID_HELP);
1047 #endif
1048  wxAcceleratorTable accel(1, entries);
1049  this->SetAcceleratorTable(accel);
1050  }
1051 
1052  if (mEffect && mEffect->mUIDebug) {
1053  buttons |= eDebugButton;
1054  }
1055 
1056  S.AddStandardButtons(buttons, bar);
1057  }
1058  S.EndPanel();
1059  }
1060 
1061  Layout();
1062  Fit();
1063  Center();
1064 
1065  mApplyBtn = (wxButton *) FindWindow(wxID_APPLY);
1066  mCloseBtn = (wxButton *) FindWindow(wxID_CANCEL);
1067 
1068  UpdateControls();
1069 
1070  w->SetAccept(!mIsGUI);
1071  (!mIsGUI ? w : FindWindow(wxID_APPLY))->SetFocus();
1072 
1073  LoadUserPresets();
1074 
1076 
1077  SetMinSize(GetSize());
1078  return true;
1079 }
1080 
1081 void EffectUIHost::OnInitDialog(wxInitDialogEvent & evt)
1082 {
1083  // Do default handling
1084  wxDialogWrapper::OnInitDialog(evt);
1085 
1086 #if wxCHECK_VERSION(3, 0, 0)
1087  //#warning "check to see if this still needed in wx3"
1088 #endif
1089 
1090  // Pure hackage coming down the pike...
1091  //
1092  // I have no idea why, but if a wxTextCtrl is the first control in the
1093  // panel, then its contents will not be automatically selected when the
1094  // dialog is displayed.
1095  //
1096  // So, we do the selection manually.
1097  wxTextCtrl *focused = wxDynamicCast(FindFocus(), wxTextCtrl);
1098  if (focused)
1099  {
1100  focused->SelectAll();
1101  }
1102 }
1103 
1104 void EffectUIHost::OnErase(wxEraseEvent & WXUNUSED(evt))
1105 {
1106  // Ignore it
1107 }
1108 
1109 void EffectUIHost::OnPaint(wxPaintEvent & WXUNUSED(evt))
1110 {
1111  wxPaintDC dc(this);
1112 
1113  dc.Clear();
1114 }
1115 
1116 void EffectUIHost::OnClose(wxCloseEvent & WXUNUSED(evt))
1117 {
1118  DoCancel();
1119 
1120  CleanupRealtime();
1121 
1122  Hide();
1123 
1124  if (mNeedsResume)
1125  Resume();
1126  mClient->CloseUI();
1127  mClient = NULL;
1128 
1129  Destroy();
1130 }
1131 
1132 void EffectUIHost::OnApply(wxCommandEvent & evt)
1133 {
1134  auto &project = *mProject;
1135 
1136  // On wxGTK (wx2.8.12), the default action is still executed even if
1137  // the button is disabled. This appears to affect all wxDialogs, not
1138  // just our Effects dialogs. So, this is a only temporary workaround
1139  // for legacy effects that disable the OK button. Hopefully this has
1140  // been corrected in wx3.
1141  if (!FindWindow(wxID_APPLY)->IsEnabled())
1142  {
1143  return;
1144  }
1145 
1146  // Honor the "select all if none" preference...a little hackish, but whatcha gonna do...
1147  if (!mIsBatch &&
1148  mEffect &&
1150  mEffect->GetType() != EffectTypeTool &&
1151  ViewInfo::Get( project ).selectedRegion.isPoint())
1152  {
1153  auto flags = AlwaysEnabledFlag;
1154  bool allowed =
1156  mEffect->GetName(),
1157  flags,
1159  if (!allowed)
1160  return;
1161  }
1162 
1163  if (!mClient->ValidateUI())
1164  {
1165  return;
1166  }
1167 
1168  // This will take care of calling TransferDataFromWindow() for an effect.
1170  {
1171  return;
1172  }
1173  // This will take care of calling TransferDataFromWindow() for a command.
1174  if (mCommand ){
1175  wxString params;
1177  }
1178 
1179  if( mEffect )
1180  mEffect->mUIResultID = evt.GetId();
1181 
1182  if (IsModal())
1183  {
1184  mDismissed = true;
1185 
1186  EndModal(true);
1187 
1188  Close();
1189 
1190  return;
1191  }
1192 
1193  // Progress dialog no longer yields, so this "shouldn't" be necessary (yet to be proven
1194  // for sure), but it is a nice visual cue that something is going on.
1195  mApplyBtn->Disable();
1196  auto cleanup = finally( [&] { mApplyBtn->Enable(); } );
1197 
1198  if( mEffect ) {
1199  CommandContext context( project );
1200  // This is absolute hackage...but easy and I can't think of another way just now.
1201  //
1202  // It should callback to the EffectManager to kick off the processing
1203  EffectUI::DoEffect(mEffect->GetID(), context,
1205  }
1206 
1207  if( mCommand )
1208  // PRL: I don't like the global and would rather pass *mProject!
1209  // But I am preserving old behavior
1210  mCommand->Apply( CommandContext{ project } );
1211 }
1212 
1214 {
1215  if (!mDismissed) {
1216  if( mEffect )
1217  mEffect->mUIResultID = wxID_CANCEL;
1218 
1219  if (IsModal())
1220  EndModal(false);
1221  else
1222  Hide();
1223 
1224  mDismissed = true;
1225  }
1226 }
1227 
1228 void EffectUIHost::OnCancel(wxCommandEvent & WXUNUSED(evt))
1229 {
1230  DoCancel();
1231  Close();
1232 }
1233 
1234 void EffectUIHost::OnHelp(wxCommandEvent & WXUNUSED(event))
1235 {
1236  if (mEffect && mEffect->GetFamily() == NYQUISTEFFECTS_FAMILY && (mEffect->ManualPage().empty())) {
1237  // Old ShowHelp required when there is no on-line manual.
1238  // Always use default web browser to allow full-featured HTML pages.
1239  HelpSystem::ShowHelp(FindWindow(wxID_HELP), mEffect->HelpPage(), wxEmptyString, true, true);
1240  }
1241  else if( mEffect )
1242  {
1243  // otherwise use the NEW ShowHelp
1244  HelpSystem::ShowHelp(FindWindow(wxID_HELP), mEffect->ManualPage(), true);
1245  }
1246 }
1247 
1248 void EffectUIHost::OnDebug(wxCommandEvent & evt)
1249 {
1250  OnApply(evt);
1251  if( mEffect )
1252  mEffect->mUIResultID = evt.GetId();
1253 }
1254 
1255 void EffectUIHost::OnMenu(wxCommandEvent & WXUNUSED(evt))
1256 {
1257  wxMenu menu;
1258  if( !mEffect )
1259  return;
1260 
1261  LoadUserPresets();
1262 
1263  if (mUserPresets.size() == 0)
1264  {
1265  menu.Append(kUserPresetsDummyID, _("User Presets"))->Enable(false);
1266  }
1267  else
1268  {
1269  auto sub = std::make_unique<wxMenu>();
1270  for (size_t i = 0, cnt = mUserPresets.size(); i < cnt; i++)
1271  {
1272  sub->Append(kUserPresetsID + i, mUserPresets[i]);
1273  }
1274  menu.Append(0, _("User Presets"), sub.release());
1275  }
1276 
1277  menu.Append(kSaveAsID, _("Save Preset..."));
1278 
1279  if (mUserPresets.size() == 0)
1280  {
1281  menu.Append(kDeletePresetDummyID, _("Delete Preset"))->Enable(false);
1282  }
1283  else
1284  {
1285  auto sub = std::make_unique<wxMenu>();
1286  for (size_t i = 0, cnt = mUserPresets.size(); i < cnt; i++)
1287  {
1288  sub->Append(kDeletePresetID + i, mUserPresets[i]);
1289  }
1290  menu.Append(0, _("Delete Preset"), sub.release());
1291  }
1292 
1293  menu.AppendSeparator();
1294 
1295  auto factory = mEffect->GetFactoryPresets();
1296 
1297  {
1298  auto sub = std::make_unique<wxMenu>();
1299  sub->Append(kDefaultsID, _("Defaults"));
1300  if (factory.size() > 0)
1301  {
1302  sub->AppendSeparator();
1303  for (size_t i = 0, cnt = factory.size(); i < cnt; i++)
1304  {
1305  auto label = factory[i];
1306  if (label.empty())
1307  {
1308  label = _("None");
1309  }
1310 
1311  sub->Append(kFactoryPresetsID + i, label);
1312  }
1313  }
1314  menu.Append(0, _("Factory Presets"), sub.release());
1315  }
1316 
1317  menu.AppendSeparator();
1318  menu.Append(kImportID, _("Import..."))->Enable(mClient->CanExportPresets());
1319  menu.Append(kExportID, _("Export..."))->Enable(mClient->CanExportPresets());
1320  menu.AppendSeparator();
1321  menu.Append(kOptionsID, _("Options..."))->Enable(mClient->HasOptions());
1322  menu.AppendSeparator();
1323 
1324  {
1325  auto sub = std::make_unique<wxMenu>();
1326 
1327  sub->Append(kDummyID, wxString::Format(_("Type: %s"),
1328  ::wxGetTranslation( mEffect->GetFamily().Translation() )));
1329  sub->Append(kDummyID, wxString::Format(_("Name: %s"), mEffect->GetName().Translation()));
1330  sub->Append(kDummyID, wxString::Format(_("Version: %s"), mEffect->GetVersion()));
1331  sub->Append(kDummyID, wxString::Format(_("Vendor: %s"), mEffect->GetVendor().Translation()));
1332  sub->Append(kDummyID, wxString::Format(_("Description: %s"), mEffect->GetDescription().Translation()));
1333 
1334  menu.Append(0, _("About"), sub.release());
1335  }
1336 
1337  wxWindow *btn = FindWindow(kMenuID);
1338  wxRect r = btn->GetRect();
1339  btn->PopupMenu(&menu, r.GetLeft(), r.GetBottom());
1340 }
1341 
1343 {
1344  if (!mClient->ValidateUI()) {
1345  // If we're previewing we should still be able to stop playback
1346  // so don't disable transport buttons.
1347  // mEffect->EnableApply(false); // currently this would also disable transport buttons.
1348  // The preferred behaviour is currently undecided, so for now
1349  // just disallow enabling until settings are valid.
1350  mEnabled = false;
1351  mEnableCb->SetValue(mEnabled);
1352  return;
1353  }
1355 }
1356 
1357 void EffectUIHost::OnEnable(wxCommandEvent & WXUNUSED(evt))
1358 {
1359  mEnabled = mEnableCb->GetValue();
1360 
1361  if (mEnabled) {
1362  Resume();
1363  mNeedsResume = false;
1364  }
1365  else
1366  {
1368  mNeedsResume = true;
1369  }
1370 
1371  UpdateControls();
1372 }
1373 
1374 void EffectUIHost::OnPlay(wxCommandEvent & WXUNUSED(evt))
1375 {
1376  if (!mSupportsRealtime)
1377  {
1379  {
1380  return;
1381  }
1382 
1383  mEffect->Preview(false);
1384 
1385  return;
1386  }
1387 
1388  if (mPlaying)
1389  {
1390  auto gAudioIO = AudioIO::Get();
1391  mPlayPos = gAudioIO->GetStreamTime();
1392  auto &projectAudioManager = ProjectAudioManager::Get( *mProject );
1393  projectAudioManager.Stop();
1394  }
1395  else
1396  {
1397  auto &viewInfo = ViewInfo::Get( *mProject );
1398  const auto &selectedRegion = viewInfo.selectedRegion;
1399  const auto &playRegion = viewInfo.playRegion;
1400  if ( playRegion.Locked() )
1401  {
1402  mRegion.setTimes(playRegion.GetStart(), playRegion.GetEnd());
1403  mPlayPos = mRegion.t0();
1404  }
1405  else if (selectedRegion.t0() != mRegion.t0() ||
1406  selectedRegion.t1() != mRegion.t1())
1407  {
1408  mRegion = selectedRegion;
1409  mPlayPos = mRegion.t0();
1410  }
1411 
1412  if (mPlayPos > mRegion.t1())
1413  {
1414  mPlayPos = mRegion.t1();
1415  }
1416 
1417  auto &projectAudioManager = ProjectAudioManager::Get( *mProject );
1418  projectAudioManager.PlayPlayRegion(
1422  }
1423 }
1424 
1425 void EffectUIHost::OnRewind(wxCommandEvent & WXUNUSED(evt))
1426 {
1427  if (mPlaying)
1428  {
1429  auto gAudioIO = AudioIO::Get();
1430  double seek;
1431  gPrefs->Read(wxT("/AudioIO/SeekShortPeriod"), &seek, 1.0);
1432 
1433  double pos = gAudioIO->GetStreamTime();
1434  if (pos - seek < mRegion.t0())
1435  {
1436  seek = pos - mRegion.t0();
1437  }
1438 
1439  gAudioIO->SeekStream(-seek);
1440  }
1441  else
1442  {
1443  mPlayPos = mRegion.t0();
1444  }
1445 }
1446 
1447 void EffectUIHost::OnFFwd(wxCommandEvent & WXUNUSED(evt))
1448 {
1449  if (mPlaying)
1450  {
1451  double seek;
1452  gPrefs->Read(wxT("/AudioIO/SeekShortPeriod"), &seek, 1.0);
1453 
1454  auto gAudioIO = AudioIO::Get();
1455  double pos = gAudioIO->GetStreamTime();
1456  if (mRegion.t0() < mRegion.t1() && pos + seek > mRegion.t1())
1457  {
1458  seek = mRegion.t1() - pos;
1459  }
1460 
1461  gAudioIO->SeekStream(seek);
1462  }
1463  else
1464  {
1465  // It allows to play past end of selection...probably useless
1466  mPlayPos = mRegion.t1();
1467  }
1468 }
1469 
1470 void EffectUIHost::OnPlayback(wxCommandEvent & evt)
1471 {
1472  evt.Skip();
1473 
1474  if (evt.GetInt() != 0)
1475  {
1476  if (evt.GetEventObject() != mProject)
1477  {
1478  mDisableTransport = true;
1479  }
1480  else
1481  {
1482  mPlaying = true;
1483  }
1484  }
1485  else
1486  {
1487  mDisableTransport = false;
1488  mPlaying = false;
1489  }
1490 
1491  if (mPlaying)
1492  {
1493  mRegion = ViewInfo::Get( *mProject ).selectedRegion;
1494  mPlayPos = mRegion.t0();
1495  }
1496 
1497  UpdateControls();
1498 }
1499 
1500 void EffectUIHost::OnCapture(wxCommandEvent & evt)
1501 {
1502  evt.Skip();
1503 
1504  if (evt.GetInt() != 0)
1505  {
1506  if (evt.GetEventObject() != mProject)
1507  {
1508  mDisableTransport = true;
1509  }
1510  else
1511  {
1512  mCapturing = true;
1513  }
1514  }
1515  else
1516  {
1517  mDisableTransport = false;
1518  mCapturing = false;
1519  }
1520 
1521  UpdateControls();
1522 }
1523 
1524 void EffectUIHost::OnUserPreset(wxCommandEvent & evt)
1525 {
1526  int preset = evt.GetId() - kUserPresetsID;
1527 
1529 
1530  return;
1531 }
1532 
1533 void EffectUIHost::OnFactoryPreset(wxCommandEvent & evt)
1534 {
1536 
1537  return;
1538 }
1539 
1540 void EffectUIHost::OnDeletePreset(wxCommandEvent & evt)
1541 {
1542  auto preset = mUserPresets[evt.GetId() - kDeletePresetID];
1543 
1544  int res = AudacityMessageBox(
1545  XO("Are you sure you want to delete \"%s\"?").Format( preset ),
1546  XO("Delete Preset"),
1547  wxICON_QUESTION | wxYES_NO);
1548  if (res == wxYES)
1549  {
1551  }
1552 
1553  LoadUserPresets();
1554 
1555  return;
1556 }
1557 
1558 void EffectUIHost::OnSaveAs(wxCommandEvent & WXUNUSED(evt))
1559 {
1560  wxTextCtrl *text;
1561  wxString name;
1562  wxDialogWrapper dlg(this, wxID_ANY, XO("Save Preset"));
1563 
1564  ShuttleGui S(&dlg, eIsCreating);
1565 
1566  S.StartPanel();
1567  {
1568  S.StartVerticalLay(1);
1569  {
1570  S.StartHorizontalLay(wxALIGN_LEFT, 0);
1571  {
1572  text = S.AddTextBox(XXO("Preset name:"), name, 30);
1573  }
1574  S.EndHorizontalLay();
1575  S.SetBorder(10);
1576  S.AddStandardButtons();
1577  }
1578  S.EndVerticalLay();
1579  }
1580  S.EndPanel();
1581 
1582  dlg.SetSize(dlg.GetSizer()->GetMinSize());
1583  dlg.Center();
1584  dlg.Fit();
1585 
1586  while (true)
1587  {
1588  int rc = dlg.ShowModal();
1589 
1590  if (rc != wxID_OK)
1591  {
1592  break;
1593  }
1594 
1595  name = text->GetValue();
1596  if (name.empty())
1597  {
1599  this,
1600  XO("You must specify a name"),
1601  XO("Save Preset") );
1602  md.Center();
1603  md.ShowModal();
1604  continue;
1605  }
1606 
1607  if ( make_iterator_range( mUserPresets ).contains( name ) )
1608  {
1610  this,
1611  XO("Preset already exists.\n\nReplace?"),
1612  XO("Save Preset"),
1613  wxYES_NO | wxCANCEL | wxICON_EXCLAMATION );
1614  md.Center();
1615  int choice = md.ShowModal();
1616  if (choice == wxID_CANCEL)
1617  {
1618  break;
1619  }
1620 
1621  if (choice == wxID_NO)
1622  {
1623  continue;
1624  }
1625  }
1626 
1628  LoadUserPresets();
1629 
1630  break;
1631  }
1632 
1633  return;
1634 }
1635 
1636 void EffectUIHost::OnImport(wxCommandEvent & WXUNUSED(evt))
1637 {
1639 
1640  LoadUserPresets();
1641 
1642  return;
1643 }
1644 
1645 void EffectUIHost::OnExport(wxCommandEvent & WXUNUSED(evt))
1646 {
1647  // may throw
1648  // exceptions are handled in AudacityApp::OnExceptionInMainLoop
1650 
1651  return;
1652 }
1653 
1654 void EffectUIHost::OnOptions(wxCommandEvent & WXUNUSED(evt))
1655 {
1656  mClient->ShowOptions();
1657 
1658  return;
1659 }
1660 
1661 void EffectUIHost::OnDefaults(wxCommandEvent & WXUNUSED(evt))
1662 {
1664 
1665  return;
1666 }
1667 
1668 wxBitmap EffectUIHost::CreateBitmap(const char * const xpm[], bool up, bool pusher)
1669 {
1670  wxMemoryDC dc;
1671  wxBitmap pic(xpm);
1672 
1673  wxBitmap mod(pic.GetWidth() + 6, pic.GetHeight() + 6, 24);
1674  dc.SelectObject(mod);
1675 
1676 #if defined(__WXGTK__)
1677  wxColour newColour = wxSystemSettings::GetColour(wxSYS_COLOUR_BACKGROUND);
1678 #else
1679  wxColour newColour = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);
1680 #endif
1681 
1682  dc.SetBackground(wxBrush(newColour));
1683  dc.Clear();
1684 
1685  int offset = 3;
1686  if (pusher)
1687  {
1688  if (!up)
1689  {
1690  offset += 1;
1691  }
1692  }
1693 
1694  dc.DrawBitmap(pic, offset, offset, true);
1695 
1696  dc.SelectObject(wxNullBitmap);
1697 
1698  return mod;
1699 }
1700 
1702 {
1703  if (mIsBatch)
1704  {
1705  return;
1706  }
1707 
1709  {
1710  // Don't allow focus to get trapped
1711  wxWindow *focus = FindFocus();
1712  if (focus == mRewindBtn || focus == mFFwdBtn || focus == mPlayBtn || focus == mEnableCb)
1713  {
1714  mCloseBtn->SetFocus();
1715  }
1716  }
1717 
1718  mApplyBtn->Enable(!mCapturing);
1720  {
1722  }
1723 
1724  if (mSupportsRealtime)
1725  {
1726  mRewindBtn->Enable(!(mCapturing || mDisableTransport));
1727  mFFwdBtn->Enable(!(mCapturing || mDisableTransport));
1728  mEnableCb->Enable(!(mCapturing || mDisableTransport));
1729 
1730  wxBitmapButton *bb;
1731 
1732  if (mPlaying)
1733  {
1734  if (!mIsGUI)
1735  {
1736  /* i18n-hint: The access key "&P" should be the same in
1737  "Stop &Playback" and "Start &Playback" */
1738  mPlayToggleBtn->SetLabel(_("Stop &Playback"));
1739  mPlayToggleBtn->Refresh();
1740  }
1741  else
1742  {
1743  bb = (wxBitmapButton *) mPlayBtn;
1744  bb->SetBitmapLabel(mStopBM);
1745  bb->SetBitmapDisabled(mStopDisabledBM);
1746  bb->SetToolTip(_("Stop"));
1747 #if defined(__WXMAC__)
1748  bb->SetName(_("Stop &Playback"));
1749 #else
1750  bb->SetLabel(_("Stop &Playback"));
1751 #endif
1752  }
1753  }
1754  else
1755  {
1756  if (!mIsGUI)
1757  {
1758  /* i18n-hint: The access key "&P" should be the same in
1759  "Stop &Playback" and "Start &Playback" */
1760  mPlayToggleBtn->SetLabel(_("Start &Playback"));
1761  mPlayToggleBtn->Refresh();
1762  }
1763  else
1764  {
1765  bb = (wxBitmapButton *) mPlayBtn;
1766  bb->SetBitmapLabel(mPlayBM);
1767  bb->SetBitmapDisabled(mPlayDisabledBM);
1768  bb->SetToolTip(_("Play"));
1769 #if defined(__WXMAC__)
1770  bb->SetName(_("Start &Playback"));
1771 #else
1772  bb->SetLabel(_("Start &Playback"));
1773 #endif
1774  }
1775  }
1776  }
1777 }
1778 
1780 {
1781  mUserPresets.clear();
1782 
1783  if( mEffect )
1785 
1786  std::sort( mUserPresets.begin(), mUserPresets.end() );
1787 
1788  return;
1789 }
1790 
1792 {
1794  {
1796 
1797  wxTheApp->Bind(EVT_AUDIOIO_PLAYBACK,
1799  this);
1800 
1801  wxTheApp->Bind(EVT_AUDIOIO_CAPTURE,
1803  this);
1804 
1805  mInitialized = true;
1806  }
1807 }
1808 
1810 {
1812  {
1814 
1815  mInitialized = false;
1816  }
1817 }
1818 
1819 wxDialog *EffectUI::DialogFactory( wxWindow &parent, EffectHostInterface *pHost,
1820  EffectUIClientInterface *client)
1821 {
1822  auto pEffect = dynamic_cast< Effect* >( pHost );
1823  if ( ! pEffect )
1824  return nullptr;
1825 
1826  // Make sure there is an associated project, whose lifetime will
1827  // govern the lifetime of the dialog, even when the dialog is
1828  // non-modal, as for realtime effects
1829  auto project = FindProjectFromWindow(&parent);
1830  if ( !project )
1831  return nullptr;
1832 
1834  safenew EffectUIHost{ &parent, *project, pEffect, client} };
1835 
1836  if (dlg->Initialize())
1837  {
1838  // release() is safe because parent will own it
1839  return dlg.release();
1840  }
1841 
1842  return nullptr;
1843 };
1844 
1845 #include "../PluginManager.h"
1846 #include "../ProjectSettings.h"
1847 #include "../ProjectWindow.h"
1848 #include "../SelectUtilities.h"
1849 #include "../TrackPanel.h"
1850 #include "../WaveTrack.h"
1851 #include "../commands/CommandManager.h"
1852 
1856 // parameters, whether to save the state to history and whether to allow
1858 
1859 /* static */ bool EffectUI::DoEffect(
1860  const PluginID & ID, const CommandContext &context, unsigned flags )
1861 {
1862  AudacityProject &project = context.project;
1863  const auto &settings = ProjectSettings::Get( project );
1864  auto &tracks = TrackList::Get( project );
1865  auto &trackPanel = TrackPanel::Get( project );
1866  auto &trackFactory = WaveTrackFactory::Get( project );
1867  auto rate = settings.GetRate();
1868  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
1869  auto &commandManager = CommandManager::Get( project );
1870  auto &window = ProjectWindow::Get( project );
1871 
1872  const PluginDescriptor *plug = PluginManager::Get().GetPlugin(ID);
1873  if (!plug)
1874  return false;
1875 
1876  EffectType type = plug->GetEffectType();
1877 
1878  // Make sure there's no activity since the effect is about to be applied
1879  // to the project's tracks. Mainly for Apply during RTP, but also used
1880  // for batch commands
1881  if (flags & EffectManager::kConfigured)
1882  {
1883  ProjectAudioManager::Get( project ).Stop();
1884  //Don't Select All if repeating Generator Effect
1885  if (!(flags & EffectManager::kConfigured)) {
1887  }
1888  }
1889 
1890  auto nTracksOriginally = tracks.size();
1891  wxWindow *focus = wxWindow::FindFocus();
1892  wxWindow *parent = nullptr;
1893  if (focus != nullptr) {
1894  parent = focus->GetParent();
1895  }
1896 
1897  bool success = false;
1898  auto cleanup = finally( [&] {
1899 
1900  if (!success) {
1901  // For now, we're limiting realtime preview to a single effect, so
1902  // make sure the menus reflect that fact that one may have just been
1903  // opened.
1904  MenuManager::Get(project).UpdateMenus( false );
1905  }
1906 
1907  } );
1908 
1909  int count = 0;
1910  bool clean = true;
1911  for (auto t : tracks.Selected< const WaveTrack >()) {
1912  if (t->GetEndTime() != 0.0)
1913  clean = false;
1914  count++;
1915  }
1916 
1918 
1919  em.SetSkipStateFlag( false );
1920  if (auto effect = em.GetEffect(ID)) {
1921 #if defined(EXPERIMENTAL_EFFECTS_RACK)
1922  if (effect->SupportsRealtime())
1923  {
1924  EffectRack::Get( context.project ).Add(effect);
1925  }
1926 #endif
1927  effect->SetUIFlags(flags);
1928  success = effect->DoEffect(
1929  rate,
1930  &tracks,
1931  &trackFactory,
1932  selectedRegion,
1933  &window,
1934  (flags & EffectManager::kConfigured) == 0
1935  ? DialogFactory
1936  : nullptr
1937  );
1938  }
1939  else
1940  success = false;
1941 
1942  if (!success)
1943  return false;
1944 
1945  if (em.GetSkipStateFlag())
1946  flags = flags | EffectManager::kSkipState;
1947 
1948  if (!(flags & EffectManager::kSkipState))
1949  {
1950  auto shortDesc = em.GetCommandName(ID);
1951  auto longDesc = em.GetCommandDescription(ID);
1952  ProjectHistory::Get( project ).PushState(longDesc, shortDesc);
1953  }
1954 
1955  if (!(flags & EffectManager::kDontRepeatLast))
1956  {
1957  // Remember a successful generator, effect, analyzer, or tool Process
1958  auto shortDesc = em.GetCommandName(ID);
1959  /* i18n-hint: %s will be the name of the effect which will be
1960  * repeated if this menu item is chosen */
1961  auto lastEffectDesc = XO("Repeat %s").Format(shortDesc);
1962  auto& menuManager = MenuManager::Get(project);
1963  switch ( type ) {
1964  case EffectTypeGenerate:
1965  commandManager.Modify(wxT("RepeatLastGenerator"), lastEffectDesc);
1966  menuManager.mLastGenerator = ID;
1967  menuManager.mRepeatGeneratorFlags = EffectManager::kConfigured;
1968  break;
1969  case EffectTypeProcess:
1970  commandManager.Modify(wxT("RepeatLastEffect"), lastEffectDesc);
1971  menuManager.mLastEffect = ID;
1972  menuManager.mRepeatEffectFlags = EffectManager::kConfigured;
1973  break;
1974  case EffectTypeAnalyze:
1975  commandManager.Modify(wxT("RepeatLastAnalyzer"), lastEffectDesc);
1976  menuManager.mLastAnalyzer = ID;
1977  menuManager.mLastAnalyzerRegistration = MenuCreator::repeattypeplugin;
1978  menuManager.mRepeatAnalyzerFlags = EffectManager::kConfigured;
1979  break;
1980  case EffectTypeTool:
1981  commandManager.Modify(wxT("RepeatLastTool"), lastEffectDesc);
1982  menuManager.mLastTool = ID;
1983  menuManager.mLastToolRegistration = MenuCreator::repeattypeplugin;
1984  menuManager.mRepeatToolFlags = EffectManager::kConfigured;
1985  if (shortDesc == XO("Nyquist Prompt")) {
1986  menuManager.mRepeatToolFlags = EffectManager::kRepeatNyquistPrompt; //Nyquist Prompt is not configured
1987  }
1988  break;
1989  }
1990  }
1991 
1992  //STM:
1993  //The following automatically re-zooms after sound was generated.
1994  // IMO, it was disorienting, removing to try out without re-fitting
1995  //mchinen:12/14/08 reapplying for generate effects
1996  if (type == EffectTypeGenerate)
1997  {
1998  if (count == 0 || (clean && selectedRegion.t0() == 0.0))
1999  window.DoZoomFit();
2000  // trackPanel->Refresh(false);
2001  }
2002 
2003  // PRL: RedrawProject explicitly because sometimes history push is skipped
2004  window.RedrawProject();
2005 
2006  if (focus != nullptr && focus->GetParent()==parent) {
2007  focus->SetFocus();
2008  }
2009 
2010  // A fix for Bug 63
2011  // New tracks added? Scroll them into view so that user sees them.
2012  // Don't care what track type. An analyser might just have added a
2013  // Label track and we want to see it.
2014  if( tracks.size() > nTracksOriginally ){
2015  // 0.0 is min scroll position, 1.0 is max scroll position.
2016  trackPanel.VerticalScroll( 1.0 );
2017  }
2018  else {
2019  auto pTrack = *tracks.Selected().begin();
2020  if (!pTrack)
2021  pTrack = *tracks.Any().begin();
2022  if (pTrack) {
2023  TrackFocus::Get(project).Set(pTrack);
2024  pTrack->EnsureVisible();
2025  }
2026  }
2027 
2028  return true;
2029 }
2030 
2032 BEGIN_EVENT_TABLE(EffectDialog, wxDialogWrapper)
2033  EVT_BUTTON(wxID_OK, EffectDialog::OnOk)
2035 
2036 EffectDialog::EffectDialog(wxWindow * parent,
2037  const TranslatableString & title,
2038  int type,
2039  int flags,
2040  int additionalButtons)
2041 : wxDialogWrapper(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, flags)
2042 {
2043  mType = type;
2044  mAdditionalButtons = additionalButtons;
2045 }
2046 
2048 {
2049  long buttons = eOkButton;
2050  if ((mType != EffectTypeAnalyze) && (mType != EffectTypeTool))
2051  {
2052  buttons |= eCancelButton;
2053  if (mType == EffectTypeProcess)
2054  {
2055  buttons |= ePreviewButton;
2056  }
2057  }
2058 
2059  ShuttleGui S(this, eIsCreating);
2060 
2061  S.SetBorder(5);
2062  S.StartVerticalLay(true);
2063  {
2064  PopulateOrExchange(S);
2066  }
2067  S.EndVerticalLay();
2068 
2069  Layout();
2070  Fit();
2071  SetMinSize(GetSize());
2072  Center();
2073 }
2074 
2079 {
2080  return;
2081 }
2082 
2084 {
2085  ShuttleGui S(this, eIsSettingToDialog);
2086  PopulateOrExchange(S);
2087 
2088  return true;
2089 }
2090 
2092 {
2094  PopulateOrExchange(S);
2095 
2096  return true;
2097 }
2098 
2100 {
2101  return true;
2102 }
2103 
2104 void EffectDialog::OnPreview(wxCommandEvent & WXUNUSED(evt))
2105 {
2106  return;
2107 }
2108 
2109 void EffectDialog::OnOk(wxCommandEvent & WXUNUSED(evt))
2110 {
2111  // On wxGTK (wx2.8.12), the default action is still executed even if
2112  // the button is disabled. This appears to affect all wxDialogs, not
2113  // just our Effects dialogs. So, this is a only temporary workaround
2114  // for legacy effects that disable the OK button. Hopefully this has
2115  // been corrected in wx3.
2116  if (FindWindow(wxID_OK)->IsEnabled() && Validate() && TransferDataFromWindow())
2117  {
2118  EndModal(true);
2119  }
2120 
2121  return;
2122 }
EffectUIClientInterface
EffectUIClientInterface is an abstract base class to populate a UI and validate UI values....
Definition: EffectInterface.h:230
EffectManager::GetSkipStateFlag
bool GetSkipStateFlag()
Definition: EffectManager.cpp:218
EVT_BUTTON
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
EffectUIHost::ShowModal
int ShowModal() override
Definition: EffectUI.cpp:830
FileConfig::SetPath
virtual void SetPath(const wxString &strPath) wxOVERRIDE
Definition: FileConfig.cpp:101
EffectDialog::mAdditionalButtons
int mAdditionalButtons
Definition: EffectUI.h:262
TranslatableString
Definition: Types.h:290
EffectUIHost::mStopBM
wxBitmap mStopBM
Definition: EffectUI.h:201
ViewInfo::Get
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:162
EffectUIHost::mIsBatch
bool mIsBatch
Definition: EffectUI.h:186
EffectUIHost::mDisableTransport
bool mDisableTransport
Definition: EffectUI.h:206
ePreviewButton
@ ePreviewButton
Definition: ShuttleGui.h:612
Effect::DoEffect
bool DoEffect(double projectRate, TrackList *list, WaveTrackFactory *factory, NotifyingSelectedRegion &selectedRegion, wxWindow *pParent=nullptr, const EffectDialogFactory &dialogFactory={})
Definition: Effect.cpp:1208
eIsCreating
@ eIsCreating
Definition: ShuttleGui.h:36
ID_RANGE
@ ID_RANGE
Definition: WaveformPrefs.cpp:78
TranslatableString::empty
bool empty() const
Definition: Types.h:329
WaveTrackFactory::Get
static WaveTrackFactory & Get(AudacityProject &project)
Definition: WaveTrack.cpp:2786
EffectDialog::OnPreview
virtual void OnPreview(wxCommandEvent &evt)
Definition: EffectUI.cpp:2104
ShuttleGuiBase::StartVerticalLay
void StartVerticalLay(int iProp=1)
Definition: ShuttleGui.cpp:1177
WaveTrack
A Track that contains audio waveform data.
Definition: WaveTrack.h:68
EffectTypeProcess
@ EffectTypeProcess
Definition: EffectInterface.h:59
EffectUIHost::TransferDataFromWindow
bool TransferDataFromWindow() override
Definition: EffectUI.cpp:817
kDeletePresetID
static const int kDeletePresetID
Definition: EffectUI.cpp:692
RealtimeEffectManager::RealtimeSetEffects
void RealtimeSetEffects(const EffectArray &mActive)
kImportID
static const int kImportID
Definition: EffectUI.cpp:678
make_iterator_range
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: MemoryX.h:625
ProjectAudioManager::Get
static ProjectAudioManager & Get(AudacityProject &project)
Definition: ProjectAudioManager.cpp:51
eIsGettingFromDialog
@ eIsGettingFromDialog
Definition: ShuttleGui.h:37
ComponentInterfaceSymbol::Translation
const wxString Translation() const
Definition: ComponentInterface.h:91
EffectHostInterface
EffectHostInterface is a decorator of a EffectUIClientInterface. It adds virtual (abstract) functions...
Definition: EffectInterface.h:119
Effect.h
EffectDialog::Init
void Init()
Definition: EffectUI.cpp:2047
kRewindID
static const int kRewindID
Definition: EffectUI.cpp:687
gPrefs
FileConfig * gPrefs
Definition: Prefs.cpp:67
SelectedRegion::t1
double t1() const
Definition: SelectedRegion.h:95
AudacityMessageBox
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption=AudacityMessageBoxCaptionStr(), long style=wxOK|wxCENTRE, wxWindow *parent=NULL, int x=wxDefaultCoord, int y=wxDefaultCoord)
Definition: AudacityMessageBox.h:20
Effect::TransferDataToWindow
virtual bool TransferDataToWindow()
Definition: Effect.cpp:1915
EffectUIHost::DoCancel
void DoCancel()
Definition: EffectUI.cpp:1213
Effect::SupportsRealtime
bool SupportsRealtime() override
Definition: Effect.cpp:234
DefaultPlayOptions
AudioIOStartStreamOptions DefaultPlayOptions(AudacityProject &project)
Definition: ProjectAudioManager.cpp:1003
Track::EnsureVisible
void EnsureVisible(bool modifyState=false)
Definition: Track.cpp:101
Effect::GetID
virtual PluginID GetID()
Definition: Effect.cpp:1023
wxPanelWrapper
Definition: wxPanelWrapper.h:41
Effect
Base class for many of the effects in Audacity.
Definition: Effect.h:71
EffectTypeGenerate
@ EffectTypeGenerate
Definition: EffectInterface.h:58
wxPanelWrapper::SetLabel
void SetLabel(const TranslatableString &label)
Definition: wxPanelWrapper.cpp:46
Effect::mUIResultID
int mUIResultID
Definition: Effect.h:478
kPlaybackID
static const int kPlaybackID
Definition: EffectUI.cpp:689
EffectUIClientInterface::ImportPresets
virtual void ImportPresets()=0
EffectUIHost::mEffect
Effect * mEffect
Definition: EffectUI.h:178
eApplyButton
@ eApplyButton
Definition: ShuttleGui.h:616
EffectUIHost::OnClose
void OnClose(wxCloseEvent &evt)
Definition: EffectUI.cpp:1116
Format
Abstract base class used in importing a file.
kFactoryPresetsID
static const int kFactoryPresetsID
Definition: EffectUI.cpp:693
TranslatableString::Inaudible
static const TranslatableString Inaudible
Definition: Types.h:292
EffectUIHost::OnApply
void OnApply(wxCommandEvent &evt)
Definition: EffectUI.cpp:1132
kCaptureID
static const int kCaptureID
Definition: EffectUI.cpp:690
Effect::LoadUserPreset
bool LoadUserPreset(const RegistryPath &name) override
Definition: Effect.cpp:553
EffectUIHost::OnSaveAs
void OnSaveAs(wxCommandEvent &evt)
Definition: EffectUI.cpp:1558
EffectManager::kConfigured
@ kConfigured
Definition: EffectManager.h:53
EffectManager::kDontRepeatLast
@ kDontRepeatLast
Definition: EffectManager.h:57
EffectUIHost::Initialize
bool Initialize()
Definition: EffectUI.cpp:998
EffectManager::GetCommandName
TranslatableString GetCommandName(const PluginID &ID)
Definition: EffectManager.cpp:101
FileConfig::GetNumberOfEntries
virtual size_t GetNumberOfEntries(bool bRecursive=false) const wxOVERRIDE
Definition: FileConfig.cpp:131
EffectUIHost::OnDebug
void OnDebug(wxCommandEvent &evt)
Definition: EffectUI.cpp:1248
EffectUIHost::mMenuBtn
wxButton * mMenuBtn
Definition: EffectUI.h:190
TrackPanel::Get
static TrackPanel & Get(AudacityProject &project)
Definition: TrackPanel.cpp:222
XO
#define XO(s)
Definition: Internat.h:32
EffectUIHost::OnEnable
void OnEnable(wxCommandEvent &evt)
Definition: EffectUI.cpp:1357
EffectUIHost::OnCancel
void OnCancel(wxCommandEvent &evt)
Definition: EffectUI.cpp:1228
ProjectSettings::Get
static ProjectSettings & Get(AudacityProject &project)
Definition: ProjectSettings.cpp:39
SelectedRegion::setTimes
bool setTimes(double t0, double t1)
Definition: SelectedRegion.h:139
kPlayID
static const int kPlayID
Definition: EffectUI.cpp:686
EffectUIHost::EffectUIHost
EffectUIHost(wxWindow *parent, AudacityProject &project, Effect *effect, EffectUIClientInterface *client)
Definition: EffectUI.cpp:719
NYQUISTEFFECTS_FAMILY
#define NYQUISTEFFECTS_FAMILY
Definition: Effect.h:58
EffectUIHost::OnFFwd
void OnFFwd(wxCommandEvent &evt)
Definition: EffectUI.cpp:1447
EffectDialog::TransferDataToWindow
bool TransferDataToWindow() override
Definition: EffectUI.cpp:2083
eCancelButton
@ eCancelButton
Definition: ShuttleGui.h:608
Effect::IsBatchProcessing
virtual bool IsBatchProcessing()
Definition: Effect.cpp:1189
kUserPresetsID
static const int kUserPresetsID
Definition: EffectUI.cpp:691
ProjectWindow::Get
static ProjectWindow & Get(AudacityProject &project)
Definition: ProjectWindow.cpp:531
FindProjectFromWindow
AudacityProject * FindProjectFromWindow(wxWindow *pWindow)
Definition: ProjectWindowBase.cpp:39
eCloseButton
@ eCloseButton
Definition: ShuttleGui.h:617
AlwaysEnabledFlag
constexpr CommandFlag AlwaysEnabledFlag
Definition: CommandFlag.h:35
EffectManager::Get
static EffectManager & Get()
Definition: EffectManager.cpp:42
Effect::GetUserPresetsGroup
RegistryPath GetUserPresetsGroup(const RegistryPath &name) override
Definition: Effect.cpp:854
EffectUIHost::mInitialized
bool mInitialized
Definition: EffectUI.h:183
EffectUIHost::OnOptions
void OnOptions(wxCommandEvent &evt)
Definition: EffectUI.cpp:1654
Effect::SaveUserPreset
bool SaveUserPreset(const RegistryPath &name) override
Definition: Effect.cpp:569
EffectUIHost::Resume
void Resume()
Definition: EffectUI.cpp:1342
ShuttleGuiBase::StartPanel
wxPanel * StartPanel(int iStyle=0)
Definition: ShuttleGui.cpp:983
EffectUIHost::mCommand
AudacityCommand * mCommand
Definition: EffectUI.h:179
MenuCreator::repeattypeplugin
@ repeattypeplugin
Definition: Menus.h:62
eIsSettingToDialog
@ eIsSettingToDialog
Definition: ShuttleGui.h:38
Effect::GetPrivateConfigSubgroups
bool GetPrivateConfigSubgroups(const RegistryPath &group, RegistryPaths &paths) override
Definition: Effect.cpp:956
ShuttleGuiBase::EndPanel
void EndPanel()
Definition: ShuttleGui.cpp:1011
AudacityMessageDialog
Wrap wxMessageDialog so that caption IS translatable.
Definition: wxPanelWrapper.h:215
ClientData::Site::RegisteredFactory
Client code makes static instance from a factory of attachments; passes it to Get or Find as a retrie...
Definition: ClientData.h:266
WaveTracksSelectedFlag
const ReservedCommandFlag & WaveTracksSelectedFlag()
Definition: CommonCommandFlags.cpp:164
Effect::TransferDataFromWindow
virtual bool TransferDataFromWindow()
Definition: Effect.cpp:1920
EffectUIHost::OnPlayback
void OnPlayback(wxCommandEvent &evt)
Definition: EffectUI.cpp:1470
EffectUI::DialogFactory
AUDACITY_DLL_API wxDialog * DialogFactory(wxWindow &parent, EffectHostInterface *pHost, EffectUIClientInterface *client)
Definition: EffectUI.cpp:1819
EffectUIHost::mCapturing
bool mCapturing
Definition: EffectUI.h:208
EffectManager::SetSkipStateFlag
void SetSkipStateFlag(bool flag)
Definition: EffectManager.cpp:213
kDummyID
static const int kDummyID
Definition: EffectUI.cpp:676
RealtimeEffectManager::RealtimeResumeOne
void RealtimeResumeOne(EffectClientInterface &effect)
Definition: RealtimeEffectManager.cpp:271
EffectUIHost::mPlayBtn
wxButton * mPlayBtn
Definition: EffectUI.h:191
PlayMode::normalPlay
@ normalPlay
AudacityCommand::IsBatchProcessing
virtual bool IsBatchProcessing()
Definition: AudacityCommand.h:69
EffectUIHost::OnImport
void OnImport(wxCommandEvent &evt)
Definition: EffectUI.cpp:1636
eDebugButton
@ eDebugButton
Definition: ShuttleGui.h:613
kFFwdID
static const int kFFwdID
Definition: EffectUI.cpp:688
kExportID
static const int kExportID
Definition: EffectUI.cpp:679
RealtimeEffectManager::RealtimeSuspendOne
void RealtimeSuspendOne(EffectClientInterface &effect)
Definition: RealtimeEffectManager.cpp:238
kOptionsID
static const int kOptionsID
Definition: EffectUI.cpp:681
EffectUI.h
EffectUIHost::mEnableCb
wxCheckBox * mEnableCb
Definition: EffectUI.h:194
eOkButton
@ eOkButton
Definition: ShuttleGui.h:607
EffectUIHost::mFFwdBtn
wxButton * mFFwdBtn
Definition: EffectUI.h:193
EffectDialog::Validate
bool Validate() override
Definition: EffectUI.cpp:2099
EffectPanel::~EffectPanel
virtual ~EffectPanel()
Definition: EffectUI.cpp:612
eDebugID
@ eDebugID
Definition: ShuttleGui.h:626
EffectUIClientInterface::ShowOptions
virtual void ShowOptions()=0
ViewInfo::selectedRegion
NotifyingSelectedRegion selectedRegion
Definition: ViewInfo.h:199
XXO
#define XXO(s)
Definition: Internat.h:45
ShuttleGuiBase::EndHorizontalLay
void EndHorizontalLay()
Definition: ShuttleGui.cpp:1170
EffectManager
EffectManager is the class that handles effects and effect categories.
Definition: EffectManager.h:46
MenuManager::UpdateMenus
void UpdateMenus(bool checkActive=true)
Definition: Menus.cpp:634
factory
static RegisteredToolbarFactory factory
Definition: ControlToolBar.cpp:804
CommandContext
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
Definition: CommandContext.h:22
RealtimeEffectManager.h
EffectUIHost::mStopDisabledBM
wxBitmap mStopDisabledBM
Definition: EffectUI.h:202
EffectUIHost::mDismissed
bool mDismissed
Definition: EffectUI.h:213
EffectManager::GetEffect
Effect * GetEffect(const PluginID &ID)
Definition: EffectManager.cpp:706
label
TranslatableString label
Definition: Tags.cpp:755
ShuttleGuiBase::StartHorizontalLay
void StartHorizontalLay(int PositionFlags=wxALIGN_CENTRE, int iProp=1)
Definition: ShuttleGui.cpp:1160
Effect::GetFactoryPresets
RegistryPaths GetFactoryPresets() override
Definition: Effect.cpp:585
EffectUIHost::mParent
wxWindow * mParent
Definition: EffectUI.h:177
EffectUIHost::InitializeRealtime
void InitializeRealtime()
Definition: EffectUI.cpp:1791
AudacityCommand::Apply
virtual bool Apply(const CommandContext &WXUNUSED(context))
Definition: AudacityCommand.h:72
ShuttleGuiBase::AddTextBox
wxTextCtrl * AddTextBox(const TranslatableString &Caption, const wxString &Value, const int nChars)
Definition: ShuttleGui.cpp:631
EffectUIHost::mProject
AudacityProject * mProject
Definition: EffectUI.h:176
ShuttleGuiBase::EndVerticalLay
void EndVerticalLay()
Definition: ShuttleGui.cpp:1196
EffectUIHost::mRegion
SelectedRegion mRegion
Definition: EffectUI.h:210
GetProjectFrame
AUDACITY_DLL_API wxFrame & GetProjectFrame(AudacityProject &project)
Get the top-level window associated with the project (as a wxFrame only, when you do not need to use ...
Definition: Project.cpp:186
Effect::LoadFactoryDefaults
bool LoadFactoryDefaults() override
Definition: Effect.cpp:605
RealtimeEffectManager::RealtimeAddEffect
void RealtimeAddEffect(EffectClientInterface *effect)
Definition: RealtimeEffectManager.cpp:113
EffectPanel::AcceptsFocus
bool AcceptsFocus() const override
Definition: EffectUI.cpp:620
eHelpButton
@ eHelpButton
Definition: ShuttleGui.h:611
EffectUIHost::OnPlay
void OnPlay(wxCommandEvent &evt)
Definition: EffectUI.cpp:1374
kDeletePresetDummyID
static const int kDeletePresetDummyID
Definition: EffectUI.cpp:683
anonymous_namespace{AdornedRulerPanel.cpp}::sKey
AudacityProject::AttachedWindows::RegisteredFactory sKey
Definition: AdornedRulerPanel.cpp:859
EffectPanel::SetAccept
void SetAccept(bool accept)
Definition: EffectUI.cpp:634
EffectUIHost::mClient
EffectUIClientInterface * mClient
Definition: EffectUI.h:180
Effect::GetType
EffectType GetType() override
Definition: Effect.cpp:132
PluginID
wxString PluginID
Definition: EffectManager.h:30
AudacityCommand::GetAutomationParameters
virtual bool GetAutomationParameters(wxString &parms)
Definition: AudacityCommand.cpp:139
EffectDialog::PopulateOrExchange
virtual void PopulateOrExchange(ShuttleGui &S)
Definition: EffectUI.cpp:2078
EffectPanel::mAcceptsFocus
bool mAcceptsFocus
Definition: EffectUI.cpp:640
AudacityCommand
Base class for command in Audacity.
Definition: AudacityCommand.h:41
SelectUtilities::SelectAllIfNone
void SelectAllIfNone(AudacityProject &project)
Definition: SelectUtilities.cpp:84
name
const TranslatableString name
Definition: Distortion.cpp:98
EffectTypeTool
@ EffectTypeTool
Definition: EffectInterface.h:61
Effect::ManualPage
virtual wxString ManualPage()
Definition: Effect.cpp:1171
EffectUIHost::mPlaying
bool mPlaying
Definition: EffectUI.h:207
kEnableID
static const int kEnableID
Definition: EffectUI.cpp:685
EffectDialog
Definition: EffectUI.h:240
EffectPanel
Definition: EffectUI.cpp:600
EffectUIHost::mEnabled
bool mEnabled
Definition: EffectUI.h:204
TrackFocus::Get
Track * Get()
Definition: TrackPanelAx.cpp:755
EffectUIHost::OnDeletePreset
void OnDeletePreset(wxCommandEvent &evt)
Definition: EffectUI.cpp:1540
EffectUIHost::OnRewind
void OnRewind(wxCommandEvent &evt)
Definition: EffectUI.cpp:1425
PluginDescriptor
Definition: PluginManager.h:45
Effect::RemovePrivateConfigSubgroup
bool RemovePrivateConfigSubgroup(const RegistryPath &group) override
Definition: Effect.cpp:1011
RealtimeEffectManager::RealtimeRemoveEffect
void RealtimeRemoveEffect(EffectClientInterface *effect)
Definition: RealtimeEffectManager.cpp:140
RealtimeEffectManager::GetRealtimeLatency
int GetRealtimeLatency()
Definition: RealtimeEffectManager.cpp:402
EffectUIHost::OnCapture
void OnCapture(wxCommandEvent &evt)
Definition: EffectUI.cpp:1500
Effect::mUIDebug
bool mUIDebug
Definition: Effect.h:518
ProjectAudioManager::Stop
void Stop(bool stopStream=true)
Definition: ProjectAudioManager.cpp:309
EffectUIClientInterface::SetHostUI
virtual void SetHostUI(EffectUIHostInterface *host)=0
RealtimeEffectManager::Get
static RealtimeEffectManager & Get()
Definition: RealtimeEffectManager.cpp:43
EffectUIHost::OnInitDialog
void OnInitDialog(wxInitDialogEvent &evt)
Definition: EffectUI.cpp:1081
EffectUIHost::OnPaint
void OnPaint(wxPaintEvent &evt)
Definition: EffectUI.cpp:1109
EffectUIHost::mApplyBtn
wxButton * mApplyBtn
Definition: EffectUI.h:188
Effect::GetCurrentSettingsGroup
RegistryPath GetCurrentSettingsGroup() override
Definition: Effect.cpp:865
EffectUIHost::OnUserPreset
void OnUserPreset(wxCommandEvent &evt)
Definition: EffectUI.cpp:1524
EffectUIHost::OnHelp
void OnHelp(wxCommandEvent &evt)
Definition: EffectUI.cpp:1234
Effect::Preview
virtual void Preview(bool dryOnly)
Definition: Effect.cpp:2294
EffectManager::kRepeatNyquistPrompt
@ kRepeatNyquistPrompt
Definition: EffectManager.h:61
EffectUIHost::mIsGUI
bool mIsGUI
Definition: EffectUI.h:185
Effect::GetVendor
VendorSymbol GetVendor() override
Definition: Effect.cpp:162
FileConfig::DeleteGroup
virtual bool DeleteGroup(const wxString &key) wxOVERRIDE
Definition: FileConfig.cpp:227
ProjectHistory::PushState
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
Definition: ProjectHistory.cpp:89
EffectUIHost::mUserPresets
RegistryPaths mUserPresets
Definition: EffectUI.h:182
wxDialogWrapper
Definition: wxPanelWrapper.h:81
wxPanelWrapper::SetName
void SetName()
Definition: wxPanelWrapper.cpp:61
SelectedRegion::t0
double t0() const
Definition: SelectedRegion.h:94
EffectUIHost::mPlayBM
wxBitmap mPlayBM
Definition: EffectUI.h:199
EffectUIHost::BuildButtonBar
wxPanel * BuildButtonBar(wxWindow *parent)
Definition: EffectUI.cpp:859
PluginManager::Get
static PluginManager & Get()
Definition: PluginManager.cpp:1761
EffectUIHost::OnMenu
void OnMenu(wxCommandEvent &evt)
Definition: EffectUI.cpp:1255
PluginDescriptor::GetEffectType
EffectType GetEffectType() const
Definition: PluginManager.cpp:1247
Effect::HelpPage
virtual wxString HelpPage()
Definition: Effect.cpp:1176
EffectUIHost::OnDefaults
void OnDefaults(wxCommandEvent &evt)
Definition: EffectUI.cpp:1661
Effect::GetFamily
EffectFamilySymbol GetFamily() override
Definition: Effect.cpp:192
MenuManager::ReportIfActionNotAllowed
bool ReportIfActionNotAllowed(const TranslatableString &Name, CommandFlag &flags, CommandFlag flagsRqd)
Definition: Menus.cpp:696
HelpSystem::ShowHelp
static void ShowHelp(wxWindow *parent, const wxString &localFileName, const wxString &remoteURL, bool bModal=false, bool alwaysDefaultBrowser=false)
Definition: HelpSystem.cpp:238
EffectUIClientInterface::PopulateUI
virtual bool PopulateUI(ShuttleGui &S)=0
TrackList::Get
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:495
kUserPresetsDummyID
static const int kUserPresetsDummyID
Definition: EffectUI.cpp:682
EffectUIHost::OnFactoryPreset
void OnFactoryPreset(wxCommandEvent &evt)
Definition: EffectUI.cpp:1533
EffectUIHost::mPlayDisabledBM
wxBitmap mPlayDisabledBM
Definition: EffectUI.h:200
_
#define _(s)
Definition: Internat.h:76
EffectUIHost::CreateBitmap
wxBitmap CreateBitmap(const char *const xpm[], bool up, bool pusher)
Definition: EffectUI.cpp:1668
UndoManager::Get
static UndoManager & Get(AudacityProject &project)
Definition: UndoManager.cpp:57
Effect::GetDescription
TranslatableString GetDescription() override
Definition: Effect.cpp:182
EffectTypeAnalyze
@ EffectTypeAnalyze
Definition: EffectInterface.h:60
AudacityProject
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:112
EffectUIClientInterface::CloseUI
virtual bool CloseUI()=0
TimeSelectedFlag
const ReservedCommandFlag & TimeSelectedFlag()
Definition: CommonCommandFlags.cpp:159
EffectUIHost::mRewindBtn
wxButton * mRewindBtn
Definition: EffectUI.h:192
kDefaultsID
static const int kDefaultsID
Definition: EffectUI.cpp:680
EffectUIHost::OnExport
void OnExport(wxCommandEvent &evt)
Definition: EffectUI.cpp:1645
MenuManager::Get
static MenuManager & Get(AudacityProject &project)
Definition: Menus.cpp:69
EffectUIHost::~EffectUIHost
virtual ~EffectUIHost()
Definition: EffectUI.cpp:790
kMenuID
static const int kMenuID
Definition: EffectUI.cpp:684
EffectPanel::AcceptsFocusFromKeyboard
bool AcceptsFocusFromKeyboard() const override
Definition: EffectUI.cpp:626
EffectUIHost
Definition: EffectUI.h:119
EffectPanel::EffectPanel
EffectPanel(wxWindow *parent)
Definition: EffectUI.cpp:602
EffectManager::kSkipState
@ kSkipState
Definition: EffectManager.h:55
EffectDialog::mType
int mType
Definition: EffectUI.h:261
EffectUI::DoEffect
AUDACITY_DLL_API bool DoEffect(const PluginID &ID, const CommandContext &context, unsigned flags)
'Repeat Last Effect'.
Definition: EffectUI.cpp:1859
EffectManager::GetCommandDescription
TranslatableString GetCommandDescription(const PluginID &ID)
Definition: EffectManager.cpp:128
RTL_WORKAROUND
#define RTL_WORKAROUND(pWnd)
Definition: GUISettings.h:21
ShuttleGui::AddStandardButtons
void AddStandardButtons(long buttons=eOkButton|eCancelButton, wxWindow *extra=NULL)
Definition: ShuttleGui.cpp:2406
UndoManager::GetCurrentState
unsigned int GetCurrentState()
Definition: UndoManager.cpp:265
EffectUIClientInterface::CanExportPresets
virtual bool CanExportPresets()=0
NotifyingSelectedRegion::isPoint
bool isPoint() const
Definition: ViewInfo.h:50
params
EffectDistortion::Params params
Definition: Distortion.cpp:99
TranslatableString::Translation
wxString Translation() const
Definition: Types.h:337
ShuttleGuiBase::SetBorder
void SetBorder(int Border)
Definition: ShuttleGui.h:497
EffectUIHost::mPlayPos
double mPlayPos
Definition: EffectUI.h:211
ComponentInterface::GetName
TranslatableString GetName()
Definition: PluginManager.cpp:3233
EffectUIHost::mPlayToggleBtn
wxButton * mPlayToggleBtn
Definition: EffectUI.h:197
CommandManager::Get
static CommandManager & Get(AudacityProject &project)
Definition: CommandManager.cpp:202
ID_REMOVE
@ ID_REMOVE
Definition: LabelDialog.cpp:75
EffectUIHost::mCloseBtn
wxButton * mCloseBtn
Definition: EffectUI.h:189
Destroy_ptr
std::unique_ptr< T, Destroyer< T > > Destroy_ptr
a convenience for using Destroyer
Definition: MemoryX.h:365
AudioIO::Get
static AudioIO * Get()
Definition: AudioIO.cpp:505
EffectUIClientInterface::IsGraphicalUI
virtual bool IsGraphicalUI()=0
EffectType
EffectType
Definition: EffectInterface.h:55
safenew
#define safenew
Definition: MemoryX.h:8
EffectManager.h
settings
static Settings & settings()
Definition: TrackInfo.cpp:87
EVT_MENU_RANGE
EVT_MENU_RANGE(FileHistory::ID_RECENT_FIRST, FileHistory::ID_RECENT_LAST, AudacityApp::OnMRUFile) bool AudacityApp
Definition: AudacityApp.cpp:782
EffectUIClientInterface::ExportPresets
virtual void ExportPresets()=0
ActiveProjects::Add
void Add(const FilePath &path)
EffectDialog::TransferDataFromWindow
bool TransferDataFromWindow() override
Definition: EffectUI.cpp:2091
EffectUIClientInterface::HasOptions
virtual bool HasOptions()=0
EffectUIHost::UpdateControls
void UpdateControls()
Definition: EffectUI.cpp:1701
EffectUIHost::mNeedsResume
bool mNeedsResume
Definition: EffectUI.h:214
CommandContext::project
AudacityProject & project
Definition: CommandContext.h:52
EffectUIHost::CleanupRealtime
void CleanupRealtime()
Definition: EffectUI.cpp:1809
EffectUIHost::OnErase
void OnErase(wxEraseEvent &evt)
Definition: EffectUI.cpp:1104
END_EVENT_TABLE
END_EVENT_TABLE()
PluginManager::GetPlugin
const PluginDescriptor * GetPlugin(const PluginID &ID)
Definition: PluginManager.cpp:2534
kSaveAsID
static const int kSaveAsID
Definition: EffectUI.cpp:677
EffectUIHost::LoadUserPresets
void LoadUserPresets()
Definition: EffectUI.cpp:1779
Effect::GetVersion
wxString GetVersion() override
Definition: Effect.cpp:172
AudacityCommand::TransferDataToWindow
virtual bool TransferDataToWindow()
Definition: AudacityCommand.cpp:227
EffectUIHost::TransferDataToWindow
bool TransferDataToWindow() override
Definition: EffectUI.cpp:808
EffectUIClientInterface::ValidateUI
virtual bool ValidateUI()=0
ProjectHistory::Get
static ProjectHistory & Get(AudacityProject &project)
Definition: ProjectHistory.cpp:26
EVT_COMMAND_RANGE
EVT_COMMAND_RANGE(ID_Slider, ID_Slider+NUMBER_OF_BANDS - 1, wxEVT_COMMAND_SLIDER_UPDATED, EffectEqualization::OnSlider) EffectEqualization
Definition: Equalization.cpp:217
EffectDialog::OnOk
virtual void OnOk(wxCommandEvent &evt)
Definition: EffectUI.cpp:2109
AudacityCommand::TransferDataFromWindow
virtual bool TransferDataFromWindow()
Definition: AudacityCommand.cpp:234
EffectUIHost::mSupportsRealtime
bool mSupportsRealtime
Definition: EffectUI.h:184
ShuttleGui
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:638
ProjectHistory::SetStateTo
void SetStateTo(unsigned int n, bool doAutosave=true)
Definition: ProjectHistory.cpp:169
Effect::LoadFactoryPreset
bool LoadFactoryPreset(int id) override
Definition: Effect.cpp:595
FileConfig::GetPath
virtual const wxString & GetPath() const wxOVERRIDE
Definition: FileConfig.cpp:106
SelectedRegion
Defines a selected portion of a project.
Definition: SelectedRegion.h:38
Effect::SetUIFlags
virtual void SetUIFlags(unsigned flags)
Definition: Effect.cpp:1181