mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-21 06:40:08 +02:00
Lyrics panel listens; AudacityProject not responsible for updating it
This commit is contained in:
parent
ad8fafa6a0
commit
96d104cb38
@ -15,11 +15,13 @@
|
||||
#include <wx/dcmemory.h>
|
||||
#include <wx/mimetype.h>
|
||||
|
||||
#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*/) :
|
||||
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<wxFrame*>(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();
|
||||
|
16
src/Lyrics.h
16
src/Lyrics.h
@ -18,6 +18,7 @@
|
||||
#include <wx/textctrl.h>
|
||||
#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<AudacityProject> mProject;
|
||||
bool mDelayedUpdate{ false };
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
|
@ -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())
|
||||
//{
|
||||
|
@ -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)
|
||||
|
@ -605,7 +605,6 @@ public:
|
||||
|
||||
void PopState(const UndoState &state);
|
||||
|
||||
void UpdateLyrics();
|
||||
void UpdateMixerBoard();
|
||||
|
||||
void GetRegionsByLabel( Regions ®ions );
|
||||
|
@ -199,7 +199,6 @@ void OnKaraoke(const CommandContext &context)
|
||||
|
||||
auto lyricsWindow = project.GetLyricsWindow(true);
|
||||
lyricsWindow->Show();
|
||||
project.UpdateLyrics();
|
||||
lyricsWindow->Raise();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user