From 96d104cb38f083e0fbf9aba42d4aa50eba7469ed Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Sat, 17 Feb 2018 16:29:24 -0500 Subject: [PATCH] Lyrics panel listens; AudacityProject not responsible for updating it --- src/Lyrics.cpp | 65 ++++++++++++++++++++++++++++++++++++++++- src/Lyrics.h | 16 +++++++--- src/LyricsWindow.cpp | 3 +- src/Project.cpp | 38 ++---------------------- src/Project.h | 1 - src/menus/ViewMenus.cpp | 1 - 6 files changed, 79 insertions(+), 45 deletions(-) diff --git a/src/Lyrics.cpp b/src/Lyrics.cpp index d4a07f165..40c2eb664 100644 --- a/src/Lyrics.cpp +++ b/src/Lyrics.cpp @@ -15,11 +15,13 @@ #include #include +#include "AudioIO.h" #include "Lyrics.h" #include "Internat.h" #include "Project.h" // for GetActiveProject #include "LabelTrack.h" #include "commands/CommandManager.h" +#include "UndoManager.h" BEGIN_EVENT_TABLE(HighlightTextCtrl, wxTextCtrl) @@ -80,10 +82,12 @@ END_EVENT_TABLE() IMPLEMENT_CLASS(LyricsPanel, wxPanel) LyricsPanel::LyricsPanel(wxWindow* parent, wxWindowID id, + AudacityProject *project, const wxPoint& pos /*= wxDefaultPosition*/, - const wxSize& size /*= wxDefaultSize*/): + const wxSize& size /*= wxDefaultSize*/) : wxPanelWrapper(parent, id, pos, size, wxWANTS_CHARS), mWidth(size.x), mHeight(size.y) + , mProject(project) { mKaraokeHeight = mHeight; mLyricsStyle = kBouncingBallLyrics; // default @@ -109,6 +113,16 @@ LyricsPanel::LyricsPanel(wxWindow* parent, wxWindowID id, wxSizeEvent dummyEvent; OnSize(dummyEvent); #endif + + parent->Bind(wxEVT_SHOW, &LyricsPanel::OnShow, this); + + auto undoManager = project->GetUndoManager(); + undoManager->Bind(EVT_UNDO_PUSHED, &LyricsPanel::UpdateLyrics, this); + undoManager->Bind(EVT_UNDO_MODIFIED, &LyricsPanel::UpdateLyrics, this); + undoManager->Bind(EVT_UNDO_RESET, &LyricsPanel::UpdateLyrics, this); + + wxTheApp->Bind(EVT_AUDIOIO_PLAYBACK, &LyricsPanel::OnStartStop, this); + wxTheApp->Bind(EVT_AUDIOIO_CAPTURE, &LyricsPanel::OnStartStop, this); } LyricsPanel::~LyricsPanel() @@ -456,6 +470,55 @@ void LyricsPanel::Update(double t) } } +void LyricsPanel::UpdateLyrics(wxEvent &e) +{ + e.Skip(); + + // It's crucial to not do that repopulating during playback. + if (gAudioIO->IsStreamActive()) { + mDelayedUpdate = true; + return; + } + + Clear(); + + if (!mProject) + return; + + // Lyrics come from only the first label track. + auto pLabelTrack = *mProject->GetTracks()->Any< const LabelTrack >().begin(); + if (!pLabelTrack) + return; + + // The code that updates the lyrics is rather expensive when there + // are a lot of labels. + // So - bail out early if the lyrics window is not visible. + // We will later force an update when the lyrics window is made visible. + auto parent = dynamic_cast(GetParent()); + if( !(parent && parent->IsVisible()) ) + return; + + AddLabels(pLabelTrack); + Finish(pLabelTrack->GetEndTime()); + Update(mProject->GetSel0()); +} + +void LyricsPanel::OnStartStop(wxCommandEvent &e) +{ + e.Skip(); + if ( !e.GetInt() && mDelayedUpdate ) { + mDelayedUpdate = false; + UpdateLyrics( e ); + } +} + +void LyricsPanel::OnShow(wxShowEvent &e) +{ + e.Skip(); + if (e.IsShown()) + UpdateLyrics(e); +} + void LyricsPanel::OnKeyEvent(wxKeyEvent & event) { AudacityProject *project = GetActiveProject(); diff --git a/src/Lyrics.h b/src/Lyrics.h index 1b68b30a6..48d0306c2 100644 --- a/src/Lyrics.h +++ b/src/Lyrics.h @@ -18,6 +18,7 @@ #include #include "widgets/wxPanelWrapper.h" +class AudacityProject; class LabelTrack; @@ -80,14 +81,11 @@ class LyricsPanel final : public wxPanelWrapper public: LyricsPanel(wxWindow* parent, wxWindowID id, + AudacityProject *project, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize); virtual ~LyricsPanel(); - void Clear(); - void AddLabels(const LabelTrack *pLT); - void Finish(double finalT); - int FindSyllable(long startChar); // Find the syllable whose char0 <= startChar <= char1. int GetCurrentSyllableIndex() { return mCurrentSyllable; }; Syllable* GetSyllable(int nSyl) { return &(mSyllables[nSyl]); }; @@ -97,6 +95,9 @@ class LyricsPanel final : public wxPanelWrapper void SetLyricsStyle(const LyricsStyle newLyricsStyle); void Update(double t); + void UpdateLyrics(wxEvent &e); + void OnShow(wxShowEvent& e); + void OnStartStop(wxCommandEvent &e); // // Event handlers @@ -116,6 +117,10 @@ class LyricsPanel final : public wxPanelWrapper void HandleLayout(); private: + void Clear(); + void AddLabels(const LabelTrack *pLT); + void Finish(double finalT); + void Add(double t, const wxString &syllable, wxString &highlightText); unsigned int GetDefaultFontSize() const; // Depends on mLyricsStyle. Call only after mLyricsStyle is set. @@ -146,6 +151,9 @@ private: int mTextHeight; // only for drawn text bool mMeasurementsDone; // only for drawn text + wxWeakRef mProject; + bool mDelayedUpdate{ false }; + DECLARE_EVENT_TABLE() }; diff --git a/src/LyricsWindow.cpp b/src/LyricsWindow.cpp index 22a7ff8f4..8b32ea73f 100644 --- a/src/LyricsWindow.cpp +++ b/src/LyricsWindow.cpp @@ -114,10 +114,9 @@ LyricsWindow::LyricsWindow(AudacityProject *parent): // //pToolBar->Realize(); - mLyricsPanel = safenew LyricsPanel(this, -1, panelPos, panelSize); + mLyricsPanel = safenew LyricsPanel(this, -1, parent, panelPos, panelSize); RTL_WORKAROUND(mLyricsPanel); - //vvv Highlight style is broken in ported version. //switch (mLyricsPanel->GetLyricsStyle()) //{ diff --git a/src/Project.cpp b/src/Project.cpp index 6832d4f2c..10500c656 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -100,8 +100,6 @@ scroll information. It also has some status flags. #include "Diags.h" #include "HistoryWindow.h" #include "InconsistencyException.h" -#include "Lyrics.h" -#include "LyricsWindow.h" #include "MixerBoard.h" #include "Internat.h" #include "import/Import.h" @@ -4594,7 +4592,6 @@ void AudacityProject::InitialState() GetMenuManager(*this).ModifyUndoMenuItems(*this); GetMenuManager(*this).UpdateMenus(*this); - this->UpdateLyrics(); this->UpdateMixerBoard(); } @@ -4631,15 +4628,12 @@ void AudacityProject::PushState(const wxString &desc, GetMenuManager(*this).UpdateMenus(*this); // Some state pushes, like changing a track gain control (& probably others), - // should not repopulate Lyrics Window and MixerBoard. - // Others, such as deleting a label or adding a wave track, obviously do. + // should not repopulate MixerBoard. + // Others, such as deleting adding a wave track, obviously do. // Could categorize these state changes, but for now... // It's crucial to not do that repopulating during playback. if (!gAudioIO->IsStreamActive(GetAudioIOToken())) - { - this->UpdateLyrics(); this->UpdateMixerBoard(); - } if (GetTracksFitVerticallyZoomed()) ViewActions::DoZoomFitV(*this); @@ -4713,7 +4707,6 @@ void AudacityProject::PopState(const UndoState &state) HandleResize(); GetMenuManager(*this).UpdateMenus(*this); - this->UpdateLyrics(); this->UpdateMixerBoard(); AutoSave(); @@ -4728,36 +4721,9 @@ void AudacityProject::SetStateTo(unsigned int n) mTrackPanel->SetFocusedTrack(NULL); mTrackPanel->Refresh(false); GetMenuManager(*this).ModifyUndoMenuItems(*this); - this->UpdateLyrics(); this->UpdateMixerBoard(); } -void AudacityProject::UpdateLyrics() -{ - // JKC: Previously we created a lyrics window, - // if it did not exist. But we don't need to. - if (!mLyricsWindow) - return; - - // Lyrics come from only the first label track. - auto pLabelTrack = *GetTracks()->Any< const LabelTrack >().begin(); - if (!pLabelTrack) - return; - - // The code that updates the lyrics is rather expensive when there - // are a lot of labels. - // So - bail out early if the lyrics window is not visible. - // We will later force an update when the lyrics window is made visible. - if( !mLyricsWindow->IsVisible() ) - return; - - LyricsPanel* pLyricsPanel = mLyricsWindow->GetLyricsPanel(); - pLyricsPanel->Clear(); - pLyricsPanel->AddLabels(pLabelTrack); - pLyricsPanel->Finish(pLabelTrack->GetEndTime()); - pLyricsPanel->Update(this->GetSel0()); -} - void AudacityProject::UpdateMixerBoard() { if (!mMixerBoard) diff --git a/src/Project.h b/src/Project.h index ef218f3ce..9df43812c 100644 --- a/src/Project.h +++ b/src/Project.h @@ -605,7 +605,6 @@ public: void PopState(const UndoState &state); - void UpdateLyrics(); void UpdateMixerBoard(); void GetRegionsByLabel( Regions ®ions ); diff --git a/src/menus/ViewMenus.cpp b/src/menus/ViewMenus.cpp index e2b2acc41..b2bce37f9 100644 --- a/src/menus/ViewMenus.cpp +++ b/src/menus/ViewMenus.cpp @@ -199,7 +199,6 @@ void OnKaraoke(const CommandContext &context) auto lyricsWindow = project.GetLyricsWindow(true); lyricsWindow->Show(); - project.UpdateLyrics(); lyricsWindow->Raise(); }