You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
231 lines
8.0 KiB
231 lines
8.0 KiB
using UnityEditor.Experimental.GraphView;
|
|
using UnityEngine.UIElements;
|
|
using UnityEngine;
|
|
using UnityEngine.VFX;
|
|
using System.Linq;
|
|
using Type = System.Type;
|
|
|
|
namespace UnityEditor.VFX.UI
|
|
{
|
|
class VFXFlowAnchor : Port, IControlledElement<VFXFlowAnchorController>, IEdgeConnectorListener
|
|
{
|
|
VFXFlowAnchorController m_Controller;
|
|
Controller IControlledElement.controller
|
|
{
|
|
get { return m_Controller; }
|
|
}
|
|
public VFXFlowAnchorController controller
|
|
{
|
|
get { return m_Controller; }
|
|
set
|
|
{
|
|
if (m_Controller != null)
|
|
{
|
|
m_Controller.context.UnregisterHandler(this);
|
|
m_Controller.UnregisterHandler(this);
|
|
}
|
|
m_Controller = value;
|
|
if (m_Controller != null)
|
|
{
|
|
m_Controller.RegisterHandler(this);
|
|
m_Controller.context.RegisterHandler(this);
|
|
}
|
|
}
|
|
}
|
|
public override bool ContainsPoint(Vector2 localPoint)
|
|
{
|
|
return (new Rect(0.0f, 0.0f, layout.width, layout.height)).Contains(localPoint);
|
|
}
|
|
|
|
public static VFXFlowAnchor Create(VFXFlowAnchorController controller)
|
|
{
|
|
var anchor = new VFXFlowAnchor(controller.orientation, controller.direction, typeof(int));
|
|
anchor.m_EdgeConnector = new EdgeConnector<VFXFlowEdge>(anchor);
|
|
anchor.AddManipulator(anchor.m_EdgeConnector);
|
|
anchor.controller = controller;
|
|
return anchor;
|
|
}
|
|
|
|
protected VFXFlowAnchor(Orientation anchorOrientation, Direction anchorDirection, Type type) : base(anchorOrientation, anchorDirection, Capacity.Multi, type)
|
|
{
|
|
this.AddStyleSheetPath("VFXFlow");
|
|
AddToClassList("EdgeConnector");
|
|
}
|
|
|
|
void IControlledElement.OnControllerChanged(ref ControllerChangedEvent e)
|
|
{
|
|
if (e.controller == controller)
|
|
{
|
|
SelfChange();
|
|
}
|
|
else if (e.controller == controller.context)
|
|
{
|
|
UpdateType();
|
|
|
|
//Need to force refreshof the edge in case the color change because of a setting of the context ( hasStrip ).
|
|
foreach (var edge in connections)
|
|
edge.MarkDirtyRepaint();
|
|
}
|
|
}
|
|
|
|
void SelfChange()
|
|
{
|
|
m_ConnectorText.text = controller.title;
|
|
|
|
if (controller.connected)
|
|
AddToClassList("connected");
|
|
else
|
|
RemoveFromClassList("connected");
|
|
|
|
|
|
switch (controller.direction)
|
|
{
|
|
case Direction.Input:
|
|
{
|
|
RemoveFromClassList("Output");
|
|
AddToClassList("Input");
|
|
}
|
|
break;
|
|
case Direction.Output:
|
|
RemoveFromClassList("Input");
|
|
AddToClassList("Output");
|
|
break;
|
|
}
|
|
|
|
UpdateType();
|
|
}
|
|
|
|
private void UpdateType()
|
|
{
|
|
VFXDataType type = controller.direction == Direction.Input ? controller.context.model.inputType : controller.context.model.outputType;
|
|
foreach (VFXDataType value in System.Enum.GetValues(typeof(VFXDataType)))
|
|
{
|
|
if (value != type)
|
|
RemoveFromClassList("type" + VFXContextUI.ContextEnumToClassName(value.ToString()));
|
|
}
|
|
AddToClassList("type" + VFXContextUI.ContextEnumToClassName(type.ToString()));
|
|
}
|
|
|
|
void IEdgeConnectorListener.OnDrop(GraphView graphView, Edge edge)
|
|
{
|
|
VFXView view = graphView as VFXView;
|
|
VFXFlowEdge flowEdge = edge as VFXFlowEdge;
|
|
VFXFlowEdgeController edgeController = new VFXFlowEdgeController(flowEdge.input.controller, flowEdge.output.controller);
|
|
|
|
if (flowEdge.controller != null)
|
|
{
|
|
view.controller.RemoveElement(flowEdge.controller);
|
|
}
|
|
|
|
view.controller.AddElement(edgeController);
|
|
}
|
|
|
|
bool ProviderFilter(IVFXModelDescriptor descriptor)
|
|
{
|
|
if (descriptor.modelType?.IsSubclassOf(typeof(VFXContext)) != true)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var model = (VFXContext)descriptor.unTypedModel;
|
|
return direction == Direction.Input
|
|
? VFXContext.CanLink(model, controller.context.model)
|
|
: VFXContext.CanLink(controller.context.model, model);
|
|
}
|
|
|
|
public override void Disconnect(Edge edge)
|
|
{
|
|
base.Disconnect(edge);
|
|
UpdateCapColor();
|
|
}
|
|
|
|
void AddLinkedContext(Variant variant, Vector2 mPos)
|
|
{
|
|
VFXView view = GetFirstAncestorOfType<VFXView>();
|
|
if (view == null) return;
|
|
Vector2 tPos = view.ChangeCoordinatesTo(view.contentViewContainer, mPos);
|
|
|
|
view.UpdateSelectionWithNewNode();
|
|
VFXContext context = view.controller.AddVFXContext(tPos, variant);
|
|
view.controller.LightApplyChanges();
|
|
|
|
if (context == null) return;
|
|
|
|
|
|
if (direction == Direction.Input)
|
|
{
|
|
controller.context.model.LinkFrom(context, 0, controller.slotIndex);
|
|
}
|
|
else
|
|
{
|
|
controller.context.model.LinkTo(context, controller.slotIndex, 0);
|
|
}
|
|
}
|
|
|
|
void IEdgeConnectorListener.OnDropOutsidePort(Edge edge, Vector2 position)
|
|
{
|
|
VFXView view = this.GetFirstAncestorOfType<VFXView>();
|
|
VFXViewController viewController = view.controller;
|
|
|
|
|
|
VFXContextUI endContext = null;
|
|
foreach (var node in view.GetAllContexts())
|
|
{
|
|
if (node.worldBound.Contains(position))
|
|
{
|
|
endContext = node;
|
|
}
|
|
}
|
|
|
|
VFXFlowEdge flowEdge = edge as VFXFlowEdge;
|
|
bool exists = false;
|
|
if (flowEdge.controller != null)
|
|
{
|
|
view.controller.RemoveElement(flowEdge.controller);
|
|
exists = true;
|
|
}
|
|
|
|
if (endContext != null)
|
|
{
|
|
VFXContextController nodeController = endContext.controller;
|
|
|
|
var compatibleAnchors = viewController.GetCompatiblePorts(controller, null);
|
|
|
|
if (controller.direction == Direction.Input)
|
|
{
|
|
foreach (var outputAnchor in nodeController.flowOutputAnchors)
|
|
{
|
|
if (compatibleAnchors.Contains(outputAnchor))
|
|
{
|
|
VFXFlowEdgeController edgeController = new VFXFlowEdgeController(controller, outputAnchor);
|
|
|
|
viewController.AddElement(edgeController);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
foreach (var inputAnchor in nodeController.flowInputAnchors)
|
|
{
|
|
if (compatibleAnchors.Contains(inputAnchor))
|
|
{
|
|
VFXFlowEdgeController edgeController = new VFXFlowEdgeController(inputAnchor, controller);
|
|
|
|
viewController.AddElement(edgeController);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (!exists)
|
|
{
|
|
VFXFilterWindow.Show(
|
|
view,
|
|
Event.current.mousePosition - new Vector2(376 * 0.5f * view.scale, 0),
|
|
view.ViewToScreenPosition(Event.current.mousePosition),
|
|
new VFXNodeProvider(viewController, AddLinkedContext, ProviderFilter, new Type[] { typeof(VFXContext) }));
|
|
}
|
|
}
|
|
}
|
|
}
|