mirror of
https://github.com/cookiengineer/audacity
synced 2026-04-06 14:27:36 +02:00
Rename EffectRack.* as EffectUI
This commit is contained in:
588
src/effects/EffectUI.cpp
Normal file
588
src/effects/EffectUI.cpp
Normal file
@@ -0,0 +1,588 @@
|
||||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
EffectUI.cpp
|
||||
|
||||
Leland Lucius
|
||||
|
||||
Audacity(R) is copyright (c) 1999-2008 Audacity Team.
|
||||
License: GPL v2. See License.txt.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include "../Audacity.h"
|
||||
#include "EffectUI.h"
|
||||
|
||||
#include "../Experimental.h"
|
||||
|
||||
#include "Effect.h"
|
||||
#include "EffectManager.h"
|
||||
#include "RealtimeEffectManager.h"
|
||||
|
||||
#if defined(EXPERIMENTAL_EFFECTS_RACK)
|
||||
|
||||
#include "../UndoManager.h"
|
||||
|
||||
#include <wx/defs.h>
|
||||
#include <wx/bmpbuttn.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/dcmemory.h>
|
||||
#include <wx/frame.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/imaglist.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/statline.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/timer.h>
|
||||
#include <wx/tglbtn.h>
|
||||
|
||||
#include "../commands/CommandContext.h"
|
||||
#include "../Prefs.h"
|
||||
#include "../Project.h"
|
||||
#include "../ProjectHistory.h"
|
||||
#include "../widgets/wxPanelWrapper.h"
|
||||
|
||||
#include "../../images/EffectRack/EffectRack.h"
|
||||
|
||||
#define COL_POWER 0
|
||||
#define COL_EDITOR 1
|
||||
#define COL_UP 2
|
||||
#define COL_DOWN 3
|
||||
#define COL_FAV 4
|
||||
#define COL_REMOVE 5
|
||||
#define COL_NAME 6
|
||||
#define NUMCOLS 7
|
||||
|
||||
#define ID_BASE 20000
|
||||
#define ID_RANGE 100
|
||||
#define ID_POWER (ID_BASE + (COL_POWER * ID_RANGE))
|
||||
#define ID_EDITOR (ID_BASE + (COL_EDITOR * ID_RANGE))
|
||||
#define ID_UP (ID_BASE + (COL_UP * ID_RANGE))
|
||||
#define ID_DOWN (ID_BASE + (COL_DOWN * ID_RANGE))
|
||||
#define ID_FAV (ID_BASE + (COL_FAV * ID_RANGE))
|
||||
#define ID_REMOVE (ID_BASE + (COL_REMOVE * ID_RANGE))
|
||||
#define ID_NAME (ID_BASE + (COL_NAME * ID_RANGE))
|
||||
|
||||
BEGIN_EVENT_TABLE(EffectRack, wxFrame)
|
||||
EVT_CLOSE(EffectRack::OnClose)
|
||||
EVT_TIMER(wxID_ANY, EffectRack::OnTimer)
|
||||
|
||||
EVT_BUTTON(wxID_APPLY, EffectRack::OnApply)
|
||||
EVT_TOGGLEBUTTON(wxID_CLEAR, EffectRack::OnBypass)
|
||||
|
||||
EVT_COMMAND_RANGE(ID_REMOVE, ID_REMOVE + 99, wxEVT_COMMAND_BUTTON_CLICKED, EffectRack::OnRemove)
|
||||
EVT_COMMAND_RANGE(ID_POWER, ID_POWER + 99, wxEVT_COMMAND_BUTTON_CLICKED, EffectRack::OnPower)
|
||||
EVT_COMMAND_RANGE(ID_EDITOR, ID_EDITOR + 99, wxEVT_COMMAND_BUTTON_CLICKED, EffectRack::OnEditor)
|
||||
EVT_COMMAND_RANGE(ID_UP, ID_UP + 99, wxEVT_COMMAND_BUTTON_CLICKED, EffectRack::OnUp)
|
||||
EVT_COMMAND_RANGE(ID_DOWN, ID_DOWN + 99, wxEVT_COMMAND_BUTTON_CLICKED, EffectRack::OnDown)
|
||||
EVT_COMMAND_RANGE(ID_FAV, ID_FAV + 99, wxEVT_COMMAND_BUTTON_CLICKED, EffectRack::OnFav)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
EffectRack::EffectRack( AudacityProject &project )
|
||||
: wxFrame( &GetProjectFrame( project ),
|
||||
wxID_ANY,
|
||||
_("Effects Rack"),
|
||||
wxDefaultPosition,
|
||||
wxDefaultSize,
|
||||
wxSYSTEM_MENU |
|
||||
wxCLOSE_BOX |
|
||||
wxCAPTION |
|
||||
wxFRAME_NO_TASKBAR |
|
||||
wxFRAME_FLOAT_ON_PARENT)
|
||||
, mProject{ project }
|
||||
{
|
||||
mBypassing = false;
|
||||
mNumEffects = 0;
|
||||
mLastLatency = 0;
|
||||
mTimer.SetOwner(this);
|
||||
|
||||
mPowerPushed = CreateBitmap(power_on_16x16_xpm, false, false);
|
||||
mPowerRaised = CreateBitmap(power_off_16x16_xpm, true, false);
|
||||
mSettingsPushed = CreateBitmap(settings_up_16x16_xpm, false, true);
|
||||
mSettingsRaised = CreateBitmap(settings_down_16x16_xpm, true, true);
|
||||
mUpDisabled = CreateBitmap(up_9x16_xpm, true, true);
|
||||
mUpPushed = CreateBitmap(up_9x16_xpm, false, true);
|
||||
mUpRaised = CreateBitmap(up_9x16_xpm, true, true);
|
||||
mDownDisabled = CreateBitmap(down_9x16_xpm, true, true);
|
||||
mDownPushed = CreateBitmap(down_9x16_xpm, false, true);
|
||||
mDownRaised = CreateBitmap(down_9x16_xpm, true, true);
|
||||
mFavPushed = CreateBitmap(fav_down_16x16_xpm, false, false);
|
||||
mFavRaised = CreateBitmap(fav_up_16x16_xpm, true, false);
|
||||
mRemovePushed = CreateBitmap(remove_16x16_xpm, false, true);
|
||||
mRemoveRaised = CreateBitmap(remove_16x16_xpm, true, true);
|
||||
|
||||
{
|
||||
auto bs = std::make_unique<wxBoxSizer>(wxVERTICAL);
|
||||
mPanel = safenew wxPanelWrapper(this, wxID_ANY);
|
||||
bs->Add(mPanel, 1, wxEXPAND);
|
||||
SetSizer(bs.release());
|
||||
}
|
||||
|
||||
{
|
||||
auto bs = std::make_unique<wxBoxSizer>(wxVERTICAL);
|
||||
{
|
||||
auto hs = std::make_unique<wxBoxSizer>(wxHORIZONTAL);
|
||||
wxASSERT(mPanel); // To justify safenew
|
||||
hs->Add(safenew wxButton(mPanel, wxID_APPLY, _("&Apply")), 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
|
||||
hs->AddStretchSpacer();
|
||||
mLatency = safenew wxStaticText(mPanel, wxID_ANY, _("Latency: 0"));
|
||||
hs->Add(mLatency, 0, wxALIGN_CENTER);
|
||||
hs->AddStretchSpacer();
|
||||
hs->Add(safenew wxToggleButton(mPanel, wxID_CLEAR, _("&Bypass")), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
|
||||
bs->Add(hs.release(), 0, wxEXPAND);
|
||||
}
|
||||
bs->Add(safenew wxStaticLine(mPanel, wxID_ANY), 0, wxEXPAND);
|
||||
|
||||
{
|
||||
auto uMainSizer = std::make_unique<wxFlexGridSizer>(7);
|
||||
uMainSizer->AddGrowableCol(6);
|
||||
uMainSizer->SetHGap(0);
|
||||
uMainSizer->SetVGap(0);
|
||||
bs->Add((mMainSizer = uMainSizer.release()), 1, wxEXPAND);
|
||||
}
|
||||
|
||||
mPanel->SetSizer(bs.release());
|
||||
}
|
||||
|
||||
wxString oldPath = gPrefs->GetPath();
|
||||
gPrefs->SetPath(wxT("/EffectsRack"));
|
||||
size_t cnt = gPrefs->GetNumberOfEntries();
|
||||
gPrefs->SetPath(oldPath);
|
||||
|
||||
EffectManager & em = EffectManager::Get();
|
||||
for (size_t i = 0; i < cnt; i++)
|
||||
{
|
||||
wxString slot;
|
||||
gPrefs->Read(wxString::Format(wxT("/EffectsRack/Slot%02d"), i), &slot);
|
||||
|
||||
Effect *effect = em.GetEffect(slot.AfterFirst(wxT(',')));
|
||||
if (effect)
|
||||
{
|
||||
Add(effect, slot.BeforeFirst(wxT(',')) == wxT("1"), true);
|
||||
}
|
||||
}
|
||||
|
||||
Fit();
|
||||
}
|
||||
|
||||
EffectRack::~EffectRack()
|
||||
{
|
||||
gPrefs->DeleteGroup(wxT("/EffectsRack"));
|
||||
|
||||
for (size_t i = 0, cnt = mEffects.size(); i < cnt; i++)
|
||||
{
|
||||
if (mFavState[i])
|
||||
{
|
||||
Effect *effect = mEffects[i];
|
||||
gPrefs->Write(wxString::Format(wxT("/EffectsRack/Slot%02d"), i),
|
||||
wxString::Format(wxT("%d,%s"),
|
||||
mPowerState[i],
|
||||
effect->GetID()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EffectRack::Add(Effect *effect, bool active, bool favorite)
|
||||
{
|
||||
if (mEffects.end() != std::find(mEffects.begin(), mEffects.end(), effect))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
wxBitmapButton *bb;
|
||||
|
||||
wxASSERT(mPanel); // To justify safenew
|
||||
bb = safenew wxBitmapButton(mPanel, ID_POWER + mNumEffects, mPowerRaised);
|
||||
bb->SetBitmapSelected(mPowerRaised);
|
||||
bb->SetName(_("Active State"));
|
||||
bb->SetToolTip(_("Set effect active state"));
|
||||
mPowerState.push_back(active);
|
||||
if (active)
|
||||
{
|
||||
bb->SetBitmapLabel(mPowerPushed);
|
||||
bb->SetBitmapSelected(mPowerPushed);
|
||||
}
|
||||
else
|
||||
{
|
||||
bb->SetBitmapLabel(mPowerRaised);
|
||||
bb->SetBitmapSelected(mPowerRaised);
|
||||
}
|
||||
mMainSizer->Add(bb, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
bb = safenew wxBitmapButton(mPanel, ID_EDITOR + mNumEffects, mSettingsRaised);
|
||||
bb->SetBitmapSelected(mSettingsPushed);
|
||||
bb->SetName(_("Show/Hide Editor"));
|
||||
bb->SetToolTip(_("Open/close effect editor"));
|
||||
mMainSizer->Add(bb, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
bb = safenew wxBitmapButton(mPanel, ID_UP + mNumEffects, mUpRaised);
|
||||
bb->SetBitmapSelected(mUpPushed);
|
||||
bb->SetBitmapDisabled(mUpDisabled);
|
||||
bb->SetName(_("Move Up"));
|
||||
bb->SetToolTip(_("Move effect up in the rack"));
|
||||
mMainSizer->Add(bb, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
bb = safenew wxBitmapButton(mPanel, ID_DOWN + mNumEffects, mDownRaised);
|
||||
bb->SetBitmapSelected(mDownPushed);
|
||||
bb->SetBitmapDisabled(mDownDisabled);
|
||||
bb->SetName(_("Move Down"));
|
||||
bb->SetToolTip(_("Move effect down in the rack"));
|
||||
mMainSizer->Add(bb, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
bb = safenew wxBitmapButton(mPanel, ID_FAV + mNumEffects, mFavRaised);
|
||||
bb->SetBitmapSelected(mFavPushed);
|
||||
bb->SetName(_("Favorite"));
|
||||
bb->SetToolTip(_("Mark effect as a favorite"));
|
||||
mFavState.push_back(favorite);
|
||||
if (favorite)
|
||||
{
|
||||
bb->SetBitmapLabel(mFavPushed);
|
||||
bb->SetBitmapSelected(mFavPushed);
|
||||
}
|
||||
else
|
||||
{
|
||||
bb->SetBitmapLabel(mFavRaised);
|
||||
bb->SetBitmapSelected(mFavRaised);
|
||||
}
|
||||
mMainSizer->Add(bb, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
bb = safenew wxBitmapButton(mPanel, ID_REMOVE + mNumEffects, mRemoveRaised);
|
||||
bb->SetBitmapSelected(mRemovePushed);
|
||||
bb->SetName(_("Remove"));
|
||||
bb->SetToolTip(_("Remove effect from the rack"));
|
||||
mMainSizer->Add(bb, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
wxStaticText *text = safenew wxStaticText(mPanel, ID_NAME + mNumEffects,
|
||||
effect->GetName().Translation() );
|
||||
text->SetToolTip(_("Name of the effect"));
|
||||
mMainSizer->Add(text, 0, wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
|
||||
|
||||
mMainSizer->Layout();
|
||||
SetSize(GetMinSize());
|
||||
Fit();
|
||||
Update();
|
||||
|
||||
mEffects.push_back(effect);
|
||||
mNumEffects++;
|
||||
|
||||
if (!mTimer.IsRunning())
|
||||
{
|
||||
mTimer.Start(1000);
|
||||
}
|
||||
|
||||
if (active)
|
||||
{
|
||||
UpdateActive();
|
||||
}
|
||||
}
|
||||
|
||||
void EffectRack::OnClose(wxCloseEvent & evt)
|
||||
{
|
||||
Show(false);
|
||||
evt.Veto();
|
||||
}
|
||||
|
||||
void EffectRack::OnTimer(wxTimerEvent & WXUNUSED(evt))
|
||||
{
|
||||
int latency = RealtimeEffectManager::Get().GetRealtimeLatency();
|
||||
if (latency != mLastLatency)
|
||||
{
|
||||
mLatency->SetLabel(wxString::Format(_("Latency: %4d"), latency));
|
||||
mLatency->Refresh();
|
||||
mLastLatency = latency;
|
||||
}
|
||||
}
|
||||
|
||||
void EffectRack::OnApply(wxCommandEvent & WXUNUSED(evt))
|
||||
{
|
||||
AudacityProject *project = &mProject;
|
||||
|
||||
bool success = false;
|
||||
auto state = UndoManager::Get( *project ).GetCurrentState();
|
||||
auto cleanup = finally( [&] {
|
||||
if(!success)
|
||||
ProjectHistory::Get( *project ).SetStateTo( state );
|
||||
} );
|
||||
|
||||
for (size_t i = 0, cnt = mEffects.size(); i < cnt; i++)
|
||||
{
|
||||
if (mPowerState[i])
|
||||
{
|
||||
if (!EffectManager::DoEffect(mEffects[i]->GetID(),
|
||||
*project,
|
||||
EffectManager::kConfigured))
|
||||
// If any effect fails (or throws), then stop.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
success = true;
|
||||
|
||||
// Only after all succeed, do the following.
|
||||
for (size_t i = 0, cnt = mEffects.size(); i < cnt; i++)
|
||||
{
|
||||
if (mPowerState[i])
|
||||
{
|
||||
mPowerState[i] = false;
|
||||
|
||||
wxBitmapButton *btn =
|
||||
static_cast<wxBitmapButton *>(FindWindowById(ID_POWER + i));
|
||||
btn->SetBitmapLabel(mPowerRaised);
|
||||
btn->SetBitmapSelected(mPowerRaised);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateActive();
|
||||
}
|
||||
|
||||
void EffectRack::OnBypass(wxCommandEvent & evt)
|
||||
{
|
||||
mBypassing = evt.GetInt() != 0;
|
||||
UpdateActive();
|
||||
}
|
||||
|
||||
void EffectRack::OnPower(wxCommandEvent & evt)
|
||||
{
|
||||
wxBitmapButton *btn = static_cast<wxBitmapButton *>(evt.GetEventObject());
|
||||
|
||||
int index = GetEffectIndex(btn);
|
||||
mPowerState[index] = !mPowerState[index];
|
||||
if (mPowerState[index])
|
||||
{
|
||||
btn->SetBitmapLabel(mPowerPushed);
|
||||
btn->SetBitmapSelected(mPowerPushed);
|
||||
}
|
||||
else
|
||||
{
|
||||
btn->SetBitmapLabel(mPowerRaised);
|
||||
btn->SetBitmapSelected(mPowerRaised);
|
||||
}
|
||||
|
||||
UpdateActive();
|
||||
}
|
||||
|
||||
void EffectRack::OnEditor(wxCommandEvent & evt)
|
||||
{
|
||||
wxBitmapButton *btn = static_cast<wxBitmapButton *>(evt.GetEventObject());
|
||||
|
||||
evt.Skip();
|
||||
|
||||
int index = GetEffectIndex(btn);
|
||||
if (index < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mEffects[index]->PromptUser(GetParent());
|
||||
}
|
||||
|
||||
void EffectRack::OnUp(wxCommandEvent & evt)
|
||||
{
|
||||
wxBitmapButton *btn = static_cast<wxBitmapButton *>(evt.GetEventObject());
|
||||
|
||||
evt.Skip();
|
||||
|
||||
int index = GetEffectIndex(btn);
|
||||
if (index <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MoveRowUp(index);
|
||||
}
|
||||
|
||||
void EffectRack::OnDown(wxCommandEvent & evt)
|
||||
{
|
||||
wxBitmapButton *btn = static_cast<wxBitmapButton *>(evt.GetEventObject());
|
||||
|
||||
evt.Skip();
|
||||
|
||||
int index = GetEffectIndex(btn);
|
||||
if (index < 0 || index == (mMainSizer->GetChildren().GetCount() / NUMCOLS) - 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MoveRowUp(index + 1);
|
||||
}
|
||||
|
||||
void EffectRack::OnFav(wxCommandEvent & evt)
|
||||
{
|
||||
wxBitmapButton *btn = static_cast<wxBitmapButton *>(evt.GetEventObject());
|
||||
|
||||
int index = GetEffectIndex(btn);
|
||||
mFavState[index] = !mFavState[index];
|
||||
if (mFavState[index])
|
||||
{
|
||||
btn->SetBitmapLabel(mFavPushed);
|
||||
btn->SetBitmapSelected(mFavPushed);
|
||||
}
|
||||
else
|
||||
{
|
||||
btn->SetBitmapLabel(mFavRaised);
|
||||
btn->SetBitmapSelected(mFavRaised);
|
||||
}
|
||||
}
|
||||
|
||||
void EffectRack::OnRemove(wxCommandEvent & evt)
|
||||
{
|
||||
wxBitmapButton *btn = static_cast<wxBitmapButton *>(evt.GetEventObject());
|
||||
|
||||
evt.Skip();
|
||||
|
||||
int index = GetEffectIndex(btn);
|
||||
if (index < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mEffects.erase(mEffects.begin() + index);
|
||||
mPowerState.erase(mPowerState.begin() + index);
|
||||
mFavState.erase(mFavState.begin() + index);
|
||||
|
||||
if (mEffects.size() == 0)
|
||||
{
|
||||
if (mTimer.IsRunning())
|
||||
{
|
||||
mTimer.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
index *= NUMCOLS;
|
||||
|
||||
for (int i = 0; i < NUMCOLS; i++)
|
||||
{
|
||||
std::unique_ptr<wxWindow> w {mMainSizer->GetItem(index)->GetWindow()};
|
||||
mMainSizer->Detach(index);
|
||||
}
|
||||
|
||||
mMainSizer->Layout();
|
||||
Fit();
|
||||
|
||||
UpdateActive();
|
||||
}
|
||||
|
||||
wxBitmap EffectRack::CreateBitmap(const char *const xpm[], bool up, bool pusher)
|
||||
{
|
||||
wxMemoryDC dc;
|
||||
wxBitmap pic(xpm);
|
||||
|
||||
wxBitmap mod(pic.GetWidth() + 6, pic.GetHeight() + 6);
|
||||
dc.SelectObject(mod);
|
||||
#if defined( __WXGTK__ )
|
||||
wxColour newColour = wxSystemSettings::GetColour( wxSYS_COLOUR_BACKGROUND );
|
||||
#else
|
||||
wxColour newColour = wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE );
|
||||
#endif
|
||||
dc.SetBackground(wxBrush(newColour));
|
||||
dc.Clear();
|
||||
|
||||
int offset = 3;
|
||||
if (pusher)
|
||||
{
|
||||
if (!up)
|
||||
{
|
||||
offset += 1;
|
||||
}
|
||||
}
|
||||
dc.DrawBitmap(pic, offset, offset, true);
|
||||
|
||||
dc.SelectObject(wxNullBitmap);
|
||||
|
||||
return mod;
|
||||
}
|
||||
|
||||
int EffectRack::GetEffectIndex(wxWindow *win)
|
||||
{
|
||||
int col = (win->GetId() - ID_BASE) / ID_RANGE;
|
||||
int row;
|
||||
int cnt = mMainSizer->GetChildren().GetCount() / NUMCOLS;
|
||||
for (row = 0; row < cnt; row++)
|
||||
{
|
||||
wxSizerItem *si = mMainSizer->GetItem((row * NUMCOLS) + col);
|
||||
if (si->GetWindow() == win)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (row == cnt)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
void EffectRack::MoveRowUp(int row)
|
||||
{
|
||||
Effect *effect = mEffects[row];
|
||||
mEffects.erase(mEffects.begin() + row);
|
||||
mEffects.insert(mEffects.begin() + row - 1, effect);
|
||||
|
||||
int state = mPowerState[row];
|
||||
mPowerState.erase(mPowerState.begin() + row);
|
||||
mPowerState.insert(mPowerState.begin() + row - 1, state);
|
||||
|
||||
state = mFavState[row];
|
||||
mFavState.erase(mFavState.begin() + row);
|
||||
mFavState.insert(mFavState.begin() + row - 1, state);
|
||||
|
||||
row *= NUMCOLS;
|
||||
|
||||
for (int i = 0; i < NUMCOLS; i++)
|
||||
{
|
||||
wxSizerItem *si = mMainSizer->GetItem(row + NUMCOLS - 1);
|
||||
wxWindow *w = si->GetWindow();
|
||||
int flags = si->GetFlag();
|
||||
int border = si->GetBorder();
|
||||
int prop = si->GetProportion();
|
||||
mMainSizer->Detach(row + NUMCOLS - 1);
|
||||
mMainSizer->Insert(row - NUMCOLS, w, prop, flags, border);
|
||||
}
|
||||
|
||||
mMainSizer->Layout();
|
||||
Refresh();
|
||||
|
||||
UpdateActive();
|
||||
}
|
||||
|
||||
void EffectRack::UpdateActive()
|
||||
{
|
||||
mActive.clear();
|
||||
|
||||
if (!mBypassing)
|
||||
{
|
||||
for (size_t i = 0, cnt = mEffects.size(); i < cnt; i++)
|
||||
{
|
||||
if (mPowerState[i])
|
||||
{
|
||||
mActive.push_back(mEffects[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RealtimeEffectManager::Get().RealtimeSetEffects(
|
||||
{ mActive.begin(), mActive.end() }
|
||||
);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
AudacityProject::AttachedWindows::RegisteredFactory sKey{
|
||||
[]( AudacityProject &parent ) -> wxWeakRef< wxWindow > {
|
||||
auto result = safenew EffectRack( parent );
|
||||
result->CenterOnParent();
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
EffectRack &EffectRack::Get( AudacityProject &project )
|
||||
{
|
||||
return project.AttachedWindows::Get< EffectRack >( sKey );
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user