Editor/MovieMaker/BlockDisplay/BlockItem.cs
using Sandbox.MovieMaker;
namespace Editor.MovieMaker.BlockDisplays;
#nullable enable
public abstract partial class BlockItem : GraphicsItem
{
private ITrackBlock? _block;
public new TimelineTrack Parent { get; private set; } = null!;
public ITrackBlock Block
{
get => _block ?? throw new InvalidOperationException();
set
{
if ( ReferenceEquals( _block, value ) ) return;
if ( _block is IDynamicBlock oldBlock )
{
oldBlock.Changed -= Block_Changed;
}
_block = value;
if ( _block is IDynamicBlock newBlock )
{
newBlock.Changed += Block_Changed;
}
}
}
public MovieTime Offset { get; set; }
protected IProjectTrack Track => Parent.View.Track;
protected MovieTimeRange TimeRange => Block.TimeRange + Offset;
protected int DataHash => HashCode.Combine( Block, TimeRange.Duration, Width );
private void Initialize( TimelineTrack parent, ITrackBlock block, MovieTime offset )
{
base.Parent = Parent = parent;
Block = block;
Offset = offset;
}
private void Block_Changed() => Layout();
protected override void OnDestroy()
{
// To remove Changed event
Block = null!;
}
public void Layout()
{
var session = Parent.Session;
PrepareGeometryChange();
Position = new Vector2( session.TimeToPixels( TimeRange.Start ), 1f );
Size = new Vector2( session.TimeToPixels( TimeRange.Duration ), Parent.Height - 2f );
Update();
}
protected override void OnPaint()
{
Paint.SetBrushAndPen( Timeline.Colors.ChannelBackground.Lighten( Parent.View.IsLocked ? 0.2f : 0f ).WithAlpha( 0.75f ) );
Paint.DrawRect( LocalRect );
if ( Parent.View.IsLocked ) return;
Paint.ClearBrush();
Paint.SetPen( Color.White.WithAlpha( 0.1f ) );
Paint.DrawLine( LocalRect.BottomLeft, LocalRect.TopLeft );
Paint.DrawLine( LocalRect.BottomRight, LocalRect.TopRight );
}
}
public interface IBlockItem<T>;
public abstract class BlockItem<T> : BlockItem, IBlockItem<T>
where T : ITrackBlock
{
public new T Block => (T)base.Block;
}
public interface IPropertyBlockItem<T>;
public abstract class PropertyBlockItem<T> : BlockItem<IPropertyBlock<T>>, IPropertyBlockItem<T>;