Audacity 3.2.0
Public Member Functions | Private Attributes | List of all members
RealtimeEffectListWindow Class Reference
Inheritance diagram for RealtimeEffectListWindow:
[legend]
Collaboration diagram for RealtimeEffectListWindow:
[legend]

Public Member Functions

 RealtimeEffectListWindow (wxWindow *parent, wxWindowID winid=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxScrolledWindowStyle, const wxString &name=wxPanelNameStr)
 
void SetFooter (wxWindow *footer)
 
void OnEffectListItemChange (const RealtimeEffectListMessage &msg)
 
void ResetDelegate ()
 
void SetDelegate (AudacityProject &project, const std::shared_ptr< EffectListUIDelegate > &delegate)
 
void EnableEffects (bool enable)
 
void ReloadEffectsList ()
 
void OnAddEffectClicked (const wxCommandEvent &event)
 
void InsertEffectRow (size_t index, const std::shared_ptr< RealtimeEffectState > &pState)
 

Private Attributes

wxWeakRef< AudacityProjectmProject
 
AButtonmAddEffect {nullptr}
 
wxWindow * mEffectListContainer {nullptr}
 
wxWindow * mFooter {nullptr}
 
std::shared_ptr< EffectListUIDelegate > mDelegate
 
Observer::Subscription mEffectListItemMovedSubscription
 

Detailed Description

Definition at line 761 of file RealtimeEffectPanel.cpp.

Constructor & Destructor Documentation

◆ RealtimeEffectListWindow()

RealtimeEffectListWindow::RealtimeEffectListWindow ( wxWindow *  parent,
wxWindowID  winid = wxID_ANY,
const wxPoint &  pos = wxDefaultPosition,
const wxSize &  size = wxDefaultSize,
long  style = wxScrolledWindowStyle,
const wxString &  name = wxPanelNameStr 
)
inline

i18n-hint: undo history record first parameter - realtime effect name second parameter - track name

i18n-hint: undo history record first parameter - realtime effect name second parameter - track name

Definition at line 774 of file RealtimeEffectPanel.cpp.

780 : wxScrolledWindow(parent, winid, pos, size, style, name)
781 {
782#ifdef __WXMSW__
783 //Fixes flickering on redraw
784 wxScrolledWindow::SetDoubleBuffered(true);
785#endif
786 auto rootSizer = std::make_unique<wxBoxSizer>(wxVERTICAL);
787
788 auto effectListContainer = safenew ThemedWindowWrapper<wxPanel>(this, wxID_ANY);
789 effectListContainer->SetBackgroundColorIndex(clrMedium);
790 effectListContainer->SetSizer(safenew wxBoxSizer(wxVERTICAL));
791 effectListContainer->SetDoubleBuffered(true);
792 effectListContainer->Hide();
793 mEffectListContainer = effectListContainer;
794
795 auto addEffect = safenew ThemedAButtonWrapper<AButton>(this, wxID_ANY);
796 addEffect->SetImageIndices(0,
797 bmpHButtonNormal,
798 bmpHButtonHover,
799 bmpHButtonDown,
800 bmpHButtonHover,
801 bmpHButtonDisabled);
802 addEffect->SetTranslatableLabel(XO("Add effect"));
803 addEffect->SetButtonType(AButton::TextButton);
804 addEffect->SetBackgroundColorIndex(clrMedium);
805 addEffect->SetForegroundColorIndex(clrTrackPanelText);
806 addEffect->Bind(wxEVT_BUTTON, &RealtimeEffectListWindow::OnAddEffectClicked, this);
807 mAddEffect = addEffect;
808
809 //indicates the insertion position of the item
810 auto dropHintLine = safenew ThemedWindowWrapper<DropHintLine>(effectListContainer, wxID_ANY);
811 dropHintLine->SetBackgroundColorIndex(clrDropHintHighlight);
812 dropHintLine->Hide();
813
814 rootSizer->Add(mEffectListContainer, 0, wxEXPAND | wxBOTTOM, 10);
815 rootSizer->Add(addEffect, 0, wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, 20);
816
817 SetSizer(rootSizer.release());
818 SetMinSize({});
819
820 Bind(EVT_MOVABLE_CONTROL_DRAG_STARTED, [dropHintLine](const MovableControlEvent& event)
821 {
822 if(auto window = dynamic_cast<wxWindow*>(event.GetEventObject()))
823 window->Raise();
824 });
825 Bind(EVT_MOVABLE_CONTROL_DRAG_POSITION, [this, dropHintLine](const MovableControlEvent& event)
826 {
827 constexpr auto DropHintLineHeight { 3 };//px
828
829 auto sizer = mEffectListContainer->GetSizer();
830 assert(sizer != nullptr);
831
832 if(event.GetSourceIndex() == event.GetTargetIndex())
833 {
834 //do not display hint line if position didn't change
835 dropHintLine->Hide();
836 return;
837 }
838
839 if(!dropHintLine->IsShown())
840 {
841 dropHintLine->Show();
842 dropHintLine->Raise();
843 if(auto window = dynamic_cast<wxWindow*>(event.GetEventObject()))
844 window->Raise();
845 }
846
847 auto item = sizer->GetItem(event.GetTargetIndex());
848 dropHintLine->SetSize(item->GetSize().x, DropHintLineHeight);
849
850 if(event.GetTargetIndex() > event.GetSourceIndex())
851 dropHintLine->SetPosition(item->GetRect().GetBottomLeft() - wxPoint(0, DropHintLineHeight));
852 else
853 dropHintLine->SetPosition(item->GetRect().GetTopLeft());
854 });
855
856 Bind(EVT_MOVABLE_CONTROL_DRAG_FINISHED, [this, dropHintLine](const MovableControlEvent& event)
857 {
858 dropHintLine->Hide();
859
860 if(!mDelegate || !mProject)
861 return;
862
863 const auto from = event.GetSourceIndex();
864 const auto to = event.GetTargetIndex();
865 if(from != to)
866 {
867 auto& effectList = mDelegate->GetEffectList();
868 auto effectName =
869 effectList.GetStateAt(from)->GetEffect()->GetName();
870 bool up = (to < from);
871 effectList.MoveEffect(from, to);
873 (up
878 ? XO("Moved %s up in %s")
883 : XO("Moved %s down in %s"))
884 .Format(effectName, mDelegate->GetSourceName()),
885 XO("Change effect order"), UndoPush::CONSOLIDATE);
886 }
887 else
888 {
889 wxWindowUpdateLocker freeze(this);
890 Layout();
891 }
892 });
893
894 SetScrollRate(0, 20);
895#if defined(__WXMSW__) || defined(__WXMAC__)
896#endif
897 }
const TranslatableString name
Definition: Distortion.cpp:76
XO("Cut/Copy/Paste")
#define safenew
Definition: MemoryX.h:10
@ TextButton
Definition: AButton.h:112
Abstract base class used in importing a file.
int GetSourceIndex() const noexcept
int GetTargetIndex() const noexcept
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
static ProjectHistory & Get(AudacityProject &project)
void OnAddEffectClicked(const wxCommandEvent &event)
std::shared_ptr< EffectListUIDelegate > mDelegate
wxWeakRef< AudacityProject > mProject

References CONSOLIDATE, ProjectHistory::Get(), MovableControlEvent::GetSourceIndex(), MovableControlEvent::GetTargetIndex(), mAddEffect, mDelegate, mEffectListContainer, mProject, OnAddEffectClicked(), ProjectHistory::PushState(), safenew, AButton::TextButton, and XO().

Here is the call graph for this function:

Member Function Documentation

◆ EnableEffects()

void RealtimeEffectListWindow::EnableEffects ( bool  enable)
inline

Definition at line 1011 of file RealtimeEffectPanel.cpp.

1012 {
1013 if (mDelegate)
1014 mDelegate->GetEffectList().SetActive(enable);
1015 }

References mDelegate.

Referenced by RealtimeEffectPanel::MakeMasterEffectPane(), and RealtimeEffectPanel::MakeTrackEffectPane().

Here is the caller graph for this function:

◆ InsertEffectRow()

void RealtimeEffectListWindow::InsertEffectRow ( size_t  index,
const std::shared_ptr< RealtimeEffectState > &  pState 
)
inline

Definition at line 1090 of file RealtimeEffectPanel.cpp.

1092 {
1093 if(!mDelegate || !mProject)
1094 return;
1095
1096 // See comment in ReloadEffectsList
1097 if(!mEffectListContainer->IsShown())
1098 mEffectListContainer->Show();
1099
1101 row->SetBackgroundColorIndex(clrEffectListItemBackground);
1102 row->SetEffect(*mProject, mDelegate, pState);
1103 mEffectListContainer->GetSizer()->Insert(index, row, 0, wxEXPAND);
1104 }

References mDelegate, mEffectListContainer, mProject, and safenew.

Referenced by OnEffectListItemChange(), and ReloadEffectsList().

Here is the caller graph for this function:

◆ OnAddEffectClicked()

void RealtimeEffectListWindow::OnAddEffectClicked ( const wxCommandEvent &  event)
inline

i18n-hint: undo history record first parameter - realtime effect name second parameter - track name

Definition at line 1047 of file RealtimeEffectPanel.cpp.

1048 {
1049 if(!mDelegate || !mProject)
1050 return;
1051
1052 const auto effectId = EffectsMenuHelper::PickEffect(
1053 *mProject,
1054 dynamic_cast<wxWindow*>(event.GetEventObject()),
1055 {}
1056 );
1057
1058 if(!effectId || effectId->empty())
1059 return;
1060
1061 auto plug = PluginManager::Get().GetPlugin(*effectId);
1062 if(!plug)
1063 return;
1064
1067 XO("This plugin could not be loaded.\nIt may have been deleted."),
1069 .Caption(XO("Plugin Error")));
1070
1071 return;
1072 }
1073
1074 if(const auto state = AudioIO::Get()->AddState(*mProject, mDelegate->GetChannelGroup(), *effectId))
1075 {
1076 auto effect = state->GetEffect();
1077 assert(effect); // postcondition of AddState
1078 const auto effectName = effect->GetName();
1079 ProjectHistory::Get(*mProject).PushState(
1084 XO("Added %s to %s").Format(effectName, mDelegate->GetSourceName()),
1085 //i18n-hint: undo history record
1086 XO("Add %s").Format(effectName));
1087 }
1088 }
static AudioIO * Get()
Definition: AudioIO.cpp:126
static bool IsPluginAvailable(const PluginDescriptor &plug)
const PluginDescriptor * GetPlugin(const PluginID &ID) const
static PluginManager & Get()
MessageBoxResult ShowMessageBox(const TranslatableString &message, MessageBoxOptions options={})
Show a modal message box with either Ok or Yes and No, and optionally Cancel.
Definition: BasicUI.h:287

References AudioIO::Get(), PluginManager::Get(), ProjectHistory::Get(), PluginManager::GetPlugin(), PluginManager::IsPluginAvailable(), mDelegate, mProject, ProjectHistory::PushState(), BasicUI::ShowMessageBox(), and XO().

Referenced by RealtimeEffectListWindow().

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

◆ OnEffectListItemChange()

void RealtimeEffectListWindow::OnEffectListItemChange ( const RealtimeEffectListMessage msg)
inline

Definition at line 916 of file RealtimeEffectPanel.cpp.

917 {
918 auto sizer = mEffectListContainer->GetSizer();
919 const auto insertItem = [this, &msg](){
920 auto& effects = mDelegate->GetEffectList();
921 InsertEffectRow(msg.srcIndex, effects.GetStateAt(msg.srcIndex));
922 if(mFooter != nullptr)
923 mFooter->Hide();
924 };
925 const auto removeItem = [&](){
927 // Don't need to auto-save changed settings of effect that is deleted
928 // Undo history push will do it anyway
929 ui.Hide();
930
931 auto window = sizer->GetItem(msg.srcIndex)->GetWindow();
932 sizer->Remove(msg.srcIndex);
933 wxTheApp->CallAfter([ref = wxWeakRef { window }] {
934 if(ref) ref->Destroy();
935 });
936
937 if(sizer->IsEmpty())
938 {
939 if(mEffectListContainer->IsDescendant(FindFocus()))
940 mAddEffect->SetFocus();
941
942 mEffectListContainer->Hide();
943 if(mFooter != nullptr)
944 mFooter->Show();
945 }
946 };
947
948 wxWindowUpdateLocker freeze(this);
950 {
951 const auto sizer = mEffectListContainer->GetSizer();
952
953 const auto movedItem = sizer->GetItem(msg.srcIndex);
954
955 const auto proportion = movedItem->GetProportion();
956 const auto flag = movedItem->GetFlag();
957 const auto border = movedItem->GetBorder();
958 const auto window = movedItem->GetWindow();
959
960 if(msg.srcIndex < msg.dstIndex)
961 window->MoveAfterInTabOrder(sizer->GetItem(msg.dstIndex)->GetWindow());
962 else
963 window->MoveBeforeInTabOrder(sizer->GetItem(msg.dstIndex)->GetWindow());
964
965 sizer->Remove(msg.srcIndex);
966 sizer->Insert(msg.dstIndex, window, proportion, flag, border);
967 }
969 {
970 insertItem();
971 }
973 {
974 removeItem();
975 }
977 {
978 insertItem();
979 }
981 {
982 removeItem();
983 }
984 SendSizeEventToParent();
985 }
static std::once_flag flag
void InsertEffectRow(size_t index, const std::shared_ptr< RealtimeEffectState > &pState)
static RealtimeEffectStateUI & Get(RealtimeEffectState &state)
std::unique_ptr< WindowPlacement > FindFocus()
Find the window that is accepting keyboard input, if any.
Definition: BasicUI.h:383
@ Remove
Effect item was removed from the list at srcIndex position. affectedState is removed state.
@ DidReplace
Effect item was replaced with a new item at srcIndex position. affectedState is an old state.
@ Move
Item position has changed, from srcIndex to dstIndex. affectedState is the moved state.
@ Insert
New effect item was added to the list at srcIndex position. affectedState is a new state.
@ WillReplace
Effect item will be replaced with a new item at srcIndex position. affectedState is the state to be r...
std::shared_ptr< RealtimeEffectState > affectedState

References RealtimeEffectListMessage::affectedState, RealtimeEffectListMessage::DidReplace, RealtimeEffectListMessage::dstIndex, BasicUI::FindFocus(), flag, RealtimeEffectStateUI::Get(), RealtimeEffectListMessage::Insert, InsertEffectRow(), mAddEffect, mDelegate, mEffectListContainer, mFooter, RealtimeEffectListMessage::Move, RealtimeEffectListMessage::Remove, RealtimeEffectListMessage::srcIndex, RealtimeEffectListMessage::type, and RealtimeEffectListMessage::WillReplace.

Referenced by SetDelegate().

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

◆ ReloadEffectsList()

void RealtimeEffectListWindow::ReloadEffectsList ( )
inline

Definition at line 1017 of file RealtimeEffectPanel.cpp.

1018 {
1019 wxWindowUpdateLocker freeze(this);
1020
1021 //delete items that were added to the sizer
1022 mEffectListContainer->Hide();
1023 mEffectListContainer->GetSizer()->Clear(true);
1024
1025
1026 if(!mDelegate || mDelegate->GetEffectList().GetStatesCount() == 0)
1027 mEffectListContainer->Hide();
1028
1029 auto isEmpty{true};
1030 if(mDelegate)
1031 {
1032 auto& effects = mDelegate->GetEffectList();
1033 isEmpty = effects.GetStatesCount() == 0;
1034 for(size_t i = 0, count = effects.GetStatesCount(); i < count; ++i)
1035 InsertEffectRow(i, effects.GetStateAt(i));
1036 }
1038 //Workaround for GTK: Underlying GTK widget does not update
1039 //its size when wxWindow size is set to zero
1040 mEffectListContainer->Show(!isEmpty);
1041 if(mFooter != nullptr)
1042 mFooter->Show(isEmpty);
1043
1044 SendSizeEventToParent();
1045 }
void SetEnabled(bool state)
Definition: AButton.h:200

References InsertEffectRow(), mAddEffect, mDelegate, mEffectListContainer, mFooter, and AButton::SetEnabled().

Referenced by ResetDelegate(), and SetDelegate().

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

◆ ResetDelegate()

void RealtimeEffectListWindow::ResetDelegate ( )
inline

Definition at line 987 of file RealtimeEffectPanel.cpp.

988 {
990
991 mProject.Release();
992 mDelegate.reset();
994 }
void Reset() noexcept
Breaks the connection (constant time)
Definition: Observer.cpp:101
Observer::Subscription mEffectListItemMovedSubscription

References mDelegate, mEffectListItemMovedSubscription, mProject, ReloadEffectsList(), and Observer::Subscription::Reset().

Referenced by RealtimeEffectPanel::ResetTrack().

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

◆ SetDelegate()

void RealtimeEffectListWindow::SetDelegate ( AudacityProject project,
const std::shared_ptr< EffectListUIDelegate > &  delegate 
)
inline

Definition at line 996 of file RealtimeEffectPanel.cpp.

997 {
999
1000 mProject = &project;
1001 mDelegate = delegate;
1003
1004 if (mDelegate)
1005 {
1006 mEffectListItemMovedSubscription = mDelegate->GetEffectList().Subscribe(
1008 }
1009 }
const auto project
void OnEffectListItemChange(const RealtimeEffectListMessage &msg)

References mDelegate, mEffectListItemMovedSubscription, mProject, OnEffectListItemChange(), project, ReloadEffectsList(), and Observer::Subscription::Reset().

Referenced by RealtimeEffectPanel::RealtimeEffectPanel(), and RealtimeEffectPanel::SetTrack().

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

◆ SetFooter()

void RealtimeEffectListWindow::SetFooter ( wxWindow *  footer)
inline

Definition at line 899 of file RealtimeEffectPanel.cpp.

900 {
901 if(footer == mFooter)
902 return;
903
904 if(mFooter != nullptr)
905 {
906 GetSizer()->Detach(mFooter);
907 mFooter->Destroy();
908 }
909
910 mFooter = footer;
911 GetSizer()->Add(mFooter, 0, wxEXPAND);
912
913 Layout();
914 }

References mFooter.

Member Data Documentation

◆ mAddEffect

AButton* RealtimeEffectListWindow::mAddEffect {nullptr}
private

◆ mDelegate

std::shared_ptr<EffectListUIDelegate> RealtimeEffectListWindow::mDelegate
private

◆ mEffectListContainer

wxWindow* RealtimeEffectListWindow::mEffectListContainer {nullptr}
private

◆ mEffectListItemMovedSubscription

Observer::Subscription RealtimeEffectListWindow::mEffectListItemMovedSubscription
private

Definition at line 771 of file RealtimeEffectPanel.cpp.

Referenced by ResetDelegate(), and SetDelegate().

◆ mFooter

wxWindow* RealtimeEffectListWindow::mFooter {nullptr}
private

Definition at line 767 of file RealtimeEffectPanel.cpp.

Referenced by OnEffectListItemChange(), ReloadEffectsList(), and SetFooter().

◆ mProject

wxWeakRef<AudacityProject> RealtimeEffectListWindow::mProject
private

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