Re-ordering tracks

I’m trying to reorder tracks in the edit. It seems that Edit:moveTrack applies only to folder tracks as that is when the parent would change? What is the best way to reorder tracks?

Thanks

If you are using a ValueTree structure for your edit, you can do something like this;

edit.state.moveChild(selected, moveTo, &edit.getUndoManager());

Hope that helps!

1 Like

Thanks, that’s exactly what I needed!

FYI, Edit::moveTrack isn’t just for moving folder tracks. There’s some sanity checking in that method which means it should probably be used for all moves. If you take a look at the TrackInsertPoint you’ll see how to use it to move a single track.

Hope that helps.

1 Like

Thanks @dave96 - following your advice I implemented it like this:

void TCPComponent::itemDropped(const SourceDetails& dragSourceDetails)
{
	if (TCPComponent* item = dynamic_cast<TCPComponent*>(dragSourceDetails.sourceComponent.get()))
	{
		te::Track::Ptr srcTrack, destTrack;
		srcTrack = item->track;
		destTrack = this->track;
		
		if (insertBefore)
		{			
			auto tip = te::TrackInsertPoint(srcTrack->getParentTrack(), srcTrack.get());
			session.edit.moveTrack(destTrack, tip);
		}

		if (insertAfter)
		{
			auto tip = te::TrackInsertPoint(destTrack->getParentTrack(), destTrack.get());
			session.edit.moveTrack(srcTrack, tip);
		}
	}
}

Thanks, Dave!

I have updated my code to use Edit::moveTrack with TrackInsertPoint.

My approach is simply to display a PopupMenu of the tracks. One is selected. Another PopupMenu shows the selected track highlighted, and allows selecting where you want the selected track to go.

trackOrder.onClick =
[this]
{
	juce::StringArray notNeeded{ "Arranger", "Tempo", "Marker", "Chord", "Master" };
	PopupMenu selectTrack;
	auto& trackList{ edit.getTrackList() };
	for (auto track : trackList)
	{
		PopupMenu::Item popMenuItem;
		const auto trackName{ track->getName() };
		if(notNeeded.contains(trackName))
			popMenuItem.setEnabled(false);
		popMenuItem.itemID = track->getIndexInEditTrackList();
		popMenuItem.text = trackName;
		selectTrack.addItem(popMenuItem);
	}

	selectTrack.showMenuAsync(PopupMenu::Options(),
	[this, &trackList, notNeeded](int selected)
	{
		PopupMenu moveToTrack;
		for (auto track : trackList)
		{
			PopupMenu::Item popMenuItem;
			const auto trackName{ track->getName() };
			if (notNeeded.contains(trackName))
				popMenuItem.setEnabled(false);
			popMenuItem.itemID = track->getIndexInEditTrackList();
			popMenuItem.text = trackName;
			popMenuItem.setColour((popMenuItem.itemID == selected) ? Colours::yellow : Colours::white);
			moveToTrack.addItem(popMenuItem);
		}

		moveToTrack.showMenuAsync(PopupMenu::Options(),
		[this, selected, &trackList](int moveTo)
		{
			te::TrackInsertPoint insertPoint{ *trackList[moveTo], true };
			edit.moveTrack(trackList[selected], insertPoint);
		}
		);
	});
};

For my purposes, this works great!