Example #1
0
        /// <summary>
        /// Formats the tree to look nicely.
        /// </summary>
        public void PositionNodesNicely()
        {
            var bt = window.tree;

            // Assumption for Nicify:
            // There must be a root set.
            if (bt.Root == null)
            {
                return;
            }

            // This is for the node editor to use to place the nodes.
            var positions = new Dictionary <BehaviourNode, Vector2>();
            var levels    = calculateLevels();
            var posParams = new PositioningParameters();

            Action <BehaviourNode> positionInPlace = (node) =>
            {
                positionNode(node, positions, levels, posParams);
            };

            TreeIterator <BehaviourNode> .Traverse(bt.Root, positionInPlace, Traversal.PostOrder);

            foreach (var editorNode in canvas.Nodes)
            {
                var behaviour = editorNode.behaviour;

                if (positions.ContainsKey(behaviour))
                {
                    Vector2 pos = positions[behaviour];
                    editorNode.bodyRect.position = pos;
                }
            }
        }
            /// <summary>
            /// Adds and removes children types based on current types selected.
            /// </summary>
            public void UpdateParentChildren()
            {
                _parentsToSetChildren.Clear();
                _parentsToClearChildren.Clear();

                TreeIterator <TypeSelectionNode> .Traverse(_root, markAdditionsAndRemovals);

                setParentChildren();
                clearParentChildren();
            }
Example #3
0
        /// <summary>
        /// Sets the position of the subtree at an offset.
        /// </summary>
        /// <param name="pos">The position of the subtree. </param>
        /// <param name="offset">Additional offset.</param>
        /// <param name="root">The subtree root.</param>
        public void SetSubtreePosition(Vector2 pos, Vector2 offset, BonsaiNode root)
        {
            float min = float.MinValue;

            if (root.Input.outputConnection != null)
            {
                float nodeTop      = root.Input.bodyRect.yMin;
                float parentBottom = root.Input.outputConnection.bodyRect.yMax;

                // The root cannot be above its parent.
                if (nodeTop < parentBottom)
                {
                    min = parentBottom;
                }
            }

            // Record the old position so we can know by how much the root moved
            // so all children can be shifted by the pan delta.
            Vector2 oldPos = root.bodyRect.position;

            // Clamp the position so it does not go above the parent.
            Vector2 diff = pos - offset;

            diff.y = Mathf.Clamp(diff.y, min, float.MaxValue);

            Vector2 rounded = SnapPosition(diff);

            root.bodyRect.position = rounded;

            // Calculate the change of position of the root.
            Vector2 pan = root.bodyRect.position - oldPos;

            // Move the entire subtree of the root.
            Action <BonsaiNode> subtreeDrag = (node) =>
            {
                // For all children, pan by the same amount that the parent changed by.
                if (node != root)
                {
                    node.bodyRect.position += SnapPosition(pan);
                }
            };

            TreeIterator <BonsaiNode> .Traverse(root, subtreeDrag);
        }
Example #4
0
        // To do this, we do a regular DFS and just check the current
        // path length at a given node to determine its level.
        private Dictionary <BehaviourNode, int> calculateLevels()
        {
            var bt = window.tree;

            if (bt.Root == null)
            {
                return(null);
            }

            var levels = new Dictionary <BehaviourNode, int>();

            Action <BehaviourNode, TreeIterator <BehaviourNode> > setLevel = (node, itr) =>
            {
                levels.Add(node, itr.CurrentLevel);
            };

            TreeIterator <BehaviourNode> .Traverse(bt.Root, setLevel, Traversal.LevelOrder);

            return(levels);
        }
Example #5
0
        /// <summary>
        /// Formats the tree to look nicely.
        /// </summary>
        public static void PositionNodesNicely(BonsaiNode root, Vector2 anchor)
        {
            // Sort parent-child connections so formatter uses latest changes.
            TreeIterator <BonsaiNode> .Traverse(
                root,
                node => node.SortChildren());

            var positioning = new FormatPositioning();

            TreeIterator <BonsaiNode> .Traverse(
                root,
                node => PositionHorizontal(node, positioning),
                Traversal.PostOrder);

            TreeIterator <BonsaiNode> .Traverse(
                root,
                node => PositionVertical(node));

            // Move the entire subtree to the anchor.
            Vector2 offset = EditorSingleDrag.StartDrag(root, root.Center);

            EditorSingleDrag.SetSubtreePosition(root, anchor, offset);
        }