Example #1
0
        public static SelectedNoteArea SelectedNoteArea(this NoteBase note, Point p, IReadOnlyEditorLaneEnvironment env)
        {
            var cr        = note.NoteSize.Size - 2;
            var areaRatio = (lr : 1, cr : cr <= 0 ? 0 : cr, rr : 1);
            var rect      = note.GetRectangle(env);
            // 実装微妙かも
            Func <SelectedNoteArea> fun = () =>
            {
                var areaSum = areaRatio.lr + areaRatio.cr + areaRatio.rr;
                if (p.X < rect.X + rect.Width * areaRatio.lr / areaSum)
                {
                    return(UI.SelectedNoteArea.Left);
                }
                if (p.X < rect.X + rect.Width * (areaRatio.lr + areaRatio.cr) / areaSum)
                {
                    return(UI.SelectedNoteArea.Center);
                }
                return(UI.SelectedNoteArea.Right);
            };

            if (rect.Contains(p))
            {
                return(fun());
            }
            rect.X -= (int)(env.LaneUnitWidth * MadcaEnv.LaneCount);
            if (rect.Contains(p))
            {
                return(fun());
            }
            return(UI.SelectedNoteArea.None);
        }
Example #2
0
 public static void DrawToLane(System.Drawing.Graphics g, IReadOnlyEditorLaneEnvironment env, NoteBase note)
 {
     // NOTE: お試し実装
     using (var sb = new SolidBrush(NoteGraphicsGenerator.GetColor(note.NoteType)))
         using (var pen = new Pen(Color.White))
         {
             g.Clip = new Region(env.LaneRect);
             var rect = note.GetRectangle(env);
             if (note.NoteType == NoteType.HoldRelay)
             {
                 g.DrawRectangle(pen, rect);
             }
             else
             {
                 g.FillRectangle(sb, rect);
             }
             DrawToLanePreviewNoteFrame(g, rect, note as PreviewNote);
             // 水平位置を1周分ずらしてもう一回描画
             rect.X -= (int)(MadcaEnv.LaneCount * env.LaneUnitWidth);
             if (note.NoteType == NoteType.HoldRelay)
             {
                 g.DrawRectangle(pen, rect);
             }
             else
             {
                 g.FillRectangle(sb, rect);
             }
             DrawToLanePreviewNoteFrame(g, rect, note as PreviewNote);
             g.ResetClip();
         }
 }
Example #3
0
        public static GraphicsPath GetGraphicsPath(this Hold hold, IReadOnlyEditorLaneEnvironment env)
        {
            var ps1       = new List <Point>();
            var ps2       = new List <Point>();
            var beginRect = hold.HoldBegin.GetRectangle(env);

            ps1.Add(beginRect.GetLeftMiddle());
            ps2.Add(beginRect.GetRightMiddle());
            foreach (var note in hold.AllNotes.Where(x => x != hold.HoldBegin).OrderBy(x => x.Timing))
            {
                var rect = note.GetRectangle(env);
                var diff = note.Lane.RawLane - hold.HoldBegin.Lane.RawLane;
                rect.X = beginRect.X + diff * (int)env.LaneUnitWidth;
                ps1.Add(rect.GetLeftMiddle());
                ps2.Add(rect.GetRightMiddle());
            }
            ps2.Reverse();
            ps1.AddRange(ps2);
            var gPath = new GraphicsPath();

            for (int i = 0; i < ps1.Count - 1; ++i)
            {
                gPath.AddLine(ps1[i], ps1[i + 1]);
            }
            return(gPath);
        }
Example #4
0
        public Rectangle GetRectangle(IReadOnlyEditorLaneEnvironment env)
        {
            var loc    = PositionConverter.ConvertVirtualToRealNorm(env, new Position(Lane, Timing));
            int width  = NoteEnvironment.NoteWidth(NoteSize.Size, env);
            int height = NoteEnvironment.NoteHeight;

            return(new Rectangle(loc.X, loc.Y - NoteEnvironment.NoteHeight / 2, width, height));
        }
Example #5
0
        /// <summary>
        /// 仮想座標から絶対実座標を計算します
        /// x座標のRangeは(-inf, inf)
        /// </summary>
        /// <param name="env">エディタレーン環境</param>
        /// <param name="position">仮想座標</param>
        /// <returns></returns>
        public static Point ConvertVirtualToReal(IReadOnlyEditorLaneEnvironment env, Position position)
        {
            var px = (int)(env.SideMargin + position.Lane.RawLane * env.LaneUnitWidth - env.OffsetXRaw);
            var py = (int)(position.Timing.BarRatio * env.TimingUnitHeight - env.OffsetY);

            px += env.PanelRegion.X;
            py  = env.PanelRegion.Height - py - env.PanelRegion.Y - (int)env.BottomMargin;
            return(new Point(px, py));
        }
Example #6
0
        /// <summary>
        /// X方向で端がつながっているレーン上で見たときに,矩形領域内に座標が含まれているかを判定します
        /// </summary>
        /// <param name="rect"></param>
        /// <param name="p"></param>
        /// <param name="env"></param>
        /// <returns></returns>
        public static bool ContainsEx(this Rectangle rect, Point p, IReadOnlyEditorLaneEnvironment env)
        {
            var tmp = rect;

            if (tmp.Contains(p))
            {
                return(true);
            }
            tmp.X -= (int)(env.LaneUnitWidth * MadcaEnv.LaneCount);
            return(tmp.Contains(p));
        }
Example #7
0
 public static void DrawToLane(System.Drawing.Graphics g, IReadOnlyEditorLaneEnvironment env, NoteBook noteBook)
 {
     // HACK: 描画対象にするHoldを画面内にあるもののみに絞ったほうがいいんじゃない?
     foreach (var hold in noteBook.Holds)
     {
         DrawHoldRegionToLane(g, env, hold);
         foreach (var note in hold.AllNotes)
         {
             DrawToLane(g, env, note);
         }
     }
     foreach (var note in noteBook.Notes)
     {
         DrawToLane(g, env, note);
     }
 }
Example #8
0
        public static void DrawHoldRegionToLane(System.Drawing.Graphics g, IReadOnlyEditorLaneEnvironment env, Hold hold)
        {
            using (var sb = new SolidBrush(Color.FromArgb(200, 200, 175, 90)))
                using (var path = hold.GetGraphicsPath(env))
                    using (var matToLeft = new Matrix())
                        using (var matToRight = new Matrix())
                            using (var matToReset = new Matrix())
                            {
                                var laneWidth = env.LaneUnitWidth * MadcaEnv.LaneCount;
                                g.Clip = new Region(env.LaneRect);
                                matToLeft.Translate(-laneWidth, 0);
                                matToRight.Translate(laneWidth, 0);
                                var leftTimes = 0;

                                try
                                {
                                    g.FillPath(sb, path);
                                }
                                catch (Exception) { }
                                while (path.GetBounds().Right > env.LaneRect.Right)
                                {
                                    path.Transform(matToLeft);
                                    try
                                    {
                                        g.FillPath(sb, path);
                                    }
                                    catch (Exception) { }
                                    leftTimes++;
                                }
                                matToReset.Translate(laneWidth * leftTimes, 0);
                                path.Transform(matToReset);

                                while (path.GetBounds().Left < env.LaneRect.Left)
                                {
                                    path.Transform(matToRight);
                                    try
                                    {
                                        g.FillPath(sb, path);
                                    }
                                    catch (Exception) { }
                                }
                                g.ResetClip();
                            }
        }
Example #9
0
        public static bool Contains(this Hold hold, Point p, IReadOnlyEditorLaneEnvironment env)
        {
            var laneWidth = env.LaneUnitWidth * MadcaEnv.LaneCount;

            var matToLeft = new Matrix();

            matToLeft.Translate(-laneWidth, 0);
            var matToRight = new Matrix();

            matToRight.Translate(laneWidth, 0);
            var leftTimes = 0;

            using (var path = hold.GetGraphicsPath(env))
            {
                if (path.IsVisible(p))
                {
                    return(true);
                }
                while (path.GetBounds().Right > env.LaneRect.Right)
                {
                    path.Transform(matToLeft);
                    if (path.IsVisible(p))
                    {
                        return(true);
                    }
                    leftTimes++;
                }
                var matToReset = new Matrix();
                matToReset.Translate(laneWidth * leftTimes, 0);
                path.Transform(matToReset);

                while (path.GetBounds().Left < env.LaneRect.Left)
                {
                    path.Transform(matToRight);
                    if (path.IsVisible(p))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Example #10
0
        /// <summary>
        /// 絶対実座標から仮想座標を計算します
        /// LaneのRangeは(-inf, inf)(RawLaneを計算)
        /// </summary>
        /// <param name="env">エディタレーン環境</param>
        /// <param name="p">実座標(左上原点)</param>
        /// <param name="beat">拍数のストライド</param>
        /// <param name="scores"></param>
        /// <param name="position">計算された仮想座標</param>
        /// <returns>仮想座標の計算に成功したかどうか</returns>
        public static bool ConvertRealToVirtual(IReadOnlyEditorLaneEnvironment env, Point p, TimingPosition beat, IReadOnlyList <IReadOnlyScore> scores, out Position position)
        {
            p        = new Point(p.X - env.PanelRegion.X, p.Y - env.PanelRegion.Y);
            position = null;
            if (env.AvailableLaneWidth == 0)
            {
                return(false);
            }
            var laneLeft  = env.SideMargin;
            var laneRight = laneLeft + env.AvailableLaneWidth;

            if (!(laneLeft <= p.X && p.X < laneRight))
            {
                return(false);
            }
            int lanePos = (int)(((p.X - laneLeft) + env.OffsetXRaw) / env.LaneUnitWidth);

            if ((p.X - laneLeft) + env.OffsetXRaw < 0)
            {
                lanePos--;
            }
            var newLanePos = new LanePotision(lanePos);
            var timing     = new TimingPosition(env.TimingUnitHeight.ToUInt(), (env.PanelRegion.Height - p.Y) - (int)env.BottomMargin + env.OffsetY);
            var accum      = new TimingPosition(1, 0);

            foreach (var score in scores)
            {
                var tmp = new TimingPosition(score.BeatDen, (int)score.BeatNum);
                if (timing < tmp + accum)
                {
                    break;
                }
                accum += tmp;
            }
            var cnt          = (int)Math.Floor(((timing - accum) / beat).BarRatio);
            var newTimingPos = new TimingPosition(beat.DivValue, cnt) + accum;

            position = new Position(newLanePos, newTimingPos);
            return(true);
        }
Example #11
0
        public static void Draw(System.Drawing.Graphics g, IReadOnlyEditorLaneEnvironment env, IReadOnlyList <Score.IReadOnlyScore> scores)
        {
            using (var backgroundBrush = new SolidBrush(backgroundColor))
                using (var laneBackBrush = new SolidBrush(laneBackColor))
                {
                    g.FillRectangle(backgroundBrush, env.PanelRegion);
                    g.FillRectangle(laneBackBrush, env.LaneRect);
                }
            using (var penBorder = new Pen(Color.White))
                using (var penMain = new Pen(Color.FromArgb(200, Color.White)))
                    using (var penSub = new Pen(Color.FromArgb(130, Color.White)))
                        using (Font myFont = new Font("MS UI Gothic", 10, FontStyle.Bold))
                            using (var penTimingMain = new Pen(timingMainColor))
                            {
                                // レーン補助線を描画
                                var diffX = (int)(env.LaneUnitWidth - env.OffsetX % env.LaneUnitWidth);
                                if (diffX == env.LaneUnitWidth)
                                {
                                    diffX = 0;
                                }
                                var curX    = diffX + env.LaneRect.Left;
                                var curLane = (diffX + env.OffsetX) / env.LaneUnitWidth;
                                for (; curX <= env.LaneRect.Right; curX += (int)env.LaneUnitWidth, ++curLane)
                                {
                                    curLane %= MadcaEnv.LaneCount;
                                    if (curLane % env.LaneGroupCount == 0)
                                    {
                                        g.DrawLine(penMain, new PointF(curX, env.PanelRegion.Y), new PointF(curX, env.PanelRegion.Y + env.AvailableLaneHeight));
                                        var textWidth = System.Windows.Forms.TextRenderer.MeasureText(g, curLane.ToString(), myFont).Width;
                                        g.DrawString(curLane.ToString(), myFont, Brushes.White, new PointF(curX - textWidth / 2 + 1.5f, env.PanelRegion.Y + env.AvailableLaneHeight + 5));
                                        continue;
                                    }
                                    g.DrawLine(penSub, new PointF(curX, env.PanelRegion.Y), new PointF(curX, env.PanelRegion.Y + env.AvailableLaneHeight));
                                }

                                // 小節線などを描画
                                if (scores == null)
                                {
                                    return;
                                }
                                var offsetTimingMin = new TimingPosition(env.TimingUnitHeight.ToUInt(), env.OffsetY);
                                var offsetTimingMax = new TimingPosition(env.TimingUnitHeight.ToUInt(), env.OffsetY + env.LaneRect.Height);
                                var drawScores      = scores.Where(x => !(x.TimingEnd <= offsetTimingMin || offsetTimingMax < x.TimingBegin));
                                foreach (var score in drawScores)
                                {
                                    var y = (int)(env.LaneRect.Bottom - (score.TimingBegin - offsetTimingMin).BarRatio * env.TimingUnitHeight);
                                    if (env.LaneRect.Top <= y && y <= env.LaneRect.Bottom)
                                    {
                                        g.DrawString(scores.IndexOf(score).ToString().PadLeft(3, '0'), myFont, Brushes.White, new Point(env.LaneRect.Left - 28, y - 12));
                                        g.DrawLine(penTimingMain, new Point(env.LaneRect.Left, y), new Point(env.LaneRect.Right, y));
                                    }
                                    for (var cnt = 1; cnt < score.BeatNum; ++cnt)
                                    {
                                        y -= (int)(env.TimingUnitHeight / score.BeatDen);
                                        if (env.LaneRect.Top <= y && y <= env.LaneRect.Bottom)
                                        {
                                            g.DrawLine(penSub, new Point(env.LaneRect.Left, y), new Point(env.LaneRect.Right, y));
                                        }
                                    }
                                }
                            }
        }
Example #12
0
        public static int NoteHeight => 5; // 決め打ち

        public static int NoteWidth(int size, IReadOnlyEditorLaneEnvironment env)
        {
            return((int)env.LaneUnitWidth * size);
        }