mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-25 08:38:39 +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:
parent
3c76cea190
commit
6050edb3ca
@ -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)
|
||||||
|
@ -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 };
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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__)
|
||||||
|
@ -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()) &&
|
||||||
|
@ -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 ) );
|
||||||
|
@ -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());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user