Files
sbox-public/game/editor/MovieMaker/Code/BlockDisplay/BlockItem.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

126 lines
2.7 KiB
C#

using Sandbox.MovieMaker;
namespace Editor.MovieMaker.BlockDisplays;
#nullable enable
public abstract partial class BlockItem : GraphicsItem, ISnapSource
{
private ITrackBlock? _block;
private float _prevWidth;
public new TimelineTrack Parent { get; private set; } = null!;
public bool IsPreview { get; set; }
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;
}
if ( _block is not null )
{
OnBlockChanged( _block.TimeRange );
}
}
}
public MovieTime Offset { get; set; }
protected IProjectTrack Track => Parent.View.Track;
protected MovieTimeRange TimeRange => Block.TimeRange + Offset;
private void Initialize( TimelineTrack parent, ITrackBlock block, MovieTime offset )
{
base.Parent = Parent = parent;
Block = block;
Offset = offset;
}
private void Block_Changed( MovieTimeRange timeRange )
{
OnBlockChanged( timeRange );
}
protected virtual void OnBlockChanged( MovieTimeRange timeRange ) { }
protected override void OnDestroy()
{
// To remove Changed event
Block = null!;
}
public void Layout()
{
var session = Parent.Session;
var width = session.TimeToPixels( TimeRange.Duration );
PrepareGeometryChange();
Position = new Vector2( session.TimeToPixels( TimeRange.Start ), (Timeline.TrackHeight - Timeline.BlockHeight) * 0.5f );
Size = new Vector2( width, Timeline.BlockHeight );
if ( MathF.Abs( width - _prevWidth ) > 0.1f )
{
_prevWidth = width;
OnResize();
}
Update();
}
protected virtual void OnResize()
{
}
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 virtual IEnumerable<SnapTarget> GetSnapTargets( MovieTime sourceTime, bool isPrimary ) =>
IsPreview ? [] : [Block.TimeRange.Start, Block.TimeRange.End];
}
public interface IBlockItem
{
MovieTime Offset { get; }
}
public interface IBlockItem<T> : IBlockItem;
public abstract class BlockItem<T> : BlockItem, IBlockItem<T>
where T : ITrackBlock
{
public new T Block => (T)base.Block;
}
public interface IPropertyBlockItem<T> : IBlockItem<T>;
public abstract class PropertyBlockItem<T> : BlockItem<IPropertyBlock<T>>, IPropertyBlockItem<T>;