diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 8fd2cb72d..1af586502 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -151,7 +151,6 @@ is time to refresh some aspect of the screen. *//*****************************************************************/ - #include "Audacity.h" #include "Experimental.h" #include "TrackPanel.h" @@ -291,14 +290,8 @@ template < class CLIPPEE, class CLIPVAL > enum { TrackPanelFirstID = 2000, - OnSetNameID, OnSetFontID, - OnMoveUpID, - OnMoveDownID, - OnMoveTopID, - OnMoveBottomID, - OnUpOctaveID, OnDownOctaveID, @@ -364,12 +357,9 @@ BEGIN_EVENT_TABLE(TrackPanel, OverlayPanel) EVT_SET_FOCUS(TrackPanel::OnSetFocus) EVT_KILL_FOCUS(TrackPanel::OnKillFocus) EVT_CONTEXT_MENU(TrackPanel::OnContextMenu) - EVT_MENU(OnSetNameID, TrackPanel::OnSetName) EVT_MENU(OnSetFontID, TrackPanel::OnSetFont) EVT_MENU(OnSetTimeTrackRangeID, TrackPanel::OnSetTimeTrackRange) - EVT_MENU_RANGE(OnMoveUpID, OnMoveDownID, TrackPanel::OnMoveTrack) - EVT_MENU_RANGE(OnMoveTopID, OnMoveBottomID, TrackPanel::OnMoveTrack) EVT_MENU_RANGE(OnUpOctaveID, OnDownOctaveID, TrackPanel::OnChangeOctave) EVT_MENU_RANGE(OnChannelLeftID, OnChannelMonoID, TrackPanel::OnChannelChange) @@ -630,7 +620,6 @@ void TrackPanel::BuildMenus(void) /* build the pop-down menu used on wave (sampled audio) tracks */ mWaveTrackMenu = std::make_unique(); - BuildCommonDropMenuItems(mWaveTrackMenu.get()); // does name, up/down etc mWaveTrackMenu->AppendRadioItem(OnWaveformID, _("Wa&veform")); mWaveTrackMenu->AppendRadioItem(OnWaveformDBID, _("&Waveform (dB)")); mWaveTrackMenu->AppendRadioItem(OnSpectrumID, _("&Spectrogram")); @@ -659,18 +648,15 @@ void TrackPanel::BuildMenus(void) /* build the pop-down menu used on note (MIDI) tracks */ mNoteTrackMenu = std::make_unique(); - BuildCommonDropMenuItems(mNoteTrackMenu.get()); // does name, up/down etc mNoteTrackMenu->Append(OnUpOctaveID, _("Up &Octave")); mNoteTrackMenu->Append(OnDownOctaveID, _("Down Octa&ve")); /* build the pop-down menu used on label tracks */ mLabelTrackMenu = std::make_unique(); - BuildCommonDropMenuItems(mLabelTrackMenu.get()); // does name, up/down etc mLabelTrackMenu->Append(OnSetFontID, _("&Font...")); /* build the pop-down menu used on time warping tracks */ mTimeTrackMenu = std::make_unique(); - BuildCommonDropMenuItems(mTimeTrackMenu.get()); // does name, up/down etc mTimeTrackMenu->AppendRadioItem(OnTimeTrackLinID, wxT("&Linear scale")); mTimeTrackMenu->AppendRadioItem(OnTimeTrackLogID, _("L&ogarithmic scale")); @@ -691,24 +677,6 @@ void TrackPanel::BuildMenus(void) */ } -void TrackPanel::BuildCommonDropMenuItems(wxMenu * menu) -{ - menu->Append(OnSetNameID, _("&Name...")); - menu->AppendSeparator(); - // It is not correct to use KeyStringDisplay here -- wxWidgets will apply - // its equivalent to the key names passed to menu functions. - menu->Append(OnMoveUpID, _("Move Track &Up") + wxT("\t") + - (GetProject()->GetCommandManager()->GetKeyFromName(wxT("TrackMoveUp")))); - menu->Append(OnMoveDownID, _("Move Track &Down") + wxT("\t") + - (GetProject()->GetCommandManager()->GetKeyFromName(wxT("TrackMoveDown")))); - menu->Append(OnMoveTopID, _("Move Track to &Top") + wxT("\t") + - (GetProject()->GetCommandManager()->GetKeyFromName(wxT("TrackMoveTop")))); - menu->Append(OnMoveBottomID, _("Move Track to &Bottom") + wxT("\t") + - (GetProject()->GetCommandManager()->GetKeyFromName(wxT("TrackMoveBottom")))); - menu->AppendSeparator(); - -} - /* // left over from PRL's vertical ruler context menu experiment in 2.1.2 // static @@ -6068,11 +6036,6 @@ void TrackPanel::OnTrackMenu(Track *t) } if (theMenu) { - theMenu->Enable(OnMoveUpID, mTracks->CanMoveUp(t)); - theMenu->Enable(OnMoveDownID, mTracks->CanMoveDown(t)); - theMenu->Enable(OnMoveTopID, mTracks->CanMoveUp(t)); - theMenu->Enable(OnMoveBottomID, mTracks->CanMoveDown(t)); - //We need to find the location of the menu rectangle. const wxRect rect = FindTrackRect(t,true); wxRect titleRect; @@ -6926,27 +6889,6 @@ void TrackPanel::OnZoomFitVertical(wxCommandEvent &) HandleWaveTrackVZoom(static_cast(mPopupMenuTarget), true, true); } -/// Move a track up, down, to top or to bottom. - -void TrackPanel::OnMoveTrack(wxCommandEvent &event) -{ - AudacityProject::MoveChoice choice; - switch (event.GetId()) { - default: - wxASSERT(false); - case OnMoveUpID: - choice = AudacityProject::OnMoveUpID; break; - case OnMoveDownID: - choice = AudacityProject::OnMoveDownID; break; - case OnMoveTopID: - choice = AudacityProject::OnMoveTopID; break; - case OnMoveBottomID: - choice = AudacityProject::OnMoveBottomID; break; - } - - GetProject()->MoveTrack(mPopupMenuTarget, choice); -} - /// This only applies to MIDI tracks. Presumably, it shifts the /// whole sequence by an octave. void TrackPanel::OnChangeOctave(wxCommandEvent & event) @@ -6965,38 +6907,6 @@ void TrackPanel::OnChangeOctave(wxCommandEvent & event) #endif } -void TrackPanel::OnSetName(wxCommandEvent & WXUNUSED(event)) -{ - Track *t = mPopupMenuTarget; - if (t) - { - wxString oldName = t->GetName(); - wxString newName = - wxGetTextFromUser(_("Change track name to:"), - _("Track Name"), oldName); - if (newName != wxT("")) // wxGetTextFromUser returns empty string on Cancel. - { - t->SetName(newName); - // if we have a linked channel this name should change as well - // (otherwise sort by name and time will crash). - if (t->GetLinked()) - t->GetLink()->SetName(newName); - - MixerBoard* pMixerBoard = this->GetMixerBoard(); - auto pt = dynamic_cast(t); - if (pMixerBoard && pt) - pMixerBoard->UpdateName(pt); - - MakeParentPushState(wxString::Format(_("Renamed '%s' to '%s'"), - oldName.c_str(), - newName.c_str()), - _("Name Change")); - - Refresh(false); - } - } -} - // Small helper class to enumerate all fonts in the system // We use this because the default implementation of // wxFontEnumerator::GetFacenames() has changed between wx2.6 and 2.8 diff --git a/src/TrackPanel.h b/src/TrackPanel.h index 051167a6c..2b1f5301d 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -340,14 +340,6 @@ class AUDACITY_DLL_API TrackPanel final : public OverlayPanel { protected: virtual MixerBoard* GetMixerBoard(); - /** @brief Populates the track pop-down menu with the common set of - * initial items. - * - * Ensures that all pop-down menus start with Name, and the commands for moving - * the track around, via a single set of c ode. - * @param menu the menu to add the commands to. - */ - virtual void BuildCommonDropMenuItems(wxMenu * menu); // left over from PRL's vertical ruler context menu experiment in 2.1.2 // static void BuildVRulerMenuItems(wxMenu * menu, int firstId, const wxArrayString &names); @@ -496,11 +488,9 @@ protected: UndoPush flags); virtual void MakeParentModifyState(bool bWantsAutoSave); // if true, writes auto-save file. Should set only if you really want the state change restored after // a crash, as it can take many seconds for large (eg. 10 track-hours) projects - virtual void OnSetName(wxCommandEvent &event); virtual void OnSetFont(wxCommandEvent &event); - virtual void OnMoveTrack (wxCommandEvent &event); virtual void OnChangeOctave (wxCommandEvent &event); virtual void OnChannelChange(wxCommandEvent &event); virtual void OnSpectrogramSettings(wxCommandEvent &event); diff --git a/src/tracks/ui/TrackControls.cpp b/src/tracks/ui/TrackControls.cpp index 076ac6482..deea704f2 100644 --- a/src/tracks/ui/TrackControls.cpp +++ b/src/tracks/ui/TrackControls.cpp @@ -13,8 +13,12 @@ Paul Licameli split from TrackPanel.cpp #include "TrackButtonHandles.h" #include "../../HitTestResult.h" #include "../../RefreshCode.h" +#include "../../MixerBoard.h" +#include "../../Project.h" #include "../../TrackPanel.h" #include "../../TrackPanelMouseEvent.h" +#include "../../WaveTrack.h" +#include int TrackControls::gCaptureState; @@ -47,6 +51,15 @@ Track *TrackControls::FindTrack() return GetTrack(); } +enum +{ + OnSetNameID = 2000, + OnMoveUpID, + OnMoveDownID, + OnMoveTopID, + OnMoveBottomID, +}; + class TrackMenuTable : public PopupMenuTable { TrackMenuTable() : mpData(NULL) {} @@ -56,11 +69,10 @@ public: static TrackMenuTable &Instance(); private: + void OnSetName(wxCommandEvent &); + void OnMoveTrack(wxCommandEvent &event); - void InitMenu(Menu*, void *pUserData) override - { - mpData = static_cast(pUserData); - } + void InitMenu(Menu *pMenu, void *pUserData) override; void DestroyMenu() override { @@ -76,9 +88,107 @@ TrackMenuTable &TrackMenuTable::Instance() return instance; } +void TrackMenuTable::InitMenu(Menu *pMenu, void *pUserData) +{ + mpData = static_cast(pUserData); + Track *const pTrack = mpData->pTrack; + + TrackList *const tracks = GetActiveProject()->GetTracks(); + + pMenu->Enable(OnMoveUpID, tracks->CanMoveUp(pTrack)); + pMenu->Enable(OnMoveDownID, tracks->CanMoveDown(pTrack)); + pMenu->Enable(OnMoveTopID, tracks->CanMoveUp(pTrack)); + pMenu->Enable(OnMoveBottomID, tracks->CanMoveDown(pTrack)); +} + BEGIN_POPUP_MENU(TrackMenuTable) + POPUP_MENU_ITEM(OnSetNameID, _("&Name..."), OnSetName) + POPUP_MENU_SEPARATOR() + POPUP_MENU_ITEM( + // It is not correct to use KeyStringDisplay here -- wxWidgets will apply + // its equivalent to the key names passed to menu functions. + OnMoveUpID, + _("Move Track &Up") + wxT("\t") + + (GetActiveProject()->GetCommandManager()-> + GetKeyFromName(wxT("TrackMoveUp"))), + OnMoveTrack) + POPUP_MENU_ITEM( + OnMoveDownID, + _("Move Track &Down") + wxT("\t") + + (GetActiveProject()->GetCommandManager()-> + GetKeyFromName(wxT("TrackMoveDown"))), + OnMoveTrack) + POPUP_MENU_ITEM( + OnMoveTopID, + _("Move Track to &Top") + wxT("\t") + + (GetActiveProject()->GetCommandManager()-> + GetKeyFromName(wxT("TrackMoveTop"))), + OnMoveTrack) + POPUP_MENU_ITEM( + OnMoveBottomID, + _("Move Track to &Bottom") + wxT("\t") + + (GetActiveProject()->GetCommandManager()-> + GetKeyFromName(wxT("TrackMoveBottom"))), + OnMoveTrack) END_POPUP_MENU() +void TrackMenuTable::OnSetName(wxCommandEvent &) +{ + Track *const pTrack = mpData->pTrack; + if (pTrack) + { + AudacityProject *const proj = ::GetActiveProject(); + const wxString oldName = pTrack->GetName(); + const wxString newName = + wxGetTextFromUser(_("Change track name to:"), + _("Track Name"), oldName); + if (newName != wxT("")) // wxGetTextFromUser returns empty string on Cancel. + { + pTrack->SetName(newName); + // if we have a linked channel this name should change as well + // (otherwise sort by name and time will crash). + if (pTrack->GetLinked()) + pTrack->GetLink()->SetName(newName); + + MixerBoard *const pMixerBoard = proj->GetMixerBoard(); + auto pt = dynamic_cast(pTrack); + if (pt && pMixerBoard) + pMixerBoard->UpdateName(pt); + + proj->PushState(wxString::Format(_("Renamed '%s' to '%s'"), + oldName.c_str(), + newName.c_str()), + _("Name Change")); + + mpData->result = RefreshCode::RefreshAll; + } + } +} + +void TrackMenuTable::OnMoveTrack(wxCommandEvent &event) +{ + AudacityProject *const project = GetActiveProject(); + AudacityProject::MoveChoice choice; + switch (event.GetId()) { + default: + wxASSERT(false); + case OnMoveUpID: + choice = AudacityProject::OnMoveUpID; break; + case OnMoveDownID: + choice = AudacityProject::OnMoveDownID; break; + case OnMoveTopID: + choice = AudacityProject::OnMoveTopID; break; + case OnMoveBottomID: + choice = AudacityProject::OnMoveBottomID; break; + } + + project->MoveTrack(mpData->pTrack, choice); + + // MoveTrack already refreshed TrackPanel, which means repaint will happen. + // This is a harmless redundancy: + mpData->result = RefreshCode::RefreshAll; +} + unsigned TrackControls::DoContextMenu (const wxRect &rect, wxWindow *pParent, wxPoint *) {