/// <summary> /// Creates an enumerable of <see cref="PortDescriptor"/>s belonging to the type of the node as specified by its /// <see cref="LogicGateType"/> set as its tag or an empty list if there is no /// <see cref="LogicGateType"/>. /// </summary> /// <param name="logicGateType"></param> public static IEnumerable <PortDescriptor> CreatePortDescriptors(LogicGateType logicGateType) { var inside = new InsideOutsidePortLabelModel().CreateInsideParameter(); var aboveEdgeLeft = FreePortLabelModel.Instance.CreateParameter(new PointD(-5, -3), new PointD(1, 1), PointD.Origin, 0); var aboveEdgeRight = FreePortLabelModel.Instance.CreateParameter(new PointD(5, -3), new PointD(0, 1), PointD.Origin, 0); var belowEdgeLeft = FreePortLabelModel.Instance.CreateParameter(new PointD(-5, 3), new PointD(1, 0), PointD.Origin, 0); switch (logicGateType) { default: case LogicGateType.And: return(new List <PortDescriptor> { new PortDescriptor { X = 0, Y = 5, EdgeDirection = EdgeDirection.In, LabelText = "in1", LabelPlacementWithEdge = aboveEdgeLeft }, new PortDescriptor { X = 0, Y = 25, EdgeDirection = EdgeDirection.In, LabelText = "in2", LabelPlacementWithEdge = belowEdgeLeft }, new PortDescriptor { X = 50, Y = 15, EdgeDirection = EdgeDirection.Out, LabelText = "out", LabelPlacementWithEdge = aboveEdgeRight } }); case LogicGateType.Nand: return(new List <PortDescriptor> { new PortDescriptor { X = 0, Y = 5, EdgeDirection = EdgeDirection.In, LabelText = "in1", LabelPlacementWithEdge = aboveEdgeLeft }, new PortDescriptor { X = 0, Y = 25, EdgeDirection = EdgeDirection.In, LabelText = "in2", LabelPlacementWithEdge = belowEdgeLeft }, new PortDescriptor { X = 50, Y = 15, EdgeDirection = EdgeDirection.Out, LabelText = "out", LabelPlacementWithEdge = aboveEdgeRight } }); case LogicGateType.Or: return(new List <PortDescriptor> { new PortDescriptor { X = 0, Y = 5, EdgeDirection = EdgeDirection.In, LabelText = "in1", LabelPlacementWithEdge = aboveEdgeLeft }, new PortDescriptor { X = 0, Y = 25, EdgeDirection = EdgeDirection.In, LabelText = "in2", LabelPlacementWithEdge = belowEdgeLeft }, new PortDescriptor { X = 50, Y = 15, EdgeDirection = EdgeDirection.Out, LabelText = "out", LabelPlacementWithEdge = aboveEdgeRight } }); case LogicGateType.Nor: return(new List <PortDescriptor> { new PortDescriptor { X = 0, Y = 5, EdgeDirection = EdgeDirection.In, LabelText = "in1", LabelPlacementWithEdge = aboveEdgeLeft }, new PortDescriptor { X = 0, Y = 25, EdgeDirection = EdgeDirection.In, LabelText = "in2", LabelPlacementWithEdge = belowEdgeLeft }, new PortDescriptor { X = 50, Y = 15, EdgeDirection = EdgeDirection.Out, LabelText = "out", LabelPlacementWithEdge = aboveEdgeRight } }); case LogicGateType.Not: return(new List <PortDescriptor> { new PortDescriptor { X = 0, Y = 15, EdgeDirection = EdgeDirection.In, LabelText = "in", LabelPlacementWithEdge = aboveEdgeLeft }, new PortDescriptor { X = 50, Y = 15, EdgeDirection = EdgeDirection.Out, LabelText = "out", LabelPlacementWithEdge = aboveEdgeRight } }); case LogicGateType.Timer: return(new[] { new PortDescriptor { X = 0, Y = 20, EdgeDirection = EdgeDirection.In, LabelText = "gnd", LabelPlacementWithEdge = inside }, new PortDescriptor { X = 0, Y = 40, EdgeDirection = EdgeDirection.In, LabelText = "trig", LabelPlacementWithEdge = inside }, new PortDescriptor { X = 0, Y = 80, EdgeDirection = EdgeDirection.Out, LabelText = "out", LabelPlacementWithEdge = inside }, new PortDescriptor { X = 0, Y = 100, EdgeDirection = EdgeDirection.In, LabelText = "rst", LabelPlacementWithEdge = inside }, new PortDescriptor { X = 70, Y = 20, EdgeDirection = EdgeDirection.In, LabelText = "Vcc", LabelPlacementWithEdge = inside }, new PortDescriptor { X = 70, Y = 40, EdgeDirection = EdgeDirection.Out, LabelText = "dis", LabelPlacementWithEdge = inside }, new PortDescriptor { X = 70, Y = 80, EdgeDirection = EdgeDirection.In, LabelText = "thr", LabelPlacementWithEdge = inside }, new PortDescriptor { X = 70, Y = 100, EdgeDirection = EdgeDirection.In, LabelText = "ctrl", LabelPlacementWithEdge = inside }, }); case LogicGateType.ADConverter: return(new[] { new PortDescriptor { X = 0, Y = 20, EdgeDirection = EdgeDirection.In, LabelText = "Vin", LabelPlacementWithEdge = inside }, new PortDescriptor { X = 0, Y = 40, EdgeDirection = EdgeDirection.In, LabelText = "gnd", LabelPlacementWithEdge = inside }, new PortDescriptor { X = 0, Y = 80, EdgeDirection = EdgeDirection.In, LabelText = "Vref", LabelPlacementWithEdge = inside }, new PortDescriptor { X = 0, Y = 100, EdgeDirection = EdgeDirection.In, LabelText = "clk", LabelPlacementWithEdge = inside }, new PortDescriptor { X = 70, Y = 20, EdgeDirection = EdgeDirection.Out, LabelText = "d1", LabelPlacementWithEdge = inside }, new PortDescriptor { X = 70, Y = 40, EdgeDirection = EdgeDirection.Out, LabelText = "d2", LabelPlacementWithEdge = inside }, new PortDescriptor { X = 70, Y = 100, EdgeDirection = EdgeDirection.Out, LabelText = "sign", LabelPlacementWithEdge = inside }, }); } }
/// <summary> /// Creates the default input mode for the GraphControl, /// a <see cref="GraphEditorInputMode"/>. /// </summary> /// <remarks> /// The control uses a custom node creation callback that creates business objects for newly /// created nodes. /// </remarks> /// <returns>a new GraphEditorInputMode instance</returns> protected virtual IInputMode CreateEditorMode() { var mode = new GraphEditorInputMode { // don't allow nodes to be created using a mouse click AllowCreateNode = false, // don't allow bends to be created using a mouse drag on an edge AllowCreateBend = false, // disable node resizing ShowHandleItems = GraphItemTypes.Bend | GraphItemTypes.Edge, // enable orthogonal edge creation and editing OrthogonalEdgeEditingContext = new OrthogonalEdgeEditingContext(), // enable drag and drop NodeDropInputMode = { Enabled = true }, // disable moving labels MoveLabelInputMode = { Enabled = false }, // enable snapping for easier orthogonal edge editing SnapContext = new GraphSnapContext { Enabled = true }, CreateEdgeInputMode = { // only allow starting an edge creation over a valid port candidate StartOverCandidateOnly = true, // show all port candidates when hovering over a node ShowPortCandidates = ShowPortCandidates.All } }; // wrap the original node creator so it copies the ports and labels from the dragged node var originalNodeCreator = mode.NodeDropInputMode.ItemCreator; mode.NodeDropInputMode.ItemCreator = (context, graph, draggedNode, dropTarget, layout) => { if (draggedNode != null) { var newNode = originalNodeCreator(context, graph, new SimpleNode { Style = draggedNode.Style, Layout = draggedNode.Layout }, dropTarget, layout); // copy the ports foreach (var port in draggedNode.Ports) { var descriptor = (PortDescriptor)port.Tag; var portStyle = new NodeStylePortStyleAdapter(new ShapeNodeStyle { Brush = descriptor.EdgeDirection == EdgeDirection.In ? Brushes.Green : Brushes.DodgerBlue, Pen = null, Shape = ShapeNodeShape.Rectangle }) { RenderSize = new SizeD(5, 5) }; var newPort = graph.AddPort(newNode, port.LocationParameter, portStyle, port.Tag); // create the port labels var parameter = new InsideOutsidePortLabelModel().CreateOutsideParameter(); graph.AddLabel(newPort, descriptor.LabelText, parameter, tag: descriptor); } // copy the labels foreach (var label in draggedNode.Labels) { graph.AddLabel(newNode, label.Text, label.LayoutParameter, label.Style, tag: label.Tag); } return(newNode); } // fallback return(originalNodeCreator(context, graph, draggedNode, dropTarget, layout)); }; mode.CreateEdgeInputMode.EdgeCreated += (sender, args) => { var sourcePortLabel = args.SourcePort.Labels.FirstOrDefault(); var targetPortLabel = args.TargetPort.Labels.FirstOrDefault(); if (sourcePortLabel != null) { ReplaceLabelModel(args.SourcePort, sourcePortLabel); } if (targetPortLabel != null) { ReplaceLabelModel(args.TargetPort, targetPortLabel); } }; graphControl.Graph.EdgeRemoved += (sender, args) => { var sourcePortLabel = args.SourcePort.Labels.FirstOrDefault(); var targetPortLabel = args.TargetPort.Labels.FirstOrDefault(); if (sourcePortLabel != null && !graphControl.Graph.EdgesAt(args.SourcePort).Any()) { graphControl.Graph.SetLabelLayoutParameter(sourcePortLabel, new InsideOutsidePortLabelModel().CreateOutsideParameter()); } if (targetPortLabel != null && !graphControl.Graph.EdgesAt(args.TargetPort).Any()) { graphControl.Graph.SetLabelLayoutParameter(targetPortLabel, new InsideOutsidePortLabelModel().CreateOutsideParameter()); } }; return(mode); }