/// <summary> /// Handles actions that occur after the user checked/unchecked an item. /// </summary> private void treeView_AfterCheck(object sender, TreeViewEventArgs e) { // if the code is currently updating the checking we skip any post actions. if (_isCheckingNodes) { return; } // check if the user check a folder NodeTag nodetag = (NodeTag)e.Node.Tag; if (nodetag.Type == NodeTagType.BehaviorFolder) { // disable the post actions _isCheckingNodes = true; // check/uncheck all the children CheckNodes(e.Node, e.Node.Checked); // enable post actions _isCheckingNodes = false; } else { // behaviour post stuff here } }
/// <summary> /// Adds this NodeGroup to the TreeView of the node explorer. /// </summary> /// <param name="pool">The TreeNodeCollection the group and its sub-groups and childrens will be added.</param> public void Register(TreeNodeCollection pool) { // check if this NodeGroup already exists in the node explorer TreeNode tnode = null; foreach (TreeNode node in pool) { if (node.Text == _name) { tnode = node; break; } } // create a new group if it does not yet exist if (tnode == null) { tnode = new TreeNode(_name, (int)_icon, (int)_icon); tnode.Tag = new NodeTag(NodeTagType.NodeFolder, null, string.Empty); pool.Add(tnode); } // add the nodes which will be shown in this group foreach (Type item in _items) { NodeTagType ntt = NodeTagType.Node; if (item.IsSubclassOf(typeof(Attachments.Attachment))) { ntt = NodeTagType.Attachment; } NodeTag nodetag = new NodeTag(ntt, item, string.Empty); TreeNode inode = new TreeNode(nodetag.Defaults.Label, (int)_icon, (int)_icon); inode.Tag = nodetag; inode.ToolTipText = nodetag.Defaults.Description; tnode.Nodes.Add(inode); } // add any sub-group foreach (NodeGroup group in _children) { group.Register(tnode.Nodes); } }
/// <summary> /// Returns the behaviour which is associated with a tree node. /// </summary> /// <param name="nodetag">The NodeTag of the tree node.</param> /// <param name="label">The label of the tree node.</param> /// <returns>Returns null if no matching behaviour could be found or loaded.</returns> internal BehaviorNode GetBehavior(NodeTag nodetag, string label) { // search the loaded behaviours if we can find one for this tree node foreach(BehaviorNode node in _loadedBehaviors) { if(node.FileManager.Filename ==nodetag.Filename) return node; } // search if we have any newly created behaviour with a matching name foreach(BehaviorNode node in _newBehaviors) { if(((Node)node).Label ==label) return node; } // not found, so we try to load the behaviour BehaviorNode behavior= LoadBehavior(nodetag.Filename); // if that was sucessful return the loaded behaviour if(behavior !=null) return behavior; MessageBox.Show("No such behavior: "+ label +" "+ nodetag.Filename, "File Error", MessageBoxButtons.OK); return null; }
/// <summary> /// Adds this NodeGroup to the TreeView of the node explorer. /// </summary> /// <param name="pool">The TreeNodeCollection the group and its sub-groups and childrens will be added.</param> public void Register(TreeNodeCollection pool) { // check if this NodeGroup already exists in the node explorer TreeNode tnode= null; foreach(TreeNode node in pool) { if(node.Text ==_name) { tnode= node; break; } } // create a new group if it does not yet exist if(tnode ==null) { tnode= new TreeNode(_name, (int) _icon, (int) _icon); tnode.Tag= new NodeTag(NodeTagType.NodeFolder, null, string.Empty); pool.Add(tnode); } // add the nodes which will be shown in this group foreach(Type item in _items) { NodeTag nodetag= new NodeTag(item.IsSubclassOf(typeof(Nodes.Node)) ? NodeTagType.Node : NodeTagType.Event, item, string.Empty); TreeNode inode= new TreeNode(nodetag.Defaults.Label, (int) _icon, (int) _icon); inode.Tag= nodetag; inode.ToolTipText= nodetag.Defaults.Description; tnode.Nodes.Add(inode); } // add any sub-group foreach(NodeGroup group in _children) group.Register(tnode.Nodes); }
/// <summary> /// Attaches a dragged node from the node explorer to an existing node. /// </summary> /// <param name="nvd">The node the new node will be attached to.</param> /// <param name="mode">The way the new node will be attached.</param> /// <param name="nodetag">The tag of the you want to create.</param> /// <param name="label">The label of the new node.</param> private void InsertNewNode(NodeViewData nvd, NodeAttachMode mode, NodeTag nodetag) { // check if the attach mode is valid if(mode ==NodeAttachMode.Event || mode ==NodeAttachMode.None) throw new Exception("A node cannot be created with the given attach mode"); if(nodetag.Type !=NodeTagType.Behavior && nodetag.Type !=NodeTagType.Node) throw new Exception("Only behaviours and nodes can be attached to a behaviour tree"); Node node= nvd.Node; Node newnode; // when we attach a behaviour we must create a special referenced behaviour node if(nodetag.Type ==NodeTagType.Behavior) { // reset any previously loaded behaviour FileManagers.FileManager.ResetLoadedBehavior(); // get the behaviour we want to reference BehaviorNode behavior= _behaviorTreeList.LoadBehavior(nodetag.Filename); // a behaviour may not reference itself if(behavior ==_rootNode.RootBehavior) return; // create the referenced behaviour node for the behaviour ReferencedBehavior refnode= new ReferencedBehavior(_rootNode.RootBehavior, behavior); // register the view so it gets updated when the referenced behaviour gets updated. refnode.ReferencedBehaviorWasModified+= new ReferencedBehavior.ReferencedBehaviorWasModifiedEventDelegate(refnode_ReferencedBehaviorWasModified); newnode= refnode; } else { // simply create the node which is supposed to be created. newnode= Node.Create(nodetag.NodeType); } // update label newnode.OnPropertyValueChanged(false); // attach the new node with the correct mode switch(mode) { // the new node is inserted in front of the target node case(NodeAttachMode.Left): Node parent= node.Parent; int k= parent.Children.IndexOf(node); Node.Connector conn= node.ParentConnector; Debug.Check(conn !=null); parent.RemoveChild(conn, node); parent.AddChild(conn, newnode, k); Node.Connector newconn= newnode.GetConnector(conn.Identifier); Debug.Check(newconn !=null); newnode.AddChild(newconn, node); // automatically select the new node _selectedNodePending= newnode; _selectedNodePendingParent= nvd.Parent; break; // the new node is simply added to the target node's children case(NodeAttachMode.Right): node.AddChild(_dragTargetConnector, newnode); // automatically select the new node _selectedNodePending= newnode; _selectedNodePendingParent= nvd; break; // the new node is placed above the target node case(NodeAttachMode.Top): int n= _dragTargetNode.Node.ParentConnector.GetChildIndex(node); node.Parent.AddChild(_dragTargetNode.Node.ParentConnector, newnode, n); // automatically select the new node _selectedNodePending= newnode; _selectedNodePendingParent= nvd.Parent; break; // the new node is placed below the target node case(NodeAttachMode.Bottom): int m= _dragTargetNode.Node.ParentConnector.GetChildIndex(node); node.Parent.AddChild(_dragTargetNode.Node.ParentConnector, newnode, m +1); // automatically select the new node _selectedNodePending= newnode; _selectedNodePendingParent= nvd.Parent; break; } // the layout needs to be recalculated LayoutChanged(); }