Audacity  3.0.3
LyricsWindow.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  LyricsWindow.cpp
6 
7  Vaughan Johnson
8  Dominic Mazzoni
9 
10 **********************************************************************/
11 
12 #include "LyricsWindow.h"
13 #include "Lyrics.h"
14 #include "AudioIO.h"
15 #include "CommonCommandFlags.h"
16 #include "prefs/GUISettings.h" // for RTL_WORKAROUND
17 #include "Project.h"
18 #include "ProjectAudioIO.h"
19 #include "ProjectFileIO.h"
20 #include "ProjectWindows.h"
21 #include "ViewInfo.h"
22 
23 #include <wx/app.h>
24 #include <wx/radiobut.h>
25 #include <wx/toolbar.h>
26 #include <wx/settings.h>
27 
28 #ifdef __WXMSW__
29  #include "../images/AudacityLogo.xpm"
30 #else
31  #include "../images/AudacityLogo48x48.xpm"
32 #endif
33 
34 #ifdef __WXMAC__
35  #include <Carbon/Carbon.h>
36 #endif
37 
38 #define AudacityKaraokeTitle XO("Audacity Karaoke%s")
39 
40 enum {
43 };
44 
45 BEGIN_EVENT_TABLE(LyricsWindow, wxFrame)
50 
52 
54  : wxFrame( &GetProjectFrame( *parent ), -1, wxString{},
55  wxPoint(100, 300), gSize,
56  //v Bug in wxFRAME_FLOAT_ON_PARENT:
57  // If both the project frame and LyricsWindow are minimized and you restore LyricsWindow,
58  // you can't restore project frame until you close LyricsWindow, but then project frame and
59  // LyricsWindow are restored but LyricsWindow is unresponsive because it thinks it's not shown.
60  // wxDEFAULT_FRAME_STYLE | wxFRAME_FLOAT_ON_PARENT)
61  wxDEFAULT_FRAME_STYLE)
62 {
63  //vvv Still necessary? It's commented out in ToolManager and Meter, so I did so here.
64  // #ifdef __WXMAC__
65  // // WXMAC doesn't support wxFRAME_FLOAT_ON_PARENT, so we do
66  // SetWindowClass((WindowRef) MacGetWindowRef(), kFloatingWindowClass);
67  // #endif
68  auto pProject = parent->shared_from_this();
69  mProject = pProject;
70 
71  SetWindowTitle();
72  auto titleChanged = [&](wxCommandEvent &evt)
73  {
74  SetWindowTitle();
75  evt.Skip();
76  };
77  wxTheApp->Bind( EVT_PROJECT_TITLE_CHANGE, titleChanged );
78 
79  // loads either the XPM or the windows resource, depending on the platform
80 #if !defined(__WXMAC__) && !defined(__WXX11__)
81  {
82 #ifdef __WXMSW__
83  wxIcon ic{ wxICON(AudacityLogo) };
84 #else
85  wxIcon ic{wxICON(AudacityLogo48x48)};
86 #endif
87  SetIcon(ic);
88  }
89  #endif
90 
91  wxPoint panelPos(0, 0);
92  wxSize panelSize = gSize;
93 
94  //vvv not yet working right in ported version, so choice is disabled.
95  // It seems when you select highlight style, the TrackPanel timer stops working, but
96  // going back to bouncing ball style starts it up again (!!!), per breakpoints in TrackPanel::OnTimer().
97  //
98  //wxToolBar* pToolBar = this->CreateToolBar();
99  //const int kHorizMargin = 8;
100  //wxASSERT(pToolBar); // To justify safenew
101  //wxRadioButton* pRadioButton_BouncingBall =
102  // safenew wxRadioButton(pToolBar, kID_RadioButton_BouncingBall, _("Bouncing Ball"), wxPoint(kHorizMargin, 4),
103  // wxDefaultSize, wxRB_GROUP);
105  //wxSize tbSize = pToolBar->GetSize();
106  //wxSize btnSize = pRadioButton_BouncingBall->GetSize();
107  //int top = (tbSize.GetHeight() - btnSize.GetHeight()) / 2;
108  //pRadioButton_BouncingBall->Move(kHorizMargin, top);
109  //pToolBar->AddControl(pRadioButton_BouncingBall);
110  //
111  //int left = kHorizMargin + btnSize.GetWidth() + kHorizMargin; //vvv Doesn't actually work. Probably need sizers.
112  //wxRadioButton* pRadioButton_Highlight =
113  // safenew wxRadioButton(pToolBar, kID_RadioButton_Highlight, _("Highlight"), wxPoint(left, top));
114  //pToolBar->AddControl(pRadioButton_Highlight);
115  //
116  //panelPos.x += tbSize.GetHeight();
117  //panelSize.y -= tbSize.GetHeight();
118  //
119  //#if defined(__WXMAC__)
120  // wxColour face = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
121  // pRadioButton_BouncingBall->SetBackgroundColour(face);
122  // pRadioButton_Highlight->SetBackgroundColour(face);
123  //#endif
124  //
125  //pToolBar->Realize();
126 
127  mLyricsPanel = safenew LyricsPanel(this, -1, parent, panelPos, panelSize);
128  RTL_WORKAROUND(mLyricsPanel);
129 
130  //vvv Highlight style is broken in ported version.
131  //switch (mLyricsPanel->GetLyricsStyle())
132  //{
133  // case LyricsPanel::kBouncingBallLyrics:
134  // pRadioButton_BouncingBall->SetValue(true); break;
135  // case LyricsPanel::kHighlightLyrics:
136  // default:
137  // pRadioButton_Highlight->SetValue(true); break;
138  //}
139 
140  // Events from the project don't propagate directly to this other frame, so...
141  pProject->Bind(EVT_TRACK_PANEL_TIMER,
143  this);
144  Center();
145 }
146 
147 void LyricsWindow::OnCloseWindow(wxCloseEvent & WXUNUSED(event))
148 {
149  this->Hide();
150 }
151 
152 void LyricsWindow::OnStyle_BouncingBall(wxCommandEvent & WXUNUSED(event))
153 {
155 }
156 
157 void LyricsWindow::OnStyle_Highlight(wxCommandEvent & WXUNUSED(event))
158 {
160 }
161 
162 void LyricsWindow::OnTimer(wxCommandEvent &event)
163 {
164  if (auto pProject = mProject.lock()) {
165  if (ProjectAudioIO::Get( *pProject ).IsAudioActive())
166  {
167  auto gAudioIO = AudioIO::Get();
168  GetLyricsPanel()->Update(gAudioIO->GetStreamTime());
169  }
170  else
171  {
172  // Reset lyrics display.
173  const auto &selectedRegion = ViewInfo::Get( *pProject ).selectedRegion;
174  GetLyricsPanel()->Update(selectedRegion.t0());
175  }
176  }
177 
178  // Let other listeners get the notification
179  event.Skip();
180 }
181 
183 {
184  wxString name;
185  if (auto pProject = mProject.lock()) {
186  name = pProject->GetProjectName();
187  if (!name.empty())
188  name.Prepend(wxT(" - "));
189  }
190 
191  SetTitle(AudacityKaraokeTitle.Format(name).Translation());
192 }
193 
195 {
196  SetWindowTitle();
197 }
198 
199 // Remaining code hooks this add-on into the application
200 #include "commands/CommandContext.h"
201 #include "commands/CommandManager.h"
202 
203 namespace {
204 
205 // Lyrics window attached to each project is built on demand by:
206 AttachedWindows::RegisteredFactory sLyricsWindowKey{
207  []( AudacityProject &parent ) -> wxWeakRef< wxWindow > {
208  return safenew LyricsWindow( &parent );
209  }
210 };
211 
212 // Define our extra menu item that invokes that factory
214  void OnKaraoke(const CommandContext &context)
215  {
216  auto &project = context.project;
217 
218  auto lyricsWindow = &GetAttachedWindows(project).Get(sLyricsWindowKey);
219  lyricsWindow->Show();
220  lyricsWindow->Raise();
221  }
222 };
223 
225  // Handler is not stateful. Doesn't need a factory registered with
226  // AudacityProject.
227  static Handler instance;
228  return instance;
229 }
230 
231 // Register that menu item
232 
233 using namespace MenuTable;
234 AttachedItem sAttachment{ wxT("View/Windows"),
236  Command( wxT("Karaoke"), XXO("&Karaoke..."), &Handler::OnKaraoke,
238 };
239 
240 }
ViewInfo::Get
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:241
TranslatableString::empty
bool empty() const
Definition: TranslatableString.h:72
ProjectFileIO.h
MenuTable::FinderScope
Definition: CommandManager.h:485
anonymous_namespace{LyricsWindow.cpp}::Handler::OnKaraoke
void OnKaraoke(const CommandContext &context)
Definition: LyricsWindow.cpp:214
Project.h
kID_RadioButton_Highlight
@ kID_RadioButton_Highlight
Definition: LyricsWindow.cpp:42
ClientData::Site::Get
Subclass & Get(const RegisteredFactory &key)
Get reference to an attachment, creating on demand if not present, down-cast it to Subclass.
Definition: ClientData.h:309
anonymous_namespace{LyricsWindow.cpp}::Handler
Definition: LyricsWindow.cpp:213
LyricsWindow
Definition: LyricsWindow.h:25
CommandManager.h
LabelTracksExistFlag
const ReservedCommandFlag & LabelTracksExistFlag()
Definition: CommonCommandFlags.cpp:224
LyricsWindow::OnStyle_BouncingBall
void OnStyle_BouncingBall(wxCommandEvent &evt)
Definition: LyricsWindow.cpp:152
anonymous_namespace{LyricsWindow.cpp}::sLyricsWindowKey
AttachedWindows::RegisteredFactory sLyricsWindowKey
Definition: LyricsWindow.cpp:206
MenuTable::AttachedItem
Definition: CommandManager.h:708
ProjectAudioIO::Get
static ProjectAudioIO & Get(AudacityProject &project)
Definition: ProjectAudioIO.cpp:22
ProjectAudioIO::IsAudioActive
bool IsAudioActive() const
Definition: ProjectAudioIO.cpp:51
LyricsWindow::OnStyle_Highlight
void OnStyle_Highlight(wxCommandEvent &evt)
Definition: LyricsWindow.cpp:157
LyricsPanel::SetLyricsStyle
void SetLyricsStyle(const LyricsStyle newLyricsStyle)
Definition: Lyrics.cpp:249
LYRICS_DEFAULT_WIDTH
#define LYRICS_DEFAULT_WIDTH
Definition: Lyrics.h:26
anonymous_namespace{LyricsWindow.cpp}::findCommandHandler
CommandHandlerObject & findCommandHandler(AudacityProject &)
Definition: LyricsWindow.cpp:224
CommandContext.h
kID_RadioButton_BouncingBall
@ kID_RadioButton_BouncingBall
Definition: LyricsWindow.cpp:41
ViewInfo::selectedRegion
NotifyingSelectedRegion selectedRegion
Definition: ViewInfo.h:229
XXO
#define XXO(s)
Definition: Internat.h:44
LyricsPanel::kHighlightLyrics
@ kHighlightLyrics
Definition: Lyrics.h:84
LyricsWindow::mLyricsPanel
LyricsPanel * mLyricsPanel
Definition: LyricsWindow.h:45
CommandContext
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
Definition: CommandContext.h:34
LyricsPanel::kBouncingBallLyrics
@ kBouncingBallLyrics
Definition: Lyrics.h:82
GetAttachedWindows
AUDACITY_DLL_API AttachedWindows & GetAttachedWindows(AudacityProject &project)
Definition: ProjectWindows.cpp:114
LyricsWindow::SetWindowTitle
void SetWindowTitle()
Definition: LyricsWindow.cpp:182
LyricsWindow::GetLyricsPanel
LyricsPanel * GetLyricsPanel()
Definition: LyricsWindow.h:30
name
const TranslatableString name
Definition: Distortion.cpp:98
LYRICS_DEFAULT_HEIGHT
#define LYRICS_DEFAULT_HEIGHT
Definition: Lyrics.h:27
ViewInfo.h
LyricsWindow::mProject
std::weak_ptr< AudacityProject > mProject
Definition: LyricsWindow.h:44
ProjectWindows.h
accessors for certain important windows associated with each project
GUISettings.h
LyricsPanel
LyricsPanel is a panel that paints the bouncing ball and the lyrics text.
Definition: Lyrics.h:78
MenuTable::Command
std::unique_ptr< CommandItem > Command(const CommandID &name, const TranslatableString &label_in, void(Handler::*pmf)(const CommandContext &), CommandFlag flags, const CommandManager::Options &options={}, CommandHandlerFinder finder=FinderScope::DefaultFinder())
Definition: CommandManager.h:675
AudioIO.h
AudacityProject
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:92
anonymous_namespace{LyricsWindow.cpp}::sAttachment
AttachedItem sAttachment
Definition: LyricsWindow.cpp:234
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: ProjectWindows.cpp:72
AudacityKaraokeTitle
#define AudacityKaraokeTitle
Definition: LyricsWindow.cpp:38
CommandHandlerObject
wxEvtHandler CommandHandlerObject
Definition: CommandFunctors.h:28
RTL_WORKAROUND
#define RTL_WORKAROUND(pWnd)
Definition: GUISettings.h:16
LyricsWindow::UpdatePrefs
void UpdatePrefs() override
Definition: LyricsWindow.cpp:194
LyricsWindow.h
LyricsPanel::Update
void Update(double t)
Definition: Lyrics.cpp:439
MenuTable
Definition: CommandManager.h:416
LyricsWindow::OnCloseWindow
void OnCloseWindow(wxCloseEvent &WXUNUSED(event))
Definition: LyricsWindow.cpp:147
AudioIO::Get
static AudioIO * Get()
Definition: AudioIO.cpp:141
safenew
#define safenew
Definition: MemoryX.h:10
gSize
const wxSize gSize
Definition: LyricsWindow.cpp:51
CommonCommandFlags.h
CommandContext::project
AudacityProject & project
Definition: CommandContext.h:64
END_EVENT_TABLE
END_EVENT_TABLE()
ProjectAudioIO.h
Lyrics.h
LyricsWindow::OnTimer
void OnTimer(wxCommandEvent &event)
Definition: LyricsWindow.cpp:162