예제 #1
0
        /// <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);
        }