private void DrawNotes(Graphics context, Score score, Rectangle gridArea, ScoreEditorConfig config, ScoreEditorLook look, Rectangle specialNoteArea, float noteStartY, float radius) { if (!score.HasAnyNote) { return; } var unit = look.BarLineSpaceUnit; var startPositionFont = _noteStartPositionFont; var shouldDrawIndicators = look.IndicatorsVisible; var numColumns = config.NumberOfColumns; foreach (var bar in score.Bars) { var numberOfGrids = bar.GetNumberOfGrids(); if (bar.Helper.HasAnyNote) { foreach (var note in bar.Notes) { if (!ScoreEditorLayout.IsNoteVisible(note, gridArea, noteStartY, unit, radius)) { continue; } if (note.Helper.IsGaming) { var x = ScoreEditorLayout.GetNotePositionX(note, gridArea, numColumns); var y = ScoreEditorLayout.GetNotePositionY(note, unit, noteStartY); var h = note.Helper; if (h.IsSlide) { if (h.HasNextFlick) { DrawFlickNote(context, note, x, y, radius, note.Basic.FlickType); } else { DrawSlideNote(context, note, x, y, radius, h.IsSlideMidway); } } else if (h.IsHoldStart) { DrawHoldNote(context, note, x, y, radius); } else { if (note.Basic.FlickType != NoteFlickType.None) { DrawFlickNote(context, note, x, y, radius, note.Basic.FlickType); } else if (h.IsHoldEnd) { DrawHoldNote(context, note, x, y, radius); } else { DrawTapNote(context, note, x, y, radius); } } // Indicators if (shouldDrawIndicators) { if (note.Helper.IsSync) { context.FillCircle(_syncIndicatorBrush, x + radius, y - radius, Definitions.IndicatorRadius); } if (note.Helper.IsHold) { context.FillCircle(_holdIndicatorBrush, x - radius, y + radius, Definitions.IndicatorRadius); } if (note.Helper.IsSlide) { context.FillCircle(_slideIndicatorBrush, x + radius, y + radius, Definitions.IndicatorRadius); } else if (note.Helper.IsFlick) { context.FillCircle(_flickIndicatorBrush, x + radius, y + radius, Definitions.IndicatorRadius); } } // Start position if (note.Basic.StartPosition != note.Basic.FinishPosition) { var startPositionX = x - radius - Definitions.StartPositionFontSize / 2; var startPositionY = y - radius - Definitions.StartPositionFontSize / 2; var text = ((int)note.Basic.StartPosition).ToString(); var textSize = context.MeasureString(startPositionFont, text); context.FillString(_noteCommonFill, startPositionFont, text, startPositionX, startPositionY + textSize.Y); } } else if (note.Helper.IsSpecial) { // Draw a special note (a rectangle) var left = specialNoteArea.Left + radius * 4; var gridY = ScoreEditorLayout.GetNotePositionY(note, unit, noteStartY); var top = gridY - radius * Definitions.SpecialNoteHeightFactor; var width = specialNoteArea.Right - left; var height = radius * 2 * Definitions.SpecialNoteHeightFactor; context.DrawRectangle(_specialNoteStroke, left, top, width, height); context.FillRectangle(_specialNoteFill, left, top, width, height); string specialNoteText; switch (note.Basic.Type) { case NoteType.VariantBpm: specialNoteText = $"BPM: {note.Params.NewBpm:0.00}"; break; default: throw new ArgumentOutOfRangeException(nameof(note.Basic.Type), note.Basic.Type, null); } var rect = context.MeasureString(_specialNoteDescriptionFont, specialNoteText); var textLeft = left + 2; var textTop = gridY + rect.Y / 2; context.FillString(_specialNoteTextBrush, _specialNoteDescriptionFont, specialNoteText, textLeft, textTop); } } } noteStartY -= numberOfGrids * unit; } }
private void DrawNoteConnections(Graphics context, Score score, Rectangle gridArea, ScoreEditorConfig config, ScoreEditorLook look, float scrollOffsetY, float noteStartY, float radius) { if (!score.HasAnyNote) { return; } var unit = look.BarLineSpaceUnit; var numColumns = config.NumberOfColumns; foreach (var bar in score.Bars) { var numberOfGrids = bar.GetNumberOfGrids(); if (bar.Helper.HasAnyNote) { foreach (var note in bar.Notes) { var thisStatus = ScoreEditorLayout.GetNoteOnStageStatus(note, gridArea, noteStartY, unit, radius); var x1 = ScoreEditorLayout.GetNotePositionX(note, gridArea, numColumns); var y1 = ScoreEditorLayout.GetNotePositionY(note, unit, noteStartY); if (note.Helper.HasNextSync && thisStatus == OnStageStatus.OnStage) { var n2 = note.Editor.NextSync; var x2 = ScoreEditorLayout.GetNotePositionX(n2, gridArea, numColumns); // Draw sync line context.DrawLine(_syncLineStroke, x1, y1, x2, y1); } if (note.Helper.IsHoldStart) { var n2 = note.Editor.HoldPair; var s2 = noteStartY; // We promise only calculate the latter note, so this method works. if (note.Basic.Bar != n2.Basic.Bar) { for (var i = note.Basic.Bar.Basic.Index; i < n2.Basic.Bar.Basic.Index; ++i) { s2 -= score.Bars[i].GetNumberOfGrids() * unit; } } var thatStatus = ScoreEditorLayout.GetNoteOnStageStatus(n2, gridArea, s2, unit, radius); if ((int)thisStatus * (int)thatStatus <= 0) { var x2 = ScoreEditorLayout.GetNotePositionX(n2, gridArea, numColumns); var y2 = ScoreEditorLayout.GetNotePositionY(score.Bars, n2.Basic.Bar.Basic.Index, n2.Basic.IndexInGrid, unit, scrollOffsetY); // Draw hold line context.DrawLine(_holdLineStroke, x1, y1, x2, y2); } } if (note.Helper.HasNextFlick) { var n2 = note.Editor.NextFlick; var s2 = noteStartY; if (note.Basic.Bar != n2.Basic.Bar) { for (var i = note.Basic.Bar.Basic.Index; i < n2.Basic.Bar.Basic.Index; ++i) { s2 -= score.Bars[i].GetNumberOfGrids() * unit; } } var thatStatus = ScoreEditorLayout.GetNoteOnStageStatus(n2, gridArea, s2, unit, radius); if ((int)thisStatus * (int)thatStatus <= 0) { var x2 = ScoreEditorLayout.GetNotePositionX(n2, gridArea, numColumns); var y2 = ScoreEditorLayout.GetNotePositionY(score.Bars, n2.Basic.Bar.Basic.Index, n2.Basic.IndexInGrid, unit, scrollOffsetY); // Draw flick line context.DrawLine(_flickLineStroke, x1, y1, x2, y2); } } if (note.Helper.HasNextSlide) { var n2 = note.Editor.NextSlide; var s2 = noteStartY; if (note.Basic.Bar != n2.Basic.Bar) { for (var i = note.Basic.Bar.Basic.Index; i < n2.Basic.Bar.Basic.Index; ++i) { s2 -= score.Bars[i].GetNumberOfGrids() * unit; } } var thatStatus = ScoreEditorLayout.GetNoteOnStageStatus(n2, gridArea, s2, unit, radius); if ((int)thisStatus * (int)thatStatus <= 0) { var x2 = ScoreEditorLayout.GetNotePositionX(n2, gridArea, numColumns); var y2 = ScoreEditorLayout.GetNotePositionY(score.Bars, n2.Basic.Bar.Basic.Index, n2.Basic.IndexInGrid, unit, scrollOffsetY); // Draw slide line context.DrawLine(_slideLineStroke, x1, y1, x2, y2); } } } } noteStartY -= numberOfGrids * unit; } }