/// <summary> /// Callback used by the decorator in <see cref="CreateEditorMode"/> /// </summary> private IPortCandidateProvider GetPortCandidateProvider(INode forNode) { var model = new MyNodePortLocationModel { Inset = 10 }; return(PortCandidateProviders.FromCandidates( new DefaultPortCandidate(forNode, model.CreateParameter(PortLocation.Center)), new DefaultPortCandidate(forNode, model.CreateParameter(PortLocation.North)), new DefaultPortCandidate(forNode, model.CreateParameter(PortLocation.East)), new DefaultPortCandidate(forNode, model.CreateParameter(PortLocation.South)), new DefaultPortCandidate(forNode, model.CreateParameter(PortLocation.West)))); }
/// <summary> /// Creates an <see cref="IPortCandidateProvider"/> that considers the node's shape and rotation. /// </summary> private static IPortCandidateProvider CreatePortCandidateProvider(INode node) { var rotatedPortModel = RotatablePortLocationModelDecorator.Instance; var freeModel = FreeNodePortLocationModel.Instance; var rnsd = (RotatableNodeStyleDecorator)node.Style; var wrapped = rnsd.Wrapped; var sns = wrapped as ShapeNodeStyle; if (wrapped is ShinyPlateNodeStyle || wrapped is BevelNodeStyle || sns != null && sns.Shape == ShapeNodeShape.RoundRectangle) { return(PortCandidateProviders.Combine( //Take all existing ports - these are assumed to have the correct port location model PortCandidateProviders.FromUnoccupiedPorts(node), //Provide explicit candidates - these are all backed by a rotatable port location model PortCandidateProviders.FromCandidates( //Port candidates at the corners that are slightly inset new DefaultPortCandidate(node, rotatedPortModel.CreateWrappingParameter(freeModel.CreateParameter(new PointD(0, 0), new PointD(5, 5)))), new DefaultPortCandidate(node, rotatedPortModel.CreateWrappingParameter(freeModel.CreateParameter(new PointD(0, 1), new PointD(5, -5)))), new DefaultPortCandidate(node, rotatedPortModel.CreateWrappingParameter(freeModel.CreateParameter(new PointD(1, 0), new PointD(-5, 5)))), new DefaultPortCandidate(node, rotatedPortModel.CreateWrappingParameter(freeModel.CreateParameter(new PointD(1, 1), new PointD(-5, -5)))), //Port candidates at the sides and the center new DefaultPortCandidate(node, rotatedPortModel.CreateWrappingParameter(FreeNodePortLocationModel.NodeLeftAnchored)), new DefaultPortCandidate(node, rotatedPortModel.CreateWrappingParameter(FreeNodePortLocationModel.NodeBottomAnchored)), new DefaultPortCandidate(node, rotatedPortModel.CreateWrappingParameter(FreeNodePortLocationModel.NodeCenterAnchored)), new DefaultPortCandidate(node, rotatedPortModel.CreateWrappingParameter(FreeNodePortLocationModel.NodeTopAnchored)), new DefaultPortCandidate(node, rotatedPortModel.CreateWrappingParameter(FreeNodePortLocationModel.NodeRightAnchored)) ))); } if (sns != null && sns.Shape == ShapeNodeShape.Rectangle) { return(PortCandidateProviders.Combine( PortCandidateProviders.FromUnoccupiedPorts(node), PortCandidateProviders.FromCandidates( //Port candidates at the corners new DefaultPortCandidate(node, rotatedPortModel.CreateWrappingParameter(FreeNodePortLocationModel.NodeTopLeftAnchored)), new DefaultPortCandidate(node, rotatedPortModel.CreateWrappingParameter(FreeNodePortLocationModel.NodeTopRightAnchored)), new DefaultPortCandidate(node, rotatedPortModel.CreateWrappingParameter(FreeNodePortLocationModel.NodeBottomLeftAnchored)), new DefaultPortCandidate(node, rotatedPortModel.CreateWrappingParameter(FreeNodePortLocationModel.NodeBottomRightAnchored)), //Port candidates at the sides and the center new DefaultPortCandidate(node, rotatedPortModel.CreateWrappingParameter(FreeNodePortLocationModel.NodeLeftAnchored)), new DefaultPortCandidate(node, rotatedPortModel.CreateWrappingParameter(FreeNodePortLocationModel.NodeBottomAnchored)), new DefaultPortCandidate(node, rotatedPortModel.CreateWrappingParameter(FreeNodePortLocationModel.NodeCenterAnchored)), new DefaultPortCandidate(node, rotatedPortModel.CreateWrappingParameter(FreeNodePortLocationModel.NodeTopAnchored)), new DefaultPortCandidate(node, rotatedPortModel.CreateWrappingParameter(FreeNodePortLocationModel.NodeRightAnchored)) ))); } if (sns != null) { // Can be an arbitrary shape. First create a dummy node that is not rotated var dummyNode = new SimpleNode { Style = sns, Layout = node.Layout }; var shapeProvider = PortCandidateProviders.FromShapeGeometry(dummyNode, 0); var shapeCandidates = shapeProvider.GetTargetPortCandidates(null); var rotatingCandidates = shapeCandidates.Select(c => new DefaultPortCandidate(node, rotatedPortModel.CreateWrappingParameter(c.LocationParameter))); return(PortCandidateProviders.Combine( PortCandidateProviders.FromUnoccupiedPorts(node), PortCandidateProviders.FromCandidates(rotatingCandidates))); } return(null); }