1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-02 08:59:28 +02:00

OverlayPanel uses weak_ptr to Overlay, which simplifies other dtors

This commit is contained in:
Paul Licameli 2019-01-23 20:53:37 -05:00
parent ac2fecf151
commit f7162d3326
10 changed files with 50 additions and 85 deletions

View File

@ -110,7 +110,6 @@ class AdornedRulerPanel::QuickPlayRulerOverlay final : public Overlay
{
public:
QuickPlayRulerOverlay(QuickPlayIndicatorOverlay &partner);
virtual ~QuickPlayRulerOverlay();
// Available to this and to partner
@ -149,20 +148,19 @@ private:
class AdornedRulerPanel::QuickPlayIndicatorOverlay final : public Overlay
{
friend QuickPlayRulerOverlay;
friend AdornedRulerPanel;
public:
QuickPlayIndicatorOverlay(AudacityProject *project);
virtual ~QuickPlayIndicatorOverlay();
private:
std::pair<wxRect, bool> DoGetRectangle(wxSize size) override;
void Draw(OverlayPanel &panel, wxDC &dc) override;
AudacityProject *mProject;
std::unique_ptr<QuickPlayRulerOverlay> mPartner
{ std::make_unique<QuickPlayRulerOverlay>(*this) };
std::shared_ptr<QuickPlayRulerOverlay> mPartner
{ std::make_shared<QuickPlayRulerOverlay>(*this) };
int mOldQPIndicatorPos { -1 };
bool mOldQPIndicatorSnapped {};
@ -179,14 +177,6 @@ AdornedRulerPanel::QuickPlayRulerOverlay::QuickPlayRulerOverlay(
QuickPlayIndicatorOverlay &partner)
: mPartner(partner)
{
GetRuler()->AddOverlay(this);
}
AdornedRulerPanel::QuickPlayRulerOverlay::~QuickPlayRulerOverlay()
{
auto ruler = GetRuler();
if (ruler)
ruler->RemoveOverlay(this);
}
AdornedRulerPanel *AdornedRulerPanel::QuickPlayRulerOverlay::GetRuler() const
@ -286,15 +276,6 @@ AdornedRulerPanel::QuickPlayIndicatorOverlay::QuickPlayIndicatorOverlay(
AudacityProject *project)
: mProject(project)
{
auto tp = mProject->GetTrackPanel();
tp->AddOverlay(this);
}
AdornedRulerPanel::QuickPlayIndicatorOverlay::~QuickPlayIndicatorOverlay()
{
auto tp = mProject->GetTrackPanel();
if (tp)
tp->RemoveOverlay(this);
}
std::pair<wxRect, bool>
@ -2175,7 +2156,10 @@ bool AdornedRulerPanel::TakesFocus() const
void AdornedRulerPanel::CreateOverlays()
{
if (!mOverlay)
if (!mOverlay) {
mOverlay =
std::make_unique<QuickPlayIndicatorOverlay>( mProject );
std::make_shared<QuickPlayIndicatorOverlay>( mProject );
mProject->GetTrackPanel()->AddOverlay( mOverlay );
this->AddOverlay( mOverlay->mPartner );
}
}

View File

@ -193,7 +193,7 @@ private:
// Cooperating objects
class QuickPlayIndicatorOverlay;
std::unique_ptr<QuickPlayIndicatorOverlay> mOverlay;
std::shared_ptr<QuickPlayIndicatorOverlay> mOverlay;
class QuickPlayRulerOverlay;

View File

@ -1178,28 +1178,28 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id,
mRuler);
mTrackPanel->UpdatePrefs();
mCursorOverlay = std::make_unique<EditCursorOverlay>(this);
mCursorOverlay = std::make_shared<EditCursorOverlay>(this);
mBackgroundCell = std::make_shared<BackgroundCell>(this);
#ifdef EXPERIMENTAL_SCRUBBING_BASIC
mScrubOverlay = std::make_unique<ScrubbingOverlay>(this);
mScrubOverlay = std::make_shared<ScrubbingOverlay>(this);
mScrubber = std::make_unique<Scrubber>(this);
#endif
mPlaybackScroller = std::make_unique<PlaybackScroller>(this);
mIndicatorOverlay = std::make_unique<PlayIndicatorOverlay>(this);
mIndicatorOverlay = std::make_shared<PlayIndicatorOverlay>(this);
this->Bind(EVT_TRACK_PANEL_TIMER,
&ViewInfo::OnTimer,
&mViewInfo);
// Add the overlays, in the sequence in which they will be painted
mTrackPanel->AddOverlay(mIndicatorOverlay.get());
mTrackPanel->AddOverlay(mCursorOverlay.get());
mTrackPanel->AddOverlay( mIndicatorOverlay );
mTrackPanel->AddOverlay( mCursorOverlay );
#ifdef EXPERIMENTAL_SCRUBBING_BASIC
mTrackPanel->AddOverlay(mScrubOverlay.get());
mTrackPanel->AddOverlay( mScrubOverlay );
#endif
mMenuManager->CreateMenusAndCommands(*this);
@ -1337,14 +1337,6 @@ AudacityProject::~AudacityProject()
// Tool manager gives us capture sometimes
if(HasCapture())
ReleaseMouse();
if(mTrackPanel) {
#ifdef EXPERIMENTAL_SCRUBBING_BASIC
mTrackPanel->RemoveOverlay(mScrubOverlay.get());
#endif
mTrackPanel->RemoveOverlay(mCursorOverlay.get());
mTrackPanel->RemoveOverlay(mIndicatorOverlay.get());
}
}
void AudacityProject::ApplyUpdatedTheme()

View File

@ -33,7 +33,7 @@
#include "toolbars/SelectionBarListener.h"
#include "toolbars/SpectralSelectionBarListener.h"
#include "MemoryX.h"
#include <memory>
#include <wx/defs.h>
#include <wx/event.h>
#include <wx/log.h>
@ -774,13 +774,13 @@ private:
friend class CommandManager;
// TrackPanelOverlay objects
std::unique_ptr<Overlay>
std::shared_ptr<Overlay>
mIndicatorOverlay, mCursorOverlay;
std::shared_ptr<BackgroundCell> mBackgroundCell;
#ifdef EXPERIMENTAL_SCRUBBING_BASIC
std::unique_ptr<Overlay> mScrubOverlay;
std::shared_ptr<Overlay> mScrubOverlay;
std::unique_ptr<Scrubber> mScrubber;
public:
Scrubber &GetScrubber() { return *mScrubber; }

View File

@ -37,15 +37,6 @@ EditCursorOverlay::EditCursorOverlay(AudacityProject *project, bool isMaster)
{
}
EditCursorOverlay::~EditCursorOverlay()
{
if (mIsMaster && mPartner) {
auto ruler = mProject->GetRulerPanel();
if (ruler)
ruler->RemoveOverlay(mPartner.get());
}
}
std::pair<wxRect, bool> EditCursorOverlay::DoGetRectangle(wxSize size)
{
const SelectedRegion &selection = mProject->GetSelection();
@ -74,8 +65,8 @@ void EditCursorOverlay::Draw(OverlayPanel &panel, wxDC &dc)
if (mIsMaster && !mPartner) {
auto ruler = mProject->GetRulerPanel();
if (ruler) {
mPartner = std::make_unique<EditCursorOverlay>(mProject, false);
ruler->AddOverlay(mPartner.get());
mPartner = std::make_shared<EditCursorOverlay>(mProject, false);
ruler->AddOverlay( mPartner );
}
}

View File

@ -11,7 +11,7 @@ Paul Licameli split from TrackPanel.cpp
#ifndef __AUDACITY_EDIT_CURSOR_OVERLAY__
#define __AUDACITY_EDIT_CURSOR_OVERLAY__
#include "../../MemoryX.h"
#include <memory>
#include "../../widgets/Overlay.h"
class AudacityProject;
@ -20,7 +20,6 @@ class EditCursorOverlay final : public Overlay
{
public:
EditCursorOverlay(AudacityProject *project, bool isMaster = true);
virtual ~EditCursorOverlay();
private:
std::pair<wxRect, bool> DoGetRectangle(wxSize size) override;
@ -28,7 +27,7 @@ private:
AudacityProject *mProject;
bool mIsMaster;
std::unique_ptr<EditCursorOverlay> mPartner;
std::shared_ptr<EditCursorOverlay> mPartner;
int mLastCursorX;
double mCursorTime;

View File

@ -115,15 +115,6 @@ PlayIndicatorOverlay::PlayIndicatorOverlay(AudacityProject *project)
this);
}
PlayIndicatorOverlay::~PlayIndicatorOverlay()
{
if (mPartner) {
auto ruler = mProject->GetRulerPanel();
if(ruler)
ruler->RemoveOverlay(mPartner.get());
}
}
void PlayIndicatorOverlay::OnTimer(wxCommandEvent &event)
{
// Let other listeners get the notification
@ -133,8 +124,8 @@ void PlayIndicatorOverlay::OnTimer(wxCommandEvent &event)
if (!mPartner) {
auto ruler = mProject->GetRulerPanel();
if (ruler) {
mPartner = std::make_unique<PlayIndicatorOverlayBase>(mProject, false);
ruler->AddOverlay(mPartner.get());
mPartner = std::make_shared<PlayIndicatorOverlayBase>(mProject, false);
ruler->AddOverlay( mPartner );
}
}

View File

@ -46,12 +46,11 @@ class PlayIndicatorOverlay final : public PlayIndicatorOverlayBase
{
public:
PlayIndicatorOverlay(AudacityProject *project);
virtual ~PlayIndicatorOverlay();
private:
void OnTimer(wxCommandEvent &event);
std::unique_ptr<PlayIndicatorOverlayBase> mPartner;
std::shared_ptr<PlayIndicatorOverlayBase> mPartner;
};
#endif

View File

@ -20,18 +20,11 @@ OverlayPanel::OverlayPanel(wxWindow * parent, wxWindowID id,
: BackedPanel(parent, id, pos, size, style)
{}
void OverlayPanel::AddOverlay(Overlay *pOverlay)
void OverlayPanel::AddOverlay( const std::weak_ptr<Overlay> &pOverlay)
{
mOverlays.push_back(pOverlay);
}
bool OverlayPanel::RemoveOverlay(Overlay *pOverlay)
{
const size_t oldSize = mOverlays.size();
mOverlays.erase(std::remove(mOverlays.begin(), mOverlays.end(), pOverlay), mOverlays.end());
return oldSize != mOverlays.size();
}
void OverlayPanel::ClearOverlays()
{
mOverlays.clear();
@ -45,10 +38,14 @@ void OverlayPanel::DrawOverlays(bool repaint_all, wxDC *pDC)
std::vector< Pair > pairs;
pairs.reserve(n_pairs);
// First...
Compress();
// ... then assume pointers are not expired
// Find out the rectangles and outdatedness for each overlay
wxSize size(GetBackingDC().GetSize());
for (const auto pOverlay : mOverlays)
pairs.push_back(pOverlay->GetRectangle(size));
pairs.push_back( pOverlay.lock()->GetRectangle(size) );
// See what requires redrawing. If repainting, all.
// If not, then whatever is outdated, and whatever will be damaged by
@ -96,7 +93,7 @@ void OverlayPanel::DrawOverlays(bool repaint_all, wxDC *pDC)
auto it2 = pairs.begin();
for (auto pOverlay : mOverlays) {
if (repaint_all || it2->second)
pOverlay->Erase(dc, GetBackingDC());
pOverlay.lock()->Erase(dc, GetBackingDC());
++it2;
}
@ -107,11 +104,23 @@ void OverlayPanel::DrawOverlays(bool repaint_all, wxDC *pDC)
// Guarantee a clean state of the dc each pass:
ADCChanger changer{ &dc };
pOverlay->Draw(*this, dc);
pOverlay.lock()->Draw(*this, dc);
}
++it2;
}
}
void OverlayPanel::Compress()
{
// remove any expired pointers
auto begin = mOverlays.begin();
auto end = mOverlays.end();
auto newEnd = std::remove_if( begin, end,
[]( const std::weak_ptr<Overlay> &pOverlay ){
return pOverlay.expired(); } );
if ( end != newEnd )
mOverlays.resize( newEnd - begin );
}
BEGIN_EVENT_TABLE(OverlayPanel, BackedPanel)
END_EVENT_TABLE()

View File

@ -9,6 +9,7 @@
#ifndef __AUDACITY_OVERLAY_PANEL__
#define __AUDACITY_OVERLAY_PANEL__
#include <memory>
#include <vector>
#include "BackedPanel.h"
@ -22,13 +23,11 @@ public:
// default as for wxPanel:
long style = wxTAB_TRAVERSAL | wxNO_BORDER);
// Registers and unregisters overlay objects.
// Registers overlay objects.
// The sequence in which they were registered is the sequence in
// which they are painted.
// OverlayPanel is not responsible for their memory management.
void AddOverlay(Overlay *pOverlay);
// Returns true if the overlay was found
bool RemoveOverlay(Overlay *pOverlay);
void AddOverlay( const std::weak_ptr<Overlay> &pOverlay );
void ClearOverlays();
// Erases and redraws to the client area the overlays that have
@ -41,7 +40,8 @@ public:
void DrawOverlays(bool repaint_all, wxDC *pDC = nullptr);
private:
std::vector<Overlay*> mOverlays;
void Compress();
std::vector< std::weak_ptr<Overlay> > mOverlays;
DECLARE_EVENT_TABLE()