/** * @brief create chart according to m_btTree. if it is null, it will clear * the view **/ private void CreateChart() { if (m_btTree == null) { m_sprites = null; } else { m_sprites = new Dictionary <string, BTEditorSprite>(); BTEditorRectangle.RecursivelyCreateSprites(m_sprites, m_btTree.Root, this); } }
/** * @brief call this after _treeNode is added to bttree **/ public void DeclareAddNode(BTNode _treeNode) { BTNode parent = m_btTree.FindParent(_treeNode); string parentKey = BTEditorRectangle.GetKey(parent); if (m_sprites.ContainsKey(parentKey)) { BTEditorRectangle.RecursivelyCreateSprites(m_sprites, parent, this); AutoLayoutChart(); Refresh(); } }
/** * @brief recursively layout the nodes **/ private void AutoLayoutChart() { if (m_btTree != null && m_btTree.Root != null && m_sprites != null) { string rootKey = BTEditorRectangle.GetKey(m_btTree.Root); // auto layout Point leftTop = new Point(10, 10); if (m_sprites.ContainsKey(rootKey)) { (m_sprites[rootKey] as BTEditorRectangle).AutoRecursivelyLayout(m_sprites, leftTop); } } }
/** * @brief recursively create sprites and insert into _sprites **/ internal static void RecursivelyCreateSprites(Dictionary <string, BTEditorSprite> _sprites, BTNode _btNode, BTTreeViewer _btTreeViewer) { if (_btNode == null) { return; } if (!_sprites.ContainsKey(BTEditorRectangle.GetKey(_btNode))) { BTEditorRectangle node = CreateRectangleNodeFromBTNode(_btNode, _btTreeViewer); node.Node = _btNode; _sprites.Add(node.GetKey(), node); } (_sprites[BTEditorRectangle.GetKey(_btNode)] as BTEditorRectangle).RecursivelyCreatChildren(_sprites); }
/** * @brief get the existing BTEditorRectangle for the given BTNode **/ internal BTEditorRectangle GetRectangle(BTNode _node) { if (_node == null) { return(null); } string key = BTEditorRectangle.GetKey(_node); if (m_sprites != null && m_sprites.ContainsKey(key)) { return(m_sprites[key] as BTEditorRectangle); } return(null); }
/** * @brief change _node's order among its siblings according to _worldPos * in BTEditorRectangle's world y positions **/ private void UpdateChildrenSequence(string _node, Point _worldPos) { if (m_sprites.ContainsKey(_node)) { BTEditorRectangle editorNode = m_sprites[_node] as BTEditorRectangle; BTNode node = editorNode.Node; if (node != null) { BTNode parent = m_btTree.FindParent(node); if (parent != null && parent.GetType().IsSubclassOf(typeof(BTCompositeNode))) { (GetRectangle(parent) as BTEditorRectangleBTCompositeNode).AdjustChildrenSequence(editorNode, _worldPos); AutoLayoutChart(); Refresh(); } } } }
internal void AdjustChildrenSequence(BTEditorRectangle _rectangle, Point _worldPos) { BTCompositeNode node = m_node as BTCompositeNode; if (node.Children != null) { node.Children.Remove(_rectangle.Node); int targetIndex = 0; foreach (BTNode child in node.Children) { if (m_treeViewer.GetRectangle(child).GetPosition().Y > _worldPos.Y) { break; } ++targetIndex; } node.Children.Insert(targetIndex, _rectangle.Node); } }
internal override int AutoRecursivelyLayout(Dictionary <string, BTEditorSprite> _sprites, Point _leftTop) { if (m_node != null) { // children BTCompositeNode node = m_node as BTCompositeNode; int x = _leftTop.X + m_bound.Width + HorizontalInterval; int y = _leftTop.Y; if (node.Children != null) { foreach (BTNode child in node.Children) { string key = GetKey(child); if (_sprites.ContainsKey(key)) { BTEditorRectangle childNode = _sprites[key] as BTEditorRectangle; int height = childNode.AutoRecursivelyLayout(_sprites, new Point(x, y)); y += height + VerticalInterval; } else { Debug.Assert(false, "Cannot find sprite for node"); } } } // self if (y != _leftTop.Y) { y -= VerticalInterval; } int needHeight = (m_bound.Height > (y - _leftTop.Y)) ? (m_bound.Height) : (y - _leftTop.Y); m_bound.X = _leftTop.X; m_bound.Y = _leftTop.Y + (needHeight - m_bound.Height) / 2; return(needHeight); } else { Debug.Assert(false, "Cannot find corresponding node"); return(0); } }
/** * @brief Set child's parent to _newParent. the function do the following things * 1. check whether the child and parent exist * 2. check whether there would be cycle structure: if the _child is _newParent's ancestor * 3. if the _newParent is ConditionNode, check if it has child. If it does, the action is illege * 4. break the old edge * 5. make new connection **/ internal bool SetParent(string _child, string _newParent) { if (!m_sprites.ContainsKey(_child) || !m_sprites.ContainsKey(_newParent)) { return(false); } BTEditorRectangle child = m_sprites[_child] as BTEditorRectangle; BTEditorRectangle newParent = m_sprites[_newParent] as BTEditorRectangle; // check cycle if (child.Node.FindParent(newParent.Node) != null) { System.Windows.Forms.MessageBox.Show("Cycle structor is illegal."); return(false); } // check newParent if (newParent.Node.GetType().IsSubclassOf(typeof(BTConditionNode))) { BTNode otherChild = (newParent.Node as BTConditionNode).Child; if (otherChild != null) { System.Windows.Forms.MessageBox.Show("Condition node cannot have more than one child."); return(false); } } // destroy old edge BTNode oldBTParent = m_btTree.FindParent(child.Node); if (oldBTParent != null) { string oldEdgeKey = BTEditorLine.GetKey(oldBTParent, child.Node); if (m_sprites.ContainsKey(oldEdgeKey)) { m_sprites.Remove(oldEdgeKey); } if (oldBTParent.GetType().IsSubclassOf(typeof(BTCompositeNode))) { (oldBTParent as BTCompositeNode).RemoveChild(child.Node); } else if (oldBTParent.GetType().IsSubclassOf(typeof(BTConditionNode))) { (oldBTParent as BTConditionNode).Child = null; } } // create new link // destroy other edge if necessary if (newParent.Node.GetType().IsSubclassOf(typeof(BTConditionNode))) { (newParent.Node as BTConditionNode).Child = child.Node; } else if (newParent.Node.GetType().IsSubclassOf(typeof(BTCompositeNode))) { (newParent.Node as BTCompositeNode).AddChild(child.Node); } else { Debug.Assert(false, "Cannot add key to node with type: " + newParent.Node.GetType().Name); return(false); } BTEditorLine newLine = new BTEditorLine(this); newLine.ParentNode = newParent.Node; newLine.ChildNode = child.Node; m_sprites.Add(newLine.GetKey(), newLine); AutoLayoutChart(); Refresh(); return(true); }
public BTTreeViewer() { InitializeComponent(); BTEditorRectangle.InitializePrototypes(); }