Track *SyncLockedTracksIterator::StartWith(Track * member) { Track *t = NULL; // A sync-locked group consists of any positive number of wave tracks followed by any // non-negative number of label tracks. Step back through any label tracks, // and then through the wave tracks above them. while (member && member->GetKind() == Track::Label) { member = l->GetPrev(member); } while (member && (member->GetKind() == Track::Wave #ifdef USE_MIDI || member->GetKind() == Track::Note #endif )) { t = member; member = l->GetPrev(member); } // Make it current (if t is still NULL there are no wave tracks, so we're // not in a sync-locked group). if (t) cur = (TrackListNode *) t->GetNode(); mInLabelSection = false; return t; }
bool TrackList::MoveDown(Track * t) { if (t) { Track *n = GetNext(t, true); if (n) { SwapNodes(t->GetNode(), n->GetNode()); return true; } } return false; }
bool TrackList::MoveUp(Track * t) { if (t) { Track *p = GetPrev(t, true); if (p) { SwapNodes(p->GetNode(), t->GetNode()); return true; } } return false; }
// Precondition: if either of s1 or s2 are "linked", then // s1 and s2 must each be the FIRST node of the linked pair. // // This is used when you want to swap the track or pair of // tracks in s1 with the track or pair of tracks in s2. // The complication is that the tracks are stored in a single // linked list, and pairs of tracks are marked only by a flag // in one of the tracks. void TrackList::SwapNodes(TrackListNode * s1, TrackListNode * s2) { Track *link; Track *source[4]; TrackListNode *target[4]; // if a null pointer is passed in, we want to know about it wxASSERT(s1); wxASSERT(s2); // Deal with firat track in each team link = s1->t->GetLink(); if (!s1->t->GetLinked() && link) { s1 = (TrackListNode *) link->GetNode(); } link = s2->t->GetLink(); if (!s2->t->GetLinked() && link) { s2 = (TrackListNode *) link->GetNode(); } target[0] = s1; source[0] = target[0]->t; if (source[0]->GetLinked()) { target[1] = target[0]->next; source[1] = target[1]->t; } else { target[1] = NULL; source[1] = NULL; } target[2] = s2; source[2] = target[2]->t; if (source[2]->GetLinked()) { target[3] = target[2]->next; source[3] = target[3]->t; } else { target[3] = NULL; source[3] = NULL; } int s = 2; for (int t = 0; t < 4; t++) { if (target[t]) { target[t]->t = source[s]; target[t]->t->SetOwner(NULL, NULL); target[t]->t->SetOwner(this, target[t]); s = (s + 1) % 4; if (!source[s]) { s = (s + 1) % 4; } } } RecalcPositions(s1); UpdatedEvent(s1); ResizedEvent(s1); }
// This is used when you want to swap the track or pair of // tracks in s1 with the track or pair of tracks in s2. // The complication is that the tracks are stored in a single // linked list, and pairs of tracks are marked only by a flag // in one of the tracks. void TrackList::SwapNodes(TrackNodePointer s1, TrackNodePointer s2) { // if a null pointer is passed in, we want to know about it wxASSERT(!isNull(s1)); wxASSERT(!isNull(s2)); // Deal with first track in each team Track *link; link = (*s1)->GetLink(); bool linked1 = link != nullptr; if (linked1 && !(*s1)->GetLinked()) { s1 = link->GetNode(); } link = (*s2)->GetLink(); bool linked2 = link != nullptr; if (linked2 && !(*s2)->GetLinked()) { s2 = link->GetNode(); } // Safety check... if (s1 == s2) return; // Be sure s1 is the earlier iterator if ((*s1)->GetIndex() >= (*s2)->GetIndex()) { std::swap(s1, s2); std::swap(linked1, linked2); } // Remove tracks value_type save11 = std::move(*s1), save12{}; s1 = erase(s1); if (linked1) { wxASSERT(s1 != s2); save12 = std::move(*s1), s1 = erase(s1); } const bool same = (s1 == s2); value_type save21 = std::move(*s2), save22{}; s2 = erase(s2); if (linked2) save22 = std::move(*s2), s2 = erase(s2); if (same) // We invalidated s1! s1 = s2; // Reinsert them Track *pTrack; if (save22) pTrack = save22.get(), pTrack->SetOwner(this, s1 = insert(s1, std::move(save22))); pTrack = save21.get(), pTrack->SetOwner(this, s1 = insert(s1, std::move(save21))); if (save12) pTrack = save12.get(), pTrack->SetOwner(this, s2 = insert(s2, std::move(save12))); pTrack = save11.get(), pTrack->SetOwner(this, s2 = insert(s2, std::move(save11))); // Now correct the Index in the tracks, and other things RecalcPositions(s1); UpdatedEvent(s1); ResizedEvent(s1); }