private static TreeNode FindItem(TreeNodeCollection nodes, string resourcelocation, string lumpname, int lumpindex, ScriptType scripttype) { foreach(TreeNode node in nodes) { // Is this the item we are looking for? TextResourceNodeData data = (TextResourceNodeData)node.Tag; if(data.NodeType == TextResourceNodeType.NODE && data.ResourceLocation == resourcelocation && data.ScriptType == scripttype && data.Resource.Filename == lumpname && data.Resource.LumpIndex == lumpindex) { // Found it! return node; } // Try children... if(node.Nodes.Count > 0) { TreeNode item = FindItem(node.Nodes, resourcelocation, lumpname, lumpindex, scripttype); if(item != null) return item; } } // No dice... return null; }
private void projecttree_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e) { //TODO: special handling for SCRIPTS/DIALOGUE if(!(e.Node.Tag is TextResourceNodeData)) throw new NotSupportedException("Tag must be TextResourceData!"); TextResourceNodeData data = (TextResourceNodeData)e.Node.Tag; // Open file if(data.Resource != null) scriptpanel.OpenResource(data.Resource); }
// Switch to closed resource icon private void projecttree_BeforeCollapse(object sender, TreeViewCancelEventArgs e) { if(!(e.Node.Tag is TextResourceNodeData)) throw new NotSupportedException("Tag must be TextResourceData!"); TextResourceNodeData data = (TextResourceNodeData)e.Node.Tag; // Group node? if(data.NodeType == TextResourceNodeType.DIRECTORY) { e.Node.ImageIndex = scriptpanel.Icons.GetScriptFolderIcon(data.ScriptType, false); e.Node.SelectedImageIndex = e.Node.ImageIndex; } }
// Compare between two tree nodes public int Compare(object o1, object o2) { TreeNode n1 = o1 as TreeNode; TreeNode n2 = o2 as TreeNode; TextResourceNodeData d1 = (TextResourceNodeData)n1.Tag; TextResourceNodeData d2 = (TextResourceNodeData)n2.Tag; // Sort resources by load order if(resourcetypes.Contains(d1.NodeType) && resourcetypes.Contains(d2.NodeType)) { int n1index = resourceorder.IndexOf(d1.ResourceLocation); int n2index = resourceorder.IndexOf(d2.ResourceLocation); if(n1index > n2index) return 1; if(n1index < n2index) return -1; return 0; } // Push map namespace resources before anything else if(d1.NodeType == TextResourceNodeType.RESOURCE_MAP && d2.NodeType != TextResourceNodeType.RESOURCE_MAP) return -1; if(d1.NodeType != TextResourceNodeType.RESOURCE_MAP && d2.NodeType == TextResourceNodeType.RESOURCE_MAP) return 1; // Push embedded WADs before anything else except map resources if(n1.Parent != null && n2.Parent != null) { if(d1.NodeType == TextResourceNodeType.RESOURCE_WAD && d2.NodeType != TextResourceNodeType.RESOURCE_WAD) return -1; if(d1.NodeType != TextResourceNodeType.RESOURCE_WAD && d2.NodeType == TextResourceNodeType.RESOURCE_WAD) return 1; } // Push script folders before script files if(d1.NodeType == TextResourceNodeType.DIRECTORY && d2.NodeType != TextResourceNodeType.DIRECTORY) return -1; if(d1.NodeType != TextResourceNodeType.DIRECTORY && d2.NodeType == TextResourceNodeType.DIRECTORY) return 1; // Sort by name return n1.Text.CompareTo(n2.Text); }
private void UpdateResourcesTree(ScriptType filtertype, string filterfilename) { TreeNode selected = projecttree.SelectedNode; TreeNode toselect = null; projecttree.BeginUpdate(); projecttree.Nodes.Clear(); char[] splitter = { Path.DirectorySeparatorChar }; bool filenamefiltered = !string.IsNullOrEmpty(filterfilename); bool filteringapplied = (filenamefiltered || filtertype != ScriptType.UNKNOWN); // Create nodes foreach(KeyValuePair<string, Dictionary<ScriptType, HashSet<ScriptResource>>> group in resourcesperlocation) { foreach(ScriptTypeItem item in usedscripttypes) { // Filter by script type? if(filtertype != ScriptType.UNKNOWN && item.Type != filtertype) continue; // Current resource has this scrit type? if(!group.Value.ContainsKey(item.Type)) continue; HashSet<ScriptResource> resources = group.Value[item.Type]; foreach(ScriptResource res in resources) { bool asreadonly = res.Resource.IsReadOnly; // Filter by filename? if(filenamefiltered && Path.GetFileName(res.Filename).IndexOf(filterfilename, StringComparison.OrdinalIgnoreCase) == -1) continue; // Resource type node added? TreeNode root; string key = res.Resource.Location.location; // WAD resource inside another resource? if(res.Resource is WADReader && ((WADReader)res.Resource).ParentResource != null) { WADReader wr = (WADReader)res.Resource; string parentkey = wr.ParentResource.Location.location; TreeNode parent = GetResourceNode(projecttree.Nodes, wr.ParentResource.Location.GetDisplayName(), parentkey, wr.ParentResource); if(parent.Nodes.ContainsKey(key)) { root = parent.Nodes[key]; } else { root = GetResourceNode(parent.Nodes, Path.GetFileName(wr.Location.GetDisplayName()), key, res.Resource); TrySelectNode(selected, root, ref toselect); } } else if(projecttree.Nodes.ContainsKey(key)) { root = projecttree.Nodes[key]; } else { root = GetResourceNode(projecttree.Nodes, res.Resource.Location.GetDisplayName(), key, res.Resource); TrySelectNode(selected, root, ref toselect); } // Single resource item or active filtering? int iconindex = scriptpanel.Icons.GetScriptIcon(res.ScriptType); if(filteringapplied || (resources.Count == 1 && res.ScriptType != ScriptType.ACS)) { // Create new node var data = new TextResourceNodeData { ResourceLocation = key, LocationInResource = Path.GetDirectoryName(res.Filename), NodeType = TextResourceNodeType.NODE, Resource = res, ScriptType = res.ScriptType, }; TreeNode scriptnode = new TreeNode(res.ToString(), iconindex, iconindex) { Tag = data, ToolTipText = data.ToString() }; if(asreadonly) scriptnode.ForeColor = SystemColors.GrayText; TrySelectNode(selected, scriptnode, ref toselect); // Add the node root.Nodes.Add(scriptnode); } else { // Script type added? string typename = "[" + Enum.GetName(typeof(ScriptType), res.ScriptType) + "]"; int groupiconindex = scriptpanel.Icons.GetScriptFolderIcon(res.ScriptType, false); TreeNode scriptroot; if(root.Nodes.ContainsKey(typename)) { scriptroot = root.Nodes[typename]; } else { var rdata = new TextResourceNodeData { ResourceLocation = key, NodeType = TextResourceNodeType.DIRECTORY, ScriptType = res.ScriptType, }; scriptroot = new TreeNode(typename, groupiconindex, groupiconindex) { Tag = rdata, Name = typename, ToolTipText = rdata.ToString() }; if(asreadonly) scriptroot.ForeColor = SystemColors.GrayText; root.Nodes.Add(scriptroot); TrySelectNode(selected, scriptroot, ref toselect); } // Add the resource path nodes if needed... string path = Path.GetDirectoryName(res.Filename); TreeNode pathnode = scriptroot; string localpath = string.Empty; if(!string.IsNullOrEmpty(path)) { List<string> parts = new List<string>(path.Split(splitter, StringSplitOptions.RemoveEmptyEntries)); while(parts.Count > 0) { if(pathnode.Nodes.ContainsKey(parts[0])) { pathnode = pathnode.Nodes[parts[0]]; } else { localpath = Path.Combine(localpath, parts[0]); TreeNode child = new TreeNode(parts[0], groupiconindex, groupiconindex); child.Name = parts[0]; var cdata = new TextResourceNodeData { ResourceLocation = key, LocationInResource = path, NodeType = TextResourceNodeType.DIRECTORY, ScriptType = res.ScriptType }; child.Tag = cdata; child.ToolTipText = cdata.ToString(); if(asreadonly) child.ForeColor = SystemColors.GrayText; pathnode.Nodes.Add(child); pathnode = child; TrySelectNode(selected, pathnode, ref toselect); } parts.RemoveAt(0); } } // Create new node TextResourceNodeData data = new TextResourceNodeData { ResourceLocation = key, LocationInResource = path, NodeType = TextResourceNodeType.NODE, Resource = res, ScriptType = res.ScriptType, }; string includepath = (res.ScriptType == ScriptType.ACS ? "\nInclude path: \"" + res.Filename + "\"" : ""); TreeNode scriptnode = new TreeNode(res.ToString(), iconindex, iconindex) { Tag = data, ToolTipText = data + includepath }; if(asreadonly) scriptnode.ForeColor = SystemColors.GrayText; TrySelectNode(selected, scriptnode, ref toselect); // Add the node pathnode.Nodes.Add(scriptnode); } } } } // If there's only one root node, shift all nodes up if(projecttree.Nodes.Count == 1 && projecttree.Nodes[0].Nodes.Count > 0) { TreeNode[] children = new TreeNode[projecttree.Nodes[0].Nodes.Count]; projecttree.Nodes[0].Nodes.CopyTo(children, 0); projecttree.Nodes.Clear(); projecttree.Nodes.AddRange(children); } // Sort the nodes projecttree.TreeViewNodeSorter = new ScriptNodesSorter(); // Have valid selection? if(toselect != null) projecttree.SelectedNode = toselect; // Expand all nodes when filtered if(filenamefiltered) projecttree.ExpandAll(); projecttree.EndUpdate(); }