143 lines
5.9 KiB
C#
143 lines
5.9 KiB
C#
using ImGuiNET;
|
|
using T3.Core.Animation;
|
|
using T3.Editor.Gui.Interaction.Snapping;
|
|
using T3.Editor.Gui.Styling;
|
|
using Color = T3.Core.DataTypes.Vector.Color;
|
|
using Vector2 = System.Numerics.Vector2;
|
|
|
|
namespace T3.Editor.Gui.Windows.TimeLine;
|
|
|
|
internal sealed class ClipRange : IValueSnapAttractor
|
|
{
|
|
/// <summary>
|
|
/// Visualizes the mapped time area within a <see cref="TimeClip"/> content
|
|
/// </summary>
|
|
public void Draw(TimeLineCanvas canvas, TimeClip timeClip, ImDrawListPtr drawlist, ValueSnapHandler snapHandler)
|
|
{
|
|
if (timeClip == null)
|
|
return;
|
|
|
|
_timeClip = timeClip;
|
|
|
|
ImGui.PushStyleColor(ImGuiCol.Button, _timeRangeMarkerColor.Rgba);
|
|
var manipulationEnabled = ImGui.GetIO().KeyAlt;
|
|
|
|
// Range start
|
|
{
|
|
var xRangeStart = canvas.TransformX(timeClip.SourceRange.Start);
|
|
var rangeStartPos = new Vector2(xRangeStart, 0);
|
|
|
|
// Shade outside
|
|
drawlist.AddRectFilled(
|
|
new Vector2(0, 0),
|
|
new Vector2(xRangeStart, _timeRangeShadowSize.Y),
|
|
_timeRangeOutsideColor);
|
|
|
|
// Shadow
|
|
drawlist.AddRectFilled(
|
|
rangeStartPos - new Vector2(_timeRangeShadowSize.X - 1, 0),
|
|
rangeStartPos + new Vector2(0, _timeRangeShadowSize.Y),
|
|
_timeRangeShadowColor);
|
|
|
|
// Line
|
|
drawlist.AddRectFilled(rangeStartPos, rangeStartPos + new Vector2(1, 9999), _timeRangeShadowColor);
|
|
|
|
if (manipulationEnabled)
|
|
{
|
|
SetCursorToBottom(
|
|
xRangeStart - _timeRangeHandleSize.X,
|
|
_timeRangeHandleSize.Y);
|
|
|
|
ImGui.Button("##StartPos", _timeRangeHandleSize);
|
|
|
|
if (ImGui.IsItemActive() && ImGui.IsMouseDragging(ImGuiMouseButton.Left))
|
|
{
|
|
var newTime = canvas.InverseTransformX(ImGui.GetIO().MousePos.X);
|
|
if (snapHandler.TryCheckForSnapping(newTime, out var snappedTime, canvas.Scale.X,
|
|
[(IValueSnapAttractor)this]))
|
|
{
|
|
newTime = (float)snappedTime;
|
|
}
|
|
var delta = newTime - timeClip.SourceRange.Start;
|
|
var speed = timeClip.TimeRange.Duration / timeClip.SourceRange.Duration;
|
|
timeClip.SourceRange.Start = newTime;
|
|
timeClip.TimeRange.Start += delta * speed;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Range end
|
|
{
|
|
var rangeEndX = canvas.TransformX(timeClip.SourceRange.End);
|
|
var rangeEndPos = new Vector2(rangeEndX, 0);
|
|
|
|
// Shade outside
|
|
var windowMaxX = ImGui.GetContentRegionAvail().X + canvas.WindowPos.X;
|
|
if (rangeEndX < windowMaxX)
|
|
drawlist.AddRectFilled(
|
|
rangeEndPos,
|
|
rangeEndPos + new Vector2(windowMaxX - rangeEndX, _timeRangeShadowSize.Y),
|
|
_timeRangeOutsideColor);
|
|
|
|
// Shadow
|
|
drawlist.AddRectFilled(
|
|
rangeEndPos + new Vector2(1,0),
|
|
rangeEndPos + _timeRangeShadowSize,
|
|
_timeRangeShadowColor);
|
|
|
|
// Line
|
|
drawlist.AddRectFilled(rangeEndPos, rangeEndPos + new Vector2(1, 9999), _timeRangeShadowColor);
|
|
|
|
if (manipulationEnabled)
|
|
{
|
|
SetCursorToBottom(
|
|
rangeEndX,
|
|
_timeRangeHandleSize.Y);
|
|
|
|
ImGui.Button("##EndPos", _timeRangeHandleSize);
|
|
|
|
if (ImGui.IsItemActive() && ImGui.IsMouseDragging(ImGuiMouseButton.Left))
|
|
{
|
|
var newTime = canvas.InverseTransformX(ImGui.GetIO().MousePos.X);
|
|
if (snapHandler.TryCheckForSnapping(newTime, out var snappedTime, canvas.Scale.X, [this]))
|
|
{
|
|
newTime = (float)snappedTime;
|
|
}
|
|
|
|
var delta = newTime - timeClip.SourceRange.End;
|
|
var speed = timeClip.TimeRange.Duration / timeClip.SourceRange.Duration;
|
|
timeClip.SourceRange.End = newTime;
|
|
timeClip.TimeRange.End += delta * speed;
|
|
}
|
|
}
|
|
}
|
|
|
|
ImGui.PopStyleColor();
|
|
}
|
|
|
|
private static void SetCursorToBottom(float xInScreen, float paddingFromBottom)
|
|
{
|
|
var maxY = ImGui.GetWindowPos().Y + ImGui.GetWindowSize().Y;
|
|
ImGui.SetCursorScreenPos(new Vector2(xInScreen, maxY - paddingFromBottom));
|
|
}
|
|
|
|
private static readonly Vector2 _timeRangeHandleSize = new(10, 20);
|
|
private static readonly Vector2 _timeRangeShadowSize = new(1, 9999);
|
|
private static readonly Color _timeRangeShadowColor = UiColors.StatusAnimated.Fade(0.2f);
|
|
private static readonly Color _timeRangeOutsideColor = UiColors.StatusAnimated.Fade(0.1f);
|
|
private static readonly Color _timeRangeMarkerColor = UiColors.StatusAnimated.Fade(0.5f);
|
|
|
|
//private static Playback _playback;
|
|
private static TimeClip _timeClip;
|
|
|
|
#region implement snapping interface -----------------------------------
|
|
void IValueSnapAttractor.CheckForSnap(ref SnapResult snapResult)
|
|
{
|
|
if (_timeClip == null)
|
|
return;
|
|
|
|
snapResult.TryToImproveWithAnchorValue( _timeClip.SourceRange.Start);
|
|
snapResult.TryToImproveWithAnchorValue( _timeClip.SourceRange.End);
|
|
}
|
|
#endregion
|
|
} |