Fix crashes in repainting, and update first visible track correctly
This commit is contained in:
parent
30ec8a1c90
commit
2806b509e2
|
@ -944,8 +944,16 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id,
|
|||
mLastSavedTracks = NULL;
|
||||
|
||||
// Register for tracklist updates
|
||||
mTracks->Connect(EVT_TRACKLIST_PERMUTED,
|
||||
wxCommandEventHandler(AudacityProject::OnTrackListUpdate),
|
||||
NULL,
|
||||
this);
|
||||
mTracks->Connect(EVT_TRACKLIST_DELETION,
|
||||
wxCommandEventHandler(AudacityProject::OnTrackListDeletion),
|
||||
wxCommandEventHandler(AudacityProject::OnTrackListUpdate),
|
||||
NULL,
|
||||
this);
|
||||
mTracks->Connect(EVT_TRACKLIST_RESIZING,
|
||||
wxCommandEventHandler(AudacityProject::OnTrackListUpdate),
|
||||
NULL,
|
||||
this);
|
||||
|
||||
|
@ -1974,9 +1982,8 @@ void AudacityProject::FixScrollbars()
|
|||
rescroll = false;
|
||||
}
|
||||
|
||||
if (lastv != mViewInfo.vpos) {
|
||||
UpdateFirstVisible();
|
||||
}
|
||||
if (lastv != mViewInfo.vpos)
|
||||
InvalidateFirstVisible();
|
||||
|
||||
// wxScrollbar only supports int values but we need a greater range, so
|
||||
// we scale the scrollbar coordinates on demand. We only do this if we
|
||||
|
@ -2020,51 +2027,30 @@ void AudacityProject::FixScrollbars()
|
|||
}
|
||||
}
|
||||
|
||||
Track *AudacityProject::GetFirstVisible()
|
||||
std::shared_ptr<Track> AudacityProject::GetFirstVisible()
|
||||
{
|
||||
if (!mViewInfo.track && GetTracks()) {
|
||||
auto pTrack = mViewInfo.track.lock();
|
||||
if (!pTrack && GetTracks()) {
|
||||
// Recompute on demand and memo-ize
|
||||
TrackListIterator iter(GetTracks());
|
||||
for (Track *t = iter.First(); t; t = iter.Next()) {
|
||||
int y = t->GetY();
|
||||
int h = t->GetHeight();
|
||||
if (y + h - 1 >= mViewInfo.vpos) {
|
||||
// At least the bottom row of pixels is not scrolled away above
|
||||
mViewInfo.track = t;
|
||||
pTrack = Track::Pointer(t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mViewInfo.track = pTrack;
|
||||
}
|
||||
|
||||
return mViewInfo.track;
|
||||
return pTrack;
|
||||
}
|
||||
|
||||
void AudacityProject::UpdateFirstVisible()
|
||||
void AudacityProject::InvalidateFirstVisible()
|
||||
{
|
||||
if (!mViewInfo.track || !GetTracks()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Track *t = mViewInfo.track;
|
||||
mViewInfo.track = NULL;
|
||||
|
||||
if (t->GetY() >= mViewInfo.vpos) {
|
||||
while (t && t->GetY() >= mViewInfo.vpos) {
|
||||
t = mTracks->GetPrev(t);
|
||||
}
|
||||
}
|
||||
|
||||
while (t) {
|
||||
int y = t->GetY();
|
||||
int h = t->GetHeight();
|
||||
if (y + h - 1 >= mViewInfo.vpos) {
|
||||
// At least the bottom row of pixels is not scrolled away above
|
||||
mViewInfo.track = t;
|
||||
return;
|
||||
}
|
||||
t = mTracks->GetNext(t);
|
||||
}
|
||||
|
||||
return;
|
||||
mViewInfo.track.reset();
|
||||
}
|
||||
|
||||
void AudacityProject::UpdateLayout()
|
||||
|
@ -2222,9 +2208,9 @@ void AudacityProject::OnToolBarUpdate(wxCommandEvent & event)
|
|||
}
|
||||
|
||||
// The projects tracklist has been updated
|
||||
void AudacityProject::OnTrackListDeletion(wxCommandEvent & event)
|
||||
void AudacityProject::OnTrackListUpdate(wxCommandEvent & event)
|
||||
{
|
||||
mViewInfo.track = NULL;
|
||||
InvalidateFirstVisible();
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
@ -2275,9 +2261,8 @@ void AudacityProject::DoScroll()
|
|||
int lastv = mViewInfo.vpos;
|
||||
mViewInfo.vpos = mVsbar->GetThumbPosition() * mViewInfo.scrollStep;
|
||||
|
||||
if (lastv != mViewInfo.vpos) {
|
||||
UpdateFirstVisible();
|
||||
}
|
||||
if (lastv != mViewInfo.vpos)
|
||||
InvalidateFirstVisible();
|
||||
|
||||
//mchinen: do not always set this project to be the active one.
|
||||
//a project may autoscroll while playing in the background
|
||||
|
@ -2692,8 +2677,16 @@ void AudacityProject::OnCloseWindow(wxCloseEvent & event)
|
|||
mImportXMLTagHandler.reset();
|
||||
|
||||
// Unregister for tracklist updates
|
||||
mTracks->Disconnect(EVT_TRACKLIST_PERMUTED,
|
||||
wxCommandEventHandler(AudacityProject::OnTrackListUpdate),
|
||||
NULL,
|
||||
this);
|
||||
mTracks->Disconnect(EVT_TRACKLIST_DELETION,
|
||||
wxCommandEventHandler(AudacityProject::OnTrackListDeletion),
|
||||
wxCommandEventHandler(AudacityProject::OnTrackListUpdate),
|
||||
NULL,
|
||||
this);
|
||||
mTracks->Disconnect(EVT_TRACKLIST_RESIZING,
|
||||
wxCommandEventHandler(AudacityProject::OnTrackListUpdate),
|
||||
NULL,
|
||||
this);
|
||||
|
||||
|
@ -3529,7 +3522,7 @@ bool AudacityProject::HandleXMLTag(const wxChar *tag, const wxChar **attrs)
|
|||
|
||||
if (longVpos != 0) {
|
||||
// PRL: It seems this must happen after SetSnapTo
|
||||
mViewInfo.track = NULL;
|
||||
mViewInfo.track.reset();
|
||||
mViewInfo.vpos = longVpos;
|
||||
mbInitializingScrollbar = true;
|
||||
}
|
||||
|
|
|
@ -191,8 +191,8 @@ class AUDACITY_DLL_API AudacityProject final : public wxFrame,
|
|||
const ViewInfo &GetViewInfo() const { return mViewInfo; }
|
||||
ViewInfo &GetViewInfo() { return mViewInfo; }
|
||||
|
||||
Track *GetFirstVisible();
|
||||
void UpdateFirstVisible();
|
||||
std::shared_ptr<Track> GetFirstVisible();
|
||||
void InvalidateFirstVisible();
|
||||
|
||||
void GetPlayRegion(double* playRegionStart, double *playRegionEnd);
|
||||
bool IsPlayRegionLocked() { return mLockPlayRegion; }
|
||||
|
@ -355,7 +355,7 @@ public:
|
|||
void OnOpenAudioFile(wxCommandEvent & event);
|
||||
void OnODTaskUpdate(wxCommandEvent & event);
|
||||
void OnODTaskComplete(wxCommandEvent & event);
|
||||
void OnTrackListDeletion(wxCommandEvent & event);
|
||||
void OnTrackListUpdate(wxCommandEvent & event);
|
||||
|
||||
void HandleResize();
|
||||
void UpdateLayout();
|
||||
|
|
|
@ -741,6 +741,7 @@ Track *SyncLockedTracksIterator::Last(bool skiplinked)
|
|||
// is managing. Any other classes that may be interested in get these updates
|
||||
// should use TrackList::Connect() and TrackList::Disconnect().
|
||||
//
|
||||
DEFINE_EVENT_TYPE(EVT_TRACKLIST_PERMUTED);
|
||||
DEFINE_EVENT_TYPE(EVT_TRACKLIST_RESIZING);
|
||||
DEFINE_EVENT_TYPE(EVT_TRACKLIST_DELETION);
|
||||
|
||||
|
@ -856,6 +857,13 @@ void TrackList::RecalcPositions(TrackNodePointer node)
|
|||
#endif // EXPERIMENTAL_OUTPUT_DISPLAY
|
||||
}
|
||||
|
||||
void TrackList::PermutationEvent()
|
||||
{
|
||||
auto e = std::make_unique<wxCommandEvent>(EVT_TRACKLIST_PERMUTED);
|
||||
// wxWidgets will own the event object
|
||||
QueueEvent(e.release());
|
||||
}
|
||||
|
||||
void TrackList::DeletionEvent()
|
||||
{
|
||||
auto e = std::make_unique<wxCommandEvent>(EVT_TRACKLIST_DELETION);
|
||||
|
@ -882,6 +890,7 @@ void TrackList::Permute(const std::vector<TrackNodePointer> &permutation)
|
|||
}
|
||||
auto n = begin();
|
||||
RecalcPositions(n);
|
||||
PermutationEvent();
|
||||
}
|
||||
|
||||
template<typename TrackKind>
|
||||
|
@ -1152,6 +1161,7 @@ void TrackList::SwapNodes(TrackNodePointer s1, TrackNodePointer s2)
|
|||
|
||||
// Now correct the Index in the tracks, and other things
|
||||
RecalcPositions(s1);
|
||||
PermutationEvent();
|
||||
}
|
||||
|
||||
bool TrackList::MoveUp(Track * t)
|
||||
|
|
|
@ -483,6 +483,9 @@ class AUDACITY_DLL_API SyncLockedTracksIterator final : public TrackListIterator
|
|||
* Clear, and Contains, plus serialization of the list of tracks.
|
||||
*/
|
||||
|
||||
// Posted when tracks are reordered but otherwise unchanged.
|
||||
DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_TRACKLIST_PERMUTED, -1);
|
||||
|
||||
// Posted when some track was added or changed its height.
|
||||
// The wxCommandEvent::GetClientData() method can be used to retrieve it.
|
||||
DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_TRACKLIST_RESIZING, -1);
|
||||
|
@ -607,6 +610,7 @@ private:
|
|||
void DoAssign(const TrackList &that);
|
||||
|
||||
void RecalcPositions(TrackNodePointer node);
|
||||
void PermutationEvent();
|
||||
void DeletionEvent();
|
||||
void ResizingEvent(TrackNodePointer node);
|
||||
|
||||
|
|
|
@ -1636,7 +1636,8 @@ void TrackPanel::DrawTracks(wxDC * dc)
|
|||
bool sliderFlag = bMultiToolDown;
|
||||
|
||||
// The track artist actually draws the stuff inside each track
|
||||
mTrackArtist->DrawTracks(GetTracks(), GetProject()->GetFirstVisible(),
|
||||
auto first = GetProject()->GetFirstVisible();
|
||||
mTrackArtist->DrawTracks(GetTracks(), first.get(),
|
||||
*dc, region, tracksRect, clip,
|
||||
mViewInfo->selectedRegion, *mViewInfo,
|
||||
envelopeFlag, bigPointsFlag, sliderFlag);
|
||||
|
|
|
@ -130,7 +130,6 @@ void ZoomInfo::FindIntervals
|
|||
ViewInfo::ViewInfo(double start, double screenDuration, double pixelsPerSecond)
|
||||
: ZoomInfo(start, pixelsPerSecond)
|
||||
, selectedRegion()
|
||||
, track(NULL)
|
||||
, total(screenDuration)
|
||||
, sbarH(0)
|
||||
, sbarScreen(1)
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <vector>
|
||||
#include <wx/event.h>
|
||||
#include "SelectedRegion.h"
|
||||
#include "MemoryX.h"
|
||||
|
||||
|
||||
class Track;
|
||||
|
@ -157,7 +158,7 @@ public:
|
|||
|
||||
// Scroll info
|
||||
|
||||
Track *track; // first visible track
|
||||
std::weak_ptr<Track> track; // first visible track
|
||||
|
||||
double total; // total width in secs
|
||||
// Current horizontal scroll bar positions, in pixels
|
||||
|
|
Loading…
Reference in New Issue