mirror of
https://github.com/cookiengineer/audacity
synced 2026-01-02 06:08:44 +01:00
Move TrackShifter subclasses each to its own new source file...
... These do not require header files; they are tiny proto-plugins that work by registration of AttachedVirtualFunction overrides at startup. Dependency may go from them to TrackView subclasses but not back; so in principle a reduced Audacity without time-shift could be linked that still uses the TrackView subclasses. But other work to make the hit test for the Time Shift tool registrable would have to precede that.
This commit is contained in:
committed by
James Crook
parent
4abd38b9a0
commit
2b542bf734
@@ -1303,172 +1303,3 @@ void WaveTrackView::Draw(
|
||||
|
||||
CommonTrackView::Draw( context, rect, iPass );
|
||||
}
|
||||
|
||||
class WaveTrackShifter final : public TrackShifter {
|
||||
public:
|
||||
WaveTrackShifter( WaveTrack &track )
|
||||
: mpTrack{ track.SharedPointer<WaveTrack>() }
|
||||
{
|
||||
InitIntervals();
|
||||
}
|
||||
~WaveTrackShifter() override {}
|
||||
Track &GetTrack() const override { return *mpTrack; }
|
||||
|
||||
HitTestResult HitTest(
|
||||
double time, const ViewInfo &viewInfo, HitTestParams* ) override
|
||||
{
|
||||
auto pClip = mpTrack->GetClipAtTime( time );
|
||||
|
||||
if (!pClip)
|
||||
return HitTestResult::Miss;
|
||||
|
||||
auto t0 = viewInfo.selectedRegion.t0();
|
||||
auto t1 = viewInfo.selectedRegion.t1();
|
||||
if ( mpTrack->IsSelected() && time >= t0 && time < t1 ) {
|
||||
// Unfix maybe many intervals (at least one because of test above)
|
||||
SelectInterval({t0, t1});
|
||||
return HitTestResult::Selection;
|
||||
}
|
||||
|
||||
// Select just one interval
|
||||
UnfixIntervals( [&](const auto &interval){
|
||||
return
|
||||
static_cast<WaveTrack::IntervalData*>(interval.Extra())
|
||||
->GetClip().get() == pClip;
|
||||
} );
|
||||
|
||||
return HitTestResult::Intervals;
|
||||
}
|
||||
|
||||
void SelectInterval( const TrackInterval &interval ) override
|
||||
{
|
||||
UnfixIntervals( [&](auto &myInterval){
|
||||
// Use a slightly different test from CommonSelectInterval, rounding times
|
||||
// to exact samples according to the clip's rate
|
||||
auto data =
|
||||
static_cast<WaveTrack::IntervalData*>( myInterval.Extra() );
|
||||
auto clip = data->GetClip().get();
|
||||
return !(clip->IsClipStartAfterClip(interval.Start()) ||
|
||||
clip->BeforeClip(interval.End()));
|
||||
});
|
||||
}
|
||||
|
||||
bool SyncLocks() override { return true; }
|
||||
|
||||
bool MayMigrateTo(Track &other) override
|
||||
{
|
||||
return TrackShifter::CommonMayMigrateTo(other);
|
||||
}
|
||||
|
||||
double HintOffsetLarger(double desiredOffset) override
|
||||
{
|
||||
// set it to a sample point, and minimum of 1 sample point
|
||||
bool positive = (desiredOffset > 0);
|
||||
if (!positive)
|
||||
desiredOffset *= -1;
|
||||
double nSamples = rint(mpTrack->GetRate() * desiredOffset);
|
||||
nSamples = std::max(nSamples, 1.0);
|
||||
desiredOffset = nSamples / mpTrack->GetRate();
|
||||
if (!positive)
|
||||
desiredOffset *= -1;
|
||||
return desiredOffset;
|
||||
}
|
||||
|
||||
double QuantizeOffset( double desiredOffset ) override
|
||||
{
|
||||
const auto rate = mpTrack->GetRate();
|
||||
// set it to a sample point
|
||||
return rint(desiredOffset * rate) / rate;
|
||||
}
|
||||
|
||||
double AdjustOffsetSmaller(double desiredOffset) override
|
||||
{
|
||||
std::vector< WaveClip * > movingClips;
|
||||
for ( auto &interval : MovingIntervals() ) {
|
||||
auto data =
|
||||
static_cast<WaveTrack::IntervalData*>( interval.Extra() );
|
||||
movingClips.push_back(data->GetClip().get());
|
||||
}
|
||||
double newAmount = 0;
|
||||
(void) mpTrack->CanOffsetClips(movingClips, desiredOffset, &newAmount);
|
||||
return newAmount;
|
||||
}
|
||||
|
||||
Intervals Detach() override
|
||||
{
|
||||
for ( auto &interval: mMoving ) {
|
||||
auto pData = static_cast<WaveTrack::IntervalData*>( interval.Extra() );
|
||||
auto pClip = pData->GetClip().get();
|
||||
// interval will still hold the clip, so ignore the return:
|
||||
(void) mpTrack->RemoveAndReturnClip(pClip);
|
||||
mMigrated.erase(pClip);
|
||||
}
|
||||
return std::move( mMoving );
|
||||
}
|
||||
|
||||
bool AdjustFit(
|
||||
const Track &otherTrack, const Intervals &intervals,
|
||||
double &desiredOffset, double tolerance) override
|
||||
{
|
||||
bool ok = true;
|
||||
auto pOtherWaveTrack = static_cast<const WaveTrack*>(&otherTrack);
|
||||
for ( auto &interval: intervals ) {
|
||||
auto pData =
|
||||
static_cast<WaveTrack::IntervalData*>( interval.Extra() );
|
||||
auto pClip = pData->GetClip().get();
|
||||
ok = pOtherWaveTrack->CanInsertClip(
|
||||
pClip, desiredOffset, tolerance );
|
||||
if( !ok )
|
||||
break;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool Attach( Intervals intervals ) override
|
||||
{
|
||||
for (auto &interval : intervals) {
|
||||
auto pData = static_cast<WaveTrack::IntervalData*>( interval.Extra() );
|
||||
auto pClip = pData->GetClip();
|
||||
if ( !mpTrack->AddClip( pClip ) )
|
||||
return false;
|
||||
mMigrated.insert( pClip.get() );
|
||||
mMoving.emplace_back( std::move( interval ) );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FinishMigration() override
|
||||
{
|
||||
auto rate = mpTrack->GetRate();
|
||||
for (auto pClip : mMigrated) {
|
||||
// Now that user has dropped the clip into a different track,
|
||||
// make sure the sample rate matches the destination track.
|
||||
pClip->Resample(rate);
|
||||
pClip->MarkChanged();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void DoHorizontalOffset( double offset ) override
|
||||
{
|
||||
for ( auto &interval : MovingIntervals() ) {
|
||||
auto data =
|
||||
static_cast<WaveTrack::IntervalData*>( interval.Extra() );
|
||||
data->GetClip()->Offset( offset );
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<WaveTrack> mpTrack;
|
||||
|
||||
// Clips that may require resampling
|
||||
std::unordered_set<WaveClip *> mMigrated;
|
||||
};
|
||||
|
||||
using MakeWaveTrackShifter = MakeTrackShifter::Override<WaveTrack>;
|
||||
template<> template<> auto MakeWaveTrackShifter::Implementation() -> Function {
|
||||
return [](WaveTrack &track, AudacityProject&) {
|
||||
return std::make_unique<WaveTrackShifter>(track);
|
||||
};
|
||||
}
|
||||
static MakeWaveTrackShifter registerMakeWaveTrackShifter;
|
||||
|
||||
Reference in New Issue
Block a user