192 lines
8.6 KiB
C#
192 lines
8.6 KiB
C#
#nullable enable
|
|
using ImGuiNET;
|
|
using T3.Core.DataTypes.Vector;
|
|
using T3.Core.Operator;
|
|
using T3.Core.Operator.Slots;
|
|
using T3.Core.Utils;
|
|
using T3.Editor.Gui.Interaction.TransformGizmos;
|
|
using T3.Editor.Gui.Styling;
|
|
using T3.Editor.Gui.UiHelpers;
|
|
using T3.Editor.Gui.Windows;
|
|
using T3.Editor.Gui.Windows.RenderExport;
|
|
using T3.Editor.UiModel;
|
|
using T3.Editor.UiModel.ProjectHandling;
|
|
using Color = T3.Core.DataTypes.Vector.Color;
|
|
using Vector2 = System.Numerics.Vector2;
|
|
|
|
namespace T3.Editor.Gui.Legacy.Interaction.Connections;
|
|
|
|
internal static class ConnectionSplitHelper
|
|
{
|
|
public static void PrepareNewFrame(ProjectView components)
|
|
{
|
|
_mousePosition = ImGui.GetMousePos();
|
|
BestMatchLastFrame = _bestMatchYetForCurrentFrame;
|
|
if (components.GraphView is not GraphView graphCanvas)
|
|
return;
|
|
|
|
if (BestMatchLastFrame != null
|
|
&& !ConnectionMaker.HasTempConnectionsFor(graphCanvas))
|
|
{
|
|
var time = ImGui.GetTime();
|
|
if (_hoverStartTime < 0)
|
|
_hoverStartTime = time;
|
|
|
|
var hoverDuration = time - _hoverStartTime;
|
|
var radius = EaseFunctions.EaseOutElastic((float)hoverDuration) * 4;
|
|
var drawList = ImGui.GetForegroundDrawList();
|
|
|
|
drawList.AddCircleFilled(BestMatchLastFrame.PositionOnScreen, radius, BestMatchLastFrame.Color, 30);
|
|
|
|
var buttonMin = _mousePosition - Vector2.One * radius / 2;
|
|
ImGui.SetCursorScreenPos(buttonMin);
|
|
|
|
if (ImGui.InvisibleButton("splitMe", Vector2.One * radius.ClampMin(1)))
|
|
{
|
|
var posOnScreen = graphCanvas.InverseTransformPositionFloat(BestMatchLastFrame.PositionOnScreen)
|
|
- new Vector2(SymbolUi.Child.DefaultOpSize.X * 0.25f,
|
|
SymbolUi.Child.DefaultOpSize.Y * 0.5f);
|
|
|
|
ConnectionMaker.SplitConnectionWithSymbolBrowser(components, components.CompositionInstance!.Symbol,
|
|
BestMatchLastFrame.Connection,
|
|
posOnScreen, graphCanvas.SymbolBrowser);
|
|
}
|
|
|
|
ImGui.BeginTooltip();
|
|
{
|
|
var connection = BestMatchLastFrame.Connection;
|
|
|
|
ISlot? outputSlot = null;
|
|
Symbol.Child.Output? output = null;
|
|
Symbol.OutputDefinition? outputDefinition;
|
|
|
|
var op = components.CompositionInstance!;
|
|
|
|
Symbol.Child? sourceOp = null;
|
|
if (op.Children.TryGetChildInstance(connection.SourceParentOrChildId, out var sourceOpInstance))
|
|
{
|
|
sourceOp = sourceOpInstance.SymbolChild;
|
|
outputDefinition = sourceOpInstance.Symbol.OutputDefinitions.SingleOrDefault(outDef => outDef.Id == connection.SourceSlotId);
|
|
if (outputDefinition != null && sourceOp != null)
|
|
{
|
|
output = sourceOp.Outputs[connection.SourceSlotId];
|
|
outputSlot = sourceOpInstance.Outputs.Single(slot => slot.Id == outputDefinition.Id);
|
|
}
|
|
}
|
|
|
|
Symbol.Child.Input? input = null;
|
|
if (op.Symbol.Children.TryGetValue(connection.TargetParentOrChildId, out var targetOp))
|
|
{
|
|
input = targetOp.Inputs[connection.TargetSlotId];
|
|
}
|
|
|
|
if (outputSlot != null && output != null && input != null)
|
|
{
|
|
|
|
var width = 160f;
|
|
ImGui.SetNextWindowSizeConstraints(new Vector2(200, 200*9/16f), new Vector2(200, 200*9/16f));
|
|
|
|
ImGui.BeginChild("thumbnail", new Vector2(width, width * 9 / 16f));
|
|
{
|
|
|
|
TransformGizmoHandling.SetDrawList(drawList);
|
|
_imageCanvasForTooltips.Update();
|
|
_imageCanvasForTooltips.SetAsCurrent();
|
|
|
|
//var sourceOpUi = SymbolUiRegistry.Entries[graphCanvas.CompositionOp.Symbol.Id].ChildUis.Single(childUi => childUi.Id == sourceOp.Id);
|
|
if (sourceOpInstance != null)
|
|
{
|
|
var sourceOpUi = sourceOpInstance.GetSymbolUi();
|
|
var outputUi = sourceOpUi.OutputUis[output.OutputDefinition.Id];
|
|
_evaluationContext.Reset();
|
|
|
|
_evaluationContext.RequestedResolution = RenderProcess.OutputWindow != null
|
|
? RenderProcess.OutputWindow.RequestedResolution
|
|
: new Int2(1280 / 2, 1720 / 2);
|
|
|
|
outputUi.DrawValue(outputSlot,
|
|
_evaluationContext,
|
|
"connectionLineThumbnail",
|
|
recompute: UserSettings.Config.HoverMode == UserSettings.GraphHoverModes.Live);
|
|
}
|
|
|
|
// if (!string.IsNullOrEmpty(sourceOpUi.Description))
|
|
// {
|
|
// ImGui.Spacing();
|
|
// ImGui.PushFont(Fonts.FontSmall);
|
|
// ImGui.PushStyleColor(ImGuiCol.Text, new Color(1, 1, 1, 0.5f).Rgba);
|
|
// ImGui.TextWrapped(sourceOpUi.Description);
|
|
// ImGui.PopStyleColor();
|
|
// ImGui.PopFont();
|
|
// }
|
|
|
|
ImageOutputCanvas.Deactivate();
|
|
TransformGizmoHandling.RestoreDrawList();
|
|
}
|
|
ImGui.EndChild();
|
|
|
|
if (sourceOp != null && targetOp != null)
|
|
{
|
|
ImGui.PushFont(Fonts.FontSmall);
|
|
var type = output.OutputDefinition.ValueType;
|
|
var connectionSource = sourceOp.ReadableName + "." + output.OutputDefinition.Name;
|
|
ImGui.TextColored(UiColors.TextMuted, connectionSource);
|
|
|
|
ImGui.TextUnformatted(type.Name);
|
|
ImGui.SameLine();
|
|
var connectionTarget = "--> " + targetOp.ReadableName + "." + input.Name;
|
|
ImGui.TextColored(UiColors.TextMuted, connectionTarget);
|
|
ImGui.PopFont();
|
|
|
|
var nodeSelection = components.NodeSelection;
|
|
FrameStats.AddHoveredId(targetOp.Id);
|
|
FrameStats.AddHoveredId(sourceOp.Id);
|
|
}
|
|
}
|
|
}
|
|
ImGui.EndTooltip();
|
|
}
|
|
else
|
|
{
|
|
_hoverStartTime = -1;
|
|
}
|
|
|
|
_bestMatchYetForCurrentFrame = null;
|
|
_bestMatchDistance = float.PositiveInfinity;
|
|
}
|
|
|
|
|
|
public static void RegisterAsPotentialSplit(Symbol.Connection connection, Color color, Vector2 position)
|
|
{
|
|
var distance = Vector2.Distance(position, _mousePosition);
|
|
if (distance > SnapDistance || distance > _bestMatchDistance)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_bestMatchYetForCurrentFrame = new PotentialConnectionSplit()
|
|
{
|
|
Connection = connection,
|
|
PositionOnScreen = position,
|
|
Color = color,
|
|
};
|
|
_bestMatchDistance = distance;
|
|
}
|
|
|
|
private static readonly ImageOutputCanvas _imageCanvasForTooltips = new() { DisableDamping = true };
|
|
private static readonly EvaluationContext _evaluationContext = new();
|
|
|
|
public static PotentialConnectionSplit? BestMatchLastFrame;
|
|
private static PotentialConnectionSplit? _bestMatchYetForCurrentFrame;
|
|
private static float _bestMatchDistance = float.PositiveInfinity;
|
|
private const int SnapDistance = 50;
|
|
private static Vector2 _mousePosition;
|
|
private static double _hoverStartTime = -1;
|
|
|
|
public sealed class PotentialConnectionSplit
|
|
{
|
|
public Vector2 PositionOnScreen;
|
|
public required Symbol.Connection Connection;
|
|
public Color Color;
|
|
}
|
|
} |