private void EditNoteModeHoldFlick(ScoreEditorHitTestResult hit, MouseEventArgs e) { var editor = _visualizer.Editor; Note lastNote = null; if (editor.HasOneSelectedNote) { lastNote = editor.GetSelectedNote(); } else if (hit.HitAnyNote && editor.HasSelectedNotes) { Debug.Print("You can only select one note to create a hold pair."); return; } Note thisNote = null; var isNoteAdded = false; if (hit.HitAnyNote) { // The clicked note is always selected. thisNote = hit.Note == _lastMouseDownNote ? hit.Note : null; } else if (hit.HitBarGridIntersection) { // If not selected, add a note and select it. thisNote = EditorAddNote(hit); isNoteAdded = true; } // If the user clicked on nothing, then clear all selections. if (thisNote == null) { ClearNoteAndBarSelection(); editor.Invalidate(); return; } // If the user clicked on the same note, just perform the standard note selection. if (lastNote == null || lastNote == thisNote) { thisNote.EditorToggleSelected(); editor.Invalidate(); return; } var relationCreated = false; if (thisNote.Basic.FinishPosition == lastNote.Basic.FinishPosition) { do { // If the selected note is already a hold note (start/end) and there is a hold relation between the // two notes, then switch selection. if (NoteHelper.AreNotesInHoldChain(thisNote, lastNote)) { // Yep just switch selection. Do nothing in this branch. } else { var errStr = EnsureHoldValid(thisNote, lastNote); if (errStr != null) { if (isNoteAdded) { thisNote.Basic.Bar.RemoveNote(thisNote); } Debug.Print(errStr); break; } // Make hold. var(first, second) = NoteHelper.Split(thisNote, lastNote); NoteHelper.MakeHold(first, second); _visualizer.InformProjectModified(); relationCreated = true; } } while (false); } else { do { // If the selected note is already a flick note and there is a flick relation between the // two notes, then switch selection. if (NoteHelper.AreNotesInFlickChain(thisNote, lastNote)) { // Yep just switch selection. Do nothing in this branch. } else { var errStr = EnsureFlickValid(thisNote, lastNote); if (errStr != null) { if (isNoteAdded) { thisNote.Basic.Bar.RemoveNote(thisNote); } Debug.Print(errStr); break; } // Make flick. var(first, second) = NoteHelper.Split(thisNote, lastNote); NoteHelper.MakeFlick(first, second); _visualizer.InformProjectModified(); relationCreated = true; } } while (false); } // Now handle a special case: link flick after a slide. if (!relationCreated) { var(first, second) = NoteHelper.Split(thisNote, lastNote); if (first.Basic.FinishPosition != second.Basic.FinishPosition) { if (first.Helper.IsSlideEnd && second.Helper.IsFlickStart) { NoteHelper.MakeSlideToFlick(first, second); _visualizer.InformProjectModified(); relationCreated = true; } } } if (relationCreated) { thisNote.EditorUnselect(); lastNote.EditorUnselect(); } else { lastNote.EditorUnselect(); thisNote.EditorSelect(); } // Did we created a hold pair? // If so, ensure the pair's start position being the same. if (relationCreated) { if (thisNote.Helper.IsHoldStart) { thisNote.Editor.HoldPair.Basic.StartPosition = thisNote.Basic.StartPosition; } else if (thisNote.Helper.IsHoldEnd) { thisNote.Basic.StartPosition = thisNote.Editor.HoldPair.Basic.StartPosition; } } editor.Invalidate(); }