diff --git a/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Synthesized/SynthesizedAudioEditor.Designer.cs b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Synthesized/SynthesizedAudioEditor.Designer.cs index 4024e682..347fa02f 100644 --- a/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Synthesized/SynthesizedAudioEditor.Designer.cs +++ b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Synthesized/SynthesizedAudioEditor.Designer.cs @@ -70,7 +70,7 @@ namespace UniversalEditor.Editors.Multimedia.Audio.Synthesized } } - private Views.PianoRoll.PianoRollView PianoRoll = null; + public Views.PianoRoll.PianoRollView PianoRoll = null; private Views.MIDIEvents.MIDIEventsView MIDIEvents = null; /// diff --git a/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Synthesized/SynthesizedAudioEditorSelection.cs b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Synthesized/SynthesizedAudioEditorSelection.cs index 8fa795ca..517df8ee 100644 --- a/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Synthesized/SynthesizedAudioEditorSelection.cs +++ b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Synthesized/SynthesizedAudioEditorSelection.cs @@ -19,6 +19,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using MBS.Framework.Drawing; +using UniversalEditor.Editors.Multimedia.Audio.Synthesized.Views.PianoRoll; using UniversalEditor.ObjectModels.Multimedia.Audio.Synthesized; using UniversalEditor.UserInterface; @@ -37,12 +39,16 @@ namespace UniversalEditor.Editors.Multimedia.Audio.Synthesized protected override void DeleteInternal() { - (_parent.Parent.Parent as Editor).BeginEdit(); + (_parent.Parent as Editor).BeginEdit(); for (int i = 0; i < Commands.Count; i++) { - (_parent.Parent.Parent as SynthesizedAudioEditor).SelectedTrack.Commands.Remove(Commands[i]); + SynthesizedAudioCommand cmd = Commands[i]; + Rectangle bounds = (_parent.Parent as SynthesizedAudioEditor).PianoRoll.GetCommandBounds(cmd); + + (_parent.Parent as SynthesizedAudioEditor).SelectedTrack.Commands.Remove(cmd); + (_parent.Parent as SynthesizedAudioEditor).PianoRoll.OnNoteDeleted(new NoteEventArgs(cmd, bounds)); } - (_parent.Parent.Parent as Editor).EndEdit(); + (_parent.Parent as Editor).EndEdit(); } } } diff --git a/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Synthesized/Views/PianoRoll/NoteEvent.cs b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Synthesized/Views/PianoRoll/NoteEvent.cs new file mode 100644 index 00000000..bc6cf5c8 --- /dev/null +++ b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Synthesized/Views/PianoRoll/NoteEvent.cs @@ -0,0 +1,39 @@ +// +// PianoRollView.cs - provides a UWT-based View for manipulating SynthesizedAudioCommands in a piano roll style +// +// Author: +// Michael Becker +// +// Copyright (c) 2019-2020 Mike Becker's Software +// +// 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 . + +using System; +using MBS.Framework.Drawing; +using UniversalEditor.ObjectModels.Multimedia.Audio.Synthesized; + +namespace UniversalEditor.Editors.Multimedia.Audio.Synthesized.Views.PianoRoll +{ + public class NoteEventArgs : EventArgs + { + public SynthesizedAudioCommand Note { get; private set; } + public Rectangle Bounds { get; private set; } + + public NoteEventArgs(SynthesizedAudioCommand note, Rectangle bounds) + { + this.Note = note; + this.Bounds = bounds; + } + } +} \ No newline at end of file diff --git a/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Synthesized/Views/PianoRoll/NoteRenderedEvent.cs b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Synthesized/Views/PianoRoll/NoteRenderedEvent.cs new file mode 100644 index 00000000..f1f54980 --- /dev/null +++ b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Synthesized/Views/PianoRoll/NoteRenderedEvent.cs @@ -0,0 +1,48 @@ +// +// NoteRenderedEvent.cs - +// +// Author: +// Michael Becker +// +// Copyright (c) 2019-2020 Mike Becker's Software +// +// 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 . + +using System; +using MBS.Framework.Drawing; +using MBS.Framework.UserInterface.Drawing; +using UniversalEditor.ObjectModels.Multimedia.Audio.Synthesized; + +namespace UniversalEditor.Editors.Multimedia.Audio.Synthesized.Views.PianoRoll +{ + public class NoteRenderedEventArgs : EventArgs + { + public Graphics Graphics { get; private set; } + public Rectangle Bounds { get; private set; } + public SynthesizedAudioCommandNote Note { get; private set; } + public bool Selected { get; private set; } + public bool Editing { get; private set; } + public bool Overlaps { get; private set; } + + public NoteRenderedEventArgs(Graphics graphics, Rectangle rect, SynthesizedAudioCommandNote note, bool selected, bool editing, bool overlaps) + { + Graphics = graphics; + Bounds = rect; + Note = note; + Selected = selected; + Editing = editing; + Overlaps = overlaps; + } + } +} \ No newline at end of file diff --git a/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Synthesized/Views/PianoRoll/PianoRollView.cs b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Synthesized/Views/PianoRoll/PianoRollView.cs index f3ce0fb8..e14019c8 100644 --- a/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Synthesized/Views/PianoRoll/PianoRollView.cs +++ b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/Editors/Multimedia/Audio/Synthesized/Views/PianoRoll/PianoRollView.cs @@ -44,7 +44,7 @@ namespace UniversalEditor.Editors.Multimedia.Audio.Synthesized.Views.PianoRoll { private class _VP : CustomControl { - private TextBox txt = null; + public TextBox txt = null; private SynthesizedAudioCommandNote _EditingNote = null; private const double MAXSCROLLHEIGHT = 4096; @@ -167,7 +167,7 @@ namespace UniversalEditor.Editors.Multimedia.Audio.Synthesized.Views.PianoRoll switch (e.Key) { - case KeyboardKey.Tab: + case KeyboardKey.Tab: { if (SelectedCommands.Count > 0) { @@ -666,6 +666,8 @@ namespace UniversalEditor.Editors.Multimedia.Audio.Synthesized.Views.PianoRoll SynthesizedAudioCommandNote note2 = note.Clone() as SynthesizedAudioCommandNote; ApplyNoteRect(ref note2, v); ((Parent as PianoRollView).Parent as SynthesizedAudioEditor).SelectedTrack.Commands.Add(note2); + + (Parent as PianoRollView).OnNoteInserted(new NoteEventArgs(note2, GetNoteRect(note2))); } else { @@ -700,6 +702,7 @@ namespace UniversalEditor.Editors.Multimedia.Audio.Synthesized.Views.PianoRoll note.Frequency = ValueToFrequency((int)drag_OriginalLocation.Y); ((Parent as PianoRollView).Parent as SynthesizedAudioEditor).SelectedTrack.Commands.Add(note); + (Parent as PianoRollView).OnNoteInserted(new NoteEventArgs(note, GetNoteRect(note))); mvarSelectedCommands.Clear(); mvarSelectedCommands.Add(note); @@ -839,7 +842,7 @@ namespace UniversalEditor.Editors.Multimedia.Audio.Synthesized.Views.PianoRoll } return gridRect; } - private Rectangle GetCommandRect(SynthesizedAudioCommand cmd) + public Rectangle GetCommandRect(SynthesizedAudioCommand cmd) { if (cmd is SynthesizedAudioCommandNote) { @@ -979,7 +982,7 @@ namespace UniversalEditor.Editors.Multimedia.Audio.Synthesized.Views.PianoRoll bool overlaps = false; if (HighlightOverlappingNotes) overlaps = NoteOverlaps(note); - DrawNote(e.Graphics, rect, note.Lyric, note.Phoneme, mvarSelectedCommands.Contains(cmd), _EditingNote == note, overlaps); + (Parent as PianoRollView).DrawNote(e.Graphics, rect, note, mvarSelectedCommands.Contains(cmd), _EditingNote == note, overlaps); } } } @@ -1041,6 +1044,8 @@ namespace UniversalEditor.Editors.Multimedia.Audio.Synthesized.Views.PianoRoll e.Graphics.DrawLine(pGrid, 0, i, Size.Width, i); } */ + + (Parent as PianoRollView).OnPaint(e); } private bool NoteOverlaps(SynthesizedAudioCommandNote note) { @@ -1059,37 +1064,6 @@ namespace UniversalEditor.Editors.Multimedia.Audio.Synthesized.Views.PianoRoll return false; } - private bool DrawNote(Graphics graphics, Rectangle rect, string lyric, string phoneme, bool selected, bool editing, bool overlaps) - { - if (rect.X > HorizontalAdjustment.Value + Size.Width) - return false; // no need to continue since we've reached the end of the visible area - - Color noteColor = SystemColors.HighlightBackground.Darken(0.1); - if (overlaps) - { - noteColor = Colors.DarkGray; - } - - if (selected) - { - graphics.FillRectangle(new SolidBrush(SystemColors.HighlightBackground), rect); - } - else - { - graphics.FillRectangle(new SolidBrush(SystemColors.WindowBackground), rect); - graphics.FillRectangle(new SolidBrush(noteColor.Alpha(0.3)), rect); - } - graphics.DrawRectangle(new Pen(noteColor.Alpha(0.5)), rect); - - Rectangle textRect = new Rectangle(rect.X + 2, rect.Y + 10, rect.Width - 4, rect.Height - 2); - - if (!(txt.Visible && editing)) - { - graphics.DrawText(String.Format("{0} [ {1} ]", lyric, phoneme), Font, textRect, new SolidBrush(selected ? SystemColors.HighlightForeground : SystemColors.WindowForeground)); - } - return true; - } - private void DrawKeyboard(Graphics g) { int gridWidth = (int)(GetLengthQuantization() * mvarZoomFactor); @@ -1128,6 +1102,61 @@ namespace UniversalEditor.Editors.Multimedia.Audio.Synthesized.Views.PianoRoll public PianoRollViewSelectionMode SelectionMode { get { return vp.SelectionMode; } set { vp.SelectionMode = value; } } private _VP vp = new _VP(); + public bool DrawNote(Graphics graphics, Rectangle rect, SynthesizedAudioCommandNote note, bool selected, bool editing, bool overlaps) + { + if (rect.X > HorizontalAdjustment.Value + Size.Width) + return false; // no need to continue since we've reached the end of the visible area + + Color noteColor = SystemColors.HighlightBackground.Darken(0.1); + if (overlaps) + { + noteColor = Colors.DarkGray; + } + + if (selected) + { + graphics.FillRectangle(new SolidBrush(SystemColors.HighlightBackground), rect); + } + else + { + graphics.FillRectangle(new SolidBrush(SystemColors.WindowBackground), rect); + graphics.FillRectangle(new SolidBrush(noteColor.Alpha(0.3)), rect); + } + graphics.DrawRectangle(new Pen(noteColor.Alpha(0.5)), rect); + + Rectangle textRect = new Rectangle(rect.X + 2, rect.Y + 10, rect.Width - 4, rect.Height - 2); + + if (!(vp.txt.Visible && editing)) + { + graphics.DrawText(String.Format("{0} [ {1} ]", note.Lyric, note.Phoneme), Font, textRect, new SolidBrush(selected ? SystemColors.HighlightForeground : SystemColors.WindowForeground)); + } + + OnNoteRendered(new NoteRenderedEventArgs(graphics, rect, note, selected, editing, overlaps)); + return true; + } + + public Rectangle GetCommandBounds(SynthesizedAudioCommand command) + { + return vp.GetCommandRect(command); + } + + public event EventHandler NoteRendered; + protected virtual void OnNoteRendered(NoteRenderedEventArgs e) + { + NoteRendered?.Invoke(this, e); + } + + public event EventHandler NoteInserted; + protected virtual void OnNoteInserted(NoteEventArgs e) + { + NoteInserted?.Invoke(this, e); + } + + public event EventHandler NoteDeleted; + protected internal virtual void OnNoteDeleted(NoteEventArgs e) + { + NoteDeleted?.Invoke(this, e); + } public PianoRollView() { diff --git a/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface.csproj b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface.csproj index 872135f8..c8710329 100644 --- a/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface.csproj +++ b/Plugins.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface/UniversalEditor.Plugins.Multimedia.UserInterface.csproj @@ -57,6 +57,8 @@ + +