mirror of
https://github.com/cookiengineer/audacity
synced 2025-11-23 17:30:17 +01:00
Define class SelectionState; move some TrackPanel functions into it
This commit is contained in:
committed by
Paul Licameli
parent
986f158efa
commit
a594207265
190
src/SelectionState.cpp
Normal file
190
src/SelectionState.cpp
Normal file
@@ -0,0 +1,190 @@
|
||||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
SelectionState.h
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include "Audacity.h"
|
||||
#include "SelectionState.h"
|
||||
#include "MixerBoard.h"
|
||||
#include "ViewInfo.h"
|
||||
#include "Track.h"
|
||||
|
||||
// Set selection length to the length of a track -- but if sync-lock is turned
|
||||
// on, use the largest possible selection in the sync-lock group.
|
||||
// If it's a stereo track, do the same for the stereo channels.
|
||||
void SelectionState::SelectTrackLength
|
||||
( TrackList &tracks, ViewInfo &viewInfo, Track &track, bool syncLocked )
|
||||
{
|
||||
SyncLockedTracksIterator it( &tracks );
|
||||
Track *t1 = it.StartWith( &track );
|
||||
double minOffset = track.GetOffset();
|
||||
double maxEnd = track.GetEndTime();
|
||||
|
||||
// If we have a sync-lock group and sync-lock linking is on,
|
||||
// check the sync-lock group tracks.
|
||||
if ( syncLocked && t1 != NULL )
|
||||
{
|
||||
for ( ; t1; t1 = it.Next())
|
||||
{
|
||||
if (t1->GetOffset() < minOffset)
|
||||
minOffset = t1->GetOffset();
|
||||
if (t1->GetEndTime() > maxEnd)
|
||||
maxEnd = t1->GetEndTime();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, check for a stereo pair
|
||||
t1 = track.GetLink();
|
||||
if (t1)
|
||||
{
|
||||
if (t1->GetOffset() < minOffset)
|
||||
minOffset = t1->GetOffset();
|
||||
if (t1->GetEndTime() > maxEnd)
|
||||
maxEnd = t1->GetEndTime();
|
||||
}
|
||||
}
|
||||
|
||||
// PRL: double click or click on track control.
|
||||
// should this select all frequencies too? I think not.
|
||||
viewInfo.selectedRegion.setTimes(minOffset, maxEnd);
|
||||
}
|
||||
|
||||
void SelectionState::SelectTrack
|
||||
( TrackList &tracks, Track &track, bool selected, bool updateLastPicked,
|
||||
MixerBoard *pMixerBoard )
|
||||
{
|
||||
bool wasCorrect = (selected == track.GetSelected());
|
||||
|
||||
tracks.Select( &track, selected );
|
||||
if (updateLastPicked)
|
||||
mLastPickedTrack = &track;
|
||||
|
||||
//The older code below avoids an anchor on an unselected track.
|
||||
|
||||
/*
|
||||
if (selected) {
|
||||
// This handles the case of linked tracks, selecting all channels
|
||||
mTracks->Select(pTrack, true);
|
||||
if (updateLastPicked)
|
||||
mLastPickedTrack = pTrack;
|
||||
}
|
||||
else {
|
||||
mTracks->Select(pTrack, false);
|
||||
if (updateLastPicked && pTrack == mLastPickedTrack)
|
||||
mLastPickedTrack = nullptr;
|
||||
}
|
||||
*/
|
||||
|
||||
// Update mixer board, but only as needed so it does not flicker.
|
||||
if (!wasCorrect) {
|
||||
auto pt = dynamic_cast< PlayableTrack* >( &track );
|
||||
if (pMixerBoard && pt)
|
||||
pMixerBoard->RefreshTrackCluster( pt );
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionState::SelectRangeOfTracks
|
||||
( TrackList &tracks, Track &rsTrack, Track &reTrack, MixerBoard *pMixerBoard )
|
||||
{
|
||||
Track *sTrack = &rsTrack, *eTrack = &reTrack;
|
||||
// Swap the track pointers if needed
|
||||
if (eTrack->GetIndex() < sTrack->GetIndex())
|
||||
std::swap(sTrack, eTrack);
|
||||
|
||||
TrackListIterator iter( &tracks );
|
||||
sTrack = iter.StartWith( sTrack );
|
||||
do {
|
||||
SelectTrack( tracks, *sTrack, true, false, pMixerBoard );
|
||||
if ( sTrack == eTrack ) {
|
||||
break;
|
||||
}
|
||||
|
||||
sTrack = iter.Next();
|
||||
} while ( sTrack );
|
||||
}
|
||||
|
||||
void SelectionState::SelectNone( TrackList &tracks, MixerBoard *pMixerBoard )
|
||||
{
|
||||
TrackListIterator iter( &tracks );
|
||||
Track *track = iter.First();
|
||||
while ( track ) {
|
||||
SelectTrack( tracks, *track, false, false, pMixerBoard );
|
||||
track = iter.Next();
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionState::ChangeSelectionOnShiftClick
|
||||
( TrackList &tracks, Track &track, MixerBoard *pMixerBoard )
|
||||
{
|
||||
|
||||
// Optional: Track already selected? Nothing to do.
|
||||
// If we enable this, Shift-Click behaves like click in this case.
|
||||
//if( pTrack->GetSelected() )
|
||||
// return;
|
||||
|
||||
// Find first and last selected track.
|
||||
Track* pFirst = nullptr;
|
||||
Track* pLast = nullptr;
|
||||
// We will either extend from the first or from the last.
|
||||
Track* pExtendFrom= nullptr;
|
||||
|
||||
if( mLastPickedTrack )
|
||||
pExtendFrom = mLastPickedTrack;
|
||||
else {
|
||||
TrackListIterator iter( &tracks );
|
||||
for (Track *t = iter.First(); t; t = iter.Next()) {
|
||||
const bool isSelected = t->GetSelected();
|
||||
// Record first and last selected.
|
||||
if( isSelected ) {
|
||||
if( !pFirst )
|
||||
pFirst = t;
|
||||
pLast = t;
|
||||
}
|
||||
// If our track is at or after the first, extend from the first.
|
||||
if( t == &track )
|
||||
pExtendFrom = pFirst;
|
||||
}
|
||||
// Our track was earlier than the first. Extend from the last.
|
||||
if( !pExtendFrom )
|
||||
pExtendFrom = pLast;
|
||||
}
|
||||
|
||||
SelectNone( tracks, pMixerBoard );
|
||||
if( pExtendFrom )
|
||||
SelectRangeOfTracks( tracks, track, *pExtendFrom, pMixerBoard );
|
||||
else
|
||||
SelectTrack( tracks, track, true, true, pMixerBoard );
|
||||
mLastPickedTrack = pExtendFrom;
|
||||
}
|
||||
|
||||
void SelectionState::HandleListSelection
|
||||
( TrackList &tracks, ViewInfo &viewInfo,
|
||||
Track &track, bool shift, bool ctrl, bool syncLocked, MixerBoard *pMixerBoard )
|
||||
{
|
||||
// AS: If the shift button is being held down, invert
|
||||
// the selection on this track.
|
||||
if (ctrl)
|
||||
SelectTrack( tracks, track, !track.GetSelected(), true, pMixerBoard );
|
||||
else {
|
||||
if (shift && mLastPickedTrack)
|
||||
ChangeSelectionOnShiftClick( tracks, track, pMixerBoard );
|
||||
else {
|
||||
SelectNone( tracks, pMixerBoard );
|
||||
SelectTrack( tracks, track, true, true, pMixerBoard );
|
||||
SelectTrackLength( tracks, viewInfo, track, syncLocked );
|
||||
}
|
||||
|
||||
if (pMixerBoard)
|
||||
pMixerBoard->RefreshTrackClusters();
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionState::TrackListUpdated( const TrackList &tracks )
|
||||
{
|
||||
if (mLastPickedTrack && !tracks.Contains(mLastPickedTrack))
|
||||
mLastPickedTrack = nullptr;
|
||||
}
|
||||
Reference in New Issue
Block a user