11namespace tracktion {
inline namespace engine
16 inline UIBehaviour& getCurrentUIBehaviour()
20 return e->getUIBehaviour();
23 inline PropertyStorage& getCurrentPropertyStorage()
27 return e->getPropertyStorage();
30 inline Edit* getCurrentlyFocusedEdit()
32 if (
auto e = getCurrentUIBehaviour().getCurrentlyFocusedEdit())
38 inline TransportControl* getActiveTransport()
40 if (
auto ed = getCurrentlyFocusedEdit())
41 return &ed->getTransport();
46 inline SelectionManager* getCurrentlyFocusedSelectionManagerWithValidEdit()
48 if (
auto sm = getCurrentUIBehaviour().getCurrentlyFocusedSelectionManager())
49 if (sm->edit !=
nullptr)
55 inline SelectableList getSelectedItems()
59 if (
auto ed = getCurrentlyFocusedEdit())
60 for (SelectionManager::Iterator sm; sm.next();)
61 if (sm->getEdit() == ed)
62 for (
auto s : sm->getSelectedObjects())
63 items.addIfNotAlreadyThere (s);
68 bool pasteIntoProject (Project& p)
70 if (
auto content = Clipboard::getInstance()->getContentWithType<Clipboard::ProjectItems>())
71 return content->pasteIntoProject (p);
76 inline void nudgeSelected (
const juce::String& commandDesc)
78 getCurrentUIBehaviour().nudgeSelected (commandDesc);
81 inline void zoomHorizontal (
float increment)
83 getCurrentUIBehaviour().zoomHorizontal (increment);
86 inline void zoomVertical (
float amount)
88 getCurrentUIBehaviour().zoomVertical (amount);
93 auto& ui = getCurrentUIBehaviour();
95 if (
auto sm = ui.getCurrentlyFocusedSelectionManager())
96 if (sm->cutSelected())
97 ui.showInfoMessage (
TRANS(
"Copied to clipboard"));
102 auto& ui = getCurrentUIBehaviour();
104 if (
auto sm = ui.getCurrentlyFocusedSelectionManager())
105 if (sm->copySelected())
106 ui.showInfoMessage (
TRANS(
"Copied to clipboard"));
111 auto& ui = getCurrentUIBehaviour();
113 if (ui.paste (*Clipboard::getInstance()))
116 if (
auto p = ui.getCurrentlyFocusedProject())
117 if (pasteIntoProject (*p))
120 ui.showWarningMessage (
TRANS(
"No suitable target for pasting the items on the clipboard!"));
125 if (
auto sm = getCurrentlyFocusedSelectionManagerWithValidEdit())
126 if (sm->insertPoint !=
nullptr)
127 if (
auto clips = Clipboard::getInstance()->getContentWithType<Clipboard::Clips>())
128 clips->pasteInsertingAtCursorPos (*sm->getEdit(), *sm->insertPoint, *sm);
131 void deleteSelected()
133 if (! juce::Component::isMouseButtonDownAnywhere())
134 if (
auto sm = getCurrentUIBehaviour().getCurrentlyFocusedSelectionManager())
135 sm->deleteSelected();
140 if (
auto sm = getCurrentlyFocusedSelectionManagerWithValidEdit())
142 if (sm->containsType<Track>())
149 void deleteRegionAndCloseGapFromSelected()
151 if (
auto sm = getCurrentlyFocusedSelectionManagerWithValidEdit())
153 if (sm->containsType<Track>())
160 void deleteRegionAndCloseGap()
162 if (
auto sm = getCurrentlyFocusedSelectionManagerWithValidEdit())
164 if (sm->containsType<Track>())
173 if (
auto transport = getActiveTransport())
175 toStart (*transport, getSelectedItems());
176 transport->startPosition = transport->getPosition();
182 if (
auto transport = getActiveTransport())
184 toEnd (*transport, getSelectedItems());
185 transport->startPosition = transport->getPosition();
189 void markIn (
bool forceAtCursor)
191 if (
auto transport = getActiveTransport())
192 transport->setLoopIn (forceAtCursor ? transport->position.get()
193 : getCurrentUIBehaviour().getEditingPosition (transport->edit));
196 void markOut (
bool forceAtCursor)
198 if (
auto transport = getActiveTransport())
199 transport->setLoopOut (forceAtCursor ? transport->position.get()
200 : getCurrentUIBehaviour().getEditingPosition (transport->edit));
205 if (
auto edit = getCurrentlyFocusedEdit())
206 edit->getTransport().play (
true);
211 if (
auto transport = getActiveTransport())
213 if (transport->isPlaying())
215 transport->stop (
false,
false,
true);
219 transport->startPosition = 0_tp;
220 transport->setPosition (0_tp);
227 if (
auto transport = getActiveTransport())
229 if (transport->isPlaying())
235 if (getCurrentPropertyStorage().getProperty (SettingID::resetCursorOnPlay))
236 transport->playFromStart (
true);
238 transport->play (
true);
243 void continueStopPlay()
245 if (
auto transport = getActiveTransport())
247 if (transport->isPlaying())
250 transport->play (
true);
256 if (
auto transport = getActiveTransport())
258 const bool wasRecording = transport->isRecording();
262 transport->stop (
false,
false);
266 getCurrentUIBehaviour().stopPreviewPlayback();
268 if (! transport->isPlaying())
269 if (getCurrentPropertyStorage().getProperty (SettingID::resetCursorOnPlay))
270 transport->setPosition (transport->startPosition);
272 transport->record (
true,
true);
277 void toggleTimecode()
279 if (
auto ed = getCurrentlyFocusedEdit())
280 ed->toggleTimecodeMode();
285 if (
auto tc = getActiveTransport())
286 tc->looping = ! tc->looping;
291 if (
auto ed = getCurrentlyFocusedEdit())
293 if (ed->getTransport().isRecording())
294 ed->getTransport().stop (
false,
false);
296 ed->recordingPunchInOut = ! ed->recordingPunchInOut;
302 if (
auto tc = getActiveTransport())
303 tc->snapToTimecode = ! tc->snapToTimecode;
308 if (
auto ed = getCurrentlyFocusedEdit())
309 ed->clickTrackEnabled = ! ed->clickTrackEnabled;
312 void toggleMidiChase()
314 if (
auto ed = getCurrentlyFocusedEdit())
315 ed->enableTimecodeSync (! ed->isTimecodeSyncEnabled());
320 if (
auto transport = getActiveTransport())
326 if (
auto transport = getActiveTransport())
330 void nudgeUp() { nudgeSelected (
"up"); }
331 void nudgeDown() { nudgeSelected (
"down"); }
332 void nudgeLeft() { nudgeSelected (
"left"); }
333 void nudgeRight() { nudgeSelected (
"right"); }
335 void zoomIn() { zoomHorizontal (0.2f); }
336 void zoomOut() { zoomHorizontal (-0.2f); }
338 void scrollTracksUp()
340 getCurrentUIBehaviour().scrollTracksUp();
343 void scrollTracksDown()
345 getCurrentUIBehaviour().scrollTracksDown();
348 void scrollTracksLeft()
350 getCurrentUIBehaviour().scrollTracksLeft();
353 void scrollTracksRight()
355 getCurrentUIBehaviour().scrollTracksRight();
358 void toggleEndToEnd()
360 if (
auto ed = getCurrentlyFocusedEdit())
361 ed->playInStopEnabled = ! ed->playInStopEnabled;
366 if (
auto ed = getCurrentlyFocusedEdit())
367 return EditFileOperations (*ed).save (
true,
true,
false);
374 if (
auto ed = getCurrentlyFocusedEdit())
375 return EditFileOperations (*ed).saveAs();
380 void armOrDisarmAllInputs()
382 if (
auto ed = getCurrentlyFocusedEdit())
387 for (
auto in : ed->getAllInputDevices())
393 if (in->isRecordingEnabled (t->itemID))
401 for (
auto in : ed->getAllInputDevices())
404 in->setRecordingEnabled (t->itemID, numArmed <= numDisarmed);
410 if (
auto transport = getActiveTransport())
411 transport->setPosition (transport->getLoopRange().getStart());
416 if (
auto transport = getActiveTransport())
417 transport->setPosition (transport->getLoopRange().getEnd());
420 void zoomToSelection()
422 getCurrentUIBehaviour().zoomToSelection();
425 void zoomTracksIn() { zoomVertical (1.1f); }
426 void zoomTracksOut() { zoomVertical (1.0f / 1.1f); }
428 void zoomToFitHorizontally()
430 getCurrentUIBehaviour().zoomToFitHorizontally();
433 void zoomToFitVertically()
435 getCurrentUIBehaviour().zoomToFitVertically();
440 zoomToFitHorizontally();
441 zoomToFitVertically();
444 void moveToNextMarker()
446 if (
auto transport = getActiveTransport())
447 if (
auto clip = transport->edit.getMarkerManager().getNextMarker (transport->getPosition()))
448 transport->setPosition (clip->getPosition().getStart());
451 void moveToPrevMarker()
453 if (
auto transport = getActiveTransport())
454 if (
auto clip = transport->edit.getMarkerManager().getPrevMarker (transport->getPosition()))
455 transport->setPosition (clip->getPosition().getStart());
460 if (
auto ed = getCurrentlyFocusedEdit())
466 if (
auto ed = getCurrentlyFocusedEdit())
472 getCurrentUIBehaviour().toggleScroll();
477 return getCurrentUIBehaviour().isScrolling();
480 void stopRecordingAndDiscard()
482 if (
auto transport = getActiveTransport())
483 transport->stop (
true,
false);
486 void stopRecordingAndRestart()
488 if (
auto transport = getActiveTransport())
490 if (transport->isRecording())
492 transport->stop (
true,
true);
493 transport->record (
true,
true);
498 void insertTempoChange()
500 if (
auto sm = getCurrentlyFocusedSelectionManagerWithValidEdit())
502 auto& edit = *sm->getEdit();
503 auto& tempoSequence = edit.tempoSequence;
505 if (tempoSequence.getNumTempos() >= 128)
507 edit.engine.getUIBehaviour().showWarningAlert (
TRANS(
"Can't insert tempo"),
508 TRANS(
"There are already too many tempos in this edit!"));
512 auto nearestBeat = TimecodeSnapType::get1BeatSnapType()
513 .roundTimeNearest (getCurrentUIBehaviour().getEditingPosition (edit), tempoSequence);
515 if (
auto newTempo = tempoSequence.insertTempo (nearestBeat))
516 sm->selectOnly (*newTempo);
518 edit.engine.getUIBehaviour().showWarningMessage (
TRANS(
"Tempo changes must be further than 1 beat apart") +
"...");
523 void insertPitchChange()
525 if (
auto sm = getCurrentlyFocusedSelectionManagerWithValidEdit())
526 if (
auto newPitch = sm->getEdit()->pitchSequence.insertPitch (getCurrentUIBehaviour().getEditingPosition (*sm->getEdit())))
527 sm->selectOnly (*newPitch);
530 void insertTimeSigChange()
532 if (
auto sm = getCurrentlyFocusedSelectionManagerWithValidEdit())
534 auto& edit = *sm->getEdit();
535 auto& tempoSequence = edit.tempoSequence;
537 if (tempoSequence.getNumTimeSigs() >= 128)
539 edit.engine.getUIBehaviour().showWarningAlert (
TRANS(
"Can't insert time signature"),
540 TRANS(
"There are already too many time signatures in this edit!"));
544 auto nearestBeat = TimecodeSnapType::get1BeatSnapType()
545 .roundTimeNearest (getCurrentUIBehaviour().getEditingPosition (edit), tempoSequence);
547 if (
auto newTempo = tempoSequence.insertTimeSig (nearestBeat))
548 sm->selectOnly (*newTempo);
550 edit.engine.getUIBehaviour().showWarningMessage (
TRANS(
"Time signature changes must be further than 1 beat apart")+
"...");
557 if (
auto sm = getCurrentlyFocusedSelectionManagerWithValidEdit())
559 auto& edit = *sm->getEdit();
561 if (
auto ct = edit.getChordTrack())
563 const auto start = edit.getTransport().getPosition();
564 auto& tempo = edit.tempoSequence.getTempoAt (start);
565 auto approxOneBarLength = TimeDuration::fromSeconds (tempo.getMatchingTimeSig().numerator * tempo.getApproxBeatLength().inSeconds());
574 getCurrentUIBehaviour().showHideVideo();
577 void showHideMixer (
bool fs)
579 getCurrentUIBehaviour().showHideMixer (fs);
582 void showHideMidiEditor (
bool fs)
584 getCurrentUIBehaviour().showHideMidiEditor (fs);
587 void showHideTrackEditor (
bool zoom)
589 getCurrentUIBehaviour().showHideTrackEditor (zoom);
592 void showHideBrowser()
594 getCurrentUIBehaviour().showHideBrowser();
597 void showHideActions()
599 getCurrentUIBehaviour().showHideActions();
602 void showHideAllPanes()
604 getCurrentUIBehaviour().showHideAllPanes();
607 void performUserAction (
int a)
609 getCurrentUIBehaviour().performUserAction (a);
614 if (
auto sm = getCurrentlyFocusedSelectionManagerWithValidEdit())
616 auto selected = sm->getSelectedObjects();
617 selected.mergeArray (
splitClips (getCurrentUIBehaviour().getAssociatedClipsToEdit (selected),
618 getCurrentUIBehaviour().getEditingPosition (*sm->getEdit())));
619 sm->select (selected);
623 void toggleAutomationReadMode()
625 if (
auto ed = getCurrentlyFocusedEdit())
627 auto& arm = ed->getAutomationRecordManager();
628 arm.setReadingAutomation (! arm.isReadingAutomation());
632 void toggleAutomationWriteMode()
634 if (
auto ed = getCurrentlyFocusedEdit())
635 ed->getAutomationRecordManager().toggleWriteAutomationMode();
638 void showHideBigMeters()
640 auto& ui = getCurrentUIBehaviour();
641 ui.setBigInputMetersMode (! ui.getBigInputMetersMode());
644 void showHideInputs()
646 getCurrentUIBehaviour().showHideInputs();
649 void showHideOutputs()
651 getCurrentUIBehaviour().showHideOutputs();
654 void showProjectScreen() { getCurrentUIBehaviour().showProjectScreen(); }
655 void showSettingsScreen() { getCurrentUIBehaviour().showSettingsScreen(); }
656 void showEditScreen() { getCurrentUIBehaviour().showEditScreen(); }
658 void resetOverloads()
660 getCurrentUIBehaviour().resetOverloads();
665 getCurrentUIBehaviour().resetPeaks();
668 void toggleTrackFreeze()
670 if (
auto sm = getCurrentlyFocusedSelectionManagerWithValidEdit())
672 auto tracks = sm->getItemsOfType<AudioTrack>();
676 for (
auto t : tracks)
677 if (t->isFrozen (Track::anyFreeze))
680 if (freezeCount == 0)
682 for (
auto t : tracks)
683 if (! t->isFrozen (Track::anyFreeze))
684 t->setFrozen (true, Track::individualFreeze);
688 for (
auto t : tracks)
static juce::Array< Engine * > getEngines()
Returns the list of currently active engines.
@ individualFreeze
Freezes a track in to a single audio file.
@ groupFreeze
Freezes multiple tracks together in to a single file.
#define TRANS(stringLiteral)
SelectableList splitClips(const SelectableList &clips, TimePosition time)
Splits the clips at a given time.
@ no
Don't move up subsequent track content.
@ yes
Do move up subsequent track content.
bool isAttached(InputDeviceInstance &instance)
Returns true if this input is assigned to a target.
juce::Array< Clip * > deleteRegion(ClipOwner &parent, TimeRange range)
Removes a region of a ClipOwner and returns any newly created clips.
void markOut(TransportControl &tc)
Sets the mark out position to the current transport position.
void deleteRegionOfTracks(Edit &edit, TimeRange rangeToDelete, bool onlySelected, CloseGap closeGap, SelectionManager *selectionManager)
Deletes a time range of an Edit, optionally closing the gap.
void toStart(TransportControl &tc, const SelectableList &items)
Moves the transport to the start of the selected objects.
void toEnd(TransportControl &tc, const SelectableList &items)
Moves the transport to the end of the selected objects.
void deleteRegionOfSelectedClips(SelectionManager &selectionManager, TimeRange rangeToDelete, CloseGap closeGap, bool moveAllSubsequentClipsOnTrack)
Deletes a time range of a Clip selection, optionally closing the gap.
void markIn(TransportControl &tc)
Sets the mark in position to the current transport position.
void tabBack(TransportControl &tc)
Moves the transport back to the previous point of interest.
void tabForward(TransportControl &tc)
Moves the transport forwards to the next point of interest.
juce::Array< AudioTrack * > getTargetTracks(InputDeviceInstance &instance)
Returns the AudioTracks this instance is assigned to.
juce::Array< Clip * > split(ClipOwner &parent, TimePosition time)
Splits the given clp owner at the time and returns any newly created clips.