Ejemplo n.º 1
0
        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();
        }