120 lines
4.7 KiB
C#
120 lines
4.7 KiB
C#
#nullable enable
|
|
using ImGuiNET;
|
|
using T3.Core.Animation;
|
|
using T3.Core.DataTypes.Vector;
|
|
using T3.Editor.Gui.Interaction.Snapping;
|
|
|
|
namespace T3.Editor.Gui.Windows.TimeLine;
|
|
|
|
internal sealed class LoopRange : IValueSnapAttractor
|
|
{
|
|
public void Draw(TimeLineCanvas canvas, Playback playback, ImDrawListPtr drawlist, ValueSnapHandler snapHandler)
|
|
{
|
|
_playback = playback;
|
|
|
|
|
|
ImGui.PushStyleColor(ImGuiCol.Button, _timeRangeMarkerColor.Rgba);
|
|
|
|
// Range start
|
|
{
|
|
var xRangeStart = canvas.TransformX(playback.LoopRange.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);
|
|
|
|
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 snappedValue, canvas.Scale.X, [this]))
|
|
{
|
|
newTime = (float)snappedValue;
|
|
}
|
|
playback.LoopRange.Start = newTime;
|
|
}
|
|
}
|
|
|
|
// Range end
|
|
{
|
|
var rangeEndX = canvas.TransformX(playback.LoopRange.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,
|
|
rangeEndPos + _timeRangeShadowSize,
|
|
_timeRangeShadowColor);
|
|
|
|
// Line
|
|
drawlist.AddRectFilled(rangeEndPos, rangeEndPos + new Vector2(1, 9999), _timeRangeShadowColor);
|
|
|
|
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 snappedValue, canvas.Scale.X, [this]))
|
|
{
|
|
newTime = (float)snappedValue;
|
|
}
|
|
playback.LoopRange.End = newTime;
|
|
}
|
|
}
|
|
|
|
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(5, 9999);
|
|
private static readonly Color _timeRangeShadowColor = new(0, 0, 0, 0.5f);
|
|
private static readonly Color _timeRangeOutsideColor = new(0.0f, 0.0f, 0.0f, 0.3f);
|
|
private static readonly Color _timeRangeMarkerColor = new(1f, 1, 1f, 0.3f);
|
|
private Playback? _playback;
|
|
|
|
#region implement snapping interface -----------------------------------
|
|
void IValueSnapAttractor.CheckForSnap(ref SnapResult snapResult)
|
|
{
|
|
if (_playback == null)
|
|
return;
|
|
|
|
snapResult.TryToImproveWithAnchorValue(_playback.LoopRange.Start);
|
|
snapResult.TryToImproveWithAnchorValue(_playback.LoopRange.End);
|
|
}
|
|
#endregion
|
|
} |