480 lines
16 KiB
C#
480 lines
16 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Data;
|
|
using System.Drawing;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
using System.Timers;
|
|
using System.Diagnostics;
|
|
using Studio.ControlsEx;
|
|
using System.Drawing.Drawing2D;
|
|
using System.Drawing.Text;
|
|
using System.Xml.Serialization;
|
|
using System.IO;
|
|
|
|
|
|
namespace Studio.Audition
|
|
{
|
|
public class Background : Panel
|
|
{
|
|
public class Panel
|
|
{
|
|
public Rectangle Bounds;
|
|
public string Title;
|
|
|
|
public Panel(Rectangle bounds, string title)
|
|
{
|
|
Bounds = bounds;
|
|
Title = title;
|
|
}
|
|
}
|
|
|
|
public List<Panel> Panels = new List<Panel>();
|
|
|
|
public Background()
|
|
{
|
|
AutoScroll = true;
|
|
Dock = DockStyle.Fill;
|
|
|
|
DoubleBuffered = true;
|
|
}
|
|
|
|
protected override void OnPaint(PaintEventArgs e)
|
|
{
|
|
e.Graphics.TranslateTransform(AutoScrollPosition.X, AutoScrollPosition.Y);
|
|
|
|
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
|
|
|
foreach (var panel in Panels)
|
|
{
|
|
Rectangle rect = panel.Bounds;
|
|
rect.Inflate(-1, -1);
|
|
|
|
GraphicsPath path = RoundedRectangle.Create(rect, 5.0f);
|
|
|
|
LinearGradientBrush linGrBrush = new LinearGradientBrush(new Point(0, panel.Bounds.Y), new Point(0, panel.Bounds.Y + panel.Bounds.Height), SystemColorsEx.ControlLight, SystemColorsEx.Control);
|
|
|
|
e.Graphics.FillPath(linGrBrush, path);
|
|
|
|
e.Graphics.DrawPath(new Pen(SystemColorsEx.Blend(0.67f, Color.FromArgb(0x00, 0x00, 0x00, 0x00), SystemColorsEx.ControlDark), 2), path);
|
|
|
|
e.Graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
|
|
|
|
StringFormat sf = new StringFormat();
|
|
sf.LineAlignment = StringAlignment.Center;
|
|
sf.Alignment = StringAlignment.Center;
|
|
sf.FormatFlags = StringFormatFlags.NoWrap;
|
|
e.Graphics.DrawString(panel.Title, new Font("MS Sans Serif", 10, FontStyle.Bold, GraphicsUnit.Pixel), new SolidBrush(SystemColorsEx.ControlText), new Rectangle(panel.Bounds.X + 8, panel.Bounds.Y + 8, panel.Bounds.Width - 16, 16), sf);
|
|
}
|
|
|
|
e.Graphics.SmoothingMode = SmoothingMode.Default;
|
|
}
|
|
}
|
|
|
|
public class AuditionForm : Form
|
|
{
|
|
protected override CreateParams CreateParams
|
|
{
|
|
get
|
|
{
|
|
CreateParams cp = base.CreateParams;
|
|
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
|
|
return cp;
|
|
}
|
|
}
|
|
|
|
private Background _background;
|
|
private System.Timers.Timer Timer;
|
|
|
|
private readonly Engine engine;
|
|
|
|
private readonly AuditionDefinitionModel Model;
|
|
|
|
private Synth Synth;
|
|
|
|
private readonly List<LedEx> EventOutControls = new List<LedEx>();
|
|
private readonly List<LevelEx> ControlOutControls = new List<LevelEx>();
|
|
private readonly List<LevelEx> SwitchOutControls = new List<LevelEx>();
|
|
private readonly bool _usingWwise;
|
|
|
|
public AuditionForm(string fileName)
|
|
{
|
|
DoubleBuffered = true;
|
|
|
|
try
|
|
{
|
|
var deserializer = new XmlSerializer(typeof(AuditionDefinitionModel));
|
|
var textReader = new StreamReader(fileName);
|
|
|
|
Model = (AuditionDefinitionModel)deserializer.Deserialize(textReader);
|
|
textReader.Close();
|
|
|
|
if (Model != null)
|
|
{
|
|
BackColor = SystemColorsEx.Control;
|
|
Text = Model.Synth + " " + DateTime.Now.ToString("g");
|
|
Icon = Properties.Resources.Sandwich;
|
|
StartPosition = FormStartPosition.CenterScreen;
|
|
|
|
engine = new Engine();
|
|
|
|
LoadScripts();
|
|
|
|
CreateControls();
|
|
|
|
FormClosed += OnFormClosed;
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
MessageBox.Show(e.Message, "Error loading panel file");
|
|
}
|
|
}
|
|
|
|
public AuditionForm(AuditionDefinitionModel model)
|
|
{
|
|
DoubleBuffered = true;
|
|
|
|
Model = model;
|
|
|
|
BackColor = SystemColorsEx.Control;
|
|
Text = model.Synth + " " + DateTime.Now.ToString("g");
|
|
Icon = Properties.Resources.Sandwich;
|
|
StartPosition = FormStartPosition.CenterScreen;
|
|
|
|
_usingWwise = File.Exists(Path.Combine(model.DataPath, "Init.bnk"));
|
|
|
|
if (_usingWwise)
|
|
{
|
|
LibSoundwich.SoundwichInitWwise(model.DataPath + "\\", "Init");
|
|
}
|
|
|
|
engine = new Engine();
|
|
|
|
LoadScripts();
|
|
|
|
CreateControls();
|
|
|
|
Synth.Activate();
|
|
|
|
FormClosed += OnFormClosed;
|
|
}
|
|
|
|
private void OnFormClosed(object sender, FormClosedEventArgs e)
|
|
{
|
|
Synth.Deactivate();
|
|
|
|
Timer.Stop();
|
|
|
|
Timer = null;
|
|
|
|
Dispose();
|
|
|
|
Synth.Dispose();
|
|
engine.Dispose();
|
|
|
|
if (_usingWwise)
|
|
{
|
|
LibSoundwich.SoundwichShutdownWwise();
|
|
}
|
|
}
|
|
|
|
private readonly Dictionary<string, EventIn> EventIns = new Dictionary<string, EventIn>();
|
|
private readonly Dictionary<string, EventOut> EventOuts = new Dictionary<string, EventOut>();
|
|
private readonly Dictionary<string, ControlIn> ControlIns = new Dictionary<string, ControlIn>();
|
|
private readonly Dictionary<string, ControlOut> ControlOuts = new Dictionary<string, ControlOut>();
|
|
private readonly Dictionary<string, SwitchIn> SwitchIns = new Dictionary<string, SwitchIn>();
|
|
private readonly Dictionary<string, SwitchOut> SwitchOuts = new Dictionary<string, SwitchOut>();
|
|
private readonly Dictionary<string, MonoOut> MonoOuts = new Dictionary<string, MonoOut>();
|
|
|
|
public string FitText(int width, string text)
|
|
{
|
|
return text;
|
|
}
|
|
|
|
public void LoadScripts()
|
|
{
|
|
engine.SetDataPath(Model.DataPath);
|
|
|
|
Synth = new Synth(engine, "TestSyn", Model.Synth);
|
|
|
|
foreach (AuditionDefinitionModel.EventIn eventIn in Model.EventIns)
|
|
{
|
|
EventIns.Add(eventIn.Module + "." + eventIn.Name, Synth.GetEventInComponent(eventIn.Module + "." + eventIn.Name));
|
|
}
|
|
|
|
foreach (AuditionDefinitionModel.EventOut eventOut in Model.EventOuts)
|
|
{
|
|
EventOut eventOutComponent = Synth.GetEventOutComponent(eventOut.Module + "." + eventOut.Name);
|
|
|
|
EventOuts.Add(eventOut.Module + "." + eventOut.Name, eventOutComponent);
|
|
|
|
eventOutComponent.OnEventOutChanged += OnEventOutComponentValueChanged;
|
|
}
|
|
|
|
foreach (AuditionDefinitionModel.ControlIn controlIn in Model.ControlIns)
|
|
{
|
|
ControlIns.Add(controlIn.Module + "." + controlIn.Name, Synth.GetControlInComponent(controlIn.Module + "." + controlIn.Name));
|
|
}
|
|
|
|
foreach (AuditionDefinitionModel.ControlOut controlOut in Model.ControlOuts)
|
|
{
|
|
ControlOut controlOutComponent = Synth.GetControlOutComponent(controlOut.Module + "." + controlOut.Name);
|
|
|
|
ControlOuts.Add(controlOut.Module + "." + controlOut.Name, controlOutComponent);
|
|
|
|
controlOutComponent.OnControlOutChanged += OnControlOutComponentValueChanged;
|
|
}
|
|
|
|
foreach (AuditionDefinitionModel.SwitchIn switchIn in Model.SwitchIns)
|
|
{
|
|
SwitchIns.Add(switchIn.Module + "." + switchIn.Name, Synth.GetSwitchInComponent(switchIn.Module + "." + switchIn.Name));
|
|
}
|
|
|
|
foreach (AuditionDefinitionModel.SwitchOut switchOut in Model.SwitchOuts)
|
|
{
|
|
SwitchOut switchOutComponent = Synth.GetSwitchOutComponent(switchOut.Module + "." + switchOut.Name);
|
|
|
|
SwitchOuts.Add(switchOut.Module + "." + switchOut.Name, switchOutComponent);
|
|
|
|
switchOutComponent.OnSwitchOutChanged += OnSwitchOutComponentValueChanged;
|
|
}
|
|
|
|
foreach (AuditionDefinitionModel.MonoOut monoOut in Model.MonoOuts)
|
|
{
|
|
MonoOut monolOutComponent = Synth.GetMonoOutComponent(monoOut.Name);
|
|
|
|
MonoOuts.Add(monoOut.Module + "\n" + monoOut.Name, monolOutComponent);
|
|
|
|
monolOutComponent.OnMonoOutChanged += OnMonoOutComponentValueChanged;
|
|
}
|
|
}
|
|
|
|
private void OnEventOutComponentValueChanged(object sender, EventArgs e)
|
|
{
|
|
EventOut eventOutComponent = sender as EventOut;
|
|
|
|
string name = EventOuts.FirstOrDefault(x => x.Value == eventOutComponent).Key;
|
|
|
|
LedEx level = EventOutControls.Find(i => i.Name == name);
|
|
|
|
BeginInvoke((Action)(() =>
|
|
{
|
|
level.Ping();
|
|
}));
|
|
}
|
|
|
|
private void OnControlOutComponentValueChanged(object sender, ControlOutChangedEventArgs e)
|
|
{
|
|
ControlOut controlOutComponent = sender as ControlOut;
|
|
|
|
string name = ControlOuts.FirstOrDefault(x => x.Value == controlOutComponent).Key;
|
|
|
|
LevelEx level = ControlOutControls.Find(i => i.Name == name);
|
|
|
|
level.Value = e.Value;
|
|
}
|
|
|
|
private void OnSwitchOutComponentValueChanged(object sender, SwitchOutChangedEventArgs e)
|
|
{
|
|
SwitchOut switchOutComponent = sender as SwitchOut;
|
|
|
|
string name = SwitchOuts.FirstOrDefault(x => x.Value == switchOutComponent).Key;
|
|
|
|
LevelEx level = SwitchOutControls.Find(i => i.Name == name);
|
|
|
|
level.Value = e.Value;
|
|
}
|
|
|
|
private void OnMonoOutComponentValueChanged(object sender, OnMonoOutChangedEventArgs e)
|
|
{
|
|
MonoOut monoOutComponent = sender as MonoOut;
|
|
|
|
string text = MonoOuts.FirstOrDefault(x => x.Value == monoOutComponent).Key;
|
|
}
|
|
|
|
private void CreateControls()
|
|
{
|
|
SuspendLayout();
|
|
|
|
_background = new Background();
|
|
|
|
foreach (AuditionDefinitionModel.Panel panel in Model.Panels)
|
|
{
|
|
_background.Panels.Add(new Background.Panel(new Rectangle(8 + 16 * panel.X, 8 + 16 * panel.Y, 16 * panel.Width, 16 * panel.Height), FitText(panel.Width * 16 - 16, panel.Name)));
|
|
}
|
|
|
|
foreach (AuditionDefinitionModel.EventIn eventIn in Model.EventIns)
|
|
{
|
|
ButtonEx button = new ButtonEx();
|
|
button.Text = FitText(80, eventIn.Name);
|
|
button.Name = eventIn.Module + "." + eventIn.Name;
|
|
button.Location = new Point(eventIn.X * 16, eventIn.Y * 16);
|
|
button.Size = new Size(80, 64);
|
|
|
|
button.OnPressed += OnEventFired;
|
|
|
|
_background.Controls.Add(button);
|
|
}
|
|
|
|
foreach (AuditionDefinitionModel.EventOut eventOut in Model.EventOuts)
|
|
{
|
|
LedEx led = new LedEx();
|
|
led.Text = FitText(80, eventOut.Name);
|
|
led.Name = eventOut.Module + "." + eventOut.Name;
|
|
led.Location = new Point(eventOut.X * 16, eventOut.Y * 16);
|
|
led.Size = new Size(80, 48);
|
|
|
|
_background.Controls.Add(led);
|
|
|
|
EventOutControls.Add(led);
|
|
}
|
|
|
|
foreach (AuditionDefinitionModel.ControlIn controlIn in Model.ControlIns)
|
|
{
|
|
KnobEx knob = new KnobEx();
|
|
knob.Text = FitText(80, controlIn.Name);
|
|
knob.Name = controlIn.Module + "." + controlIn.Name;
|
|
knob.Location = new Point(controlIn.X * 16, controlIn.Y * 16);
|
|
knob.Size = new Size(80, 96);
|
|
|
|
knob.Min = controlIn.Min;
|
|
knob.Max = controlIn.Max;
|
|
|
|
if (controlIn.Min < controlIn.Mid && controlIn.Mid < controlIn.Max)
|
|
{
|
|
knob.Mid = controlIn.Mid;
|
|
}
|
|
else
|
|
{
|
|
knob.Mid = controlIn.Min + 0.5f * (controlIn.Max - controlIn.Min);
|
|
}
|
|
|
|
knob.Value = controlIn.InitValue;
|
|
knob.BigStep = 1.0f;
|
|
|
|
knob.ValueChanged += OnValueChanged;
|
|
|
|
_background.Controls.Add(knob);
|
|
}
|
|
|
|
foreach (AuditionDefinitionModel.ControlOut controlOut in Model.ControlOuts)
|
|
{
|
|
LevelEx level = new LevelEx();
|
|
level.Text = FitText(80, controlOut.Name);
|
|
level.Name = controlOut.Module + "." + controlOut.Name;
|
|
level.Location = new Point(controlOut.X * 16, controlOut.Y * 16);
|
|
level.Size = new Size(80, 192);
|
|
|
|
level.Min = controlOut.Min;
|
|
level.Max = controlOut.Max;
|
|
level.Value = controlOut.InitValue;
|
|
|
|
_background.Controls.Add(level);
|
|
|
|
ControlOutControls.Add(level);
|
|
}
|
|
|
|
foreach (AuditionDefinitionModel.SwitchIn switchIn in Model.SwitchIns)
|
|
{
|
|
KnobEx knob = new KnobEx();
|
|
knob.Text = FitText(80, switchIn.Name);
|
|
knob.Name = switchIn.Module + "." + switchIn.Name;
|
|
knob.Location = new Point(switchIn.X * 16, switchIn.Y * 16);
|
|
knob.Size = new Size(80, 96);
|
|
|
|
knob.Min = switchIn.Min;
|
|
knob.Max = switchIn.Max;
|
|
knob.Mid = (float)switchIn.Min + 0.5f * (float)(switchIn.Max - switchIn.Min);
|
|
knob.Value = switchIn.InitValue;
|
|
knob.SmallStep = 1.0f;
|
|
knob.BigStep = 1.0f;
|
|
knob.Decimals = 0;
|
|
|
|
knob.ValueChanged += OnSwitchChanged;
|
|
|
|
_background.Controls.Add(knob);
|
|
}
|
|
|
|
foreach (AuditionDefinitionModel.SwitchOut switchOut in Model.SwitchOuts)
|
|
{
|
|
LevelEx level = new LevelEx();
|
|
level.Text = FitText(80, switchOut.Name);
|
|
level.Name = switchOut.Module + "." + switchOut.Name;
|
|
level.Location = new Point(switchOut.X * 16, switchOut.Y * 16);
|
|
level.Size = new Size(80, 192);
|
|
|
|
level.Min = switchOut.Min;
|
|
level.Max = switchOut.Max;
|
|
level.Value = switchOut.InitValue;
|
|
level.Decimals = 0;
|
|
|
|
_background.Controls.Add(level);
|
|
|
|
SwitchOutControls.Add(level);
|
|
}
|
|
|
|
int width = 0;
|
|
int height = 0;
|
|
foreach (var panel in _background.Panels)
|
|
{
|
|
width = Math.Max(width, panel.Bounds.X + panel.Bounds.Width);
|
|
height = Math.Max(height, panel.Bounds.Y + panel.Bounds.Height);
|
|
}
|
|
|
|
_background.Width = width + 8;
|
|
_background.Height = height + 8;
|
|
|
|
ClientSize = new Size(_background.Width, _background.Height);
|
|
|
|
MaximumSize = new Size(Width, Height);
|
|
|
|
Width = Math.Min(Width, Screen.FromControl(this).Bounds.Width);
|
|
Height = Math.Min(Height, Screen.FromControl(this).Bounds.Height);
|
|
|
|
Controls.Add(_background);
|
|
|
|
ResumeLayout(false);
|
|
|
|
PerformLayout();
|
|
|
|
Timer = new System.Timers.Timer(33);
|
|
Timer.Enabled = true;
|
|
Timer.Elapsed += OnElapsed;
|
|
}
|
|
|
|
private void OnElapsed(object sender, ElapsedEventArgs e)
|
|
{
|
|
engine.Tick();
|
|
|
|
if (_usingWwise)
|
|
{
|
|
LibSoundwich.SoundwichTickWwise();
|
|
}
|
|
}
|
|
|
|
private void OnValueChanged(object sender, EventArgs e)
|
|
{
|
|
KnobEx knob = sender as KnobEx;
|
|
|
|
ControlIns[knob.Name].Set(knob.Value);
|
|
}
|
|
|
|
private void OnSwitchChanged(object sender, EventArgs e)
|
|
{
|
|
KnobEx knob = sender as KnobEx;
|
|
|
|
SwitchIns[knob.Name].Set((int)Math.Round(knob.Value));
|
|
}
|
|
|
|
private void OnEventFired(object sender, EventArgs e)
|
|
{
|
|
ButtonEx button = sender as ButtonEx;
|
|
|
|
EventIns[button.Name].Set();
|
|
}
|
|
}
|
|
}
|