1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-25 16:48:44 +02:00

Bug2598: Envelope edit not dependend on visibility of channels...

... And other rewrites.  Don't use a cache of wave clip X coordinates computed
during drawing.
This commit is contained in:
Paul Licameli 2020-11-19 22:26:10 -05:00
parent 3c76cea190
commit 6050edb3ca
9 changed files with 26 additions and 71 deletions

View File

@ -1187,22 +1187,6 @@ void WaveClip::TimeToSamplesClip(double t0, sampleCount *s0) const
*s0 = sampleCount( floor(((t0 - mOffset) * mRate) + 0.5) ); *s0 = sampleCount( floor(((t0 - mOffset) * mRate) + 0.5) );
} }
void WaveClip::ClearDisplayRect() const
{
mDisplayRect.x = mDisplayRect.y = -1;
mDisplayRect.width = mDisplayRect.height = -1;
}
void WaveClip::SetDisplayRect(const wxRect& r) const
{
mDisplayRect = r;
}
void WaveClip::GetDisplayRect(wxRect* r)
{
*r = mDisplayRect;
}
/*! @excsafety{Strong} */ /*! @excsafety{Strong} */
std::shared_ptr<SampleBlock> WaveClip::AppendNewBlock( std::shared_ptr<SampleBlock> WaveClip::AppendNewBlock(
samplePtr buffer, sampleFormat format, size_t len) samplePtr buffer, sampleFormat format, size_t len)

View File

@ -272,12 +272,6 @@ public:
double t0, double t1, bool mayThrow = true) const; double t0, double t1, bool mayThrow = true) const;
float GetRMS(double t0, double t1, bool mayThrow = true) const; float GetRMS(double t0, double t1, bool mayThrow = true) const;
// Set/clear/get rectangle that this WaveClip fills on screen. This is
// called by TrackArtist while actually drawing the tracks and clips.
void ClearDisplayRect() const;
void SetDisplayRect(const wxRect& r) const;
void GetDisplayRect(wxRect* r);
/** Whenever you do an operation to the sequence that will change the number /** Whenever you do an operation to the sequence that will change the number
* of samples (that is, the length of the clip), you will want to call this * of samples (that is, the length of the clip), you will want to call this
* function to tell the envelope about it. */ * function to tell the envelope about it. */
@ -366,8 +360,6 @@ public:
mutable std::unique_ptr<SpecPxCache> mSpecPxCache; mutable std::unique_ptr<SpecPxCache> mSpecPxCache;
protected: protected:
mutable wxRect mDisplayRect {};
double mOffset { 0 }; double mOffset { 0 };
int mRate; int mRate;
int mDirty { 0 }; int mDirty { 0 };

View File

@ -2069,19 +2069,6 @@ void WaveTrack::GetEnvelopeValues(double *buffer, size_t bufferLen,
} }
} }
WaveClip* WaveTrack::GetClipAtX(int xcoord)
{
for (const auto &clip: mClips)
{
wxRect r;
clip->GetDisplayRect(&r);
if (xcoord >= r.x && xcoord < r.x+r.width)
return clip.get();
}
return NULL;
}
WaveClip* WaveTrack::GetClipAtSample(sampleCount sample) WaveClip* WaveTrack::GetClipAtSample(sampleCount sample)
{ {
for (const auto &clip: mClips) for (const auto &clip: mClips)
@ -2119,18 +2106,18 @@ WaveClip* WaveTrack::GetClipAtTime(double time)
return p != clips.rend() ? *p : nullptr; return p != clips.rend() ? *p : nullptr;
} }
Envelope* WaveTrack::GetEnvelopeAtX(int xcoord) Envelope* WaveTrack::GetEnvelopeAtTime(double time)
{ {
WaveClip* clip = GetClipAtX(xcoord); WaveClip* clip = GetClipAtTime(time);
if (clip) if (clip)
return clip->GetEnvelope(); return clip->GetEnvelope();
else else
return NULL; return NULL;
} }
Sequence* WaveTrack::GetSequenceAtX(int xcoord) Sequence* WaveTrack::GetSequenceAtTime(double time)
{ {
WaveClip* clip = GetClipAtX(xcoord); WaveClip* clip = GetClipAtTime(time);
if (clip) if (clip)
return clip->GetSequence(); return clip->GetSequence();
else else

View File

@ -271,12 +271,11 @@ private:
// //
// MM: We now have more than one sequence and envelope per track, so // MM: We now have more than one sequence and envelope per track, so
// instead of GetSequence() and GetEnvelope() we have the following // instead of GetSequence() and GetEnvelope() we have the following
// function which give the sequence and envelope which is under the // function which give the sequence and envelope which contains the given
// given X coordinate of the mouse pointer. // time.
// //
WaveClip* GetClipAtX(int xcoord); Sequence* GetSequenceAtTime(double time);
Sequence* GetSequenceAtX(int xcoord); Envelope* GetEnvelopeAtTime(double time);
Envelope* GetEnvelopeAtX(int xcoord);
WaveClip* GetClipAtSample(sampleCount sample); WaveClip* GetClipAtSample(sampleCount sample);
WaveClip* GetClipAtTime(double time); WaveClip* GetClipAtTime(double time);

View File

@ -119,9 +119,9 @@ UIHandlePtr SampleHandle::HitTest
/// method that tells us if the mouse event landed on an /// method that tells us if the mouse event landed on an
/// editable sample /// editable sample
const auto wavetrack = pTrack.get(); const auto wavetrack = pTrack.get();
const auto time = viewInfo.PositionToTime(state.m_x, rect.x);
const double tt = const double tt = adjustTime(wavetrack, time);
adjustTime(wavetrack, viewInfo.PositionToTime(state.m_x, rect.x));
if (!SampleResolutionTest(viewInfo, wavetrack, tt, rect.width)) if (!SampleResolutionTest(viewInfo, wavetrack, tt, rect.width))
return {}; return {};
@ -140,7 +140,7 @@ UIHandlePtr SampleHandle::HitTest
wavetrack->GetDisplayBounds(&zoomMin, &zoomMax); wavetrack->GetDisplayBounds(&zoomMin, &zoomMax);
double envValue = 1.0; double envValue = 1.0;
Envelope* env = wavetrack->GetEnvelopeAtX(state.GetX()); Envelope* env = wavetrack->GetEnvelopeAtTime(time);
if (env) if (env)
// Calculate sample as it would be rendered, so quantize time // Calculate sample as it would be rendered, so quantize time
envValue = env->GetValue( tt, 1.0 / wavetrack->GetRate() ); envValue = env->GetValue( tt, 1.0 / wavetrack->GetRate() );
@ -436,7 +436,7 @@ UIHandle::Result SampleHandle::Cancel(AudacityProject *pProject)
} }
float SampleHandle::FindSampleEditingLevel float SampleHandle::FindSampleEditingLevel
(const wxMouseEvent &event, const ViewInfo &, double t0) (const wxMouseEvent &event, const ViewInfo &viewInfo, double t0)
{ {
// Calculate where the mouse is located vertically (between +/- 1) // Calculate where the mouse is located vertically (between +/- 1)
float zoomMin, zoomMax; float zoomMin, zoomMax;
@ -450,7 +450,8 @@ float SampleHandle::FindSampleEditingLevel
mClickedTrack->GetWaveformSettings().dBRange, zoomMin, zoomMax); mClickedTrack->GetWaveformSettings().dBRange, zoomMin, zoomMax);
//Take the envelope into account //Take the envelope into account
Envelope *const env = mClickedTrack->GetEnvelopeAtX(event.m_x); const auto time = viewInfo.PositionToTime(event.m_x, mRect.x);
Envelope *const env = mClickedTrack->GetEnvelopeAtTime(time);
if (env) if (env)
{ {
// Calculate sample as it would be rendered, so quantize time // Calculate sample as it would be rendered, so quantize time

View File

@ -210,10 +210,6 @@ void DrawClipSpectrum(TrackPanelDrawingContext &context,
const double &leftOffset = params.leftOffset; const double &leftOffset = params.leftOffset;
const wxRect &mid = params.mid; const wxRect &mid = params.mid;
// If we get to this point, the clip is actually visible on the
// screen, so remember the display rectangle.
clip->SetDisplayRect(hiddenMid);
double freqLo = SelectedRegion::UndefinedFrequency; double freqLo = SelectedRegion::UndefinedFrequency;
double freqHi = SelectedRegion::UndefinedFrequency; double freqHi = SelectedRegion::UndefinedFrequency;
#ifdef EXPERIMENTAL_SPECTRAL_EDITING #ifdef EXPERIMENTAL_SPECTRAL_EDITING
@ -644,10 +640,6 @@ void SpectrumView::Draw(
const auto wt = std::static_pointer_cast<const WaveTrack>( const auto wt = std::static_pointer_cast<const WaveTrack>(
FindTrack()->SubstitutePendingChangedTrack()); FindTrack()->SubstitutePendingChangedTrack());
for (const auto &clip : wt->GetClips()) {
clip->ClearDisplayRect();
}
const auto artist = TrackArtist::Get( context ); const auto artist = TrackArtist::Get( context );
#if defined(__WXMAC__) #if defined(__WXMAC__)

View File

@ -84,7 +84,10 @@ std::vector<UIHandlePtr> WaveformView::DetailedHitTest(
// Unconditional hits appropriate to the tool // Unconditional hits appropriate to the tool
// If tools toolbar were eliminated, we would eliminate these // If tools toolbar were eliminated, we would eliminate these
case ToolCodes::envelopeTool: { case ToolCodes::envelopeTool: {
auto envelope = pTrack->GetEnvelopeAtX( st.state.m_x ); auto &viewInfo = ViewInfo::Get(*pProject);
auto time =
viewInfo.PositionToTime(st.state.m_x, st.rect.GetX());
auto envelope = pTrack->GetEnvelopeAtTime(time);
result = EnvelopeHandle::HitAnywhere( result = EnvelopeHandle::HitAnywhere(
view.mEnvelopeHandle, envelope, false); view.mEnvelopeHandle, envelope, false);
break; break;
@ -712,10 +715,6 @@ void DrawClipWaveform(TrackPanelDrawingContext &context,
int iColorIndex = clip->GetColourIndex(); int iColorIndex = clip->GetColourIndex();
artist->SetColours( iColorIndex ); artist->SetColours( iColorIndex );
// If we get to this point, the clip is actually visible on the
// screen, so remember the display rectangle.
clip->SetDisplayRect(hiddenMid);
// The bounds (controlled by vertical zooming; -1.0...1.0 // The bounds (controlled by vertical zooming; -1.0...1.0
// by default) // by default)
float zoomMin, zoomMax; float zoomMin, zoomMax;
@ -1012,10 +1011,6 @@ void WaveformView::Draw(
const auto wt = std::static_pointer_cast<const WaveTrack>( const auto wt = std::static_pointer_cast<const WaveTrack>(
FindTrack()->SubstitutePendingChangedTrack()); FindTrack()->SubstitutePendingChangedTrack());
for (const auto &clip : wt->GetClips()) {
clip->ClearDisplayRect();
}
const auto artist = TrackArtist::Get( context ); const auto artist = TrackArtist::Get( context );
const auto hasSolo = artist->hasSolo; const auto hasSolo = artist->hasSolo;
bool muted = (hasSolo || wt->GetMute()) && bool muted = (hasSolo || wt->GetMute()) &&

View File

@ -93,7 +93,9 @@ UIHandlePtr EnvelopeHandle::WaveTrackHitTest
{ {
/// method that tells us if the mouse event landed on an /// method that tells us if the mouse event landed on an
/// envelope boundary. /// envelope boundary.
Envelope *const envelope = wt->GetEnvelopeAtX(state.GetX()); auto &viewInfo = ViewInfo::Get(*pProject);
auto time = viewInfo.PositionToTime(state.m_x, rect.GetX());
Envelope *const envelope = wt->GetEnvelopeAtTime(time);
if (!envelope) if (!envelope)
return {}; return {};
@ -194,7 +196,9 @@ UIHandle::Result EnvelopeHandle::Click
mEnvelopeEditors.push_back( mEnvelopeEditors.push_back(
std::make_unique< EnvelopeEditor >( *mEnvelope, true ) ); std::make_unique< EnvelopeEditor >( *mEnvelope, true ) );
else { else {
auto e2 = channel->GetEnvelopeAtX(event.GetX()); auto time =
viewInfo.PositionToTime(event.GetX(), evt.rect.GetX());
auto e2 = channel->GetEnvelopeAtTime(time);
if (e2) if (e2)
mEnvelopeEditors.push_back( mEnvelopeEditors.push_back(
std::make_unique< EnvelopeEditor >( *e2, true ) ); std::make_unique< EnvelopeEditor >( *e2, true ) );

View File

@ -570,7 +570,8 @@ UIHandle::Result SelectHandle::Click
// Special case: if we're over a clip in a WaveTrack, // Special case: if we're over a clip in a WaveTrack,
// select just that clip // select just that clip
pTrack->TypeSwitch( [&] ( WaveTrack *wt ) { pTrack->TypeSwitch( [&] ( WaveTrack *wt ) {
WaveClip *const selectedClip = wt->GetClipAtX(event.m_x); auto time = viewInfo.PositionToTime(event.m_x, mRect.x);
WaveClip *const selectedClip = wt->GetClipAtTime(time);
if (selectedClip) { if (selectedClip) {
viewInfo.selectedRegion.setTimes( viewInfo.selectedRegion.setTimes(
selectedClip->GetOffset(), selectedClip->GetEndTime()); selectedClip->GetOffset(), selectedClip->GetEndTime());