11namespace tracktion {
inline namespace engine
29 if (
id == IDs::groupID)
33 for (
auto cc : collectionClips)
35 if (cc->containsClip (c))
39 if (cc->getNumClips() == 0)
41 collectionClips.removeObject (cc);
42 ct.trackItemsDirty =
true;
46 cc->updateStartAndEnd();
47 ct.trackItemsDirty =
true;
53 auto cc = findOrCreateCollectionClip (c->getGroupID());
55 cc->updateStartAndEnd();
56 ct.trackItemsDirty =
true;
62 else if (
id == IDs::start ||
id == IDs::length)
68 if (
auto cc = findCollectionClip (c->getGroupID()))
70 cc->updateStartAndEnd();
71 ct.trackItemsDirty =
true;
86 auto cc = findOrCreateCollectionClip (c->getGroupID());
88 cc->updateStartAndEnd();
89 ct.trackItemsDirty =
true;
99 for (
auto cc : collectionClips)
101 if (cc->removeClip (EditItemID::fromID (child)))
103 if (cc->getNumClips() == 0)
105 collectionClips.removeObject (cc);
106 ct.trackItemsDirty =
true;
110 cc->updateStartAndEnd();
111 ct.trackItemsDirty =
true;
119 for (
auto cc : collectionClips)
120 if (cc->getGroupID() == groupID)
124 cc->setGroupID (groupID);
125 collectionClips.add (cc);
126 ct.trackItemsDirty =
true;
133 for (
auto cc : collectionClips)
134 if (cc->getGroupID() == groupID)
140 void clipCreated (
Clip& c)
142 auto cc = findOrCreateCollectionClip (c.getGroupID());
144 cc->updateStartAndEnd();
145 ct.trackItemsDirty =
true;
148 void valueTreeChildOrderChanged (
juce::ValueTree&,
int,
int)
override {}
161 :
Track (ed, v, hasModifierList)
166ClipTrack::~ClipTrack()
181 c->flushStateToValueTree();
185void ClipTrack::refreshTrackItems()
const
187 TRACKTION_ASSERT_MESSAGE_THREAD
191 trackItemsDirty =
false;
194 trackItems.ensureStorageAllocated (
getClips().size());
197 trackItems.add (clip);
199 for (
auto cc : collectionClipList->collectionClips)
209 return trackItems.size();
215 return trackItems[idx];
221 return trackItems.indexOf (ti);
237CollectionClip* ClipTrack::getCollectionClip (
int index)
const noexcept
239 return collectionClipList->collectionClips[index].get();
244 if (clip->isGrouped())
245 for (
auto cc : collectionClipList->collectionClips)
252int ClipTrack::getNumCollectionClips() const noexcept
254 return collectionClipList->collectionClips.size();
257int ClipTrack::indexOfCollectionClip (CollectionClip* cc)
const
259 return collectionClipList->collectionClips.indexOf (cc);
262int ClipTrack::getIndexOfNextCollectionClipAt (TimePosition time)
267CollectionClip* ClipTrack::getNextCollectionClipAt (TimePosition time)
269 return collectionClipList->collectionClips [getIndexOfNextCollectionClipAt (time)].get();
272bool ClipTrack::contains (CollectionClip* cc)
const
274 return collectionClipList->collectionClips.contains (cc);
284 if (
auto at =
dynamic_cast<const AudioTrack*
> (
this))
285 for (
auto slot :
const_cast<AudioTrack*
> (at)->getClipSlotList().getClipSlots())
286 if (
auto c = slot->getClip())
295 return toDuration (getTotalRange().getEnd());
298TimeDuration ClipTrack::getLengthIncludingInputTracks()
const
300 auto l = getLength();
303 if (t != this && t->getOutput().getDestinationTrack() == this)
304 l =
std::max (l, t->getLengthIncludingInputTracks());
309TimeRange ClipTrack::getTotalRange()
const
314bool ClipTrack::addClip (
const Clip::Ptr& clip)
324 auto um = clip->getUndoManager();
325 clip->state.getParent().removeChild (clip->state, um);
333 clip->edit.engine.getUIBehaviour().showWarningMessage (
TRANS(
"Can't add any more clips to this track!"));
339void ClipTrack::addCollectionClip (CollectionClip* cc)
341 CollectionClip::Ptr refHolder (cc);
344 for (
int i = collectionClipList->collectionClips.size(); --i >= 0;)
345 if (collectionClipList->collectionClips[i]->containsClip (cc->getClip (0).get()))
346 collectionClipList->collectionClips.remove (i);
348 collectionClipList->collectionClips.add (cc);
351void ClipTrack::removeCollectionClip (CollectionClip* cc)
353 collectionClipList->collectionClips.removeObject (cc);
363 ClipPosition position,
bool deleteExistingClips,
bool allowSpottingAdjustment)
366 position, deleteExistingClips ? DeleteExistingClips::yes :
DeleteExistingClips::no, allowSpottingAdjustment);
370 ClipPosition position,
bool deleteExistingClips)
375WaveAudioClip::Ptr ClipTrack::insertWaveClip (
const juce::String& name, ProjectItemID sourceID,
376 ClipPosition position,
bool deleteExistingClips)
381MidiClip::Ptr ClipTrack::insertMIDIClip (
const juce::String& name, TimeRange position, SelectionManager* sm)
387 sm->selectOnly (newClip.get());
388 sm->keepSelectedObjectsOnScreen();
397MidiClip::Ptr ClipTrack::insertMIDIClip (TimeRange position, SelectionManager* sm)
402EditClip::Ptr ClipTrack::insertEditClip (TimeRange position, ProjectItemID sourceID)
407void ClipTrack::deleteRegion (TimeRange range, SelectionManager* sm)
412 for (
auto newClip : newClips)
413 sm->addToSelection (newClip);
416void ClipTrack::deleteRegionOfClip (Clip::Ptr c, TimeRange range, SelectionManager* sm)
422 for (
auto newClip : newClips)
423 sm->addToSelection (newClip);
428 return insertNewClip (type, name, { pos, 0_td }, sm);
435 if (
auto newClip = insertClipWithState ({}, name, type, position,
false,
false))
439 sm->selectOnly (newClip);
440 sm->keepSelectedObjectsOnScreen();
449Clip* ClipTrack::insertNewClip (
TrackItem::Type type, TimeRange pos, SelectionManager* sm)
454bool ClipTrack::containsAnyMIDIClips()
const
482 collectionClipList->clipCreated (c);
484 trackItemsDirty =
true;
491 trackItemsDirty =
true;
498 trackItemsDirty =
true;
503 trackItemsDirty =
true;
510 for (
int i = in.
length(); --i >= 0;)
544 for (
int i = clips.size(); --i >= 0;)
546 auto c = clips.getUnchecked (i);
548 if (c->getPosition().time.getCentre() >=
time)
554 for (
int i = clipsToDo.
size(); --i >= 0;)
556 c->setStart (c->getPosition().getStart() + amountOfSpace,
false,
true);
564 cuts.addArray (o->getInterestingTimes());
575 for (
auto c : findAllTimesOfInterest())
576 if (c > t + TimeDuration::fromSeconds (0.0001))
579 return toPosition (getLength());
587 auto cuts = findAllTimesOfInterest();
589 for (
int i = cuts.
size(); --i >= 0;)
590 if (cuts.
getUnchecked (i) < t - TimeDuration::fromSeconds (0.0001))
602 if (
auto plugins = c->getPluginList())
603 if (plugins->contains (plugin))
615 destArray.addArray (c->getAllPlugins());
618 for (
auto childClip : containerClip->getClips())
619 destArray.addArray (childClip->getAllPlugins());
630 c->sendMirrorUpdateToAllPlugins (p);
633bool ClipTrack::areAnyClipsUsingFile (
const AudioFile& af)
637 if (acb->isUsingFile (af))
ElementType getUnchecked(int index) const
int size() const noexcept
static bool isDigit(char character) noexcept
int size() const noexcept
ObjectClassPtr getUnchecked(int index) const noexcept
ObjectClass * add(ObjectClass *newObject)
int length() const noexcept
String dropLastCharacters(int numberToDrop) const
int getTrailingIntValue() const noexcept
void addListener(Listener *listener)
void addChild(const ValueTree &child, int index, UndoManager *undoManager)
void removeListener(Listener *listener)
Base class for Clips that produce some kind of audio e.g.
const juce::Array< Clip * > & getClips() const
Returns the clips this owner contains.
void initialiseClipOwner(Edit &, juce::ValueTree clipParentState)
Must be called once from the subclass constructor to init the clip owner.
void flushStateToValueTree() override
Flushes all plugin states on the track to the state object.
Clip * findClipForID(EditItemID) const override
Returns a clip one with a matching ID can be found on this Track.
TimePosition getNextTimeOfInterest(TimePosition afterThisTime)
finds the next cut point
TrackItem * getTrackItem(int idx) const override
Should return the TrackItem at the given index.
EditItemID getClipOwnerID() override
Must return the ID of this ClipOwner.
void clipAddedOrRemoved() override
Called when a clip is added or removed.
Edit & getClipOwnerEdit() override
Must return the Edit this ClipOwner belongs to.
void sendMirrorUpdateToAllPlugins(Plugin &) const override
Sends a message to all plugins that the given plugin has changed.
void clipPositionChanged() override
Called when a clip start or end position has changed.
void insertSpaceIntoTrack(TimePosition, TimeDuration) override
inserts space and moves everything up
void initialise() override
Initialises the Track.
int getNumTrackItems() const override
Should return the number of TrackItem[s] on this Track.
Plugin::Array getAllPlugins() const override
Returns all pugins on this Track.
Clip * splitClip(Clip &, TimePosition)
breaks a clip into 2 bits
juce::ValueTree & getClipOwnerState() override
Must return the state of this ClipOwner.
TrackItem * getNextTrackItemAt(TimePosition) override
Should return the TrackItem after this time.
void splitAt(TimePosition)
split all clips at this time
void clipOrderChanged() override
Called when clips have moved times so that their order has changed.
bool containsPlugin(const Plugin *) const override
Tests whether this Track or a clip on it contains the given plugin.
int indexOfTrackItem(TrackItem *) const override
Should return the index of the given TrackItem.
void clipCreated(Clip &) override
Called when a clip is created which could be during Edit load.
int getIndexOfNextTrackItemAt(TimePosition) override
Should return the index of the TrackItem after this time.
Selectable * getClipOwnerSelectable() override
Must return the selectable if this ClipOwner is one.
static bool isClipState(const juce::ValueTree &)
Checks whether a ValueTree is some kind of clip state.
A clip that can contain multiple other clips and mix their output together.
const EditItemID itemID
Every EditItem has an ID which is unique within the edit.
The Tracktion Edit class!
Engine & engine
A reference to the Engine.
virtual EditLimits getEditLimits()
Should return the maximum number of elements that can be added to an Edit.
EngineBehaviour & getEngineBehaviour() const
Returns the EngineBehaviour instance.
Base class for things that can be selected, and whose properties can appear in the properties panel.
virtual void changed()
This should be called to send a change notification to any SelectableListeners that are registered wi...
Base class for EditItems that live in a Track, e.g.
Type
Defines the types of item that can live on Track[s].
static void sortByTime(ArrayType &items)
Helper function to sort an array of TrackItem[s] by their start time.
static juce::String getSuggestedNameForNewItem(Type)
Returns a text string for a new clip of the given type.
Base class for tracks which contain clips and plugins and can be added to Edit[s].
virtual void setFrozen(bool, FreezeType)
Attempts to freeze or unfreeze the track using a given FreezeType.
PluginList pluginList
The Track's PluginList.
@ groupFreeze
Freezes multiple tracks together in to a single file.
virtual void flushStateToValueTree()
Flushes all plugin states on the track to the state object.
juce::ValueTree state
The state of this Track.
virtual Plugin::Array getAllPlugins() const
Returns all pugins on this Track.
virtual void initialise()
Initialises the Track.
virtual void insertSpaceIntoTrack(TimePosition, TimeDuration)
Should insert empty space in to the track, shuffling down any items after the time.
#define TRANS(stringLiteral)
bool containsAnyMIDIClips(const ClipOwner &co)
Returns true if the clip owner contains any MIDI clips.
int findIndexOfNextItemAt(const ArrayType &items, TimePosition time)
Returns the index of the next item after the given time.
juce::Array< AudioTrack * > getAudioTracks(const Edit &edit)
Returns all the AudioTracks in an Edit.
juce::Array< Clip * > deleteRegion(ClipOwner &parent, TimeRange range)
Removes a region of a ClipOwner and returns any newly created clips.
MidiClip::Ptr insertMIDIClip(ClipOwner &parent, const juce::String &name, TimeRange position)
Inserts a new MidiClip into the ClipOwner's clip list.
juce::ReferenceCountedObjectPtr< WaveAudioClip > insertWaveClip(ClipOwner &parent, const juce::String &name, const juce::File &sourceFile, ClipPosition position, DeleteExistingClips deleteExistingClips)
Inserts a new WaveAudioClip into the ClipOwner's clip list.
TimeRange findUnionOfEditTimeRanges(const ArrayType &items)
Returns the the time range that covers all the given TrackItems.
EditClip::Ptr insertEditClip(ClipOwner &parent, TimeRange position, ProjectItemID sourceID)
Inserts a new EditClip into the ClipOwner's clip list.
DeleteExistingClips
Determines behaviour for overwriting clips.
int maxClipsInTrack
The maximum number of Clip[s] a Track can contain.
bool containsClip(const Edit &edit, Clip *clip)
Returns true if an Edit contains a given clip.
Clip * insertClipWithState(ClipOwner &clipOwner, juce::ValueTree clipState)
Inserts a clip with the given state in to the ClipOwner's clip list.
juce::Array< Clip * > split(ClipOwner &parent, TimePosition time)
Splits the given clp owner at the time and returns any newly created clips.
Represents a duration in real-life time.
Represents a position in real-life time.
ID for objects of type EditElement - e.g.
#define CRASH_TRACER
This macro adds the current location to a stack which gets logged if a crash happens.