Files
sbox-public/game/editor/MovieMaker/Code/Modes/Motion/TrackModification.cs
s&box team 71f266059a Open source release
This commit imports the C# engine code and game files, excluding C++ source code.

[Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
2025-11-24 09:05:18 +00:00

98 lines
2.2 KiB
C#

using Sandbox.MovieMaker;
namespace Editor.MovieMaker;
#nullable enable
/// <summary>
/// Holds and applies pending changes for a track.
/// </summary>
public interface ITrackModificationPreview
{
IProjectPropertyTrack Track { get; }
ITrackModification? Modification { get; set; }
void Clear();
bool Update( TimeSelection selection, IModificationOptions options );
bool Commit( TimeSelection selection, IModificationOptions options );
}
internal sealed class TrackModificationPreview<T> : ITrackModificationPreview
{
public EditMode EditMode { get; }
public ProjectPropertyTrack<T> Track { get; }
public TrackView View { get; }
IProjectPropertyTrack ITrackModificationPreview.Track => Track;
private readonly List<PropertyBlock<T>> _original = new();
private readonly List<PropertyBlock<T>> _applied = new();
private MovieTimeRange? _lastSliceRange;
public ITrackModification<T>? Modification { get; set; }
ITrackModification? ITrackModificationPreview.Modification
{
get => Modification;
set
{
Modification = (ITrackModification<T>?)value;
_original.Clear();
_lastSliceRange = null;
}
}
public TrackModificationPreview( EditMode editMode, ProjectPropertyTrack<T> track )
{
EditMode = editMode;
Track = track;
View = EditMode.Session.TrackList.Find( track )
?? throw new Exception( "Can't find view for track!" );
}
public void Clear()
{
View.ClearPreviewBlocks();
}
public bool Update( TimeSelection selection, IModificationOptions options )
{
if ( Modification is not { } modification || View.IsLocked )
{
Clear();
return false;
}
var timeRange = selection.TotalTimeRange;
if ( _lastSliceRange != timeRange )
{
_lastSliceRange = timeRange;
_original.Clear();
_original.AddRange( Track.Slice( timeRange ) );
}
_applied.Clear();
_applied.AddRange( modification.Apply( _original, selection, options ) );
View.SetPreviewBlocks( _original, _applied );
return true;
}
public bool Commit( TimeSelection selection, IModificationOptions options )
{
if ( !Update( selection, options ) || _applied is not { } blended ) return false;
var changed = Track.AddRange( blended );
Clear();
return changed;
}
}