private void DrawBarGrid(Graphics context, Rectangle gridArea, ScoreEditorConfig config, float barStartY, int numberOfGrids, float unit, float noteRadius, PrimaryBeatMode primaryBeatMode) { // Vertical var verticalY1 = barStartY; var verticalY2 = barStartY - numberOfGrids * unit; var verticalPen = _barNormalGridPen; var numColumns = config.NumberOfColumns; for (var i = 0; i < numColumns; ++i) { var x = gridArea.Left + gridArea.Width * i / (numColumns - 1); context.DrawLine(verticalPen, x, verticalY1, x, verticalY2); } // Calculate zooming compensation. var firstClearDrawnRatio = ScoreEditorLayout.BarZoomRatio.FirstOrDefault(i => unit * i >= noteRadius * ScoreEditorLayout.SpaceUnitRadiusRatio); if (firstClearDrawnRatio == 0) { firstClearDrawnRatio = numberOfGrids; } // Calculate primary beat grids. int numBeats; switch (primaryBeatMode) { case PrimaryBeatMode.EveryFourBeats: numBeats = 4; break; case PrimaryBeatMode.EveryThreeBeats: numBeats = 3; break; default: throw new ArgumentOutOfRangeException(nameof(primaryBeatMode), primaryBeatMode, null); } var primaryBeatIndex = numberOfGrids / numBeats; var secondaryBeatIndex = primaryBeatIndex / 2; var textBrush = _gridNumberBrush; var textFont = _gridNumberFont; int visibleGridsPerBeat; // For the usage, see below. if (primaryBeatIndex % firstClearDrawnRatio == 0) { visibleGridsPerBeat = primaryBeatIndex / firstClearDrawnRatio; } else { // This patch does not actually 'patch' very well. But it is still better than splitting // the non-separatable 3-beat measures into some weird 5-beat(=32/6) rendering. visibleGridsPerBeat = primaryBeatIndex * numBeats / 4 / firstClearDrawnRatio; } if (visibleGridsPerBeat <= 0) { visibleGridsPerBeat = 1; } var visibleGridCounter = 1; // Horizontal for (var i = 0; i <= numberOfGrids; ++i) { if (i % firstClearDrawnRatio != 0) { continue; } var currentY = barStartY - unit * i; Pen pen; if (i == 0) { // Grid start. pen = _barGridStartBeatPen; } else if (i % primaryBeatIndex == 0) { // Primary beat. pen = _barPrimaryBeatPen; } else if (i % secondaryBeatIndex == 0) { // Secondary beat. pen = _barSecondaryBeatPen; } else { // Normal grid. pen = _barNormalGridPen; } context.DrawLine(pen, gridArea.Left, currentY, gridArea.Right, currentY); if (i < numberOfGrids) { // Prints like // 1/4 2/4 3/4 4/4 1/4 2/4 ... var text = $"{visibleGridCounter}/{visibleGridsPerBeat}"; var textSize = context.MeasureString(_gridNumberFont, text); var textLeft = gridArea.Left - textSize.X - ScoreEditorLayout.GridNumberMargin; var textTop = currentY + textSize.Y / 2; context.FillString(textBrush, textFont, text, textLeft, textTop); if (visibleGridCounter >= visibleGridsPerBeat) { visibleGridCounter = 1; } else { ++visibleGridCounter; } } } }
public static (DialogResult DialogResult, double BPM, double MusicOffset) RequestInput(IWin32Window parentWindow, ProjectSettings projectSettings, PrimaryBeatMode primaryBeatMode) { using (var f = new FBeatmapSettings()) { f.Localize(LanguageManager.Current); f._bpm = projectSettings.BeatPerMinute; f._musicOffset = projectSettings.StartTimeOffset; f._primaryBeatMode = primaryBeatMode; f.MonitorLocalizationChange(); var r = f.ShowDialog(parentWindow); f.UnmonitorLocalizationChange(); var bpm = f._bpm; var offset = f._musicOffset; return(r, bpm, offset); } }