using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.ComponentModel; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using BuzzGUI.Interfaces; using BuzzGUI.Common; using BuzzGUI.Common.InterfaceExtensions; namespace Relativion.GUI { public class MachineGUIFactory : IMachineGUIFactory { public IMachineGUI CreateGUI(IMachineGUIHost host) { return new RelativionGUI(); } } public partial class RelativionGUI : UserControl, IMachineGUI, INotifyPropertyChanged { PianoKeyboard ctrlKeyboard; PianoKeyboard targetKeyboard; const int velocity = 100; public RelativionGUI() { InitializeComponent(); ctrlKeyboard = new PianoKeyboard(this, 8, Colors.Green); ctrlKeyboard.KeyDown += (key) => { Machine.SendMIDINote(0, key, velocity); }; ctrlKeyboard.KeyUp += (key) => { Machine.SendMIDINote(0, key, 0); }; targetKeyboard = new PianoKeyboard(this, 4, Colors.Red) { HorizontalAlignment = System.Windows.HorizontalAlignment.Left }; this.SizeChanged += (sender, e) => { kbsv.Width = e.NewSize.Width; targetkbsv.Width = e.NewSize.Width; kbsv.ScrollToHorizontalOffset((machine.GetParameter("Ctrl. Root").GetValue(0) + 0.5) * ctrlKeyboard.dim.NoteWidth - e.NewSize.Width / 2); //targetkbsv.ScrollToHorizontalOffset(12.5 * targetKeyboard.dim.NoteWidth - e.NewSize.Width / 2); }; targetkbsv.Content = targetKeyboard; kbsv.Content = ctrlKeyboard; targetkbsv.ScrollToHorizontalOffset(12 * targetKeyboard.dim.NoteWidth); DataContext = this; new MachineGUIUpdateTimer(this, () => { if (Machine == null) return; new MachineGUIMessage { Send = bw => { bw.Write(2); }, // get active notes Receive = br => { int count = br.ReadInt32(); bool[] ctrl = new bool[128]; bool[] target = new bool[128]; for (int i = 0; i < count; i++) { ctrl[br.ReadByte()] = true; target[br.ReadByte()] = true; } for (int i = 0; i < 128; i++) { if (ctrl[i]) ctrlKeyboard.PianoKeyDown(i); else ctrlKeyboard.PianoKeyUp(i); if (target[i]) targetKeyboard.PianoKeyDown(i); else targetKeyboard.PianoKeyUp(i); } }, Machine = machine }; }); } IMachine machine; public IMachine Machine { get { return machine; } set { if (machine != null) { machine.Graph.Buzz.Song.MachineAdded -= new Action(Song_MachineAdded); machine.Graph.Buzz.Song.MachineRemoved -= new Action(Song_MachineRemoved); machine.GetParameter("Ctrl. Root").UnsubscribeEvents(0, RootNoteValueChanged, null); } machine = value; if (machine != null) { machine.Graph.Buzz.Song.MachineAdded += new Action(Song_MachineAdded); machine.Graph.Buzz.Song.MachineRemoved += new Action(Song_MachineRemoved); machine.GetParameter("Ctrl. Root").SubscribeEvents(0, RootNoteValueChanged, null); foreach (var m in machine.Graph.Buzz.Song.Machines) Song_MachineAdded(m); } } } void RootNoteValueChanged(IParameter param, int track) { ctrlKeyboard.RootNote = param.GetValue(track); } void Song_MachineAdded(IMachine m) { if (m.DLL.Info.Type == MachineType.Master || (m.DLL.Info.Flags & MachineInfoFlags.CONTROL_MACHINE) == MachineInfoFlags.CONTROL_MACHINE) return; m.PropertyChanged += MachinePropertyChanged; machineList.Add(new MachineVM(m)); PropertyChanged.Raise(this, "MachineList"); } void Song_MachineRemoved(IMachine m) { m.PropertyChanged -= MachinePropertyChanged; var vm = machineList.FirstOrDefault(x => x.Machine == m); if (vm == null) return; machineList.Remove(vm); PropertyChanged.Raise(this, "MachineList"); } void MachinePropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == "Name") { var vm = machineList.First(x => x.Machine == sender as IMachine); PropertyChanged.Raise(vm, "Name"); } } public class MachineVM : INotifyPropertyChanged { public IMachine Machine { get; set; } public MachineVM(IMachine m) { Machine = m; } public string Name { get { return Machine.Name; } } #region INotifyPropertyChanged Members #pragma warning disable 67 public event PropertyChangedEventHandler PropertyChanged; #endregion } List machineList = new List(); public IEnumerable MachineList { get { return machineList.OrderBy(m => m.Machine.Name); } } MachineVM targetMachine; public MachineVM TargetMachine { get { if (targetMachine == null) { new MachineGUIMessage { Send = bw => { bw.Write(0); }, // get machine by name Receive = br => { string name = br.ReadASCIIZString(); targetMachine = machineList.Where(m => m.Machine.Name == name).FirstOrDefault(); }, Machine = machine }; } return targetMachine; } set { targetMachine = value; new MachineGUIMessage { Send = bw => { bw.Write(1); // set machine by name bw.WriteASCIIZString(targetMachine.Machine.Name); }, Machine = machine }; PropertyChanged.Raise(this, "TargetMachine"); } } #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; #endregion } }