internal void CalcAxis(PianoProperties pprops, RollConfigures rconf)
 {
     if (_me.Y <= rconf.Const_TitleHeight && _me.Y >= 0)
     {
         _area = AreaType.Title;
     }
     else if (_me.X <= rconf.Const_RollWidth && _me.X >= 0)
     {
         _area = AreaType.Roll;
     }
     else
     {
         _area = AreaType.Track;
     }
     if (_area != AreaType.Title)
     {
         double drawed_noteSpt  = (double)(_me.Y - rconf.Const_TitleHeight) / rconf.Const_RollNoteHeight;
         uint   _noteNumber     = pprops.PianoTopNote - (uint)drawed_noteSpt;
         double cent            = 0.5 - drawed_noteSpt + (uint)drawed_noteSpt;
         int    _notePitchWheel = (int)Math.Round(cent * 0x2000, 0);
         _pitchvp            = new PitchValuePair(_noteNumber, _notePitchWheel);
         _pitchvp.OctaveType = pprops.OctaveType;
     }
     if (_area != AreaType.Roll)
     {
         long drawed_pixel = _me.X - rconf.Const_RollWidth;
         _tick = (long)Math.Round((pprops.PianoStartTick + pprops.dertPixel2dertTick(drawed_pixel)), 0);
     }
 }
 internal void CalcAxis(PianoProperties pprops, RollConfigures rconf, PianoMouseEventArgs cache)
 {
     if (cache != null && cache.MouseEventArgs.X == _me.X && cache.MouseEventArgs.Y == _me.Y)
     {
         _tick    = cache.Tick;
         _pitchvp = cache.PitchValue;
         _area    = cache.Area;
     }
     else
     {
         CalcAxis(pprops, rconf);
     }
 }
        private void DrawPianoRollArea(object sender, BalthasarLib.D2DPainter.D2DPaintEventArgs e)
        {
            D2DGraphics g = e.D2DGraphics;

            int y        = rconf.Const_TitleHeight;                                                        //绘制点纵坐标
            int cNote    = (int)pprops.PianoTopNote;                                                       //绘制区域第一个阶的音符
            int MyNotePx = (int)((e.MousePoint.Y - rconf.Const_TitleHeight) / rconf.Const_RollNoteHeight); //获取当前琴键
            int MyNote   = (int)pprops.PianoTopNote - MyNotePx;                                            //获取坐标

            while (y < e.ClipRectangle.Height)                                                             //若未画超界
            {
                //计算绘制区域
                Point     LT        = new Point(0, y);                                                                                                                                             //矩形左上角
                Point     LB        = new Point(0, y + rconf.Const_RollNoteHeight);                                                                                                                //矩形左下角
                Point     RT        = new Point(rconf.Const_RollWidth, y);                                                                                                                         //矩形右上角
                Point     RB        = new Point(rconf.Const_RollWidth, y + rconf.Const_RollNoteHeight);                                                                                            //矩形右下角
                Rectangle WhiteRect = new Rectangle(LT, new Size(rconf.Const_RollWidth, rconf.Const_RollNoteHeight));                                                                              //矩形区域
                Rectangle BlackRect = new Rectangle(LT, new Size(rconf.Const_RollBlackWidth, rconf.Const_RollNoteHeight));                                                                         //矩形区域
                Rectangle WordRect  = new Rectangle(new Point(LT.X + rconf.Const_RollBlackWidth, LT.Y), new Size(rconf.Const_RollWidth - rconf.Const_RollBlackWidth, rconf.Const_RollNoteHeight)); //矩形区域
                //绘制基础矩形
                g.FillRectangle(WhiteRect, rconf.PianoColor_WhiteKey);
                g.DrawRectangle(WhiteRect, rconf.PianoColor_Line);
                //绘制黑键
                PitchValuePair NoteValue = new PitchValuePair((uint)cNote, 0);
                NoteValue.OctaveType = pprops.OctaveType;
                int  Octave     = NoteValue.Octave;
                int  Key        = NoteValue.Key;
                bool isBlackKey = NoteValue.IsBlackKey;
                if (isBlackKey)
                {
                    g.FillRectangle(BlackRect, rconf.PianoColor_BlackKey);
                }
                //获取鼠标位置琴键
                //绘制符号
                if (MyNote == cNote)
                {
                    g.FillRectangle(WordRect, rconf.PianoColor_MouseKey);
                    g.DrawText("  " + NoteValue.NoteChar + Octave.ToString(), WordRect, rconf.PianoColor_BlackKey, new System.Drawing.Font("Tahoma", 10));
                }
                else if (Key == 0)
                {
                    g.DrawText("  " + NoteValue.NoteChar + Octave.ToString(), WordRect, rconf.PianoColor_BlackKey, new System.Drawing.Font("Tahoma", 10));
                }

                //递归
                y     = y + rconf.Const_RollNoteHeight;
                cNote = cNote - 1;
            }
            //Rise 绘制Note等//传递事件
            //            e.ClipRectangle.Width - rconf.Const_RollWidth, rconf.Const_RollNoteHeight

            Rectangle CurrentRect = new Rectangle(
                0,
                rconf.Const_TitleHeight,
                rconf.Const_RollWidth,
                e.ClipRectangle.Height - rconf.Const_TitleHeight);//可绘制区域

            if (RollPaint != null)
            {
                D2DPaintEventArgs d2de = new D2DPaintEventArgs(
                    e.D2DGraphics,
                    CurrentRect,
                    e.MousePoint
                    );
                RollPaint(sender, new BalthasarLib.PianoRollWindow.DrawUtils.RollDrawUtils(d2de, rconf, pprops));
            }
        }
        private void DrawPianoTrackArea(object sender, BalthasarLib.D2DPainter.D2DPaintEventArgs e, PianoRollPoint startPoint)
        {
            D2DGraphics g = e.D2DGraphics;

            int y = rconf.Const_TitleHeight;//绘制点纵坐标
            int w = e.ClipRectangle.Width - rconf.Const_VScrollBarWidth;
            //绘制钢琴窗
            int cNote = (int)pprops.PianoTopNote; //绘制区域第一个阶的音符

            while (y < e.ClipRectangle.Height)    //若未画超界
            {
                //计算绘制区域
                Point     LT   = new Point(rconf.Const_RollWidth, y);                                                //矩形左上角
                Point     LB   = new Point(rconf.Const_RollWidth, y + rconf.Const_RollNoteHeight);                   //矩形左下角
                Point     RT   = new Point(w, y);                                                                    //矩形右上角
                Point     RB   = new Point(w, y + rconf.Const_RollNoteHeight);                                       //矩形右下角
                Rectangle Rect = new Rectangle(LT, new Size(w - rconf.Const_RollWidth, rconf.Const_RollNoteHeight)); //矩形区域
                //计算色域
                PitchValuePair NoteValue = new PitchValuePair((uint)cNote, 0);
                NoteValue.OctaveType = pprops.OctaveType;
                int   Octave     = NoteValue.OctaveType == PitchValuePair.OctaveTypeEnum.Voice ? NoteValue.Octave : NoteValue.Octave - 1;
                int   Key        = NoteValue.Key;
                bool  isBlackKey = NoteValue.IsBlackKey;
                Color KeyColor   = isBlackKey ? rconf.RollColor_BlackKey_NormalSound : rconf.RollColor_WhiteKey_NormalSound;
                Color LineColor  = rconf.RollColor_LineKey_NormalSound;
                Color OLineColor = rconf.RollColor_LineOctive_NormalSound;
                switch (rconf.getVoiceArea(cNote))
                {
                case RollConfigures.VoiceKeyArea.OverSound: KeyColor = isBlackKey ? rconf.RollColor_BlackKey_OverSound : rconf.RollColor_WhiteKey_OverSound; LineColor = rconf.RollColor_LineKey_OverSound; OLineColor = rconf.RollColor_LineOctive_OverSound; break;

                case RollConfigures.VoiceKeyArea.NoSound: KeyColor = isBlackKey ? rconf.RollColor_BlackKey_NoSound : rconf.RollColor_WhiteKey_NoSound; LineColor = rconf.RollColor_LineKey_NoSound; OLineColor = rconf.RollColor_LineOctive_OverSound; break;
                }
                //绘制矩形
                g.FillRectangle(Rect, KeyColor);
                //绘制边线
                g.DrawLine(LB, RB, (Key == 5 || Key == 0) ? OLineColor : LineColor, 2);//isB ? LineL : LineB);
                //递归
                y     = y + rconf.Const_RollNoteHeight;
                cNote = cNote - 1;
            }
            //绘制分节符
            //初始化
            double x               = rconf.Const_RollWidth;                        //起点画线
            long   BeatNumber      = startPoint.BeatNumber;                        //获取起点拍号
            double BeatPixelLength = pprops.dertTick2dertPixel(pprops.BeatLength); //一拍长度

            if (startPoint.DenominatolTicksBefore != 0)                            //非完整Beats
            {
                //起点不在小节线
                BeatNumber = startPoint.NextWholeBeatNumber;
                x          = x + pprops.dertTick2dertPixel(startPoint.NextWholeBeatDistance);
            }
            while (x <= w)
            {
                g.DrawLine(
                    new Point((int)Math.Round(x, 0), rconf.Const_TitleHeight),
                    new Point((int)Math.Round(x, 0), e.ClipRectangle.Height),
                    BeatNumber % pprops.BeatsCountPerSummery == 0 ? Color.Black : rconf.RollColor_LineOctive_NormalSound
                    );
                BeatNumber = BeatNumber + 1;
                x          = x + BeatPixelLength;
            }
            //Rise 绘制Note等//传递事件
            Rectangle CurrentRect = new Rectangle(
                rconf.Const_RollWidth,
                rconf.Const_TitleHeight,
                w - rconf.Const_RollWidth,
                e.ClipRectangle.Height - rconf.Const_TitleHeight);//可绘制区域

            if (TrackPaint != null)
            {
                D2DPaintEventArgs d2de = new D2DPaintEventArgs(
                    e.D2DGraphics,
                    CurrentRect,
                    e.MousePoint
                    );
                TrackPaint(sender, new BalthasarLib.PianoRollWindow.DrawUtils.TrackDrawUtils(d2de, rconf, pprops));
            }
        }