From 872a30787d3c3a199bd323cdd8d1d131c02ca503 Mon Sep 17 00:00:00 2001 From: alcexhim Date: Sun, 27 Sep 2015 23:40:38 -0400 Subject: [PATCH] Made improvements to Piano Roll Editor --- .../Synthesized/PianoRoll/PianoRollControl.cs | 248 +++++++++++++++++- .../SynthesizedAudioEditor.Designer.cs | 8 +- .../Synthesized/SynthesizedAudioEditor.resx | 11 +- .../Color.cs | 8 + 4 files changed, 266 insertions(+), 9 deletions(-) diff --git a/CSharp/Engines/WindowsForms/Plugins/UniversalEditor.Plugins.Multimedia.UserInterface.WindowsForms/Controls/Multimedia/Audio/Synthesized/PianoRoll/PianoRollControl.cs b/CSharp/Engines/WindowsForms/Plugins/UniversalEditor.Plugins.Multimedia.UserInterface.WindowsForms/Controls/Multimedia/Audio/Synthesized/PianoRoll/PianoRollControl.cs index 235c29ec..0222b448 100644 --- a/CSharp/Engines/WindowsForms/Plugins/UniversalEditor.Plugins.Multimedia.UserInterface.WindowsForms/Controls/Multimedia/Audio/Synthesized/PianoRoll/PianoRollControl.cs +++ b/CSharp/Engines/WindowsForms/Plugins/UniversalEditor.Plugins.Multimedia.UserInterface.WindowsForms/Controls/Multimedia/Audio/Synthesized/PianoRoll/PianoRollControl.cs @@ -6,6 +6,8 @@ using System.Data; using System.Linq; using System.Text; using System.Windows.Forms; +using AwesomeControls.Theming; +using UniversalEditor.ObjectModels.Multimedia.Audio.Synthesized; namespace UniversalEditor.Controls.Multimedia.Audio.Synthesized.PianoRoll { @@ -14,17 +16,257 @@ namespace UniversalEditor.Controls.Multimedia.Audio.Synthesized.PianoRoll public PianoRollControl() { InitializeComponent(); + DoubleBuffered = true; } - private Size mvarGridSize = new Size(128, 16); - public Size GridSize { get { return mvarGridSize; } set { mvarGridSize = value; } } + private SynthesizedAudioCommand.SynthesizedAudioCommandCollection mvarCommands = new SynthesizedAudioCommand.SynthesizedAudioCommandCollection(); + public SynthesizedAudioCommand.SynthesizedAudioCommandCollection Commands { get { return mvarCommands; } } + + private SynthesizedAudioCommand.SynthesizedAudioCommandCollection mvarSelectedCommands = new SynthesizedAudioCommand.SynthesizedAudioCommandCollection(); + public SynthesizedAudioCommand.SynthesizedAudioCommandCollection SelectedCommands { get { return mvarSelectedCommands; } } + + private bool mvarShowKeyboard = true; + public bool ShowKeyboard { get { return mvarShowKeyboard; } set { mvarShowKeyboard = value; Invalidate(); } } + + private int mvarKeyboardWidth = 64; + public int KeyboardWidth { get { return mvarKeyboardWidth; } set { mvarKeyboardWidth = value; Invalidate(); } } + + private int mvarQuarterNoteWidth = 48; + private int mvarNoteHeight = 14; + + private double mvarZoomFactor = 1.0; + public double ZoomFactor { get { return mvarZoomFactor; } set { mvarZoomFactor = value; Invalidate(); } } private Size mvarQuantizationSize = new Size(16, 16); - public Size QuantizationSize { get { return mvarQuantizationSize; } set { mvarQuantizationSize = value; } } + public Size QuantizationSize { get { return mvarQuantizationSize; } set { mvarQuantizationSize = value; Invalidate(); } } + + private bool drag_Dragging = false; + private Point drag_OriginalLocation = new Point(); + private Point drag_CurrentLocation = new Point(); + + protected override void OnMouseDown(MouseEventArgs e) + { + base.OnMouseDown(e); + + Point pt = e.Location; + if (mvarShowKeyboard) + { + pt.X -= mvarKeyboardWidth; + } + + SynthesizedAudioCommand cmd = HitTest(e.Location); + if (cmd != null) + { + if (Control.ModifierKeys == Keys.None) + { + mvarSelectedCommands.Clear(); + } + else if (Control.ModifierKeys == Keys.Shift) + { + + } + mvarSelectedCommands.Add(cmd); + } + + if (e.Button == System.Windows.Forms.MouseButtons.Left) + { + drag_OriginalLocation = Quantize(pt); + drag_CurrentLocation = drag_OriginalLocation; + drag_Dragging = true; + } + } + + protected override void OnMouseMove(MouseEventArgs e) + { + base.OnMouseMove(e); + if (e.Button == System.Windows.Forms.MouseButtons.Left) + { + Point pt = e.Location; + if (mvarShowKeyboard) + { + pt.X -= mvarKeyboardWidth; + } + + drag_CurrentLocation = Quantize(new Point(pt.X, drag_OriginalLocation.Y)); + Invalidate(); + } + } + + private double ValueToFrequency(int value) + { + return value; + } + private int FrequencyToValue(double frequency) + { + return (int)frequency; + } + + protected override void OnMouseUp(MouseEventArgs e) + { + base.OnMouseUp(e); + drag_Dragging = false; + + if (drag_CurrentLocation.X - drag_OriginalLocation.X > 0) + { + SynthesizedAudioCommandNote note = new SynthesizedAudioCommandNote(); + note.Position = drag_OriginalLocation.X; + note.Length = (drag_CurrentLocation.X - drag_OriginalLocation.X); + note.Frequency = ValueToFrequency(drag_OriginalLocation.Y); + mvarCommands.Add(note); + + mvarSelectedCommands.Clear(); + mvarSelectedCommands.Add(note); + } + + Invalidate(); + } + + private Point Quantize(Point pt) + { + int qX = (int)((double)(pt.X / mvarQuarterNoteWidth)); + int qY = (int)((double)((pt.Y / mvarNoteHeight))); + return new Point(qX, qY); + } + private Point Unquantize(Point pt) + { + int uqX = (int)(pt.X * mvarQuarterNoteWidth); + int uqY = (int)(pt.Y * mvarNoteHeight); + return new Point(uqX, uqY); + } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); + + List noteValuesBlackKeys = new List(new int[] + { + 1, 3, 5, 8, 10 + }); + + int gridWidth = (int)(mvarQuarterNoteWidth * mvarZoomFactor); + int gridHeight = (int)(mvarNoteHeight * mvarZoomFactor); + + Rectangle gridRect = GetGridRect(); + if (mvarShowKeyboard) + { + Rectangle keyboardRect = GetKeyboardRect(); + + for (int i = 0; i < keyboardRect.Height; i += gridHeight) + { + int noteValue = (int)(((double)i / gridHeight) % 12) + 1; + e.Graphics.DrawLine(new Pen(Colors.LightGray.ToGdiColor()), keyboardRect.Left, i, keyboardRect.Right, i); + + if (noteValuesBlackKeys.Contains(noteValue)) + { + // has a black key + e.Graphics.FillRectangle(new SolidBrush(Colors.DarkGray.ToGdiColor()), keyboardRect.Left, i, (int)((double)keyboardRect.Width / 2), gridHeight); + } + } + } + + Pen gridPen = new Pen(Colors.LightGray.ToGdiColor()); + + for (int i = 0; i < this.Height; i += gridHeight) + { + int noteValue = (int)(((double)i / gridHeight) % 12) + 1; + if (noteValuesBlackKeys.Contains(noteValue)) + { + e.Graphics.FillRectangle(new SolidBrush(Color.FromRGBA(0xDD, 0xDD, 0xDD).ToGdiColor()), new Rectangle(gridRect.Left, gridRect.Top + i, gridRect.Width, gridHeight)); + } + + gridPen.Color = Colors.LightGray.ToGdiColor(); + e.Graphics.DrawLine(gridPen, gridRect.Left, gridRect.Top + i, gridRect.Right, gridRect.Top + i); + + // e.Graphics.DrawString(noteValue.ToString(), Font, new SolidBrush(Colors.Red.ToGdiColor()), new Point(0, i)); + } + for (int i = 0; i < this.Width; i += gridWidth) + { + if ((i % (mvarQuarterNoteWidth * 4)) == 0) + { + gridPen.Color = Colors.DarkGray.ToGdiColor(); + } + else + { + gridPen.Color = Colors.LightGray.ToGdiColor(); + } + e.Graphics.DrawLine(gridPen, gridRect.Left + i, gridRect.Top, gridRect.Left + i, gridRect.Bottom); + } + + if (drag_Dragging) + { + Pen draggingPen = new Pen(Colors.DarkGray.ToGdiColor()); + draggingPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot; + + Rectangle draggingRect = new Rectangle(drag_OriginalLocation.X * mvarQuarterNoteWidth, drag_OriginalLocation.Y * mvarNoteHeight, (drag_CurrentLocation.X * mvarQuarterNoteWidth) - (drag_OriginalLocation.X * mvarQuarterNoteWidth), mvarNoteHeight); + draggingRect.Offset(gridRect.X, gridRect.Y); + + e.Graphics.DrawRectangle(draggingPen, draggingRect); + } + + foreach (SynthesizedAudioCommand cmd in mvarCommands) + { + if (cmd is SynthesizedAudioCommandNote) + { + SynthesizedAudioCommandNote note = (cmd as SynthesizedAudioCommandNote); + + Rectangle rect = GetNoteRect(note); + + if (mvarSelectedCommands.Contains(cmd)) + { + e.Graphics.FillRectangle(new SolidBrush(Color.FromRGBA(0xCC, 0xCC, 0xFF).ToGdiColor()), rect); + } + else + { + e.Graphics.FillRectangle(new SolidBrush(Color.FromRGBA(0xCC, 0xFF, 0xCC).ToGdiColor()), rect); + } + } + } } + + public SynthesizedAudioCommand HitTest(Point pt) + { + return HitTest(pt.X, pt.Y); + } + public SynthesizedAudioCommand HitTest(int x, int y) + { + foreach (SynthesizedAudioCommand cmd in mvarCommands) + { + Rectangle rect = GetCommandRect(cmd); + if (rect.Contains(x, y)) return cmd; + } + return null; + } + + private Rectangle GetKeyboardRect() + { + Rectangle keyboardRect = ClientRectangle; + keyboardRect.Width = mvarKeyboardWidth; + return keyboardRect; + } + private Rectangle GetGridRect() + { + Rectangle gridRect = ClientRectangle; + if (mvarShowKeyboard) + { + Rectangle keyboardRect = GetKeyboardRect(); + gridRect.X += keyboardRect.Left + keyboardRect.Width; + } + return gridRect; + } + private Rectangle GetCommandRect(SynthesizedAudioCommand cmd) + { + if (cmd is SynthesizedAudioCommandNote) + { + return GetNoteRect(cmd as SynthesizedAudioCommandNote); + } + return Rectangle.Empty; + } + private Rectangle GetNoteRect(SynthesizedAudioCommandNote note) + { + Rectangle gridRect = GetGridRect(); + Point pt1 = Unquantize(new Point((int)(note.Position), FrequencyToValue(note.Frequency))); + Point pt2 = Unquantize(new Point((int)note.Length, FrequencyToValue(note.Frequency))); + return new Rectangle(gridRect.X + pt1.X + 1, gridRect.Y + pt1.Y + 1, pt2.X - 1, mvarNoteHeight - 1); + } } } diff --git a/CSharp/Engines/WindowsForms/Plugins/UniversalEditor.Plugins.Multimedia.UserInterface.WindowsForms/Editors/Multimedia/Audio/Synthesized/SynthesizedAudioEditor.Designer.cs b/CSharp/Engines/WindowsForms/Plugins/UniversalEditor.Plugins.Multimedia.UserInterface.WindowsForms/Editors/Multimedia/Audio/Synthesized/SynthesizedAudioEditor.Designer.cs index a6564588..e7af45f9 100644 --- a/CSharp/Engines/WindowsForms/Plugins/UniversalEditor.Plugins.Multimedia.UserInterface.WindowsForms/Editors/Multimedia/Audio/Synthesized/SynthesizedAudioEditor.Designer.cs +++ b/CSharp/Engines/WindowsForms/Plugins/UniversalEditor.Plugins.Multimedia.UserInterface.WindowsForms/Editors/Multimedia/Audio/Synthesized/SynthesizedAudioEditor.Designer.cs @@ -52,6 +52,7 @@ this.renameToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItem4 = new System.Windows.Forms.ToolStripSeparator(); this.propertiesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); this.splitContainer1.Panel1.SuspendLayout(); this.splitContainer1.Panel2.SuspendLayout(); this.splitContainer1.SuspendLayout(); @@ -100,12 +101,14 @@ this.pnlPianoRoll.BackColor = System.Drawing.SystemColors.Window; this.pnlPianoRoll.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this.pnlPianoRoll.Dock = System.Windows.Forms.DockStyle.Fill; - this.pnlPianoRoll.GridSize = new System.Drawing.Size(128, 16); + this.pnlPianoRoll.KeyboardWidth = 64; this.pnlPianoRoll.Location = new System.Drawing.Point(0, 0); this.pnlPianoRoll.Name = "pnlPianoRoll"; this.pnlPianoRoll.QuantizationSize = new System.Drawing.Size(16, 16); + this.pnlPianoRoll.ShowKeyboard = true; this.pnlPianoRoll.Size = new System.Drawing.Size(417, 375); this.pnlPianoRoll.TabIndex = 0; + this.pnlPianoRoll.ZoomFactor = 1D; // // mnuContextTreeView // @@ -122,7 +125,7 @@ this.toolStripMenuItem4, this.propertiesToolStripMenuItem}); this.mnuContextTreeView.Name = "mnuContextTreeView"; - this.mnuContextTreeView.Size = new System.Drawing.Size(194, 220); + this.mnuContextTreeView.Size = new System.Drawing.Size(194, 198); // // addToolStripMenuItem // @@ -246,6 +249,7 @@ this.Size = new System.Drawing.Size(631, 375); this.splitContainer1.Panel1.ResumeLayout(false); this.splitContainer1.Panel2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); this.splitContainer1.ResumeLayout(false); this.pnlTrackEditor.ResumeLayout(false); this.mnuContextTreeView.ResumeLayout(false); diff --git a/CSharp/Engines/WindowsForms/Plugins/UniversalEditor.Plugins.Multimedia.UserInterface.WindowsForms/Editors/Multimedia/Audio/Synthesized/SynthesizedAudioEditor.resx b/CSharp/Engines/WindowsForms/Plugins/UniversalEditor.Plugins.Multimedia.UserInterface.WindowsForms/Editors/Multimedia/Audio/Synthesized/SynthesizedAudioEditor.resx index 81998adf..ba4e9384 100644 --- a/CSharp/Engines/WindowsForms/Plugins/UniversalEditor.Plugins.Multimedia.UserInterface.WindowsForms/Editors/Multimedia/Audio/Synthesized/SynthesizedAudioEditor.resx +++ b/CSharp/Engines/WindowsForms/Plugins/UniversalEditor.Plugins.Multimedia.UserInterface.WindowsForms/Editors/Multimedia/Audio/Synthesized/SynthesizedAudioEditor.resx @@ -112,12 +112,15 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - 17, 17 + + 7, 8 + + + 38 \ No newline at end of file diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Multimedia/Color.cs b/CSharp/Plugins/UniversalEditor.Plugins.Multimedia/Color.cs index 96a1fa4b..6461baa5 100644 --- a/CSharp/Plugins/UniversalEditor.Plugins.Multimedia/Color.cs +++ b/CSharp/Plugins/UniversalEditor.Plugins.Multimedia/Color.cs @@ -136,8 +136,16 @@ namespace UniversalEditor public static Color LightGoldenrodYellow { get { return m_LightGoldenrodYellow; } } private static Color m_LightGray = Color.FromRGBA(211, 211, 211); public static Color LightGray { get { return m_LightGray; } } + private static Color m_Silver = Color.FromRGBA(192, 192, 192); public static Color Silver { get { return m_Silver; } } + + private static Color m_GhostWhite = Color.FromRGBA(0xF8, 0xF8, 0xFF); + public static Color GhostWhite { get { return m_GhostWhite; } } + + private static Color m_Gainsboro = Color.FromRGBA(0xDC, 0xDC, 0xDC); + public static Color Gainsboro { get { return m_Gainsboro; } } + private static Color m_DarkGray = Color.FromRGBA(128, 128, 128); public static Color DarkGray { get { return m_DarkGray; } } }