Porting the old SynthesizedAudioEditor from original UE-WindowsForms to UE-UWT with additional features and improvements

This commit is contained in:
Michael Becker 2019-10-07 18:44:39 -04:00
parent 7c43d491de
commit c6820038cb
6 changed files with 785 additions and 1 deletions

View File

@ -17,6 +17,7 @@
<Command ID="JobConnect" Title="_Connect Notes..." />
<Command ID="JobInsertLyrics" Title="Insert _Lyrics..." />
<Command ID="JobImportTempo" Title="Import External DAW _Tempo..." />
<Command ID="Job" Title="_Job">
<Items>
@ -29,6 +30,7 @@
<CommandReference CommandID="JobConnect" />
<Separator />
<CommandReference CommandID="JobInsertLyrics" />
<CommandReference CommandID="JobImportTempo" />
</Items>
</Command>
@ -41,6 +43,7 @@
<Command ID="TrackRenderCurrent" Title="Render Current _Track" />
<Command ID="TrackRenderAll" Title="Render All Track_s" />
<Command ID="TrackOverlay" Title="_Overlay" />
<Command ID="Track" Title="Trac_k">
<Items>
@ -53,11 +56,24 @@
<Separator />
<CommandReference CommandID="TrackRenderCurrent" />
<CommandReference CommandID="TrackRenderAll" />
<Separator />
<CommandReference CommandID="TrackOverlay" />
</Items>
</Command>
<Command ID="Part" Title="Pa_rt" />
<Command ID="Lyrics" Title="_Lyrics" />
<Command ID="LyricsNoteProperty" Title="Not_e Property..." />
<Command ID="LyricsPhonemeTransformation" Title="Phoneme _Transformation..." />
<Command ID="LyricsUserWordDictionary" Title="User Word Di_ctionary..." />
<Command ID="Lyrics" Title="_Lyrics">
<Items>
<CommandReference CommandID="LyricsNoteProperty" />
<CommandReference CommandID="LyricsPhonemeTransformation" />
<CommandReference CommandID="LyricsUserWordDictionary" />
</Items>
</Command>
<Command ID="Transport" Title="Tra_nsport" />
</Commands>
<MenuBar>

View File

@ -0,0 +1,71 @@
//
// PianoRollEditor.Designer.cs
//
// Author:
// Mike Becker <alcexhim@gmail.com>
//
// Copyright (c) 2019 Mike Becker
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using MBS.Framework.UserInterface;
using MBS.Framework.UserInterface.Controls;
using MBS.Framework.UserInterface.Layouts;
using UniversalEditor.UserInterface;
using UniversalEditor.ObjectModels.Multimedia.Audio.Synthesized;
using UniversalEditor.Editors.Multimedia.Audio.Synthesized.PianoRoll.Controls;
using UniversalEditor.ObjectModels.Markup;
namespace UniversalEditor.Editors.Multimedia.Audio.Synthesized.PianoRoll
{
partial class PianoRollEditor : Editor
{
public PianoRollEditor()
{
InitializeComponent();
}
private static EditorReference _er = null;
public override EditorReference MakeReference()
{
if (_er == null)
{
_er = base.MakeReference();
_er.SupportedObjectModels.Add(typeof(SynthesizedAudioObjectModel));
}
return _er;
}
private PianoRollView PianoRoll = null;
protected override void OnObjectModelChanged(EventArgs e)
{
base.OnObjectModelChanged(e);
}
private void InitializeComponent()
{
this.Layout = new BoxLayout(Orientation.Vertical);
PianoRoll = new PianoRollView();
this.Controls.Add(PianoRoll, new BoxLayout.Constraints(true, true));
}
}
}

View File

@ -0,0 +1,57 @@
//
// PianoRollEditor.cs
//
// Author:
// Mike Becker <alcexhim@gmail.com>
//
// Copyright (c) 2019 Mike Becker
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using UniversalEditor.UserInterface;
namespace UniversalEditor.Editors.Multimedia.Audio.Synthesized.PianoRoll
{
public partial class PianoRollEditor
{
public override void UpdateSelections()
{
throw new NotImplementedException();
}
protected override EditorSelection CreateSelectionInternal(object content)
{
throw new NotImplementedException();
}
protected override void OnToolboxItemSelected(ToolboxItemEventArgs e)
{
base.OnToolboxItemSelected(e);
switch (e.Item.Name)
{
case "ToolboxItem_Select":
{
this.PianoRoll.SelectionMode = PianoRollSelectionMode.Select;
break;
}
case "ToolboxItem_Insert":
{
this.PianoRoll.SelectionMode = PianoRollSelectionMode.Insert;
break;
}
}
}
}
}

View File

@ -0,0 +1,30 @@
//
// PianoRollSelectionMode.cs
//
// Author:
// Mike Becker <alcexhim@gmail.com>
//
// Copyright (c) 2019 Mike Becker
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
namespace UniversalEditor.Editors.Multimedia.Audio.Synthesized.PianoRoll
{
public enum PianoRollSelectionMode
{
Select,
Insert,
Delete
}
}

View File

@ -0,0 +1,602 @@
//
// PianoRollControl.cs
//
// Author:
// Mike Becker <alcexhim@gmail.com>
//
// Copyright (c) 2019 Mike Becker
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
using MBS.Framework.Drawing;
using MBS.Framework.UserInterface;
using MBS.Framework.UserInterface.Drawing;
using MBS.Framework.UserInterface.Input.Keyboard;
using MBS.Framework.UserInterface.Input.Mouse;
using UniversalEditor.ObjectModels.Multimedia.Audio.Synthesized;
namespace UniversalEditor.Editors.Multimedia.Audio.Synthesized.PianoRoll.Controls
{
public class PianoRollView : /*View*/ CustomControl
{
private Menu contextMenu = null;
public PianoRollView()
{
this.contextMenu = new Menu();
this.contextMenu.Items.AddRange(new MenuItem[]
{
new CommandMenuItem("_Arrow", null, ContextMenuArrow_Click),
new CommandMenuItem("Dra_w", null, ContextMenuPencil_Click),
new CommandMenuItem("_Erase", null, ContextMenuErase_Click),
new SeparatorMenuItem(),
new CommandMenuItem("_Note Fixed Length", new MenuItem[] // disables drawing note length, forcing to specified length
{
new CommandMenuItem("ContextMenu_NoteFixedLength_1", "1/1 [1920]", null, ContextMenu_NoteFixedLength_Click),
new CommandMenuItem("ContextMenu_NoteFixedLength_2", "1/2 [960]", null, ContextMenu_NoteFixedLength_Click),
new CommandMenuItem("ContextMenu_NoteFixedLength_4", "1/4 [480]", null, ContextMenu_NoteFixedLength_Click),
new CommandMenuItem("ContextMenu_NoteFixedLength_8", "1/8 [240]", null, ContextMenu_NoteFixedLength_Click),
new CommandMenuItem("ContextMenu_NoteFixedLength_16", "1/16 [120]", null, ContextMenu_NoteFixedLength_Click),
new CommandMenuItem("ContextMenu_NoteFixedLength_32", "1/32 [60]", null, ContextMenu_NoteFixedLength_Click),
new CommandMenuItem("ContextMenu_NoteFixedLength_64", "1/64 [30]", null, ContextMenu_NoteFixedLength_Click),
new CommandMenuItem("ContextMenu_NoteFixedLength_Off", "Off", null, ContextMenu_NoteFixedLength_Click),
new SeparatorMenuItem(),
new CommandMenuItem("Triplet"),
new CommandMenuItem("Dot")
}),
new CommandMenuItem("_Quantize", new MenuItem[] // controls the quantize of position when drawing a new note
{
new CommandMenuItem("1/4"),
new CommandMenuItem("1/8"),
new CommandMenuItem("1/16"),
new CommandMenuItem("1/32"), // default
new CommandMenuItem("1/64"),
new CommandMenuItem("Off"),
new SeparatorMenuItem(),
new CommandMenuItem("Triplet")
}),
new CommandMenuItem("_Length", new MenuItem[] // controls the quantize of length when drawing a new note
{
new CommandMenuItem("1/4"),
new CommandMenuItem("1/8"),
new CommandMenuItem("1/16"),
new CommandMenuItem("1/32"), // default
new CommandMenuItem("1/64"),
new CommandMenuItem("Off"),
new SeparatorMenuItem(),
new CommandMenuItem("Triplet")
}),
new CommandMenuItem("_Show Grid Lines", null, ContextMenuToggleGridLines_Click), // toggles grid lines for quantized positions
new SeparatorMenuItem(),
new CommandMenuItem("_Undo"), // should be CommandReferenceCommandItem for EditUndo application-global command
new CommandMenuItem("Cu_t"),
new CommandMenuItem("_Copy"),
new CommandMenuItem("_Paste"),
new CommandMenuItem("_Delete"),
new SeparatorMenuItem(),
new CommandMenuItem("Select _All"),
new CommandMenuItem("Select All _Events"),
new SeparatorMenuItem(),
new CommandMenuItem("Insert _Lyrics..."),
new SeparatorMenuItem(),
new CommandMenuItem("_Properties...") // displays Note Property dialog
});
this.ContextMenu = contextMenu;
}
/// <summary>
/// When greater than -1, specifies the note length at which all newly-created notes are set and prevents dragging to specify note length.
/// </summary>
/// <value>The length of a newly-created note.</value>
public int FixedNoteLength { get; set; } = -1;
private int _PositionQuantization = -1;
public int PositionQuantization
{
get { return _PositionQuantization; }
set
{
_PositionQuantization = value;
Refresh();
}
}
private void ContextMenu_NoteFixedLength_Click(object sender, EventArgs e)
{
MenuItem mi = (sender as MenuItem);
string sValue = mi.Name.Substring("ContextMenu_NoteFixedLength_".Length);
int iValue = -1;
if (sValue != "Off")
{
iValue = Int32.Parse(sValue);
}
}
protected override void OnBeforeContextMenu(EventArgs e)
{
base.OnBeforeContextMenu(e);
contextMenu.Items[10].Visible = (SelectedCommands.Count > 0);
contextMenu.Items[11].Visible = (SelectedCommands.Count > 0);
contextMenu.Items[12].Visible = (SelectedCommands.Count > 0);
contextMenu.Items[13].Visible = (SelectedCommands.Count > 0);
}
private void ContextMenuArrow_Click(object sender, EventArgs e)
{
SelectionMode = PianoRollSelectionMode.Select;
}
private void ContextMenuPencil_Click(object sender, EventArgs e)
{
SelectionMode = PianoRollSelectionMode.Insert;
}
private void ContextMenuErase_Click(object sender, EventArgs e)
{
SelectionMode = PianoRollSelectionMode.Delete;
}
private void ContextMenuToggleGridLines_Click(object sender, EventArgs e)
{
ShowGridLines = !ShowGridLines;
}
private bool _ShowGridLines = false;
public bool ShowGridLines { get { return _ShowGridLines; } set { _ShowGridLines = value; Refresh(); } }
private PianoRollSelectionMode _SelectionMode;
public PianoRollSelectionMode SelectionMode
{
get { return _SelectionMode; }
set
{
_SelectionMode = value;
switch (_SelectionMode)
{
case PianoRollSelectionMode.Insert:
{
Cursor = Cursors.Pencil;
break;
}
case PianoRollSelectionMode.Select:
{
Cursor = Cursors.Default;
break;
}
case PianoRollSelectionMode.Delete:
{
Cursor = Cursors.Eraser;
break;
}
}
}
}
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; } }
public SynthesizedAudioCommand HitTest(Vector2D pt)
{
return HitTest((int)pt.X, (int)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;
}
public SynthesizedAudioCommand[] HitTest(Rectangle rect)
{
List<SynthesizedAudioCommand> list = new List<SynthesizedAudioCommand>();
foreach (SynthesizedAudioCommand cmd in mvarCommands)
{
Rectangle rect1 = GetCommandRect(cmd);
if (rect.Normalize().IntersectsWith(rect1)) list.Add(cmd);
}
return list.ToArray();
}
private SynthesizedAudioTrack _SelectedTrack = null;
public SynthesizedAudioTrack SelectedTrack
{
get { return _SelectedTrack; }
set { _SelectedTrack = value; Refresh(); }
}
public int GridSize { get; set; } = 4;
public Dimension2D NoteSize { get; set; } = new Dimension2D(12, 16);
private Pen pGrid = new Pen(Colors.LightGray);
private Pen pGridAlt = new Pen(Colors.Gray);
private Pen pSelectionBorder = new Pen(Colors.SteelBlue);
private SolidBrush bSelectionFill = new SolidBrush(Color.FromRGBADouble(Colors.SteelBlue.R, Colors.SteelBlue.G, Colors.SteelBlue.B, 0.5));
private Pen pSelectionBorderDrawing = new Pen(Colors.DarkGray);
private SolidBrush bSelectionFillDrawing = new SolidBrush(Color.FromRGBADouble(Colors.DarkGray.R, Colors.DarkGray.G, Colors.DarkGray.B, 0.5));
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 Dimension2D mvarQuantizationSize = new Dimension2D(16, 16);
public Dimension2D QuantizationSize { get { return mvarQuantizationSize; } set { mvarQuantizationSize = value; Invalidate(); } }
private bool m_selecting = false;
private double cx = 0, cy = 0;
private double dx = 0, dy = 0;
private Vector2D drag_OriginalLocation = new Vector2D(0, 0);
private Vector2D drag_CurrentLocation = new Vector2D(0, 0);
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
SynthesizedAudioCommand cmd = HitTest(e.Location);
if ((e.ModifierKeys == KeyboardModifierKey.None && e.Buttons == MouseButtons.Primary) || cmd == null)
{
mvarSelectedCommands.Clear();
}
if (cmd != null)
{
bool remove = false;
if (e.ModifierKeys == KeyboardModifierKey.Shift)
{
if (mvarSelectedCommands.Count > 0)
{
int startIndex = mvarCommands.IndexOf(mvarSelectedCommands[mvarSelectedCommands.Count - 1]);
int endIndex = mvarCommands.IndexOf(cmd);
mvarSelectedCommands.Clear();
for (int i = startIndex; i < endIndex; i++)
{
mvarSelectedCommands.Add(mvarCommands[i]);
}
}
}
else if (e.ModifierKeys == KeyboardModifierKey.Control)
{
remove = mvarSelectedCommands.Contains(cmd);
}
if (remove)
{
mvarSelectedCommands.Remove(cmd);
}
else
{
mvarSelectedCommands.Add(cmd);
}
}
if (e.Buttons == MouseButtons.Primary)
{
if (mvarShowKeyboard && e.X < mvarKeyboardWidth)
{
return;
}
cx = e.X;
cy = e.Y;
dx = e.X;
dy = e.Y;
m_selecting = true;
drag_OriginalLocation = Quantize(new Vector2D(cx, cy));
drag_CurrentLocation = drag_OriginalLocation;
}
Refresh();
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
SynthesizedAudioCommand cmd = HitTest(e.Location);
if (ShowKeyboard && e.X < KeyboardWidth || cmd != null)
{
Cursor = Cursors.Default;
}
else if (SelectionMode == PianoRollSelectionMode.Insert)
{
Cursor = Cursors.Pencil;
}
if (e.Buttons == MouseButtons.Primary)
{
dx = e.X;
dy = e.Y;
if (ShowKeyboard && dx < KeyboardWidth)
dx = KeyboardWidth;
if (SelectionMode == PianoRollSelectionMode.Select || SelectionMode == PianoRollSelectionMode.Insert)
{
drag_CurrentLocation = Quantize(new Vector2D(dx, drag_OriginalLocation.Y));
if (SelectionMode == PianoRollSelectionMode.Select)
{
Rectangle rectSelection = new Rectangle(cx, cy, dx - cx, dy - cy);
SynthesizedAudioCommand[] cmds = HitTest(rectSelection);
mvarSelectedCommands.Clear();
foreach (SynthesizedAudioCommand cmd1 in cmds)
{
mvarSelectedCommands.Add(cmd1);
}
}
Refresh();
}
}
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
if (e.Buttons == MouseButtons.Primary)
{
if (SelectionMode == PianoRollSelectionMode.Insert)
{
if (drag_CurrentLocation.X - drag_OriginalLocation.X > 0)
{
SynthesizedAudioCommandNote note = new SynthesizedAudioCommandNote();
note.Position = (int)drag_OriginalLocation.X;
note.Length = (drag_CurrentLocation.X - drag_OriginalLocation.X);
note.Frequency = ValueToFrequency((int)drag_OriginalLocation.Y);
mvarCommands.Add(note);
mvarSelectedCommands.Clear();
mvarSelectedCommands.Add(note);
}
}
m_selecting = false;
Refresh();
}
}
protected override void OnMouseDoubleClick(MouseEventArgs e)
{
base.OnMouseDoubleClick(e);
if (e.Buttons == MouseButtons.Primary)
{
SynthesizedAudioCommand cmd = HitTest(e.Location);
if (cmd is SynthesizedAudioCommandNote)
{
SynthesizedAudioCommandNote note = (cmd as SynthesizedAudioCommandNote);
Rectangle rect = GetNoteRect(note);
/*
txtLyric.Location = rect.Location;
txtLyric.Size = rect.Size;
txtLyric.Text = note.Lyric;
txtLyric.Enabled = true;
txtLyric.Visible = true;
txtLyric.Focus();
*/
}
}
}
int[] noteValuesBlackKeys = new int[] { 1, 3, 5, 8, 10 };
private Vector2D Quantize(Vector2D pt)
{
if (mvarShowKeyboard)
pt.X -= mvarKeyboardWidth;
int qX = (int)((double)(pt.X / mvarQuarterNoteWidth));
int qY = (int)((double)((pt.Y / mvarNoteHeight)));
return new Vector2D(qX, qY);
}
private Vector2D Unquantize(Vector2D pt)
{
int uqX = (int)(pt.X * mvarQuarterNoteWidth);
int uqY = (int)(pt.Y * mvarNoteHeight);
return new Vector2D(uqX, uqY);
}
private Rectangle GetKeyboardRect()
{
Rectangle keyboardRect = new Rectangle(0, 0, Size.Width, Size.Height); // ClientRectangle
keyboardRect.Width = mvarKeyboardWidth;
return keyboardRect;
}
private Rectangle GetGridRect()
{
Rectangle gridRect = new Rectangle(0, 0, Size.Width, Size.Height); // ClientRectangle;
if (mvarShowKeyboard)
{
Rectangle keyboardRect = GetKeyboardRect();
gridRect.X += keyboardRect.X + 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();
Vector2D pt1 = Unquantize(new Vector2D((int)(note.Position), FrequencyToValue(note.Frequency)));
Vector2D pt2 = Unquantize(new Vector2D((int)note.Length, FrequencyToValue(note.Frequency)));
return new Rectangle(gridRect.X + pt1.X + 1, gridRect.Y + pt1.Y + 1, pt2.X - 1, mvarNoteHeight - 1);
}
private double ValueToFrequency(int value)
{
return value;
}
private int FrequencyToValue(double frequency)
{
return (int)frequency;
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
int gridWidth = (int)(mvarQuarterNoteWidth * mvarZoomFactor);
int gridHeight = (int)(mvarNoteHeight * mvarZoomFactor);
Rectangle gridRect = GetGridRect();
if (mvarShowKeyboard)
{
DrawKeyboard(e.Graphics);
}
Pen gridPen = new Pen(Colors.LightGray);
for (int i = 0; i < Size.Height; i += gridHeight)
{
int noteValue = (int)(((double)i / gridHeight) % 12) + 1;
if (Array.IndexOf<int>(noteValuesBlackKeys, noteValue) != -1)
{
e.Graphics.FillRectangle(new SolidBrush(Color.FromRGBAByte(0xDD, 0xDD, 0xDD)), new Rectangle(gridRect.X, gridRect.Y + i, gridRect.Width, gridHeight));
}
gridPen.Color = Colors.LightGray;
e.Graphics.DrawLine(gridPen, gridRect.X, gridRect.Y + i, gridRect.Right, gridRect.Y + i);
string[] noteNames = new string[]
{
"A#", "A", "G#", "G", "F#", "F", "E", "D#", "D", "C#", "C", "B"
};
if ((noteValue - 1) >= 0 && (noteValue - 1) < noteNames.Length)
{
string noteName = noteNames[noteValue - 1];
if (noteName.EndsWith("#")) continue;
if (!noteName.Equals("C")) continue;
e.Graphics.DrawText(noteName, Font, new Vector2D(mvarKeyboardWidth - 24, i + 1), new SolidBrush(noteName.Equals("C") ? Colors.DarkGray : Colors.LightGray));
}
e.Graphics.DrawText(noteValue.ToString(), Font, new Vector2D(0, i), new SolidBrush(Colors.Red));
}
for (int i = 0; i < Size.Width; i += (ShowGridLines ? (gridWidth / 2) : gridWidth))
{
if ((i % (mvarQuarterNoteWidth * 4)) == 0)
{
gridPen.Color = Colors.DarkGray;
}
else
{
gridPen.Color = Colors.LightGray;
}
e.Graphics.DrawLine(gridPen, gridRect.X + i, gridRect.Y, gridRect.X + i, gridRect.Bottom);
}
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.FromRGBAByte(0xCC, 0xCC, 0xFF)), rect);
}
else
{
e.Graphics.FillRectangle(new SolidBrush(Color.FromRGBAByte(0xCC, 0xFF, 0xCC)), rect);
}
e.Graphics.DrawRectangle(new Pen(Colors.DarkGray), rect);
Rectangle textRect = new Rectangle(rect.X + 2, rect.Y + 1, rect.Width - 4, rect.Height - 2);
e.Graphics.DrawText(note.Lyric, Font, textRect, new SolidBrush(Colors.Black));
}
}
if (m_selecting)
{
if (SelectionMode == PianoRollSelectionMode.Select)
{
e.Graphics.DrawRectangle(pSelectionBorder, new Rectangle(cx, cy, dx - cx, dy - cy));
e.Graphics.FillRectangle(bSelectionFill, new Rectangle(cx, cy, dx - cx, dy - cy));
}
else if (SelectionMode == PianoRollSelectionMode.Insert)
{
Rectangle dragrect = new Rectangle(drag_OriginalLocation.X * mvarQuarterNoteWidth, drag_OriginalLocation.Y * mvarNoteHeight, (drag_CurrentLocation.X * mvarQuarterNoteWidth) - (drag_OriginalLocation.X * mvarQuarterNoteWidth), mvarNoteHeight);
if (mvarShowKeyboard)
{
dragrect.X += mvarKeyboardWidth;
}
e.Graphics.DrawRectangle(pSelectionBorderDrawing, dragrect);
e.Graphics.FillRectangle(bSelectionFillDrawing, dragrect);
}
}
/*
// draw grids
for (int i = 0; i < Size.Width; i += (int) NoteSize.Width)
{
if (!ShowGridLines && (i % (int)(8 * NoteSize.Width) != 0))
continue;
e.Graphics.DrawLine(((i % (int)(8 * NoteSize.Width)) == 0) ? pGridAlt : pGrid, i, 0, i, Size.Height);
}
for (int i = 0; i < Size.Height; i += (int)NoteSize.Height)
{
e.Graphics.DrawLine(pGrid, 0, i, Size.Width, i);
}
*/
}
private void DrawKeyboard(Graphics g)
{
int gridWidth = (int)(mvarQuarterNoteWidth * mvarZoomFactor);
int gridHeight = (int)(mvarNoteHeight * mvarZoomFactor);
Rectangle keyboardRect = GetKeyboardRect();
for (int i = 0; i < keyboardRect.Height; i += gridHeight)
{
int noteValue = (int)(((double)i / gridHeight) % 12) + 1;
g.DrawLine(new Pen(Colors.LightGray), keyboardRect.X, i, keyboardRect.Right, i);
if (Array.IndexOf<int>(noteValuesBlackKeys, noteValue) != -1)
{
// has a black key
g.FillRectangle(new SolidBrush(Colors.DarkGray), keyboardRect.X, i, (int)((double)keyboardRect.Width / 2), gridHeight);
}
}
}
private int QuantizeHeight(int cy)
{
return (int)((double)cy / mvarNoteHeight);
}
private int QuantizeWidth(int cy)
{
return (int)((double)cy / mvarQuarterNoteWidth);
}
}
}

View File

@ -34,6 +34,10 @@
<Compile Include="Editors\Multimedia\Picture\PictureEditor.Designer.cs" />
<Compile Include="Controls\DrawingArea\DrawingAreaControl.cs" />
<Compile Include="SettingsProviders\SingingStyleDefaultsSettingsProvider.cs" />
<Compile Include="Editors\Multimedia\Audio\Synthesized\PianoRoll\PianoRollEditor.cs" />
<Compile Include="Editors\Multimedia\Audio\Synthesized\PianoRoll\PianoRollEditor.Designer.cs" />
<Compile Include="Editors\Multimedia\Audio\Synthesized\PianoRoll\Views\PianoRollView.cs" />
<Compile Include="Editors\Multimedia\Audio\Synthesized\PianoRoll\PianoRollSelectionMode.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="Editors\" />
@ -42,6 +46,10 @@
<Folder Include="Controls\" />
<Folder Include="Controls\DrawingArea\" />
<Folder Include="SettingsProviders\" />
<Folder Include="Editors\Multimedia\Audio\" />
<Folder Include="Editors\Multimedia\Audio\Synthesized\" />
<Folder Include="Editors\Multimedia\Audio\Synthesized\PianoRoll\" />
<Folder Include="Editors\Multimedia\Audio\Synthesized\PianoRoll\Views\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Libraries\UniversalEditor.Core\UniversalEditor.Core.csproj">