SonicAudioTools/Source/CsbBuilder/MainForm.cs
2017-01-26 23:40:46 +03:00

2254 lines
82 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Xml;
using System.Xml.Serialization;
using CsbBuilder.Builder;
using CsbBuilder.BuilderNode;
using CsbBuilder.Audio;
using CsbBuilder.Importer;
using CsbBuilder.Project;
using CsbBuilder.Serialization;
using CsbBuilder.Properties;
using SonicAudioLib.IO;
using NAudio.Wave;
namespace CsbBuilder
{
public partial class MainForm : Form
{
private bool enabled = false;
private bool saved = true;
private CsbProject project = null;
private TreeNode copiedNode = null;
private TreeView treeViewOfCopiedNode = null;
private List<IWavePlayer> sounds = new List<IWavePlayer>();
public MainForm()
{
InitializeComponent();
imageList.Images.Add("Node", Resources.Node);
imageList.Images.Add("Folder", Resources.Folder);
imageList.Images.Add("FolderOpen", Resources.FolderOpen);
imageList.Images.Add("Sound", Resources.Sound);
}
public void ClearTreeViews()
{
cueTree.Nodes.Clear();
synthTree.Nodes.Clear();
soundElementTree.Nodes.Clear();
aisacTree.Nodes.Clear();
voiceLimitGroupTree.Nodes.Clear();
}
public void ExpandAllTreeViews()
{
cueTree.ExpandAll();
if (cueTree.Nodes.Count > 0)
{
cueTree.Nodes[0].EnsureVisible();
}
synthTree.ExpandAll();
if (synthTree.Nodes.Count > 0)
{
synthTree.Nodes[0].EnsureVisible();
}
soundElementTree.ExpandAll();
if (soundElementTree.Nodes.Count > 0)
{
soundElementTree.Nodes[0].EnsureVisible();
}
aisacTree.ExpandAll();
if (aisacTree.Nodes.Count > 0)
{
aisacTree.Nodes[0].EnsureVisible();
}
voiceLimitGroupTree.ExpandAll();
if (voiceLimitGroupTree.Nodes.Count > 0)
{
voiceLimitGroupTree.Nodes[0].EnsureVisible();
}
}
public void ClearProject()
{
project = null;
ClearTreeViews();
Text = "CSB Builder";
saved = true;
}
public void DisplayOnTreeView()
{
foreach (BuilderCueNode cueNode in project.CueNodes)
{
TreeNode treeNode = new TreeNode();
treeNode.ContextMenuStrip = cueReferenceMenu;
treeNode.Name = cueNode.Name;
treeNode.Text = treeNode.Name;
treeNode.Tag = cueNode;
cueTree.Nodes.Add(treeNode);
}
foreach (BuilderSynthNode synthNode in project.SynthNodes)
{
TreeNode treeNode = synthTree.CreateNodesByFullPath(synthNode.Name);
treeNode.ContextMenuStrip = trackMenu;
treeNode.Tag = synthNode;
if (synthNode.Type == BuilderSynthType.Single)
{
treeNode.ContextMenuStrip = trackItemMenu;
treeNode.ImageIndex = 3;
treeNode.SelectedImageIndex = 3;
}
while ((treeNode = treeNode.Parent) != null)
{
if (treeNode.Tag == null)
{
treeNode.ContextMenuStrip = synthFolderMenu;
}
}
}
foreach (BuilderSoundElementNode soundElementNode in project.SoundElementNodes)
{
TreeNode treeNode = soundElementTree.CreateNodesByFullPath(soundElementNode.Name);
treeNode.ContextMenuStrip = soundElementMenu;
treeNode.Tag = soundElementNode;
treeNode.ImageIndex = 3;
treeNode.SelectedImageIndex = 3;
while ((treeNode = treeNode.Parent) != null)
{
if (treeNode.Tag == null)
{
treeNode.ContextMenuStrip = folderMenu;
}
}
}
foreach (BuilderAisacNode aisacNode in project.AisacNodes)
{
TreeNode treeNode = aisacTree.CreateNodesByFullPath(aisacNode.Name);
treeNode.ContextMenuStrip = aisacNodeMenu;
treeNode.Tag = aisacNode;
while ((treeNode = treeNode.Parent) != null)
{
if (treeNode.Tag == null)
{
treeNode.ContextMenuStrip = aisacFolderMenu;
}
}
}
foreach (BuilderVoiceLimitGroupNode voiceLimitGroupNode in project.VoiceLimitGroupNodes)
{
TreeNode treeNode = new TreeNode();
treeNode.ContextMenuStrip = nodeMenu;
treeNode.Name = voiceLimitGroupNode.Name;
treeNode.Text = treeNode.Name;
treeNode.Tag = voiceLimitGroupNode;
voiceLimitGroupTree.Nodes.Add(treeNode);
}
}
public void SetProject(CsbProject project)
{
StopSound(null, null);
if (!enabled)
{
splitContainer1.Enabled = true;
splitContainer2.Enabled = true;
propertyGrid.Enabled = true;
saveProjectAsToolStripMenuItem.Enabled = true;
saveProjectToolStripMenuItem.Enabled = true;
buildCurrentProjectAsToolStripMenuItem.Enabled = true;
buildCurrentProjectToolStripMenuItem.Enabled = true;
mergeProjectToolStripMenuItem.Enabled = true;
ımportAndMergeToolStripMenuItem.Enabled = true;
enabled = true;
}
ClearProject();
this.project = project;
project.Create();
DisplayOnTreeView();
UpdateAllNodes();
ExpandAllTreeViews();
Text += $" - {project.Name}";
}
private void CreateNewProject(object sender, EventArgs e)
{
if (AskForSave() == DialogResult.Cancel)
{
return;
}
using (CreateNewProjectForm newProject = new CreateNewProjectForm())
{
if (newProject.ShowDialog(this) == DialogResult.OK)
{
SetProject(newProject.Project);
project.Save();
}
}
}
private void ImportCsbFile(object sender, EventArgs e)
{
if (AskForSave() == DialogResult.Cancel)
{
return;
}
using (OpenFileDialog openCsbFile = new OpenFileDialog
{
Title = "Import CSB File",
DefaultExt = "csb",
Filter = "CSB Files|*.csb",
})
{
if (openCsbFile.ShowDialog() == DialogResult.OK)
{
using (CreateNewProjectForm createProject = new CreateNewProjectForm(openCsbFile.FileName))
{
if (createProject.ShowDialog(this) == DialogResult.OK)
{
createProject.Project.Create();
CsbImporter.Import(openCsbFile.FileName, createProject.Project);
SetProject(createProject.Project);
project.Save();
}
}
}
}
}
private void OnNodeClick(object sender, TreeNodeMouseClickEventArgs e)
{
e.Node.TreeView.SelectedNode = e.Node;
}
private TreeNode CreateCueNode(TreeNodeCollection collection, TreeNode parent, int nodeIndex = -1)
{
saved = false;
int index = 0;
while (collection.ContainsKey($"Cue_{index}"))
{
index++;
}
TreeNode treeNode = nodeIndex == -1 ? collection.Add($"Cue_{index}") : collection.Insert(nodeIndex, $"Cue_{index}");
treeNode.Name = treeNode.Text;
treeNode.ContextMenuStrip = cueReferenceMenu;
BuilderCueNode cueNode = new BuilderCueNode();
cueNode.Name = treeNode.FullPath;
if (project.CueNodes.Count > 0)
{
cueNode.Identifier = project.CueNodes.Max(cue => cue.Identifier) + 1;
}
treeNode.Tag = cueNode;
project.CueNodes.Add(cueNode);
treeNode.TreeView.SelectedNode = treeNode;
treeNode.EnsureVisible();
return treeNode;
}
private void RemoveNode(BuilderBaseNode node)
{
if (node is BuilderCueNode)
{
project.CueNodes.Remove((BuilderCueNode)node);
}
else if (node is BuilderSynthNode)
{
BuilderSynthNode synthNode = (BuilderSynthNode)node;
project.SynthNodes.Remove(synthNode);
project.CueNodes.Where(cue => cue.SynthReference == synthNode.Name).ToList().ForEach(cue => cue.SynthReference = string.Empty);
project.SynthNodes.Where(synth => synth.Children.Contains(synthNode.Name)).ToList().ForEach(synth => synth.Children.Remove(synthNode.Name));
}
else if (node is BuilderSoundElementNode)
{
BuilderSoundElementNode soundElementNode = (BuilderSoundElementNode)node;
project.SoundElementNodes.Remove(soundElementNode);
project.SynthNodes.Where(soundElement => soundElement.SoundElementReference == soundElementNode.Name).ToList().ForEach(synth => synth.SoundElementReference = string.Empty);
}
else if (node is BuilderAisacNode)
{
BuilderAisacNode aisacNode = (BuilderAisacNode)node;
project.AisacNodes.Remove(aisacNode);
project.SynthNodes.Where(synth => synth.AisacReference == aisacNode.Name).ToList().ForEach(synth => synth.AisacReference = string.Empty);
}
else if (node is BuilderVoiceLimitGroupNode)
{
BuilderVoiceLimitGroupNode voiceLimitGroupNode = (BuilderVoiceLimitGroupNode)node;
project.VoiceLimitGroupNodes.Remove(voiceLimitGroupNode);
project.SynthNodes.Where(synth => synth.VoiceLimitGroupReference == voiceLimitGroupNode.Name).ToList().ForEach(voiceLimitGroup => voiceLimitGroup.VoiceLimitGroupReference = string.Empty);
}
}
private TreeNode CreateSynthNode(TreeNodeCollection collection, TreeNode parent, int nodeIndex = -1)
{
saved = false;
int index = 0;
while (collection.ContainsKey($"Synth_{index}"))
{
index++;
}
TreeNode treeNode = nodeIndex == -1 ? collection.Add($"Synth_{index}") : collection.Insert(nodeIndex, $"Synth_{index}");
treeNode.Name = treeNode.Text;
treeNode.ContextMenuStrip = trackMenu;
BuilderSynthNode synthNode = new BuilderSynthNode();
synthNode.Type = BuilderSynthType.WithChildren;
synthNode.Name = treeNode.FullPath;
treeNode.Tag = synthNode;
project.SynthNodes.Add(synthNode);
if (parent != null && parent.Tag is BuilderSynthNode)
{
BuilderSynthNode parentSynthNode = (BuilderSynthNode)parent.Tag;
if (parentSynthNode.Type == BuilderSynthType.WithChildren)
{
parentSynthNode.Children.Add(synthNode.Name);
}
}
treeNode.TreeView.SelectedNode = treeNode;
treeNode.EnsureVisible();
return treeNode;
}
private TreeNode CreateSoundNode(TreeNodeCollection collection, TreeNode parent, int nodeIndex = -1)
{
saved = false;
int index = 0;
while (collection.ContainsKey($"Sound_{index}"))
{
index++;
}
TreeNode treeNode = nodeIndex == -1 ? collection.Add($"Sound_{index}") : collection.Insert(nodeIndex, $"Sound_{index}");
treeNode.Name = treeNode.Text;
treeNode.ContextMenuStrip = trackItemMenu;
treeNode.ImageIndex = 3;
treeNode.SelectedImageIndex = 3;
BuilderSynthNode synthNode = new BuilderSynthNode();
synthNode.Name = treeNode.FullPath;
treeNode.Tag = synthNode;
project.SynthNodes.Add(synthNode);
if (parent != null && parent.Tag is BuilderSynthNode)
{
BuilderSynthNode parentSynthNode = (BuilderSynthNode)parent.Tag;
if (parentSynthNode.Type == BuilderSynthType.WithChildren)
{
parentSynthNode.Children.Add(synthNode.Name);
}
}
treeNode.TreeView.SelectedNode = treeNode;
treeNode.EnsureVisible();
return treeNode;
}
private TreeNode CreateSoundElementNode(TreeNodeCollection collection, TreeNode parent, int nodeIndex = -1)
{
saved = false;
int index = 0;
while (collection.ContainsKey($"SoundElement_{index}"))
{
index++;
}
TreeNode treeNode = nodeIndex == -1 ? collection.Add($"SoundElement_{index}") : collection.Insert(nodeIndex, $"SoundElement_{index}");
treeNode.Name = treeNode.Text;
treeNode.ContextMenuStrip = soundElementMenu;
BuilderSoundElementNode soundElementNode = new BuilderSoundElementNode();
soundElementNode.Name = treeNode.FullPath;
treeNode.Tag = soundElementNode;
treeNode.ImageIndex = 3;
treeNode.SelectedImageIndex = 3;
project.SoundElementNodes.Add(soundElementNode);
treeNode.TreeView.SelectedNode = treeNode;
treeNode.EnsureVisible();
return treeNode;
}
private TreeNode CreateAisacNode(TreeNodeCollection collection, TreeNode parent, int nodeIndex = -1, BuilderAisacNode aisacNodeToImport = null)
{
saved = false;
int index = 0;
while (collection.ContainsKey($"AISAC_{index}"))
{
index++;
}
TreeNode treeNode = nodeIndex == -1 ? collection.Add($"AISAC_{index}") : collection.Insert(nodeIndex, $"AISAC_{index}");
treeNode.Name = treeNode.Text;
treeNode.ContextMenuStrip = aisacNodeMenu;
BuilderAisacNode aisacNode = aisacNodeToImport != null ? aisacNodeToImport : new BuilderAisacNode();
aisacNode.Name = treeNode.FullPath;
treeNode.Tag = aisacNode;
project.AisacNodes.Add(aisacNode);
treeNode.TreeView.SelectedNode = treeNode;
treeNode.EnsureVisible();
return treeNode;
}
private TreeNode CreateVoiceLimitGroupNode(TreeNodeCollection collection, TreeNode parent, int nodeIndex = -1)
{
saved = false;
int index = 0;
while (collection.ContainsKey($"VoiceLimitGroup_{index}"))
{
index++;
}
TreeNode treeNode = nodeIndex == -1 ? collection.Add($"VoiceLimitGroup_{index}") : collection.Insert(nodeIndex, $"VoiceLimitGroup_{index}");
treeNode.Name = treeNode.Text;
treeNode.ContextMenuStrip = nodeMenu;
BuilderVoiceLimitGroupNode voiceLimitGroup = new BuilderVoiceLimitGroupNode();
voiceLimitGroup.Name = treeNode.FullPath;
treeNode.Tag = voiceLimitGroup;
project.VoiceLimitGroupNodes.Add(voiceLimitGroup);
treeNode.TreeView.SelectedNode = treeNode;
treeNode.EnsureVisible();
return treeNode;
}
private TreeNode CreateFolder(TreeNodeCollection collection, TreeNode parent)
{
saved = false;
int index = 0;
while (collection.ContainsKey($"Folder_{index}"))
{
index++;
}
TreeNode treeNode = collection.Add($"Folder_{index}");
treeNode.Name = treeNode.Text;
treeNode.ContextMenuStrip = folderMenu;
treeNode.ImageIndex = 1;
treeNode.SelectedImageIndex = 2;
treeNode.TreeView.SelectedNode = treeNode;
treeNode.EnsureVisible();
return treeNode;
}
private TreeNode CreateSynthFolder(TreeNodeCollection collection)
{
saved = false;
int index = 0;
while (collection.ContainsKey($"Folder_{index}"))
{
index++;
}
TreeNode treeNode = collection.Add($"Folder_{index}");
treeNode.Name = treeNode.Text;
treeNode.ContextMenuStrip = synthFolderMenu;
treeNode.ImageIndex = 1;
treeNode.SelectedImageIndex = 2;
treeNode.TreeView.SelectedNode = treeNode;
treeNode.EnsureVisible();
return treeNode;
}
private void CreateChildNode(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView)
{
TreeView selectedTree = (TreeView)menuStrip.SourceControl;
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedTree == cueTree)
{
CreateCueNode(selectedTree.Nodes, null);
}
else if (selectedTree == synthTree)
{
if (selectedNode.Tag is BuilderSynthNode && ((BuilderSynthNode)selectedNode.Tag).Type == BuilderSynthType.WithChildren)
{
CreateSoundNode(selectedNode.Nodes, selectedNode);
}
else
{
CreateSynthNode(selectedNode.Nodes, selectedNode);
}
}
else if (selectedTree == soundElementTree)
{
CreateSoundElementNode(selectedNode.Nodes, selectedNode);
}
else if (selectedTree == aisacTree)
{
CreateAisacNode(selectedNode.Nodes, selectedNode);
}
else if (selectedTree == voiceLimitGroupTree)
{
CreateVoiceLimitGroupNode(selectedTree.Nodes, null);
}
}
}
private void CreateNode(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView)
{
TreeView selectedTree = (TreeView)menuStrip.SourceControl;
if (selectedTree == cueTree)
{
CreateCueNode(selectedTree.Nodes, null);
}
else if (selectedTree == synthTree)
{
CreateSynthNode(selectedTree.Nodes, null);
}
else if (selectedTree == soundElementTree)
{
CreateSoundElementNode(selectedTree.Nodes, null);
}
else if (selectedTree == aisacTree)
{
CreateAisacNode(selectedTree.Nodes, null);
}
else if (selectedTree == voiceLimitGroupTree)
{
CreateVoiceLimitGroupNode(selectedTree.Nodes, null);
}
}
}
private void CreateFolder(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView)
{
TreeView selectedTree = (TreeView)menuStrip.SourceControl;
if (selectedTree == synthTree)
{
CreateSynthFolder(selectedTree.Nodes);
}
else
{
CreateFolder(selectedTree.Nodes, null);
}
}
}
private void RemoveNodes(TreeNodeCollection collection)
{
foreach (TreeNode node in collection)
{
if (node.Tag is BuilderBaseNode)
{
RemoveNode((BuilderBaseNode)node.Tag);
}
RemoveNodes(node.Nodes);
}
}
private void RemoveNode(TreeNode treeNode)
{
saved = false;
if (treeNode.Tag is BuilderBaseNode)
{
RemoveNode((BuilderBaseNode)treeNode.Tag);
}
RemoveNodes(treeNode.Nodes);
treeNode.Remove();
}
private void RemoveNode(object sender, EventArgs e)
{
saved = false;
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView)
{
TreeView selectedTree = (TreeView)menuStrip.SourceControl;
TreeNode selectedNode = selectedTree.SelectedNode;
RemoveNode(selectedNode);
}
}
private void BuildProject(object sender, EventArgs e)
{
project.BinaryDirectory.Create();
project.Order(cueTree, synthTree, soundElementTree, aisacTree, voiceLimitGroupTree);
Builder.CsbBuilder.Build(project, Path.Combine(project.BinaryDirectory.FullName, project.Name + ".csb"));
Process.Start(project.BinaryDirectory.FullName);
}
private void CopyFullPath(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView)
{
TreeView selectedTree = (TreeView)menuStrip.SourceControl;
TreeNode selectedNode = selectedTree.SelectedNode;
Clipboard.SetText(selectedNode.FullPath);
}
}
private void CreateChildFolder(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView)
{
TreeView selectedTree = (TreeView)menuStrip.SourceControl;
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedTree == synthTree)
{
CreateSynthFolder(selectedNode.Nodes);
}
else
{
CreateFolder(selectedNode.Nodes, selectedNode);
}
}
}
private void RenameNode(object sender, TreeNodeMouseClickEventArgs e)
{
e.Node.BeginEdit();
}
private void UpdateNodeNoRename(TreeNode treeNode)
{
if (treeNode.Tag is BuilderBaseNode)
{
BuilderBaseNode baseNode = (BuilderBaseNode)treeNode.Tag;
baseNode.Name = treeNode.FullPath;
}
foreach (TreeNode childNode in treeNode.Nodes)
{
UpdateNodeNoRename(childNode);
}
}
private void UpdateNodes(TreeNodeCollection collection)
{
foreach (TreeNode treeNode in collection)
{
if (treeNode.Tag is BuilderBaseNode)
{
BuilderBaseNode baseNode = (BuilderBaseNode)treeNode.Tag;
string previousName = baseNode.Name;
baseNode.Name = treeNode.FullPath;
// Do it only if it's different, don't waste time
if (previousName != baseNode.Name)
{
string fullPath = baseNode.Name;
if (baseNode is BuilderSynthNode)
{
project.CueNodes.Where(cue => cue.SynthReference == previousName).ToList().ForEach(cue => cue.SynthReference = fullPath);
project.SynthNodes.Where(synth => synth.Children.Contains(previousName)).ToList().ForEach(synth => synth.Children[synth.Children.IndexOf(previousName)] = fullPath);
}
else if (baseNode is BuilderSoundElementNode)
{
project.SynthNodes.Where(synth => synth.SoundElementReference == previousName).ToList().ForEach(synth => synth.SoundElementReference = fullPath);
}
else if (baseNode is BuilderAisacNode)
{
project.SynthNodes.Where(synth => synth.AisacReference == previousName).ToList().ForEach(synth => synth.AisacReference = fullPath);
}
else if (baseNode is BuilderVoiceLimitGroupNode)
{
project.SynthNodes.Where(synth => synth.VoiceLimitGroupReference == previousName).ToList().ForEach(synth => synth.VoiceLimitGroupReference = fullPath);
}
}
}
else
{
treeNode.ImageIndex = 1;
treeNode.SelectedImageIndex = 2;
}
UpdateNodes(treeNode.Nodes);
}
}
private void UpdateAllNodes()
{
UpdateNodes(cueTree.Nodes);
UpdateNodes(synthTree.Nodes);
UpdateNodes(soundElementTree.Nodes);
UpdateNodes(aisacTree.Nodes);
UpdateNodes(voiceLimitGroupTree.Nodes);
}
private void OnRenameEnd(object sender, NodeLabelEditEventArgs e)
{
if (string.IsNullOrEmpty(e.Label))
{
e.CancelEdit = true;
return;
}
saved = false;
string previousName = e.Node.FullPath;
e.Node.Name = e.Label;
e.Node.Text = e.Label;
string fullPath = e.Node.FullPath;
UpdateAllNodes();
if (e.Node.Tag is BuilderSynthNode)
{
project.CueNodes.Where(cue => cue.SynthReference == previousName).ToList().ForEach(cue => cue.SynthReference = fullPath);
project.SynthNodes.Where(synth => synth.Children.Contains(previousName)).ToList().ForEach(synth => synth.Children[synth.Children.IndexOf(previousName)] = fullPath);
}
else if (e.Node.Tag is BuilderSoundElementNode)
{
project.SynthNodes.Where(synth => synth.SoundElementReference == previousName).ToList().ForEach(synth => synth.SoundElementReference = fullPath);
}
else if (e.Node.Tag is BuilderAisacNode)
{
project.SynthNodes.Where(synth => synth.AisacReference == previousName).ToList().ForEach(synth => synth.AisacReference = fullPath);
}
else if (e.Node.Tag is BuilderVoiceLimitGroupNode)
{
project.SynthNodes.Where(synth => synth.VoiceLimitGroupReference == previousName).ToList().ForEach(synth => synth.VoiceLimitGroupReference = fullPath);
}
propertyGrid.Refresh();
}
private void OnPropertyChange(object s, PropertyValueChangedEventArgs e)
{
saved = false;
propertyGrid.Refresh();
}
private DialogResult AskForSave()
{
DialogResult dialogResult = DialogResult.No;
if (!saved)
{
dialogResult = MessageBox.Show("Do you want to save your changes?", "CSB Builder", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);
if (dialogResult == DialogResult.Yes)
{
SaveProject(null, null);
}
}
return dialogResult;
}
private void LoadProject(object sender, EventArgs e)
{
if (AskForSave() == DialogResult.Cancel)
{
return;
}
using (OpenFileDialog openProject = new OpenFileDialog
{
Title = "Open CSB Project File",
Filter = "CSB Project files|*.csbproject",
DefaultExt = "csbproject",
})
{
if (openProject.ShowDialog() == DialogResult.OK)
{
CsbProject csbProject = CsbProject.Load(openProject.FileName);
if (!csbProject.AudioDirectory.Exists)
{
MessageBox.Show("Audio directory does not seem to be present for this project. All the audio references will be removed.");
csbProject.SoundElementNodes.ForEach(soundElementNode => soundElementNode.Intro = string.Empty);
csbProject.SoundElementNodes.ForEach(soundElementNode => soundElementNode.Loop = string.Empty);
}
SetProject(csbProject);
}
}
}
private void SaveProject(object sender, EventArgs e)
{
project.Order(cueTree, synthTree, soundElementTree, aisacTree, voiceLimitGroupTree);
project.Save();
saved = true;
}
private void SaveProjectAs(object sender, EventArgs e)
{
using (SaveFileDialog saveProject = new SaveFileDialog
{
Title = "Save CSB Project File As",
Filter = "CSB Project files|*.csbproject",
DefaultExt = "csbproject",
})
{
if (saveProject.ShowDialog() == DialogResult.OK)
{
project.Order(cueTree, synthTree, soundElementTree, aisacTree, voiceLimitGroupTree);
project.SaveAs(saveProject.FileName);
saved = true;
// Reload the project
SetProject(project);
}
}
}
private void OnClose(object sender, FormClosingEventArgs e)
{
if (AskForSave() == DialogResult.Cancel)
{
e.Cancel = true;
}
}
private void Exit(object sender, EventArgs e)
{
Close();
}
private void BuildProjectAs(object sender, EventArgs e)
{
using (SaveFileDialog buildCsb = new SaveFileDialog()
{
Title = "Build Current Project As",
DefaultExt = "csb",
Filter = "CSB Files|*.csb",
FileName = project.Name,
})
{
if (buildCsb.ShowDialog() == DialogResult.OK)
{
project.Order(cueTree, synthTree, soundElementTree, aisacTree, voiceLimitGroupTree);
Builder.CsbBuilder.Build(project, buildCsb.FileName);
}
}
}
private void AfterNodeSelect(object sender, TreeViewEventArgs e)
{
propertyGrid.SelectedObject = e.Node.Tag;
}
private void MergeProject(object sender, EventArgs e)
{
using (OpenFileDialog openProject = new OpenFileDialog
{
Title = "Merge Project With",
Filter = "CSB Project files|*.csbproject",
DefaultExt = "csbproject",
})
{
if (openProject.ShowDialog() == DialogResult.OK)
{
CsbProject csbProject = CsbProject.Load(openProject.FileName);
if (!csbProject.AudioDirectory.Exists)
{
MessageBox.Show("Audio directory does not seem to be present for this project. All the audio references will be removed.");
csbProject.SoundElementNodes.ForEach(soundElementNode => soundElementNode.Intro = string.Empty);
csbProject.SoundElementNodes.ForEach(soundElementNode => soundElementNode.Loop = string.Empty);
}
else
{
// Copy all to this project's audio folder
foreach (FileInfo audioFile in csbProject.AudioDirectory.EnumerateFiles())
{
audioFile.CopyTo(Path.Combine(project.AudioDirectory.FullName, audioFile.Name), true);
}
}
project.CueNodes.AddRange(csbProject.CueNodes);
project.SynthNodes.AddRange(csbProject.SynthNodes);
project.SoundElementNodes.AddRange(csbProject.SoundElementNodes);
project.AisacNodes.AddRange(csbProject.AisacNodes);
project.VoiceLimitGroupNodes.AddRange(csbProject.VoiceLimitGroupNodes);
// Reload
SetProject(project);
}
}
}
private void ImportAndMergeProject(object sender, EventArgs e)
{
using (OpenFileDialog openCsbFile = new OpenFileDialog
{
Title = "Import And Merge CSB File With",
DefaultExt = "csb",
Filter = "CSB Files|*.csb",
})
{
if (openCsbFile.ShowDialog() == DialogResult.OK)
{
CsbProject csbProject = new CsbProject();
csbProject.Directory = project.Directory;
CsbImporter.Import(openCsbFile.FileName, csbProject);
project.CueNodes.AddRange(csbProject.CueNodes);
project.SynthNodes.AddRange(csbProject.SynthNodes);
project.SoundElementNodes.AddRange(csbProject.SoundElementNodes);
project.AisacNodes.AddRange(csbProject.AisacNodes);
project.VoiceLimitGroupNodes.AddRange(csbProject.VoiceLimitGroupNodes);
// Reload
SetProject(project);
}
}
}
private void OnKeyDown(object sender, KeyEventArgs e)
{
TreeView treeView = (TreeView)sender;
if (e.KeyCode == Keys.Delete && treeView.SelectedNode != null)
{
RemoveNode(treeView.SelectedNode);
}
else if (e.Control && e.KeyCode == Keys.C && treeView.SelectedNode != null)
{
CopyNode(treeView.SelectedNode);
}
else if (e.Control && e.KeyCode == Keys.V && treeView == treeViewOfCopiedNode)
{
if (treeView.SelectedNode == null)
{
PasteNode();
}
else if (treeView.SelectedNode != null && (treeView.SelectedNode.Tag == null || (treeView.SelectedNode.Tag is BuilderSynthNode && ((BuilderSynthNode)treeView.SelectedNode.Tag).Type == BuilderSynthType.WithChildren)))
{
PasteAsChildNode(treeView.SelectedNode);
}
else if (treeView.SelectedNode != null && treeView.SelectedNode.Tag != null)
{
PasteNode(treeView.SelectedNode.Index + 1);
}
}
else if (e.KeyCode == Keys.Enter && treeView.SelectedNode != null)
{
treeView.SelectedNode.BeginEdit();
}
}
private bool CheckIfAny(TreeView treeView)
{
foreach (TreeNode treeNode in treeView.Nodes)
{
if (CheckIfAny(treeNode))
{
return true;
}
}
return false;
}
private bool CheckIfAny(TreeNode treeNode)
{
if (treeNode.Tag != null)
{
return true;
}
foreach (TreeNode childNode in treeNode.Nodes)
{
if (CheckIfAny(childNode))
{
return true;
}
}
return false;
}
private void SetAisacReference(object sender, EventArgs e)
{
if (!CheckIfAny(aisacTree))
{
MessageBox.Show("This project does not contain any Aisac nodes.", "CSB Builder", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
using (SetReferenceForm setReferenceForm = new SetReferenceForm(aisacTree))
{
if (setReferenceForm.ShowDialog(this) == DialogResult.OK)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView)
{
TreeView selectedTree = (TreeView)menuStrip.SourceControl;
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedNode.Tag is BuilderSynthNode)
{
BuilderSynthNode synthNode = (BuilderSynthNode)selectedNode.Tag;
if (setReferenceForm.SelectedNode == null)
{
synthNode.AisacReference = string.Empty;
}
else
{
synthNode.AisacReference = setReferenceForm.SelectedNode.FullPath;
}
}
saved = false;
propertyGrid.Refresh();
}
}
}
}
private void SetVoiceLimitGroupReference(object sender, EventArgs e)
{
if (voiceLimitGroupTree.Nodes.Count == 0)
{
MessageBox.Show("This project does not contain any Voice Limit Group nodes.", "CSB Builder", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
using (SetReferenceForm setReferenceForm = new SetReferenceForm(voiceLimitGroupTree))
{
if (setReferenceForm.ShowDialog(this) == DialogResult.OK)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView)
{
TreeView selectedTree = (TreeView)menuStrip.SourceControl;
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedNode.Tag is BuilderSynthNode)
{
BuilderSynthNode synthNode = (BuilderSynthNode)selectedNode.Tag;
if (setReferenceForm.SelectedNode == null)
{
synthNode.VoiceLimitGroupReference = string.Empty;
}
else
{
synthNode.VoiceLimitGroupReference = setReferenceForm.SelectedNode.FullPath;
}
}
saved = false;
propertyGrid.Refresh();
}
}
}
}
private void SetSynthReference(object sender, EventArgs e)
{
if (!CheckIfAny(synthTree))
{
MessageBox.Show("This project does not contain any Synth nodes.", "CSB Builder", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
using (SetReferenceForm setReferenceForm = new SetReferenceForm(synthTree))
{
if (setReferenceForm.ShowDialog(this) == DialogResult.OK)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView)
{
TreeView selectedTree = (TreeView)menuStrip.SourceControl;
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedNode.Tag is BuilderCueNode)
{
BuilderCueNode cueNode = (BuilderCueNode)selectedNode.Tag;
if (setReferenceForm.SelectedNode == null)
{
cueNode.SynthReference = string.Empty;
}
else
{
cueNode.SynthReference = setReferenceForm.SelectedNode.FullPath;
}
}
saved = false;
propertyGrid.Refresh();
}
}
}
}
private void SelectSynthReference(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView)
{
TreeView selectedTree = (TreeView)menuStrip.SourceControl;
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedNode.Tag is BuilderCueNode)
{
BuilderCueNode cueNode = (BuilderCueNode)selectedNode.Tag;
if (!string.IsNullOrEmpty(cueNode.SynthReference))
{
TreeNode treeNode = synthTree.FindNodeByFullPath(cueNode.SynthReference);
synthTree.SelectedNode = treeNode;
treeNode.EnsureVisible();
synthTree.Focus();
}
}
}
}
private void SelectAisacReference(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView)
{
TreeView selectedTree = (TreeView)menuStrip.SourceControl;
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedNode.Tag is BuilderSynthNode)
{
BuilderSynthNode synthNode = (BuilderSynthNode)selectedNode.Tag;
if (!string.IsNullOrEmpty(synthNode.AisacReference))
{
TreeNode treeNode = aisacTree.FindNodeByFullPath(synthNode.AisacReference);
tabControl1.SelectTab(tabPage1);
aisacTree.SelectedNode = treeNode;
treeNode.EnsureVisible();
aisacTree.Focus();
}
}
}
}
private void SelectVoiceLimitGroupReference(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView)
{
TreeView selectedTree = (TreeView)menuStrip.SourceControl;
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedNode.Tag is BuilderSynthNode)
{
BuilderSynthNode synthNode = (BuilderSynthNode)selectedNode.Tag;
if (!string.IsNullOrEmpty(synthNode.VoiceLimitGroupReference))
{
TreeNode treeNode = voiceLimitGroupTree.FindNodeByFullPath(synthNode.VoiceLimitGroupReference);
tabControl1.SelectTab(tabPage2);
voiceLimitGroupTree.SelectedNode = treeNode;
treeNode.EnsureVisible();
voiceLimitGroupTree.Focus();
}
}
}
}
private void SelectSoundElementReference(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView)
{
TreeView selectedTree = (TreeView)menuStrip.SourceControl;
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedNode.Tag is BuilderSynthNode)
{
BuilderSynthNode synthNode = (BuilderSynthNode)selectedNode.Tag;
if (!string.IsNullOrEmpty(synthNode.SoundElementReference))
{
TreeNode treeNode = soundElementTree.FindNodeByFullPath(synthNode.SoundElementReference);
soundElementTree.SelectedNode = treeNode;
treeNode.EnsureVisible();
soundElementTree.Focus();
}
}
}
}
private void SetSoundElementReference(object sender, EventArgs e)
{
if (!CheckIfAny(soundElementTree))
{
MessageBox.Show("This project does not contain any Sound nodes.", "CSB Builder", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
using (SetReferenceForm setReferenceForm = new SetReferenceForm(soundElementTree))
{
if (setReferenceForm.ShowDialog(this) == DialogResult.OK)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView)
{
TreeView selectedTree = (TreeView)menuStrip.SourceControl;
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedNode.Tag is BuilderSynthNode)
{
BuilderSynthNode synthNode = (BuilderSynthNode)selectedNode.Tag;
if (setReferenceForm.SelectedNode == null)
{
synthNode.SoundElementReference = string.Empty;
}
else
{
synthNode.SoundElementReference = setReferenceForm.SelectedNode.FullPath;
}
}
saved = false;
propertyGrid.Refresh();
}
}
}
}
private void SetAudio(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView)
{
TreeView selectedTree = (TreeView)menuStrip.SourceControl;
TreeNode selectedNode = selectedTree.SelectedNode;
BuilderSoundElementNode soundElementNode = (BuilderSoundElementNode)selectedNode.Tag;
if (selectedNode.Tag is BuilderSoundElementNode)
{
string intro = soundElementNode.Intro;
if (!string.IsNullOrEmpty(intro))
{
intro = Path.Combine(project.AudioDirectory.FullName, intro);
}
string loop = soundElementNode.Loop;
if (!string.IsNullOrEmpty(loop))
{
loop = Path.Combine(project.AudioDirectory.FullName, loop);
}
using (SetAudioForm setAudioForm = new SetAudioForm(intro, loop))
{
if (setAudioForm.ShowDialog(this) == DialogResult.OK)
{
uint sampleRate = soundElementNode.SampleRate;
byte channelCount = soundElementNode.ChannelCount;
uint introSampleCount = 0;
soundElementNode.Intro = project.AddAudio(setAudioForm.Intro);
if (!string.IsNullOrEmpty(setAudioForm.Intro))
{
ReadAdx(setAudioForm.Intro, out sampleRate, out channelCount, out introSampleCount);
}
uint loopSampleCount = 0;
soundElementNode.Loop = project.AddAudio(setAudioForm.Loop);
if (!string.IsNullOrEmpty(setAudioForm.Loop))
{
ReadAdx(setAudioForm.Loop, out sampleRate, out channelCount, out loopSampleCount);
}
soundElementNode.SampleRate = sampleRate;
soundElementNode.ChannelCount = channelCount;
soundElementNode.SampleCount = introSampleCount + loopSampleCount;
propertyGrid.Refresh();
}
}
}
}
}
public void ReadAdx(string path, out uint sampleRate, out byte channelCount, out uint sampleCount)
{
AdxHeader header = AdxConverter.LoadHeader(path);
sampleRate = header.SampleRate;
channelCount = header.ChannelCount;
sampleCount = header.SampleCount;
}
private void CreateChildSoundNode(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView)
{
TreeView selectedTree = (TreeView)menuStrip.SourceControl;
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedNode.Tag == null)
{
CreateSoundNode(selectedNode.Nodes, selectedNode);
}
}
}
private void CreateSound(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView)
{
TreeView selectedTree = (TreeView)menuStrip.SourceControl;
CreateSoundNode(selectedTree.Nodes, null);
}
}
private int GetByteCountFromMiliseconds(int miliseconds, int sampleRate, int channelCount, int bitsPerSample)
{
return (int)(miliseconds * sampleRate / 1000.0) * channelCount * bitsPerSample / 8;
}
private void AddSoundElementSound(BuilderSoundElementNode soundElementNode, double volume, double pitch, int sampleCount, int delayTime)
{
BufferedWaveProvider provider = null;
int delayInBytes = 0;
if (!string.IsNullOrEmpty(soundElementNode.Intro))
{
provider = AdxConverter.Decode(project.GetFullAudioPath(soundElementNode.Intro), volume, pitch);
if (delayTime != 0)
{
delayInBytes = GetByteCountFromMiliseconds(delayTime, provider.WaveFormat.SampleRate, provider.WaveFormat.Channels, provider.WaveFormat.BitsPerSample);
byte[] buffer = new byte[provider.BufferLength];
provider.Read(buffer, 0, buffer.Length);
provider = new BufferedWaveProvider(provider.WaveFormat);
provider.BufferLength = delayInBytes + buffer.Length;
provider.ReadFully = false;
provider.AddSamples(new byte[delayInBytes], 0, delayInBytes);
provider.AddSamples(buffer, 0, buffer.Length);
}
}
// If there's ANYTHING that can loop audio files in NAudio... please, tell me!
if (!string.IsNullOrEmpty(soundElementNode.Loop))
{
BufferedWaveProvider loopProvider = AdxConverter.Decode(project.GetFullAudioPath(soundElementNode.Loop), volume, pitch);
if (provider == null && delayTime != 0)
{
delayInBytes = GetByteCountFromMiliseconds(delayTime, loopProvider.WaveFormat.SampleRate, loopProvider.WaveFormat.Channels, loopProvider.WaveFormat.BitsPerSample);
}
int writtenByteCount = 0;
byte[] intro = null;
byte[] loop = new byte[loopProvider.BufferLength];
loopProvider.Read(loop, 0, loop.Length);
if (provider != null)
{
intro = new byte[provider.BufferLength];
provider.Read(intro, 0, intro.Length);
}
provider = new BufferedWaveProvider(loopProvider.WaveFormat);
provider.BufferLength = 0;
if (sampleCount != -1)
{
provider.BufferLength = delayInBytes + (sampleCount * provider.WaveFormat.Channels * provider.WaveFormat.BitsPerSample / 8);
}
else
{
if (intro != null)
{
provider.BufferLength += intro.Length;
}
provider.BufferLength += loop.Length;
}
provider.ReadFully = false;
if (intro != null)
{
provider.AddSamples(intro, 0, intro.Length);
writtenByteCount += intro.Length;
}
else if (intro == null && delayTime != 0)
{
provider.BufferLength += delayInBytes;
provider.AddSamples(new byte[delayInBytes], 0, delayInBytes);
writtenByteCount += delayInBytes;
}
if (sampleCount != -1)
{
while (writtenByteCount < provider.BufferLength)
{
if ((writtenByteCount + loop.Length) > provider.BufferLength)
{
provider.AddSamples(loop, 0, provider.BufferLength - writtenByteCount);
break;
}
writtenByteCount += loop.Length;
provider.AddSamples(loop, 0, loop.Length);
}
}
else
{
provider.AddSamples(loop, 0, loop.Length);
}
}
if (provider != null)
{
WaveOut sound = new WaveOut();
sound.Init(provider);
sounds.Add(sound);
}
}
private void AddSoundElementSound(TreeNode soundElementTreeNode, double volume, double pitch, int sampleCount, int delayTime)
{
BuilderSoundElementNode soundElementNode = (BuilderSoundElementNode)soundElementTreeNode.Tag;
AddSoundElementSound(soundElementNode, volume, pitch, sampleCount, delayTime);
}
private double GetSecondsFromSampleCount(int sampleCount, int sampleRate)
{
return sampleCount / (double)sampleRate;
}
private void GetTheBiggestSampleCount(TreeNode synthTreeNode, ref int sampleCount)
{
if (synthTreeNode.Tag is BuilderSynthNode)
{
BuilderSynthNode synthNode = (BuilderSynthNode)synthTreeNode.Tag;
if (synthNode.Type == BuilderSynthType.Single && !string.IsNullOrEmpty(synthNode.SoundElementReference))
{
BuilderSoundElementNode soundElementNode = (BuilderSoundElementNode)soundElementTree.FindNodeByFullPath(synthNode.SoundElementReference).Tag;
// We want the loop to be at least 10 seconds
int soundElementSampleCount = (int)soundElementNode.SampleCount;
while (GetSecondsFromSampleCount(soundElementSampleCount, (int)soundElementNode.SampleRate) < 10.0)
{
soundElementSampleCount *= 2;
}
if (soundElementSampleCount > sampleCount)
{
sampleCount = soundElementSampleCount;
}
}
}
foreach (TreeNode childNode in synthTreeNode.Nodes)
{
GetTheBiggestSampleCount(childNode, ref sampleCount);
}
}
private double GetAbsolutePitch(TreeNode synthTreeNode)
{
double pitch = 0;
while (synthTreeNode != null)
{
if (synthTreeNode.Tag is BuilderSynthNode)
{
BuilderSynthNode synthNode = (BuilderSynthNode)synthTreeNode.Tag;
pitch += synthNode.Pitch;
}
synthTreeNode = synthTreeNode.Parent;
}
return pitch / 1000.0;
}
private double GetAbsoluteVolume(TreeNode synthTreeNode)
{
double volume = 1000;
while (synthTreeNode != null)
{
if (synthTreeNode.Tag is BuilderSynthNode)
{
BuilderSynthNode synthNode = (BuilderSynthNode)synthTreeNode.Tag;
volume = (volume * synthNode.Volume) / 1000;
}
synthTreeNode = synthTreeNode.Parent;
}
return volume / 1000.0;
}
private int GetAbsoluteDelayTime(TreeNode synthTreeNode)
{
int delayTime = 0;
while (synthTreeNode != null)
{
if (synthTreeNode.Tag is BuilderSynthNode)
{
BuilderSynthNode synthNode = (BuilderSynthNode)synthTreeNode.Tag;
delayTime += (int)synthNode.DelayTime;
}
synthTreeNode = synthTreeNode.Parent;
}
return delayTime;
}
private void AddSynthSound(TreeNode synthTreeNode, int sampleCount)
{
BuilderSynthNode synthNode = (BuilderSynthNode)synthTreeNode.Tag;
if (synthNode.Type == BuilderSynthType.WithChildren)
{
if (synthNode.PlaybackType == BuilderSynthPlaybackType.RandomNoRepeat || synthNode.PlaybackType == BuilderSynthPlaybackType.Random)
{
TreeNode childNode = synthTreeNode.Nodes[synthNode.RandomChildNode];
BuilderSynthNode childSynthNode = (BuilderSynthNode)childNode.Tag;
if (childSynthNode.Type == BuilderSynthType.Single && !string.IsNullOrEmpty(childSynthNode.SoundElementReference) && childSynthNode.PlayThisTurn)
{
AddSoundElementSound(soundElementTree.FindNodeByFullPath(childSynthNode.SoundElementReference), GetAbsoluteVolume(childNode), GetAbsolutePitch(childNode), sampleCount, GetAbsoluteDelayTime(childNode));
}
else if (childSynthNode.Type == BuilderSynthType.WithChildren)
{
AddSynthSound(childNode, sampleCount);
}
}
else if (synthNode.PlaybackType == BuilderSynthPlaybackType.Sequential)
{
TreeNode childNode = synthTreeNode.Nodes[synthNode.NextChildNode];
BuilderSynthNode childSynthNode = (BuilderSynthNode)childNode.Tag;
if (childSynthNode.Type == BuilderSynthType.Single && !string.IsNullOrEmpty(childSynthNode.SoundElementReference) && childSynthNode.PlayThisTurn)
{
AddSoundElementSound(soundElementTree.FindNodeByFullPath(childSynthNode.SoundElementReference), GetAbsoluteVolume(childNode), GetAbsolutePitch(childNode), sampleCount, GetAbsoluteDelayTime(childNode));
}
else if (childSynthNode.Type == BuilderSynthType.WithChildren)
{
AddSynthSound(childNode, sampleCount);
}
}
else
{
foreach (TreeNode childNode in synthTreeNode.Nodes)
{
BuilderSynthNode childSynthNode = (BuilderSynthNode)childNode.Tag;
if (childSynthNode.Type == BuilderSynthType.Single && !string.IsNullOrEmpty(childSynthNode.SoundElementReference) && childSynthNode.PlayThisTurn)
{
AddSoundElementSound(soundElementTree.FindNodeByFullPath(childSynthNode.SoundElementReference), GetAbsoluteVolume(childNode), GetAbsolutePitch(childNode), sampleCount, GetAbsoluteDelayTime(childNode));
}
else if (childSynthNode.Type == BuilderSynthType.WithChildren)
{
AddSynthSound(childNode, sampleCount);
}
}
}
}
else if (synthNode.Type == BuilderSynthType.Single)
{
if (!string.IsNullOrEmpty(synthNode.SoundElementReference) && synthNode.PlayThisTurn)
{
AddSoundElementSound(soundElementTree.FindNodeByFullPath(synthNode.SoundElementReference), synthNode.Volume / 1000.0, synthNode.Pitch / 1000.0, GetTheBiggestSampleCount(synthTreeNode), (int)synthNode.DelayTime);
}
}
}
private int GetTheBiggestSampleCount(TreeNode synthNode)
{
int sampleCount = -1;
GetTheBiggestSampleCount(synthNode, ref sampleCount);
return sampleCount;
}
private void PlaySound(object sender, EventArgs e)
{
StopSound(sender, e);
if (cueTree.Focused && cueTree.SelectedNode != null && cueTree.SelectedNode.Tag is BuilderCueNode)
{
BuilderCueNode cueNode = (BuilderCueNode)cueTree.SelectedNode.Tag;
if (!string.IsNullOrEmpty(cueNode.SynthReference))
{
TreeNode synthNode = synthTree.FindNodeByFullPath(cueNode.SynthReference);
AddSynthSound(synthNode, GetTheBiggestSampleCount(synthNode));
}
}
else if (soundElementTree.Focused && soundElementTree.SelectedNode != null && soundElementTree.SelectedNode.Tag is BuilderSoundElementNode)
{
AddSoundElementSound(soundElementTree.SelectedNode, 1, 0, -1, 0);
}
else if (synthTree.Focused && synthTree.SelectedNode != null && synthTree.SelectedNode.Tag is BuilderSynthNode)
{
AddSynthSound(synthTree.SelectedNode, GetTheBiggestSampleCount(synthTree.SelectedNode));
}
sounds.ForEach(sound => sound.Play());
}
private void StopSound(object sender, EventArgs e)
{
sounds.ForEach(sound =>
{
sound.Stop();
sound.Dispose();
});
sounds.Clear();
}
private TreeNode CloneNode(TreeNode treeNode)
{
TreeNode clonedNode = (TreeNode)treeNode.Clone();
CloneTag(clonedNode);
return clonedNode;
}
private void CloneTag(TreeNode treeNode)
{
if (treeNode.Tag != null && treeNode.Tag is ICloneable)
{
treeNode.Tag = ((ICloneable)treeNode.Tag).Clone();
}
foreach (TreeNode childNode in treeNode.Nodes)
{
CloneTag(childNode);
}
}
private void CopyNode(TreeNode treeNode)
{
treeViewOfCopiedNode = treeNode.TreeView;
copiedNode = CloneNode(treeNode);
}
private void CopyNode(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView)
{
TreeView selectedTree = (TreeView)menuStrip.SourceControl;
TreeNode selectedNode = selectedTree.SelectedNode;
CopyNode(selectedNode);
}
}
private void AddToProject(TreeNode treeNode)
{
if (treeNode.Tag is BuilderCueNode)
{
BuilderCueNode cueNode = (BuilderCueNode)treeNode.Tag;
// Do checks
if (!string.IsNullOrEmpty(cueNode.SynthReference) && synthTree.FindNodeByFullPath(cueNode.SynthReference) == null)
{
cueNode.SynthReference = string.Empty;
}
project.CueNodes.Add(cueNode);
}
else if (treeNode.Tag is BuilderSynthNode)
{
BuilderSynthNode synthNode = (BuilderSynthNode)treeNode.Tag;
if (!string.IsNullOrEmpty(synthNode.SoundElementReference) && soundElementTree.FindNodeByFullPath(synthNode.SoundElementReference) == null)
{
synthNode.SoundElementReference = string.Empty;
}
if (!string.IsNullOrEmpty(synthNode.AisacReference) && aisacTree.FindNodeByFullPath(synthNode.AisacReference) == null)
{
synthNode.AisacReference = string.Empty;
}
if (!string.IsNullOrEmpty(synthNode.VoiceLimitGroupReference) && !voiceLimitGroupTree.Nodes.ContainsKey(synthNode.VoiceLimitGroupReference))
{
synthNode.VoiceLimitGroupReference = string.Empty;
}
project.SynthNodes.Add(synthNode);
}
if (treeNode.Tag is BuilderSoundElementNode)
{
BuilderSoundElementNode soundElementNode = (BuilderSoundElementNode)treeNode.Tag;
if (!string.IsNullOrEmpty(soundElementNode.Intro) && !File.Exists(project.GetFullAudioPath(soundElementNode.Intro)))
{
soundElementNode.Intro = string.Empty;
}
if (!string.IsNullOrEmpty(soundElementNode.Loop) && !File.Exists(project.GetFullAudioPath(soundElementNode.Loop)))
{
soundElementNode.Loop = string.Empty;
}
project.SoundElementNodes.Add(soundElementNode);
}
if (treeNode.Tag is BuilderAisacNode)
{
project.AisacNodes.Add((BuilderAisacNode)treeNode.Tag);
}
if (treeNode.Tag is BuilderVoiceLimitGroupNode)
{
project.VoiceLimitGroupNodes.Add((BuilderVoiceLimitGroupNode)treeNode.Tag);
}
}
private void PasteAsChildNode(TreeNode parent, int nodeIndex = -1)
{
saved = false;
TreeNode nodeToPaste = CloneNode(copiedNode);
// Look for any duplicates
int index = -1;
string name = nodeToPaste.Name;
while (parent.Nodes.ContainsKey(nodeToPaste.Name))
{
nodeToPaste.Name = $"{name}_Copy{++index}";
}
nodeToPaste.Text = nodeToPaste.Name;
// paste it now
if (nodeIndex == -1)
{
parent.Nodes.Add(nodeToPaste);
}
else
{
parent.Nodes.Insert(nodeIndex, nodeToPaste);
}
// Update the CSB node and its children (will prevent some issues)
UpdateNodeNoRename(nodeToPaste);
// fix node if the tree is synthTree, and the nodes are synth nodes
if (parent.TreeView == synthTree && parent.Tag is BuilderSynthNode && nodeToPaste.Tag is BuilderSynthNode)
{
BuilderSynthNode synthNode = (BuilderSynthNode)parent.Tag;
BuilderSynthNode copiedSynthNode = (BuilderSynthNode)nodeToPaste.Tag;
if (synthNode.Type == BuilderSynthType.WithChildren)
{
// add the new node to track's children
synthNode.Children.Add(copiedSynthNode.Name);
}
}
AddToProject(nodeToPaste);
nodeToPaste.TreeView.SelectedNode = nodeToPaste;
nodeToPaste.EnsureVisible();
}
private void PasteNode(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView)
{
TreeView selectedTree = (TreeView)menuStrip.SourceControl;
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedTree == treeViewOfCopiedNode)
{
// Parent is a CSB node but the copied object is a folder? abort.
if (selectedNode.Tag != null && copiedNode.Tag == null)
{
return;
}
PasteAsChildNode(selectedNode);
}
}
}
private void PasteNode(int nodeIndex = -1)
{
saved = false;
TreeNode nodeToPaste = CloneNode(copiedNode);
// check if it's cue and fix duplicate identifier if needed
if (nodeToPaste.Tag is BuilderCueNode)
{
BuilderCueNode cueNode = (BuilderCueNode)nodeToPaste.Tag;
while (project.CueNodes.Exists(cue => cue.Identifier == cueNode.Identifier))
{
cueNode.Identifier++;
}
}
// paste
if (treeViewOfCopiedNode.SelectedNode != null && treeViewOfCopiedNode.SelectedNode.Parent != null)
{
// Look for any duplicates
int index = -1;
string name = nodeToPaste.Name;
while (treeViewOfCopiedNode.SelectedNode.Parent.Nodes.ContainsKey(nodeToPaste.Name))
{
nodeToPaste.Name = $"{name}_Copy{++index}";
}
nodeToPaste.Text = nodeToPaste.Name;
if (nodeIndex == -1)
{
treeViewOfCopiedNode.SelectedNode.Parent.Nodes.Add(nodeToPaste);
}
else
{
treeViewOfCopiedNode.SelectedNode.Parent.Nodes.Insert(nodeIndex, nodeToPaste);
}
}
else
{
// Look for any duplicates
int index = -1;
string name = nodeToPaste.Name;
while (treeViewOfCopiedNode.Nodes.ContainsKey(nodeToPaste.Name))
{
nodeToPaste.Name = $"{name}_Copy{++index}";
}
nodeToPaste.Text = nodeToPaste.Name;
if (nodeIndex == -1)
{
treeViewOfCopiedNode.Nodes.Add(nodeToPaste);
}
else
{
treeViewOfCopiedNode.Nodes.Insert(nodeIndex, nodeToPaste);
}
}
// update the CSB node and its children
UpdateNodeNoRename(nodeToPaste);
AddToProject(nodeToPaste);
nodeToPaste.TreeView.SelectedNode = nodeToPaste;
nodeToPaste.EnsureVisible();
}
private void PasteNodeOnTree(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView)
{
TreeView selectedTree = (TreeView)menuStrip.SourceControl;
if (selectedTree == treeViewOfCopiedNode)
{
PasteNode();
}
}
}
private void PasteAndInsertNode(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView)
{
TreeView selectedTree = (TreeView)menuStrip.SourceControl;
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedTree == treeViewOfCopiedNode)
{
PasteNode(selectedNode.Index + 1);
}
}
}
private void ShowAbout(object sender, EventArgs e)
{
MessageBox.Show($"{Program.ApplicationVersion} by Skyth (blueskythlikesclouds)", "CSB Builder");
}
private void CreateChildTrackNode(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView)
{
TreeView selectedTree = (TreeView)menuStrip.SourceControl;
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedTree == synthTree)
{
CreateSynthNode(selectedNode.Nodes, selectedNode);
}
}
}
private void CreateAndInsertNode(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView)
{
TreeView selectedTree = (TreeView)menuStrip.SourceControl;
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedTree == cueTree)
{
CreateCueNode(selectedTree.Nodes, null, selectedNode.Index + 1);
}
else if (selectedTree == synthTree)
{
if (selectedNode.Tag is BuilderSynthNode && ((BuilderSynthNode)selectedNode.Tag).Type == BuilderSynthType.WithChildren)
{
CreateSoundNode(selectedNode.Nodes, selectedNode, selectedNode.Index + 1);
}
else
{
CreateSynthNode(selectedNode.Nodes, selectedNode, selectedNode.Index + 1);
}
}
else if (selectedTree == soundElementTree)
{
CreateSoundElementNode(selectedNode.Parent != null ? selectedNode.Parent.Nodes : selectedTree.Nodes, selectedNode, selectedNode.Index + 1);
}
else if (selectedTree == aisacTree)
{
CreateAisacNode(selectedNode.Nodes, selectedNode, selectedNode.Index + 1);
}
else if (selectedTree == voiceLimitGroupTree)
{
CreateVoiceLimitGroupNode(selectedTree.Nodes, null, selectedNode.Index + 1);
}
}
}
private void CreateAndInsertSoundNode(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView)
{
TreeView selectedTree = (TreeView)menuStrip.SourceControl;
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedNode.Tag is BuilderSynthNode)
{
if (selectedNode.Parent == null)
{
CreateSoundNode(synthTree.Nodes, null, selectedNode.Index + 1);
}
else
{
CreateSoundNode(selectedNode.Parent.Nodes, selectedNode.Parent, selectedNode.Index + 1);
}
}
}
}
private void LoadTemplate(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView)
{
TreeView selectedTree = (TreeView)menuStrip.SourceControl;
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedTree == aisacTree)
{
using (OpenFileDialog openAisacTemplate = new OpenFileDialog()
{
Title = "Load AISAC Template",
Filter = "XML Files|*.xml",
DefaultExt = "xml",
FileName = selectedNode != null ? selectedNode.Name : string.Empty,
})
{
if (openAisacTemplate.ShowDialog() == DialogResult.OK)
{
XmlSerializer aisacSerializer = new XmlSerializer(typeof(BuilderAisacNode));
try
{
using (Stream source = File.OpenRead(openAisacTemplate.FileName))
{
BuilderAisacNode aisacNode = (BuilderAisacNode)aisacSerializer.Deserialize(source);
TreeNode aisacTreeNode = null;
// folder
if (selectedNode != null && selectedNode.Tag == null)
{
aisacTreeNode = CreateAisacNode(selectedNode.Nodes, selectedNode, -1, aisacNode);
}
// aisac
else if (selectedNode != null && selectedNode.Tag is BuilderAisacNode)
{
project.AisacNodes[project.AisacNodes.IndexOf((BuilderAisacNode)selectedNode.Tag)] = aisacNode;
aisacNode.Name = selectedNode.FullPath;
selectedNode.Tag = aisacNode;
selectedTree.SelectedNode = selectedNode;
}
// nothing, create a new aisac
else if (selectedNode == null)
{
aisacTreeNode = CreateAisacNode(aisacTree.Nodes, null, -1, aisacNode);
}
// fix the current aisac if it was imported
if (aisacTreeNode != null)
{
if (!string.IsNullOrEmpty(aisacNode.Name))
{
// duplicate? fix it really quick
string name = Path.GetFileName(aisacNode.Name);
string uniqueName = name;
TreeNodeCollection collection = aisacTreeNode.Parent != null ? aisacTreeNode.Parent.Nodes : aisacTree.Nodes;
int index = -1;
while (collection.ContainsKey(uniqueName))
{
uniqueName = $"{name}_{++index}";
}
aisacTreeNode.Name = uniqueName;
aisacTreeNode.Text = aisacTreeNode.Name;
}
aisacNode.Name = aisacTreeNode.FullPath;
aisacTreeNode.Tag = aisacNode;
selectedTree.SelectedNode = aisacTreeNode;
aisacTreeNode.EnsureVisible();
}
}
}
catch
{
MessageBox.Show("The template file is invalid.", "CSB Builder", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
}
}
private void SaveTemplate(object sender, EventArgs e)
{
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
if (menuStrip.SourceControl is TreeView)
{
TreeView selectedTree = (TreeView)menuStrip.SourceControl;
TreeNode selectedNode = selectedTree.SelectedNode;
if (selectedTree == aisacTree)
{
using (SaveFileDialog saveAisacTemplate = new SaveFileDialog()
{
Title = "Save AISAC Template",
Filter = "XML Files|*.xml",
DefaultExt = "xml",
FileName = selectedNode.Name,
})
{
if (saveAisacTemplate.ShowDialog() == DialogResult.OK)
{
if (selectedNode.Tag is BuilderAisacNode)
{
XmlSerializer aisacSerializer = new XmlSerializer(typeof(BuilderAisacNode));
using (Stream destination = File.Create(saveAisacTemplate.FileName))
{
aisacSerializer.Serialize(destination, selectedNode.Tag);
}
}
}
}
}
}
}
}
}