Porting the old SynthesizedAudioEditor from original UE-WindowsForms to UE-UWT with additional features and improvements
This commit is contained in:
parent
7c43d491de
commit
c6820038cb
@ -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>
|
||||
|
||||
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user