Audacity  2.2.2
TrackControls.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3 Audacity: A Digital Audio Editor
4 
5 TrackControls.cpp
6 
7 Paul Licameli split from TrackPanel.cpp
8 
9 **********************************************************************/
10 
11 #include "../../Audacity.h"
12 #include "TrackControls.h"
13 #include "TrackButtonHandles.h"
14 #include "TrackSelectHandle.h"
15 #include "../../HitTestResult.h"
16 #include "../../RefreshCode.h"
17 #include "../../MixerBoard.h"
18 #include "../../Project.h"
19 #include "../../TrackPanel.h" // for TrackInfo
20 #include "../../TrackPanelMouseEvent.h"
21 #include "../../Track.h"
22 #include <wx/textdlg.h>
23 #include "../../commands/CommandType.h"
24 #include "../../commands/Command.h"
25 #include "../../ShuttleGui.h"
26 
27 
28 TrackControls::TrackControls( std::shared_ptr<Track> pTrack )
29  : mwTrack{ pTrack }
30 {
31 }
32 
34 {
35 }
36 
37 std::shared_ptr<Track> TrackControls::FindTrack()
38 {
39  return mwTrack.lock();
40 }
41 
42 std::vector<UIHandlePtr> TrackControls::HitTest
44  const AudacityProject *WXUNUSED(project))
45 {
46  // Hits are mutually exclusive, results single
47 
48  const wxMouseState &state = st.state;
49  const wxRect &rect = st.rect;
50  UIHandlePtr result;
51  std::vector<UIHandlePtr> results;
52 
53  auto pTrack = FindTrack();
54  // shared pointer to this:
55  auto sThis = pTrack->GetTrackControl();
56 
57  if (NULL != (result = CloseButtonHandle::HitTest(
58  mCloseHandle, state, rect, this)))
59  results.push_back(result);
60 
61  if (NULL != (result = MenuButtonHandle::HitTest(
62  mMenuHandle, state, rect, sThis)))
63  results.push_back(result);
64 
65  if (NULL != (result = MinimizeButtonHandle::HitTest(
66  mMinimizeHandle, state, rect, this)))
67  results.push_back(result);
68 
69  if (results.empty()) {
70  if (NULL != (result = TrackSelectHandle::HitAnywhere(
71  mSelectHandle, pTrack)))
72  results.push_back(result);
73  }
74 
75  return results;
76 }
77 
78 enum
79 {
80  OnSetNameID = 2000,
85 };
86 
88 {
89  TrackMenuTable() : mpData(NULL) {}
91 
92 public:
93  static TrackMenuTable &Instance();
94 
95 private:
96  void OnSetName(wxCommandEvent &);
97  void OnMoveTrack(wxCommandEvent &event);
98 
99  void InitMenu(Menu *pMenu, void *pUserData) override;
100 
101  void DestroyMenu() override
102  {
103  mpData = nullptr;
104  }
105 
107 };
108 
110 {
111  static TrackMenuTable instance;
112  return instance;
113 }
114 
115 void TrackMenuTable::InitMenu(Menu *pMenu, void *pUserData)
116 {
117  mpData = static_cast<TrackControls::InitMenuData*>(pUserData);
118  Track *const pTrack = mpData->pTrack;
119 
120  TrackList *const tracks = GetActiveProject()->GetTracks();
121 
122  pMenu->Enable(OnMoveUpID, tracks->CanMoveUp(pTrack));
123  pMenu->Enable(OnMoveDownID, tracks->CanMoveDown(pTrack));
124  pMenu->Enable(OnMoveTopID, tracks->CanMoveUp(pTrack));
125  pMenu->Enable(OnMoveBottomID, tracks->CanMoveDown(pTrack));
126 }
127 
129  POPUP_MENU_ITEM(OnSetNameID, _("&Name..."), OnSetName)
132  // It is not correct to use NormalizedKeyString::Display here --
133  // wxWidgets will apply its equivalent to the key names passed to menu
134  // functions.
135  OnMoveUpID,
136  _("Move Track &Up") + wxT("\t") +
137  (GetActiveProject()->GetCommandManager()->
138  GetKeyFromName(wxT("TrackMoveUp")).Raw()),
139  OnMoveTrack)
141  OnMoveDownID,
142  _("Move Track &Down") + wxT("\t") +
143  (GetActiveProject()->GetCommandManager()->
144  GetKeyFromName(wxT("TrackMoveDown")).Raw()),
145  OnMoveTrack)
147  OnMoveTopID,
148  _("Move Track to &Top") + wxT("\t") +
149  (GetActiveProject()->GetCommandManager()->
150  GetKeyFromName(wxT("TrackMoveTop")).Raw()),
151  OnMoveTrack)
154  _("Move Track to &Bottom") + wxT("\t") +
155  (GetActiveProject()->GetCommandManager()->
156  GetKeyFromName(wxT("TrackMoveBottom")).Raw()),
157  OnMoveTrack)
159 
160 
161 
162 
163 #define SET_TRACK_NAME_PLUGIN_SYMBOL IdentInterfaceSymbol{ XO("Set Track Name") }
164 
165 // An example of using an AudacityCommand simply to create a dialog.
166 // We can add additional functions later, if we want to make it
167 // available to scripting.
168 // However there is no reason to, as SetTrackStatus is already provided.
169 class SetTrackNameCommand : public AudacityCommand
170 {
171 public:
172  // CommandDefinitionInterface overrides
175  //wxString GetDescription() override {return _("Sets the track name.");};
176  //bool DefineParams( ShuttleParams & S ) override;
177  void PopulateOrExchange(ShuttleGui & S) override;
178  //bool Apply(const CommandContext & context) override;
179 
180  // Provide an override, if we want the help button.
181  // wxString ManualPage() override {return wxT("");};
182 public:
183  wxString mName;
184 };
185 
186 void SetTrackNameCommand::PopulateOrExchange(ShuttleGui & S)
187 {
188  S.AddSpace(0, 5);
189 
190  S.StartMultiColumn(2, wxALIGN_CENTER);
191  {
192  S.TieTextBox(_("Name:"),mName);
193  }
194  S.EndMultiColumn();
195 }
196 
197 void TrackMenuTable::OnSetName(wxCommandEvent &)
198 {
199  Track *const pTrack = mpData->pTrack;
200  if (pTrack)
201  {
202  AudacityProject *const proj = ::GetActiveProject();
203  const wxString oldName = pTrack->GetName();
204 
205  SetTrackNameCommand Command;
206  Command.mName = oldName;
207  // Bug 1837 : We need an OK/Cancel result if we are to enter a blank string.
208  bool bResult = Command.PromptUser( proj );
209  if (bResult)
210  {
211  wxString newName = Command.mName;
212  pTrack->SetName(newName);
213  // if we have a linked channel this name should change as well
214  // (otherwise sort by name and time will crash).
215  if (pTrack->GetLinked())
216  pTrack->GetLink()->SetName(newName);
217 
218  MixerBoard *const pMixerBoard = proj->GetMixerBoard();
219  auto pt = dynamic_cast<PlayableTrack*>(pTrack);
220  if (pt && pMixerBoard)
221  pMixerBoard->UpdateName(pt);
222 
223  proj->PushState(wxString::Format(_("Renamed '%s' to '%s'"),
224  oldName,
225  newName),
226  _("Name Change"));
227 
229  }
230  }
231 }
232 
233 void TrackMenuTable::OnMoveTrack(wxCommandEvent &event)
234 {
235  AudacityProject *const project = GetActiveProject();
237  switch (event.GetId()) {
238  default:
239  wxASSERT(false);
240  case OnMoveUpID:
241  choice = AudacityProject::OnMoveUpID; break;
242  case OnMoveDownID:
243  choice = AudacityProject::OnMoveDownID; break;
244  case OnMoveTopID:
245  choice = AudacityProject::OnMoveTopID; break;
246  case OnMoveBottomID:
247  choice = AudacityProject::OnMoveBottomID; break;
248  }
249 
250  project->MoveTrack(mpData->pTrack, choice);
251 
252  // MoveTrack already refreshed TrackPanel, which means repaint will happen.
253  // This is a harmless redundancy:
255 }
256 
258  (const wxRect &rect, wxWindow *pParent, wxPoint *)
259 {
260  wxRect buttonRect;
261  TrackInfo::GetTitleBarRect(rect, buttonRect);
262 
263  auto track = FindTrack();
264  if (!track)
266 
267  InitMenuData data{ track.get(), pParent, RefreshCode::RefreshNone };
268 
269  const auto pTable = &TrackMenuTable::Instance();
270  auto pMenu = PopupMenuTable::BuildMenu(pParent, pTable, &data);
271 
272  PopupMenuTable *const pExtension = GetMenuExtension(track.get());
273  if (pExtension)
274  pMenu->Extend(pExtension);
275 
276  pParent->PopupMenu
277  (pMenu.get(), buttonRect.x + 1, buttonRect.y + buttonRect.height + 1);
278 
279  return data.result;
280 }
#define POPUP_MENU_SEPARATOR()
void OnSetName(wxCommandEvent &)
virtual void PopulateOrExchange(ShuttleGui &WXUNUSED(S))
A list of TrackListNode items.
Definition: Track.h:619
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI...
Definition: ShuttleGui.h:409
bool CanMoveDown(Track *t) const
Definition: Track.cpp:1121
void InitMenu(Menu *pMenu, void *pUserData) override
TrackControls::InitMenuData * mpData
virtual std::vector< UIHandlePtr > HitTest(const TrackPanelMouseState &state, const AudacityProject *) override=0
void EndMultiColumn()
virtual ~TrackControls()=0
#define SET_TRACK_NAME_PLUGIN_SYMBOL
bool GetLinked() const
Definition: Track.h:279
void DestroyMenu() override
#define END_POPUP_MENU()
void MoveTrack(Track *target, MoveChoice choice)
Move a track up, down, to top or to bottom.
Definition: Menus.cpp:4191
static UIHandlePtr HitTest(std::weak_ptr< MenuButtonHandle > &holder, const wxMouseState &state, const wxRect &rect, const std::shared_ptr< TrackPanelCell > &pCell)
std::shared_ptr< Track > FindTrack() override
MixerBoard * GetMixerBoard()
Definition: Project.h:516
unsigned DoContextMenu(const wxRect &rect, wxWindow *pParent, wxPoint *pPosition) override
AudacityProject provides the main window, with tools and tracks contained within it.
Definition: Project.h:176
IdentInterfaceSymbol GetSymbol() override=0
bool CanMoveUp(Track *t) const
Definition: Track.cpp:1116
void StartMultiColumn(int nCols, int PositionFlags=wxALIGN_LEFT)
static UIHandlePtr HitTest(std::weak_ptr< CloseButtonHandle > &holder, const wxMouseState &state, const wxRect &rect, TrackPanelCell *pCell)
Fundamental data object of Audacity, placed in the TrackPanel. Classes derived form it include the Wa...
Definition: Track.h:102
TrackControls(std::shared_ptr< Track > pTrack)
static std::unique_ptr< Menu > BuildMenu(wxEvtHandler *pParent, PopupMenuTable *pTable, void *pUserData=NULL)
wxString GetName() const
Definition: Track.h:271
IdentInterfaceSymbol pairs a persistent string identifier used internally with an optional...
Base class for command in Audacity.
An AudioTrack that can be played and stopped.
Definition: Track.h:376
std::shared_ptr< UIHandle > UIHandlePtr
Definition: TrackPanel.h:59
static UIHandlePtr HitTest(std::weak_ptr< MinimizeButtonHandle > &holder, const wxMouseState &state, const wxRect &rect, TrackPanelCell *pCell)
static void GetTitleBarRect(const wxRect &rect, wxRect &dest)
void UpdateName(const PlayableTrack *pTrack)
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom")).Raw()), OnMoveTrack)#define SET_TRACK_NAME_PLUGIN_SYMBOLclass SetTrackNameCommand:public AudacityCommand
DECLARE_POPUP_MENU(TrackMenuTable)
void PushState(const wxString &desc, const wxString &shortDesc)
Definition: Project.cpp:4702
void SetName(const wxString &n)
Definition: Track.h:272
POPUP_MENU_ITEM(OnMoveUpID, _("Move Track &Up")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveUp")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveDownID
Track * GetLink() const
Definition: Track.cpp:269
AUDACITY_DLL_API AudacityProject * GetActiveProject()
Definition: Project.cpp:308
void OnMoveTrack(wxCommandEvent &event)
wxSizerItem * AddSpace(int width, int height)
static UIHandlePtr HitAnywhere(std::weak_ptr< TrackSelectHandle > &holder, const std::shared_ptr< Track > &pTrack)
TrackList * GetTracks()
Definition: Project.h:192
std::weak_ptr< Track > mwTrack
Definition: TrackControls.h:58
wxTextCtrl * TieTextBox(const wxString &Prompt, WrappedType &WrappedRef, const int nChars)
static TrackMenuTable & Instance()
BEGIN_POPUP_MENU(SpectrumVRulerMenuTable)