diff --git a/ANX.Framework.Content.Pipeline/Tasks/ContentProject.cs b/ANX.Framework.Content.Pipeline/Tasks/ContentProject.cs index 07bb36b5..816e05df 100644 --- a/ANX.Framework.Content.Pipeline/Tasks/ContentProject.cs +++ b/ANX.Framework.Content.Pipeline/Tasks/ContentProject.cs @@ -199,6 +199,7 @@ namespace ANX.Framework.Content.Pipeline.Tasks writer.WriteEndElement(); } writer.WriteEndElement(); + writer.WriteEndElement(); } writer.WriteEndElement(); @@ -309,23 +310,36 @@ namespace ANX.Framework.Content.Pipeline.Tasks case "BuildItem": if (versionMajor == 1 && versionMinor >= 0) { + if (reader.NodeType != XmlNodeType.Element) + break; var buildItem = new BuildItem(); lastBuildItem = buildItem; - if (reader.NodeType == XmlNodeType.Attribute) + reader.MoveToFirstAttribute(); + while (reader.NodeType == XmlNodeType.Attribute) { switch (reader.Name) { case "AssetName": buildItem.AssetName = reader.ReadContentAsString(); + reader.MoveToNextAttribute(); break; case "OutputFilename": buildItem.OutputFilename = reader.ReadContentAsString(); + reader.MoveToNextAttribute(); break; case "Importer": buildItem.ImporterName = reader.ReadContentAsString(); + reader.MoveToNextAttribute(); break; case "Processor": buildItem.ProcessorName = reader.ReadContentAsString(); + if (buildItem.AssetName == null) + reader.MoveToNextAttribute(); + else + reader.Read(); + break; + case "": + reader.Read(); break; } } diff --git a/Tools/ANXContentCompilerGUI/ANX.ContentCompiler.GUI.csproj b/Tools/ANXContentCompilerGUI/ANX.ContentCompiler.GUI.csproj index 701210d8..166e62bc 100644 --- a/Tools/ANXContentCompilerGUI/ANX.ContentCompiler.GUI.csproj +++ b/Tools/ANXContentCompilerGUI/ANX.ContentCompiler.GUI.csproj @@ -22,6 +22,7 @@ DEBUG;TRACE prompt 4 + true AnyCPU @@ -123,6 +124,7 @@ + ArrowButton.cs diff --git a/Tools/ANXContentCompilerGUI/Dialogues/NewProjectScreen.cs b/Tools/ANXContentCompilerGUI/Dialogues/NewProjectScreen.cs index a16b05c0..e877ea11 100644 --- a/Tools/ANXContentCompilerGUI/Dialogues/NewProjectScreen.cs +++ b/Tools/ANXContentCompilerGUI/Dialogues/NewProjectScreen.cs @@ -59,6 +59,8 @@ namespace ANX.ContentCompiler.GUI.Dialogues { if (String.IsNullOrEmpty(textBoxName.Text)) MessageBox.Show("Give your child a name!", "Missing value", MessageBoxButtons.OK, MessageBoxIcon.Warning); + else if (Directory.Exists(textBoxLocation.Text)) + MessageBox.Show("A project with this name already exists in that path!", "Will not overwrite existing stuff", MessageBoxButtons.OK, MessageBoxIcon.Error); else DialogResult = DialogResult.OK; } diff --git a/Tools/ANXContentCompilerGUI/MainWindow.Designer.cs b/Tools/ANXContentCompilerGUI/MainWindow.Designer.cs index 53eea6ff..88820eba 100644 --- a/Tools/ANXContentCompilerGUI/MainWindow.Designer.cs +++ b/Tools/ANXContentCompilerGUI/MainWindow.Designer.cs @@ -259,6 +259,7 @@ namespace ANX.ContentCompiler.GUI this.treeView.Name = "treeView"; this.treeView.Size = new System.Drawing.Size(219, 527); this.treeView.TabIndex = 0; + this.treeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.TreeViewAfterSelect); // // treeViewContextMenu // @@ -318,7 +319,7 @@ namespace ANX.ContentCompiler.GUI this.splitContainerProperties.Panel2.Controls.Add(this.propertyGrid); this.splitContainerProperties.Panel2.ForeColor = System.Drawing.Color.White; this.splitContainerProperties.Size = new System.Drawing.Size(640, 549); - this.splitContainerProperties.SplitterDistance = 409; + this.splitContainerProperties.SplitterDistance = 366; this.splitContainerProperties.TabIndex = 0; // // editingState @@ -327,7 +328,7 @@ namespace ANX.ContentCompiler.GUI this.editingState.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.editingState.Location = new System.Drawing.Point(0, 0); this.editingState.Name = "editingState"; - this.editingState.Size = new System.Drawing.Size(407, 547); + this.editingState.Size = new System.Drawing.Size(364, 547); this.editingState.TabIndex = 1; this.editingState.Visible = false; // @@ -337,7 +338,7 @@ namespace ANX.ContentCompiler.GUI this.startState.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.startState.Location = new System.Drawing.Point(0, 0); this.startState.Name = "startState"; - this.startState.Size = new System.Drawing.Size(407, 547); + this.startState.Size = new System.Drawing.Size(364, 547); this.startState.TabIndex = 0; this.startState.Visible = false; // @@ -349,7 +350,7 @@ namespace ANX.ContentCompiler.GUI this.labelProperties.ForeColor = System.Drawing.Color.White; this.labelProperties.Location = new System.Drawing.Point(3, 0); this.labelProperties.Name = "labelProperties"; - this.labelProperties.Size = new System.Drawing.Size(221, 19); + this.labelProperties.Size = new System.Drawing.Size(264, 19); this.labelProperties.TabIndex = 2; this.labelProperties.Text = "Properties"; this.labelProperties.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; @@ -370,10 +371,11 @@ namespace ANX.ContentCompiler.GUI this.propertyGrid.LineColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); this.propertyGrid.Location = new System.Drawing.Point(3, 22); this.propertyGrid.Name = "propertyGrid"; - this.propertyGrid.Size = new System.Drawing.Size(221, 503); + this.propertyGrid.Size = new System.Drawing.Size(264, 503); this.propertyGrid.TabIndex = 0; this.propertyGrid.ViewBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(44)))), ((int)(((byte)(44)))), ((int)(((byte)(44))))); this.propertyGrid.ViewForeColor = System.Drawing.Color.White; + this.propertyGrid.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler(this.PropertyGridPropertyValueChanged); // // menuState // diff --git a/Tools/ANXContentCompilerGUI/MainWindow.cs b/Tools/ANXContentCompilerGUI/MainWindow.cs index 6fe39e2e..34433800 100644 --- a/Tools/ANXContentCompilerGUI/MainWindow.cs +++ b/Tools/ANXContentCompilerGUI/MainWindow.cs @@ -1,6 +1,8 @@ using System; +using System.Collections.Generic; using System.Drawing; using System.IO; +using System.Linq; using System.Windows.Forms; using ANX.ContentCompiler.GUI.Dialogues; using ANX.Framework.Content.Pipeline; @@ -103,6 +105,7 @@ namespace ANX.ContentCompiler.GUI _contentProject = new ContentProject(ProjectName) { OutputDirectory = ProjectOutputDir, + InputDirectory = ProjectFolder, Configuration = "Release", Creator = "ANX Content Compiler (4.0)", ContentRoot = "Content", @@ -166,6 +169,42 @@ namespace ANX.ContentCompiler.GUI } #endregion + #region FileMethods + private void AddFile(string file) + { + if (!File.Exists(file)) + throw new FileNotFoundException(); + + var folder = _contentProject.ContentRoot; + var node = treeView.SelectedNode; + if (node != null) + folder = node.Name; + else + node = treeView.Nodes[0]; + var absPath = ProjectFolder + Path.DirectorySeparatorChar + folder + Path.DirectorySeparatorChar + Path.GetFileName(file); + if (!Directory.Exists(Path.Combine(ProjectFolder, folder))) + Directory.CreateDirectory(Path.Combine(ProjectFolder, folder)); + File.Copy(file, absPath); + var item = new BuildItem + { + AssetName = String.IsNullOrEmpty(folder) ? folder.Replace(_contentProject.ContentRoot, "") + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(file) : Path.GetFileNameWithoutExtension(file), + SourceFilename = absPath, + OutputFilename = ProjectOutputDir + Path.DirectorySeparatorChar + folder + Path.DirectorySeparatorChar + Path.GetFileName(file), + ImporterName = ImporterManager.GuessImporterByFileExtension(file) + }; + _contentProject.BuildItems.Add(item); + } + + public void AddFiles(string[] files) + { + foreach (var file in files) + { + AddFile(file); + } + ChangeEnvironmentOpenProject(); + } + #endregion + #region EnvironmentStates public void ChangeEnvironmentStartState() { @@ -173,6 +212,8 @@ namespace ANX.ContentCompiler.GUI startState.Visible = true; Text = "ANX Content Compiler 4"; labelTitle.Text = "ANX Content Compiler 4"; + treeView.Nodes.Clear(); + propertyGrid.SelectedObject = null; } public void ChangeEnvironmentOpenProject() @@ -181,6 +222,68 @@ namespace ANX.ContentCompiler.GUI editingState.Visible = true; Text = ProjectName + " - ANX Content Compiler 4"; labelTitle.Text = "ANX Content Compiler 4 - " + ProjectName; + + ProjectFolder = _contentProject.InputDirectory; + treeView.Nodes.Clear(); + var rootNode = new TreeNode(ProjectName + "(" + _contentProject.ContentRoot + ")") {Name = _contentProject.ContentRoot}; + treeView.Nodes.Add(rootNode); + var lastNode = rootNode; + foreach (var parts in _contentProject.BuildItems.Select(buildItem => buildItem.AssetName.Split('/')).Where(parts => parts.Length >= 2)) + { + for (int i=0; i < parts.Length - 1; i++) + { + var node = new TreeNode(parts[i]) {Name = lastNode.Name + "/" + parts[i] + "/"}; + if (!lastNode.Nodes.Contains(node)) + { + lastNode.Nodes.Add(node); + lastNode = node; + } + else + { + lastNode = lastNode.Nodes[parts[i]]; + } + } + lastNode = rootNode; + } + if (_contentProject.BuildItems.Count > 0) + { + foreach (var buildItem in _contentProject.BuildItems) + { + String[] parts = null; + if (buildItem.AssetName.Contains("\\")) + parts = buildItem.AssetName.Split('\\'); + else if (buildItem.AssetName.Contains("/")) + parts = buildItem.AssetName.Split('/'); + /*if (parts.Length >= 2) + { + for (int i = 0; i < parts.Length - 1; i++) + { + lastNode = lastNode.Nodes[parts[i]]; + } + }*/ + string path = ""; + if (parts != null) + { + for (int i = 0; i < parts.Length - 1; i++) + { + path = parts[i]; + } + } + if (!String.IsNullOrEmpty(path)) + { + var node = treeView.RecursiveSearch(path); + if (node == null) throw new ArgumentNullException("Node not found!"); + var item = new TreeNode(parts[parts.Length - 1]) {Name = buildItem.AssetName}; + node.Nodes.Add(item); + } + else + { + var item = new TreeNode(buildItem.AssetName) {Name = buildItem.AssetName}; + treeView.Nodes[0].Nodes.Add(item); + } + } + } + } #endregion @@ -295,5 +398,39 @@ namespace ANX.ContentCompiler.GUI } #endregion + + #region TreeViewEvents + private void TreeViewAfterSelect(object sender, TreeViewEventArgs e) + { + if (treeView.SelectedNode == treeView.TopNode) + propertyGrid.SelectedObject = _contentProject; + else + { + foreach (var buildItem in _contentProject.BuildItems.Where(buildItem => buildItem.AssetName.Equals(treeView.SelectedNode.Name))) + { + propertyGrid.SelectedObject = buildItem; + } + } + } + #endregion + + #region PropertyGridEvents + private void PropertyGridPropertyValueChanged(object s, PropertyValueChangedEventArgs e) + { + ProjectName = _contentProject.Name; + ProjectImportersDir = _contentProject.ReferenceIncludeDirectory; + ProjectFolder = _contentProject.InputDirectory; + ProjectOutputDir = _contentProject.OutputDirectory; + if (e.ChangedItem.Label.Equals("ContentRoot")) + { + foreach (BuildItem buildItem in _contentProject.BuildItems) + { + buildItem.AssetName = buildItem.AssetName.Replace((string)e.OldValue, _contentProject.ContentRoot); + } + treeView.Nodes[0].RecursivelyReplacePartOfName((string)e.OldValue, _contentProject.ContentRoot); + } + ChangeEnvironmentOpenProject(); + } + #endregion } } \ No newline at end of file diff --git a/Tools/ANXContentCompilerGUI/States/EditingState.Designer.cs b/Tools/ANXContentCompilerGUI/States/EditingState.Designer.cs index 78f1107f..9560ba04 100644 --- a/Tools/ANXContentCompilerGUI/States/EditingState.Designer.cs +++ b/Tools/ANXContentCompilerGUI/States/EditingState.Designer.cs @@ -58,6 +58,7 @@ this.arrowButtonAddFiles.Name = "arrowButtonAddFiles"; this.arrowButtonAddFiles.Size = new System.Drawing.Size(348, 64); this.arrowButtonAddFiles.TabIndex = 5; + this.arrowButtonAddFiles.Click += new System.EventHandler(this.ArrowButtonAddFilesClick); // // arrowButtonCreateFolder // diff --git a/Tools/ANXContentCompilerGUI/States/EditingState.cs b/Tools/ANXContentCompilerGUI/States/EditingState.cs index 192cf071..eae7aa42 100644 --- a/Tools/ANXContentCompilerGUI/States/EditingState.cs +++ b/Tools/ANXContentCompilerGUI/States/EditingState.cs @@ -16,5 +16,16 @@ namespace ANX.ContentCompiler.GUI.States BackColor = Settings.MainColor; } + private void ArrowButtonAddFilesClick(object sender, EventArgs e) + { + using (var dlg = new OpenFileDialog()) + { + dlg.Multiselect = true; + dlg.Title = "Add files"; + if (dlg.ShowDialog() == DialogResult.OK) + MainWindow.Instance.AddFiles(dlg.FileNames); + } + } + } } diff --git a/Tools/ANXContentCompilerGUI/States/EditingState.resx b/Tools/ANXContentCompilerGUI/States/EditingState.resx index 5ea0895e..29dcb1b3 100644 --- a/Tools/ANXContentCompilerGUI/States/EditingState.resx +++ b/Tools/ANXContentCompilerGUI/States/EditingState.resx @@ -112,9 +112,9 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 \ No newline at end of file diff --git a/Tools/ANXContentCompilerGUI/TreeViewExtensions.cs b/Tools/ANXContentCompilerGUI/TreeViewExtensions.cs new file mode 100644 index 00000000..9ce8bc9c --- /dev/null +++ b/Tools/ANXContentCompilerGUI/TreeViewExtensions.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace ANX.ContentCompiler.GUI +{ + public static class TreeViewExtensions + { + /// + /// Performs a recursive search on this TreeView's nodes and its child nodes. Returns the first item found. + /// + /// The TreeView + /// Name to search for + /// The first node matching the given criteria or null + public static TreeNode RecursiveSearch(this TreeView treeView, String name) + { + foreach (TreeNode treeNode in treeView.Nodes) + { + if (treeNode.Name.Equals(name)) + return treeNode; + + var retNode = treeNode.RecursiveSearch(name); + if (retNode != null) + { + return retNode; + } + } + return null; + } + + /// + /// Performs a recursive search on this TreeNode's nodes and their child nodes. Returns the first item found. + /// + /// The TreeNode + /// Name to search for + /// The first node matching the given criteria or null + public static TreeNode RecursiveSearch(this TreeNode treeNode, String name) + { + foreach (TreeNode node in treeNode.Nodes) + { + if (node.Name.Equals(name)) + return node; + + var ret = node.RecursiveSearch(name); + if (ret != null) + return ret; + } + return null; + } + + /// + /// Recursively replaces all parts of the names/texts with new values. + /// + /// + /// + /// + public static void RecursivelyReplacePartOfName(this TreeNode tree, string old, string newString) + { + tree.Name = tree.Name.Replace(old, newString); + tree.Text = tree.Text.Replace(old, newString); + foreach (TreeNode node in tree.Nodes) + { + node.RecursivelyReplacePartOfName(old, newString); + } + } + } +}