Пример #1
0
        public PitchPointHitInfo HitTestPitchPoint(Point mousePos)
        {
            if (!midiVM.ShowPitch)
            {
                return(null);
            }
            foreach (var note in midiVM.Part.notes)
            {
                // FIXME pitch point maybe in view while note is not.
                if (midiVM.NoteIsInView(note) && !note.Error)
                {
                    double          lastX = 0, lastY = 0;
                    PitchPointShape lastShape = PitchPointShape.l;
                    for (int i = 0; i < note.pitch.data.Count; i++)
                    {
                        var    pit     = note.pitch.data[i];
                        int    posTick = note.position + Project.MillisecondToTick(pit.X);
                        double noteNum = note.tone + pit.Y / 10;
                        double x       = midiVM.TickToCanvas(posTick);
                        double y       = midiVM.NoteNumToCanvas(noteNum) + midiVM.TrackHeight / 2;
                        if (Math.Abs(mousePos.X - x) < 4 && Math.Abs(mousePos.Y - y) < 4)
                        {
                            return new PitchPointHitInfo()
                                   {
                                       Note = note, Index = i, OnPoint = true
                                   }
                        }
                        ;
                        else if (mousePos.X < x && i > 0 && mousePos.X > lastX)
                        {
                            // Hit test curve
                            double castY = MusicMath.InterpolateShape(lastX, x, lastY, y, mousePos.X, lastShape) - mousePos.Y;

                            if (y >= lastY)
                            {
                                if (mousePos.Y - y > 3 || lastY - mousePos.Y > 3)
                                {
                                    break;
                                }
                            }
                            else
                            {
                                if (y - mousePos.Y > 3 || mousePos.Y - lastY > 3)
                                {
                                    break;
                                }
                            }
                            double castX = MusicMath.InterpolateShapeX(lastX, x, lastY, y, mousePos.Y, lastShape) - mousePos.X;
                            double dis   = double.IsNaN(castX) ? Math.Abs(castY) : Math.Cos(Math.Atan2(Math.Abs(castY), Math.Abs(castX))) * Math.Abs(castY);
                            if (dis < 3)
                            {
                                double msX = DocManager.Inst.Project.TickToMillisecond(midiVM.CanvasToQuarter(mousePos.X) * DocManager.Inst.Project.resolution - note.position);
                                double msY = (midiVM.CanvasToPitch(mousePos.Y) - note.tone) * 10;
                                return(new PitchPointHitInfo()
                                {
                                    Note = note, Index = i - 1, OnPoint = false, X = (float)msX, Y = (float)msY
                                });
                            }
                            else
                            {
                                break;
                            }
                        }
                        lastX     = x;
                        lastY     = y;
                        lastShape = pit.shape;
                    }
                }
            }
            return(null);
        }
Пример #2
0
        public PitchPointHitTestResult HitTestPitchPoint(Point mousePos)
        {
            foreach (var note in midiVM.Part.Notes)
            {
                if (midiVM.NoteIsInView(note)) // FIXME this is not enough
                {
                    if (note.Error)
                    {
                        continue;
                    }
                    double          lastX = 0, lastY = 0;
                    PitchPointShape lastShape = PitchPointShape.l;
                    for (int i = 0; i < note.PitchBend.Points.Count; i++)
                    {
                        var    pit     = note.PitchBend.Points[i];
                        int    posTick = note.PosTick + Project.MillisecondToTick(pit.X);
                        double noteNum = note.NoteNum + pit.Y / 10;
                        double x       = midiVM.TickToCanvas(posTick);
                        double y       = midiVM.NoteNumToCanvas(noteNum) + midiVM.TrackHeight / 2;
                        if (Math.Abs(mousePos.X - x) < 4 && Math.Abs(mousePos.Y - y) < 4)
                        {
                            return new PitchPointHitTestResult()
                                   {
                                       Note = note, Index = i, OnPoint = true
                                   }
                        }
                        ;
                        else if (mousePos.X < x && i > 0 && mousePos.X > lastX)
                        {
                            // Hit test curve
                            var lastPit = note.PitchBend.Points[i - 1];

                            double castY = MusicMath.InterpolateShape(lastX, x, lastY, y, mousePos.X, lastShape) - mousePos.Y;
                            if (y >= lastY)
                            {
                                if (mousePos.Y - y > 3 || lastY - mousePos.Y > 3)
                                {
                                    break;
                                }
                            }
                            else
                            {
                                if (y - mousePos.Y > 3 || mousePos.Y - lastY > 3)
                                {
                                    break;
                                }
                            }
                            double castX = MusicMath.InterpolateShapeX(lastX, x, lastY, y, mousePos.Y, lastShape) - mousePos.X;
                            double dis   = double.IsNaN(castX) ? Math.Abs(castY) : Math.Cos(Math.Atan2(Math.Abs(castY), Math.Abs(castX))) * Math.Abs(castY);
                            if (dis < 3)
                            {
                                double msX = DocManager.Inst.Project.TickToMillisecond(midiVM.CanvasToQuarter(mousePos.X) * DocManager.Inst.Project.Resolution - note.PosTick);
                                double msY = (midiVM.CanvasToPitch(mousePos.Y) - note.NoteNum) * 10;
                                return(new PitchPointHitTestResult()
                                {
                                    Note = note, Index = i - 1, OnPoint = false, X = msX, Y = msY
                                });
                            }
                            else
                            {
                                break;
                            }
                        }
                        lastX     = x;
                        lastY     = y;
                        lastShape = pit.Shape;
                    }
                }
            }
            return(null);
        }