Ejemplo n.º 1
0
// replace or paste items sub-chunk _tmpltItems
// _paste==false for replace, paste otherwise
// _p: optional (to factorize chunk updates)
bool ReplacePasteItemsFromTrackTemplate(MediaTrack* _tr, WDL_FastString* _tmpltItems, bool _paste, SNM_ChunkParserPatcher* _p)
{
	bool updated = false;
	if (_tr && _tr != GetMasterTrack(NULL) && _tmpltItems) // no items on master
	{
		SNM_ChunkParserPatcher* p = (_p ? _p : new SNM_ChunkParserPatcher(_tr));

		 // delete current items?
		if (!_paste)
			updated |= p->RemoveSubChunk("ITEM", 2, -1);

		// insert template items
		if (_tmpltItems->GetLength())
		{
			WDL_FastString tmpltItems(_tmpltItems); // do not alter _tmpltItems!

			// offset items if needed
			int* offsOpt = (int*)GetConfigVar("templateditcursor"); // >= REAPER v4.15
			if (offsOpt && *offsOpt)
			{
				double add = GetCursorPositionEx(NULL);
				SNM_ChunkParserPatcher pitems(&tmpltItems);
				pitems.ParsePatch(SNM_D_ADD, 1, "ITEM", "POSITION", -1, 1, &add);
			}

			p->GetChunk()->Insert(tmpltItems.Get(), p->GetChunk()->GetLength()-2); // -2: before ">\n"
			p->IncUpdates(); // as we directly work on the chunk
			updated = true;
		}

		if (!_p)
			DELETE_NULL(p); // + auto-commit if needed
	}
	return updated;
}
Ejemplo n.º 2
0
void FSlomoTrackEditor::HandleAddSlomoTrackMenuEntryExecute()
{
	UMovieSceneSequence* FocusedSequence = GetSequencer()->GetFocusedMovieSceneSequence();
	UMovieScene* MovieScene = FocusedSequence->GetMovieScene();
	if (MovieScene == nullptr)
	{
		return;
	}

	UMovieSceneTrack* SlomoTrack = MovieScene->FindMasterTrack( UMovieSceneSlomoTrack::StaticClass() );
	if (SlomoTrack != nullptr)
	{
		return;
	}

	const FScopedTransaction Transaction(NSLOCTEXT("Sequencer", "AddSlomoTrack_Transaction", "Add Play Rate Track"));

	MovieScene->Modify();
		
	SlomoTrack = GetMasterTrack( UMovieSceneSlomoTrack::StaticClass() );
	ensure(SlomoTrack);

	SlomoTrack->AddSection(SlomoTrack->CreateNewSection());

	GetSequencer()->NotifyMovieSceneDataChanged();
}
Ejemplo n.º 3
0
// return false if no track icon has been found
// note: _fnOutSz is ignored atm
bool GetTrackIcon(MediaTrack* _tr, char* _fnOut, int _fnOutSz)
{
	if (_tr && _fnOut && _tr!=GetMasterTrack(NULL))  // exclude master (icon not supported yet, v4.13) 
	{
		SNM_ChunkParserPatcher p(_tr);
		p.SetWantsMinimalState(true);
		return (p.Parse(SNM_GET_CHUNK_CHAR, 1, "TRACK", "TRACKIMGFN", 0, 1, _fnOut, NULL, "TRACKID") > 0);
	}
	return false;
}
Ejemplo n.º 4
0
// take the master into account (contrary to CountSelectedTracks())
int SNM_CountSelectedTracks(ReaProject* _proj, bool _master)
{
	int selCnt = CountSelectedTracks(_proj);
	if (_master) {
		MediaTrack* mtr = GetMasterTrack(_proj);
		if (mtr && *(int*)GetSetMediaTrackInfo(mtr, "I_SELECTED", NULL))
			selCnt++;
	}
	return selCnt;
}
Ejemplo n.º 5
0
// overrides the native GetTrackGUID(): returns a special GUID for the master track
// (useful for persistence as no GUID is stored in RPP files for the master..)
// note: TrackToGuid(NULL) will return also NULL, contrary to GetTrackGUID(NULL)
const GUID* TrackToGuid(MediaTrack* tr)
{
	if (tr)
	{
		if (tr == GetMasterTrack(NULL))
			return &GUID_NULL;
		else
			return GetTrackGUID(tr);
	}
	return NULL;
}
Ejemplo n.º 6
0
bool TrackMatchesGuid(MediaTrack* tr, const GUID* g)
{
	if (tr && g)
	{
		if (GuidsEqual(GetTrackGUID(tr), g))
			return true;
		// 2nd try for the master
		if (tr == GetMasterTrack(NULL))
			return GuidsEqual(g, &GUID_NULL);
	}
	return false;
}
Ejemplo n.º 7
0
// apply a track template (primitive: no undo, folder states are lost, receives are removed)
// _tmplt: the track template
// _p: optional (to factorize chunk updates)
// note: assumes _tmplt contains a single track (with items/envs already removed when _itemsFromTmplt/_envsFromTmplt are false)
//       i.e. use MakeSingleTrackTemplateChunk() first!
bool ApplyTrackTemplatePrimitive(MediaTrack* _tr, WDL_FastString* _tmplt, bool _itemsFromTmplt, bool _envsFromTmplt, SNM_SendPatcher* _p)
{
	bool updated = false;
	if (_tr && _tmplt)
	{
		WDL_FastString tmplt(_tmplt); // not to mod the input template..
		SNM_ChunkParserPatcher* p = (_p ? _p : new SNM_ChunkParserPatcher(_tr));

		// add current track items, if any
		if (!_itemsFromTmplt) 
		{
/*JFB!! works with SNM_ChunkParserPatcher v2
			WDL_FastString curItems;
			if (p->GetSubChunk("ITEM", 2, -1, &curItems) >= 0) // -1 to get all items in one go
				newChunk.Insert(&curItems, newChunk.GetLength()-2); // -2: ">\n", 
*/
			// insert current items in template
			int posItems = p->GetSubChunk("ITEM", 2, 0);
			if (posItems >= 0)
				tmplt.Insert((char*)(p->GetChunk()->Get()+posItems), tmplt.GetLength()-2, p->GetChunk()->GetLength()-posItems-2); // -2: ">\n"
		}
		// safety: force items removal for master track
		//JFB REAPER BUG: test required, items would be added to the master (!)
		else if (_tr == GetMasterTrack(NULL))
		{
			SNM_ChunkParserPatcher ptmplt(&tmplt);
			ptmplt.RemoveSubChunk("ITEM", 2, -1);
		}

		// add current track envs in template, if any
		if (!_envsFromTmplt) 
		{
/*JFB simple casting ko: _mode mess, etc...
			if (const char* envs = ((SNM_TrackEnvParserPatcher*)p)->GetTrackEnvelopes())
*/
			SNM_TrackEnvParserPatcher penv(p->GetChunk(), false); // no auto-commit!
			if (const char* envs = penv.GetTrackEnvelopes()) // get all track envs in one go, exclude fx param envs
			{
				SNM_ChunkParserPatcher ptmplt(&tmplt);
				// ">ITEM": best effort for the break keyword (fx chain might not exist, etc..)
				ptmplt.InsertAfterBefore(1, envs, "TRACK", "MAINSEND", 1, 0, "<ITEM");
			}
		}

		// the meat, apply template!
		p->SetChunk(tmplt.Get());
		updated = true;

		if (!_p)
			DELETE_NULL(p); // + auto-commit if needed
	}
	return updated;
}
Ejemplo n.º 8
0
// get a track from a project by selected track count index
// rmk: to be used with SNM_CountSelectedTracks() and not the API's 
//      CountSelectedTracks() which does not take the master into account..
MediaTrack* SNM_GetSelectedTrack(ReaProject* _proj, int _idx, bool _withMaster)
{
	if (_withMaster)
	{
		MediaTrack* mtr = GetMasterTrack(_proj);
		if (mtr && *(int*)GetSetMediaTrackInfo(mtr, "I_SELECTED", NULL)) {
			if (!_idx) return mtr;
			else return GetSelectedTrack(_proj, _idx-1);
		}
	}
	return GetSelectedTrack(_proj, _idx);
}
Ejemplo n.º 9
0
// primitive (no undo point), removes track icon if _fn == ""
bool SetTrackIcon(MediaTrack* _tr, const char* _fn)
{
	bool updated = false;
	if (_tr && _fn && _tr!=GetMasterTrack(NULL)) // exclude master (icon not supported yet, v4.13)
	{
		SNM_ChunkParserPatcher p(_tr); // nothing done yet
		int iconChunkPos = p.Parse(SNM_GET_CHUNK_CHAR, 1, "TRACK", "TRACKIMGFN", 0, 1, NULL, NULL, "TRACKID");
		char pIconLine[SNM_MAX_CHUNK_LINE_LENGTH] = "";
		if (_snprintfStrict(pIconLine, sizeof(pIconLine), "TRACKIMGFN \"%s\"\n", _fn) > 0)
		{
			if (iconChunkPos > 0)
				updated |= p.ReplaceLine(--iconChunkPos, pIconLine); //JFB!! to update with SNM_ChunkParserPatcher v2
			else 
				updated |= p.InsertAfterBefore(0, pIconLine, "TRACK", "FX", 1, 0, "TRACKID");
		}
	}
	return updated;
}
Ejemplo n.º 10
0
// apply a track template (preserves routings and folder states)
// _p: optional (to factorize chunk updates)
// note: assumes _tmplt contains a single track (with items/envs already removed when _itemsFromTmplt/_envsFromTmplt are false)
//       i.e. use MakeSingleTrackTemplateChunk() first!
bool ApplyTrackTemplate(MediaTrack* _tr, WDL_FastString* _tmplt, bool _itemsFromTmplt, bool _envsFromTmplt, void* _p)
{
	bool updated = false;
	if (_tr && _tmplt && _tmplt->GetLength())
	{
		SNM_SendPatcher* p = (_p ? (SNM_SendPatcher*)_p : new SNM_SendPatcher(_tr));

		// store receives, folder and compact states
		WDL_PtrList_DeleteOnDestroy<WDL_PtrList_DeleteOnDestroy<SNM_SndRcv> > rcvs;
		WDL_PtrList_DeleteOnDestroy<WDL_PtrList_DeleteOnDestroy<SNM_SndRcv> > snds;
		WDL_PtrList<MediaTrack> trs; trs.Add(_tr);
		WDL_FastString busLine, compbusLine;
		if (_tr != GetMasterTrack(NULL))
		{
			CopySendsReceives(true, &trs, &snds, &rcvs);
			// parse twice but it does not cost much (search at the very start of the chunk)
			p->Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "TRACK", "ISBUS", 0, -1, &busLine, NULL, "BUSCOMP");
			p->Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "TRACK", "BUSCOMP", 0, -1, &compbusLine, NULL, "SHOWINMIX");
		}

		// apply tr template
		if ((updated = ApplyTrackTemplatePrimitive(_tr, _tmplt, _itemsFromTmplt, _envsFromTmplt, p)))
		{
			// restore receives, folder and compact states
			WDL_PtrList<SNM_ChunkParserPatcher> ps; ps.Add(p);
			PasteSendsReceives(&trs, &snds, &rcvs, &ps);

			if (busLine.GetLength())
				p->ReplaceLine("TRACK", "ISBUS", 1, 0, busLine.Get(), "BUSCOMP");
			if (compbusLine.GetLength())
				p->ReplaceLine("TRACK", "BUSCOMP", 1, 0, compbusLine.Get(), "SHOWINMIX");
		}

/*JFB!! works with SNM_ChunkParserPatcher v2 + "SNM_SendPatcher" to remove

		// store current receives, folder and compact states
		// done through the chunk because the API is incomplete for folder states (tcp only)
		WDL_FastString rcvs, busLine, compbusLine;
		if (_tr != GetMasterTrack(NULL))
		{
			// parse twice but it does not cost much (search at the very start of the chunk)
			p->Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "TRACK", "AUXRECV", -1, -1, &rcvs, NULL, "MIDIOUT");
			p->Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "TRACK", "ISBUS", 0, -1, &busLine, NULL, "BUSCOMP");
			p->Parse(SNM_GET_SUBCHUNK_OR_LINE, 1, "TRACK", "BUSCOMP", 0, -1, &compbusLine, NULL, "SHOWINMIX");
		}

		// apply tr template
		if (updated = ApplyTrackTemplatePrimitive(_tr, _tmpltChunk, _itemsFromTmplt, _envsFromTmplt, p)) 
		{
			// restore receives, folder and compact states
			if (busLine.GetLength())
				p->ReplaceLine("TRACK", "ISBUS", 1, 0, busLine.Get(), "BUSCOMP");
			if (compbusLine.GetLength())
				p->ReplaceLine("TRACK", "BUSCOMP", 1, 0, compbusLine.Get(), "SHOWINMIX");
			if (rcvs.GetLength())
				p->InsertAfterBefore(0, rcvs.Get(), "TRACK", "MIDIOUT", 1, 0, "MAINSEND");
		}
*/
		if (!_p)
			DELETE_NULL(p); // + auto-commit if needed
	}
	return updated;
}
Ejemplo n.º 11
0
// get a track from a project by track count (1-based, 0 for master)
MediaTrack* SNM_GetTrack(ReaProject* _proj, int _idx) {
	if (!_idx) return GetMasterTrack(_proj);
	return GetTrack(_proj, _idx-1);
}