public static void drawLinks(Graphics g, Nodes.Node n) { foreach (var kvp in n.getProperties()) { if (kvp.Value.isInput && kvp.Value.input != null) { if (kvp.Value.getType() == NodeProperties.Type.CHANNELS) { g.DrawLine(linkChannels, NodeArtist.getJointPos(kvp.Value.input.node, kvp.Value.input.port, false), NodeArtist.getJointPos(n, kvp.Key, true)); } else if (kvp.Value.getType() == NodeProperties.Type.COLOR) { g.DrawLine(linkColors, NodeArtist.getJointPos(kvp.Value.input.node, kvp.Value.input.port, false), NodeArtist.getJointPos(n, kvp.Key, true)); } else if (kvp.Value.getType() == NodeProperties.Type.VECTORS) { g.DrawLine(linkVectors, NodeArtist.getJointPos(kvp.Value.input.node, kvp.Value.input.port, false), NodeArtist.getJointPos(n, kvp.Key, true)); } else { g.DrawLine(linePen, NodeArtist.getJointPos(kvp.Value.input.node, kvp.Value.input.port, false), NodeArtist.getJointPos(n, kvp.Key, true)); } } } }
public static Point getJointPos(Nodes.Node n, string port, bool input) { Rectangle nodeRect = getRect(n); Point result = nodeRect.Location; result.Y += nodeTitleFont.Height; if (n.getExtra() != null) { result.Y += nodeExtraFont.Height; } foreach (var kvp in n.getProperties()) { if (kvp.Key == port) { break; } if (kvp.Value.isInput || kvp.Value.isOutput) { result.Y += nodeFont.Height; } } if (!input) { result.X += nodeRect.Width; } result.Y += ballSize / 2; return(result); }
public void newProject() { filename = ""; path = ""; dirty = false; nodes.Clear(); selectedNodes.Clear(); selectedNode = null; }
public static Rectangle getPaddedRect(Nodes.Node n) { Rectangle r = getRect(n); r.X -= ballSize / 2; r.Y -= ballSize / 2; r.Width += ballSize; r.Height += ballSize; return(r); }
public static void drawGraphNode(Graphics g, Nodes.Node n, bool isSelected) { Rectangle nodeRect = getRect(n); //draw background g.FillRectangle(isSelected ? Brushes.Wheat : Brushes.CadetBlue, nodeRect); g.DrawRectangle(Pens.Black, nodeRect); drawTitle(g, n, ref nodeRect); drawProperties(g, n, ref nodeRect); }
private static void drawTitle(Graphics g, Nodes.Node n, ref Rectangle nodeRect) { //draw title g.DrawString(n.getName(), nodeTitleFont, Brushes.Black, nodeRect.X + (nodeRect.Width - System.Windows.Forms.TextRenderer.MeasureText(n.getName(), nodeTitleFont).Width) / 2, nodeRect.Y); nodeRect.Y += nodeFont.Height; g.DrawLine(Pens.Black, nodeRect.Left, nodeRect.Y, nodeRect.Right, nodeRect.Y); //draw extra if (n.getExtra() != null && n.getExtra() != "") { g.DrawString(n.getExtra(), nodeExtraFont, Brushes.Black, nodeRect.Location); nodeRect.Y += nodeFont.Height; g.DrawLine(Pens.Black, nodeRect.Left, nodeRect.Y, nodeRect.Right, nodeRect.Y); } }
private void readConnections(List <string[]> connections) { foreach (string[] link in connections) { Nodes.Node src = nodes.Find(i => i.getID() == link[0]); Nodes.Node dst = nodes.Find(i => i.getID() == link[2]); if (src == null || dst == null) { Console.WriteLine(string.Format("Couldn't link nodes {0}.{1} to {2}.{3}", link[0], link[1], link[2], link[3])); } else { Nodes.Node.connect(src, link[1], dst, link[3]); } } }
//Read project public int readProject(StreamReader stream) { List <string[]> connections = new List <string[]>(); //read file line by line and build nodes. Nodes.Node n = readNode(stream, connections); while (n != null) { nodes.Add(n); n = readNode(stream, connections); } //build connections in nodes readConnections(connections); return(0); }
public static string hitJoint(Nodes.Node n, Rectangle rect, int x, int y, bool inputsOnly) { //assume using a padded rect //missed the balls. if (x > rect.Left + ballSize && x < rect.Right - ballSize) { return(null); } rect.Y += nodeTitleFont.Height; if (n.getExtra() != null) { rect.Y += nodeExtraFont.Height; } if (y < rect.Y) { return(null); } Point pos; foreach (var kvp in n.getProperties()) { if ((kvp.Value.isInput && inputsOnly) || (kvp.Value.isOutput && !inputsOnly)) { pos = getJointPos(n, kvp.Key, inputsOnly); pos.X -= x; pos.Y -= y; //intentionally dividing by 2 instead of 4 to expand the 'okay' selection radius. if (pos.X * pos.X + pos.Y * pos.Y < ballSize * ballSize / 2) { return(kvp.Key); } } } return(null); }
public static Rectangle getRect(Nodes.Node n) { int titleWidth = System.Windows.Forms.TextRenderer.MeasureText(n.getName(), nodeTitleFont).Width; Rectangle nodeRect = new Rectangle(); nodeRect.Location = n.getPos(); nodeRect.Width = Math.Max(100, titleWidth); nodeRect.Height = nodeTitleFont.Height; //count the lines to cover with text if (n.getExtra() != null && n.getExtra() != "") { nodeRect.Height += nodeExtraFont.Height; } foreach (var kvp in n.getProperties()) { if (kvp.Value.isInput || kvp.Value.isOutput) { nodeRect.Height += nodeFont.Height; } } return(nodeRect); }
public void addNode(Node n) { project.addNode(n); recalcFocus(); }
/// <summary> /// Add a node to the project. Does not check for duplicates. /// </summary> /// <param name="node">The node to add the project.</param> public void addNode(Nodes.Node node) { nodes.Add(node); }
private static void drawProperties(Graphics g, Nodes.Node n, ref Rectangle nodeRect) { //draw properties foreach (var kvp in n.getProperties()) { //draw bubbles if (kvp.Value.isInput) { g.DrawString(kvp.Key, nodeFont, Brushes.Black, nodeRect.Left + ballSize / 2, nodeRect.Y); if (kvp.Value.input != null) { switch (kvp.Value.getType()) { case NodeProperties.Type.CHANNELS: g.FillEllipse(brushChannels, nodeRect.Left - ballSize / 2, nodeRect.Y + ballOffset, ballSize, ballSize); break; case NodeProperties.Type.COLOR: g.FillEllipse(brushColors, nodeRect.Left - ballSize / 2, nodeRect.Y + ballOffset, ballSize, ballSize); break; case NodeProperties.Type.VECTORS: g.FillEllipse(brushVectors, nodeRect.Left - ballSize / 2, nodeRect.Y + ballOffset, ballSize, ballSize); break; default: g.FillEllipse(Brushes.Black, nodeRect.Left - ballSize / 2, nodeRect.Y + ballOffset, ballSize, ballSize); break; } } else { switch (kvp.Value.getType()) { case NodeProperties.Type.CHANNELS: g.DrawEllipse(linkChannels, nodeRect.Left - ballSize / 2, nodeRect.Y + ballOffset, ballSize, ballSize); break; case NodeProperties.Type.COLOR: g.DrawEllipse(linkColors, nodeRect.Left - ballSize / 2, nodeRect.Y + ballOffset, ballSize, ballSize); break; case NodeProperties.Type.VECTORS: g.DrawEllipse(linkVectors, nodeRect.Left - ballSize / 2, nodeRect.Y + ballOffset, ballSize, ballSize); break; default: g.DrawEllipse(Pens.Black, nodeRect.Left - ballSize / 2, nodeRect.Y + ballOffset, ballSize, ballSize); break; } } nodeRect.Y += nodeFont.Height; } else if (kvp.Value.isOutput) { g.DrawString(kvp.Key, nodeFont, Brushes.Black, nodeRect.Left + (nodeRect.Width - g.MeasureString(kvp.Key, nodeFont).Width), nodeRect.Y); if (kvp.Value.output.Any()) { switch (kvp.Value.getType()) { case NodeProperties.Type.CHANNELS: g.FillEllipse(brushChannels, nodeRect.Right - ballSize / 2, nodeRect.Y + ballOffset, ballSize, ballSize); break; case NodeProperties.Type.COLOR: g.FillEllipse(brushColors, nodeRect.Right - ballSize / 2, nodeRect.Y + ballOffset, ballSize, ballSize); break; case NodeProperties.Type.VECTORS: g.FillEllipse(brushVectors, nodeRect.Right - ballSize / 2, nodeRect.Y + ballOffset, ballSize, ballSize); break; default: g.FillEllipse(Brushes.Black, nodeRect.Right - ballSize / 2, nodeRect.Y + ballOffset, ballSize, ballSize); break; } } else { switch (kvp.Value.getType()) { case NodeProperties.Type.CHANNELS: g.DrawEllipse(linkChannels, nodeRect.Right - ballSize / 2, nodeRect.Y + ballOffset, ballSize, ballSize); break; case NodeProperties.Type.COLOR: g.DrawEllipse(linkColors, nodeRect.Right - ballSize / 2, nodeRect.Y + ballOffset, ballSize, ballSize); break; case NodeProperties.Type.VECTORS: g.DrawEllipse(linkVectors, nodeRect.Right - ballSize / 2, nodeRect.Y + ballOffset, ballSize, ballSize); break; default: g.DrawEllipse(Pens.Black, nodeRect.Right - ballSize / 2, nodeRect.Y + ballOffset, ballSize, ballSize); break; } } nodeRect.Y += nodeFont.Height; } } }
protected void removeOutput(string port, Node to, string toPort) { //Note: only breaks this end of the connection. if (properties.ContainsKey(port)) { properties[port].output.RemoveWhere(x => x.node == to && x.port.Equals(toPort)); } }
public Address(Node n, string s) { node = n; port = s; }
protected bool addOutput(string port, Node to, string toPort) { //if there's an old connection, doesn't matter. Output can be 1..* HashSet<Address> cnx; if (properties.ContainsKey(port)) { cnx = properties[port].output; cnx.Add(new Address(to, toPort)); return true; } return false; }
protected bool addInput(string port, Node from, string fromPort) { //if the port is valid if (properties.ContainsKey(port)) { //if there's an old connection, disconnect both ends if (properties[port].input != null) { properties[port].input.node.removeOutput(properties[port].input.port, this, port); properties[port].input = null; } //place the new connection properties[port].input = new Address(from, fromPort); soil(); return true; } //else fail return false; }
public static void disconnect(Node from, string fromPort, Node to, string toPort) { from.removeOutput(fromPort, to, toPort); to.removeInput(toPort); }
private void select(Node sel, bool toggle) { if (toggle) { if (sel != null) project.selectedNodes.Add(sel); } else { project.selectedNodes.Clear(); if (sel != null) project.selectedNodes.Add(sel); } if (project.selectedNodes.Count() == 1) { project.selectedNode = sel; eSelectionChanged?.Invoke(this, new EventArgs()); } Invalidate(); }
public static bool connect(Node from, string fromPort, Node to, string toPort) { if (!from.addOutput(fromPort, to, toPort)) return false; if (!to.addInput(toPort, from, fromPort)) { from.removeOutput(fromPort, to, toPort); return false; } return true; }