/// <summary> /// Called when a mouse button is pressed /// </summary> protected override void OnMouseDown(MouseEventArgs e) { base.OnMouseDown(e); MusicNote note; int x = e.X, y = e.Y + VerticalScroll.Value; for (int i = 0; i < Notes.Count; ++i) { note = Notes[i]; if (note.Bounds.Contains(x, y)) { if ((Control.ModifierKeys & Keys.Control) == Keys.Control) { Notes.RemoveAt(i); //if ctrl is pressed remove the note Invalidate(false); } else //else pass the event to the note { inputNote = note; note.MarkMouseDown(new MouseEventArgs(e.Button, e.Clicks, x - note.Bounds.X, y - note.Bounds.Y, e.Delta)); } break; } } }
/// <summary> /// Stops the length adjustment of the specified note /// </summary> /// <param name="note">The note whose length to stop adjusting</param> public void StopAdjustingNote(MusicNote note) { if (note != null) { noteLengthCandidates.Remove(note); } }
/// <summary> /// Called when a mouse button is released /// </summary> protected override void OnMouseUp(MouseEventArgs e) { base.OnMouseUp(e); if (inputNote != null) { inputNote.MarkMouseUp(new MouseEventArgs(e.Button, e.Clicks, e.X - inputNote.Bounds.X, e.Y + VerticalScroll.Value - inputNote.Bounds.Y, e.Delta)); inputNote = null; } }
/// <summary> /// Adds the specified note at the end of the staff /// </summary> /// <param name="pitch">The pitch of the note</param> /// <param name="lengthInMillisecs">The length of the note in milliseconds</param> public MusicNote AddNote(NoteEnum pitch, float lengthInMillisecs) { MusicNote note = new MusicNote(this, Keyboard, pitch, lengthInMillisecs, nextNoteLoc); Notes.Add(note); UpdateNextLoc(note.Bounds.Width, true, true); Invalidate(note.Bounds, false); return(note); }
/// <summary> /// Starts the timer for note length adjustment /// </summary> /// <param name="note">The note whose length to start adjusting</param> /// <param name="stopwatch">The stopwatch to measure with</param> public void StartAdjustingNote(MusicNote note, Stopwatch stopwatch) { if (note == null) { return; } else if (!noteLengthCandidates.ContainsKey(note)) { noteLengthCandidates.Add(note, stopwatch); } Timer.Interval = MinimumTimerInterval; Timer.Enabled = true; }
/// <summary> /// Called when the timer has elapsed /// </summary> private void Timer_Tick(object sender, EventArgs e) { if (noteLengthCandidates.Count != 0) //if has notes whose lengths are being adjusted live { foreach (KeyValuePair <MusicNote, Stopwatch> pair in noteLengthCandidates) { pair.Key.Length = ToNoteLength(pair.Value.ElapsedMilliseconds); } } if (isPlaying) //if sequential note playback is running { if (playerNoteIndex < Notes.Count) { MusicNote currentNote = Notes[playerNoteIndex]; if (currentNoteLength.ElapsedMilliseconds >= currentNote.LengthInMilliseconds) //if current note is finished { if (playerNoteIndex < Notes.Count) //stop old note { Keyboard.MarkKeyReleased(currentNote.Pitch); currentNote.Highlighted = false; } playerNoteIndex++; if (playerNoteIndex < Notes.Count) { //play new note currentNote = Notes[playerNoteIndex]; Timer.Interval = Math.Max((int)currentNote.LengthInMilliseconds, MinimumTimerInterval); Keyboard.MarkKeyPressed(currentNote.Pitch, false); currentNoteLength.Restart(); currentNote.Highlighted = true; } else { StopPlayingNotes(); //arrived to the end of the notes } } } else { StopPlayingNotes(); } } if (!isPlaying && noteLengthCandidates.Count == 0) { Timer.Enabled = false; //nothing left to do } }
/// <summary> /// Called when a mouse button is released on the piano keyboard /// </summary> protected override void OnMouseUp(MouseEventArgs e) { base.OnMouseUp(e); if (e.Button == MouseButtons.Left) { leftMouseDown = false; if (lastMouseNote != NoteEnum.None) { MidiPlayer.StopNote(lastMouseNote); Staff.StopAdjustingNote(currentMouseNote); currentMouseNote = null; Invalidate(GetNoteArea(lastMouseNote), false); pressedNotes.Remove(lastMouseNote); lastMouseNote = NoteEnum.None; } } SilenceStopwatch.Restart(); }
/// <summary> /// Pauses sequential note playback /// </summary> /// <param name="leaveHighlighted">Whether to leave the current note highlighted</param> public void PausePlayingNotes(bool leaveHighlighted = false) { if (!isPlaying) { return; } isPlaying = false; if (playerNoteIndex >= 0 && playerNoteIndex < Notes.Count) { MusicNote current = Notes[playerNoteIndex]; Keyboard.MarkKeyReleased(current.Pitch); current.Highlighted = leaveHighlighted; } currentNoteLength.Reset(); if (StoppedPlaying != null) { StoppedPlaying(); } }
/// <summary> /// Marks the specified note as currently pressed /// </summary> /// <param name="note">The note to press on the piano keyboard</param> /// <param name="addToStaff">Whether to add the specified note to the staff</param> public void MarkKeyPressed(NoteEnum note, bool addToStaff) { if (!(note == NoteEnum.None || pressedNotes.ContainsKey(note))) { Stopwatch stopwatch = Stopwatch.StartNew(); MidiPlayer.PlayNote(note); if (addToStaff) { int silenceLength = (int)SilenceStopwatch.ElapsedMilliseconds; NoteLength restLength = Staff.ToNoteLength(silenceLength); if (restLength >= NoteLength.DemiSemiQuaver) { Staff.AddNote(NoteEnum.None, restLength); } else { MusicNote lastNote = Staff.LastNote; if (lastNote != null) { lastNote.LengthInMilliseconds += silenceLength; } } } SilenceStopwatch.Restart(); if (addToStaff) { MusicNote noteControl = Staff.AddNote(note, NoteLength.HemiDemiSemiQuaver); pressedNotes.Add(note, noteControl); Staff.StartAdjustingNote(noteControl, stopwatch); } else { pressedNotes.Add(note, null); } Invalidate(GetNoteArea(note), false); } }
/// <summary> /// Called when the mouse is moved on the piano keyboard /// </summary> protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); if (leftMouseDown) { Stopwatch stopwatch = Stopwatch.StartNew(); lastCursorLocation = e.Location; NoteEnum currentNote = GetNoteAtPoint(e.Location); NoteEnum oldNote = lastMouseNote; if (!pressedNotes.ContainsKey(currentNote)) { lastMouseNote = currentNote; if (oldNote != NoteEnum.None) { MidiPlayer.StopNote(oldNote); } if (currentNote != NoteEnum.None) { MidiPlayer.PlayNote(currentNote); } if (oldNote != NoteEnum.None) { Staff.StopAdjustingNote(currentMouseNote); currentMouseNote = null; pressedNotes.Remove(oldNote); Invalidate(GetNoteArea(oldNote)); } if (currentNote != NoteEnum.None) { currentMouseNote = Staff.AddNote(currentNote, NoteLength.HemiDemiSemiQuaver); pressedNotes.Add(currentNote, currentMouseNote); Staff.StartAdjustingNote(currentMouseNote, stopwatch); Invalidate(GetNoteArea(currentNote)); } } } }
/// <summary> /// Called when a mouse button is pressed onto the piano keyboard /// </summary> protected override void OnMouseDown(MouseEventArgs e) { base.OnMouseDown(e); if (e.Button == MouseButtons.Left) { Stopwatch stopwatch = Stopwatch.StartNew(); lastCursorLocation = e.Location; leftMouseDown = true; lastMouseNote = GetNoteAtPoint(e.Location); if (lastMouseNote != NoteEnum.None) { MidiPlayer.PlayNote(lastMouseNote); int silenceLength = (int)SilenceStopwatch.ElapsedMilliseconds; NoteLength restLength = Staff.ToNoteLength(silenceLength); if (restLength >= NoteLength.DemiSemiQuaver) { Staff.AddNote(NoteEnum.None, restLength); } else { MusicNote lastNote = Staff.LastNote; if (lastNote != null) { lastNote.LengthInMilliseconds += silenceLength; } } SilenceStopwatch.Restart(); currentMouseNote = Staff.AddNote(lastMouseNote, NoteLength.HemiDemiSemiQuaver); if (!pressedNotes.ContainsKey(lastMouseNote)) { pressedNotes.Add(lastMouseNote, currentMouseNote); } Staff.StartAdjustingNote(currentMouseNote, stopwatch); Invalidate(GetNoteArea(lastMouseNote), false); } } }