예제 #1
0
        private void AutoFormatConnectedNodes(List <XNode.Node> nodes, Rect boundingBox)
        {
            if (nodes.Count <= 1)
            {
                return;
            }

            // Assumes that all nodes are connected

            // Storing extra data for each node
            var graphNodes = nodes.ToDictionary(n => n, n => new FormattedNode()
            {
                Node = n
            });

            // Find rightmost nodes (nodes that don't have any of our nodes to the right)
            var endNodes = graphNodes.Values
                           .Where(n => !n.Node.Outputs.SelectMany(o => o.GetConnections()).Any(c => graphNodes.ContainsKey(c.node)))
                           .OrderBy(n => n.Node.position.y)  // Keep the order of the endNodes
                           .ToList();

            var endNode = new FormattedNode()
            {
                Layer = -1, ChildNodes = endNodes
            };

            // Sorted child nodes, as a tree
            SetChildNodes(graphNodes, endNode);

            // Longest path layering
            int maxLayer = SetLayers(graphNodes, endNode);

            // Set offsets
            int maxOffset = SetOffsets(endNode, maxLayer);

            Vector2 topRightPosition = endNodes.First().Node.position;

            // TODO: Better node spacing (figure out how much space the biggest node in this row takes up and make the row a bit bigger than that)
            foreach (var n in graphNodes)
            {
                n.Key.position.x = (-n.Value.Layer) * 250 + topRightPosition.x;
            }

            foreach (var n in graphNodes)
            {
                n.Key.position.y = n.Value.Offset * 250 + topRightPosition.y;
            }
        }
예제 #2
0
        private static int SetOffsets(FormattedNode endNode, int maxLayer)
        {
            int maxOffset = 0;

            int[] offsets = new int[maxLayer + 1];
            // TODO: Replace with iterative version?

            /*var nodeStack = new Stack<Tuple<FormattedNode, FormattedNode>>();
             * nodeStack.Push(Tuple.Create(endNode, endNode));
             * while(nodeStack.Count > 0)
             * {
             *
             * }*/
            void SetOffsets(FormattedNode node, FormattedNode straightParent)
            {
                if (node.Layer >= 0 && offsets[node.Layer] > node.Offset)
                {
                    straightParent.SubtreeOffset = Math.Max(straightParent.SubtreeOffset, offsets[node.Layer] - node.Offset);
                }

                int  childOffset    = node.Offset;
                bool firstIteration = true;

                foreach (var childNode in node.ChildNodes)
                {
                    childNode.Offset = childOffset;
                    SetOffsets(childNode, firstIteration ? straightParent : childNode);
                    childOffset = childNode.Offset + 1;

                    firstIteration = false;
                }

                if (node.Layer >= 0)
                {
                    node.Offset        += straightParent.SubtreeOffset;
                    maxOffset           = Math.Max(maxOffset, node.Offset);
                    offsets[node.Layer] = node.Offset + 1;
                }
            }

            SetOffsets(endNode, endNode);
            return(maxOffset);
        }
        protected override MarkdownNode VisitFormatted(FormattedNode formatted)
        {
            var(tagOpen, tagClose) = formatted.Formatting switch
            {
                TextFormatting.Bold => ("<strong>", "</strong>"),
                TextFormatting.Italic => ("<em>", "</em>"),
                TextFormatting.Underline => ("<u>", "</u>"),
                TextFormatting.Strikethrough => ("<s>", "</s>"),
                TextFormatting.Spoiler => (
                    "<span class=\"spoiler spoiler--hidden\" onclick=\"showSpoiler(event, this)\"><span class=\"spoiler-text\">", "</span></span>"),
                TextFormatting.Quote => ("<div class=\"quote\">", "</div>"),
                _ => throw new ArgumentOutOfRangeException(nameof(formatted.Formatting))
            };

            _buffer.Append(tagOpen);
            var result = base.VisitFormatted(formatted);

            _buffer.Append(tagClose);

            return(result);
        }
예제 #4
0
 public virtual MarkdownNode VisitFormatted(FormattedNode formatted)
 {
     Visit(formatted.Children);
     return(formatted);
 }
예제 #5
0
        private static int SetLayers(Dictionary <XNode.Node, FormattedNode> graphNodes, FormattedNode endNode)
        {
            int maxLayer   = 0;
            var nodesStack = new Stack <XNode.Node>(endNode.ChildNodes.Select(c => c.Node));

            while (nodesStack.Count > 0)
            {
                var node  = nodesStack.Pop();
                int layer = graphNodes[node].Layer;

                foreach (var input in node.Inputs)
                {
                    if (input.Connection != null && graphNodes.TryGetValue(input.Connection.node, out var inputGraphNode))
                    {
                        inputGraphNode.Layer = Math.Max(inputGraphNode.Layer, layer + 1);
                        maxLayer             = Math.Max(maxLayer, inputGraphNode.Layer);
                        nodesStack.Push(input.Connection.node);
                    }
                }
            }

            return(maxLayer);
        }
예제 #6
0
        private void SetChildNodes(Dictionary <XNode.Node, FormattedNode> graphNodes, FormattedNode endNode)
        {
            var nodesStack = new Stack <FormattedNode>();

            nodesStack.Push(endNode);
            var visitedChildNodes = new HashSet <FormattedNode>();

            while (nodesStack.Count > 0)
            {
                var node = nodesStack.Pop();

                if (node.ChildNodes == null)
                {
                    node.ChildNodes = Sort(node.Node.Inputs)
                                      .SelectMany(input => input.GetConnections())
                                      .Select(c => graphNodes.TryGetValue(c.node, out FormattedNode n) ? n : null)
                                      .Where(n => n != null && !visitedChildNodes.Contains(n))
                                      .ToList();
                }

                for (int i = node.ChildNodes.Count - 1; i >= 0; i--)
                {
                    visitedChildNodes.Add(node.ChildNodes[i]);
                    nodesStack.Push(node.ChildNodes[i]);
                }
            }
        }