Beispiel #1
0
        public bool AddNode(Node node)
        {
            if (node == null ||
                _graphNodes.Contains(node))
                return false;

            _graphNodes.Insert(0, node);
            if (NodeAdded != null)
            {
                var eventArgs = new AcceptNodeEventArgs(node);
                NodeAdded(this, eventArgs);
                if (eventArgs.Cancel)
                {
                    _graphNodes.Remove(node);
                    return false;
                }
            }

            BringElementToFront(node);
            // FocusElement = node;
            UpdateRevisionIndex();
            if (InvalidateViews != null)
                InvalidateViews(this, EventArgs.Empty);
            return true;
        }
Beispiel #2
0
        private static NodeSize Measure(Graphics context, Node node)
        {
            if (node == null)
                return new NodeSize { BaseSize = SizeF.Empty, LeftPartWidth = 0, RightPartWidth = 0 };

            SizeF size = Size.Empty;
            size.Height = (int)GraphConstants.TopHeight;

            bool[] firstItem = new bool[3] { true, true, true };
            SizeF[] sizes = new SizeF[3] { size, size, size };
            foreach (var item in EnumerateNodeItems(node))
            {
                var side = GetSide(item);
                var itemSize = item.Measure(context);

                if (side != 1)
                    itemSize = AdjustConnectorSize(itemSize);

                sizes[side].Width = Math.Max(sizes[side].Width, itemSize.Width);
                if (!firstItem[side])
                    sizes[side].Height += GraphConstants.ItemSpacing;
                sizes[side].Height += itemSize.Height;
                firstItem[side] = false;
            }

            size = sizes[1];
            for (uint c = 0; c < 3; ++c)
                size.Height = Math.Max(size.Height, sizes[c].Height);

            size.Width += GraphConstants.NodeExtraWidth;
            size.Height += GraphConstants.BottomHeight;

            return new NodeSize { BaseSize = size, LeftPartWidth = sizes[0].Width, RightPartWidth = sizes[2].Width };
        }
Beispiel #3
0
		static IEnumerable<NodeItem> EnumerateNodeItems(Node node)
		{
			if (node == null)
				yield break;

			yield return node.titleItem;
			if (node.Collapsed)
				yield break;
			
			foreach (var item in node.Items)
				yield return item;
		}
Beispiel #4
0
        public static void RenderConnections(Graphics graphics, Node node, HashSet<NodeConnection> skipConnections, bool showLabels)
        {
            foreach (var connection in node.connections.Reverse<NodeConnection>())
            {
                if (connection == null)
                    continue;

                if (skipConnections.Add(connection))
                {
                    var to		= connection.To;
                    var from	= connection.From;

                    RectangleF toBounds;
                    RectangleF fromBounds;
                    if (to == null) toBounds = new RectangleF(0.0f, 0.0f, 0.0f, 0.0f);
                    else if (to.Node.Collapsed) toBounds = to.Node.inputBounds;
                    else toBounds = to.bounds;
                    if (from == null) fromBounds = new RectangleF(0.0f, 0.0f, 0.0f, 0.0f);
                    else if (from.Node.Collapsed) fromBounds = from.Node.outputBounds;
                    else fromBounds = from.bounds;

                    var pt1 = ConnectorInterfacePoint(fromBounds, ConnectorType.Output);
                    var pt2 = ConnectorInterfacePoint(toBounds, ConnectorType.Input);

                    if (to != null && from != null)
                    {
                        float centerX;
                        float centerY;
                        using (var path = GetArrowLinePath(pt1.X, pt1.Y, pt2.X, pt2.Y, out centerX, out centerY, false))
                        {
                            using (var brush = new SolidBrush(GetArrowLineColor(connection.state | RenderState.Connected)))
                            {
                                graphics.FillPath(brush, path);
                                graphics.DrawPath(BorderPen, path);
                            }
                            connection.bounds = path.GetBounds();
                        }

                        if (showLabels &&
                            !string.IsNullOrWhiteSpace(connection.Name))
                        {
                            var center = new PointF(centerX, centerY);
                            RenderLabel(graphics, connection, connection.Name, center, connection.state);
                        }
                    }
                    else if (to!=null || from!=null)
                    {
                        //  this is a basic connection. It just connects one connector to a
                        //  static string value (either a variable name or constant value)
                        //      Draw a small arrow from the connection label to the connector
                        if (!string.IsNullOrWhiteSpace(connection.Name))
                        {
                            PointF center;
                            if (to != null) center = pt2;
                            else if (from != null) center = pt1;
                            else center = new PointF();
                            center.X -= 16;
                            RenderLabel(graphics, connection, "= " + connection.Name, center, connection.state);
                        }
                    }
                }
            }
        }
Beispiel #5
0
        public static void PerformLayout(Graphics graphics, Node node)
        {
            if (node == null)
                return;
            var size		= Measure(graphics, node);
            var position	= node.Location;
            node.bounds		= new RectangleF(position, size);

            var path				= new GraphicsPath(FillMode.Winding);
            var left				= position.X;
            var top					= position.Y;
            var right				= position.X + size.Width;
            var bottom				= position.Y + size.Height;

            node.inputConnectors.Clear();
            node.outputConnectors.Clear();
            //node.connections.Clear();

            var itemPosition = position;
            itemPosition.X += (int)GraphConstants.HorizontalSpacing;
            if (node.Collapsed)
            {
                foreach (var item in node.Items)
                {
                    var inputConnector	= item.Input;
                    if (inputConnector != null && inputConnector.Enabled)
                    {
                        inputConnector.bounds = Rectangle.Empty;
                        node.inputConnectors.Add(inputConnector);
                    }
                    var outputConnector = item.Output;
                    if (outputConnector != null && outputConnector.Enabled)
                    {
                        outputConnector.bounds = Rectangle.Empty;
                        node.outputConnectors.Add(outputConnector);
                    }
                }
                var itemSize		= PreRenderItem(graphics, node.titleItem, itemPosition);
                var realHeight		= itemSize.Height - GraphConstants.TopHeight;
                var connectorY		= itemPosition.Y  + (int)Math.Ceiling(realHeight / 2.0f);

                node.inputBounds = new RectangleF(      left - GraphConstants.ConnectorWidthCollapsed,
                                                        connectorY,
                                                        GraphConstants.ConnectorWidthCollapsed,
                                                        realHeight);
                node.outputBounds = new RectangleF(     right - GraphConstants.ConnectorWidthCollapsed,
                                                        connectorY,
                                                        GraphConstants.ConnectorWidthCollapsed,
                                                        realHeight);
            } else
            {
                node.inputBounds	= Rectangle.Empty;
                node.outputBounds	= Rectangle.Empty;

                foreach (var item in EnumerateNodeItems(node))
                {
                    var itemSize		= PreRenderItem(graphics, item, itemPosition);
                    var realHeight		= itemSize.Height;
                    var inputConnector	= item.Input;
                    if (inputConnector != null && inputConnector.Enabled)
                    {
                        if (itemSize.IsEmpty)
                        {
                            inputConnector.bounds = Rectangle.Empty;
                        } else
                        {
                            inputConnector.bounds = new RectangleF( left - GraphConstants.ConnectorWidth, itemPosition.Y,
                                                                    GraphConstants.ConnectorWidth, realHeight);
                        }
                        node.inputConnectors.Add(inputConnector);
                    }
                    var outputConnector = item.Output;
                    if (outputConnector != null && outputConnector.Enabled)
                    {
                        if (itemSize.IsEmpty)
                        {
                            outputConnector.bounds = Rectangle.Empty;
                        } else
                        {
                            outputConnector.bounds = new RectangleF(right, itemPosition.Y,
                                                                    GraphConstants.ConnectorWidth, realHeight);
                        }
                        node.outputConnectors.Add(outputConnector);
                    }
                    itemPosition.Y += itemSize.Height + GraphConstants.ItemSpacing;
                }
            }
            node.itemsBounds = new RectangleF(left, top, right - left, bottom - top);
        }
Beispiel #6
0
        public static SizeF Measure(Graphics context, Node node)
        {
            if (node == null)
                return SizeF.Empty;

            SizeF size = Size.Empty;
            size.Height = (int)GraphConstants.TopHeight;
            foreach (var item in EnumerateNodeItems(node))
            {
                var itemSize = item.Measure(context);
                size.Width = Math.Max(size.Width, itemSize.Width);
                size.Height += GraphConstants.ItemSpacing + itemSize.Height;
            }

            if (node.Collapsed)
                size.Height -= GraphConstants.ItemSpacing;

            size.Width += GraphConstants.NodeExtraWidth;
            size.Height += GraphConstants.BottomHeight;
            return size;
        }
Beispiel #7
0
 public AcceptNodeEventArgs(Node node, bool cancel)
     : base(cancel)
 {
     Node = node;
 }
Beispiel #8
0
 public AcceptNodeEventArgs(Node node)
 {
     Node = node;
 }
Beispiel #9
0
 public NodeEventArgs(Node node)
 {
     Node = node;
 }
Beispiel #10
0
 public bool DisconnectAll(Node node)
 {
     bool modified = false;
     var connections = node.Connections.ToList();
     foreach (var connection in connections)
         modified |= Disconnect(connection);
     return modified;
 }
Beispiel #11
0
		static void Render(Graphics graphics, Node node, object context)
		{
			var size		= node.bounds.Size;
			var position	= node.bounds.Location;

            var cornerSize          = GraphConstants.CornerSize;
			var left				= position.X;
			var top					= position.Y;
			var right				= position.X + size.Width;
			var bottom				= position.Y + size.Height;

            Brush brush;
            if ((node.state & RenderState.Dragging) != 0)       { brush = DraggingBrush; }
            else if ((node.state & RenderState.Hover) != 0)     { brush = HoverBrush; }
            else                                                { brush = NormalBrush; }

            const Boolean roundedRectRendering = false;
            if (roundedRectRendering)
            {
                using (var path = new GraphicsPath(FillMode.Winding))
                {
                    path.AddArc(left, top, cornerSize, cornerSize, 180, 90);
                    path.AddArc(right - cornerSize, top, cornerSize, cornerSize, 270, 90);

                    path.AddArc(right - cornerSize, bottom - cornerSize, cornerSize, cornerSize, 0, 90);
                    path.AddArc(left, bottom - cornerSize, cornerSize, cornerSize, 90, 90);
                    path.CloseFigure();

                    graphics.FillPath(brush, path);
                    graphics.DrawPath(BorderPen, path);
                }
            }
            else 
            {
                var rect = new Rectangle((int)left, (int)top, (int)(right - left), (int)(bottom - top));

                if (node.Collapsed)
                {
                    graphics.FillRectangle(TitleAreaBrush, rect);
                }
                else
                {
                    int titleHeight = (node.titleItem != null) ? (int)(node.titleItem.bounds.Height + GraphConstants.TopHeight) : 0;
                    titleHeight = Math.Min((int)(bottom - top), titleHeight);

                    var titleRect = new Rectangle((int)left, (int)top, (int)(right - left), titleHeight);
                    var backgroundRect = new Rectangle((int)left, (int)top + titleHeight, (int)(right - left), (int)(bottom - top) - titleHeight);

                    DrawShadow(graphics, rect);
                    graphics.FillRectangle(brush, backgroundRect);
                    if (titleHeight != 0)
                        graphics.FillRectangle(TitleAreaBrush, titleRect);
                    graphics.DrawRectangle(BorderPen, rect);
                }

                if ((node.state & RenderState.Focus) != 0)
                {
                    // We're going to draw a outline around the edge of the entire node
                    // This should be a thick line, with some bright color
                    var outline = new Rectangle(rect.Left - 4, rect.Top - 4, rect.Width + 8, rect.Height + 8);
                    graphics.DrawRectangle(FocusPen, outline);
                }
            }

            if (node.Collapsed)
            {
                RenderItem(graphics, new SizeF(node.bounds.Width - GraphConstants.NodeExtraWidth, 0), node.titleItem, node.titleItem.bounds.Location, context);
            }
            else
            {
                var minimumItemSize = new SizeF(node.bounds.Width - GraphConstants.NodeExtraWidth, 0);
                foreach (var item in EnumerateNodeItems(node))
                {
                    RenderItem(graphics, minimumItemSize, item, item.bounds.Location, context);
                }
            }

            foreach (var item in node.Items)    // (don't use EnumerateItems because we want to show collapsed nodes)
            {
                // note --  the "connected" state is not stored in the retained state member
                //          ... so if we want to colour the connectors based on if they are connected,
                //          we need to look for connections now.
                var inputConnector	= item.Input;
				if (inputConnector != null && inputConnector.Enabled && !inputConnector.bounds.IsEmpty)
					RenderConnector(graphics, inputConnector.bounds, inputConnector.state, ConnectorType.Input, inputConnector, node.Collapsed);
				var outputConnector = item.Output;
				if (outputConnector != null && outputConnector.Enabled && !outputConnector.bounds.IsEmpty)
                    RenderConnector(graphics, outputConnector.bounds, outputConnector.state, ConnectorType.Output, outputConnector, node.Collapsed);
			}
		}
Beispiel #12
0
        public static void PerformLayout(Graphics graphics, Node node)
		{
			if (node == null)
				return;
			var size = Measure(graphics, node);
			var position = node.Location;
            node.bounds = new RectangleF(position, size.BaseSize);
            position.Y += (int)GraphConstants.TopHeight;
			
			var path = new GraphicsPath(FillMode.Winding);
			var left = position.X;
			var top = position.Y;
            var right = position.X + size.BaseSize.Width;
            var bottom = position.Y + size.BaseSize.Height;
			
			var itemPosition = position;
			itemPosition.X += (int)GraphConstants.HorizontalSpacing;
			if (node.Collapsed)
			{
                uint inputConnectorCount = 0, outputConnectorCount = 0;
                foreach (var item in node.Items)
                {
                    if (item.Input != null && item.Input.Enabled) ++inputConnectorCount;
                    if (item.Output != null && item.Output.Enabled) ++outputConnectorCount;
                }

                uint inputConnectorIndex = 0, outputConnectorIndex = 0;
                foreach (var item in node.Items)
				{
					if (item.Input != null && item.Input.Enabled)
					{
                        item.Input.bounds = CollapsedInputConnector(node.bounds, inputConnectorIndex, inputConnectorCount);
                        ++inputConnectorIndex;
                    }
					if (item.Output != null && item.Output.Enabled)
					{
                        item.Output.bounds = CollapsedOutputConnector(node.bounds, outputConnectorIndex, outputConnectorCount);
                        ++outputConnectorIndex;
                    }
				}

				var itemSize = PreRenderItem(graphics, node.titleItem, itemPosition);
			} 
            else
			{
                PointF[] positions = new PointF[] { itemPosition, itemPosition, itemPosition };
                float[] widths = new float[] { size.LeftPartWidth, size.BaseSize.Width, size.RightPartWidth };

				foreach (var item in EnumerateNodeItems(node))
				{
                    var inputConnector = item.Input;
                    var outputConnector = item.Output;

                    var side = GetSide(item);
                    var itemSize = PreRenderItem(graphics, item, positions[side]);
					var realHeight = itemSize.Height;
					
					if (inputConnector != null && inputConnector.Enabled)
					{
						if (itemSize.IsEmpty)
						{
							inputConnector.bounds = Rectangle.Empty;
						} 
                        else
						{
                            inputConnector.bounds = new RectangleF(
                                left - widths[side], positions[side].Y,
                                widths[side], realHeight);
						}
					}

					if (outputConnector != null && outputConnector.Enabled)
					{
						if (itemSize.IsEmpty)
						{
							outputConnector.bounds = Rectangle.Empty;
						} 
                        else
						{
                            outputConnector.bounds = new RectangleF(
                                right, positions[side].Y,
                                widths[side], realHeight);
						}
					}

                    positions[side].Y += itemSize.Height + GraphConstants.ItemSpacing;
				}
			}
		}
Beispiel #13
0
 public static Node CreateNode(ShaderFragmentArchive.Function fn, String archiveName, HyperGraph.GraphControl graphControl, ShaderDiagram.Document doc)
 {
     var node = new Node(fn.Name);
     node.Tag = new ShaderProcedureNodeTag(archiveName);
     node.AddItem(new ShaderFragmentPreviewItem(graphControl, doc));
     foreach (var param in fn.InputParameters)
     {
         node.AddItem(new ShaderFragmentNodeItem(param.Name, param.Type, archiveName + ":" + param.Name, true, false));
     }
     foreach (var output in fn.Outputs)
     {
         node.AddItem(new ShaderFragmentNodeItem(output.Name, output.Type, archiveName + ":" + output.Name, false, true));
     }
     return node;
 }
Beispiel #14
0
 public static Node CreateEmptyParameterNode(ShaderFragmentArchive.Parameter.SourceType sourceType, String archiveName, String title)
 {
     var node = new Node(title);
     node.Tag = new ShaderParameterNodeTag(archiveName);
     int selectedIndex = 0;
     List<String> typeNames = new List<String>();
     foreach (var e in Enum.GetValues(typeof(ShaderFragmentArchive.Parameter.SourceType)).Cast<ShaderFragmentArchive.Parameter.SourceType>())
     {
         if (e == sourceType)
         {
             selectedIndex = typeNames.Count;
         }
         typeNames.Add(AsString(e));
     }
     var typeSelection = new HyperGraph.Items.NodeDropDownItem(typeNames.ToArray(), selectedIndex, false, false);
     node.AddItem(typeSelection);
     typeSelection.SelectionChanged += ParameterNodeTypeChanged;
     return node;
 }
Beispiel #15
0
        static void Render(Graphics graphics, Node node)
        {
            var size		= node.bounds.Size;
            var position	= node.bounds.Location;

            var cornerSize          = GraphConstants.CornerSize;
            var left				= position.X;
            var top					= position.Y;
            var right				= position.X + size.Width;
            var bottom				= position.Y + size.Height;

            Brush brush;
            if ((node.state & (RenderState.Dragging | RenderState.Focus)) != 0)         { brush = FocusBrush; }
            else if ((node.state & RenderState.Hover) != 0)                             { brush = HoverBrush; }
            else                                                                        { brush = NormalBrush; }

            const Boolean roundedRectRendering = false;
            if (roundedRectRendering)
            {
                using (var path = new GraphicsPath(FillMode.Winding))
                {
                    path.AddArc(left, top, cornerSize, cornerSize, 180, 90);
                    path.AddArc(right - cornerSize, top, cornerSize, cornerSize, 270, 90);

                    path.AddArc(right - cornerSize, bottom - cornerSize, cornerSize, cornerSize, 0, 90);
                    path.AddArc(left, bottom - cornerSize, cornerSize, cornerSize, 90, 90);
                    path.CloseFigure();

                    graphics.FillPath(brush, path);
                    graphics.DrawPath(BorderPen, path);
                }
            }
            else
            {
                var rect = new Rectangle((int)left, (int)top, (int)(right - left), (int)(bottom - top));
                int titleSize = Math.Min((int)(bottom - top), GraphConstants.TopHeight + GraphConstants.TitleHeight);
                var titleRect = new Rectangle((int)left, (int)top, (int)(right - left), titleSize);
                var backgroundRect = new Rectangle((int)left, (int)top + titleSize, (int)(right - left), (int)(bottom - top) - titleSize);

                DrawShadow(graphics, rect);
                graphics.FillRectangle(brush, backgroundRect);
                graphics.FillRectangle(TitleAreaBrush, titleRect);
                graphics.DrawRectangle(BorderPen, rect);
            }

            /*
                if (!node.Collapsed)
                    graphics.DrawLine(Pens.Black,
                        left  + GraphConstants.ConnectorSize, node.titleItem.bounds.Bottom - GraphConstants.ItemSpacing,
                        right - GraphConstants.ConnectorSize, node.titleItem.bounds.Bottom - GraphConstants.ItemSpacing);
            */

            var itemPosition = position;
            itemPosition.X += (int)GraphConstants.HorizontalSpacing;
            itemPosition.Y += (int)GraphConstants.TopHeight;
            if (node.Collapsed)
            {
                // bool inputConnected = false;
                // var inputState	= RenderState.None;
                // var outputState = node.outputState;
                // foreach (var connection in node.connections)
                // {
                // 	if (connection.To.Node == node)
                // 	{
                // 		inputState |= connection.state;
                // 		inputConnected = true;
                // 	}
                // 	if (connection.From.Node == node)
                // 		outputState |= connection.state | RenderState.Connected;
                // }

                RenderItem(graphics, new SizeF(node.bounds.Width - GraphConstants.NodeExtraWidth, 0), node.titleItem, itemPosition);
                // if (node.inputConnectors.Count > 0)
                // 	RenderConnector(graphics, node.inputBounds, node.inputState, ConnectorType.Input);
                // if (node.outputConnectors.Count > 0)
                // 	RenderConnector(graphics, node.outputBounds, outputState, ConnectorType.Output);
                //if (inputConnected)
                //	RenderArrow(graphics, node.inputBounds, inputState);
            } else
            {
                node.inputBounds	= Rectangle.Empty;
                node.outputBounds	= Rectangle.Empty;

                var minimumItemSize = new SizeF(node.bounds.Width - GraphConstants.NodeExtraWidth, 0);
                foreach (var item in EnumerateNodeItems(node))
                {
                    RenderItem(graphics, minimumItemSize, item, itemPosition);
                    var inputConnector	= item.Input;
                    if (inputConnector != null && inputConnector.Enabled)
                    {
                        if (!inputConnector.bounds.IsEmpty)
                        {
                            var state		= RenderState.None;
                            var connected	= false;
                            foreach (var connection in node.connections)
                            {
                                if (connection.To == inputConnector)
                                {
                                    state |= connection.state;
                                    connected = true;
                                }
                            }

                            RenderConnector(graphics,
                                            inputConnector.bounds,
                                            inputConnector.state, ConnectorType.Input,
                                            inputConnector);

                            if (connected)
                                RenderArrow(graphics, inputConnector.bounds, state);
                        }
                    }
                    var outputConnector = item.Output;
                    if (outputConnector != null && outputConnector.Enabled)
                    {
                        if (!outputConnector.bounds.IsEmpty)
                        {
                            var state = outputConnector.state;
                            foreach (var connection in node.connections)
                            {
                                if (connection.From == outputConnector)
                                    state |= connection.state | RenderState.Connected;
                            }
                            RenderConnector(graphics, outputConnector.bounds, state, ConnectorType.Output, outputConnector);
                        }
                    }
                    itemPosition.Y += item.bounds.Height + GraphConstants.ItemSpacing;
                }
            }
        }
Beispiel #16
0
        private static NodeItem FindOrCreateNodeItem(Node node, Func<NodeItem, bool> predicate, Func<NodeItem> creator)
        {
            foreach (var i in node.Items)
                if (predicate(i))
                    return i;

            var newItem = creator();
            node.AddItem(newItem);
            return newItem;
        }
Beispiel #17
0
 private void MatchVisualNode(HyperGraph.Node dst, ShaderPatcherLayer.VisualNode src)
 {
     dst.Location  = src.Location;
     dst.Collapsed = src.State == ShaderPatcherLayer.VisualNode.StateType.Collapsed;
 }
Beispiel #18
0
        public void RemoveNode(Node node)
        {
            if (node == null)
                return;

            if (NodeRemoving != null)
            {
                var eventArgs = new AcceptNodeEventArgs(node);
                NodeRemoving(this, eventArgs);
                if (eventArgs.Cancel)
                    return;
            }
            // if (HasFocus(node))
            //     FocusElement = null;

            DisconnectAll(node);
            _graphNodes.Remove(node);
            UpdateRevisionIndex();
            if (InvalidateViews != null) 
                InvalidateViews(this, EventArgs.Empty);

            if (NodeRemoved != null)
                NodeRemoved(this, new NodeEventArgs(node));
        }