2017-01-26 23:40:46 +03:00
|
|
|
|
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;
|
2017-06-21 01:19:47 +03:00
|
|
|
|
using System.Runtime.InteropServices;
|
2017-01-26 23:40:46 +03:00
|
|
|
|
|
|
|
|
|
using CsbBuilder.Builder;
|
2017-06-21 01:19:47 +03:00
|
|
|
|
using CsbBuilder.BuilderNodes;
|
2017-01-26 23:40:46 +03:00
|
|
|
|
using CsbBuilder.Audio;
|
|
|
|
|
using CsbBuilder.Importer;
|
|
|
|
|
using CsbBuilder.Project;
|
|
|
|
|
using CsbBuilder.Serialization;
|
|
|
|
|
using CsbBuilder.Properties;
|
|
|
|
|
|
|
|
|
|
using SonicAudioLib.IO;
|
2017-06-21 01:19:47 +03:00
|
|
|
|
using SonicAudioLib.Archives;
|
2017-01-26 23:40:46 +03:00
|
|
|
|
|
|
|
|
|
using NAudio.Wave;
|
|
|
|
|
|
|
|
|
|
namespace CsbBuilder
|
|
|
|
|
{
|
|
|
|
|
public partial class MainForm : Form
|
|
|
|
|
{
|
2017-04-17 19:06:29 +03:00
|
|
|
|
public static Settings Settings;
|
|
|
|
|
|
2017-01-26 23:40:46 +03:00
|
|
|
|
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>();
|
|
|
|
|
|
2017-06-21 01:19:47 +03:00
|
|
|
|
private string filters = null;
|
|
|
|
|
|
|
|
|
|
private string Filters
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrEmpty(filters))
|
|
|
|
|
{
|
|
|
|
|
var culture = Thread.CurrentThread.CurrentUICulture;
|
|
|
|
|
|
|
|
|
|
var formats = VGMStreamNative.GetFormats().OrderBy(format => format);
|
|
|
|
|
var formatFilter = formats.Select(format => $"{format.ToUpper(culture)} Files|*.{format}");
|
|
|
|
|
filters = $"All Formats|{string.Join(";", formats.Select(format => $"*.{format}"))}|{string.Join("|", formatFilter)}";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return filters;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-26 23:40:46 +03:00
|
|
|
|
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);
|
2017-04-17 19:06:29 +03:00
|
|
|
|
|
|
|
|
|
Settings = Settings.Load();
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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();
|
2017-04-23 19:22:25 +03:00
|
|
|
|
Text = Program.ApplicationTitle;
|
2017-01-26 23:40:46 +03:00
|
|
|
|
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;
|
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
string parentName = parent != null && Settings.NameNodeAfterParent ? parent.Name : "Cue";
|
|
|
|
|
while (collection.ContainsKey($"{parentName}_{index}"))
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
index++;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
TreeNode treeNode = nodeIndex == -1 ? collection.Add($"{parentName}_{index}") : collection.Insert(nodeIndex, $"{parentName}_{index}");
|
2017-01-26 23:40:46 +03:00
|
|
|
|
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)
|
|
|
|
|
{
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (node is BuilderCueNode cueNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
2017-03-09 20:48:17 +03:00
|
|
|
|
project.CueNodes.Remove(cueNode);
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
else if (node is BuilderSynthNode synthNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
else if (node is BuilderSoundElementNode soundElementNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
project.SoundElementNodes.Remove(soundElementNode);
|
|
|
|
|
|
|
|
|
|
project.SynthNodes.Where(soundElement => soundElement.SoundElementReference == soundElementNode.Name).ToList().ForEach(synth => synth.SoundElementReference = string.Empty);
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
else if (node is BuilderAisacNode aisacNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
project.AisacNodes.Remove(aisacNode);
|
|
|
|
|
|
|
|
|
|
project.SynthNodes.Where(synth => synth.AisacReference == aisacNode.Name).ToList().ForEach(synth => synth.AisacReference = string.Empty);
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
else if (node is BuilderVoiceLimitGroupNode voiceLimitGroupNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
string parentName = parent != null && Settings.NameNodeAfterParent ? parent.Name : "Synth";
|
|
|
|
|
while (collection.ContainsKey($"{parentName}_{index}"))
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
index++;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
TreeNode treeNode = nodeIndex == -1 ? collection.Add($"{parentName}_{index}") : collection.Insert(nodeIndex, $"{parentName}_{index}");
|
2017-01-26 23:40:46 +03:00
|
|
|
|
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);
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (parent != null && parent.Tag is BuilderSynthNode parentSynthNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
string parentName = parent != null && Settings.NameNodeAfterParent ? parent.Name : "Sound";
|
|
|
|
|
while (collection.ContainsKey($"{parentName}_{index}"))
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
index++;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
TreeNode treeNode = nodeIndex == -1 ? collection.Add($"{parentName}_{index}") : collection.Insert(nodeIndex, $"{parentName}_{index}");
|
2017-01-26 23:40:46 +03:00
|
|
|
|
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);
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (parent != null && parent.Tag is BuilderSynthNode parentSynthNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
string parentName = parent != null && Settings.NameNodeAfterParent ? parent.Name : "SoundElement";
|
|
|
|
|
while (collection.ContainsKey($"{parentName}_{index}"))
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
index++;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
TreeNode treeNode = nodeIndex == -1 ? collection.Add($"{parentName}_{index}") : collection.Insert(nodeIndex, $"{parentName}_{index}");
|
2017-01-26 23:40:46 +03:00
|
|
|
|
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;
|
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
string parentName = parent != null && Settings.NameNodeAfterParent ? parent.Name : "AISAC";
|
|
|
|
|
while (collection.ContainsKey($"{parentName}_{index}"))
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
index++;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
TreeNode treeNode = nodeIndex == -1 ? collection.Add($"{parentName}_{index}") : collection.Insert(nodeIndex, $"{parentName}_{index}");
|
2017-01-26 23:40:46 +03:00
|
|
|
|
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;
|
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
string parentName = parent != null && Settings.NameNodeAfterParent ? parent.Name : "VoiceLimitGroup";
|
|
|
|
|
while (collection.ContainsKey($"{parentName}_{index}"))
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
index++;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
TreeNode treeNode = nodeIndex == -1 ? collection.Add($"{parentName}_{index}") : collection.Insert(nodeIndex, $"{parentName}_{index}");
|
2017-01-26 23:40:46 +03:00
|
|
|
|
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;
|
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
string parentName = parent != null && Settings.NameNodeAfterParent ? parent.Name : "Folder";
|
2017-01-26 23:40:46 +03:00
|
|
|
|
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;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (menuStrip.SourceControl is TreeView selectedTree)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
TreeNode selectedNode = selectedTree.SelectedNode;
|
|
|
|
|
|
|
|
|
|
if (selectedTree == cueTree)
|
|
|
|
|
{
|
|
|
|
|
CreateCueNode(selectedTree.Nodes, null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else if (selectedTree == synthTree)
|
|
|
|
|
{
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (selectedNode.Tag is BuilderSynthNode synthNode && synthNode.Type == BuilderSynthType.WithChildren)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (menuStrip.SourceControl is TreeView selectedTree)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (menuStrip.SourceControl is TreeView selectedTree)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
if (selectedTree == synthTree)
|
|
|
|
|
{
|
|
|
|
|
CreateSynthFolder(selectedTree.Nodes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
CreateFolder(selectedTree.Nodes, null);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void RemoveNodes(TreeNodeCollection collection)
|
|
|
|
|
{
|
|
|
|
|
foreach (TreeNode node in collection)
|
|
|
|
|
{
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (node.Tag is BuilderBaseNode baseNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
2017-03-09 20:48:17 +03:00
|
|
|
|
RemoveNode(baseNode);
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RemoveNodes(node.Nodes);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void RemoveNode(TreeNode treeNode)
|
|
|
|
|
{
|
|
|
|
|
saved = false;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (treeNode.Tag is BuilderBaseNode baseNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
2017-03-09 20:48:17 +03:00
|
|
|
|
RemoveNode(baseNode);
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RemoveNodes(treeNode.Nodes);
|
|
|
|
|
treeNode.Remove();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void RemoveNode(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
saved = false;
|
|
|
|
|
|
|
|
|
|
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (menuStrip.SourceControl is TreeView selectedTree)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (menuStrip.SourceControl is TreeView selectedTree)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
TreeNode selectedNode = selectedTree.SelectedNode;
|
|
|
|
|
|
|
|
|
|
Clipboard.SetText(selectedNode.FullPath);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CreateChildFolder(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (menuStrip.SourceControl is TreeView selectedTree)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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)
|
|
|
|
|
{
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (treeNode.Tag is BuilderBaseNode baseNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
baseNode.Name = treeNode.FullPath;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (TreeNode childNode in treeNode.Nodes)
|
|
|
|
|
{
|
|
|
|
|
UpdateNodeNoRename(childNode);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void UpdateNodes(TreeNodeCollection collection)
|
|
|
|
|
{
|
|
|
|
|
foreach (TreeNode treeNode in collection)
|
|
|
|
|
{
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (treeNode.Tag is BuilderBaseNode baseNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
private void RenameNode(TreeNode node, string name)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
2017-04-17 19:06:29 +03:00
|
|
|
|
saved = false;
|
|
|
|
|
string previousName = node.FullPath;
|
|
|
|
|
|
|
|
|
|
// check siblings before rename
|
|
|
|
|
TreeNodeCollection collection = node.Parent != null ? node.Parent.Nodes : node.TreeView.Nodes;
|
|
|
|
|
|
|
|
|
|
if (collection.ContainsKey(name))
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
2017-04-17 19:06:29 +03:00
|
|
|
|
int index = -1;
|
|
|
|
|
string _name = name;
|
|
|
|
|
while (collection.ContainsKey(name))
|
|
|
|
|
{
|
|
|
|
|
name = $"{_name}_{++index}";
|
|
|
|
|
}
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
node.Name = name;
|
|
|
|
|
node.Text = name;
|
2017-01-26 23:40:46 +03:00
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
string fullPath = node.FullPath;
|
2017-01-26 23:40:46 +03:00
|
|
|
|
|
|
|
|
|
UpdateAllNodes();
|
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
if (node.Tag is BuilderSynthNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
else if (node.Tag is BuilderSoundElementNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
project.SynthNodes.Where(synth => synth.SoundElementReference == previousName).ToList().ForEach(synth => synth.SoundElementReference = fullPath);
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
else if (node.Tag is BuilderAisacNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
project.SynthNodes.Where(synth => synth.AisacReference == previousName).ToList().ForEach(synth => synth.AisacReference = fullPath);
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
else if (node.Tag is BuilderVoiceLimitGroupNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
project.SynthNodes.Where(synth => synth.VoiceLimitGroupReference == previousName).ToList().ForEach(synth => synth.VoiceLimitGroupReference = fullPath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
propertyGrid.Refresh();
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
private void OnRenameEnd(object sender, NodeLabelEditEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrEmpty(e.Label) || e.Label == e.Node.Name)
|
|
|
|
|
{
|
|
|
|
|
e.CancelEdit = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RenameNode(e.Node, e.Label);
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-26 23:40:46 +03:00
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
else if (treeView.SelectedNode != null && (treeView.SelectedNode.Tag == null || (treeView.SelectedNode.Tag is BuilderSynthNode synthNode && synthNode.Type == BuilderSynthType.WithChildren)))
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (menuStrip.SourceControl is TreeView selectedTree)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
TreeNode selectedNode = selectedTree.SelectedNode;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (selectedNode.Tag is BuilderSynthNode synthNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (menuStrip.SourceControl is TreeView selectedTree)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
TreeNode selectedNode = selectedTree.SelectedNode;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (selectedNode.Tag is BuilderSynthNode synthNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (menuStrip.SourceControl is TreeView selectedTree)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (menuStrip.SourceControl is TreeView selectedTree)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
TreeNode selectedNode = selectedTree.SelectedNode;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (selectedNode.Tag is BuilderCueNode cueNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (menuStrip.SourceControl is TreeView selectedTree)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
TreeNode selectedNode = selectedTree.SelectedNode;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (selectedNode.Tag is BuilderSynthNode synthNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (menuStrip.SourceControl is TreeView selectedTree)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
TreeNode selectedNode = selectedTree.SelectedNode;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (selectedNode.Tag is BuilderSynthNode synthNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (menuStrip.SourceControl is TreeView selectedTree)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
TreeNode selectedNode = selectedTree.SelectedNode;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (selectedNode.Tag is BuilderSynthNode synthNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (menuStrip.SourceControl is TreeView selectedTree)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
TreeNode selectedNode = selectedTree.SelectedNode;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (selectedNode.Tag is BuilderSynthNode synthNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
if (setReferenceForm.SelectedNode == null)
|
|
|
|
|
{
|
|
|
|
|
synthNode.SoundElementReference = string.Empty;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
synthNode.SoundElementReference = setReferenceForm.SelectedNode.FullPath;
|
2017-04-17 19:06:29 +03:00
|
|
|
|
|
|
|
|
|
if (Settings.RenameToSoundElement)
|
|
|
|
|
{
|
|
|
|
|
RenameNode(selectedNode, setReferenceForm.SelectedNode.Name);
|
|
|
|
|
}
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
saved = false;
|
|
|
|
|
propertyGrid.Refresh();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void SetAudio(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (menuStrip.SourceControl is TreeView selectedTree)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
TreeNode selectedNode = selectedTree.SelectedNode;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (selectedNode.Tag is BuilderSoundElementNode soundElementNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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)
|
|
|
|
|
{
|
2017-06-21 01:19:47 +03:00
|
|
|
|
using (var reader = new VGMStreamReader(path))
|
|
|
|
|
{
|
|
|
|
|
sampleRate = (uint)reader.WaveFormat.SampleRate;
|
|
|
|
|
channelCount = (byte)reader.WaveFormat.Channels;
|
|
|
|
|
sampleCount = (uint)(reader.Length / 2);
|
|
|
|
|
}
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CreateChildSoundNode(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (menuStrip.SourceControl is TreeView selectedTree)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (menuStrip.SourceControl is TreeView selectedTree)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
CreateSoundNode(selectedTree.Nodes, null);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private int GetByteCountFromMiliseconds(int miliseconds, int sampleRate, int channelCount, int bitsPerSample)
|
|
|
|
|
{
|
|
|
|
|
return (int)(miliseconds * sampleRate / 1000.0) * channelCount * bitsPerSample / 8;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-21 01:19:47 +03:00
|
|
|
|
private int GetMilisecondsFromByteCount(int byteCount, int sampleRate, int channelCount, int bitsPerSample)
|
|
|
|
|
{
|
|
|
|
|
return (int)((8000.0 * byteCount) / (sampleRate * channelCount * bitsPerSample));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private WaveStream GetWaveStream(string path)
|
|
|
|
|
{
|
|
|
|
|
if (path.EndsWith(".wav", StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
return new WaveFileReader(project.GetFullAudioPath(path));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new VGMStreamReader(project.GetFullAudioPath(path));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void AddSoundElementSound(BuilderSoundElementNode soundElementNode, double volume, double pitch, int delayTime)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
2017-04-17 19:06:29 +03:00
|
|
|
|
WaveStream waveStream = null;
|
2017-01-26 23:40:46 +03:00
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
if (!string.IsNullOrEmpty(soundElementNode.Intro) && string.IsNullOrEmpty(soundElementNode.Loop))
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
2017-06-21 01:19:47 +03:00
|
|
|
|
var reader = new VGMStreamReader(project.GetFullAudioPath(soundElementNode.Intro));
|
|
|
|
|
reader.DisableLoop();
|
|
|
|
|
|
|
|
|
|
waveStream = new ExtendedWaveStream(reader)
|
|
|
|
|
{
|
|
|
|
|
DelayTime = delayTime,
|
|
|
|
|
Volume = volume,
|
|
|
|
|
Pitch = pitch,
|
|
|
|
|
};
|
2017-04-17 19:06:29 +03:00
|
|
|
|
}
|
2017-01-26 23:40:46 +03:00
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
else if (string.IsNullOrEmpty(soundElementNode.Intro) && !string.IsNullOrEmpty(soundElementNode.Loop))
|
|
|
|
|
{
|
2017-06-21 01:19:47 +03:00
|
|
|
|
var reader = new VGMStreamReader(project.GetFullAudioPath(soundElementNode.Loop));
|
|
|
|
|
reader.ForceLoop();
|
|
|
|
|
|
|
|
|
|
waveStream = new ExtendedWaveStream(reader)
|
|
|
|
|
{
|
|
|
|
|
DelayTime = delayTime,
|
|
|
|
|
Volume = volume,
|
|
|
|
|
Pitch = pitch,
|
|
|
|
|
ForceLoop = true,
|
|
|
|
|
};
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
else if (!string.IsNullOrEmpty(soundElementNode.Intro) && !string.IsNullOrEmpty(soundElementNode.Loop))
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
2017-06-21 01:19:47 +03:00
|
|
|
|
var intro = new VGMStreamReader(project.GetFullAudioPath(soundElementNode.Intro));
|
|
|
|
|
intro.DisableLoop();
|
|
|
|
|
|
|
|
|
|
var loop = new VGMStreamReader(project.GetFullAudioPath(soundElementNode.Loop));
|
|
|
|
|
loop.ForceLoop();
|
|
|
|
|
|
|
|
|
|
waveStream = new ExtendedWaveStream(intro, loop)
|
|
|
|
|
{
|
|
|
|
|
DelayTime = delayTime,
|
|
|
|
|
Volume = volume,
|
|
|
|
|
Pitch = pitch,
|
|
|
|
|
ForceLoop = true,
|
|
|
|
|
};
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
if (waveStream != null)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
2017-06-21 01:19:47 +03:00
|
|
|
|
IWavePlayer wavePlayer = null;
|
|
|
|
|
|
|
|
|
|
switch (Settings.WavePlayer)
|
|
|
|
|
{
|
|
|
|
|
case Settings.NAudioWavePlayer.WaveOut:
|
|
|
|
|
wavePlayer = new WaveOut();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Settings.NAudioWavePlayer.WasapiOut:
|
|
|
|
|
wavePlayer = new WasapiOut();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Settings.NAudioWavePlayer.DirectSoundOut:
|
|
|
|
|
wavePlayer = new DirectSoundOut();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Settings.NAudioWavePlayer.AsioOut:
|
|
|
|
|
wavePlayer = new AsioOut();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wavePlayer.Init(waveStream);
|
|
|
|
|
sounds.Add(wavePlayer);
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-21 01:19:47 +03:00
|
|
|
|
private void AddSoundElementSound(TreeNode soundElementTreeNode, double volume, double pitch, int delayTime)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
2017-06-21 01:19:47 +03:00
|
|
|
|
AddSoundElementSound((BuilderSoundElementNode)soundElementTreeNode.Tag, volume, pitch, delayTime);
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private double GetSecondsFromSampleCount(int sampleCount, int sampleRate)
|
|
|
|
|
{
|
|
|
|
|
return sampleCount / (double)sampleRate;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void GetTheBiggestSampleCount(TreeNode synthTreeNode, ref int sampleCount)
|
|
|
|
|
{
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (synthTreeNode.Tag is BuilderSynthNode synthNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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)
|
|
|
|
|
{
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (synthTreeNode.Tag is BuilderSynthNode synthNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
pitch += synthNode.Pitch;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
synthTreeNode = synthTreeNode.Parent;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-21 01:19:47 +03:00
|
|
|
|
return pitch / 1500.0;
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private double GetAbsoluteVolume(TreeNode synthTreeNode)
|
|
|
|
|
{
|
|
|
|
|
double volume = 1000;
|
|
|
|
|
|
|
|
|
|
while (synthTreeNode != null)
|
|
|
|
|
{
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (synthTreeNode.Tag is BuilderSynthNode synthNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
2017-06-21 01:19:47 +03:00
|
|
|
|
volume = (volume * synthNode.Volume) / 1000.0;
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
synthTreeNode = synthTreeNode.Parent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return volume / 1000.0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private int GetAbsoluteDelayTime(TreeNode synthTreeNode)
|
|
|
|
|
{
|
|
|
|
|
int delayTime = 0;
|
|
|
|
|
|
|
|
|
|
while (synthTreeNode != null)
|
|
|
|
|
{
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (synthTreeNode.Tag is BuilderSynthNode synthNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
delayTime += (int)synthNode.DelayTime;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
synthTreeNode = synthTreeNode.Parent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return delayTime;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-21 01:19:47 +03:00
|
|
|
|
private void AddSynthSound(TreeNode synthTreeNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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)
|
|
|
|
|
{
|
2017-06-21 01:19:47 +03:00
|
|
|
|
AddSoundElementSound(soundElementTree.FindNodeByFullPath(childSynthNode.SoundElementReference), GetAbsoluteVolume(childNode), GetAbsolutePitch(childNode), GetAbsoluteDelayTime(childNode));
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else if (childSynthNode.Type == BuilderSynthType.WithChildren)
|
|
|
|
|
{
|
2017-06-21 01:19:47 +03:00
|
|
|
|
AddSynthSound(childNode);
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
2017-06-21 01:19:47 +03:00
|
|
|
|
AddSoundElementSound(soundElementTree.FindNodeByFullPath(childSynthNode.SoundElementReference), GetAbsoluteVolume(childNode), GetAbsolutePitch(childNode), GetAbsoluteDelayTime(childNode));
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else if (childSynthNode.Type == BuilderSynthType.WithChildren)
|
|
|
|
|
{
|
2017-06-21 01:19:47 +03:00
|
|
|
|
AddSynthSound(childNode);
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
foreach (TreeNode childNode in synthTreeNode.Nodes)
|
|
|
|
|
{
|
|
|
|
|
BuilderSynthNode childSynthNode = (BuilderSynthNode)childNode.Tag;
|
|
|
|
|
|
|
|
|
|
if (childSynthNode.Type == BuilderSynthType.Single && !string.IsNullOrEmpty(childSynthNode.SoundElementReference) && childSynthNode.PlayThisTurn)
|
|
|
|
|
{
|
2017-06-21 01:19:47 +03:00
|
|
|
|
AddSoundElementSound(soundElementTree.FindNodeByFullPath(childSynthNode.SoundElementReference), GetAbsoluteVolume(childNode), GetAbsolutePitch(childNode), GetAbsoluteDelayTime(childNode));
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else if (childSynthNode.Type == BuilderSynthType.WithChildren)
|
|
|
|
|
{
|
2017-06-21 01:19:47 +03:00
|
|
|
|
AddSynthSound(childNode);
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else if (synthNode.Type == BuilderSynthType.Single)
|
|
|
|
|
{
|
|
|
|
|
if (!string.IsNullOrEmpty(synthNode.SoundElementReference) && synthNode.PlayThisTurn)
|
|
|
|
|
{
|
2017-06-21 01:19:47 +03:00
|
|
|
|
AddSoundElementSound(soundElementTree.FindNodeByFullPath(synthNode.SoundElementReference), synthNode.Volume / 1000.0, synthNode.Pitch / 1500.0, (int)synthNode.DelayTime);
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private int GetTheBiggestSampleCount(TreeNode synthNode)
|
|
|
|
|
{
|
|
|
|
|
int sampleCount = -1;
|
|
|
|
|
GetTheBiggestSampleCount(synthNode, ref sampleCount);
|
|
|
|
|
|
|
|
|
|
return sampleCount;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void PlaySound(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
StopSound(sender, e);
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (cueTree.Focused && cueTree.SelectedNode != null && cueTree.SelectedNode.Tag is BuilderCueNode cueNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
if (!string.IsNullOrEmpty(cueNode.SynthReference))
|
|
|
|
|
{
|
|
|
|
|
TreeNode synthNode = synthTree.FindNodeByFullPath(cueNode.SynthReference);
|
2017-06-21 01:19:47 +03:00
|
|
|
|
AddSynthSound(synthNode);
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else if (soundElementTree.Focused && soundElementTree.SelectedNode != null && soundElementTree.SelectedNode.Tag is BuilderSoundElementNode)
|
|
|
|
|
{
|
2017-06-21 01:19:47 +03:00
|
|
|
|
AddSoundElementSound(soundElementTree.SelectedNode, 1, 0, 0);
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else if (synthTree.Focused && synthTree.SelectedNode != null && synthTree.SelectedNode.Tag is BuilderSynthNode)
|
|
|
|
|
{
|
2017-06-21 01:19:47 +03:00
|
|
|
|
AddSynthSound(synthTree.SelectedNode);
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (treeNode.Tag != null && treeNode.Tag is ICloneable clonable)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
2017-03-09 20:48:17 +03:00
|
|
|
|
treeNode.Tag = clonable.Clone();
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (menuStrip.SourceControl is TreeView selectedTree)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
2017-03-09 20:48:17 +03:00
|
|
|
|
CopyNode(selectedTree.SelectedNode);
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void AddToProject(TreeNode treeNode)
|
|
|
|
|
{
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (treeNode.Tag is BuilderCueNode cueNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
// Do checks
|
|
|
|
|
if (!string.IsNullOrEmpty(cueNode.SynthReference) && synthTree.FindNodeByFullPath(cueNode.SynthReference) == null)
|
|
|
|
|
{
|
|
|
|
|
cueNode.SynthReference = string.Empty;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
project.CueNodes.Add(cueNode);
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
else if (treeNode.Tag is BuilderSynthNode synthNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (treeNode.Tag is BuilderSoundElementNode soundElementNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (treeNode.Tag is BuilderAisacNode aisacNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
2017-03-09 20:48:17 +03:00
|
|
|
|
project.AisacNodes.Add(aisacNode);
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (treeNode.Tag is BuilderVoiceLimitGroupNode voiceLimitGroupNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
2017-03-09 20:48:17 +03:00
|
|
|
|
project.VoiceLimitGroupNodes.Add(voiceLimitGroupNode);
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (parent.TreeView == synthTree && parent.Tag is BuilderSynthNode synthNode && nodeToPaste.Tag is BuilderSynthNode copiedSynthNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (menuStrip.SourceControl is TreeView selectedTree)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (nodeToPaste.Tag is BuilderCueNode cueNode)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (menuStrip.SourceControl is TreeView selectedTree)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
if (selectedTree == treeViewOfCopiedNode)
|
|
|
|
|
{
|
|
|
|
|
PasteNode();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void PasteAndInsertNode(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (menuStrip.SourceControl is TreeView selectedTree)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
TreeNode selectedNode = selectedTree.SelectedNode;
|
|
|
|
|
|
|
|
|
|
if (selectedTree == treeViewOfCopiedNode)
|
|
|
|
|
{
|
|
|
|
|
PasteNode(selectedNode.Index + 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ShowAbout(object sender, EventArgs e)
|
|
|
|
|
{
|
2017-04-23 19:22:25 +03:00
|
|
|
|
MessageBox.Show($"{Program.ApplicationTitle} by Skyth (blueskythlikesclouds)", "CSB Builder");
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CreateChildTrackNode(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (menuStrip.SourceControl is TreeView selectedTree)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
TreeNode selectedNode = selectedTree.SelectedNode;
|
|
|
|
|
|
|
|
|
|
if (selectedTree == synthTree)
|
|
|
|
|
{
|
|
|
|
|
CreateSynthNode(selectedNode.Nodes, selectedNode);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CreateAndInsertNode(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
ContextMenuStrip menuStrip = (ContextMenuStrip)((ToolStripItem)sender).Owner;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (menuStrip.SourceControl is TreeView selectedTree)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
TreeNode selectedNode = selectedTree.SelectedNode;
|
|
|
|
|
|
|
|
|
|
if (selectedTree == cueTree)
|
|
|
|
|
{
|
|
|
|
|
CreateCueNode(selectedTree.Nodes, null, selectedNode.Index + 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else if (selectedTree == synthTree)
|
|
|
|
|
{
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (selectedNode.Tag is BuilderSynthNode synthNode && synthNode.Type == BuilderSynthType.WithChildren)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (menuStrip.SourceControl is TreeView selectedTree)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (menuStrip.SourceControl is TreeView selectedTree)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
2017-03-09 20:48:17 +03:00
|
|
|
|
if (menuStrip.SourceControl is TreeView selectedTree)
|
2017-01-26 23:40:46 +03:00
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-04-17 19:06:29 +03:00
|
|
|
|
|
|
|
|
|
private void OpenSettings(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
using (SettingsForm settings = new SettingsForm())
|
|
|
|
|
{
|
|
|
|
|
settings.ShowDialog(this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void convertADXsToWAVToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
using (OpenFileDialog openFileDialog = new OpenFileDialog
|
|
|
|
|
{
|
2017-06-21 01:19:47 +03:00
|
|
|
|
Title = "Convert Audio Files",
|
|
|
|
|
FileName = "Select audio files you want to convert and press Open",
|
|
|
|
|
Filter = Filters,
|
2017-04-17 19:06:29 +03:00
|
|
|
|
Multiselect = true,
|
|
|
|
|
})
|
|
|
|
|
{
|
|
|
|
|
if (openFileDialog.ShowDialog(this) == DialogResult.OK)
|
|
|
|
|
{
|
|
|
|
|
using (SaveFileDialog saveFileDialog = new SaveFileDialog
|
|
|
|
|
{
|
|
|
|
|
Title = "Output Directory",
|
|
|
|
|
FileName = "Enter into a directory and press Save",
|
|
|
|
|
})
|
|
|
|
|
{
|
|
|
|
|
if (saveFileDialog.ShowDialog(this) == DialogResult.OK)
|
|
|
|
|
{
|
2017-06-21 01:19:47 +03:00
|
|
|
|
var failedFiles = new List<string>();
|
|
|
|
|
|
|
|
|
|
Action<string> action = fileName =>
|
2017-04-17 19:06:29 +03:00
|
|
|
|
{
|
2017-06-21 01:19:47 +03:00
|
|
|
|
VGMStreamReader reader = null;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
reader = new VGMStreamReader(fileName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
catch (NullReferenceException)
|
|
|
|
|
{
|
|
|
|
|
failedFiles.Add(Path.GetFileName(fileName));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
using (reader)
|
2017-04-17 19:06:29 +03:00
|
|
|
|
using (WaveFileWriter writer = new WaveFileWriter(
|
|
|
|
|
Path.Combine(
|
|
|
|
|
Path.GetDirectoryName(saveFileDialog.FileName),
|
|
|
|
|
Path.GetFileNameWithoutExtension(fileName) + ".wav"),
|
|
|
|
|
reader.WaveFormat))
|
|
|
|
|
{
|
2017-06-21 01:19:47 +03:00
|
|
|
|
if (reader.LoopFlag)
|
|
|
|
|
{
|
|
|
|
|
// Intro
|
|
|
|
|
DataStream.CopyPartTo(reader, writer, reader.LoopStartPosition, Settings.BufferSize);
|
|
|
|
|
|
|
|
|
|
// Loops
|
|
|
|
|
DataStream.CopyPartTo(reader, writer, (reader.LoopEndPosition - reader.LoopStartPosition) * Settings.LoopCount, Settings.BufferSize);
|
|
|
|
|
|
|
|
|
|
// Last loop, fade away
|
|
|
|
|
byte[] buffer = new byte[Settings.BufferSize];
|
|
|
|
|
|
|
|
|
|
// Fade will be 10 seconds
|
|
|
|
|
double sampleCount = (int)(reader.WaveFormat.AverageBytesPerSecond * Settings.FadeTime);
|
|
|
|
|
|
|
|
|
|
int i;
|
|
|
|
|
int j = (int)(sampleCount + reader.WaveFormat.AverageBytesPerSecond * Settings.FadeDelay);
|
2017-04-17 19:06:29 +03:00
|
|
|
|
|
2017-06-21 01:19:47 +03:00
|
|
|
|
while (j > 0)
|
|
|
|
|
{
|
|
|
|
|
reader.Read(buffer, 0, buffer.Length);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < buffer.Length && j > 0; i += 2, j--)
|
|
|
|
|
{
|
|
|
|
|
double volume = j / sampleCount;
|
|
|
|
|
|
|
|
|
|
// Clamp to 0.0-1.0 range so delay actually works
|
|
|
|
|
volume = volume > 1.0 ? 1.0 : volume;
|
|
|
|
|
|
|
|
|
|
PostSampleEditor.ApplyVolume(buffer, i, volume);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
writer.Write(buffer, 0, i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else
|
2017-04-17 19:06:29 +03:00
|
|
|
|
{
|
2017-06-21 01:19:47 +03:00
|
|
|
|
DataStream.CopyTo(reader, writer, Settings.BufferSize);
|
2017-04-17 19:06:29 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-06-21 01:19:47 +03:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (Settings.EnableThreading)
|
|
|
|
|
{
|
|
|
|
|
Parallel.ForEach(openFileDialog.FileNames, new ParallelOptions { MaxDegreeOfParallelism = Settings.MaxThreads }, action);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
foreach (var item in openFileDialog.FileNames)
|
|
|
|
|
{
|
|
|
|
|
action(item);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (failedFiles.Count != 0)
|
|
|
|
|
{
|
|
|
|
|
MessageBox.Show($"Following files could not be converted:\n{string.Join("\n", failedFiles)}", "CSB Builder", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
2017-04-17 19:06:29 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void extractAAXToFolderToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
using (OpenFileDialog openFileDialog = new OpenFileDialog
|
|
|
|
|
{
|
|
|
|
|
Title = "Extract AAX Files",
|
|
|
|
|
FileName = "Select AAX files you want to extract and press Open",
|
|
|
|
|
Filter = "AAX Files|*.aax",
|
|
|
|
|
DefaultExt = "aax",
|
|
|
|
|
Multiselect = true,
|
|
|
|
|
})
|
|
|
|
|
{
|
|
|
|
|
if (openFileDialog.ShowDialog(this) == DialogResult.OK)
|
|
|
|
|
{
|
|
|
|
|
using (SaveFileDialog saveFileDialog = new SaveFileDialog
|
|
|
|
|
{
|
|
|
|
|
Title = "Output Directory",
|
|
|
|
|
FileName = "Enter into a directory and press Save",
|
|
|
|
|
})
|
|
|
|
|
{
|
|
|
|
|
if (saveFileDialog.ShowDialog(this) == DialogResult.OK)
|
|
|
|
|
{
|
2017-06-21 01:19:47 +03:00
|
|
|
|
DataExtractor extractor = new DataExtractor();
|
|
|
|
|
extractor.EnableThreading = Settings.EnableThreading;
|
|
|
|
|
extractor.MaxThreads = Settings.MaxThreads;
|
|
|
|
|
extractor.BufferSize = Settings.BufferSize;
|
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
foreach (string fileName in openFileDialog.FileNames)
|
|
|
|
|
{
|
|
|
|
|
CriAaxArchive aaxArchive = new CriAaxArchive();
|
|
|
|
|
aaxArchive.Load(fileName, Settings.BufferSize);
|
|
|
|
|
|
|
|
|
|
foreach (CriAaxEntry entry in aaxArchive)
|
|
|
|
|
{
|
|
|
|
|
using (Stream source = File.OpenRead(fileName))
|
|
|
|
|
{
|
2017-06-21 01:19:47 +03:00
|
|
|
|
extractor.Add(fileName, Path.Combine(
|
|
|
|
|
Path.GetDirectoryName(saveFileDialog.FileName),
|
|
|
|
|
$"{Path.GetFileNameWithoutExtension(fileName)}_{entry.Flag}{aaxArchive.GetModeExtension()}"),
|
|
|
|
|
entry.Position,
|
|
|
|
|
entry.Length);
|
2017-04-17 19:06:29 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-06-21 01:19:47 +03:00
|
|
|
|
|
|
|
|
|
extractor.Run();
|
2017-04-17 19:06:29 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void packFolderToAAXToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
using (OpenFileDialog openFileDialog = new OpenFileDialog
|
|
|
|
|
{
|
2017-06-21 01:19:47 +03:00
|
|
|
|
Title = "Pack ADX Files",
|
2017-04-17 19:06:29 +03:00
|
|
|
|
FileName = "Select ADX files you want to pack and press Open",
|
2017-06-21 01:19:47 +03:00
|
|
|
|
Filter = "All Files|*.adx;*.wav|ADX Files|*.adx|WAV Files|*.wav",
|
2017-04-17 19:06:29 +03:00
|
|
|
|
Multiselect = true,
|
|
|
|
|
})
|
|
|
|
|
{
|
|
|
|
|
string[] files = null;
|
|
|
|
|
DialogResult dialogResult;
|
|
|
|
|
|
|
|
|
|
while ((dialogResult = openFileDialog.ShowDialog(this)) == DialogResult.OK)
|
|
|
|
|
{
|
|
|
|
|
if (openFileDialog.FileNames.Length > 2)
|
|
|
|
|
{
|
|
|
|
|
MessageBox.Show("You can select maximum 2 ADX files.", "CSB Builder", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-21 01:19:47 +03:00
|
|
|
|
else if (openFileDialog.FileNames.Length == 2 &&
|
|
|
|
|
!Path.GetExtension(openFileDialog.FileNames[0]).Equals(
|
|
|
|
|
Path.GetExtension(openFileDialog.FileNames[1]), StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
MessageBox.Show("You can select only the same type of files.", "CSB Builder", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-17 19:06:29 +03:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
files = openFileDialog.FileNames;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dialogResult == DialogResult.OK)
|
|
|
|
|
{
|
|
|
|
|
using (SaveFileDialog saveFileDialog = new SaveFileDialog
|
|
|
|
|
{
|
|
|
|
|
Title = "Output File",
|
2017-06-21 01:19:47 +03:00
|
|
|
|
FileName = $"{Path.GetFileNameWithoutExtension(files[0])}.aax",
|
2017-04-17 19:06:29 +03:00
|
|
|
|
Filter = "AAX Files|*.aax",
|
|
|
|
|
DefaultExt = "aax",
|
|
|
|
|
})
|
|
|
|
|
{
|
|
|
|
|
if (saveFileDialog.ShowDialog(this) == DialogResult.OK)
|
|
|
|
|
{
|
|
|
|
|
CriAaxArchive archive = new CriAaxArchive();
|
2017-06-21 01:19:47 +03:00
|
|
|
|
archive.SetModeFromExtension(files[0]);
|
2017-04-17 19:06:29 +03:00
|
|
|
|
|
|
|
|
|
for (int i = 0; i < files.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
archive.Add(new CriAaxEntry { FilePath = new FileInfo(files[i]), Flag = (CriAaxEntryFlag)i });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
archive.Save(saveFileDialog.FileName);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-06-21 01:19:47 +03:00
|
|
|
|
|
|
|
|
|
private void convertAndSplitLoopingToWAVToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
using (OpenFileDialog openFileDialog = new OpenFileDialog
|
|
|
|
|
{
|
|
|
|
|
Title = "Convert And Split Audio Files",
|
|
|
|
|
FileName = "Select audio files you want to convert and press Open",
|
|
|
|
|
Filter = Filters,
|
|
|
|
|
Multiselect = true,
|
|
|
|
|
})
|
|
|
|
|
{
|
|
|
|
|
if (openFileDialog.ShowDialog(this) == DialogResult.OK)
|
|
|
|
|
{
|
|
|
|
|
using (SaveFileDialog saveFileDialog = new SaveFileDialog
|
|
|
|
|
{
|
|
|
|
|
Title = "Output Directory",
|
|
|
|
|
FileName = "Enter into a directory and press Save",
|
|
|
|
|
})
|
|
|
|
|
{
|
|
|
|
|
if (saveFileDialog.ShowDialog(this) == DialogResult.OK)
|
|
|
|
|
{
|
|
|
|
|
var failedFiles = new List<string>();
|
|
|
|
|
|
|
|
|
|
Action<string> action = fileName =>
|
|
|
|
|
{
|
|
|
|
|
VGMStreamReader reader = null;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
reader = new VGMStreamReader(fileName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
catch (NullReferenceException)
|
|
|
|
|
{
|
|
|
|
|
failedFiles.Add(Path.GetFileName(fileName));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
using (reader)
|
|
|
|
|
{
|
|
|
|
|
string outputFileName =
|
|
|
|
|
Path.Combine(
|
|
|
|
|
Path.GetDirectoryName(saveFileDialog.FileName),
|
|
|
|
|
Path.GetFileNameWithoutExtension(fileName));
|
|
|
|
|
|
|
|
|
|
WaveFileWriter introWriter;
|
|
|
|
|
WaveFileWriter loopWriter;
|
|
|
|
|
|
|
|
|
|
if (reader.LoopFlag)
|
|
|
|
|
{
|
|
|
|
|
using (introWriter = new WaveFileWriter(outputFileName + "_Intro.wav", reader.WaveFormat))
|
|
|
|
|
using (loopWriter = new WaveFileWriter(outputFileName + "_Loop.wav", reader.WaveFormat))
|
|
|
|
|
{
|
|
|
|
|
DataStream.CopyPartTo(reader, introWriter, 0, reader.LoopStartPosition, Settings.BufferSize);
|
|
|
|
|
DataStream.CopyPartTo(reader, loopWriter, reader.LoopStartPosition, reader.LoopEndPosition - reader.LoopStartPosition, Settings.BufferSize);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// No loop enabled, directly extract the intro
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
using (introWriter = new WaveFileWriter(outputFileName + "_Intro.wav", reader.WaveFormat))
|
|
|
|
|
{
|
|
|
|
|
DataStream.CopyTo(reader, introWriter, Settings.BufferSize);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (Settings.EnableThreading)
|
|
|
|
|
{
|
|
|
|
|
Parallel.ForEach(openFileDialog.FileNames, new ParallelOptions { MaxDegreeOfParallelism = Settings.MaxThreads }, action);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
foreach (var item in openFileDialog.FileNames)
|
|
|
|
|
{
|
|
|
|
|
action(item);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (failedFiles.Count != 0)
|
|
|
|
|
{
|
|
|
|
|
MessageBox.Show($"Following files could not be converted:\n{string.Join("\n", failedFiles)}", "CSB Builder", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-01-26 23:40:46 +03:00
|
|
|
|
}
|
|
|
|
|
}
|